From cdc749e22925d5b370cb51ace3cace940bd76cb5 Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Thu, 14 Dec 2017 22:34:07 +0900 Subject: clk: renesas: r8a77965: Add MSIOF controller clocks This patch adds MSIOF{0,1,2,3} clocks to the R8A77965 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77965-cpg-mssr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index b1acfb60351c..8fae5e9c4a77 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -116,6 +116,10 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { DEF_MOD("scif3", 204, R8A77965_CLK_S3D4), DEF_MOD("scif1", 206, R8A77965_CLK_S3D4), DEF_MOD("scif0", 207, R8A77965_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A77965_CLK_MSO), + DEF_MOD("msiof2", 209, R8A77965_CLK_MSO), + DEF_MOD("msiof1", 210, R8A77965_CLK_MSO), + DEF_MOD("msiof0", 211, R8A77965_CLK_MSO), DEF_MOD("sys-dmac2", 217, R8A77965_CLK_S0D3), DEF_MOD("sys-dmac1", 218, R8A77965_CLK_S0D3), DEF_MOD("sys-dmac0", 219, R8A77965_CLK_S0D3), -- cgit v1.2.3 From 5bf2fbbef50ca521ade4d4fbd366e9273743c503 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 28 Mar 2018 20:26:12 +0100 Subject: clk: renesas: cpg-mssr: Add r8a77470 support Add RZ/G1C (R8A77470) Clock Pulse Generator / Module Standby and Software Reset support. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a77470-cpg-mssr.c | 229 ++++++++++++++++++++++++++++++++ drivers/clk/renesas/rcar-gen2-cpg.c | 12 ++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 6 files changed, 254 insertions(+) create mode 100644 drivers/clk/renesas/r8a77470-cpg-mssr.c (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index ef76c861ec84..f32896fa9dda 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -7,6 +7,7 @@ config CLK_RENESAS select CLK_R8A7740 if ARCH_R8A7740 select CLK_R8A7743 if ARCH_R8A7743 select CLK_R8A7745 if ARCH_R8A7745 + select CLK_R8A77470 if ARCH_R8A77470 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 select CLK_R8A7790 if ARCH_R8A7790 @@ -60,6 +61,10 @@ config CLK_R8A7745 bool "RZ/G1E clock support" if COMPILE_TEST select CLK_RCAR_GEN2_CPG +config CLK_R8A77470 + bool "RZ/G1C clock support" if COMPILE_TEST + select CLK_RCAR_GEN2_CPG + config CLK_R8A7778 bool "R-Car M1A clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 6c0f19636e3e..a4edea99c4ec 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_CLK_R8A73A4) += clk-r8a73a4.o obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a77470-cpg-mssr.c b/drivers/clk/renesas/r8a77470-cpg-mssr.c new file mode 100644 index 000000000000..ab0fb10b6bf0 --- /dev/null +++ b/drivers/clk/renesas/r8a77470-cpg-mssr.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a77470 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen2-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A77470_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_USB_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL1_DIV2, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a77470_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("usb_extal", CLK_USB_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + + /* Core Clock Outputs */ + DEF_BASE("sdh", R8A77470_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), + DEF_BASE("sd0", R8A77470_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), + DEF_BASE("sd1", R8A77470_CLK_SD1, CLK_TYPE_GEN2_SD1, CLK_PLL1), + DEF_BASE("qspi", R8A77470_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), + DEF_BASE("rcan", R8A77470_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL), + + DEF_FIXED("z2", R8A77470_CLK_Z2, CLK_PLL0, 1, 1), + DEF_FIXED("zx", R8A77470_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("zs", R8A77470_CLK_ZS, CLK_PLL1, 6, 1), + DEF_FIXED("hp", R8A77470_CLK_HP, CLK_PLL1, 12, 1), + DEF_FIXED("b", R8A77470_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("lb", R8A77470_CLK_LB, CLK_PLL1, 24, 1), + DEF_FIXED("p", R8A77470_CLK_P, CLK_PLL1, 24, 1), + DEF_FIXED("cl", R8A77470_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cp", R8A77470_CLK_CP, CLK_PLL1, 48, 1), + DEF_FIXED("m2", R8A77470_CLK_M2, CLK_PLL1, 8, 1), + DEF_FIXED("zb3", R8A77470_CLK_ZB3, CLK_PLL3, 4, 1), + DEF_FIXED("mp", R8A77470_CLK_MP, CLK_PLL1_DIV2, 15, 1), + DEF_FIXED("cpex", R8A77470_CLK_CPEX, CLK_EXTAL, 2, 1), + DEF_FIXED("r", R8A77470_CLK_R, CLK_PLL1, 49152, 1), + DEF_FIXED("osc", R8A77470_CLK_OSC, CLK_PLL1, 12288, 1), + + DEF_DIV6P1("sd2", R8A77470_CLK_SD2, CLK_PLL1_DIV2, 0x078), +}; + +static const struct mssr_mod_clk r8a77470_mod_clks[] __initconst = { + DEF_MOD("msiof0", 0, R8A77470_CLK_MP), + DEF_MOD("vcp0", 101, R8A77470_CLK_ZS), + DEF_MOD("vpc0", 103, R8A77470_CLK_ZS), + DEF_MOD("tmu1", 111, R8A77470_CLK_P), + DEF_MOD("3dg", 112, R8A77470_CLK_ZS), + DEF_MOD("2d-dmac", 115, R8A77470_CLK_ZS), + DEF_MOD("fdp1-0", 119, R8A77470_CLK_ZS), + DEF_MOD("tmu3", 121, R8A77470_CLK_P), + DEF_MOD("tmu2", 122, R8A77470_CLK_P), + DEF_MOD("cmt0", 124, R8A77470_CLK_R), + DEF_MOD("vsp1du0", 128, R8A77470_CLK_ZS), + DEF_MOD("vsp1-sy", 131, R8A77470_CLK_ZS), + DEF_MOD("msiof2", 205, R8A77470_CLK_MP), + DEF_MOD("msiof1", 208, R8A77470_CLK_MP), + DEF_MOD("sys-dmac1", 218, R8A77470_CLK_ZS), + DEF_MOD("sys-dmac0", 219, R8A77470_CLK_ZS), + DEF_MOD("sdhi2", 312, R8A77470_CLK_SD2), + DEF_MOD("sdhi1", 313, R8A77470_CLK_SD1), + DEF_MOD("sdhi0", 314, R8A77470_CLK_SD0), + DEF_MOD("usbhs-dmac0-ch1", 326, R8A77470_CLK_HP), + DEF_MOD("usbhs-dmac1-ch1", 327, R8A77470_CLK_HP), + DEF_MOD("cmt1", 329, R8A77470_CLK_R), + DEF_MOD("usbhs-dmac0-ch0", 330, R8A77470_CLK_HP), + DEF_MOD("usbhs-dmac1-ch0", 331, R8A77470_CLK_HP), + DEF_MOD("rwdt", 402, R8A77470_CLK_R), + DEF_MOD("irqc", 407, R8A77470_CLK_CP), + DEF_MOD("intc-sys", 408, R8A77470_CLK_ZS), + DEF_MOD("audio-dmac0", 502, R8A77470_CLK_HP), + DEF_MOD("pwm", 523, R8A77470_CLK_P), + DEF_MOD("usb-ehci-0", 703, R8A77470_CLK_MP), + DEF_MOD("usbhs-0", 704, R8A77470_CLK_HP), + DEF_MOD("usb-ehci-1", 705, R8A77470_CLK_MP), + DEF_MOD("usbhs-1", 706, R8A77470_CLK_HP), + DEF_MOD("hscif2", 713, R8A77470_CLK_ZS), + DEF_MOD("scif5", 714, R8A77470_CLK_P), + DEF_MOD("scif4", 715, R8A77470_CLK_P), + DEF_MOD("hscif1", 716, R8A77470_CLK_ZS), + DEF_MOD("hscif0", 717, R8A77470_CLK_ZS), + DEF_MOD("scif3", 718, R8A77470_CLK_P), + DEF_MOD("scif2", 719, R8A77470_CLK_P), + DEF_MOD("scif1", 720, R8A77470_CLK_P), + DEF_MOD("scif0", 721, R8A77470_CLK_P), + DEF_MOD("du1", 723, R8A77470_CLK_ZX), + DEF_MOD("du0", 724, R8A77470_CLK_ZX), + DEF_MOD("ipmmu-sgx", 800, R8A77470_CLK_ZX), + DEF_MOD("etheravb", 812, R8A77470_CLK_HP), + DEF_MOD("ether", 813, R8A77470_CLK_P), + DEF_MOD("gpio5", 907, R8A77470_CLK_CP), + DEF_MOD("gpio4", 908, R8A77470_CLK_CP), + DEF_MOD("gpio3", 909, R8A77470_CLK_CP), + DEF_MOD("gpio2", 910, R8A77470_CLK_CP), + DEF_MOD("gpio1", 911, R8A77470_CLK_CP), + DEF_MOD("gpio0", 912, R8A77470_CLK_CP), + DEF_MOD("can1", 915, R8A77470_CLK_P), + DEF_MOD("can0", 916, R8A77470_CLK_P), + DEF_MOD("qspi_mod-1", 917, R8A77470_CLK_QSPI), + DEF_MOD("qspi_mod-0", 918, R8A77470_CLK_QSPI), + DEF_MOD("i2c4", 927, R8A77470_CLK_HP), + DEF_MOD("i2c3", 928, R8A77470_CLK_HP), + DEF_MOD("i2c2", 929, R8A77470_CLK_HP), + DEF_MOD("i2c1", 930, R8A77470_CLK_HP), + DEF_MOD("i2c0", 931, R8A77470_CLK_HP), + DEF_MOD("ssi-all", 1005, R8A77470_CLK_P), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A77470_CLK_P), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a77470_crit_mod_clks[] __initconst = { + MOD_CLK_ID(402), /* RWDT */ + MOD_CLK_ID(408), /* INTC-SYS (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 (MHz) *1 *2 + *--------------------------------------------------- + * 0 0 20 x80 x78 x50 + * 0 1 26 x60 x60 x56 + * 1 0 Prohibitted setting + * 1 1 30 x52 x52 x50 + * + * *1 : Table 7.4 indicates VCO output (PLL0 = VCO) + * *2 : Table 7.4 indicates VCO output (PLL1 = VCO) + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \ + (((md) & BIT(13)) >> 13)) + +static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[4] __initconst = { + /* EXTAL div PLL1 mult x2 PLL3 mult */ + { 1, 156, 50, }, + { 1, 120, 56, }, + { /* Invalid*/ }, + { 1, 104, 50, }, +}; + +static int __init r8a77470_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen2_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode); +} + +const struct cpg_mssr_info r8a77470_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a77470_core_clks, + .num_core_clks = ARRAY_SIZE(r8a77470_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a77470_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a77470_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a77470_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a77470_crit_mod_clks), + + /* Callbacks */ + .init = r8a77470_cpg_mssr_init, + .cpg_clk_register = rcar_gen2_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index feb14579a71b..0c49f59d5074 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "renesas-cpg-mssr.h" #include "rcar-gen2-cpg.h" @@ -261,6 +262,11 @@ static const struct rcar_gen2_cpg_pll_config *cpg_pll_config __initdata; static unsigned int cpg_pll0_div __initdata; static u32 cpg_mode __initdata; +static const struct soc_device_attribute soc_r8a77470[] = { + { .soc_id = "r8a77470" }, + { /* sentinel */ } +}; + struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, struct clk **clks, void __iomem *base, @@ -327,11 +333,17 @@ struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN2_SD0: table = cpg_sd01_div_table; + if (soc_device_match(soc_r8a77470)) + table++; + shift = 4; break; case CLK_TYPE_GEN2_SD1: table = cpg_sd01_div_table; + if (soc_device_match(soc_r8a77470)) + table++; + shift = 0; break; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 4e88e980fb76..2c467f96a94a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -652,6 +652,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a7745_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A77470 + { + .compatible = "renesas,r8a77470-cpg-mssr", + .data = &r8a77470_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7790 { .compatible = "renesas,r8a7790-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 97ccb093c10f..efe2a149acce 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -133,6 +133,7 @@ struct cpg_mssr_info { extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; +extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; -- cgit v1.2.3 From 2c2557e3901e861c78020a3bb202dffc264119cf Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Mar 2018 10:59:14 +0200 Subject: clk: renesas: r8a7743: Fix LB clock divider The CLK_TYPE_GEN2_LB clock type is meant for SoCs like R-Car H2, where the LB clock divider depends on the value of the MD18 pin. On RZ/G1M, the LB clock divider is fixed to 24. Hence model the clock as a fixed factor clock instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Reviewed-by: Fabrizio Castro --- drivers/clk/renesas/r8a7743-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/r8a7743-cpg-mssr.c b/drivers/clk/renesas/r8a7743-cpg-mssr.c index d3c8b1e2969f..011c170ec3f9 100644 --- a/drivers/clk/renesas/r8a7743-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7743-cpg-mssr.c @@ -52,7 +52,6 @@ static const struct cpg_core_clk r8a7743_core_clks[] __initconst = { /* Core Clock Outputs */ DEF_BASE("z", R8A7743_CLK_Z, CLK_TYPE_GEN2_Z, CLK_PLL0), - DEF_BASE("lb", R8A7743_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), DEF_BASE("sdh", R8A7743_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), DEF_BASE("sd0", R8A7743_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), DEF_BASE("qspi", R8A7743_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), @@ -63,6 +62,7 @@ static const struct cpg_core_clk r8a7743_core_clks[] __initconst = { DEF_FIXED("zs", R8A7743_CLK_ZS, CLK_PLL1, 6, 1), DEF_FIXED("hp", R8A7743_CLK_HP, CLK_PLL1, 12, 1), DEF_FIXED("b", R8A7743_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("lb", R8A7743_CLK_LB, CLK_PLL1, 24, 1), DEF_FIXED("p", R8A7743_CLK_P, CLK_PLL1, 24, 1), DEF_FIXED("cl", R8A7743_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("m2", R8A7743_CLK_M2, CLK_PLL1, 8, 1), -- cgit v1.2.3 From 83fab8ea62ca74eaa51613ba8eeaf925f4f8087c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Mar 2018 11:01:47 +0200 Subject: clk: renesas: r8a7745: Fix LB clock divider The CLK_TYPE_GEN2_LB clock type is meant for SoCs like R-Car H2, where the LB clock divider depends on the value of the MD18 pin. On RZ/G1E, the LB clock divider is fixed to 24. Hence model the clock as a fixed factor clock instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Reviewed-by: Fabrizio Castro --- drivers/clk/renesas/r8a7745-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/r8a7745-cpg-mssr.c b/drivers/clk/renesas/r8a7745-cpg-mssr.c index 87f5a3619e4f..4b0a9243b748 100644 --- a/drivers/clk/renesas/r8a7745-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7745-cpg-mssr.c @@ -51,7 +51,6 @@ static const struct cpg_core_clk r8a7745_core_clks[] __initconst = { DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), /* Core Clock Outputs */ - DEF_BASE("lb", R8A7745_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), DEF_BASE("sdh", R8A7745_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), DEF_BASE("sd0", R8A7745_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), DEF_BASE("qspi", R8A7745_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), @@ -63,6 +62,7 @@ static const struct cpg_core_clk r8a7745_core_clks[] __initconst = { DEF_FIXED("zs", R8A7745_CLK_ZS, CLK_PLL1, 6, 1), DEF_FIXED("hp", R8A7745_CLK_HP, CLK_PLL1, 12, 1), DEF_FIXED("b", R8A7745_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("lb", R8A7745_CLK_LB, CLK_PLL1, 24, 1), DEF_FIXED("p", R8A7745_CLK_P, CLK_PLL1, 24, 1), DEF_FIXED("cl", R8A7745_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("cp", R8A7745_CLK_CP, CLK_PLL1, 48, 1), -- cgit v1.2.3 From 6041ce57f2c8c231017a1b4f7a71b606bb1c1016 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Mar 2018 11:02:18 +0200 Subject: clk: renesas: r8a7791/r8a7793: Fix LB clock divider The CLK_TYPE_GEN2_LB clock type is meant for SoCs like R-Car H2, where the LB clock divider depends on the value of the MD18 pin. On R-Car M2-W and M2-N, the LB clock divider is fixed to 24. Hence model the clock as a fixed factor clock instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Reviewed-by: Fabrizio Castro --- drivers/clk/renesas/r8a7791-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c index 820b220b09cc..1b91f03b7598 100644 --- a/drivers/clk/renesas/r8a7791-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c @@ -57,7 +57,6 @@ static struct cpg_core_clk r8a7791_core_clks[] __initdata = { /* Core Clock Outputs */ DEF_BASE("z", R8A7791_CLK_Z, CLK_TYPE_GEN2_Z, CLK_PLL0), - DEF_BASE("lb", R8A7791_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), DEF_BASE("adsp", R8A7791_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1), DEF_BASE("sdh", R8A7791_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), DEF_BASE("sd0", R8A7791_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), @@ -70,6 +69,7 @@ static struct cpg_core_clk r8a7791_core_clks[] __initdata = { DEF_FIXED("hp", R8A7791_CLK_HP, CLK_PLL1, 12, 1), DEF_FIXED("i", R8A7791_CLK_I, CLK_PLL1, 2, 1), DEF_FIXED("b", R8A7791_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("lb", R8A7791_CLK_LB, CLK_PLL1, 24, 1), DEF_FIXED("p", R8A7791_CLK_P, CLK_PLL1, 24, 1), DEF_FIXED("cl", R8A7791_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("m2", R8A7791_CLK_M2, CLK_PLL1, 8, 1), -- cgit v1.2.3 From 0873305e68ac2a4665f1f3d27bb0b98a4312e5bd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Mar 2018 11:02:42 +0200 Subject: clk: renesas: r8a7792: Fix LB clock divider The CLK_TYPE_GEN2_LB clock type is meant for SoCs like R-Car H2, where the LB clock divider depends on the value of the MD18 pin. On R-Car V2H, the LB clock divider is fixed to 24. Hence model the clock as a fixed factor clock instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Reviewed-by: Fabrizio Castro --- drivers/clk/renesas/r8a7792-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c index 609a54080496..493e07859f5f 100644 --- a/drivers/clk/renesas/r8a7792-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c @@ -53,7 +53,6 @@ static const struct cpg_core_clk r8a7792_core_clks[] __initconst = { DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), /* Core Clock Outputs */ - DEF_BASE("lb", R8A7792_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), DEF_BASE("qspi", R8A7792_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2), DEF_FIXED("z", R8A7792_CLK_Z, CLK_PLL0, 1, 1), @@ -63,6 +62,7 @@ static const struct cpg_core_clk r8a7792_core_clks[] __initconst = { DEF_FIXED("hp", R8A7792_CLK_HP, CLK_PLL1, 12, 1), DEF_FIXED("i", R8A7792_CLK_I, CLK_PLL1, 3, 1), DEF_FIXED("b", R8A7792_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("lb", R8A7792_CLK_LB, CLK_PLL1, 24, 1), DEF_FIXED("p", R8A7792_CLK_P, CLK_PLL1, 24, 1), DEF_FIXED("cl", R8A7792_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("m2", R8A7792_CLK_M2, CLK_PLL1, 8, 1), -- cgit v1.2.3 From 279ebbcae5a1298433c1b4f9425c89897d017cc0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Mar 2018 11:03:00 +0200 Subject: clk: renesas: r8a7794: Fix LB clock divider The CLK_TYPE_GEN2_LB clock type is meant for SoCs like R-Car H2, where the LB clock divider depends on the value of the MD18 pin. On R-Car E2, the LB clock divider is fixed to 24. Hence model the clock as a fixed factor clock instead. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Reviewed-by: Fabrizio Castro --- drivers/clk/renesas/r8a7794-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c index 2a40bbeaeeaf..088f4b79fdfc 100644 --- a/drivers/clk/renesas/r8a7794-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c @@ -55,7 +55,6 @@ static const struct cpg_core_clk r8a7794_core_clks[] __initconst = { DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), /* Core Clock Outputs */ - DEF_BASE("lb", R8A7794_CLK_LB, CLK_TYPE_GEN2_LB, CLK_PLL1), DEF_BASE("adsp", R8A7794_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1), DEF_BASE("sdh", R8A7794_CLK_SDH, CLK_TYPE_GEN2_SDH, CLK_PLL1), DEF_BASE("sd0", R8A7794_CLK_SD0, CLK_TYPE_GEN2_SD0, CLK_PLL1), @@ -69,6 +68,7 @@ static const struct cpg_core_clk r8a7794_core_clks[] __initconst = { DEF_FIXED("hp", R8A7794_CLK_HP, CLK_PLL1, 12, 1), DEF_FIXED("i", R8A7794_CLK_I, CLK_PLL1, 2, 1), DEF_FIXED("b", R8A7794_CLK_B, CLK_PLL1, 12, 1), + DEF_FIXED("lb", R8A7794_CLK_LB, CLK_PLL1, 24, 1), DEF_FIXED("p", R8A7794_CLK_P, CLK_PLL1, 24, 1), DEF_FIXED("cl", R8A7794_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("cp", R8A7794_CLK_CP, CLK_PLL1, 48, 1), -- cgit v1.2.3 From 246e232437e5a045792aee95b2f9c7718516596c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 9 Apr 2018 13:50:41 +0200 Subject: clk: renesas: r8a77980: Correct parent clock of PCIEC0 According to the R-Car Gen3 Hardware Manual Errata for Rev 0.80 of December 22, 2017, the parent clock of the PCIe module clock on R-Car V3H is S2D2. Fixes: ce15783c510a9905 ("clk: renesas: cpg-mssr: add R8A77980 support") Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77980-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c index 7aaae73a321a..d7ebd9ec0059 100644 --- a/drivers/clk/renesas/r8a77980-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c @@ -116,7 +116,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = { DEF_MOD("sys-dmac1", 218, R8A77980_CLK_S0D3), DEF_MOD("tpu0", 304, R8A77980_CLK_S3D4), DEF_MOD("sdif", 314, R8A77980_CLK_SD0), - DEF_MOD("pciec0", 319, R8A77980_CLK_S3D1), + DEF_MOD("pciec0", 319, R8A77980_CLK_S2D2), DEF_MOD("intc-ex", 407, R8A77980_CLK_CP), DEF_MOD("intc-ap", 408, R8A77980_CLK_S0D3), DEF_MOD("hscif3", 517, R8A77980_CLK_S3D1), -- cgit v1.2.3 From a34f778cb89a8554a5d1f5a75b297c07c672afce Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Mar 2018 10:56:56 +0200 Subject: clk: renesas: rcar-gen2: Centralize quirks handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce centralized quirks handling like on R-Car Gen3, and convert the RZ/G1C SD clock table handling over to it. This makes it easier to add more quirks later, if/when needed. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Reviewed-by: Biju Das --- drivers/clk/renesas/rcar-gen2-cpg.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index 0c49f59d5074..daf88bc2cdae 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -261,9 +261,15 @@ static const struct clk_div_table cpg_sd01_div_table[] = { static const struct rcar_gen2_cpg_pll_config *cpg_pll_config __initdata; static unsigned int cpg_pll0_div __initdata; static u32 cpg_mode __initdata; +static u32 cpg_quirks __initdata; -static const struct soc_device_attribute soc_r8a77470[] = { - { .soc_id = "r8a77470" }, +#define SD_SKIP_FIRST BIT(0) /* Skip first clock in SD table */ + +static const struct soc_device_attribute cpg_quirks_match[] __initconst = { + { + .soc_id = "r8a77470", + .data = (void *)SD_SKIP_FIRST, + }, { /* sentinel */ } }; @@ -333,7 +339,7 @@ struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN2_SD0: table = cpg_sd01_div_table; - if (soc_device_match(soc_r8a77470)) + if (cpg_quirks & SD_SKIP_FIRST) table++; shift = 4; @@ -341,7 +347,7 @@ struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN2_SD1: table = cpg_sd01_div_table; - if (soc_device_match(soc_r8a77470)) + if (cpg_quirks & SD_SKIP_FIRST) table++; shift = 0; @@ -372,9 +378,15 @@ struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, int __init rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config, unsigned int pll0_div, u32 mode) { + const struct soc_device_attribute *attr; + cpg_pll_config = config; cpg_pll0_div = pll0_div; cpg_mode = mode; + attr = soc_device_match(cpg_quirks_match); + if (attr) + cpg_quirks = (uintptr_t)attr->data; + pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks); spin_lock_init(&cpg_lock); -- cgit v1.2.3 From 3570a2af473789c5d5f5b9e04f72295102967824 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 20 Apr 2018 21:27:44 +0900 Subject: clk: renesas: cpg-mssr: Add support for R-Car E3 Initial support for R-Car E3 (r8a77990), including core and module clocks. Based on the Table 8.2g of "R-Car Series, 3rd Generation User's Manual: Hardware ((Rev. 0.80, Oct 31, 2017) with Manual Errata on Feb. 28, 2018". Inspried by patches by Takeshi Kihara in the BSP. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a77990-cpg-mssr.c | 289 ++++++++++++++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 5 files changed, 302 insertions(+) create mode 100644 drivers/clk/renesas/r8a77990-cpg-mssr.c (limited to 'drivers/clk') diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index f32896fa9dda..f9ba71311727 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -19,6 +19,7 @@ config CLK_RENESAS select CLK_R8A77965 if ARCH_R8A77965 select CLK_R8A77970 if ARCH_R8A77970 select CLK_R8A77980 if ARCH_R8A77980 + select CLK_R8A77990 if ARCH_R8A77990 select CLK_R8A77995 if ARCH_R8A77995 select CLK_SH73A0 if ARCH_SH73A0 @@ -116,6 +117,10 @@ config CLK_R8A77980 bool "R-Car V3H clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A77990 + bool "R-Car E3 clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A77995 bool "R-Car D3 clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index a4edea99c4ec..fe5bac9215e5 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o obj-$(CONFIG_CLK_R8A77965) += r8a77965-cpg-mssr.o obj-$(CONFIG_CLK_R8A77970) += r8a77970-cpg-mssr.o obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c new file mode 100644 index 000000000000..9e14f1486fbb --- /dev/null +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a77990 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2015 Renesas Electronics Corp. + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A77990_CLK_CPEX, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL0D4, + CLK_PLL0D6, + CLK_PLL0D8, + CLK_PLL0D20, + CLK_PLL0D24, + CLK_PLL1D2, + CLK_PE, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a77990_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + + DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 1, 100), + DEF_FIXED(".pll0d4", CLK_PLL0D4, CLK_PLL0, 4, 1), + DEF_FIXED(".pll0d6", CLK_PLL0D6, CLK_PLL0, 6, 1), + DEF_FIXED(".pll0d8", CLK_PLL0D8, CLK_PLL0, 8, 1), + DEF_FIXED(".pll0d20", CLK_PLL0D20, CLK_PLL0, 20, 1), + DEF_FIXED(".pll0d24", CLK_PLL0D24, CLK_PLL0, 24, 1), + DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1), + DEF_FIXED(".pe", CLK_PE, CLK_PLL0D20, 1, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), + + /* Core Clock Outputs */ + DEF_FIXED("za2", R8A77990_CLK_ZA2, CLK_PLL0D24, 1, 1), + DEF_FIXED("za8", R8A77990_CLK_ZA8, CLK_PLL0D8, 1, 1), + DEF_FIXED("ztr", R8A77990_CLK_ZTR, CLK_PLL1, 6, 1), + DEF_FIXED("zt", R8A77990_CLK_ZT, CLK_PLL1, 4, 1), + DEF_FIXED("zx", R8A77990_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("s0d1", R8A77990_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d3", R8A77990_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d6", R8A77990_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d12", R8A77990_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s0d24", R8A77990_CLK_S0D24, CLK_S0, 24, 1), + DEF_FIXED("s1d1", R8A77990_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A77990_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A77990_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A77990_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A77990_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A77990_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A77990_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A77990_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A77990_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A77990_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A77990_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd3", R8A77990_CLK_SD3, CLK_SDSRC, 0x026c), + + DEF_FIXED("cl", R8A77990_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cp", R8A77990_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A77990_CLK_CPEX, CLK_EXTAL, 4, 1), + DEF_FIXED("osc", R8A77990_CLK_OSC, CLK_EXTAL, 384, 1), + DEF_FIXED("r", R8A77990_CLK_R, CLK_EXTAL, 1536, 1), + + DEF_GEN3_PE("s0d6c", R8A77990_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2), + DEF_GEN3_PE("s3d1c", R8A77990_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), + DEF_GEN3_PE("s3d2c", R8A77990_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), + DEF_GEN3_PE("s3d4c", R8A77990_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), + + DEF_DIV6P1("canfd", R8A77990_CLK_CANFD, CLK_PLL0D6, 0x244), + DEF_DIV6P1("csi0", R8A77990_CLK_CSI0, CLK_PLL1D2, 0x00c), + DEF_DIV6P1("mso", R8A77990_CLK_MSO, CLK_PLL1D2, 0x014), +}; + +static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = { + DEF_MOD("scif5", 202, R8A77990_CLK_S3D4C), + DEF_MOD("scif4", 203, R8A77990_CLK_S3D4C), + DEF_MOD("scif3", 204, R8A77990_CLK_S3D4C), + DEF_MOD("scif1", 206, R8A77990_CLK_S3D4C), + DEF_MOD("scif0", 207, R8A77990_CLK_S3D4C), + DEF_MOD("msiof3", 208, R8A77990_CLK_MSO), + DEF_MOD("msiof2", 209, R8A77990_CLK_MSO), + DEF_MOD("msiof1", 210, R8A77990_CLK_MSO), + DEF_MOD("msiof0", 211, R8A77990_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A77990_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A77990_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A77990_CLK_S3D1), + + DEF_MOD("cmt3", 300, R8A77990_CLK_R), + DEF_MOD("cmt2", 301, R8A77990_CLK_R), + DEF_MOD("cmt1", 302, R8A77990_CLK_R), + DEF_MOD("cmt0", 303, R8A77990_CLK_R), + DEF_MOD("scif2", 310, R8A77990_CLK_S3D4C), + DEF_MOD("sdif3", 311, R8A77990_CLK_SD3), + DEF_MOD("sdif1", 313, R8A77990_CLK_SD1), + DEF_MOD("sdif0", 314, R8A77990_CLK_SD0), + DEF_MOD("pcie0", 319, R8A77990_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A77990_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A77990_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A77990_CLK_S3D1), + + DEF_MOD("rwdt", 402, R8A77990_CLK_R), + DEF_MOD("intc-ex", 407, R8A77990_CLK_CP), + DEF_MOD("intc-ap", 408, R8A77990_CLK_S0D3), + + DEF_MOD("audmac0", 502, R8A77990_CLK_S3D4), + DEF_MOD("drif7", 508, R8A77990_CLK_S3D2), + DEF_MOD("drif6", 509, R8A77990_CLK_S3D2), + DEF_MOD("drif5", 510, R8A77990_CLK_S3D2), + DEF_MOD("drif4", 511, R8A77990_CLK_S3D2), + DEF_MOD("drif3", 512, R8A77990_CLK_S3D2), + DEF_MOD("drif2", 513, R8A77990_CLK_S3D2), + DEF_MOD("drif1", 514, R8A77990_CLK_S3D2), + DEF_MOD("drif0", 515, R8A77990_CLK_S3D2), + DEF_MOD("hscif4", 516, R8A77990_CLK_S3D1C), + DEF_MOD("hscif3", 517, R8A77990_CLK_S3D1C), + DEF_MOD("hscif2", 518, R8A77990_CLK_S3D1C), + DEF_MOD("hscif1", 519, R8A77990_CLK_S3D1C), + DEF_MOD("hscif0", 520, R8A77990_CLK_S3D1C), + DEF_MOD("thermal", 522, R8A77990_CLK_CP), + DEF_MOD("pwm", 523, R8A77990_CLK_S3D4C), + + DEF_MOD("fcpvd1", 602, R8A77990_CLK_S1D2), + DEF_MOD("fcpvd0", 603, R8A77990_CLK_S1D2), + DEF_MOD("fcpvb0", 607, R8A77990_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A77990_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A77990_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A77990_CLK_S0D1), + DEF_MOD("vspd1", 622, R8A77990_CLK_S1D2), + DEF_MOD("vspd0", 623, R8A77990_CLK_S1D2), + DEF_MOD("vspb", 626, R8A77990_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A77990_CLK_S0D1), + + DEF_MOD("ehci0", 703, R8A77990_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A77990_CLK_S3D4), + DEF_MOD("csi40", 716, R8A77990_CLK_CSI0), + DEF_MOD("du1", 723, R8A77990_CLK_S2D1), + DEF_MOD("du0", 724, R8A77990_CLK_S2D1), + DEF_MOD("lvds", 727, R8A77990_CLK_S2D1), + + DEF_MOD("vin5", 806, R8A77990_CLK_S1D2), + DEF_MOD("vin4", 807, R8A77990_CLK_S1D2), + DEF_MOD("etheravb", 812, R8A77990_CLK_S3D2), + + DEF_MOD("gpio6", 906, R8A77990_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A77990_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A77990_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A77990_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A77990_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A77990_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A77990_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A77990_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A77990_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A77990_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A77990_CLK_S3D2), + DEF_MOD("i2c5", 919, R8A77990_CLK_S3D2), + DEF_MOD("i2c-dvfs", 926, R8A77990_CLK_CP), + DEF_MOD("i2c4", 927, R8A77990_CLK_S3D2), + DEF_MOD("i2c3", 928, R8A77990_CLK_S3D2), + DEF_MOD("i2c2", 929, R8A77990_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A77990_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A77990_CLK_S3D2), + + DEF_MOD("ssi-all", 1005, R8A77990_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A77990_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a77990_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 + *-------------------------------------------------------------------- + * 0 48 x 1 x100/4 x100/3 x100/3 + * 1 48 x 1 x100/4 x100/3 x58/3 + */ +#define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 100, 3, 100, 3, }, + { 1, 100, 3, 58, 3, }, +}; + +static int __init r8a77990_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode); +} + +const struct cpg_mssr_info r8a77990_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a77990_core_clks, + .num_core_clks = ARRAY_SIZE(r8a77990_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a77990_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a77990_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a77990_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a77990_crit_mod_clks), + + /* Callbacks */ + .init = r8a77990_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 2c467f96a94a..49e510691eee 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -717,6 +717,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a77980_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A77990 + { + .compatible = "renesas,r8a77990-cpg-mssr", + .data = &r8a77990_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A77995 { .compatible = "renesas,r8a77995-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index efe2a149acce..642f720b9b05 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -143,6 +143,7 @@ extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; extern const struct cpg_mssr_info r8a77965_cpg_mssr_info; extern const struct cpg_mssr_info r8a77970_cpg_mssr_info; extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; +extern const struct cpg_mssr_info r8a77990_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; -- cgit v1.2.3 From b8c1ddadc8155831bae6fed85204221eff203f9e Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 23 Apr 2018 21:35:09 +0200 Subject: clk: meson: meson8b: add support for the NAND clocks This adds the NAND clocks (from the HHI_NAND_CLK_CNTL register) to the Meson8b clock driver. There are three NAND clocks: a gate which enables or disables the NAND clock, a mux and a divider (which divides the mux output). Unfortunately the public S805 datasheet does not document the mux parents. However, the vendor kernel has a few hints for us which allows us to make an educated guess about the clock parents. To do this we need to have a look at set_nand_core_clk() from the vendor's NAND driver (see [0]): - XTAL = (4<<9) | (1<<8) | 0 - 160MHz = (0<<9) | (1<<8) | 3) - 182MHz = (3<<9) | (1<<8) | 1) - 212MHz = (1<<9) | (1<<8) | 3) - 255MHz = (2<<9) | (1<<8) | 1) While there is a comment for the XTAL parent (which indicates that it should only be used for debugging) we have to do a bit of math for the other parents: target_freq * divider = rate of parent clock Bit 8 above is the enable bit, so we can ignore it here. Bits 11:9 are the mux index and bits 6:0 are the 0-based divider (so we need to add 1). This gives us: - mux 0 (160MHz * 4) = fclk_div4 (actual rate = 637.5MHz, off by 2.5MHz) - mux 1 (212MHz * 4) = fclk_div3 (actual rate = 850MHz, off by 2MHz) - mux 2 (255MHz * 2) = fclk_div5 (matches exactly 510MHz) - mux 3 (182MHz * 2) = fclk_div7 (actual rate = 346.3MHz, off by 0.3MHz) [0] https://github.com/khadas/linux/blob/9587681285cb/drivers/amlogic/amlnf/dev/amlnf_ctrl.c#L314 Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ drivers/clk/meson/meson8b.h | 5 ++++- 2 files changed, 58 insertions(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index cc2992493e0b..e6e9a9db1095 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -639,6 +639,54 @@ static struct clk_regmap meson8b_cpu_clk = { }, }; +static struct clk_regmap meson8b_nand_clk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_NAND_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "nand_clk_sel", + .ops = &clk_regmap_mux_ops, + /* FIXME all other parents are unknown: */ + .parent_names = (const char *[]){ "fclk_div4", "fclk_div3", + "fclk_div5", "fclk_div7", "xtal" }, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_nand_clk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_NAND_CLK_CNTL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "nand_clk_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "nand_clk_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_nand_clk_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_NAND_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "nand_clk_gate", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "nand_clk_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); @@ -834,6 +882,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw, [CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw, [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw, + [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, + [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, + [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -939,6 +990,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_fclk_div4, &meson8b_fclk_div5, &meson8b_fclk_div7, + &meson8b_nand_clk_sel, + &meson8b_nand_clk_div, + &meson8b_nand_clk_gate, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index 6e414bd36981..a687dc60b6d0 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -40,6 +40,7 @@ #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ #define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ +#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */ #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ @@ -83,8 +84,10 @@ #define CLKID_FCLK_DIV4_DIV 107 #define CLKID_FCLK_DIV5_DIV 108 #define CLKID_FCLK_DIV7_DIV 109 +#define CLKID_NAND_SEL 110 +#define CLKID_NAND_DIV 111 -#define CLK_NR_CLKS 110 +#define CLK_NR_CLKS 113 /* * include the CLKID and RESETID that have -- cgit v1.2.3 From a565242eb9fca13051ec374b427022a0e22421cf Mon Sep 17 00:00:00 2001 From: Maxime Jourdan Date: Tue, 24 Apr 2018 20:48:38 +0200 Subject: clk: meson: gxbb: add the video decoder clocks Add the SEL/DIV/GATE for VDEC_1 and VDEC_HEVC. Signed-off-by: Maxime Jourdan Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/clk/meson/gxbb.h | 6 ++- 2 files changed, 119 insertions(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index b1e4d9557610..a893b1edda22 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -1543,6 +1543,102 @@ static struct clk_regmap gxbb_vapb = { }, }; +/* VDEC clocks */ + +static const char * const gxbb_vdec_parent_names[] = { + "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +}; + +static struct clk_regmap gxbb_vdec_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC_CLK_CNTL, + .mask = 0x3, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = gxbb_vdec_parent_names, + .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_vdec_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC_CLK_CNTL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_1_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "vdec_1_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_vdec_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_1", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "vdec_1_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_vdec_hevc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .mask = 0x3, + .shift = 25, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevc_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = gxbb_vdec_parent_names, + .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_vdec_hevc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevc_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "vdec_hevc_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_vdec_hevc = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_hevc", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "vdec_hevc_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); @@ -1786,6 +1882,12 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { [CLKID_FCLK_DIV4_DIV] = &gxbb_fclk_div4_div.hw, [CLKID_FCLK_DIV5_DIV] = &gxbb_fclk_div5_div.hw, [CLKID_FCLK_DIV7_DIV] = &gxbb_fclk_div7_div.hw, + [CLKID_VDEC_1_SEL] = &gxbb_vdec_1_sel.hw, + [CLKID_VDEC_1_DIV] = &gxbb_vdec_1_div.hw, + [CLKID_VDEC_1] = &gxbb_vdec_1.hw, + [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, + [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, + [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -1942,6 +2044,12 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_FCLK_DIV4_DIV] = &gxbb_fclk_div4_div.hw, [CLKID_FCLK_DIV5_DIV] = &gxbb_fclk_div5_div.hw, [CLKID_FCLK_DIV7_DIV] = &gxbb_fclk_div7_div.hw, + [CLKID_VDEC_1_SEL] = &gxbb_vdec_1_sel.hw, + [CLKID_VDEC_1_DIV] = &gxbb_vdec_1_div.hw, + [CLKID_VDEC_1] = &gxbb_vdec_1.hw, + [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, + [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, + [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -2100,6 +2208,12 @@ static struct clk_regmap *const gx_clk_regmaps[] = { &gxbb_fclk_div4, &gxbb_fclk_div5, &gxbb_fclk_div7, + &gxbb_vdec_1_sel, + &gxbb_vdec_1_div, + &gxbb_vdec_1, + &gxbb_vdec_hevc_sel, + &gxbb_vdec_hevc_div, + &gxbb_vdec_hevc, }; struct clkc_data { diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index 9febf3f03739..b3ef54f65a9d 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -204,8 +204,12 @@ #define CLKID_FCLK_DIV4_DIV 148 #define CLKID_FCLK_DIV5_DIV 149 #define CLKID_FCLK_DIV7_DIV 150 +#define CLKID_VDEC_1_SEL 151 +#define CLKID_VDEC_1_DIV 152 +#define CLKID_VDEC_HEVC_SEL 154 +#define CLKID_VDEC_HEVC_DIV 155 -#define NR_CLKS 151 +#define NR_CLKS 157 /* include the CLKIDs that have been made part of the DT binding */ #include -- cgit v1.2.3 From bdfa6394c229e05f78970242e63d660441dc0a17 Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Thu, 26 Apr 2018 16:44:31 +0800 Subject: clk: meson: migrate to devm_of_clk_add_hw_provider API There is a protential memory leak, as of_clk_del_provider is never called if of_clk_add_hw_provider has been executed. Fix this by using devm variant API. Fixes: f8c11f79912d ("clk: meson: Add GXBB AO Clock and Reset controller driver") Suggested-by: Stephen Boyd Signed-off-by: Yixun Lan Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb-aoclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 9ec23ae9a219..eebb580b9e0f 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -191,7 +191,7 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) if (ret) return ret; - return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &gxbb_aoclk_onecell_data); } -- cgit v1.2.3 From 88e2da81241e2ca678b37a194c454888f243914b Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Thu, 3 May 2018 21:26:20 +0800 Subject: clk: meson: aoclk: refactor common code into dedicated file We try to refactor the common code into one dedicated file, while preparing to add new Meson-AXG aoclk driver, this would help us to better share the code by all aoclk drivers. Suggested-by: Jerome Brunet Signed-off-by: Yixun Lan Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 7 +++ drivers/clk/meson/Makefile | 1 + drivers/clk/meson/gxbb-aoclk.c | 94 ++++++++++++++--------------------------- drivers/clk/meson/gxbb-aoclk.h | 5 +++ drivers/clk/meson/meson-aoclk.c | 81 +++++++++++++++++++++++++++++++++++ drivers/clk/meson/meson-aoclk.h | 34 +++++++++++++++ 6 files changed, 160 insertions(+), 62 deletions(-) create mode 100644 drivers/clk/meson/meson-aoclk.c create mode 100644 drivers/clk/meson/meson-aoclk.h (limited to 'drivers/clk') diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index d5cbec522aec..fddc7ec7b820 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -3,6 +3,12 @@ config COMMON_CLK_AMLOGIC depends on OF depends on ARCH_MESON || COMPILE_TEST +config COMMON_CLK_MESON_AO + bool + depends on OF + depends on ARCH_MESON || COMPILE_TEST + select COMMON_CLK_REGMAP_MESON + config COMMON_CLK_REGMAP_MESON bool select REGMAP @@ -21,6 +27,7 @@ config COMMON_CLK_GXBB bool depends on COMMON_CLK_AMLOGIC select RESET_CONTROLLER + select COMMON_CLK_MESON_AO select COMMON_CLK_REGMAP_MESON select MFD_SYSCON help diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index ffee82e60b7a..0a8df284f4e7 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o +obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o obj-$(CONFIG_COMMON_CLK_AXG) += axg.o diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index eebb580b9e0f..20f73e0d82a4 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -52,39 +52,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include #include -#include #include -#include -#include -#include -#include -#include #include "clk-regmap.h" +#include "meson-aoclk.h" #include "gxbb-aoclk.h" -struct gxbb_aoclk_reset_controller { - struct reset_controller_dev reset; - unsigned int *data; - struct regmap *regmap; -}; - -static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct gxbb_aoclk_reset_controller *reset = - container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); - - return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0, - BIT(reset->data[id])); -} - -static const struct reset_control_ops gxbb_aoclk_reset_ops = { - .reset = gxbb_aoclk_do_reset, -}; - #define GXBB_AO_GATE(_name, _bit) \ static struct clk_regmap _name##_ao = { \ .data = &(struct clk_regmap_gate_data) { \ @@ -117,7 +90,7 @@ static struct aoclk_cec_32k cec_32k_ao = { }, }; -static unsigned int gxbb_aoclk_reset[] = { +static const unsigned int gxbb_aoclk_reset[] = { [RESET_AO_REMOTE] = 16, [RESET_AO_I2C_MASTER] = 18, [RESET_AO_I2C_SLAVE] = 19, @@ -135,7 +108,7 @@ static struct clk_regmap *gxbb_aoclk_gate[] = { [CLKID_AO_IR_BLASTER] = &ir_blaster_ao, }; -static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { +static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { .hws = { [CLKID_AO_REMOTE] = &remote_ao.hw, [CLKID_AO_I2C_MASTER] = &i2c_master_ao.hw, @@ -145,58 +118,55 @@ static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, [CLKID_AO_CEC_32K] = &cec_32k_ao.hw, }, - .num = 7, + .num = NR_CLKS, }; -static int gxbb_aoclkc_probe(struct platform_device *pdev) +static int gxbb_register_cec_ao_32k(struct platform_device *pdev) { - struct gxbb_aoclk_reset_controller *rstc; struct device *dev = &pdev->dev; struct regmap *regmap; - int ret, clkid; - - rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); - if (!rstc) - return -ENOMEM; + int ret; regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); if (IS_ERR(regmap)) { dev_err(dev, "failed to get regmap\n"); - return -ENODEV; - } - - /* Reset Controller */ - rstc->regmap = regmap; - rstc->data = gxbb_aoclk_reset; - rstc->reset.ops = &gxbb_aoclk_reset_ops; - rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); - rstc->reset.of_node = dev->of_node; - ret = devm_reset_controller_register(dev, &rstc->reset); - - /* - * Populate regmap and register all clks - */ - for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { - gxbb_aoclk_gate[clkid]->map = regmap; - - ret = devm_clk_hw_register(dev, - gxbb_aoclk_onecell_data.hws[clkid]); - if (ret) - return ret; + return PTR_ERR(regmap); } /* Specific clocks */ cec_32k_ao.regmap = regmap; ret = devm_clk_hw_register(dev, &cec_32k_ao.hw); + if (ret) { + dev_err(&pdev->dev, "clk cec_32k_ao register failed.\n"); + return ret; + } + + return 0; +} + +static const struct meson_aoclk_data gxbb_aoclkc_data = { + .reset_reg = AO_RTI_GEN_CNTL_REG0, + .num_reset = ARRAY_SIZE(gxbb_aoclk_reset), + .reset = gxbb_aoclk_reset, + .num_clks = ARRAY_SIZE(gxbb_aoclk_gate), + .clks = gxbb_aoclk_gate, + .hw_data = &gxbb_aoclk_onecell_data, +}; + +static int gxbb_aoclkc_probe(struct platform_device *pdev) +{ + int ret = gxbb_register_cec_ao_32k(pdev); if (ret) return ret; - return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, - &gxbb_aoclk_onecell_data); + return meson_aoclkc_probe(pdev); } static const struct of_device_id gxbb_aoclkc_match_table[] = { - { .compatible = "amlogic,meson-gx-aoclkc" }, + { + .compatible = "amlogic,meson-gx-aoclkc", + .data = &gxbb_aoclkc_data, + }, { } }; diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h index 0be78383f257..65962fc9ecdc 100644 --- a/drivers/clk/meson/gxbb-aoclk.h +++ b/drivers/clk/meson/gxbb-aoclk.h @@ -8,6 +8,8 @@ #ifndef __GXBB_AOCLKC_H #define __GXBB_AOCLKC_H +#define NR_CLKS 7 + /* AO Configuration Clock registers offsets */ #define AO_RTI_PWR_CNTL_REG1 0x0c #define AO_RTI_PWR_CNTL_REG0 0x10 @@ -28,4 +30,7 @@ struct aoclk_cec_32k { extern const struct clk_ops meson_aoclk_cec_32k_ops; +#include +#include + #endif /* __GXBB_AOCLKC_H */ diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c new file mode 100644 index 000000000000..f965845917e3 --- /dev/null +++ b/drivers/clk/meson/meson-aoclk.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Amlogic Meson-AXG Clock Controller Driver + * + * Copyright (c) 2016 BayLibre, SAS. + * Author: Neil Armstrong + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + * Author: Yixun Lan + */ + +#include +#include +#include +#include +#include "clk-regmap.h" +#include "meson-aoclk.h" + +static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct meson_aoclk_reset_controller *rstc = + container_of(rcdev, struct meson_aoclk_reset_controller, reset); + + return regmap_write(rstc->regmap, rstc->data->reset_reg, + BIT(rstc->data->reset[id])); +} + +static const struct reset_control_ops meson_aoclk_reset_ops = { + .reset = meson_aoclk_do_reset, +}; + +int meson_aoclkc_probe(struct platform_device *pdev) +{ + struct meson_aoclk_reset_controller *rstc; + struct meson_aoclk_data *data; + struct device *dev = &pdev->dev; + struct regmap *regmap; + int ret, clkid; + + data = (struct meson_aoclk_data *) of_device_get_match_data(dev); + if (!data) + return -ENODEV; + + rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); + if (!rstc) + return -ENOMEM; + + regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get regmap\n"); + return PTR_ERR(regmap); + } + + /* Reset Controller */ + rstc->data = data; + rstc->regmap = regmap; + rstc->reset.ops = &meson_aoclk_reset_ops; + rstc->reset.nr_resets = data->num_reset, + rstc->reset.of_node = dev->of_node; + ret = devm_reset_controller_register(dev, &rstc->reset); + if (ret) { + dev_err(dev, "failed to register reset controller\n"); + return ret; + } + + /* + * Populate regmap and register all clks + */ + for (clkid = 0; clkid < data->num_clks; clkid++) { + data->clks[clkid]->map = regmap; + + ret = devm_clk_hw_register(dev, data->hw_data->hws[clkid]); + if (ret) + return ret; + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + (void *) data->hw_data); +} diff --git a/drivers/clk/meson/meson-aoclk.h b/drivers/clk/meson/meson-aoclk.h new file mode 100644 index 000000000000..ab2819e88922 --- /dev/null +++ b/drivers/clk/meson/meson-aoclk.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2017 BayLibre, SAS + * Author: Neil Armstrong + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + * Author: Yixun Lan + */ + +#ifndef __MESON_AOCLK_H__ +#define __MESON_AOCLK_H__ + +#include +#include +#include "clk-regmap.h" + +struct meson_aoclk_data { + const unsigned int reset_reg; + const int num_reset; + const unsigned int *reset; + int num_clks; + struct clk_regmap **clks; + const struct clk_hw_onecell_data *hw_data; +}; + +struct meson_aoclk_reset_controller { + struct reset_controller_dev reset; + const struct meson_aoclk_data *data; + struct regmap *regmap; +}; + +int meson_aoclkc_probe(struct platform_device *pdev); +#endif -- cgit v1.2.3 From 6693e2199ea1366ff6a1791258b20b615a2fd667 Mon Sep 17 00:00:00 2001 From: Qiufang Dai Date: Thu, 3 May 2018 21:26:23 +0800 Subject: clk: meson-axg: Add AO Clock and Reset controller driver Adds a Clock and Reset controller driver for the Always-On part of the Amlogic Meson-AXG SoC. Signed-off-by: Qiufang Dai Signed-off-by: Yixun Lan Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 1 + drivers/clk/meson/Makefile | 2 +- drivers/clk/meson/axg-aoclk.c | 164 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/meson/axg-aoclk.h | 29 ++++++++ 4 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/meson/axg-aoclk.c create mode 100644 drivers/clk/meson/axg-aoclk.h (limited to 'drivers/clk') diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index fddc7ec7b820..815659eebea3 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -38,6 +38,7 @@ config COMMON_CLK_AXG bool depends on COMMON_CLK_AMLOGIC select RESET_CONTROLLER + select COMMON_CLK_MESON_AO select COMMON_CLK_REGMAP_MESON select MFD_SYSCON help diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 0a8df284f4e7..d0d13aeb369a 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -6,5 +6,5 @@ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o -obj-$(CONFIG_COMMON_CLK_AXG) += axg.o +obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c new file mode 100644 index 000000000000..29e088542387 --- /dev/null +++ b/drivers/clk/meson/axg-aoclk.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Amlogic Meson-AXG Clock Controller Driver + * + * Copyright (c) 2016 Baylibre SAS. + * Author: Michael Turquette + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ +#include +#include +#include +#include +#include "clk-regmap.h" +#include "meson-aoclk.h" +#include "axg-aoclk.h" + +#define AXG_AO_GATE(_name, _bit) \ +static struct clk_regmap axg_aoclk_##_name = { \ + .data = &(struct clk_regmap_gate_data) { \ + .offset = (AO_RTI_GEN_CNTL_REG0), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = "axg_ao_" #_name, \ + .ops = &clk_regmap_gate_ops, \ + .parent_names = (const char *[]){ "clk81" }, \ + .num_parents = 1, \ + .flags = CLK_IGNORE_UNUSED, \ + }, \ +} + +AXG_AO_GATE(remote, 0); +AXG_AO_GATE(i2c_master, 1); +AXG_AO_GATE(i2c_slave, 2); +AXG_AO_GATE(uart1, 3); +AXG_AO_GATE(uart2, 5); +AXG_AO_GATE(ir_blaster, 6); +AXG_AO_GATE(saradc, 7); + +static struct clk_regmap axg_aoclk_clk81 = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_RTI_PWR_CNTL_REG0, + .mask = 0x1, + .shift = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_ao_clk81", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "clk81", "ao_alt_xtal"}, + .num_parents = 2, + }, +}; + +static struct clk_regmap axg_aoclk_saradc_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_SAR_CLK, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_ao_saradc_mux", + .ops = &clk_regmap_mux_ops, + .parent_names = (const char *[]){ "xtal", "axg_ao_clk81" }, + .num_parents = 2, + }, +}; + +static struct clk_regmap axg_aoclk_saradc_div = { + .data = &(struct clk_regmap_div_data) { + .offset = AO_SAR_CLK, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_ao_saradc_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "axg_ao_saradc_mux" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap axg_aoclk_saradc_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = AO_SAR_CLK, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_ao_saradc_gate", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "axg_ao_saradc_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const unsigned int axg_aoclk_reset[] = { + [RESET_AO_REMOTE] = 16, + [RESET_AO_I2C_MASTER] = 18, + [RESET_AO_I2C_SLAVE] = 19, + [RESET_AO_UART1] = 17, + [RESET_AO_UART2] = 22, + [RESET_AO_IR_BLASTER] = 23, +}; + +static struct clk_regmap *axg_aoclk_regmap[] = { + [CLKID_AO_REMOTE] = &axg_aoclk_remote, + [CLKID_AO_I2C_MASTER] = &axg_aoclk_i2c_master, + [CLKID_AO_I2C_SLAVE] = &axg_aoclk_i2c_slave, + [CLKID_AO_UART1] = &axg_aoclk_uart1, + [CLKID_AO_UART2] = &axg_aoclk_uart2, + [CLKID_AO_IR_BLASTER] = &axg_aoclk_ir_blaster, + [CLKID_AO_SAR_ADC] = &axg_aoclk_saradc, + [CLKID_AO_CLK81] = &axg_aoclk_clk81, + [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux, + [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div, + [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate, +}; + +static const struct clk_hw_onecell_data axg_aoclk_onecell_data = { + .hws = { + [CLKID_AO_REMOTE] = &axg_aoclk_remote.hw, + [CLKID_AO_I2C_MASTER] = &axg_aoclk_i2c_master.hw, + [CLKID_AO_I2C_SLAVE] = &axg_aoclk_i2c_slave.hw, + [CLKID_AO_UART1] = &axg_aoclk_uart1.hw, + [CLKID_AO_UART2] = &axg_aoclk_uart2.hw, + [CLKID_AO_IR_BLASTER] = &axg_aoclk_ir_blaster.hw, + [CLKID_AO_SAR_ADC] = &axg_aoclk_saradc.hw, + [CLKID_AO_CLK81] = &axg_aoclk_clk81.hw, + [CLKID_AO_SAR_ADC_SEL] = &axg_aoclk_saradc_mux.hw, + [CLKID_AO_SAR_ADC_DIV] = &axg_aoclk_saradc_div.hw, + [CLKID_AO_SAR_ADC_CLK] = &axg_aoclk_saradc_gate.hw, + }, + .num = NR_CLKS, +}; + +static const struct meson_aoclk_data axg_aoclkc_data = { + .reset_reg = AO_RTI_GEN_CNTL_REG0, + .num_reset = ARRAY_SIZE(axg_aoclk_reset), + .reset = axg_aoclk_reset, + .num_clks = ARRAY_SIZE(axg_aoclk_regmap), + .clks = axg_aoclk_regmap, + .hw_data = &axg_aoclk_onecell_data, +}; + +static const struct of_device_id axg_aoclkc_match_table[] = { + { + .compatible = "amlogic,meson-axg-aoclkc", + .data = &axg_aoclkc_data, + }, + { } +}; + +static struct platform_driver axg_aoclkc_driver = { + .probe = meson_aoclkc_probe, + .driver = { + .name = "axg-aoclkc", + .of_match_table = axg_aoclkc_match_table, + }, +}; + +builtin_platform_driver(axg_aoclkc_driver); diff --git a/drivers/clk/meson/axg-aoclk.h b/drivers/clk/meson/axg-aoclk.h new file mode 100644 index 000000000000..91384d8dd844 --- /dev/null +++ b/drivers/clk/meson/axg-aoclk.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2017 BayLibre, SAS + * Author: Neil Armstrong + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ + +#ifndef __AXG_AOCLKC_H +#define __AXG_AOCLKC_H + +#define NR_CLKS 11 +/* AO Configuration Clock registers offsets + * Register offsets from the data sheet must be multiplied by 4. + */ +#define AO_RTI_PWR_CNTL_REG1 0x0C +#define AO_RTI_PWR_CNTL_REG0 0x10 +#define AO_RTI_GEN_CNTL_REG0 0x40 +#define AO_OSCIN_CNTL 0x58 +#define AO_CRT_CLK_CNTL1 0x68 +#define AO_SAR_CLK 0x90 +#define AO_RTC_ALT_CLK_CNTL0 0x94 +#define AO_RTC_ALT_CLK_CNTL1 0x98 + +#include +#include + +#endif /* __AXG_AOCLKC_H */ -- cgit v1.2.3 From 24a2e6796eb23d17d4e32a27f19336248666272c Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Thu, 3 May 2018 21:26:24 +0800 Subject: clk: meson: drop CLK_SET_RATE_PARENT flag The clk81 is not expected to be changed, so drop this flag. Signed-off-by: Yixun Lan Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb-aoclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 20f73e0d82a4..408e3e2fca18 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -69,7 +69,7 @@ static struct clk_regmap _name##_ao = { \ .ops = &clk_regmap_gate_ops, \ .parent_names = (const char *[]){ "clk81" }, \ .num_parents = 1, \ - .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ + .flags = CLK_IGNORE_UNUSED, \ }, \ } -- cgit v1.2.3 From a714dceb721407c2a5d2887938f37e34ed00669c Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Mon, 7 May 2018 17:04:57 +0530 Subject: clk: davinci: psc-da830: fix USB0 48MHz PHY clock registration USB0 48MHz PHY clock registration fails on DA830 because the da8xx-cfgchip clock driver cannot get a reference to USB0 LPSC clock. The USB0 LPSC needs to be enabled during PHY clock enable. Setup the clock lookup correctly to fix this. Signed-off-by: Sekhar Nori Reviewed-by: David Lechner Signed-off-by: Stephen Boyd --- drivers/clk/davinci/psc-da830.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/psc-da830.c b/drivers/clk/davinci/psc-da830.c index f61abf5632ff..081b039fcb02 100644 --- a/drivers/clk/davinci/psc-da830.c +++ b/drivers/clk/davinci/psc-da830.c @@ -55,7 +55,8 @@ const struct davinci_psc_init_data da830_psc0_init_data = { .psc_init = &da830_psc0_init, }; -LPSC_CLKDEV2(usb0_clkdev, NULL, "musb-da8xx", +LPSC_CLKDEV3(usb0_clkdev, "fck", "da830-usb-phy-clks", + NULL, "musb-da8xx", NULL, "cppi41-dmaengine"); LPSC_CLKDEV1(usb1_clkdev, NULL, "ohci-da8xx"); /* REVISIT: gpio-davinci.c should be modified to drop con_id */ -- cgit v1.2.3 From a982e45dc150da3a08907b6dd676b735391704b4 Mon Sep 17 00:00:00 2001 From: Marcin Ziemianowicz Date: Sun, 29 Apr 2018 15:01:11 -0400 Subject: clk: at91: PLL recalc_rate() now using cached MUL and DIV values When a USB device is connected to the USB host port on the SAM9N12 then you get "-62" error which seems to indicate USB replies from the device are timing out. Based on a logic sniffer, I saw the USB bus was running at half speed. The PLL code uses cached MUL and DIV values which get set in set_rate() and applied in prepare(), but the recalc_rate() function instead queries the hardware instead of using these cached values. Therefore, if recalc_rate() is called between a set_rate() and prepare(), the wrong frequency is calculated and later the USB clock divider for the SAM9N12 SOC will be configured for an incorrect clock. In my case, the PLL hardware was set to 96 Mhz before the OHCI driver loads, and therefore the usb clock divider was being set to /2 even though the OHCI driver set the PLL to 48 Mhz. As an alternative explanation, I noticed this was fixed in the past by 87e2ed338f1b ("clk: at91: fix recalc_rate implementation of PLL driver") but the bug was later re-introduced by 1bdf02326b71 ("clk: at91: make use of syscon/regmap internally"). Fixes: 1bdf02326b71 ("clk: at91: make use of syscon/regmap internally) Cc: Signed-off-by: Marcin Ziemianowicz Acked-by: Boris Brezillon Signed-off-by: Stephen Boyd --- drivers/clk/at91/clk-pll.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c index 7d3223fc7161..72b6091eb7b9 100644 --- a/drivers/clk/at91/clk-pll.c +++ b/drivers/clk/at91/clk-pll.c @@ -132,19 +132,8 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_pll *pll = to_clk_pll(hw); - unsigned int pllr; - u16 mul; - u8 div; - - regmap_read(pll->regmap, PLL_REG(pll->id), &pllr); - - div = PLL_DIV(pllr); - mul = PLL_MUL(pllr, pll->layout); - - if (!div || !mul) - return 0; - return (parent_rate / div) * (mul + 1); + return (parent_rate / pll->div) * (pll->mul + 1); } static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, -- cgit v1.2.3 From 22f65a389f612f9de5f3597fd305ef63f393f769 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 16 May 2018 10:50:40 +0200 Subject: clk: meson: use SPDX license identifiers consistently Replace every license notices in drivers/clk/meson by SPDX license identifiers, as described in license-rules.rst Acked-by: Neil Armstrong Acked-by: Stephen Boyd Signed-off-by: Jerome Brunet --- drivers/clk/meson/clk-audio-divider.c | 13 +-------- drivers/clk/meson/clk-mpll.c | 52 +---------------------------------- drivers/clk/meson/clk-pll.c | 13 +-------- drivers/clk/meson/clk-regmap.c | 6 ++-- drivers/clk/meson/clk-regmap.h | 8 ++++-- drivers/clk/meson/clkc.h | 13 +-------- drivers/clk/meson/gxbb-aoclk-32k.c | 3 +- drivers/clk/meson/gxbb-aoclk.c | 51 +--------------------------------- drivers/clk/meson/gxbb-aoclk.h | 3 +- drivers/clk/meson/gxbb.c | 15 +--------- drivers/clk/meson/gxbb.h | 52 +---------------------------------- drivers/clk/meson/meson8b.c | 16 +---------- drivers/clk/meson/meson8b.h | 13 +-------- 13 files changed, 20 insertions(+), 238 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/clk-audio-divider.c b/drivers/clk/meson/clk-audio-divider.c index f7ab5b1db342..58f546e04807 100644 --- a/drivers/clk/meson/clk-audio-divider.c +++ b/drivers/clk/meson/clk-audio-divider.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2017 AmLogic, Inc. * Author: Jerome Brunet - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . */ /* diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c index 0df1227b65b3..45c3a2261f2f 100644 --- a/drivers/clk/meson/clk-mpll.c +++ b/drivers/clk/meson/clk-mpll.c @@ -1,57 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) /* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright (c) 2016 AmLogic, Inc. - * Author: Michael Turquette - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called COPYING - * - * BSD LICENSE - * * Copyright (c) 2016 AmLogic, Inc. * Author: Michael Turquette - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 65a7bd903551..3e04617ac47f 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione * * Copyright (c) 2018 Baylibre, SAS. * Author: Jerome Brunet - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . */ /* diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c index 3645fdb62343..bd8dbcbdc73c 100644 --- a/drivers/clk/meson/clk-regmap.c +++ b/drivers/clk/meson/clk-regmap.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2018 BayLibre, SAS. -// Author: Jerome Brunet +/* + * Copyright (c) 2018 BayLibre, SAS. + * Author: Jerome Brunet + */ #include "clk-regmap.h" diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h index 627c888026d7..ed2d4348dbe2 100644 --- a/drivers/clk/meson/clk-regmap.h +++ b/drivers/clk/meson/clk-regmap.h @@ -1,6 +1,8 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2018 BayLibre, SAS. -// Author: Jerome Brunet +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018 BayLibre, SAS. + * Author: Jerome Brunet + */ #ifndef __CLK_REGMAP_H #define __CLK_REGMAP_H diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 8fe73c4edca8..7b90c9748c73 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -1,18 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . */ #ifndef __CLKC_H diff --git a/drivers/clk/meson/gxbb-aoclk-32k.c b/drivers/clk/meson/gxbb-aoclk-32k.c index 491634dbc985..680467141a1d 100644 --- a/drivers/clk/meson/gxbb-aoclk-32k.c +++ b/drivers/clk/meson/gxbb-aoclk-32k.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2017 BayLibre, SAS. * Author: Neil Armstrong - * - * SPDX-License-Identifier: GPL-2.0+ */ #include diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 408e3e2fca18..42ed61d3c3fb 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -1,56 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) /* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * * Copyright (c) 2016 BayLibre, SAS. * Author: Neil Armstrong - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * BSD LICENSE - * - * Copyright (c) 2016 BayLibre, SAS. - * Author: Neil Armstrong - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h index 65962fc9ecdc..3aa638d4ed21 100644 --- a/drivers/clk/meson/gxbb-aoclk.h +++ b/drivers/clk/meson/gxbb-aoclk.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 2017 BayLibre, SAS * Author: Neil Armstrong - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef __GXBB_AOCLKC_H diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index a893b1edda22..240658404367 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -1,20 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * AmLogic S905 / GXBB Clock Controller Driver - * * Copyright (c) 2016 AmLogic, Inc. * Michael Turquette - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . */ #include diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index b3ef54f65a9d..ec1a812bf1fd 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -1,57 +1,7 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ /* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * * Copyright (c) 2016 AmLogic, Inc. * Author: Michael Turquette - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called COPYING - * - * BSD LICENSE - * - * Copyright (c) 2016 BayLibre, Inc. - * Author: Michael Turquette - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __GXBB_H diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index e6e9a9db1095..54dcb60f2dd5 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -1,24 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * AmLogic S802 (Meson8) / S805 (Meson8b) / S812 (Meson8m2) Clock Controller - * Driver - * * Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione * * Copyright (c) 2016 BayLibre, Inc. * Michael Turquette - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . */ #include diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index a687dc60b6d0..5d09412b5084 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -1,21 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione * * Copyright (c) 2016 BayLibre, Inc. * Michael Turquette - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . */ #ifndef __MESON8B_H -- cgit v1.2.3 From 72e1f2302040398dafb64bbb93abdde78c1f2267 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 20 May 2018 19:16:06 +0200 Subject: clk: meson: meson8b: mark fclk_div2 gate clocks as CLK_IS_CRITICAL Until commit 05f814402d6174 ("clk: meson: add fdiv clock gates") we relied on the bootloader to enable the fclk_div clock gates. It turns out that our clock tree is incomplete at least on Meson8b (tested with an Odroid-C1, which uses an RGMII PHY) because after the mentioned commit Ethernet is not working anymore (no RX/TX activity can be seen). At the same time Ethernet was still working on Meson8m2 with a RMII PHY. Testing has shown that as soon as "fclk_div2" is disabled Ethernet stops working on Odroid-C1. Unfortunately it's currently not clear what the Ethernet controller IP block uses the fclk_div2 clock for. Mark the clock as CLK_IS_CRITICAL to keep it enabled (as it's already enabled by most bootloaders by default, which is why we didn't notice it before). Fixes: 05f814402d6174 ("clk: meson: add fdiv clock gates") Cc: stable@vger.kernel.org Signed-off-by: Martin Blumenstingl Tested-by: Kevin Hilman Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 54dcb60f2dd5..98f96d801de6 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -232,6 +232,13 @@ static struct clk_regmap meson8b_fclk_div2 = { .ops = &clk_regmap_gate_ops, .parent_names = (const char *[]){ "fclk_div2_div" }, .num_parents = 1, + /* + * FIXME: Ethernet with a RGMII PHYs is not working if + * fclk_div2 is disabled. it is currently unclear why this + * is. keep it enabled until the Ethernet driver knows how + * to manage this clock. + */ + .flags = CLK_IS_CRITICAL, }, }; -- cgit v1.2.3 From bae1106c37c60661a94739b3f0a52138e227d604 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Tue, 15 May 2018 18:36:51 +0200 Subject: clk: meson: mpll: add round closest support Allow the mpll driver to round the requested rate up if CLK_MESON_MPLL_ROUND_CLOSEST is set and it provides a rate closer to the requested rate. Acked-by: Neil Armstrong Acked-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/clk-mpll.c | 24 +++++++++++++++++++----- drivers/clk/meson/clkc.h | 3 +++ 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c index 45c3a2261f2f..650f75cc15a9 100644 --- a/drivers/clk/meson/clk-mpll.c +++ b/drivers/clk/meson/clk-mpll.c @@ -39,10 +39,23 @@ static long rate_from_params(unsigned long parent_rate, static void params_from_rate(unsigned long requested_rate, unsigned long parent_rate, unsigned int *sdm, - unsigned int *n2) + unsigned int *n2, + u8 flags) { uint64_t div = parent_rate; - unsigned long rem = do_div(div, requested_rate); + uint64_t frac = do_div(div, requested_rate); + + frac *= SDM_DEN; + + if (flags & CLK_MESON_MPLL_ROUND_CLOSEST) + *sdm = DIV_ROUND_CLOSEST_ULL(frac, requested_rate); + else + *sdm = DIV_ROUND_UP_ULL(frac, requested_rate); + + if (*sdm == SDM_DEN) { + *sdm = 0; + div += 1; + } if (div < N2_MIN) { *n2 = N2_MIN; @@ -52,7 +65,6 @@ static void params_from_rate(unsigned long requested_rate, *sdm = SDM_DEN - 1; } else { *n2 = div; - *sdm = DIV_ROUND_UP_ULL((u64)rem * SDM_DEN, requested_rate); } } @@ -75,9 +87,11 @@ static long mpll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk); unsigned int sdm, n2; - params_from_rate(rate, *parent_rate, &sdm, &n2); + params_from_rate(rate, *parent_rate, &sdm, &n2, mpll->flags); return rate_from_params(*parent_rate, sdm, n2); } @@ -90,7 +104,7 @@ static int mpll_set_rate(struct clk_hw *hw, unsigned int sdm, n2; unsigned long flags = 0; - params_from_rate(rate, parent_rate, &sdm, &n2); + params_from_rate(rate, parent_rate, &sdm, &n2, mpll->flags); if (mpll->lock) spin_lock_irqsave(mpll->lock, flags); diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 7b90c9748c73..2fb084330ee9 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -86,8 +86,11 @@ struct meson_clk_mpll_data { struct parm ssen; struct parm misc; spinlock_t *lock; + u8 flags; }; +#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) + struct meson_clk_audio_div_data { struct parm div; u8 flags; -- cgit v1.2.3 From de1ca2d07bdc3fb4a21991ca78b026324636f541 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Tue, 15 May 2018 18:36:52 +0200 Subject: clk: meson: axg: let mpll clocks round closest Let the mpll dividers achieve the closest rate possible, even if it means rounding the requested rate up. This is done to improve the accuracy of the rates provided by these plls to the audio subsystem Acked-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 5f5d468c1efe..bd4dbc696b88 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -461,6 +461,7 @@ static struct clk_regmap axg_mpll0_div = { .width = 1, }, .lock = &meson_clk_lock, + .flags = CLK_MESON_MPLL_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ .name = "mpll0_div", @@ -507,6 +508,7 @@ static struct clk_regmap axg_mpll1_div = { .width = 1, }, .lock = &meson_clk_lock, + .flags = CLK_MESON_MPLL_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ .name = "mpll1_div", @@ -553,6 +555,7 @@ static struct clk_regmap axg_mpll2_div = { .width = 1, }, .lock = &meson_clk_lock, + .flags = CLK_MESON_MPLL_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ .name = "mpll2_div", @@ -599,6 +602,7 @@ static struct clk_regmap axg_mpll3_div = { .width = 1, }, .lock = &meson_clk_lock, + .flags = CLK_MESON_MPLL_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ .name = "mpll3_div", -- cgit v1.2.3 From b4d73d224d9bc6881266fd95ab11ef738ef7333f Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 25 May 2018 13:11:42 -0500 Subject: clk: davinci: pll-dm355: drop pll2_sysclk2 This removes pll2_sysclk2 from the TI DM355 clock driver. This SoC doesn't have such a clock. Also, SYSCLK_ALWAYS_ENABLED is transferred to pll2_sysclk1 since it drives the DDR and doesn't have another mechanism to keep it on. Reported-by: Sekhar Nori Signed-off-by: David Lechner Acked-by: Sekhar Nori Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-2-david@lechnology.com --- drivers/clk/davinci/pll-dm355.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/pll-dm355.c b/drivers/clk/davinci/pll-dm355.c index 5345f8286c50..718d9bbbf30d 100644 --- a/drivers/clk/davinci/pll-dm355.c +++ b/drivers/clk/davinci/pll-dm355.c @@ -62,8 +62,7 @@ static const struct davinci_pll_clk_info dm355_pll2_info = { PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV, }; -SYSCLK(1, pll2_sysclk1, pll2, 5, SYSCLK_FIXED_DIV); -SYSCLK(2, pll2_sysclk2, pll2, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); +SYSCLK(1, pll2_sysclk1, pll2, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); int dm355_pll2_init(struct device *dev, void __iomem *base) { @@ -71,8 +70,6 @@ int dm355_pll2_init(struct device *dev, void __iomem *base) davinci_pll_sysclk_register(dev, &pll2_sysclk1, base); - davinci_pll_sysclk_register(dev, &pll2_sysclk2, base); - davinci_pll_sysclkbp_clk_register(dev, "pll2_sysclkbp", base); return 0; -- cgit v1.2.3 From 6ce190bc424bd951c5ab94b875f650b365570707 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 25 May 2018 13:11:43 -0500 Subject: clk: davinci: pll-dm355: fix SYSCLKn parent names This fixes the parent clock names of the SYSCLKn clocks for the DM355 SoC in the TI DaVinici PLL clock driver. It appears that this name just didn't get updated to the correct name like the other SoCs during the driver's development. Reported-by: Sekhar Nori Signed-off-by: David Lechner Acked-by: Sekhar Nori Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-3-david@lechnology.com --- drivers/clk/davinci/pll-dm355.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/pll-dm355.c b/drivers/clk/davinci/pll-dm355.c index 718d9bbbf30d..93f4a53d6b44 100644 --- a/drivers/clk/davinci/pll-dm355.c +++ b/drivers/clk/davinci/pll-dm355.c @@ -22,10 +22,10 @@ static const struct davinci_pll_clk_info dm355_pll1_info = { PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV, }; -SYSCLK(1, pll1_sysclk1, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); -SYSCLK(2, pll1_sysclk2, pll1, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); -SYSCLK(3, pll1_sysclk3, pll1, 5, SYSCLK_ALWAYS_ENABLED); -SYSCLK(4, pll1_sysclk4, pll1, 5, SYSCLK_ALWAYS_ENABLED); +SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); +SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); +SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED); +SYSCLK(4, pll1_sysclk4, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED); int dm355_pll1_init(struct device *dev, void __iomem *base) { @@ -62,7 +62,7 @@ static const struct davinci_pll_clk_info dm355_pll2_info = { PLL_POSTDIV_ALWAYS_ENABLED | PLL_POSTDIV_FIXED_DIV, }; -SYSCLK(1, pll2_sysclk1, pll2, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); +SYSCLK(1, pll2_sysclk1, pll2_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); int dm355_pll2_init(struct device *dev, void __iomem *base) { -- cgit v1.2.3 From 715478bb63ffd76cf90f6536be8592e3f6df9567 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 25 May 2018 13:11:44 -0500 Subject: clk: davinci: psc-dm355: fix ASP0/1 clkdev lookups The clkdev lookups for the ASP0/1 devices on TI DM355 were declared, but not assigned to any LPSC. This assigns the clkdev lookups to the correct LPSCs. Reported-by: Sekhar Nori Signed-off-by: David Lechner Reviewed-by: Sekhar Nori Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-4-david@lechnology.com --- drivers/clk/davinci/psc-dm355.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/psc-dm355.c b/drivers/clk/davinci/psc-dm355.c index 6995ecea2677..128e7345b20c 100644 --- a/drivers/clk/davinci/psc-dm355.c +++ b/drivers/clk/davinci/psc-dm355.c @@ -41,14 +41,14 @@ static const struct davinci_lpsc_clk_info dm355_psc_info[] = { LPSC(5, 0, timer3, pll1_auxclk, NULL, 0), LPSC(6, 0, spi1, pll1_sysclk2, spi1_clkdev, 0), LPSC(7, 0, mmcsd1, pll1_sysclk2, mmcsd1_clkdev, 0), - LPSC(8, 0, asp1, pll1_sysclk2, NULL, 0), + LPSC(8, 0, asp1, pll1_sysclk2, mcbsp1_clkdev, 0), LPSC(9, 0, usb, pll1_sysclk2, usb_clkdev, 0), LPSC(10, 0, pwm3, pll1_auxclk, NULL, 0), LPSC(11, 0, spi2, pll1_sysclk2, spi2_clkdev, 0), LPSC(12, 0, rto, pll1_auxclk, NULL, 0), LPSC(14, 0, aemif, pll1_sysclk2, aemif_clkdev, 0), LPSC(15, 0, mmcsd0, pll1_sysclk2, mmcsd0_clkdev, 0), - LPSC(17, 0, asp0, pll1_sysclk2, NULL, 0), + LPSC(17, 0, asp0, pll1_sysclk2, mcbsp0_clkdev, 0), LPSC(18, 0, i2c, pll1_auxclk, i2c_clkdev, 0), LPSC(19, 0, uart0, pll1_auxclk, uart0_clkdev, 0), LPSC(20, 0, uart1, pll1_auxclk, uart1_clkdev, 0), -- cgit v1.2.3 From 7f02f18e7f87831747aaa2685f63d16fb2649c6a Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Fri, 25 May 2018 13:11:45 -0500 Subject: clk: davinci: pll-dm646x: keep PLL2 SYSCLK1 always enabled PLL2 SYSCLK1 on DM646x is connected to DDR2 PHY and cannot be disabled. Mark it so to prevent unused clock disable infrastructure from disabling it. Signed-off-by: Sekhar Nori Reviewed-by: David Lechner Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-5-david@lechnology.com --- drivers/clk/davinci/pll-dm646x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/pll-dm646x.c b/drivers/clk/davinci/pll-dm646x.c index a61cc3256418..0ae827e3ce80 100644 --- a/drivers/clk/davinci/pll-dm646x.c +++ b/drivers/clk/davinci/pll-dm646x.c @@ -72,7 +72,7 @@ static const struct davinci_pll_clk_info dm646x_pll2_info = { .flags = 0, }; -SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0); +SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, SYSCLK_ALWAYS_ENABLED); int dm646x_pll2_init(struct device *dev, void __iomem *base) { -- cgit v1.2.3 From 9c39fc1fe87a5f60f0103afbbcf0d8eaedc28ab7 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Fri, 25 May 2018 13:11:46 -0500 Subject: clk: davinci: psc-dm365: fix few clocks Fix parent of EMAC and voice codec PSC clocks. Documentation is clear on EMAC clock parent, but its not fully clear on parent of voice codec clock. The implementation chosen is matches arch/arm/mach-davinci/dm365.c. Add a comment explaining this for posterity. There is only one power domain on DM365. Fix the power domain of voice codec and vpss dac modules. While at it, add a comment explaining how the parent of vpss dac clock was derived. Note that this patch does not touch the parent of vpss dac clock. Signed-off-by: Sekhar Nori Reviewed-by: David Lechner Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-6-david@lechnology.com --- drivers/clk/davinci/psc-dm365.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/psc-dm365.c b/drivers/clk/davinci/psc-dm365.c index 3ad915f37376..289af3913fb0 100644 --- a/drivers/clk/davinci/psc-dm365.c +++ b/drivers/clk/davinci/psc-dm365.c @@ -65,9 +65,22 @@ static const struct davinci_lpsc_clk_info dm365_psc_info[] = { LPSC(31, 0, arm, pll2_sysclk2, NULL, LPSC_ALWAYS_ENABLED), LPSC(38, 0, spi3, pll1_sysclk4, spi3_clkdev, 0), LPSC(39, 0, spi4, pll1_auxclk, spi4_clkdev, 0), - LPSC(40, 0, emac, pll2_sysclk4, emac_clkdev, 0), - LPSC(44, 1, voice_codec, pll1_sysclk3, voice_codec_clkdev, 0), - LPSC(46, 1, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0), + LPSC(40, 0, emac, pll1_sysclk4, emac_clkdev, 0), + /* + * The TRM (ARM Subsystem User's Guide) shows two clocks input into + * voice codec module (PLL2 SYSCLK4 with a DIV2 and PLL1 SYSCLK4). Its + * not fully clear from documentation which clock should be considered + * as parent for PSC. The clock chosen here is to maintain + * compatibility with existing code in arch/arm/mach-davinci/dm365.c + */ + LPSC(44, 0, voice_codec, pll2_sysclk4, voice_codec_clkdev, 0), + /* + * Its not fully clear from TRM (ARM Subsystem User's Guide) as to what + * the parent of VPSS DAC LPSC should actually be. PLL1 SYSCLK3 feeds + * into HDVICP and MJCP. The clock chosen here is to remain compatible + * with code existing in arch/arm/mach-davinci/dm365.c + */ + LPSC(46, 0, vpss_dac, pll1_sysclk3, vpss_dac_clkdev, 0), LPSC(47, 0, vpss_master, pll1_sysclk5, vpss_master_clkdev, 0), LPSC(50, 0, mjcp, pll1_sysclk3, NULL, 0), { } -- cgit v1.2.3 From 76c9dd9dbd6459f1faf2b10351eb3d3f90255fa1 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 25 May 2018 13:11:47 -0500 Subject: clk: davinci: pll: allow dev == NULL This modifies the TI Davinci PLL clock driver to allow for the case when dev == NULL. On some (most) SoCs that use this driver, the PLL clock needs to be registered during early boot because it is used for clocksource/clkevent and there will be no platform device available. Signed-off-by: David Lechner Reviewed-by: Sekhar Nori Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-7-david@lechnology.com --- drivers/clk/davinci/pll-da830.c | 5 +- drivers/clk/davinci/pll-da850.c | 22 +-- drivers/clk/davinci/pll-dm355.c | 9 +- drivers/clk/davinci/pll-dm365.c | 9 +- drivers/clk/davinci/pll-dm644x.c | 9 +- drivers/clk/davinci/pll-dm646x.c | 9 +- drivers/clk/davinci/pll.c | 279 ++++++++++++++++++++++++++------------- drivers/clk/davinci/pll.h | 30 ++--- 8 files changed, 235 insertions(+), 137 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/pll-da830.c b/drivers/clk/davinci/pll-da830.c index 929a3d3a9adb..0a0d06fb25fd 100644 --- a/drivers/clk/davinci/pll-da830.c +++ b/drivers/clk/davinci/pll-da830.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -36,11 +37,11 @@ SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0); SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_FIXED_DIV); SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0); -int da830_pll_init(struct device *dev, void __iomem *base) +int da830_pll_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &da830_pll_info, "ref_clk", base); + davinci_pll_clk_register(dev, &da830_pll_info, "ref_clk", base, cfgchip); clk = davinci_pll_sysclk_register(dev, &pll0_sysclk2, base); clk_register_clkdev(clk, "pll0_sysclk2", "da830-psc0"); diff --git a/drivers/clk/davinci/pll-da850.c b/drivers/clk/davinci/pll-da850.c index 2a038b7908cc..59cc2e3733f9 100644 --- a/drivers/clk/davinci/pll-da850.c +++ b/drivers/clk/davinci/pll-da850.c @@ -7,7 +7,9 @@ #include #include +#include #include +#include #include #include #include @@ -81,11 +83,11 @@ static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info = { .ocsrc_mask = GENMASK(4, 0), }; -int da850_pll0_init(struct device *dev, void __iomem *base) +int da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &da850_pll0_info, "ref_clk", base); + davinci_pll_clk_register(dev, &da850_pll0_info, "ref_clk", base, cfgchip); clk = davinci_pll_sysclk_register(dev, &pll0_sysclk1, base); clk_register_clkdev(clk, "pll0_sysclk1", "da850-psc0"); @@ -134,11 +136,11 @@ static const struct davinci_pll_sysclk_info *da850_pll0_sysclk_info[] = { NULL }; -int of_da850_pll0_init(struct device *dev, void __iomem *base) +int of_da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { - return of_davinci_pll_init(dev, &da850_pll0_info, + return of_davinci_pll_init(dev, dev->of_node, &da850_pll0_info, &da850_pll0_obsclk_info, - da850_pll0_sysclk_info, 7, base); + da850_pll0_sysclk_info, 7, base, cfgchip); } static const struct davinci_pll_clk_info da850_pll1_info = { @@ -179,11 +181,11 @@ static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info = { .ocsrc_mask = GENMASK(4, 0), }; -int da850_pll1_init(struct device *dev, void __iomem *base) +int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &da850_pll1_info, "oscin", base); + davinci_pll_clk_register(dev, &da850_pll1_info, "oscin", base, cfgchip); davinci_pll_sysclk_register(dev, &pll1_sysclk1, base); @@ -204,9 +206,9 @@ static const struct davinci_pll_sysclk_info *da850_pll1_sysclk_info[] = { NULL }; -int of_da850_pll1_init(struct device *dev, void __iomem *base) +int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { - return of_davinci_pll_init(dev, &da850_pll1_info, + return of_davinci_pll_init(dev, dev->of_node, &da850_pll1_info, &da850_pll1_obsclk_info, - da850_pll1_sysclk_info, 3, base); + da850_pll1_sysclk_info, 3, base, cfgchip); } diff --git a/drivers/clk/davinci/pll-dm355.c b/drivers/clk/davinci/pll-dm355.c index 93f4a53d6b44..505aed80be9a 100644 --- a/drivers/clk/davinci/pll-dm355.c +++ b/drivers/clk/davinci/pll-dm355.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -27,11 +28,11 @@ SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED) SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED); SYSCLK(4, pll1_sysclk4, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED); -int dm355_pll1_init(struct device *dev, void __iomem *base) +int dm355_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &dm355_pll1_info, "ref_clk", base); + davinci_pll_clk_register(dev, &dm355_pll1_info, "ref_clk", base, cfgchip); clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base); clk_register_clkdev(clk, "pll1_sysclk1", "dm355-psc"); @@ -64,9 +65,9 @@ static const struct davinci_pll_clk_info dm355_pll2_info = { SYSCLK(1, pll2_sysclk1, pll2_pllen, 5, SYSCLK_FIXED_DIV | SYSCLK_ALWAYS_ENABLED); -int dm355_pll2_init(struct device *dev, void __iomem *base) +int dm355_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { - davinci_pll_clk_register(dev, &dm355_pll2_info, "oscin", base); + davinci_pll_clk_register(dev, &dm355_pll2_info, "oscin", base, cfgchip); davinci_pll_sysclk_register(dev, &pll2_sysclk1, base); diff --git a/drivers/clk/davinci/pll-dm365.c b/drivers/clk/davinci/pll-dm365.c index 5f8d9f42d0f3..2d29712753a3 100644 --- a/drivers/clk/davinci/pll-dm365.c +++ b/drivers/clk/davinci/pll-dm365.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -56,11 +57,11 @@ static const struct davinci_pll_obsclk_info dm365_pll1_obsclk_info = { .ocsrc_mask = BIT(4), }; -int dm365_pll1_init(struct device *dev, void __iomem *base) +int dm365_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &dm365_pll1_info, "ref_clk", base); + davinci_pll_clk_register(dev, &dm365_pll1_info, "ref_clk", base, cfgchip); clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base); clk_register_clkdev(clk, "pll1_sysclk1", "dm365-psc"); @@ -119,11 +120,11 @@ static const struct davinci_pll_obsclk_info dm365_pll2_obsclk_info = { .ocsrc_mask = BIT(4), }; -int dm365_pll2_init(struct device *dev, void __iomem *base) +int dm365_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &dm365_pll2_info, "oscin", base); + davinci_pll_clk_register(dev, &dm365_pll2_info, "oscin", base, cfgchip); davinci_pll_sysclk_register(dev, &pll2_sysclk1, base); diff --git a/drivers/clk/davinci/pll-dm644x.c b/drivers/clk/davinci/pll-dm644x.c index 69bf785377cf..7650fadfaac8 100644 --- a/drivers/clk/davinci/pll-dm644x.c +++ b/drivers/clk/davinci/pll-dm644x.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -27,11 +28,11 @@ SYSCLK(2, pll1_sysclk2, pll1_pllen, 4, SYSCLK_FIXED_DIV); SYSCLK(3, pll1_sysclk3, pll1_pllen, 4, SYSCLK_FIXED_DIV); SYSCLK(5, pll1_sysclk5, pll1_pllen, 4, SYSCLK_FIXED_DIV); -int dm644x_pll1_init(struct device *dev, void __iomem *base) +int dm644x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &dm644x_pll1_info, "ref_clk", base); + davinci_pll_clk_register(dev, &dm644x_pll1_info, "ref_clk", base, cfgchip); clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base); clk_register_clkdev(clk, "pll1_sysclk1", "dm644x-psc"); @@ -66,9 +67,9 @@ static const struct davinci_pll_clk_info dm644x_pll2_info = { SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, 0); SYSCLK(2, pll2_sysclk2, pll2_pllen, 4, 0); -int dm644x_pll2_init(struct device *dev, void __iomem *base) +int dm644x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { - davinci_pll_clk_register(dev, &dm644x_pll2_info, "oscin", base); + davinci_pll_clk_register(dev, &dm644x_pll2_info, "oscin", base, cfgchip); davinci_pll_sysclk_register(dev, &pll2_sysclk1, base); diff --git a/drivers/clk/davinci/pll-dm646x.c b/drivers/clk/davinci/pll-dm646x.c index 0ae827e3ce80..26982970df0e 100644 --- a/drivers/clk/davinci/pll-dm646x.c +++ b/drivers/clk/davinci/pll-dm646x.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -29,11 +30,11 @@ SYSCLK(6, pll1_sysclk6, pll1_pllen, 4, 0); SYSCLK(8, pll1_sysclk8, pll1_pllen, 4, 0); SYSCLK(9, pll1_sysclk9, pll1_pllen, 4, 0); -int dm646x_pll1_init(struct device *dev, void __iomem *base) +int dm646x_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { struct clk *clk; - davinci_pll_clk_register(dev, &dm646x_pll1_info, "ref_clk", base); + davinci_pll_clk_register(dev, &dm646x_pll1_info, "ref_clk", base, cfgchip); clk = davinci_pll_sysclk_register(dev, &pll1_sysclk1, base); clk_register_clkdev(clk, "pll1_sysclk1", "dm646x-psc"); @@ -74,9 +75,9 @@ static const struct davinci_pll_clk_info dm646x_pll2_info = { SYSCLK(1, pll2_sysclk1, pll2_pllen, 4, SYSCLK_ALWAYS_ENABLED); -int dm646x_pll2_init(struct device *dev, void __iomem *base) +int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) { - davinci_pll_clk_register(dev, &dm646x_pll2_info, "oscin", base); + davinci_pll_clk_register(dev, &dm646x_pll2_info, "oscin", base, cfgchip); davinci_pll_sysclk_register(dev, &pll2_sysclk1, base); diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c index 23a24c944f1d..2eb981e61185 100644 --- a/drivers/clk/davinci/pll.c +++ b/drivers/clk/davinci/pll.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -223,6 +224,7 @@ static const struct clk_ops dm365_pll_ops = { /** * davinci_pll_div_register - common *DIV clock implementation + * @dev: The PLL platform device or NULL * @name: the clock name * @parent_name: the parent clock name * @reg: the *DIV register @@ -240,17 +242,21 @@ static struct clk *davinci_pll_div_register(struct device *dev, const struct clk_ops *divider_ops = &clk_divider_ops; struct clk_gate *gate; struct clk_divider *divider; + struct clk *clk; + int ret; - gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); + gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) return ERR_PTR(-ENOMEM); gate->reg = reg; gate->bit_idx = DIV_ENABLE_SHIFT; - divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL); - if (!divider) - return ERR_PTR(-ENOMEM); + divider = kzalloc(sizeof(*divider), GFP_KERNEL); + if (!divider) { + ret = -ENOMEM; + goto err_free_gate; + } divider->reg = reg; divider->shift = DIV_RATIO_SHIFT; @@ -261,9 +267,22 @@ static struct clk *davinci_pll_div_register(struct device *dev, divider_ops = &clk_divider_ro_ops; } - return clk_register_composite(dev, name, parent_names, num_parents, - NULL, NULL, ÷r->hw, divider_ops, - &gate->hw, &clk_gate_ops, flags); + clk = clk_register_composite(dev, name, parent_names, num_parents, + NULL, NULL, ÷r->hw, divider_ops, + &gate->hw, &clk_gate_ops, flags); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto err_free_divider; + } + + return clk; + +err_free_divider: + kfree(divider); +err_free_gate: + kfree(gate); + + return ERR_PTR(ret); } struct davinci_pllen_clk { @@ -321,36 +340,17 @@ static int davinci_pllen_rate_change(struct notifier_block *nb, return NOTIFY_OK; } -static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *dev) -{ - struct davinci_pll_platform_data *pdata = dev_get_platdata(dev); - - /* - * Platform data is optional, so allocate a new struct if one was not - * provided. For device tree, this will always be the case. - */ - if (!pdata) - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return NULL; - - /* for device tree, we need to fill in the struct */ - if (dev->of_node) - pdata->cfgchip = - syscon_regmap_lookup_by_compatible("ti,da830-cfgchip"); - - return pdata; -} - static struct notifier_block davinci_pllen_notifier = { .notifier_call = davinci_pllen_rate_change, }; /** * davinci_pll_clk_register - Register a PLL clock + * @dev: The PLL platform device or NULL * @info: The device-specific clock info * @parent_name: The parent clock name * @base: The PLL's memory region + * @cfgchip: CFGCHIP syscon regmap for info->unlock_reg or NULL * * This creates a series of clocks that represent the PLL. * @@ -366,9 +366,9 @@ static struct notifier_block davinci_pllen_notifier = { struct clk *davinci_pll_clk_register(struct device *dev, const struct davinci_pll_clk_info *info, const char *parent_name, - void __iomem *base) + void __iomem *base, + struct regmap *cfgchip) { - struct davinci_pll_platform_data *pdata; char prediv_name[MAX_NAME_SIZE]; char pllout_name[MAX_NAME_SIZE]; char postdiv_name[MAX_NAME_SIZE]; @@ -376,11 +376,12 @@ struct clk *davinci_pll_clk_register(struct device *dev, struct clk_init_data init; struct davinci_pll_clk *pllout; struct davinci_pllen_clk *pllen; - struct clk *pllout_clk, *clk; - - pdata = davinci_pll_get_pdata(dev); - if (!pdata) - return ERR_PTR(-ENOMEM); + struct clk *oscin_clk = NULL; + struct clk *prediv_clk = NULL; + struct clk *pllout_clk; + struct clk *postdiv_clk = NULL; + struct clk *pllen_clk; + int ret; if (info->flags & PLL_HAS_CLKMODE) { /* @@ -392,10 +393,10 @@ struct clk *davinci_pll_clk_register(struct device *dev, * a number of different things. In this driver we use it to * mean the signal after the PLLCTL[CLKMODE] switch. */ - clk = clk_register_fixed_factor(dev, OSCIN_CLK_NAME, - parent_name, 0, 1, 1); - if (IS_ERR(clk)) - return clk; + oscin_clk = clk_register_fixed_factor(dev, OSCIN_CLK_NAME, + parent_name, 0, 1, 1); + if (IS_ERR(oscin_clk)) + return oscin_clk; parent_name = OSCIN_CLK_NAME; } @@ -411,30 +412,34 @@ struct clk *davinci_pll_clk_register(struct device *dev, /* Some? DM355 chips don't correctly report the PREDIV value */ if (info->flags & PLL_PREDIV_FIXED8) - clk = clk_register_fixed_factor(dev, prediv_name, - parent_name, flags, 1, 8); + prediv_clk = clk_register_fixed_factor(dev, prediv_name, + parent_name, flags, 1, 8); else - clk = davinci_pll_div_register(dev, prediv_name, + prediv_clk = davinci_pll_div_register(dev, prediv_name, parent_name, base + PREDIV, fixed, flags); - if (IS_ERR(clk)) - return clk; + if (IS_ERR(prediv_clk)) { + ret = PTR_ERR(prediv_clk); + goto err_unregister_oscin; + } parent_name = prediv_name; } /* Unlock writing to PLL registers */ if (info->unlock_reg) { - if (IS_ERR_OR_NULL(pdata->cfgchip)) + if (IS_ERR_OR_NULL(cfgchip)) dev_warn(dev, "Failed to get CFGCHIP (%ld)\n", - PTR_ERR(pdata->cfgchip)); + PTR_ERR(cfgchip)); else - regmap_write_bits(pdata->cfgchip, info->unlock_reg, + regmap_write_bits(cfgchip, info->unlock_reg, info->unlock_mask, 0); } - pllout = devm_kzalloc(dev, sizeof(*pllout), GFP_KERNEL); - if (!pllout) - return ERR_PTR(-ENOMEM); + pllout = kzalloc(sizeof(*pllout), GFP_KERNEL); + if (!pllout) { + ret = -ENOMEM; + goto err_unregister_prediv; + } snprintf(pllout_name, MAX_NAME_SIZE, "%s_pllout", info->name); @@ -456,9 +461,11 @@ struct clk *davinci_pll_clk_register(struct device *dev, pllout->pllm_min = info->pllm_min; pllout->pllm_max = info->pllm_max; - pllout_clk = devm_clk_register(dev, &pllout->hw); - if (IS_ERR(pllout_clk)) - return pllout_clk; + pllout_clk = clk_register(dev, &pllout->hw); + if (IS_ERR(pllout_clk)) { + ret = PTR_ERR(pllout_clk); + goto err_free_pllout; + } clk_hw_set_rate_range(&pllout->hw, info->pllout_min_rate, info->pllout_max_rate); @@ -474,17 +481,21 @@ struct clk *davinci_pll_clk_register(struct device *dev, if (info->flags & PLL_POSTDIV_ALWAYS_ENABLED) flags |= CLK_IS_CRITICAL; - clk = davinci_pll_div_register(dev, postdiv_name, parent_name, - base + POSTDIV, fixed, flags); - if (IS_ERR(clk)) - return clk; + postdiv_clk = davinci_pll_div_register(dev, postdiv_name, + parent_name, base + POSTDIV, fixed, flags); + if (IS_ERR(postdiv_clk)) { + ret = PTR_ERR(postdiv_clk); + goto err_unregister_pllout; + } parent_name = postdiv_name; } - pllen = devm_kzalloc(dev, sizeof(*pllout), GFP_KERNEL); - if (!pllen) - return ERR_PTR(-ENOMEM); + pllen = kzalloc(sizeof(*pllout), GFP_KERNEL); + if (!pllen) { + ret = -ENOMEM; + goto err_unregister_postdiv; + } snprintf(pllen_name, MAX_NAME_SIZE, "%s_pllen", info->name); @@ -497,17 +508,35 @@ struct clk *davinci_pll_clk_register(struct device *dev, pllen->hw.init = &init; pllen->base = base; - clk = devm_clk_register(dev, &pllen->hw); - if (IS_ERR(clk)) - return clk; + pllen_clk = clk_register(dev, &pllen->hw); + if (IS_ERR(pllen_clk)) { + ret = PTR_ERR(pllen_clk); + goto err_free_pllen; + } - clk_notifier_register(clk, &davinci_pllen_notifier); + clk_notifier_register(pllen_clk, &davinci_pllen_notifier); return pllout_clk; + +err_free_pllen: + kfree(pllen); +err_unregister_postdiv: + clk_unregister(postdiv_clk); +err_unregister_pllout: + clk_unregister(pllout_clk); +err_free_pllout: + kfree(pllout); +err_unregister_prediv: + clk_unregister(prediv_clk); +err_unregister_oscin: + clk_unregister(oscin_clk); + + return ERR_PTR(ret); } /** * davinci_pll_auxclk_register - Register bypass clock (AUXCLK) + * @dev: The PLL platform device or NULL * @name: The clock name * @base: The PLL memory region */ @@ -521,6 +550,7 @@ struct clk *davinci_pll_auxclk_register(struct device *dev, /** * davinci_pll_sysclkbp_clk_register - Register bypass divider clock (SYSCLKBP) + * @dev: The PLL platform device or NULL * @name: The clock name * @base: The PLL memory region */ @@ -535,6 +565,7 @@ struct clk *davinci_pll_sysclkbp_clk_register(struct device *dev, /** * davinci_pll_obsclk_register - Register oscillator divider clock (OBSCLK) + * @dev: The PLL platform device or NULL * @info: The clock info * @base: The PLL memory region */ @@ -546,9 +577,11 @@ davinci_pll_obsclk_register(struct device *dev, struct clk_mux *mux; struct clk_gate *gate; struct clk_divider *divider; + struct clk *clk; u32 oscdiv; + int ret; - mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); + mux = kzalloc(sizeof(*mux), GFP_KERNEL); if (!mux) return ERR_PTR(-ENOMEM); @@ -556,16 +589,20 @@ davinci_pll_obsclk_register(struct device *dev, mux->table = info->table; mux->mask = info->ocsrc_mask; - gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); - if (!gate) - return ERR_PTR(-ENOMEM); + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) { + ret = -ENOMEM; + goto err_free_mux; + } gate->reg = base + CKEN; gate->bit_idx = CKEN_OBSCLK_SHIFT; - divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL); - if (!divider) - return ERR_PTR(-ENOMEM); + divider = kzalloc(sizeof(*divider), GFP_KERNEL); + if (!divider) { + ret = -ENOMEM; + goto err_free_gate; + } divider->reg = base + OSCDIV; divider->shift = DIV_RATIO_SHIFT; @@ -576,11 +613,27 @@ davinci_pll_obsclk_register(struct device *dev, oscdiv |= BIT(DIV_ENABLE_SHIFT); writel(oscdiv, base + OSCDIV); - return clk_register_composite(dev, info->name, info->parent_names, - info->num_parents, - &mux->hw, &clk_mux_ops, - ÷r->hw, &clk_divider_ops, - &gate->hw, &clk_gate_ops, 0); + clk = clk_register_composite(dev, info->name, info->parent_names, + info->num_parents, + &mux->hw, &clk_mux_ops, + ÷r->hw, &clk_divider_ops, + &gate->hw, &clk_gate_ops, 0); + + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto err_free_divider; + } + + return clk; + +err_free_divider: + kfree(divider); +err_free_gate: + kfree(gate); +err_free_mux: + kfree(mux); + + return ERR_PTR(ret); } /* The PLL SYSCLKn clocks have a mechanism for synchronizing rate changes. */ @@ -616,6 +669,7 @@ static struct notifier_block davinci_pll_sysclk_notifier = { /** * davinci_pll_sysclk_register - Register divider clocks (SYSCLKn) + * @dev: The PLL platform device or NULL * @info: The clock info * @base: The PLL memory region */ @@ -630,6 +684,7 @@ davinci_pll_sysclk_register(struct device *dev, struct clk *clk; u32 reg; u32 flags = 0; + int ret; /* PLLDIVn registers are not entirely consecutive */ if (info->id < 4) @@ -637,16 +692,18 @@ davinci_pll_sysclk_register(struct device *dev, else reg = PLLDIV4 + 4 * (info->id - 4); - gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); + gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) return ERR_PTR(-ENOMEM); gate->reg = base + reg; gate->bit_idx = DIV_ENABLE_SHIFT; - divider = devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL); - if (!divider) - return ERR_PTR(-ENOMEM); + divider = kzalloc(sizeof(*divider), GFP_KERNEL); + if (!divider) { + ret = -ENOMEM; + goto err_free_gate; + } divider->reg = base + reg; divider->shift = DIV_RATIO_SHIFT; @@ -668,22 +725,31 @@ davinci_pll_sysclk_register(struct device *dev, clk = clk_register_composite(dev, info->name, &info->parent_name, 1, NULL, NULL, ÷r->hw, divider_ops, &gate->hw, &clk_gate_ops, flags); - if (IS_ERR(clk)) - return clk; + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto err_free_divider; + } clk_notifier_register(clk, &davinci_pll_sysclk_notifier); return clk; + +err_free_divider: + kfree(divider); +err_free_gate: + kfree(gate); + + return ERR_PTR(ret); } -int of_davinci_pll_init(struct device *dev, +int of_davinci_pll_init(struct device *dev, struct device_node *node, const struct davinci_pll_clk_info *info, const struct davinci_pll_obsclk_info *obsclk_info, const struct davinci_pll_sysclk_info **div_info, u8 max_sysclk_id, - void __iomem *base) + void __iomem *base, + struct regmap *cfgchip) { - struct device_node *node = dev->of_node; struct device_node *child; const char *parent_name; struct clk *clk; @@ -693,7 +759,7 @@ int of_davinci_pll_init(struct device *dev, else parent_name = OSCIN_CLK_NAME; - clk = davinci_pll_clk_register(dev, info, parent_name, base); + clk = davinci_pll_clk_register(dev, info, parent_name, base, cfgchip); if (IS_ERR(clk)) { dev_err(dev, "failed to register %s\n", info->name); return PTR_ERR(clk); @@ -711,13 +777,15 @@ int of_davinci_pll_init(struct device *dev, int n_clks = max_sysclk_id + 1; int i; - clk_data = devm_kzalloc(dev, sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); if (!clk_data) return -ENOMEM; - clks = devm_kmalloc_array(dev, n_clks, sizeof(*clks), GFP_KERNEL); - if (!clks) + clks = kmalloc_array(n_clks, sizeof(*clks), GFP_KERNEL); + if (!clks) { + kfree(clk_data); return -ENOMEM; + } clk_data->clks = clks; clk_data->clk_num = n_clks; @@ -770,6 +838,27 @@ int of_davinci_pll_init(struct device *dev, return 0; } +static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *dev) +{ + struct davinci_pll_platform_data *pdata = dev_get_platdata(dev); + + /* + * Platform data is optional, so allocate a new struct if one was not + * provided. For device tree, this will always be the case. + */ + if (!pdata) + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + /* for device tree, we need to fill in the struct */ + if (dev->of_node) + pdata->cfgchip = + syscon_regmap_lookup_by_compatible("ti,da830-cfgchip"); + + return pdata; +} + static const struct of_device_id davinci_pll_of_match[] = { { .compatible = "ti,da850-pll0", .data = of_da850_pll0_init }, { .compatible = "ti,da850-pll1", .data = of_da850_pll1_init }, @@ -791,11 +880,13 @@ static const struct platform_device_id davinci_pll_id_table[] = { { } }; -typedef int (*davinci_pll_init)(struct device *dev, void __iomem *base); +typedef int (*davinci_pll_init)(struct device *dev, void __iomem *base, + struct regmap *cfgchip); static int davinci_pll_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct davinci_pll_platform_data *pdata; const struct of_device_id *of_id; davinci_pll_init pll_init = NULL; struct resource *res; @@ -812,12 +903,18 @@ static int davinci_pll_probe(struct platform_device *pdev) return -EINVAL; } + pdata = davinci_pll_get_pdata(dev); + if (!pdata) { + dev_err(dev, "missing platform data\n"); + return -EINVAL; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); - return pll_init(dev, base); + return pll_init(dev, base, pdata->cfgchip); } static struct platform_driver davinci_pll_driver = { diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h index b1b6fb23f972..562652fc0759 100644 --- a/drivers/clk/davinci/pll.h +++ b/drivers/clk/davinci/pll.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #define PLL_HAS_CLKMODE BIT(0) /* PLL has PLLCTL[CLKMODE] */ @@ -94,7 +95,8 @@ struct davinci_pll_obsclk_info { struct clk *davinci_pll_clk_register(struct device *dev, const struct davinci_pll_clk_info *info, const char *parent_name, - void __iomem *base); + void __iomem *base, + struct regmap *cfgchip); struct clk *davinci_pll_auxclk_register(struct device *dev, const char *name, void __iomem *base); @@ -110,32 +112,24 @@ davinci_pll_sysclk_register(struct device *dev, const struct davinci_pll_sysclk_info *info, void __iomem *base); -int of_davinci_pll_init(struct device *dev, +int of_davinci_pll_init(struct device *dev, struct device_node *node, const struct davinci_pll_clk_info *info, const struct davinci_pll_obsclk_info *obsclk_info, const struct davinci_pll_sysclk_info **div_info, u8 max_sysclk_id, - void __iomem *base); + void __iomem *base, + struct regmap *cfgchip); /* Platform-specific callbacks */ -int da830_pll_init(struct device *dev, void __iomem *base); +int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); +int of_da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); +int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); -int da850_pll0_init(struct device *dev, void __iomem *base); -int da850_pll1_init(struct device *dev, void __iomem *base); -int of_da850_pll0_init(struct device *dev, void __iomem *base); -int of_da850_pll1_init(struct device *dev, void __iomem *base); +int dm355_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); -int dm355_pll1_init(struct device *dev, void __iomem *base); -int dm355_pll2_init(struct device *dev, void __iomem *base); +int dm644x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); -int dm365_pll1_init(struct device *dev, void __iomem *base); -int dm365_pll2_init(struct device *dev, void __iomem *base); - -int dm644x_pll1_init(struct device *dev, void __iomem *base); -int dm644x_pll2_init(struct device *dev, void __iomem *base); - -int dm646x_pll1_init(struct device *dev, void __iomem *base); -int dm646x_pll2_init(struct device *dev, void __iomem *base); +int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); #endif /* __CLK_DAVINCI_PLL_H___ */ -- cgit v1.2.3 From 17d8bacf19bb5ea5f258f9c0644d5688f9ba03a9 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 25 May 2018 13:11:48 -0500 Subject: clk: davinci: da850-pll: change PLL0 to CLK_OF_DECLARE PLL0 on davinci/da850-type device needs to be registered early in boot because it is needed for clocksource/clockevent. Change the driver to use CLK_OF_DECLARE for this special case. Reviewed-by: Sekhar Nori Signed-off-by: David Lechner Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-8-david@lechnology.com --- drivers/clk/davinci/pll-da850.c | 21 +++++++++++++++++---- drivers/clk/davinci/pll.c | 4 +++- drivers/clk/davinci/pll.h | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/pll-da850.c b/drivers/clk/davinci/pll-da850.c index 59cc2e3733f9..0f7198191ea2 100644 --- a/drivers/clk/davinci/pll-da850.c +++ b/drivers/clk/davinci/pll-da850.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -136,11 +138,22 @@ static const struct davinci_pll_sysclk_info *da850_pll0_sysclk_info[] = { NULL }; -int of_da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) +void of_da850_pll0_init(struct device_node *node) { - return of_davinci_pll_init(dev, dev->of_node, &da850_pll0_info, - &da850_pll0_obsclk_info, - da850_pll0_sysclk_info, 7, base, cfgchip); + void __iomem *base; + struct regmap *cfgchip; + + base = of_iomap(node, 0); + if (!base) { + pr_err("%s: ioremap failed\n", __func__); + return; + } + + cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip"); + + of_davinci_pll_init(NULL, node, &da850_pll0_info, + &da850_pll0_obsclk_info, + da850_pll0_sysclk_info, 7, base, cfgchip); } static const struct davinci_pll_clk_info da850_pll1_info = { diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c index 2eb981e61185..84a343060bc8 100644 --- a/drivers/clk/davinci/pll.c +++ b/drivers/clk/davinci/pll.c @@ -859,8 +859,10 @@ static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *de return pdata; } +/* needed in early boot for clocksource/clockevent */ +CLK_OF_DECLARE(da850_pll0, "ti,da850-pll0", of_da850_pll0_init); + static const struct of_device_id davinci_pll_of_match[] = { - { .compatible = "ti,da850-pll0", .data = of_da850_pll0_init }, { .compatible = "ti,da850-pll1", .data = of_da850_pll1_init }, { } }; diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h index 562652fc0759..b2e5c4496645 100644 --- a/drivers/clk/davinci/pll.h +++ b/drivers/clk/davinci/pll.h @@ -123,7 +123,7 @@ int of_davinci_pll_init(struct device *dev, struct device_node *node, /* Platform-specific callbacks */ int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); -int of_da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); +void of_da850_pll0_init(struct device_node *node); int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); int dm355_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); -- cgit v1.2.3 From 043eaa70ad736380a631e820e32ad9176b020887 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 25 May 2018 13:11:49 -0500 Subject: clk: davinci: psc: allow for dev == NULL On some davinci SoCs, we need to register the PSC clocks during early boot because they are needed for clocksource/clockevent. These changes allow for dev == NULL because in this case, we won't have a platform device for the clocks. Signed-off-by: David Lechner Reviewed-by: Sekhar Nori Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-9-david@lechnology.com --- drivers/clk/davinci/psc-dm355.c | 3 ++- drivers/clk/davinci/psc-dm365.c | 3 ++- drivers/clk/davinci/psc-dm644x.c | 3 ++- drivers/clk/davinci/psc-dm646x.c | 3 ++- drivers/clk/davinci/psc.c | 58 ++++++++++++++++++++++++++++++---------- 5 files changed, 52 insertions(+), 18 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/psc-dm355.c b/drivers/clk/davinci/psc-dm355.c index 128e7345b20c..ddd250107c4e 100644 --- a/drivers/clk/davinci/psc-dm355.c +++ b/drivers/clk/davinci/psc-dm355.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -68,7 +69,7 @@ static const struct davinci_lpsc_clk_info dm355_psc_info[] = { { } }; -static int dm355_psc_init(struct device *dev, void __iomem *base) +int dm355_psc_init(struct device *dev, void __iomem *base) { return davinci_psc_register_clocks(dev, dm355_psc_info, 42, base); } diff --git a/drivers/clk/davinci/psc-dm365.c b/drivers/clk/davinci/psc-dm365.c index 289af3913fb0..8c73086cc676 100644 --- a/drivers/clk/davinci/psc-dm365.c +++ b/drivers/clk/davinci/psc-dm365.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -86,7 +87,7 @@ static const struct davinci_lpsc_clk_info dm365_psc_info[] = { { } }; -static int dm365_psc_init(struct device *dev, void __iomem *base) +int dm365_psc_init(struct device *dev, void __iomem *base) { return davinci_psc_register_clocks(dev, dm365_psc_info, 52, base); } diff --git a/drivers/clk/davinci/psc-dm644x.c b/drivers/clk/davinci/psc-dm644x.c index c22367baa46f..fc0230e3a3d6 100644 --- a/drivers/clk/davinci/psc-dm644x.c +++ b/drivers/clk/davinci/psc-dm644x.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -63,7 +64,7 @@ static const struct davinci_lpsc_clk_info dm644x_psc_info[] = { { } }; -static int dm644x_psc_init(struct device *dev, void __iomem *base) +int dm644x_psc_init(struct device *dev, void __iomem *base) { return davinci_psc_register_clocks(dev, dm644x_psc_info, 41, base); } diff --git a/drivers/clk/davinci/psc-dm646x.c b/drivers/clk/davinci/psc-dm646x.c index 468ef86ea40b..c3f82ed70a80 100644 --- a/drivers/clk/davinci/psc-dm646x.c +++ b/drivers/clk/davinci/psc-dm646x.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -58,7 +59,7 @@ static const struct davinci_lpsc_clk_info dm646x_psc_info[] = { { } }; -static int dm646x_psc_init(struct device *dev, void __iomem *base) +int dm646x_psc_init(struct device *dev, void __iomem *base) { return davinci_psc_register_clocks(dev, dm646x_psc_info, 46, base); } diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index ce170e600f09..6326ba1fe3cc 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ struct davinci_psc_data { /** * struct davinci_lpsc_clk - LPSC clock structure - * @dev: the device that provides this LPSC + * @dev: the device that provides this LPSC or NULL * @hw: clk_hw for the LPSC * @pm_domain: power domain for the LPSC * @genpd_clk: clock reference owned by @pm_domain @@ -221,6 +222,7 @@ static void davinci_psc_genpd_detach_dev(struct generic_pm_domain *pm_domain, /** * davinci_lpsc_clk_register - register LPSC clock + * @dev: the clocks's device or NULL * @name: name of this clock * @parent_name: name of clock's parent * @regmap: PSC MMIO region @@ -238,7 +240,7 @@ davinci_lpsc_clk_register(struct device *dev, const char *name, int ret; bool is_on; - lpsc = devm_kzalloc(dev, sizeof(*lpsc), GFP_KERNEL); + lpsc = kzalloc(sizeof(*lpsc), GFP_KERNEL); if (!lpsc) return ERR_PTR(-ENOMEM); @@ -261,9 +263,15 @@ davinci_lpsc_clk_register(struct device *dev, const char *name, lpsc->pd = pd; lpsc->flags = flags; - ret = devm_clk_hw_register(dev, &lpsc->hw); - if (ret < 0) + ret = clk_hw_register(dev, &lpsc->hw); + if (ret < 0) { + kfree(lpsc); return ERR_PTR(ret); + } + + /* for now, genpd is only registered when using device-tree */ + if (!dev || !dev->of_node) + return lpsc; /* genpd attach needs a way to look up this clock */ ret = clk_hw_register_clkdev(&lpsc->hw, name, best_dev_name(dev)); @@ -378,13 +386,15 @@ __davinci_psc_register_clocks(struct device *dev, struct regmap *regmap; int i, ret; - psc = devm_kzalloc(dev, sizeof(*psc), GFP_KERNEL); + psc = kzalloc(sizeof(*psc), GFP_KERNEL); if (!psc) return ERR_PTR(-ENOMEM); - clks = devm_kmalloc_array(dev, num_clks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return ERR_PTR(-ENOMEM); + clks = kmalloc_array(num_clks, sizeof(*clks), GFP_KERNEL); + if (!clks) { + ret = -ENOMEM; + goto err_free_psc; + } psc->clk_data.clks = clks; psc->clk_data.clk_num = num_clks; @@ -396,16 +406,20 @@ __davinci_psc_register_clocks(struct device *dev, for (i = 0; i < num_clks; i++) clks[i] = ERR_PTR(-ENOENT); - pm_domains = devm_kcalloc(dev, num_clks, sizeof(*pm_domains), GFP_KERNEL); - if (!pm_domains) - return ERR_PTR(-ENOMEM); + pm_domains = kcalloc(num_clks, sizeof(*pm_domains), GFP_KERNEL); + if (!pm_domains) { + ret = -ENOMEM; + goto err_free_clks; + } psc->pm_data.domains = pm_domains; psc->pm_data.num_domains = num_clks; - regmap = devm_regmap_init_mmio(dev, base, &davinci_psc_regmap_config); - if (IS_ERR(regmap)) - return ERR_CAST(regmap); + regmap = regmap_init_mmio(dev, base, &davinci_psc_regmap_config); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto err_free_pm_domains; + } for (; info->name; info++) { struct davinci_lpsc_clk *lpsc; @@ -423,6 +437,13 @@ __davinci_psc_register_clocks(struct device *dev, pm_domains[info->md] = &lpsc->pm_domain; } + /* + * for now, a reset controller is only registered when there is a device + * to associate it with. + */ + if (!dev) + return psc; + psc->rcdev.ops = &davinci_psc_reset_ops; psc->rcdev.owner = THIS_MODULE; psc->rcdev.dev = dev; @@ -436,6 +457,15 @@ __davinci_psc_register_clocks(struct device *dev, dev_warn(dev, "Failed to register reset controller (%d)\n", ret); return psc; + +err_free_pm_domains: + kfree(pm_domains); +err_free_clks: + kfree(clks); +err_free_psc: + kfree(psc); + + return ERR_PTR(ret); } int davinci_psc_register_clocks(struct device *dev, -- cgit v1.2.3 From 4eff0bebf4ed5ed6d1a4dffe7dfd420b270c229a Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 25 May 2018 13:11:50 -0500 Subject: clk: davinci: Fix link errors when not all SoCs are enabled This fixes linker errors due to undefined symbols when one or more of the TI DaVinci SoCs is not enabled in the kernel config. Signed-off-by: David Lechner Signed-off-by: Michael Turquette Link: lkml.kernel.org/r/20180525181150.17873-10-david@lechnology.com --- drivers/clk/davinci/pll.c | 16 ++++++++++++++++ drivers/clk/davinci/pll.h | 11 ++++++++--- drivers/clk/davinci/psc.c | 14 ++++++++++++++ drivers/clk/davinci/psc.h | 12 ++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c index 84a343060bc8..65abd371692d 100644 --- a/drivers/clk/davinci/pll.c +++ b/drivers/clk/davinci/pll.c @@ -860,25 +860,41 @@ static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *de } /* needed in early boot for clocksource/clockevent */ +#ifdef CONFIG_ARCH_DAVINCI_DA850 CLK_OF_DECLARE(da850_pll0, "ti,da850-pll0", of_da850_pll0_init); +#endif static const struct of_device_id davinci_pll_of_match[] = { +#ifdef CONFIG_ARCH_DAVINCI_DA850 { .compatible = "ti,da850-pll1", .data = of_da850_pll1_init }, +#endif { } }; static const struct platform_device_id davinci_pll_id_table[] = { +#ifdef CONFIG_ARCH_DAVINCI_DA830 { .name = "da830-pll", .driver_data = (kernel_ulong_t)da830_pll_init }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DA850 { .name = "da850-pll0", .driver_data = (kernel_ulong_t)da850_pll0_init }, { .name = "da850-pll1", .driver_data = (kernel_ulong_t)da850_pll1_init }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM355 { .name = "dm355-pll1", .driver_data = (kernel_ulong_t)dm355_pll1_init }, { .name = "dm355-pll2", .driver_data = (kernel_ulong_t)dm355_pll2_init }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM365 { .name = "dm365-pll1", .driver_data = (kernel_ulong_t)dm365_pll1_init }, { .name = "dm365-pll2", .driver_data = (kernel_ulong_t)dm365_pll2_init }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM644x { .name = "dm644x-pll1", .driver_data = (kernel_ulong_t)dm644x_pll1_init }, { .name = "dm644x-pll2", .driver_data = (kernel_ulong_t)dm644x_pll2_init }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM646x { .name = "dm646x-pll1", .driver_data = (kernel_ulong_t)dm646x_pll1_init }, { .name = "dm646x-pll2", .driver_data = (kernel_ulong_t)dm646x_pll2_init }, +#endif { } }; diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h index b2e5c4496645..7cc354dd29e2 100644 --- a/drivers/clk/davinci/pll.h +++ b/drivers/clk/davinci/pll.h @@ -122,14 +122,19 @@ int of_davinci_pll_init(struct device *dev, struct device_node *node, /* Platform-specific callbacks */ +#ifdef CONFIG_ARCH_DAVINCI_DA850 int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); void of_da850_pll0_init(struct device_node *node); int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); - +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM355 int dm355_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); - +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM644x int dm644x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); - +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM646x int dm646x_pll2_init(struct device *dev, void __iomem *base, struct regmap *cfgchip); +#endif #endif /* __CLK_DAVINCI_PLL_H___ */ diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index 6326ba1fe3cc..fffbed5e263b 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -513,20 +513,34 @@ int of_davinci_psc_clk_init(struct device *dev, } static const struct of_device_id davinci_psc_of_match[] = { +#ifdef CONFIG_ARCH_DAVINCI_DA850 { .compatible = "ti,da850-psc0", .data = &of_da850_psc0_init_data }, { .compatible = "ti,da850-psc1", .data = &of_da850_psc1_init_data }, +#endif { } }; static const struct platform_device_id davinci_psc_id_table[] = { +#ifdef CONFIG_ARCH_DAVINCI_DA830 { .name = "da830-psc0", .driver_data = (kernel_ulong_t)&da830_psc0_init_data }, { .name = "da830-psc1", .driver_data = (kernel_ulong_t)&da830_psc1_init_data }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DA850 { .name = "da850-psc0", .driver_data = (kernel_ulong_t)&da850_psc0_init_data }, { .name = "da850-psc1", .driver_data = (kernel_ulong_t)&da850_psc1_init_data }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM355 { .name = "dm355-psc", .driver_data = (kernel_ulong_t)&dm355_psc_init_data }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM365 { .name = "dm365-psc", .driver_data = (kernel_ulong_t)&dm365_psc_init_data }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM644x { .name = "dm644x-psc", .driver_data = (kernel_ulong_t)&dm644x_psc_init_data }, +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM646x { .name = "dm646x-psc", .driver_data = (kernel_ulong_t)&dm646x_psc_init_data }, +#endif { } }; diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h index c2a7df6413fe..6a42529d31a9 100644 --- a/drivers/clk/davinci/psc.h +++ b/drivers/clk/davinci/psc.h @@ -94,15 +94,27 @@ struct davinci_psc_init_data { int (*psc_init)(struct device *dev, void __iomem *base); }; +#ifdef CONFIG_ARCH_DAVINCI_DA830 extern const struct davinci_psc_init_data da830_psc0_init_data; extern const struct davinci_psc_init_data da830_psc1_init_data; +#endif +#ifdef CONFIG_ARCH_DAVINCI_DA850 extern const struct davinci_psc_init_data da850_psc0_init_data; extern const struct davinci_psc_init_data da850_psc1_init_data; extern const struct davinci_psc_init_data of_da850_psc0_init_data; extern const struct davinci_psc_init_data of_da850_psc1_init_data; +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM355 extern const struct davinci_psc_init_data dm355_psc_init_data; +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM356 extern const struct davinci_psc_init_data dm365_psc_init_data; +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM644x extern const struct davinci_psc_init_data dm644x_psc_init_data; +#endif +#ifdef CONFIG_ARCH_DAVINCI_DM646x extern const struct davinci_psc_init_data dm646x_psc_init_data; +#endif #endif /* __CLK_DAVINCI_PSC_H__ */ -- cgit v1.2.3