From 3ee5f8ab5e718afdde9984a089137360bdfc66eb Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sat, 14 Sep 2019 15:51:00 +0200 Subject: [PATCH 001/160] clk: sunxi-ng: h6: Use sigma-delta modulation for audio PLL Audio devices needs exact clock rates in order to correctly reproduce the sound. Until now, only integer factors were used to configure H6 audio PLL which resulted in inexact rates. Fix that by adding support for fractional factors using sigma-delta modulation look-up table. It contains values for two most commonly used audio base frequencies. Signed-off-by: Jernej Skrabec Acked-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index d89353a3cdec..ed6338d74474 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -203,12 +203,21 @@ static struct ccu_nkmp pll_hsic_clk = { * hardcode it to match with the clock names. */ #define SUN50I_H6_PLL_AUDIO_REG 0x078 + +static struct ccu_sdm_setting pll_audio_sdm_table[] = { + { .rate = 541900800, .pattern = 0xc001288d, .m = 1, .n = 22 }, + { .rate = 589824000, .pattern = 0xc00126e9, .m = 1, .n = 24 }, +}; + static struct ccu_nm pll_audio_base_clk = { .enable = BIT(31), .lock = BIT(28), .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, + BIT(24), 0x178, BIT(31)), .common = { + .features = CCU_FEATURE_SIGMA_DELTA_MOD, .reg = 0x078, .hw.init = CLK_HW_INIT("pll-audio-base", "osc24M", &ccu_nm_ops, @@ -753,12 +762,12 @@ static const struct clk_hw *clk_parent_pll_audio[] = { }; /* - * The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a - * fixed post-divider 2. + * The divider of pll-audio is fixed to 24 for now, so 24576000 and 22579200 + * rates can be set exactly in conjunction with sigma-delta modulation. */ static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio", clk_parent_pll_audio, - 8, 1, CLK_SET_RATE_PARENT); + 24, 1, CLK_SET_RATE_PARENT); static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x", clk_parent_pll_audio, 4, 1, CLK_SET_RATE_PARENT); @@ -1215,12 +1224,12 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev) } /* - * Force the post-divider of pll-audio to 8 and the output divider - * of it to 1, to make the clock name represents the real frequency. + * Force the post-divider of pll-audio to 12 and the output divider + * of it to 2, so 24576000 and 22579200 rates can be set exactly. */ val = readl(reg + SUN50I_H6_PLL_AUDIO_REG); val &= ~(GENMASK(21, 16) | BIT(0)); - writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG); + writel(val | (11 << 16) | BIT(0), reg + SUN50I_H6_PLL_AUDIO_REG); /* * First clock parent (osc32K) is unusable for CEC. But since there From be67c41781cb4c06a4acb0b92db0cbb728e955e2 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 5 Sep 2019 07:52:06 +0100 Subject: [PATCH 002/160] dt-bindings: power: Add r8a774b1 SYSC power domain definitions This patch adds power domain indices for the RZ/G2N (a.k.a r8a774b1) SoC. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/1567666326-27373-1-git-send-email-biju.das@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/power/r8a774b1-sysc.h | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 include/dt-bindings/power/r8a774b1-sysc.h diff --git a/include/dt-bindings/power/r8a774b1-sysc.h b/include/dt-bindings/power/r8a774b1-sysc.h new file mode 100644 index 000000000000..373736402f04 --- /dev/null +++ b/include/dt-bindings/power/r8a774b1-sysc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2019 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_POWER_R8A774B1_SYSC_H__ +#define __DT_BINDINGS_POWER_R8A774B1_SYSC_H__ + +/* + * These power domain indices match the numbers of the interrupt bits + * representing the power areas in the various Interrupt Registers + * (e.g. SYSCISR, Interrupt Status Register) + */ + +#define R8A774B1_PD_CA57_CPU0 0 +#define R8A774B1_PD_CA57_CPU1 1 +#define R8A774B1_PD_A3VP 9 +#define R8A774B1_PD_CA57_SCU 12 +#define R8A774B1_PD_A3VC 14 +#define R8A774B1_PD_3DG_A 17 +#define R8A774B1_PD_3DG_B 18 +#define R8A774B1_PD_A2VC1 26 + +/* Always-on power area */ +#define R8A774B1_PD_ALWAYS_ON 32 + +#endif /* __DT_BINDINGS_POWER_R8A774B1_SYSC_H__ */ From 54ce17dd40fd846a7ac1e87e1103032933d2bd21 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 5 Sep 2019 07:52:40 +0100 Subject: [PATCH 003/160] dt-bindings: clk: Add r8a774b1 CPG Core Clock Definitions Add all RZ/G2N Clock Pulse Generator Core Clock Outputs, as listed in Table 8.2d ("List of Clocks [RZ/G2N]") of the RZ/G2N Hardware User's Manual. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/1567666360-28035-1-git-send-email-biju.das@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r8a774b1-cpg-mssr.h | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 include/dt-bindings/clock/r8a774b1-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a774b1-cpg-mssr.h b/include/dt-bindings/clock/r8a774b1-cpg-mssr.h new file mode 100644 index 000000000000..1355451b74b0 --- /dev/null +++ b/include/dt-bindings/clock/r8a774b1-cpg-mssr.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2019 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A774B1_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A774B1_CPG_MSSR_H__ + +#include + +/* r8a774b1 CPG Core Clocks */ +#define R8A774B1_CLK_Z 0 +#define R8A774B1_CLK_ZG 1 +#define R8A774B1_CLK_ZTR 2 +#define R8A774B1_CLK_ZTRD2 3 +#define R8A774B1_CLK_ZT 4 +#define R8A774B1_CLK_ZX 5 +#define R8A774B1_CLK_S0D1 6 +#define R8A774B1_CLK_S0D2 7 +#define R8A774B1_CLK_S0D3 8 +#define R8A774B1_CLK_S0D4 9 +#define R8A774B1_CLK_S0D6 10 +#define R8A774B1_CLK_S0D8 11 +#define R8A774B1_CLK_S0D12 12 +#define R8A774B1_CLK_S1D2 13 +#define R8A774B1_CLK_S1D4 14 +#define R8A774B1_CLK_S2D1 15 +#define R8A774B1_CLK_S2D2 16 +#define R8A774B1_CLK_S2D4 17 +#define R8A774B1_CLK_S3D1 18 +#define R8A774B1_CLK_S3D2 19 +#define R8A774B1_CLK_S3D4 20 +#define R8A774B1_CLK_LB 21 +#define R8A774B1_CLK_CL 22 +#define R8A774B1_CLK_ZB3 23 +#define R8A774B1_CLK_ZB3D2 24 +#define R8A774B1_CLK_CR 25 +#define R8A774B1_CLK_DDR 26 +#define R8A774B1_CLK_SD0H 27 +#define R8A774B1_CLK_SD0 28 +#define R8A774B1_CLK_SD1H 29 +#define R8A774B1_CLK_SD1 30 +#define R8A774B1_CLK_SD2H 31 +#define R8A774B1_CLK_SD2 32 +#define R8A774B1_CLK_SD3H 33 +#define R8A774B1_CLK_SD3 34 +#define R8A774B1_CLK_RPC 35 +#define R8A774B1_CLK_RPCD2 36 +#define R8A774B1_CLK_MSO 37 +#define R8A774B1_CLK_HDMI 38 +#define R8A774B1_CLK_CSI0 39 +#define R8A774B1_CLK_CP 40 +#define R8A774B1_CLK_CPEX 41 +#define R8A774B1_CLK_R 42 +#define R8A774B1_CLK_OSC 43 +#define R8A774B1_CLK_CANFD 44 + +#endif /* __DT_BINDINGS_CLOCK_R8A774B1_CPG_MSSR_H__ */ From ba28236e043dae273ce22782008e667e6e4bbd5e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 27 Aug 2019 15:22:12 +0200 Subject: [PATCH 004/160] clk: renesas: mstp: Delete unnecessary kfree() in cpg_mstp_clocks_init() A NULL pointer would be passed to a call of the function kfree() directly after a call of the function kzalloc() failed at one place. Remove this superfluous function call. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Link: https://lore.kernel.org/r/e66b822b-026b-29cc-e461-6334aafd1d30@web.de Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/clk-mstp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index e326e6dc09fc..003e9ce45757 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -189,10 +189,8 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) unsigned int i; group = kzalloc(struct_size(group, clks, MSTP_MAX_CLOCKS), GFP_KERNEL); - if (group == NULL) { - kfree(group); + if (!group) return; - } clks = group->clks; spin_lock_init(&group->lock); From 58256143cff7c2e0a72fe609e797a36b26a3c381 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:36:15 +0200 Subject: [PATCH 005/160] clk: renesas: Remove R-Car Gen2 legacy DT clock support As of commit 362b334b17943d84 ("ARM: dts: r8a7791: Convert to new CPG/MSSR bindings"), all upstream R-Car Gen2 device tree source files use the unified "Renesas Clock Pulse Generator / Module Standby and Software Reset" DT bindings. Hence remove backward compatibility with old R-Car Gen2 device trees describing a hierarchical representation of the various CPG and MSTP clocks. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20190830133615.11274-1-geert+renesas@glider.be --- drivers/clk/renesas/Kconfig | 20 -- drivers/clk/renesas/Makefile | 1 - drivers/clk/renesas/clk-rcar-gen2.c | 457 ---------------------------- 3 files changed, 478 deletions(-) delete mode 100644 drivers/clk/renesas/clk-rcar-gen2.c diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index b879e3e3a6b4..afca67f7e27a 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -31,17 +31,6 @@ config CLK_RENESAS if CLK_RENESAS -config CLK_RENESAS_LEGACY - bool "Legacy DT clock support" - depends on CLK_R8A7790 || CLK_R8A7791 || CLK_R8A7792 || CLK_R8A7794 - help - Enable backward compatibility with old device trees describing a - hierarchical representation of the various CPG and MSTP clocks. - - Say Y if you want your kernel to work with old DTBs. - It is safe to say N if you use the DTS that is supplied with the - current kernel source tree. - # SoC config CLK_EMEV2 bool "Emma Mobile EV2 clock support" if COMPILE_TEST @@ -94,24 +83,20 @@ config CLK_R8A7779 config CLK_R8A7790 bool "R-Car H2 clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 config CLK_R8A7791 bool "R-Car M2-W/N clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 config CLK_R8A7792 bool "R-Car V2H clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG config CLK_R8A7794 bool "R-Car E2 clock support" if COMPILE_TEST - select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY select CLK_RCAR_GEN2_CPG select CLK_RENESAS_DIV6 @@ -155,11 +140,6 @@ config CLK_SH73A0 # Family -config CLK_RCAR_GEN2 - bool "R-Car Gen2 legacy clock support" if COMPILE_TEST - select CLK_RENESAS_CPG_MSTP - select CLK_RENESAS_DIV6 - config CLK_RCAR_GEN2_CPG bool "R-Car Gen2 CPG clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSSR diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index c793e3cc9452..eab3af2539c7 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o # Family -obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c deleted file mode 100644 index da9fe3f032eb..000000000000 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ /dev/null @@ -1,457 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * rcar_gen2 Core CPG Clocks - * - * Copyright (C) 2013 Ideas On Board SPRL - * - * Contact: Laurent Pinchart - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct rcar_gen2_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -#define CPG_FRQCRB 0x00000004 -#define CPG_FRQCRB_KICK BIT(31) -#define CPG_SDCKCR 0x00000074 -#define CPG_PLL0CR 0x000000d8 -#define CPG_FRQCRC 0x000000e0 -#define CPG_FRQCRC_ZFC_MASK (0x1f << 8) -#define CPG_FRQCRC_ZFC_SHIFT 8 -#define CPG_ADSPCKCR 0x0000025c -#define CPG_RCANCKCR 0x00000270 - -/* ----------------------------------------------------------------------------- - * Z Clock - * - * Traits of this clock: - * prepare - clk_prepare only ensures that parents are prepared - * enable - clk_enable only ensures that parents are enabled - * rate - rate is adjustable. clk->rate = parent->rate * mult / 32 - * parent - fixed parent. No clk_set_parent support - */ - -struct cpg_z_clk { - struct clk_hw hw; - void __iomem *reg; - void __iomem *kick_reg; -}; - -#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) - -static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - unsigned int val; - - val = (readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK) >> CPG_FRQCRC_ZFC_SHIFT; - mult = 32 - val; - - return div_u64((u64)parent_rate * mult, 32); -} - -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long prate = *parent_rate; - unsigned int mult; - - if (!prate) - prate = 1; - - mult = div_u64((u64)rate * 32, prate); - mult = clamp(mult, 1U, 32U); - - return *parent_rate / 32 * mult; -} - -static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - u32 val, kick; - unsigned int i; - - mult = div_u64((u64)rate * 32, parent_rate); - mult = clamp(mult, 1U, 32U); - - if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) - return -EBUSY; - - val = readl(zclk->reg); - val &= ~CPG_FRQCRC_ZFC_MASK; - val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; - writel(val, zclk->reg); - - /* - * Set KICK bit in FRQCRB to update hardware setting and wait for - * clock change completion. - */ - kick = readl(zclk->kick_reg); - kick |= CPG_FRQCRB_KICK; - writel(kick, zclk->kick_reg); - - /* - * Note: There is no HW information about the worst case latency. - * - * Using experimental measurements, it seems that no more than - * ~10 iterations are needed, independently of the CPU rate. - * Since this value might be dependent on external xtal rate, pll1 - * rate or even the other emulation clocks rate, use 1000 as a - * "super" safe value. - */ - for (i = 1000; i; i--) { - if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) - return 0; - - cpu_relax(); - } - - return -ETIMEDOUT; -} - -static const struct clk_ops cpg_z_clk_ops = { - .recalc_rate = cpg_z_clk_recalc_rate, - .round_rate = cpg_z_clk_round_rate, - .set_rate = cpg_z_clk_set_rate, -}; - -static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg) -{ - static const char *parent_name = "pll0"; - struct clk_init_data init; - struct cpg_z_clk *zclk; - struct clk *clk; - - zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); - if (!zclk) - return ERR_PTR(-ENOMEM); - - init.name = "z"; - init.ops = &cpg_z_clk_ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - zclk->reg = cpg->reg + CPG_FRQCRC; - zclk->kick_reg = cpg->reg + CPG_FRQCRB; - zclk->hw.init = &init; - - clk = clk_register(NULL, &zclk->hw); - if (IS_ERR(clk)) - kfree(zclk); - - return clk; -} - -static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg, - struct device_node *np) -{ - const char *parent_name = of_clk_get_parent_name(np, 1); - struct clk_fixed_factor *fixed; - struct clk_gate *gate; - struct clk *clk; - - fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); - if (!fixed) - return ERR_PTR(-ENOMEM); - - fixed->mult = 1; - fixed->div = 6; - - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) { - kfree(fixed); - return ERR_PTR(-ENOMEM); - } - - gate->reg = cpg->reg + CPG_RCANCKCR; - gate->bit_idx = 8; - gate->flags = CLK_GATE_SET_TO_DISABLE; - gate->lock = &cpg->lock; - - clk = clk_register_composite(NULL, "rcan", &parent_name, 1, NULL, NULL, - &fixed->hw, &clk_fixed_factor_ops, - &gate->hw, &clk_gate_ops, 0); - if (IS_ERR(clk)) { - kfree(gate); - kfree(fixed); - } - - return clk; -} - -/* ADSP divisors */ -static const struct clk_div_table cpg_adsp_div_table[] = { - { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, - { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, - { 10, 36 }, { 11, 48 }, { 0, 0 }, -}; - -static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg) -{ - const char *parent_name = "pll1"; - struct clk_divider *div; - struct clk_gate *gate; - struct clk *clk; - - div = kzalloc(sizeof(*div), GFP_KERNEL); - if (!div) - return ERR_PTR(-ENOMEM); - - div->reg = cpg->reg + CPG_ADSPCKCR; - div->width = 4; - div->table = cpg_adsp_div_table; - div->lock = &cpg->lock; - - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) { - kfree(div); - return ERR_PTR(-ENOMEM); - } - - gate->reg = cpg->reg + CPG_ADSPCKCR; - gate->bit_idx = 8; - gate->flags = CLK_GATE_SET_TO_DISABLE; - gate->lock = &cpg->lock; - - clk = clk_register_composite(NULL, "adsp", &parent_name, 1, NULL, NULL, - &div->hw, &clk_divider_ops, - &gate->hw, &clk_gate_ops, 0); - if (IS_ERR(clk)) { - kfree(gate); - kfree(div); - } - - return clk; -} - -/* ----------------------------------------------------------------------------- - * CPG Clock Data - */ - -/* - * MD EXTAL PLL0 PLL1 PLL3 - * 14 13 19 (MHz) *1 *1 - *--------------------------------------------------- - * 0 0 0 15 x 1 x172/2 x208/2 x106 - * 0 0 1 15 x 1 x172/2 x208/2 x88 - * 0 1 0 20 x 1 x130/2 x156/2 x80 - * 0 1 1 20 x 1 x130/2 x156/2 x66 - * 1 0 0 26 / 2 x200/2 x240/2 x122 - * 1 0 1 26 / 2 x200/2 x240/2 x102 - * 1 1 0 30 / 2 x172/2 x208/2 x106 - * 1 1 1 30 / 2 x172/2 x208/2 x88 - * - * *1 : Table 7.6 indicates VCO output (PLLx = VCO/2) - */ -#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ - (((md) & BIT(13)) >> 12) | \ - (((md) & BIT(19)) >> 19)) -struct cpg_pll_config { - unsigned int extal_div; - unsigned int pll1_mult; - unsigned int pll3_mult; - unsigned int pll0_mult; /* For R-Car V2H and E2 only */ -}; - -static const struct cpg_pll_config cpg_pll_configs[8] __initconst = { - { 1, 208, 106, 200 }, { 1, 208, 88, 200 }, - { 1, 156, 80, 150 }, { 1, 156, 66, 150 }, - { 2, 240, 122, 230 }, { 2, 240, 102, 230 }, - { 2, 208, 106, 200 }, { 2, 208, 88, 200 }, -}; - -/* SDHI divisors */ -static const struct clk_div_table cpg_sdh_div_table[] = { - { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, - { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, - { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 }, -}; - -static const struct clk_div_table cpg_sd01_div_table[] = { - { 4, 8 }, - { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, - { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 }, -}; - -/* ----------------------------------------------------------------------------- - * Initialization - */ - -static u32 cpg_mode __initdata; - -static const char * const pll0_mult_match[] = { - "renesas,r8a7792-cpg-clocks", - "renesas,r8a7794-cpg-clocks", - NULL -}; - -static struct clk * __init -rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, - const struct cpg_pll_config *config, - const char *name) -{ - const struct clk_div_table *table = NULL; - const char *parent_name; - unsigned int shift; - unsigned int mult = 1; - unsigned int div = 1; - - if (!strcmp(name, "main")) { - parent_name = of_clk_get_parent_name(np, 0); - div = config->extal_div; - } else if (!strcmp(name, "pll0")) { - /* PLL0 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - if (of_device_compatible_match(np, pll0_mult_match)) { - /* R-Car V2H and E2 do not have PLL0CR */ - mult = config->pll0_mult; - div = 3; - } else { - u32 value = readl(cpg->reg + CPG_PLL0CR); - mult = ((value >> 24) & ((1 << 7) - 1)) + 1; - } - parent_name = "main"; - } else if (!strcmp(name, "pll1")) { - parent_name = "main"; - mult = config->pll1_mult / 2; - } else if (!strcmp(name, "pll3")) { - parent_name = "main"; - mult = config->pll3_mult; - } else if (!strcmp(name, "lb")) { - parent_name = "pll1"; - div = cpg_mode & BIT(18) ? 36 : 24; - } else if (!strcmp(name, "qspi")) { - parent_name = "pll1_div2"; - div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2) - ? 8 : 10; - } else if (!strcmp(name, "sdh")) { - parent_name = "pll1"; - table = cpg_sdh_div_table; - shift = 8; - } else if (!strcmp(name, "sd0")) { - parent_name = "pll1"; - table = cpg_sd01_div_table; - shift = 4; - } else if (!strcmp(name, "sd1")) { - parent_name = "pll1"; - table = cpg_sd01_div_table; - shift = 0; - } else if (!strcmp(name, "z")) { - return cpg_z_clk_register(cpg); - } else if (!strcmp(name, "rcan")) { - return cpg_rcan_clk_register(cpg, np); - } else if (!strcmp(name, "adsp")) { - return cpg_adsp_clk_register(cpg); - } else { - return ERR_PTR(-EINVAL); - } - - if (!table) - return clk_register_fixed_factor(NULL, name, parent_name, 0, - mult, div); - else - return clk_register_divider_table(NULL, name, parent_name, 0, - cpg->reg + CPG_SDCKCR, shift, - 4, 0, table, &cpg->lock); -} - -/* - * Reset register definitions. - */ -#define MODEMR 0xe6160060 - -static u32 __init rcar_gen2_read_mode_pins(void) -{ - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - u32 mode; - - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - - return mode; -} - -static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) -{ - const struct cpg_pll_config *config; - struct rcar_gen2_cpg *cpg; - struct clk **clks; - unsigned int i; - int num_clks; - - if (rcar_rst_read_mode_pins(&cpg_mode)) { - /* Backward-compatibility with old DT */ - pr_warn("%pOF: failed to obtain mode pins from RST\n", np); - cpg_mode = rcar_gen2_read_mode_pins(); - } - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - if (WARN_ON(cpg->reg == NULL)) - return; - - config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = rcar_gen2_cpg_register_clock(np, cpg, config, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %pOFn %s clock (%ld)\n", - __func__, np, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); - - cpg_mstp_add_clk_domain(np); -} -CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks", - rcar_gen2_cpg_clocks_init); From 3e8c1d4cce6b679f4cfd81dfdbbf727f06986aa5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:08 +0200 Subject: [PATCH 006/160] clk: renesas: rcar-gen2: Improve arithmetic divisions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use div64_ul() instead of div_u64() if the divisor is unsigned long, to avoid truncation to 32-bit on 64-bit platforms, - Prefer ULL constant suffixes over casts to u64, - Prioritize multiplication over division, to increase accuracy. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20190830134515.11925-2-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen2-cpg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index f596a2dafcf4..c378505830f0 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -72,10 +72,10 @@ static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, if (!prate) prate = 1; - mult = div_u64((u64)rate * 32, prate); + mult = div64_ul(rate * 32ULL, prate); mult = clamp(mult, 1U, 32U); - return *parent_rate / 32 * mult; + return div_u64((u64)*parent_rate * mult, 32); } static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -86,7 +86,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, u32 val, kick; unsigned int i; - mult = div_u64((u64)rate * 32, parent_rate); + mult = div64_ul(rate * 32ULL, parent_rate); mult = clamp(mult, 1U, 32U); if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) From b5dea62d34042d173ba1d1887c8dd40262423d68 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:09 +0200 Subject: [PATCH 007/160] clk: renesas: rcar-gen3: Improve arithmetic divisions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use div64_ul() instead of div_u64() if the divisor is unsigned long, to avoid truncation to 32-bit on 64-bit platforms, - Use div_u64() for 64-by-32 divisions. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20190830134515.11925-3-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen3-cpg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index d25c8ba00a65..c594bc067c3b 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -122,10 +122,10 @@ static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned int mult; prate = *parent_rate / zclk->fixed_div; - mult = div_u64(rate * 32ULL, prate); + mult = div64_ul(rate * 32ULL, prate); mult = clamp(mult, 1U, 32U); - return (u64)prate * mult / 32; + return div_u64((u64)prate * mult, 32); } static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, From e8adb3a0f74cf568030b7bd1f77d877e6f308d17 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:10 +0200 Subject: [PATCH 008/160] clk: renesas: rcar-gen3: Avoid double table iteration in SD .set_rate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The .set_rate() callback for the SD clocks is always called with a valid clock rate, returned by .round_rate(). Hence there is no need to iterate through the divider table twice: once to repeat the work done by .round_rate(), and a second time to find the corresponding divider entry. Just iterate once, looking for the divider that matches the passed clock rate. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20190830134515.11925-4-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen3-cpg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index c594bc067c3b..0866be30dc72 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -339,14 +339,14 @@ static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, } static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) + unsigned long parent_rate) { struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); unsigned int i; for (i = 0; i < clock->div_num; i++) - if (div == clock->div_table[i].div) + if (rate == DIV_ROUND_CLOSEST(parent_rate, + clock->div_table[i].div)) break; if (i >= clock->div_num) From f1195d4ec70b230553bbab80c251c3cd79db715b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:11 +0200 Subject: [PATCH 009/160] clk: renesas: rcar-gen3: Absorb cpg_sd_clock_calc_div() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpg_sd_clock_round_rate() is the sole caller of cpg_sd_clock_calc_div(), hence absorb the latter into the former. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20190830134515.11925-5-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen3-cpg.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 0866be30dc72..261f72983096 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -309,15 +309,15 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, clock->div_table[clock->cur_div_idx].div); } -static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, - unsigned long rate, - unsigned long parent_rate) +static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) { unsigned long calc_rate, diff, diff_min = ULONG_MAX; + struct sd_clock *clock = to_sd_clock(hw); unsigned int i, best_div = 0; for (i = 0; i < clock->div_num; i++) { - calc_rate = DIV_ROUND_CLOSEST(parent_rate, + calc_rate = DIV_ROUND_CLOSEST(*parent_rate, clock->div_table[i].div); diff = calc_rate > rate ? calc_rate - rate : rate - calc_rate; if (diff < diff_min) { @@ -326,16 +326,7 @@ static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, } } - return best_div; -} - -static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); - - return DIV_ROUND_CLOSEST(*parent_rate, div); + return DIV_ROUND_CLOSEST(*parent_rate, best_div); } static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, From 8a6d97a46dfd73a87b76a277b2045bd4036c35aa Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:12 +0200 Subject: [PATCH 010/160] clk: renesas: rcar-gen3: Loop to find best rate in cpg_sd_clock_round_rate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cpg_sd_clock_round_rate() really needs the best rate, not the best divider. Hence change the iteration to find the former, and get rid of the final division. Add an out-of-range rate check while at it. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20190830134515.11925-6-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen3-cpg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 261f72983096..39cd0c4e4e79 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -312,21 +312,25 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { - unsigned long calc_rate, diff, diff_min = ULONG_MAX; + unsigned long best_rate = ULONG_MAX, diff_min = ULONG_MAX; struct sd_clock *clock = to_sd_clock(hw); - unsigned int i, best_div = 0; + unsigned long calc_rate, diff; + unsigned int i; for (i = 0; i < clock->div_num; i++) { calc_rate = DIV_ROUND_CLOSEST(*parent_rate, clock->div_table[i].div); diff = calc_rate > rate ? calc_rate - rate : rate - calc_rate; if (diff < diff_min) { - best_div = clock->div_table[i].div; + best_rate = calc_rate; diff_min = diff; } } - return DIV_ROUND_CLOSEST(*parent_rate, best_div); + if (best_rate > LONG_MAX) + return -EINVAL; + + return best_rate; } static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, From 10003938a0c64c2f0d8934ef3f4f36ac5b4960dc Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 19 Sep 2019 09:17:13 +0100 Subject: [PATCH 011/160] dt-bindings: clock: renesas: cpg-mssr: Document r8a774b1 binding Add binding documentation for the RZ/G2N (R8A774b1) Clock Pulse Generator driver. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/1568881036-4404-6-git-send-email-biju.das@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 916a601b76a7..b5edebeb12b4 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -19,6 +19,7 @@ Required Properties: - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) + - "renesas,r8a774b1-cpg-mssr" for the r8a774a1 SoC (RZ/G2N) - "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E) - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2) - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W) @@ -40,10 +41,11 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1, - r8a774c0, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, - r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77990, - r8a77995) - - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) + r8a774b1, r8a774c0, r8a7790, r8a7791, r8a7792, r8a7793, + r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, + r8a77990, r8a77995) + - "extalr" (r8a774a1, r8a774b1, r8a7795, r8a7796, r8a77965, r8a77970, + r8a77980) - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, r8a7794) From 0b9f1c2c2fd4481990515a2918297a50a23a3b34 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 19 Sep 2019 09:17:14 +0100 Subject: [PATCH 012/160] clk: renesas: cpg-mssr: Add r8a774b1 support Add RZ/G2N (R8A774B1) Clock Pulse Generator / Module Standby and Software Reset support. Based on the Table 8.4d of "RZ/G Series, 2nd Generation User's Manual: Hardware (Rev. 0.80, May 2019)". Signed-off-by: Biju Das Link: https://lore.kernel.org/r/1568881036-4404-7-git-send-email-biju.das@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a774b1-cpg-mssr.c | 322 ++++++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 5 files changed, 335 insertions(+) create mode 100644 drivers/clk/renesas/r8a774b1-cpg-mssr.c diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index afca67f7e27a..be03bb748012 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -12,6 +12,7 @@ config CLK_RENESAS select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 select CLK_R8A774A1 if ARCH_R8A774A1 + select CLK_R8A774B1 if ARCH_R8A774B1 select CLK_R8A774C0 if ARCH_R8A774C0 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 @@ -69,6 +70,10 @@ config CLK_R8A774A1 bool "RZ/G2M clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A774B1 + bool "RZ/G2N clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A774C0 bool "RZ/G2E clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index eab3af2539c7..ef0fdd00d2b7 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -9,6 +9,7 @@ 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_R8A774A1) += r8a774a1-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774B1) += r8a774b1-cpg-mssr.o obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c new file mode 100644 index 000000000000..6cad6ba4a682 --- /dev/null +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774b1 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2019 Renesas Electronics Corp. + * + * Based on r8a7796-cpg-mssr.c + * + * Copyright (C) 2016 Glider bvba + */ + +#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 = R8A774B1_CLK_CANFD, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774b1_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), + + /* Core Clock Outputs */ + DEF_GEN3_Z("z", R8A774B1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8), + DEF_FIXED("ztr", R8A774B1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A774B1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A774B1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A774B1_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A774B1_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A774B1_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A774B1_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A774B1_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A774B1_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A774B1_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A774B1_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d2", R8A774B1_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774B1_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774B1_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774B1_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774B1_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774B1_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774B1_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774B1_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A774B1_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A774B1_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A774B1_CLK_CPEX, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("canfd", R8A774B1_CLK_CANFD, CLK_PLL1_DIV4, 0x244), + DEF_DIV6P1("csi0", R8A774B1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A774B1_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A774B1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_GEN3_OSC("osc", R8A774B1_CLK_OSC, CLK_EXTAL, 8), + + DEF_BASE("r", R8A774B1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = { + DEF_MOD("fdp1-0", 119, R8A774B1_CLK_S0D1), + DEF_MOD("scif5", 202, R8A774B1_CLK_S3D4), + DEF_MOD("scif4", 203, R8A774B1_CLK_S3D4), + DEF_MOD("scif3", 204, R8A774B1_CLK_S3D4), + DEF_MOD("scif1", 206, R8A774B1_CLK_S3D4), + DEF_MOD("scif0", 207, R8A774B1_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A774B1_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774B1_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774B1_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774B1_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774B1_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A774B1_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A774B1_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A774B1_CLK_R), + DEF_MOD("cmt2", 301, R8A774B1_CLK_R), + DEF_MOD("cmt1", 302, R8A774B1_CLK_R), + DEF_MOD("cmt0", 303, R8A774B1_CLK_R), + DEF_MOD("tpu0", 304, R8A774B1_CLK_S3D4), + DEF_MOD("scif2", 310, R8A774B1_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A774B1_CLK_SD3), + DEF_MOD("sdif2", 312, R8A774B1_CLK_SD2), + DEF_MOD("sdif1", 313, R8A774B1_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774B1_CLK_SD0), + DEF_MOD("pcie1", 318, R8A774B1_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A774B1_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774B1_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774B1_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774B1_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A774B1_CLK_R), + DEF_MOD("intc-ex", 407, R8A774B1_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774B1_CLK_S0D3), + DEF_MOD("audmac1", 501, R8A774B1_CLK_S1D2), + DEF_MOD("audmac0", 502, R8A774B1_CLK_S1D2), + DEF_MOD("hscif4", 516, R8A774B1_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A774B1_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A774B1_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A774B1_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A774B1_CLK_S3D1), + DEF_MOD("thermal", 522, R8A774B1_CLK_CP), + DEF_MOD("pwm", 523, R8A774B1_CLK_S0D12), + DEF_MOD("fcpvd1", 602, R8A774B1_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A774B1_CLK_S0D2), + DEF_MOD("fcpvb0", 607, R8A774B1_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774B1_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774B1_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A774B1_CLK_S0D2), + DEF_MOD("vspd1", 622, R8A774B1_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A774B1_CLK_S0D2), + DEF_MOD("vspb", 626, R8A774B1_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774B1_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A774B1_CLK_S3D2), + DEF_MOD("ehci0", 703, R8A774B1_CLK_S3D2), + DEF_MOD("hsusb", 704, R8A774B1_CLK_S3D2), + DEF_MOD("csi20", 714, R8A774B1_CLK_CSI0), + DEF_MOD("csi40", 716, R8A774B1_CLK_CSI0), + DEF_MOD("du3", 721, R8A774B1_CLK_S2D1), + DEF_MOD("du1", 723, R8A774B1_CLK_S2D1), + DEF_MOD("du0", 724, R8A774B1_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774B1_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A774B1_CLK_HDMI), + DEF_MOD("vin7", 804, R8A774B1_CLK_S0D2), + DEF_MOD("vin6", 805, R8A774B1_CLK_S0D2), + DEF_MOD("vin5", 806, R8A774B1_CLK_S0D2), + DEF_MOD("vin4", 807, R8A774B1_CLK_S0D2), + DEF_MOD("vin3", 808, R8A774B1_CLK_S0D2), + DEF_MOD("vin2", 809, R8A774B1_CLK_S0D2), + DEF_MOD("vin1", 810, R8A774B1_CLK_S0D2), + DEF_MOD("vin0", 811, R8A774B1_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A774B1_CLK_S0D6), + DEF_MOD("sata0", 815, R8A774B1_CLK_S3D2), + DEF_MOD("gpio7", 905, R8A774B1_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A774B1_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774B1_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774B1_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774B1_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774B1_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774B1_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774B1_CLK_S3D4), + DEF_MOD("can-fd", 914, R8A774B1_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A774B1_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774B1_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6), + DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP), + DEF_MOD("i2c4", 927, R8A774B1_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A774B1_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A774B1_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774B1_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774B1_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774B1_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, R8A774B1_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 r8a774b1_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *----------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +static int __init r8a774b1_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)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +} + +const struct cpg_mssr_info r8a774b1_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774b1_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774b1_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774b1_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774b1_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774b1_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774b1_crit_mod_clks), + + /* Callbacks */ + .init = r8a774b1_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 132cc96895e3..35966678148e 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -702,6 +702,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a774a1_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774B1 + { + .compatible = "renesas,r8a774b1-cpg-mssr", + .data = &r8a774b1_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A774C0 { .compatible = "renesas,r8a774c0-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 4ddcdf3bfb95..3b852ba0ecec 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -159,6 +159,7 @@ 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 r8a774a1_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774b1_cpg_mssr_info; extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; From 834f65e18c82d10b781bee2ad207b590574eeaf9 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Tue, 1 Oct 2019 22:06:56 +0200 Subject: [PATCH 013/160] clk: sunxi-ng: h6: Allow GPU to change parent rate GPU PLL was designed with dynamic frequency switching in mind so driver can adjust rate based on the GPU load. Allow GPU clock to change parent rate (GPU PLL is the only possible parent of GPU clock). Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index ed6338d74474..f2497d0a4683 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -299,7 +299,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670, 0, 3, /* M */ 24, 1, /* mux */ BIT(31), /* gate */ - 0); + CLK_SET_RATE_PARENT); static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2", 0x67c, BIT(0), 0); From 8ad1193eae4c6eb68d389eb0c29fd1cfdf63b656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Mon, 30 Sep 2019 22:26:01 +0200 Subject: [PATCH 014/160] clk: bd718x7: Add MODULE_ALIAS() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes device probing when built as a module. Signed-off-by: Guido Günther Link: https://lkml.kernel.org/r/e1d01b68cdf7dbff9bdd03bab953f828431ad292.1569875042.git.agx@sigxcpu.org Signed-off-by: Stephen Boyd --- drivers/clk/clk-bd718x7.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index ae6e5baee330..00926c587390 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -133,3 +133,4 @@ module_platform_driver(bd71837_clk); MODULE_AUTHOR("Matti Vaittinen "); MODULE_DESCRIPTION("BD71837/BD71847/BD70528 chip clk driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd718xx-clk"); From 9c2b87a6c2ab4988fdffed258fc8a2acecba99c9 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 25 Sep 2019 12:23:46 +0100 Subject: [PATCH 015/160] clk: hisilicon: fix sparse warnings in clk-hi3670.c Fix the following warnings from sparse by removing the 0 initialiser that is actually a pointer. drivers/clk/hisilicon/clk-hi3670.c:298:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:300:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:302:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:304:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:306:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:308:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:310:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:312:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:314:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:316:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:318:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:320:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:322:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:324:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:326:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:328:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:330:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:332:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:334:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:336:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:338:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:340:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:342:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:344:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:346:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:348:65: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:350:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:352:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:488:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:490:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:492:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:494:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:496:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:498:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:500:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:502:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:504:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:506:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:508:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:510:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:512:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:514:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:516:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:518:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:520:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:522:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:524:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:526:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:528:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:530:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:532:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:534:71: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:536:71: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:538:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:611:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:614:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:616:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:653:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:655:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:657:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:659:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:661:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:663:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:665:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:735:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:737:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:739:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:741:63: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:743:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:745:64: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:802:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:804:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:806:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:808:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:810:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3670.c:812:69: warning: Using plain integer as NULL pointer Signed-off-by: Ben Dooks Link: https://lkml.kernel.org/r/20190925112347.14141-1-ben.dooks@codethink.co.uk Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/clk-hi3670.c | 152 ++++++++++++++--------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/drivers/clk/hisilicon/clk-hi3670.c b/drivers/clk/hisilicon/clk-hi3670.c index fd8c837a6ea3..4d05a71683a5 100644 --- a/drivers/clk/hisilicon/clk-hi3670.c +++ b/drivers/clk/hisilicon/clk-hi3670.c @@ -295,61 +295,61 @@ static const struct hisi_gate_clock hi3670_crgctrl_gate_sep_clks[] = { static const struct hisi_gate_clock hi3670_crgctrl_gate_clks[] = { { HI3670_AUTODIV_SYSBUS, "autodiv_sysbus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0x404, 5, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x404, 5, CLK_GATE_HIWORD_MASK, }, { HI3670_AUTODIV_EMMC0BUS, "autodiv_emmc0bus", "autodiv_sysbus", - CLK_SET_RATE_PARENT, 0x404, 1, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x404, 1, CLK_GATE_HIWORD_MASK, }, { HI3670_PCLK_ANDGT_MMC1_PCIE, "pclk_andgt_mmc1_pcie", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xf8, 13, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xf8, 13, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_GATE_VCODECBUS_GT, "clk_gate_vcodecbus_gt", "clk_mux_vcodecbus", - CLK_SET_RATE_PARENT, 0x0F0, 8, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0F0, 8, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_SD, "clk_andgt_sd", "clk_mux_sd_pll", - CLK_SET_RATE_PARENT, 0xF4, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 3, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_SD_SYS_GT, "clk_sd_sys_gt", "clkin_sys", - CLK_SET_RATE_PARENT, 0xF4, 5, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 5, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_SDIO, "clk_andgt_sdio", "clk_mux_sdio_pll", - CLK_SET_RATE_PARENT, 0xF4, 8, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 8, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_SDIO_SYS_GT, "clk_sdio_sys_gt", "clkin_sys", - CLK_SET_RATE_PARENT, 0xF4, 6, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 6, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_A53HPM_ANDGT, "clk_a53hpm_andgt", "clk_mux_a53hpm", - CLK_SET_RATE_PARENT, 0x0F4, 7, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0F4, 7, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_320M_PLL_GT, "clk_320m_pll_gt", "clk_mux_320m", - CLK_SET_RATE_PARENT, 0xF8, 10, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF8, 10, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_UARTH, "clk_andgt_uarth", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 11, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 11, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_UARTL, "clk_andgt_uartl", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 10, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 10, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_UART0, "clk_andgt_uart0", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 9, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 9, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_SPI, "clk_andgt_spi", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF4, 13, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 13, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_PCIEAXI, "clk_andgt_pcieaxi", "clk_mux_pcieaxi", - CLK_SET_RATE_PARENT, 0xfc, 15, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xfc, 15, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_DIV_AO_ASP_GT, "clk_div_ao_asp_gt", "clk_mux_ao_asp", - CLK_SET_RATE_PARENT, 0xF4, 4, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 4, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_GATE_CSI_TRANS, "clk_gate_csi_trans", "clk_ppll2", - CLK_SET_RATE_PARENT, 0xF4, 14, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 14, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_GATE_DSI_TRANS, "clk_gate_dsi_trans", "clk_ppll2", - CLK_SET_RATE_PARENT, 0xF4, 1, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF4, 1, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_PTP, "clk_andgt_ptp", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xF8, 5, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF8, 5, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_OUT0, "clk_andgt_out0", "clk_ppll0", - CLK_SET_RATE_PARENT, 0xF0, 10, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 10, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_OUT1, "clk_andgt_out1", "clk_ppll0", - CLK_SET_RATE_PARENT, 0xF0, 11, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 11, CLK_GATE_HIWORD_MASK, }, { HI3670_CLKGT_DP_AUDIO_PLL_AO, "clkgt_dp_audio_pll_ao", "clk_ppll6", - CLK_SET_RATE_PARENT, 0xF8, 15, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF8, 15, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_VDEC, "clk_andgt_vdec", "clk_mux_vdec", - CLK_SET_RATE_PARENT, 0xF0, 13, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 13, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_VENC, "clk_andgt_venc", "clk_mux_venc", - CLK_SET_RATE_PARENT, 0xF0, 9, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xF0, 9, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_ANGT, "clk_isp_snclk_angt", "clk_div_a53hpm", - CLK_SET_RATE_PARENT, 0x108, 2, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 2, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_RXDPHY, "clk_andgt_rxdphy", "clk_div_a53hpm", - CLK_SET_RATE_PARENT, 0x0F0, 12, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0F0, 12, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_ICS, "clk_andgt_ics", "clk_mux_ics", - CLK_SET_RATE_PARENT, 0xf0, 14, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xf0, 14, CLK_GATE_HIWORD_MASK, }, { HI3670_AUTODIV_DMABUS, "autodiv_dmabus", "autodiv_sysbus", - CLK_SET_RATE_PARENT, 0x404, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x404, 3, CLK_GATE_HIWORD_MASK, }, }; static const char *const @@ -485,57 +485,57 @@ static const struct hisi_mux_clock hi3670_crgctrl_mux_clks[] = { static const struct hisi_divider_clock hi3670_crgctrl_divider_clks[] = { { HI3670_CLK_DIV_CFGBUS, "clk_div_cfgbus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0xEC, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xEC, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_MMC0BUS, "clk_div_mmc0bus", "autodiv_emmc0bus", - CLK_SET_RATE_PARENT, 0x0EC, 2, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0EC, 2, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_MMC1BUS, "clk_div_mmc1bus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0x0EC, 3, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0EC, 3, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_PCLK_DIV_MMC1_PCIE, "pclk_div_mmc1_pcie", "pclk_andgt_mmc1_pcie", - CLK_SET_RATE_PARENT, 0xb4, 6, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb4, 6, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_VCODECBUS, "clk_div_vcodecbus", "clk_gate_vcodecbus_gt", - CLK_SET_RATE_PARENT, 0x0BC, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x0BC, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_SD, "clk_div_sd", "clk_andgt_sd", - CLK_SET_RATE_PARENT, 0xB8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB8, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_SDIO, "clk_div_sdio", "clk_andgt_sdio", - CLK_SET_RATE_PARENT, 0xC0, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC0, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UARTH, "clk_div_uarth", "clk_andgt_uarth", - CLK_SET_RATE_PARENT, 0xB0, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB0, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UARTL, "clk_div_uartl", "clk_andgt_uartl", - CLK_SET_RATE_PARENT, 0xB0, 8, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB0, 8, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UART0, "clk_div_uart0", "clk_andgt_uart0", - CLK_SET_RATE_PARENT, 0xB0, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xB0, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_I2C, "clk_div_i2c", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xE8, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xE8, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_SPI, "clk_div_spi", "clk_andgt_spi", - CLK_SET_RATE_PARENT, 0xC4, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC4, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_PCIEAXI, "clk_div_pcieaxi", "clk_andgt_pcieaxi", - CLK_SET_RATE_PARENT, 0xb4, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb4, 0, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_AO_ASP, "clk_div_ao_asp", "clk_div_ao_asp_gt", - CLK_SET_RATE_PARENT, 0x108, 6, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 6, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CSI_TRANS, "clk_div_csi_trans", "clk_gate_csi_trans", - CLK_SET_RATE_PARENT, 0xD4, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xD4, 0, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_DSI_TRANS, "clk_div_dsi_trans", "clk_gate_dsi_trans", - CLK_SET_RATE_PARENT, 0xD4, 10, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xD4, 10, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_PTP, "clk_div_ptp", "clk_andgt_ptp", - CLK_SET_RATE_PARENT, 0xD8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xD8, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT0_PLL, "clk_div_clkout0_pll", "clk_andgt_out0", - CLK_SET_RATE_PARENT, 0xe0, 4, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe0, 4, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT1_PLL, "clk_div_clkout1_pll", "clk_andgt_out1", - CLK_SET_RATE_PARENT, 0xe0, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe0, 10, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLKDIV_DP_AUDIO_PLL_AO, "clkdiv_dp_audio_pll_ao", "clkgt_dp_audio_pll_ao", - CLK_SET_RATE_PARENT, 0xBC, 11, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xBC, 11, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_VDEC, "clk_div_vdec", "clk_andgt_vdec", - CLK_SET_RATE_PARENT, 0xC4, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC4, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_VENC, "clk_div_venc", "clk_andgt_venc", - CLK_SET_RATE_PARENT, 0xC0, 8, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xC0, 8, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_DIV0, "clk_isp_snclk_div0", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_DIV1, "clk_isp_snclk_div1", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x10C, 14, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x10C, 14, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ISP_SNCLK_DIV2, "clk_isp_snclk_div2", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x10C, 11, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x10C, 11, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_ICS, "clk_div_ics", "clk_andgt_ics", - CLK_SET_RATE_PARENT, 0xE4, 9, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xE4, 9, 6, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_pmuctrl */ @@ -608,12 +608,12 @@ static const struct hisi_gate_clock hi3670_sctrl_gate_sep_clks[] = { static const struct hisi_gate_clock hi3670_sctrl_gate_clks[] = { { HI3670_CLK_ANDGT_IOPERI, "clk_andgt_ioperi", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x270, 6, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x270, 6, CLK_GATE_HIWORD_MASK, }, { HI3670_CLKANDGT_ASP_SUBSYS_PERI, "clkandgt_asp_subsys_peri", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x268, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 3, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANGT_ASP_SUBSYS, "clk_angt_asp_subsys", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x258, 0, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x258, 0, CLK_GATE_HIWORD_MASK, }, }; static const char *const @@ -650,19 +650,19 @@ static const struct hisi_mux_clock hi3670_sctrl_mux_clks[] = { static const struct hisi_divider_clock hi3670_sctrl_divider_clks[] = { { HI3670_CLK_DIV_AOBUS, "clk_div_aobus", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_UFS_SUBSYS, "clk_div_ufs_subsys", "clk_mux_ufs_subsys", - CLK_SET_RATE_PARENT, 0x274, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x274, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_IOPERI, "clk_div_ioperi", "clk_andgt_ioperi", - CLK_SET_RATE_PARENT, 0x270, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x270, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT0_TCXO, "clk_div_clkout0_tcxo", "clkin_sys", - CLK_SET_RATE_PARENT, 0x254, 6, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 6, 3, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_CLKOUT1_TCXO, "clk_div_clkout1_tcxo", "clkin_sys", - CLK_SET_RATE_PARENT, 0x254, 9, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 9, 3, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_ASP_SUBSYS_PERI_DIV, "clk_asp_subsys_peri_div", "clkandgt_asp_subsys_peri", - CLK_SET_RATE_PARENT, 0x268, 0, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 0, 3, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_ASP_SUBSYS, "clk_div_asp_subsys", "clk_angt_asp_subsys", - CLK_SET_RATE_PARENT, 0x250, 0, 3, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x250, 0, 3, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_iomcu */ @@ -732,17 +732,17 @@ static const struct hisi_gate_clock hi3670_media1_gate_sep_clks[] = { static const struct hisi_gate_clock hi3670_media1_gate_clks[] = { { HI3670_CLK_GATE_VIVOBUS_ANDGT, "clk_gate_vivobus_andgt", "clk_mux_vivobus", - CLK_SET_RATE_PARENT, 0x84, 3, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 3, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_EDC0, "clk_andgt_edc0", "clk_mux_edc0", - CLK_SET_RATE_PARENT, 0x84, 7, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 7, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_LDI0, "clk_andgt_ldi0", "clk_mux_ldi0", - CLK_SET_RATE_PARENT, 0x84, 9, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 9, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_ANDGT_LDI1, "clk_andgt_ldi1", "clk_mux_ldi1", - CLK_SET_RATE_PARENT, 0x84, 8, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 8, CLK_GATE_HIWORD_MASK, }, { HI3670_CLK_MMBUF_PLL_ANDGT, "clk_mmbuf_pll_andgt", "clk_sw_mmbuf", - CLK_SET_RATE_PARENT, 0x84, 14, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 14, CLK_GATE_HIWORD_MASK, }, { HI3670_PCLK_MMBUF_ANDGT, "pclk_mmbuf_andgt", "aclk_div_mmbuf", - CLK_SET_RATE_PARENT, 0x84, 15, CLK_GATE_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x84, 15, CLK_GATE_HIWORD_MASK, }, }; static const char *const @@ -799,17 +799,17 @@ static const struct hisi_mux_clock hi3670_media1_mux_clks[] = { static const struct hisi_divider_clock hi3670_media1_divider_clks[] = { { HI3670_CLK_DIV_VIVOBUS, "clk_div_vivobus", "clk_gate_vivobus_andgt", - CLK_SET_RATE_PARENT, 0x74, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x74, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_EDC0, "clk_div_edc0", "clk_andgt_edc0", - CLK_SET_RATE_PARENT, 0x68, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x68, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_LDI0, "clk_div_ldi0", "clk_andgt_ldi0", - CLK_SET_RATE_PARENT, 0x60, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x60, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_CLK_DIV_LDI1, "clk_div_ldi1", "clk_andgt_ldi1", - CLK_SET_RATE_PARENT, 0x64, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x64, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_ACLK_DIV_MMBUF, "aclk_div_mmbuf", "clk_mmbuf_pll_andgt", - CLK_SET_RATE_PARENT, 0x7C, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x7C, 10, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3670_PCLK_DIV_MMBUF, "pclk_div_mmbuf", "pclk_mmbuf_andgt", - CLK_SET_RATE_PARENT, 0x78, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x78, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_media2 */ From 999915711188c32a2ddcda582441e4761139a437 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 25 Sep 2019 12:23:47 +0100 Subject: [PATCH 016/160] clk: hisilicon: fix sparse warnings in clk-hi3660.c Fix sparse warnings of a 0 being used for a pointer by removing it from the initialiser. drivers/clk/hisilicon/clk-hi3660.c:336:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:338:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:340:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:342:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:344:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:346:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:348:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:350:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:352:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:354:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:356:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:358:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:360:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:362:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:364:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:366:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:368:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:370:69: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:372:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:374:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:376:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:378:71: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:423:68: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:425:68: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:427:68: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:429:68: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:449:70: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:451:71: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:453:71: warning: Using plain integer as NULL pointer drivers/clk/hisilicon/clk-hi3660.c:455:71: warning: Using plain integer as NULL pointer Signed-off-by: Ben Dooks Link: https://lkml.kernel.org/r/20190925112347.14141-2-ben.dooks@codethink.co.uk Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/clk-hi3660.c | 60 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/clk/hisilicon/clk-hi3660.c b/drivers/clk/hisilicon/clk-hi3660.c index 5b3ad26dcc77..41f61726ab19 100644 --- a/drivers/clk/hisilicon/clk-hi3660.c +++ b/drivers/clk/hisilicon/clk-hi3660.c @@ -333,49 +333,49 @@ static const struct hisi_mux_clock hi3660_crgctrl_mux_clks[] = { static const struct hisi_divider_clock hi3660_crgctrl_divider_clks[] = { { HI3660_CLK_DIV_UART0, "clk_div_uart0", "clk_andgt_uart0", - CLK_SET_RATE_PARENT, 0xb0, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb0, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UART1, "clk_div_uart1", "clk_andgt_uart1", - CLK_SET_RATE_PARENT, 0xb0, 8, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb0, 8, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UARTH, "clk_div_uarth", "clk_andgt_uarth", - CLK_SET_RATE_PARENT, 0xb0, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb0, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_MMC, "clk_div_mmc", "clk_andgt_mmc", - CLK_SET_RATE_PARENT, 0xb4, 3, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb4, 3, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_SD, "clk_div_sd", "clk_andgt_sd", - CLK_SET_RATE_PARENT, 0xb8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xb8, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_EDC0, "clk_div_edc0", "clk_andgt_edc0", - CLK_SET_RATE_PARENT, 0xbc, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xbc, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_LDI0, "clk_div_ldi0", "clk_andgt_ldi0", - CLK_SET_RATE_PARENT, 0xbc, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xbc, 10, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_SDIO, "clk_div_sdio", "clk_andgt_sdio", - CLK_SET_RATE_PARENT, 0xc0, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc0, 0, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_LDI1, "clk_div_ldi1", "clk_andgt_ldi1", - CLK_SET_RATE_PARENT, 0xc0, 8, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc0, 8, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_SPI, "clk_div_spi", "clk_andgt_spi", - CLK_SET_RATE_PARENT, 0xc4, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc4, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_VENC, "clk_div_venc", "clk_andgt_venc", - CLK_SET_RATE_PARENT, 0xc8, 6, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xc8, 6, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_VDEC, "clk_div_vdec", "clk_andgt_vdec", - CLK_SET_RATE_PARENT, 0xcc, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xcc, 0, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_VIVOBUS, "clk_div_vivobus", "clk_vivobus_andgt", - CLK_SET_RATE_PARENT, 0xd0, 7, 5, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xd0, 7, 5, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_I2C, "clk_div_i2c", "clk_div_320m", - CLK_SET_RATE_PARENT, 0xe8, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe8, 4, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UFSPHY, "clk_div_ufsphy_cfg", "clk_gate_ufsphy_gt", - CLK_SET_RATE_PARENT, 0xe8, 9, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xe8, 9, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_CFGBUS, "clk_div_cfgbus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0xec, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_MMC0BUS, "clk_div_mmc0bus", "autodiv_emmc0bus", - CLK_SET_RATE_PARENT, 0xec, 2, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 2, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_MMC1BUS, "clk_div_mmc1bus", "clk_div_sysbus", - CLK_SET_RATE_PARENT, 0xec, 3, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 3, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_UFSPERI, "clk_div_ufsperi", "clk_gate_ufs_subsys", - CLK_SET_RATE_PARENT, 0xec, 14, 1, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0xec, 14, 1, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_AOMM, "clk_div_aomm", "clk_aomm_andgt", - CLK_SET_RATE_PARENT, 0x100, 7, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x100, 7, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_ISP_SNCLK, "clk_isp_snclk_div", "clk_isp_snclk_fac", - CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_IOPERI, "clk_div_ioperi", "clk_mux_ioperi", - CLK_SET_RATE_PARENT, 0x108, 11, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x108, 11, 4, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_pmuctrl */ @@ -420,13 +420,13 @@ static const struct hisi_gate_clock hi3660_sctrl_gate_clks[] = { { HI3660_PCLK_MMBUF_ANDGT, "pclk_mmbuf_andgt", "clk_sw_mmbuf", CLK_SET_RATE_PARENT, 0x258, 7, CLK_GATE_HIWORD_MASK, }, { HI3660_CLK_MMBUF_PLL_ANDGT, "clk_mmbuf_pll_andgt", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x260, 11, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x260, 11, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_FLL_MMBUF_ANDGT, "clk_fll_mmbuf_andgt", "clk_fll_src", - CLK_SET_RATE_PARENT, 0x260, 12, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x260, 12, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_SYS_MMBUF_ANDGT, "clk_sys_mmbuf_andgt", "clkin_sys", - CLK_SET_RATE_PARENT, 0x260, 13, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x260, 13, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_GATE_PCIEPHY_GT, "clk_gate_pciephy_gt", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x268, 11, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 11, CLK_DIVIDER_HIWORD_MASK, }, }; static const char *const @@ -446,13 +446,13 @@ static const struct hisi_mux_clock hi3660_sctrl_mux_clks[] = { static const struct hisi_divider_clock hi3660_sctrl_divider_clks[] = { { HI3660_CLK_DIV_AOBUS, "clk_div_aobus", "clk_ppll0", - CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_PCLK_DIV_MMBUF, "pclk_div_mmbuf", "pclk_mmbuf_andgt", - CLK_SET_RATE_PARENT, 0x258, 10, 2, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x258, 10, 2, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_ACLK_DIV_MMBUF, "aclk_div_mmbuf", "clk_mmbuf_pll_andgt", - CLK_SET_RATE_PARENT, 0x258, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x258, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, { HI3660_CLK_DIV_PCIEPHY, "clk_div_pciephy", "clk_gate_pciephy_gt", - CLK_SET_RATE_PARENT, 0x268, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, }, + CLK_SET_RATE_PARENT, 0x268, 12, 4, CLK_DIVIDER_HIWORD_MASK, }, }; /* clk_iomcu */ From 4d8fb4948472c976d0c6dcf3380f92332dd660c1 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jun 2019 14:52:42 +0200 Subject: [PATCH 017/160] clk: mvebu: armada-37xx-periph: add PCIe gated clock The PCIe clock is a gated clock which has the same source as GbE0 (both IPs share a set of registers). This source clock is called 'gbe_core' in the driver. Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190627125245.26788-2-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-37xx-periph.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 5fc6d486a381..d9d84299da46 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -303,6 +303,7 @@ PERIPH_CLK_GATE_DIV(gbe_bm, 12, DIV_SEL1, 0, clk_table1); PERIPH_CLK_FULL_DD(sdio, 11, 14, DIV_SEL0, DIV_SEL0, 3, 6); PERIPH_CLK_FULL_DD(usb32_usb2_sys, 16, 16, DIV_SEL0, DIV_SEL0, 9, 12); PERIPH_CLK_FULL_DD(usb32_ss_sys, 17, 18, DIV_SEL0, DIV_SEL0, 15, 18); +static PERIPH_GATE(pcie, 14); static struct clk_periph_data data_sb[] = { REF_CLK_MUX_DD(gbe_50), @@ -318,6 +319,7 @@ static struct clk_periph_data data_sb[] = { REF_CLK_FULL_DD(sdio), REF_CLK_FULL_DD(usb32_usb2_sys), REF_CLK_FULL_DD(usb32_ss_sys), + REF_CLK_GATE(pcie, "gbe_core"), { }, }; From e7ea59b6dc6ddb86dabf88c11cd6748da2313b37 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jun 2019 14:52:43 +0200 Subject: [PATCH 018/160] clk: mvebu: armada-37xx-periph: change suspend/resume time Armada 3700 PCIe IP relies on the PCIe clock managed by this driver. For reasons related to the PCI core's organization when suspending/resuming, PCI host controller drivers must reconfigure their registers at suspend_noirq()/resume_noirq() which happens after suspend()/suspend_late() and before resume_early()/resume(). Device link support in the clock framework enforce that the clock driver's resume() callback will be called before the PCIe driver's. But, any resume_noirq() callback will be called before all the registered resume() callbacks. The solution to support PCIe resume operation is to change the "priority" of this clock driver PM callbacks to "_noirq()". Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190627125245.26788-3-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-37xx-periph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index d9d84299da46..f5746f9ea929 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -714,8 +714,8 @@ static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev) } static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, - armada_3700_periph_clock_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, + armada_3700_periph_clock_resume) }; static int armada_3700_periph_clock_probe(struct platform_device *pdev) From 8511c9de1a31e2dd183573e9a91317e33948fa47 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jun 2019 14:52:44 +0200 Subject: [PATCH 019/160] dt-bindings: clk: armada3700: fix typo in SoC name This documentation is about Armada 3700 SoCs. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lkml.kernel.org/r/20190627125245.26788-4-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/armada3700-periph-clock.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt index 1e3370ba189f..85972715e593 100644 --- a/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt +++ b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt @@ -9,7 +9,7 @@ bridge. The peripheral clock consumer should specify the desired clock by having the clock ID in its "clocks" phandle cell. -The following is a list of provided IDs for Armada 370 North bridge clocks: +The following is a list of provided IDs for Armada 3700 North bridge clocks: ID Clock name Description ----------------------------------- 0 mmc MMC controller @@ -30,7 +30,7 @@ ID Clock name Description 15 eip97 EIP 97 16 cpu CPU -The following is a list of provided IDs for Armada 370 South bridge clocks: +The following is a list of provided IDs for Armada 3700 South bridge clocks: ID Clock name Description ----------------------------------- 0 gbe-50 50 MHz parent clock for Gigabit Ethernet From 06aeb3fb9f310f7e9dcdfc524bde8901d367019f Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 27 Jun 2019 14:52:45 +0200 Subject: [PATCH 020/160] dt-bindings: clk: armada3700: document the PCIe clock Add a reference to the missing PCIe clock managed by this IP. The clock resides in the south bridge. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Link: https://lkml.kernel.org/r/20190627125245.26788-5-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/armada3700-periph-clock.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt index 85972715e593..fbf58c443c04 100644 --- a/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt +++ b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt @@ -46,6 +46,7 @@ ID Clock name Description 10 sdio SDIO 11 usb32-sub2-sys USB 2 clock 12 usb32-ss-sys USB 3 clock +13 pcie PCIe controller Required properties: From 094234fcf46146339caaac8282aa15d225a5911a Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Wed, 4 Sep 2019 12:49:18 +0300 Subject: [PATCH 021/160] clk: imx: pll14xx: Fix quick switch of S/K parameter The PLL14xx on imx8m can change the S and K parameter without requiring a reset and relock of the whole PLL. Fix clk_pll144xx_mp_change register reading and use it for pll1443 as well since no reset+relock is required on K changes either. Signed-off-by: Leonard Crestez Fixes: 8646d4dcc7fb ("clk: imx: Add PLLs driver for imx8mm soc") Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-pll14xx.c | 40 +++++++---------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 7a815ec76aa5..45dc7cc1f967 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -112,43 +112,17 @@ static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, return fvco; } -static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate, +static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate, u32 pll_div) { u32 old_mdiv, old_pdiv; - old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK; + old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; + old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv; } -static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate, - u32 pll_div_ctl0, u32 pll_div_ctl1) -{ - u32 old_mdiv, old_pdiv, old_kdiv; - - old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; - old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; - - return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || - rate->kdiv != old_kdiv; -} - -static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate, - u32 pll_div_ctl0, u32 pll_div_ctl1) -{ - u32 old_mdiv, old_pdiv, old_kdiv; - - old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; - old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; - - return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || - rate->kdiv != old_kdiv; -} - static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll) { u32 val; @@ -174,7 +148,7 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, tmp = readl_relaxed(pll->base + 4); - if (!clk_pll1416x_mp_change(rate, tmp)) { + if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + 4); @@ -239,13 +213,15 @@ static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, } tmp = readl_relaxed(pll->base + 4); - div_val = readl_relaxed(pll->base + 8); - if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) { + if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + 4); + tmp = rate->kdiv << KDIV_SHIFT; + writel_relaxed(tmp, pll->base + 8); + return 0; } From 43cdaa1567ad3931fbde438853947d45238cc040 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 6 Sep 2019 09:34:05 -0400 Subject: [PATCH 022/160] clk: imx8mm: Move 1443X/1416X PLL clock structure to common place Many i.MX8M SoCs use same 1443X/1416X PLL, such as i.MX8MM, i.MX8MN and later i.MX8M SoCs, moving these PLL definitions to pll14xx driver can save a lot of duplicated code on each platform. Meanwhile, no need to define PLL clock structure for every module which uses same type of PLL, e.g., audio/video/dram use 1443X PLL, arm/gpu/vpu/sys use 1416X PLL, define 2 PLL clock structure for each group is enough. Signed-off-by: Anson Huang Reviewed-by: Leonard Crestez Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mm.c | 87 ++++------------------------------- drivers/clk/imx/clk-pll14xx.c | 30 ++++++++++++ drivers/clk/imx/clk.h | 3 ++ 3 files changed, 43 insertions(+), 77 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 067ab876911d..04876ec66127 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -26,73 +26,6 @@ static u32 share_count_disp; static u32 share_count_pdm; static u32 share_count_nand; -static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = { - PLL_1416X_RATE(1800000000U, 225, 3, 0), - PLL_1416X_RATE(1600000000U, 200, 3, 0), - PLL_1416X_RATE(1200000000U, 300, 3, 1), - PLL_1416X_RATE(1000000000U, 250, 3, 1), - PLL_1416X_RATE(800000000U, 200, 3, 1), - PLL_1416X_RATE(750000000U, 250, 2, 2), - PLL_1416X_RATE(700000000U, 350, 3, 2), - PLL_1416X_RATE(600000000U, 300, 3, 2), -}; - -static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = { - PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), - PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), -}; - -static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), - PLL_1443X_RATE(594000000U, 198, 2, 2, 0), -}; - -static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), -}; - -static struct imx_pll14xx_clk imx8mm_audio_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_audiopll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_video_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_videopll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_dram_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_drampll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_arm_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_gpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_vpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_sys_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; @@ -396,16 +329,16 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll); - clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll); - clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll); - clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll); - clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll); - clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll); - clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll); - clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll); - clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll); - clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll); + clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); + clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); + clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); + clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll); + clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); + clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); + clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); + clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx_1416x_pll); + clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx_1416x_pll); + clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); /* PLL bypass out */ clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 45dc7cc1f967..64826e22c328 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -41,6 +41,36 @@ struct clk_pll14xx { #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) +const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { + PLL_1416X_RATE(1800000000U, 225, 3, 0), + PLL_1416X_RATE(1600000000U, 200, 3, 0), + PLL_1416X_RATE(1200000000U, 300, 3, 1), + PLL_1416X_RATE(1000000000U, 250, 3, 1), + PLL_1416X_RATE(800000000U, 200, 3, 1), + PLL_1416X_RATE(750000000U, 250, 2, 2), + PLL_1416X_RATE(700000000U, 350, 3, 2), + PLL_1416X_RATE(600000000U, 300, 3, 2), +}; + +const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { + PLL_1443X_RATE(650000000U, 325, 3, 2, 0), + PLL_1443X_RATE(594000000U, 198, 2, 2, 0), + PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), + PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), +}; + +struct imx_pll14xx_clk imx_1443x_pll = { + .type = PLL_1443X, + .rate_table = imx_pll1443x_tbl, + .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), +}; + +struct imx_pll14xx_clk imx_1416x_pll = { + .type = PLL_1416X, + .rate_table = imx_pll1416x_tbl, + .rate_count = ARRAY_SIZE(imx_pll1416x_tbl), +}; + static const struct imx_pll14xx_rate_table *imx_get_pll_settings( struct clk_pll14xx *pll, unsigned long rate) { diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index f7a389a50401..bc5bb6ac8636 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -50,6 +50,9 @@ struct imx_pll14xx_clk { int flags; }; +extern struct imx_pll14xx_clk imx_1416x_pll; +extern struct imx_pll14xx_clk imx_1443x_pll; + #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk From 0ae4fbc63c31fd318a7feb8590f0a05b250aa79e Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 6 Sep 2019 09:34:06 -0400 Subject: [PATCH 023/160] clk: imx8mn: Use common 1443X/1416X PLL clock structure Use common 1413X/1416X PLL clock structure to save a lot of duplicated code on i.MX8MN clock driver. Signed-off-by: Anson Huang Reviewed-by: Leonard Crestez Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mn.c | 89 ++++------------------------------- drivers/clk/imx/clk-pll14xx.c | 2 + 2 files changed, 12 insertions(+), 79 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 47a4b44ba3cb..7a5590b967d5 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -39,75 +39,6 @@ enum { NR_PLLS, }; -static const struct imx_pll14xx_rate_table imx8mn_pll1416x_tbl[] = { - PLL_1416X_RATE(1800000000U, 225, 3, 0), - PLL_1416X_RATE(1600000000U, 200, 3, 0), - PLL_1416X_RATE(1500000000U, 375, 3, 1), - PLL_1416X_RATE(1400000000U, 350, 3, 1), - PLL_1416X_RATE(1200000000U, 300, 3, 1), - PLL_1416X_RATE(1000000000U, 250, 3, 1), - PLL_1416X_RATE(800000000U, 200, 3, 1), - PLL_1416X_RATE(750000000U, 250, 2, 2), - PLL_1416X_RATE(700000000U, 350, 3, 2), - PLL_1416X_RATE(600000000U, 300, 3, 2), -}; - -static const struct imx_pll14xx_rate_table imx8mn_audiopll_tbl[] = { - PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), - PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), -}; - -static const struct imx_pll14xx_rate_table imx8mn_videopll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), - PLL_1443X_RATE(594000000U, 198, 2, 2, 0), -}; - -static const struct imx_pll14xx_rate_table imx8mn_drampll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), -}; - -static struct imx_pll14xx_clk imx8mn_audio_pll = { - .type = PLL_1443X, - .rate_table = imx8mn_audiopll_tbl, - .rate_count = ARRAY_SIZE(imx8mn_audiopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_video_pll = { - .type = PLL_1443X, - .rate_table = imx8mn_videopll_tbl, - .rate_count = ARRAY_SIZE(imx8mn_videopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_dram_pll = { - .type = PLL_1443X, - .rate_table = imx8mn_drampll_tbl, - .rate_count = ARRAY_SIZE(imx8mn_drampll_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_arm_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_gpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_vpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mn_sys_pll = { - .type = PLL_1416X, - .rate_table = imx8mn_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mn_pll1416x_tbl), -}; - static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; @@ -409,16 +340,16 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) clks[IMX8MN_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mn_audio_pll); - clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mn_audio_pll); - clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mn_video_pll); - clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mn_dram_pll); - clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mn_gpu_pll); - clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mn_vpu_pll); - clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mn_arm_pll); - clks[IMX8MN_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mn_sys_pll); - clks[IMX8MN_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mn_sys_pll); - clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mn_sys_pll); + clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); + clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); + clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); + clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll); + clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); + clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); + clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); + clks[IMX8MN_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx_1416x_pll); + clks[IMX8MN_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx_1416x_pll); + clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); /* PLL bypass out */ clks[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 64826e22c328..7faad6065785 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -44,6 +44,8 @@ struct clk_pll14xx { const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { PLL_1416X_RATE(1800000000U, 225, 3, 0), PLL_1416X_RATE(1600000000U, 200, 3, 0), + PLL_1416X_RATE(1500000000U, 375, 3, 1), + PLL_1416X_RATE(1400000000U, 350, 3, 1), PLL_1416X_RATE(1200000000U, 300, 3, 1), PLL_1416X_RATE(1000000000U, 250, 3, 1), PLL_1416X_RATE(800000000U, 200, 3, 1), From 56278c8fcb71874d591907d654272d511ce3597c Mon Sep 17 00:00:00 2001 From: Biju Das Date: Mon, 23 Sep 2019 15:41:28 +0100 Subject: [PATCH 024/160] clk: renesas: r8a774b1: Add TMU clock This patch adds the TMU clocks to the R8A774B1 SoC. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/1569249688-15821-1-git-send-email-biju.das@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a774b1-cpg-mssr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c index 6cad6ba4a682..c9af70917312 100644 --- a/drivers/clk/renesas/r8a774b1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -110,6 +110,11 @@ static const struct cpg_core_clk r8a774b1_core_clks[] __initconst = { }; static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = { + DEF_MOD("tmu4", 121, R8A774B1_CLK_S0D6), + DEF_MOD("tmu3", 122, R8A774B1_CLK_S3D2), + DEF_MOD("tmu2", 123, R8A774B1_CLK_S3D2), + DEF_MOD("tmu1", 124, R8A774B1_CLK_S3D2), + DEF_MOD("tmu0", 125, R8A774B1_CLK_CP), DEF_MOD("fdp1-0", 119, R8A774B1_CLK_S0D1), DEF_MOD("scif5", 202, R8A774B1_CLK_S3D4), DEF_MOD("scif4", 203, R8A774B1_CLK_S3D4), From 0ea0a188fdc5ace5afd0e25c87575c5fc1ae7e89 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 2 Oct 2019 11:15:23 +0200 Subject: [PATCH 025/160] dt-bindings: clk: axg-audio: add sm1 bindings Add the compatible and clock ids of the sm1 audio clock controller Reviewed-by: Neil Armstrong Signed-off-by: Jerome Brunet --- .../bindings/clock/amlogic,axg-audio-clkc.txt | 3 ++- include/dt-bindings/clock/axg-audio-clkc.h | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt index b3957d10d241..3a8948c04bc9 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt @@ -7,7 +7,8 @@ devices. Required Properties: - compatible : should be "amlogic,axg-audio-clkc" for the A113X and A113D, - "amlogic,g12a-audio-clkc" for G12A. + "amlogic,g12a-audio-clkc" for G12A, + "amlogic,sm1-audio-clkc" for S905X3. - reg : physical base address of the clock controller and length of memory mapped region. - clocks : a list of phandle + clock-specifier pairs for the clocks listed diff --git a/include/dt-bindings/clock/axg-audio-clkc.h b/include/dt-bindings/clock/axg-audio-clkc.h index 75901c636893..f561f5c5ef8f 100644 --- a/include/dt-bindings/clock/axg-audio-clkc.h +++ b/include/dt-bindings/clock/axg-audio-clkc.h @@ -80,5 +80,15 @@ #define AUD_CLKID_TDM_SCLK_PAD0 160 #define AUD_CLKID_TDM_SCLK_PAD1 161 #define AUD_CLKID_TDM_SCLK_PAD2 162 +#define AUD_CLKID_TOP 163 +#define AUD_CLKID_TORAM 164 +#define AUD_CLKID_EQDRC 165 +#define AUD_CLKID_RESAMPLE_B 166 +#define AUD_CLKID_TOVAD 167 +#define AUD_CLKID_LOCKER 168 +#define AUD_CLKID_SPDIFIN_LB 169 +#define AUD_CLKID_FRDDR_D 170 +#define AUD_CLKID_TODDR_D 171 +#define AUD_CLKID_LOOPBACK_B 172 #endif /* __AXG_AUDIO_CLKC_BINDINGS_H */ From aa03ea9bce8c4e45749077254f376b236026f6a0 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 2 Oct 2019 11:15:24 +0200 Subject: [PATCH 026/160] dt-bindings: clock: meson: add sm1 resets to the axg-audio controller Add the reset id of the sm1 audio clock controller Reviewed-by: Neil Armstrong Signed-off-by: Jerome Brunet --- .../reset/amlogic,meson-g12a-audio-reset.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h index 14b78dabed0e..f805129ca7af 100644 --- a/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h +++ b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h @@ -35,4 +35,19 @@ #define AUD_RESET_TOHDMITX 24 #define AUD_RESET_CLKTREE 25 +/* SM1 added resets */ +#define AUD_RESET_RESAMPLE_B 26 +#define AUD_RESET_TOVAD 27 +#define AUD_RESET_LOCKER 28 +#define AUD_RESET_SPDIFIN_LB 29 +#define AUD_RESET_FRATV 30 +#define AUD_RESET_FRHDMIRX 31 +#define AUD_RESET_FRDDR_D 32 +#define AUD_RESET_TODDR_D 33 +#define AUD_RESET_LOOPBACK_B 34 +#define AUD_RESET_EARCTX 35 +#define AUD_RESET_EARCRX 36 +#define AUD_RESET_FRDDR_E 37 +#define AUD_RESET_TODDR_E 38 + #endif From 38340cb2ac4a814e74f36d80752a343b4747afc5 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 2 Oct 2019 11:15:25 +0200 Subject: [PATCH 027/160] clk: meson: axg-audio: remove useless defines Defining the number of each input type is no longer necessary since we are not using the clk-input hack anymore Fixes: 282420eed23f ("clk: meson: axg-audio: migrate to the new parent description method") Acked-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 18b23cdf679c..60ac71856e5e 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -20,10 +20,6 @@ #include "clk-phase.h" #include "sclk-div.h" -#define AUD_MST_IN_COUNT 8 -#define AUD_SLV_SCLK_COUNT 10 -#define AUD_SLV_LRCLK_COUNT 10 - #define AUD_GATE(_name, _reg, _bit, _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct clk_regmap_gate_data){ \ From 255cab9d27d78703f7450d720859ee146d0ee6e1 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 2 Oct 2019 11:15:26 +0200 Subject: [PATCH 028/160] clk: meson: axg-audio: fix regmap last register Since the addition of the g12a, the last register is AUDIO_CLK_SPDIFOUT_B_CTRL. Fixes: 075001385c66 ("clk: meson: axg-audio: add g12a support") Acked-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 60ac71856e5e..4b34601342bb 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -997,7 +997,7 @@ static const struct regmap_config axg_audio_regmap_cfg = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .max_register = AUDIO_CLK_PDMIN_CTRL1, + .max_register = AUDIO_CLK_SPDIFOUT_B_CTRL, }; struct audioclk_data { From 8ff93f2832492c5f290f7dd8d43ee66c7f8d997f Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 2 Oct 2019 11:15:27 +0200 Subject: [PATCH 029/160] clk: meson: axg-audio: prepare sm1 addition Rearrange the macro definition of the clocks of the axg-audio controller. Also, the sm1 variant will feature tiny modification of different blocks in this controller. Because of that, we need to fallback to the old way of defining parent for some of the clocks, using signal name. Reviewed-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 1465 ++++++++++++++++++--------------- 1 file changed, 781 insertions(+), 684 deletions(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 4b34601342bb..ce8836776d1c 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -20,8 +20,7 @@ #include "clk-phase.h" #include "sclk-div.h" -#define AUD_GATE(_name, _reg, _bit, _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ +#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) { \ .data = &(struct clk_regmap_gate_data){ \ .offset = (_reg), \ .bit_idx = (_bit), \ @@ -29,14 +28,13 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } -#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) \ -struct clk_regmap aud_##_name = { \ +#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) { \ .data = &(struct clk_regmap_mux_data){ \ .offset = (_reg), \ .mask = (_mask), \ @@ -52,8 +50,7 @@ struct clk_regmap aud_##_name = { \ }, \ } -#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ +#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) { \ .data = &(struct clk_regmap_div_data){ \ .offset = (_reg), \ .shift = (_shift), \ @@ -63,14 +60,13 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data){ \ .name = "aud_"#_name, \ .ops = &clk_regmap_divider_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ } -#define AUD_PCLK_GATE(_name, _bit) \ -struct clk_regmap aud_##_name = { \ +#define AUD_PCLK_GATE(_name, _bit) { \ .data = &(struct clk_regmap_gate_data){ \ .offset = (AUDIO_CLK_GATE_EN), \ .bit_idx = (_bit), \ @@ -84,116 +80,9 @@ struct clk_regmap aud_##_name = { \ .num_parents = 1, \ }, \ } -/* Audio peripheral clocks */ -static AUD_PCLK_GATE(ddr_arb, 0); -static AUD_PCLK_GATE(pdm, 1); -static AUD_PCLK_GATE(tdmin_a, 2); -static AUD_PCLK_GATE(tdmin_b, 3); -static AUD_PCLK_GATE(tdmin_c, 4); -static AUD_PCLK_GATE(tdmin_lb, 5); -static AUD_PCLK_GATE(tdmout_a, 6); -static AUD_PCLK_GATE(tdmout_b, 7); -static AUD_PCLK_GATE(tdmout_c, 8); -static AUD_PCLK_GATE(frddr_a, 9); -static AUD_PCLK_GATE(frddr_b, 10); -static AUD_PCLK_GATE(frddr_c, 11); -static AUD_PCLK_GATE(toddr_a, 12); -static AUD_PCLK_GATE(toddr_b, 13); -static AUD_PCLK_GATE(toddr_c, 14); -static AUD_PCLK_GATE(loopback, 15); -static AUD_PCLK_GATE(spdifin, 16); -static AUD_PCLK_GATE(spdifout, 17); -static AUD_PCLK_GATE(resample, 18); -static AUD_PCLK_GATE(power_detect, 19); -static AUD_PCLK_GATE(spdifout_b, 21); - -/* Audio Master Clocks */ -static const struct clk_parent_data mst_mux_parent_data[] = { - { .fw_name = "mst_in0", }, - { .fw_name = "mst_in1", }, - { .fw_name = "mst_in2", }, - { .fw_name = "mst_in3", }, - { .fw_name = "mst_in4", }, - { .fw_name = "mst_in5", }, - { .fw_name = "mst_in6", }, - { .fw_name = "mst_in7", }, -}; - -#define AUD_MST_MUX(_name, _reg, _flag) \ - AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ - mst_mux_parent_data, 0) - -#define AUD_MST_MCLK_MUX(_name, _reg) \ - AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) - -#define AUD_MST_SYS_MUX(_name, _reg) \ - AUD_MST_MUX(_name, _reg, 0) - -static AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); -static AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); -static AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); -static AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); -static AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); -static AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); -static AUD_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AUD_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AUD_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); -static AUD_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); - -#define AUD_MST_DIV(_name, _reg, _flag) \ - AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ - aud_##_name##_sel, CLK_SET_RATE_PARENT) \ - -#define AUD_MST_MCLK_DIV(_name, _reg) \ - AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) - -#define AUD_MST_SYS_DIV(_name, _reg) \ - AUD_MST_DIV(_name, _reg, 0) - -static AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); -static AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); -static AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL); -static AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); -static AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); -static AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); -static AUD_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AUD_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AUD_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); -static AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); - -#define AUD_MST_MCLK_GATE(_name, _reg) \ - AUD_GATE(_name, _reg, 31, aud_##_name##_div, \ - CLK_SET_RATE_PARENT) - -static AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); -static AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL); -static AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL); -static AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL); -static AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL); -static AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL); -static AUD_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); -static AUD_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AUD_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); - -/* Sample Clocks */ -#define AUD_MST_SCLK_PRE_EN(_name, _reg) \ - AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ - aud_mst_##_name##_mclk, 0) - -static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \ - _hi_shift, _hi_width, _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ + _hi_shift, _hi_width, _pname, _iflags) { \ .data = &(struct meson_sclk_div_data) { \ .div = { \ .reg_off = (_reg), \ @@ -209,38 +98,14 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_sclk_div_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ } -#define AUD_MST_SCLK_DIV(_name, _reg) \ - AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ - aud_mst_##_name##_sclk_pre_en, \ - CLK_SET_RATE_PARENT) - -static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); - -#define AUD_MST_SCLK_POST_EN(_name, _reg) \ - AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ - aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT) - -static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); - #define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ - _phws, _iflags) \ -struct clk_regmap aud_##_name = { \ + _pname, _iflags) { \ .data = &(struct meson_clk_triphase_data) { \ .ph0 = { \ .reg_off = (_reg), \ @@ -261,52 +126,91 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_clk_triphase_ops, \ - .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ + .parent_names = (const char *[]){ #_pname }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } +#define AUD_PHASE(_name, _reg, _width, _shift, _pname, _iflags) { \ + .data = &(struct meson_clk_phase_data) { \ + .ph = { \ + .reg_off = (_reg), \ + .shift = (_shift), \ + .width = (_width), \ + }, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = "aud_"#_name, \ + .ops = &meson_clk_phase_ops, \ + .parent_names = (const char *[]){ #_pname }, \ + .num_parents = 1, \ + .flags = (_iflags), \ + }, \ +} + +/* Audio Master Clocks */ +static const struct clk_parent_data mst_mux_parent_data[] = { + { .fw_name = "mst_in0", }, + { .fw_name = "mst_in1", }, + { .fw_name = "mst_in2", }, + { .fw_name = "mst_in3", }, + { .fw_name = "mst_in4", }, + { .fw_name = "mst_in5", }, + { .fw_name = "mst_in6", }, + { .fw_name = "mst_in7", }, +}; + +#define AUD_MST_MUX(_name, _reg, _flag) \ + AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ + mst_mux_parent_data, 0) +#define AUD_MST_DIV(_name, _reg, _flag) \ + AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ + aud_##_name##_sel, CLK_SET_RATE_PARENT) +#define AUD_MST_MCLK_GATE(_name, _reg) \ + AUD_GATE(_name, _reg, 31, aud_##_name##_div, \ + CLK_SET_RATE_PARENT) + +#define AUD_MST_MCLK_MUX(_name, _reg) \ + AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) +#define AUD_MST_MCLK_DIV(_name, _reg) \ + AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) + +#define AUD_MST_SYS_MUX(_name, _reg) \ + AUD_MST_MUX(_name, _reg, 0) +#define AUD_MST_SYS_DIV(_name, _reg) \ + AUD_MST_DIV(_name, _reg, 0) + +/* Sample Clocks */ +#define AUD_MST_SCLK_PRE_EN(_name, _reg) \ + AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ + aud_mst_##_name##_mclk, 0) +#define AUD_MST_SCLK_DIV(_name, _reg) \ + AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ + aud_mst_##_name##_sclk_pre_en, \ + CLK_SET_RATE_PARENT) +#define AUD_MST_SCLK_POST_EN(_name, _reg) \ + AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ + aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT) #define AUD_MST_SCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \ aud_mst_##_name##_sclk_post_en, CLK_SET_RATE_PARENT) -static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); -static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); -static AUD_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1); -static AUD_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1); -static AUD_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1); -static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); - #define AUD_MST_LRCLK_DIV(_name, _reg) \ AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \ - aud_mst_##_name##_sclk_post_en, 0) \ - -static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); -static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); - + aud_mst_##_name##_sclk_post_en, 0) #define AUD_MST_LRCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \ aud_mst_##_name##_lrclk_div, CLK_SET_RATE_PARENT) -static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); -static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); -static AUD_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1); -static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); -static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); -static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); - +/* TDM bit clock sources */ static const struct clk_parent_data tdm_sclk_parent_data[] = { - { .hw = &aud_mst_a_sclk.hw, }, - { .hw = &aud_mst_b_sclk.hw, }, - { .hw = &aud_mst_c_sclk.hw, }, - { .hw = &aud_mst_d_sclk.hw, }, - { .hw = &aud_mst_e_sclk.hw, }, - { .hw = &aud_mst_f_sclk.hw, }, + { .name = "aud_mst_a_sclk", .index = -1, }, + { .name = "aud_mst_b_sclk", .index = -1, }, + { .name = "aud_mst_c_sclk", .index = -1, }, + { .name = "aud_mst_d_sclk", .index = -1, }, + { .name = "aud_mst_e_sclk", .index = -1, }, + { .name = "aud_mst_f_sclk", .index = -1, }, { .fw_name = "slv_sclk0", }, { .fw_name = "slv_sclk1", }, { .fw_name = "slv_sclk2", }, @@ -319,78 +223,14 @@ static const struct clk_parent_data tdm_sclk_parent_data[] = { { .fw_name = "slv_sclk9", }, }; -#define AUD_TDM_SCLK_MUX(_name, _reg) \ - AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ - CLK_MUX_ROUND_CLOSEST, \ - tdm_sclk_parent_data, 0) - -static AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - -#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \ - AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ - aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT) - -static AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - -#define AUD_TDM_SCLK_POST_EN(_name, _reg) \ - AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ - aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT) - -static AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - -#define AUD_TDM_SCLK(_name, _reg) \ - struct clk_regmap aud_tdm##_name##_sclk = { \ - .data = &(struct meson_clk_phase_data) { \ - .ph = { \ - .reg_off = (_reg), \ - .shift = 29, \ - .width = 1, \ - }, \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = "aud_tdm"#_name"_sclk", \ - .ops = &meson_clk_phase_ops, \ - .parent_hws = (const struct clk_hw *[]) { \ - &aud_tdm##_name##_sclk_post_en.hw \ - }, \ - .num_parents = 1, \ - .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \ - }, \ -} - -static AUD_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); - +/* TDM sample clock sources */ static const struct clk_parent_data tdm_lrclk_parent_data[] = { - { .hw = &aud_mst_a_lrclk.hw, }, - { .hw = &aud_mst_b_lrclk.hw, }, - { .hw = &aud_mst_c_lrclk.hw, }, - { .hw = &aud_mst_d_lrclk.hw, }, - { .hw = &aud_mst_e_lrclk.hw, }, - { .hw = &aud_mst_f_lrclk.hw, }, + { .name = "aud_mst_a_lrclk", .index = -1, }, + { .name = "aud_mst_b_lrclk", .index = -1, }, + { .name = "aud_mst_c_lrclk", .index = -1, }, + { .name = "aud_mst_d_lrclk", .index = -1, }, + { .name = "aud_mst_e_lrclk", .index = -1, }, + { .name = "aud_mst_f_lrclk", .index = -1, }, { .fw_name = "slv_lrclk0", }, { .fw_name = "slv_lrclk1", }, { .fw_name = "slv_lrclk2", }, @@ -403,69 +243,326 @@ static const struct clk_parent_data tdm_lrclk_parent_data[] = { { .fw_name = "slv_lrclk9", }, }; -#define AUD_TDM_LRLCK(_name, _reg) \ - AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ - CLK_MUX_ROUND_CLOSEST, \ - tdm_lrclk_parent_data, 0) +#define AUD_TDM_SCLK_MUX(_name, _reg) \ + AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ + CLK_MUX_ROUND_CLOSEST, tdm_sclk_parent_data, 0) +#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \ + AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ + aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT) +#define AUD_TDM_SCLK_POST_EN(_name, _reg) \ + AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ + aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT) +#define AUD_TDM_SCLK(_name, _reg) \ + AUD_PHASE(tdm##_name##_sclk, _reg, 1, 29, \ + aud_tdm##_name##_sclk_post_en, \ + CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT) -static AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); -static AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); -static AUD_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL); -static AUD_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); -static AUD_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); -static AUD_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); -static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); +#define AUD_TDM_LRLCK(_name, _reg) \ + AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ + CLK_MUX_ROUND_CLOSEST, tdm_lrclk_parent_data, 0) + +/* Pad master clock sources */ +static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = { + { .name = "aud_mst_a_mclk", .index = -1, }, + { .name = "aud_mst_b_mclk", .index = -1, }, + { .name = "aud_mst_c_mclk", .index = -1, }, + { .name = "aud_mst_d_mclk", .index = -1, }, + { .name = "aud_mst_e_mclk", .index = -1, }, + { .name = "aud_mst_f_mclk", .index = -1, }, +}; + +/* Pad bit clock sources */ +static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = { + { .name = "aud_mst_a_sclk", .index = -1, }, + { .name = "aud_mst_b_sclk", .index = -1, }, + { .name = "aud_mst_c_sclk", .index = -1, }, + { .name = "aud_mst_d_sclk", .index = -1, }, + { .name = "aud_mst_e_sclk", .index = -1, }, + { .name = "aud_mst_f_sclk", .index = -1, }, +}; + +/* Pad sample clock sources */ +static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = { + { .name = "aud_mst_a_lrclk", .index = -1, }, + { .name = "aud_mst_b_lrclk", .index = -1, }, + { .name = "aud_mst_c_lrclk", .index = -1, }, + { .name = "aud_mst_d_lrclk", .index = -1, }, + { .name = "aud_mst_e_lrclk", .index = -1, }, + { .name = "aud_mst_f_lrclk", .index = -1, }, +}; -/* G12a Pad control */ #define AUD_TDM_PAD_CTRL(_name, _reg, _shift, _parents) \ AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents, \ CLK_SET_RATE_NO_REPARENT) -static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = { - { .hw = &aud_mst_a_mclk.hw }, - { .hw = &aud_mst_b_mclk.hw }, - { .hw = &aud_mst_c_mclk.hw }, - { .hw = &aud_mst_d_mclk.hw }, - { .hw = &aud_mst_e_mclk.hw }, - { .hw = &aud_mst_f_mclk.hw }, -}; +/* Common Clocks */ +static struct clk_regmap ddr_arb = AUD_PCLK_GATE(ddr_arb, 0); +static struct clk_regmap pdm = AUD_PCLK_GATE(pdm, 1); +static struct clk_regmap tdmin_a = AUD_PCLK_GATE(tdmin_a, 2); +static struct clk_regmap tdmin_b = AUD_PCLK_GATE(tdmin_b, 3); +static struct clk_regmap tdmin_c = AUD_PCLK_GATE(tdmin_c, 4); +static struct clk_regmap tdmin_lb = AUD_PCLK_GATE(tdmin_lb, 5); +static struct clk_regmap tdmout_a = AUD_PCLK_GATE(tdmout_a, 6); +static struct clk_regmap tdmout_b = AUD_PCLK_GATE(tdmout_b, 7); +static struct clk_regmap tdmout_c = AUD_PCLK_GATE(tdmout_c, 8); +static struct clk_regmap frddr_a = AUD_PCLK_GATE(frddr_a, 9); +static struct clk_regmap frddr_b = AUD_PCLK_GATE(frddr_b, 10); +static struct clk_regmap frddr_c = AUD_PCLK_GATE(frddr_c, 11); +static struct clk_regmap toddr_a = AUD_PCLK_GATE(toddr_a, 12); +static struct clk_regmap toddr_b = AUD_PCLK_GATE(toddr_b, 13); +static struct clk_regmap toddr_c = AUD_PCLK_GATE(toddr_c, 14); +static struct clk_regmap loopback = AUD_PCLK_GATE(loopback, 15); +static struct clk_regmap spdifin = AUD_PCLK_GATE(spdifin, 16); +static struct clk_regmap spdifout = AUD_PCLK_GATE(spdifout, 17); +static struct clk_regmap resample = AUD_PCLK_GATE(resample, 18); +static struct clk_regmap power_detect = AUD_PCLK_GATE(power_detect, 19); -static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0, - mclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4, - mclk_pad_ctrl_parent_data); +static struct clk_regmap spdifout_clk_sel = + AUD_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); +static struct clk_regmap pdm_dclk_sel = + AUD_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); +static struct clk_regmap spdifin_clk_sel = + AUD_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static struct clk_regmap pdm_sysclk_sel = + AUD_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static struct clk_regmap spdifout_b_clk_sel = + AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); -static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = { - { .hw = &aud_mst_a_lrclk.hw }, - { .hw = &aud_mst_b_lrclk.hw }, - { .hw = &aud_mst_c_lrclk.hw }, - { .hw = &aud_mst_d_lrclk.hw }, - { .hw = &aud_mst_e_lrclk.hw }, - { .hw = &aud_mst_f_lrclk.hw }, -}; +static struct clk_regmap spdifout_clk_div = + AUD_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); +static struct clk_regmap pdm_dclk_div = + AUD_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); +static struct clk_regmap spdifin_clk_div = + AUD_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static struct clk_regmap pdm_sysclk_div = + AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static struct clk_regmap spdifout_b_clk_div = + AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); -static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16, - lrclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20, - lrclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24, - lrclk_pad_ctrl_parent_data); +static struct clk_regmap spdifout_clk = + AUD_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); +static struct clk_regmap spdifin_clk = + AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static struct clk_regmap pdm_dclk = + AUD_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); +static struct clk_regmap pdm_sysclk = + AUD_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static struct clk_regmap spdifout_b_clk = + AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); -static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = { - { .hw = &aud_mst_a_sclk.hw }, - { .hw = &aud_mst_b_sclk.hw }, - { .hw = &aud_mst_c_sclk.hw }, - { .hw = &aud_mst_d_sclk.hw }, - { .hw = &aud_mst_e_sclk.hw }, - { .hw = &aud_mst_f_sclk.hw }, -}; +static struct clk_regmap mst_a_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_sclk_pre_en = + AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); -static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0, - sclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4, - sclk_pad_ctrl_parent_data); -static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, - sclk_pad_ctrl_parent_data); +static struct clk_regmap mst_a_sclk_div = + AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_sclk_div = + AUD_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_sclk_div = + AUD_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_sclk_div = + AUD_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_sclk_div = + AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_sclk_div = + AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); + +static struct clk_regmap mst_a_sclk_post_en = + AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_sclk_post_en = + AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_sclk_post_en = + AUD_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_sclk_post_en = + AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_sclk_post_en = + AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_sclk_post_en = + AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); + +static struct clk_regmap mst_a_sclk = + AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); +static struct clk_regmap mst_b_sclk = + AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); +static struct clk_regmap mst_c_sclk = + AUD_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1); +static struct clk_regmap mst_d_sclk = + AUD_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1); +static struct clk_regmap mst_e_sclk = + AUD_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1); +static struct clk_regmap mst_f_sclk = + AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); + +static struct clk_regmap mst_a_lrclk_div = + AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); +static struct clk_regmap mst_b_lrclk_div = + AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); +static struct clk_regmap mst_c_lrclk_div = + AUD_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); +static struct clk_regmap mst_d_lrclk_div = + AUD_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); +static struct clk_regmap mst_e_lrclk_div = + AUD_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); +static struct clk_regmap mst_f_lrclk_div = + AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); + +static struct clk_regmap mst_a_lrclk = + AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); +static struct clk_regmap mst_b_lrclk = + AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); +static struct clk_regmap mst_c_lrclk = + AUD_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1); +static struct clk_regmap mst_d_lrclk = + AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); +static struct clk_regmap mst_e_lrclk = + AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); +static struct clk_regmap mst_f_lrclk = + AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); + +static struct clk_regmap tdmin_a_sclk_sel = + AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk_sel = + AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk_sel = + AUD_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk_sel = + AUD_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk_sel = + AUD_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk_sel = + AUD_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk_sel = + AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk_pre_en = + AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk_post_en = + AUD_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk_post_en = + AUD_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk_post_en = + AUD_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk_post_en = + AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_sclk = + AUD_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_sclk = + AUD_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_sclk = + AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_sclk = + AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_sclk = + AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_sclk = + AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_sclk = + AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +static struct clk_regmap tdmin_a_lrclk = + AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); +static struct clk_regmap tdmin_b_lrclk = + AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); +static struct clk_regmap tdmin_c_lrclk = + AUD_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL); +static struct clk_regmap tdmin_lb_lrclk = + AUD_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); +static struct clk_regmap tdmout_a_lrclk = + AUD_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); +static struct clk_regmap tdmout_b_lrclk = + AUD_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); +static struct clk_regmap tdmout_c_lrclk = + AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); + +/* AXG/G12A Clocks */ +static struct clk_regmap mst_a_mclk_sel = + AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); +static struct clk_regmap mst_b_mclk_sel = + AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); +static struct clk_regmap mst_c_mclk_sel = + AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); +static struct clk_regmap mst_d_mclk_sel = + AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); +static struct clk_regmap mst_e_mclk_sel = + AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); +static struct clk_regmap mst_f_mclk_sel = + AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); + +static struct clk_regmap mst_a_mclk_div = + AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); +static struct clk_regmap mst_b_mclk_div = + AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); +static struct clk_regmap mst_c_mclk_div = + AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL); +static struct clk_regmap mst_d_mclk_div = + AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); +static struct clk_regmap mst_e_mclk_div = + AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); +static struct clk_regmap mst_f_mclk_div = + AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); + +static struct clk_regmap mst_a_mclk = + AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); +static struct clk_regmap mst_b_mclk = + AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL); +static struct clk_regmap mst_c_mclk = + AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL); +static struct clk_regmap mst_d_mclk = + AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL); +static struct clk_regmap mst_e_mclk = + AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL); +static struct clk_regmap mst_f_mclk = + AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL); + +/* G12a clocks */ +static struct clk_regmap g12a_tdm_mclk_pad_0 = AUD_TDM_PAD_CTRL( + mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0, mclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_mclk_pad_1 = AUD_TDM_PAD_CTRL( + mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4, mclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_lrclk_pad_0 = AUD_TDM_PAD_CTRL( + lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16, lrclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_lrclk_pad_1 = AUD_TDM_PAD_CTRL( + lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20, lrclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_lrclk_pad_2 = AUD_TDM_PAD_CTRL( + lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24, lrclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_sclk_pad_0 = AUD_TDM_PAD_CTRL( + sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0, sclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_sclk_pad_1 = AUD_TDM_PAD_CTRL( + sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4, sclk_pad_ctrl_parent_data); +static struct clk_regmap g12a_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL( + sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data); + +/* G12a/SM1 clocks */ +static struct clk_regmap spdifout_b = AUD_PCLK_GATE(spdifout_b, 21); /* * Array of all clocks provided by this provider @@ -473,127 +570,127 @@ static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, */ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { .hws = { - [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw, - [AUD_CLKID_PDM] = &aud_pdm.hw, - [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw, - [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw, - [AUD_CLKID_TDMIN_C] = &aud_tdmin_c.hw, - [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw, - [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw, - [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw, - [AUD_CLKID_TDMOUT_C] = &aud_tdmout_c.hw, - [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw, - [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw, - [AUD_CLKID_FRDDR_C] = &aud_frddr_c.hw, - [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw, - [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw, - [AUD_CLKID_TODDR_C] = &aud_toddr_c.hw, - [AUD_CLKID_LOOPBACK] = &aud_loopback.hw, - [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw, - [AUD_CLKID_SPDIFOUT] = &aud_spdifout.hw, - [AUD_CLKID_RESAMPLE] = &aud_resample.hw, - [AUD_CLKID_POWER_DETECT] = &aud_power_detect.hw, - [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw, - [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw, - [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw, - [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw, - [AUD_CLKID_MST_E_MCLK_SEL] = &aud_mst_e_mclk_sel.hw, - [AUD_CLKID_MST_F_MCLK_SEL] = &aud_mst_f_mclk_sel.hw, - [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw, - [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw, - [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw, - [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw, - [AUD_CLKID_MST_E_MCLK_DIV] = &aud_mst_e_mclk_div.hw, - [AUD_CLKID_MST_F_MCLK_DIV] = &aud_mst_f_mclk_div.hw, - [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw, - [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw, - [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw, - [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw, - [AUD_CLKID_MST_E_MCLK] = &aud_mst_e_mclk.hw, - [AUD_CLKID_MST_F_MCLK] = &aud_mst_f_mclk.hw, - [AUD_CLKID_SPDIFOUT_CLK_SEL] = &aud_spdifout_clk_sel.hw, - [AUD_CLKID_SPDIFOUT_CLK_DIV] = &aud_spdifout_clk_div.hw, - [AUD_CLKID_SPDIFOUT_CLK] = &aud_spdifout_clk.hw, - [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw, - [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw, - [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw, - [AUD_CLKID_PDM_DCLK_SEL] = &aud_pdm_dclk_sel.hw, - [AUD_CLKID_PDM_DCLK_DIV] = &aud_pdm_dclk_div.hw, - [AUD_CLKID_PDM_DCLK] = &aud_pdm_dclk.hw, - [AUD_CLKID_PDM_SYSCLK_SEL] = &aud_pdm_sysclk_sel.hw, - [AUD_CLKID_PDM_SYSCLK_DIV] = &aud_pdm_sysclk_div.hw, - [AUD_CLKID_PDM_SYSCLK] = &aud_pdm_sysclk.hw, - [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw, - [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw, - [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw, - [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw, - [AUD_CLKID_MST_E_SCLK_PRE_EN] = &aud_mst_e_sclk_pre_en.hw, - [AUD_CLKID_MST_F_SCLK_PRE_EN] = &aud_mst_f_sclk_pre_en.hw, - [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw, - [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw, - [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw, - [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw, - [AUD_CLKID_MST_E_SCLK_DIV] = &aud_mst_e_sclk_div.hw, - [AUD_CLKID_MST_F_SCLK_DIV] = &aud_mst_f_sclk_div.hw, - [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw, - [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw, - [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw, - [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw, - [AUD_CLKID_MST_E_SCLK_POST_EN] = &aud_mst_e_sclk_post_en.hw, - [AUD_CLKID_MST_F_SCLK_POST_EN] = &aud_mst_f_sclk_post_en.hw, - [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw, - [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw, - [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw, - [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw, - [AUD_CLKID_MST_E_SCLK] = &aud_mst_e_sclk.hw, - [AUD_CLKID_MST_F_SCLK] = &aud_mst_f_sclk.hw, - [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw, - [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw, - [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw, - [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw, - [AUD_CLKID_MST_E_LRCLK_DIV] = &aud_mst_e_lrclk_div.hw, - [AUD_CLKID_MST_F_LRCLK_DIV] = &aud_mst_f_lrclk_div.hw, - [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw, - [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw, - [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw, - [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw, - [AUD_CLKID_MST_E_LRCLK] = &aud_mst_e_lrclk.hw, - [AUD_CLKID_MST_F_LRCLK] = &aud_mst_f_lrclk.hw, - [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw, - [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw, - [AUD_CLKID_TDMIN_C_SCLK_SEL] = &aud_tdmin_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw, - [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw, - [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw, - [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &aud_tdmout_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &aud_tdmin_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &aud_tdmout_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &aud_tdmin_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &aud_tdmout_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw, - [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw, - [AUD_CLKID_TDMIN_C_SCLK] = &aud_tdmin_c_sclk.hw, - [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw, - [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw, - [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw, - [AUD_CLKID_TDMOUT_C_SCLK] = &aud_tdmout_c_sclk.hw, - [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw, - [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw, - [AUD_CLKID_TDMIN_C_LRCLK] = &aud_tdmin_c_lrclk.hw, - [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw, - [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw, - [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw, - [AUD_CLKID_TDMOUT_C_LRCLK] = &aud_tdmout_c_lrclk.hw, + [AUD_CLKID_DDR_ARB] = &ddr_arb.hw, + [AUD_CLKID_PDM] = &pdm.hw, + [AUD_CLKID_TDMIN_A] = &tdmin_a.hw, + [AUD_CLKID_TDMIN_B] = &tdmin_b.hw, + [AUD_CLKID_TDMIN_C] = &tdmin_c.hw, + [AUD_CLKID_TDMIN_LB] = &tdmin_lb.hw, + [AUD_CLKID_TDMOUT_A] = &tdmout_a.hw, + [AUD_CLKID_TDMOUT_B] = &tdmout_b.hw, + [AUD_CLKID_TDMOUT_C] = &tdmout_c.hw, + [AUD_CLKID_FRDDR_A] = &frddr_a.hw, + [AUD_CLKID_FRDDR_B] = &frddr_b.hw, + [AUD_CLKID_FRDDR_C] = &frddr_c.hw, + [AUD_CLKID_TODDR_A] = &toddr_a.hw, + [AUD_CLKID_TODDR_B] = &toddr_b.hw, + [AUD_CLKID_TODDR_C] = &toddr_c.hw, + [AUD_CLKID_LOOPBACK] = &loopback.hw, + [AUD_CLKID_SPDIFIN] = &spdifin.hw, + [AUD_CLKID_SPDIFOUT] = &spdifout.hw, + [AUD_CLKID_RESAMPLE] = &resample.hw, + [AUD_CLKID_POWER_DETECT] = &power_detect.hw, + [AUD_CLKID_MST_A_MCLK_SEL] = &mst_a_mclk_sel.hw, + [AUD_CLKID_MST_B_MCLK_SEL] = &mst_b_mclk_sel.hw, + [AUD_CLKID_MST_C_MCLK_SEL] = &mst_c_mclk_sel.hw, + [AUD_CLKID_MST_D_MCLK_SEL] = &mst_d_mclk_sel.hw, + [AUD_CLKID_MST_E_MCLK_SEL] = &mst_e_mclk_sel.hw, + [AUD_CLKID_MST_F_MCLK_SEL] = &mst_f_mclk_sel.hw, + [AUD_CLKID_MST_A_MCLK_DIV] = &mst_a_mclk_div.hw, + [AUD_CLKID_MST_B_MCLK_DIV] = &mst_b_mclk_div.hw, + [AUD_CLKID_MST_C_MCLK_DIV] = &mst_c_mclk_div.hw, + [AUD_CLKID_MST_D_MCLK_DIV] = &mst_d_mclk_div.hw, + [AUD_CLKID_MST_E_MCLK_DIV] = &mst_e_mclk_div.hw, + [AUD_CLKID_MST_F_MCLK_DIV] = &mst_f_mclk_div.hw, + [AUD_CLKID_MST_A_MCLK] = &mst_a_mclk.hw, + [AUD_CLKID_MST_B_MCLK] = &mst_b_mclk.hw, + [AUD_CLKID_MST_C_MCLK] = &mst_c_mclk.hw, + [AUD_CLKID_MST_D_MCLK] = &mst_d_mclk.hw, + [AUD_CLKID_MST_E_MCLK] = &mst_e_mclk.hw, + [AUD_CLKID_MST_F_MCLK] = &mst_f_mclk.hw, + [AUD_CLKID_SPDIFOUT_CLK_SEL] = &spdifout_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_CLK_DIV] = &spdifout_clk_div.hw, + [AUD_CLKID_SPDIFOUT_CLK] = &spdifout_clk.hw, + [AUD_CLKID_SPDIFIN_CLK_SEL] = &spdifin_clk_sel.hw, + [AUD_CLKID_SPDIFIN_CLK_DIV] = &spdifin_clk_div.hw, + [AUD_CLKID_SPDIFIN_CLK] = &spdifin_clk.hw, + [AUD_CLKID_PDM_DCLK_SEL] = &pdm_dclk_sel.hw, + [AUD_CLKID_PDM_DCLK_DIV] = &pdm_dclk_div.hw, + [AUD_CLKID_PDM_DCLK] = &pdm_dclk.hw, + [AUD_CLKID_PDM_SYSCLK_SEL] = &pdm_sysclk_sel.hw, + [AUD_CLKID_PDM_SYSCLK_DIV] = &pdm_sysclk_div.hw, + [AUD_CLKID_PDM_SYSCLK] = &pdm_sysclk.hw, + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &mst_a_sclk_pre_en.hw, + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &mst_b_sclk_pre_en.hw, + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &mst_c_sclk_pre_en.hw, + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &mst_d_sclk_pre_en.hw, + [AUD_CLKID_MST_E_SCLK_PRE_EN] = &mst_e_sclk_pre_en.hw, + [AUD_CLKID_MST_F_SCLK_PRE_EN] = &mst_f_sclk_pre_en.hw, + [AUD_CLKID_MST_A_SCLK_DIV] = &mst_a_sclk_div.hw, + [AUD_CLKID_MST_B_SCLK_DIV] = &mst_b_sclk_div.hw, + [AUD_CLKID_MST_C_SCLK_DIV] = &mst_c_sclk_div.hw, + [AUD_CLKID_MST_D_SCLK_DIV] = &mst_d_sclk_div.hw, + [AUD_CLKID_MST_E_SCLK_DIV] = &mst_e_sclk_div.hw, + [AUD_CLKID_MST_F_SCLK_DIV] = &mst_f_sclk_div.hw, + [AUD_CLKID_MST_A_SCLK_POST_EN] = &mst_a_sclk_post_en.hw, + [AUD_CLKID_MST_B_SCLK_POST_EN] = &mst_b_sclk_post_en.hw, + [AUD_CLKID_MST_C_SCLK_POST_EN] = &mst_c_sclk_post_en.hw, + [AUD_CLKID_MST_D_SCLK_POST_EN] = &mst_d_sclk_post_en.hw, + [AUD_CLKID_MST_E_SCLK_POST_EN] = &mst_e_sclk_post_en.hw, + [AUD_CLKID_MST_F_SCLK_POST_EN] = &mst_f_sclk_post_en.hw, + [AUD_CLKID_MST_A_SCLK] = &mst_a_sclk.hw, + [AUD_CLKID_MST_B_SCLK] = &mst_b_sclk.hw, + [AUD_CLKID_MST_C_SCLK] = &mst_c_sclk.hw, + [AUD_CLKID_MST_D_SCLK] = &mst_d_sclk.hw, + [AUD_CLKID_MST_E_SCLK] = &mst_e_sclk.hw, + [AUD_CLKID_MST_F_SCLK] = &mst_f_sclk.hw, + [AUD_CLKID_MST_A_LRCLK_DIV] = &mst_a_lrclk_div.hw, + [AUD_CLKID_MST_B_LRCLK_DIV] = &mst_b_lrclk_div.hw, + [AUD_CLKID_MST_C_LRCLK_DIV] = &mst_c_lrclk_div.hw, + [AUD_CLKID_MST_D_LRCLK_DIV] = &mst_d_lrclk_div.hw, + [AUD_CLKID_MST_E_LRCLK_DIV] = &mst_e_lrclk_div.hw, + [AUD_CLKID_MST_F_LRCLK_DIV] = &mst_f_lrclk_div.hw, + [AUD_CLKID_MST_A_LRCLK] = &mst_a_lrclk.hw, + [AUD_CLKID_MST_B_LRCLK] = &mst_b_lrclk.hw, + [AUD_CLKID_MST_C_LRCLK] = &mst_c_lrclk.hw, + [AUD_CLKID_MST_D_LRCLK] = &mst_d_lrclk.hw, + [AUD_CLKID_MST_E_LRCLK] = &mst_e_lrclk.hw, + [AUD_CLKID_MST_F_LRCLK] = &mst_f_lrclk.hw, + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &tdmin_a_sclk_sel.hw, + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &tdmin_b_sclk_sel.hw, + [AUD_CLKID_TDMIN_C_SCLK_SEL] = &tdmin_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &tdmin_lb_sclk_sel.hw, + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &tdmout_a_sclk_sel.hw, + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &tdmout_b_sclk_sel.hw, + [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &tdmout_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &tdmin_a_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &tdmin_b_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &tdmin_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &tdmin_lb_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &tdmout_a_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &tdmout_b_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &tdmout_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &tdmin_a_sclk_post_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &tdmin_b_sclk_post_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &tdmin_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &tdmin_lb_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &tdmout_a_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &tdmout_b_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &tdmout_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_A_SCLK] = &tdmin_a_sclk.hw, + [AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw, + [AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw, + [AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw, + [AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw, + [AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw, + [AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw, + [AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw, + [AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw, + [AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw, + [AUD_CLKID_TDMIN_LB_LRCLK] = &tdmin_lb_lrclk.hw, + [AUD_CLKID_TDMOUT_A_LRCLK] = &tdmout_a_lrclk.hw, + [AUD_CLKID_TDMOUT_B_LRCLK] = &tdmout_b_lrclk.hw, + [AUD_CLKID_TDMOUT_C_LRCLK] = &tdmout_c_lrclk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -605,139 +702,139 @@ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { */ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = { .hws = { - [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw, - [AUD_CLKID_PDM] = &aud_pdm.hw, - [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw, - [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw, - [AUD_CLKID_TDMIN_C] = &aud_tdmin_c.hw, - [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw, - [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw, - [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw, - [AUD_CLKID_TDMOUT_C] = &aud_tdmout_c.hw, - [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw, - [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw, - [AUD_CLKID_FRDDR_C] = &aud_frddr_c.hw, - [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw, - [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw, - [AUD_CLKID_TODDR_C] = &aud_toddr_c.hw, - [AUD_CLKID_LOOPBACK] = &aud_loopback.hw, - [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw, - [AUD_CLKID_SPDIFOUT] = &aud_spdifout.hw, - [AUD_CLKID_RESAMPLE] = &aud_resample.hw, - [AUD_CLKID_POWER_DETECT] = &aud_power_detect.hw, - [AUD_CLKID_SPDIFOUT_B] = &aud_spdifout_b.hw, - [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw, - [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw, - [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw, - [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw, - [AUD_CLKID_MST_E_MCLK_SEL] = &aud_mst_e_mclk_sel.hw, - [AUD_CLKID_MST_F_MCLK_SEL] = &aud_mst_f_mclk_sel.hw, - [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw, - [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw, - [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw, - [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw, - [AUD_CLKID_MST_E_MCLK_DIV] = &aud_mst_e_mclk_div.hw, - [AUD_CLKID_MST_F_MCLK_DIV] = &aud_mst_f_mclk_div.hw, - [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw, - [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw, - [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw, - [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw, - [AUD_CLKID_MST_E_MCLK] = &aud_mst_e_mclk.hw, - [AUD_CLKID_MST_F_MCLK] = &aud_mst_f_mclk.hw, - [AUD_CLKID_SPDIFOUT_CLK_SEL] = &aud_spdifout_clk_sel.hw, - [AUD_CLKID_SPDIFOUT_CLK_DIV] = &aud_spdifout_clk_div.hw, - [AUD_CLKID_SPDIFOUT_CLK] = &aud_spdifout_clk.hw, - [AUD_CLKID_SPDIFOUT_B_CLK_SEL] = &aud_spdifout_b_clk_sel.hw, - [AUD_CLKID_SPDIFOUT_B_CLK_DIV] = &aud_spdifout_b_clk_div.hw, - [AUD_CLKID_SPDIFOUT_B_CLK] = &aud_spdifout_b_clk.hw, - [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw, - [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw, - [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw, - [AUD_CLKID_PDM_DCLK_SEL] = &aud_pdm_dclk_sel.hw, - [AUD_CLKID_PDM_DCLK_DIV] = &aud_pdm_dclk_div.hw, - [AUD_CLKID_PDM_DCLK] = &aud_pdm_dclk.hw, - [AUD_CLKID_PDM_SYSCLK_SEL] = &aud_pdm_sysclk_sel.hw, - [AUD_CLKID_PDM_SYSCLK_DIV] = &aud_pdm_sysclk_div.hw, - [AUD_CLKID_PDM_SYSCLK] = &aud_pdm_sysclk.hw, - [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw, - [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw, - [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw, - [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw, - [AUD_CLKID_MST_E_SCLK_PRE_EN] = &aud_mst_e_sclk_pre_en.hw, - [AUD_CLKID_MST_F_SCLK_PRE_EN] = &aud_mst_f_sclk_pre_en.hw, - [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw, - [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw, - [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw, - [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw, - [AUD_CLKID_MST_E_SCLK_DIV] = &aud_mst_e_sclk_div.hw, - [AUD_CLKID_MST_F_SCLK_DIV] = &aud_mst_f_sclk_div.hw, - [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw, - [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw, - [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw, - [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw, - [AUD_CLKID_MST_E_SCLK_POST_EN] = &aud_mst_e_sclk_post_en.hw, - [AUD_CLKID_MST_F_SCLK_POST_EN] = &aud_mst_f_sclk_post_en.hw, - [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw, - [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw, - [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw, - [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw, - [AUD_CLKID_MST_E_SCLK] = &aud_mst_e_sclk.hw, - [AUD_CLKID_MST_F_SCLK] = &aud_mst_f_sclk.hw, - [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw, - [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw, - [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw, - [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw, - [AUD_CLKID_MST_E_LRCLK_DIV] = &aud_mst_e_lrclk_div.hw, - [AUD_CLKID_MST_F_LRCLK_DIV] = &aud_mst_f_lrclk_div.hw, - [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw, - [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw, - [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw, - [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw, - [AUD_CLKID_MST_E_LRCLK] = &aud_mst_e_lrclk.hw, - [AUD_CLKID_MST_F_LRCLK] = &aud_mst_f_lrclk.hw, - [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw, - [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw, - [AUD_CLKID_TDMIN_C_SCLK_SEL] = &aud_tdmin_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw, - [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw, - [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw, - [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &aud_tdmout_c_sclk_sel.hw, - [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &aud_tdmin_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &aud_tdmout_c_sclk_pre_en.hw, - [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw, - [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw, - [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &aud_tdmin_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw, - [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &aud_tdmout_c_sclk_post_en.hw, - [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw, - [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw, - [AUD_CLKID_TDMIN_C_SCLK] = &aud_tdmin_c_sclk.hw, - [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw, - [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw, - [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw, - [AUD_CLKID_TDMOUT_C_SCLK] = &aud_tdmout_c_sclk.hw, - [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw, - [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw, - [AUD_CLKID_TDMIN_C_LRCLK] = &aud_tdmin_c_lrclk.hw, - [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw, - [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw, - [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw, - [AUD_CLKID_TDMOUT_C_LRCLK] = &aud_tdmout_c_lrclk.hw, - [AUD_CLKID_TDM_MCLK_PAD0] = &aud_tdm_mclk_pad_0.hw, - [AUD_CLKID_TDM_MCLK_PAD1] = &aud_tdm_mclk_pad_1.hw, - [AUD_CLKID_TDM_LRCLK_PAD0] = &aud_tdm_lrclk_pad_0.hw, - [AUD_CLKID_TDM_LRCLK_PAD1] = &aud_tdm_lrclk_pad_1.hw, - [AUD_CLKID_TDM_LRCLK_PAD2] = &aud_tdm_lrclk_pad_2.hw, - [AUD_CLKID_TDM_SCLK_PAD0] = &aud_tdm_sclk_pad_0.hw, - [AUD_CLKID_TDM_SCLK_PAD1] = &aud_tdm_sclk_pad_1.hw, - [AUD_CLKID_TDM_SCLK_PAD2] = &aud_tdm_sclk_pad_2.hw, + [AUD_CLKID_DDR_ARB] = &ddr_arb.hw, + [AUD_CLKID_PDM] = &pdm.hw, + [AUD_CLKID_TDMIN_A] = &tdmin_a.hw, + [AUD_CLKID_TDMIN_B] = &tdmin_b.hw, + [AUD_CLKID_TDMIN_C] = &tdmin_c.hw, + [AUD_CLKID_TDMIN_LB] = &tdmin_lb.hw, + [AUD_CLKID_TDMOUT_A] = &tdmout_a.hw, + [AUD_CLKID_TDMOUT_B] = &tdmout_b.hw, + [AUD_CLKID_TDMOUT_C] = &tdmout_c.hw, + [AUD_CLKID_FRDDR_A] = &frddr_a.hw, + [AUD_CLKID_FRDDR_B] = &frddr_b.hw, + [AUD_CLKID_FRDDR_C] = &frddr_c.hw, + [AUD_CLKID_TODDR_A] = &toddr_a.hw, + [AUD_CLKID_TODDR_B] = &toddr_b.hw, + [AUD_CLKID_TODDR_C] = &toddr_c.hw, + [AUD_CLKID_LOOPBACK] = &loopback.hw, + [AUD_CLKID_SPDIFIN] = &spdifin.hw, + [AUD_CLKID_SPDIFOUT] = &spdifout.hw, + [AUD_CLKID_RESAMPLE] = &resample.hw, + [AUD_CLKID_POWER_DETECT] = &power_detect.hw, + [AUD_CLKID_SPDIFOUT_B] = &spdifout_b.hw, + [AUD_CLKID_MST_A_MCLK_SEL] = &mst_a_mclk_sel.hw, + [AUD_CLKID_MST_B_MCLK_SEL] = &mst_b_mclk_sel.hw, + [AUD_CLKID_MST_C_MCLK_SEL] = &mst_c_mclk_sel.hw, + [AUD_CLKID_MST_D_MCLK_SEL] = &mst_d_mclk_sel.hw, + [AUD_CLKID_MST_E_MCLK_SEL] = &mst_e_mclk_sel.hw, + [AUD_CLKID_MST_F_MCLK_SEL] = &mst_f_mclk_sel.hw, + [AUD_CLKID_MST_A_MCLK_DIV] = &mst_a_mclk_div.hw, + [AUD_CLKID_MST_B_MCLK_DIV] = &mst_b_mclk_div.hw, + [AUD_CLKID_MST_C_MCLK_DIV] = &mst_c_mclk_div.hw, + [AUD_CLKID_MST_D_MCLK_DIV] = &mst_d_mclk_div.hw, + [AUD_CLKID_MST_E_MCLK_DIV] = &mst_e_mclk_div.hw, + [AUD_CLKID_MST_F_MCLK_DIV] = &mst_f_mclk_div.hw, + [AUD_CLKID_MST_A_MCLK] = &mst_a_mclk.hw, + [AUD_CLKID_MST_B_MCLK] = &mst_b_mclk.hw, + [AUD_CLKID_MST_C_MCLK] = &mst_c_mclk.hw, + [AUD_CLKID_MST_D_MCLK] = &mst_d_mclk.hw, + [AUD_CLKID_MST_E_MCLK] = &mst_e_mclk.hw, + [AUD_CLKID_MST_F_MCLK] = &mst_f_mclk.hw, + [AUD_CLKID_SPDIFOUT_CLK_SEL] = &spdifout_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_CLK_DIV] = &spdifout_clk_div.hw, + [AUD_CLKID_SPDIFOUT_CLK] = &spdifout_clk.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_SEL] = &spdifout_b_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_DIV] = &spdifout_b_clk_div.hw, + [AUD_CLKID_SPDIFOUT_B_CLK] = &spdifout_b_clk.hw, + [AUD_CLKID_SPDIFIN_CLK_SEL] = &spdifin_clk_sel.hw, + [AUD_CLKID_SPDIFIN_CLK_DIV] = &spdifin_clk_div.hw, + [AUD_CLKID_SPDIFIN_CLK] = &spdifin_clk.hw, + [AUD_CLKID_PDM_DCLK_SEL] = &pdm_dclk_sel.hw, + [AUD_CLKID_PDM_DCLK_DIV] = &pdm_dclk_div.hw, + [AUD_CLKID_PDM_DCLK] = &pdm_dclk.hw, + [AUD_CLKID_PDM_SYSCLK_SEL] = &pdm_sysclk_sel.hw, + [AUD_CLKID_PDM_SYSCLK_DIV] = &pdm_sysclk_div.hw, + [AUD_CLKID_PDM_SYSCLK] = &pdm_sysclk.hw, + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &mst_a_sclk_pre_en.hw, + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &mst_b_sclk_pre_en.hw, + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &mst_c_sclk_pre_en.hw, + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &mst_d_sclk_pre_en.hw, + [AUD_CLKID_MST_E_SCLK_PRE_EN] = &mst_e_sclk_pre_en.hw, + [AUD_CLKID_MST_F_SCLK_PRE_EN] = &mst_f_sclk_pre_en.hw, + [AUD_CLKID_MST_A_SCLK_DIV] = &mst_a_sclk_div.hw, + [AUD_CLKID_MST_B_SCLK_DIV] = &mst_b_sclk_div.hw, + [AUD_CLKID_MST_C_SCLK_DIV] = &mst_c_sclk_div.hw, + [AUD_CLKID_MST_D_SCLK_DIV] = &mst_d_sclk_div.hw, + [AUD_CLKID_MST_E_SCLK_DIV] = &mst_e_sclk_div.hw, + [AUD_CLKID_MST_F_SCLK_DIV] = &mst_f_sclk_div.hw, + [AUD_CLKID_MST_A_SCLK_POST_EN] = &mst_a_sclk_post_en.hw, + [AUD_CLKID_MST_B_SCLK_POST_EN] = &mst_b_sclk_post_en.hw, + [AUD_CLKID_MST_C_SCLK_POST_EN] = &mst_c_sclk_post_en.hw, + [AUD_CLKID_MST_D_SCLK_POST_EN] = &mst_d_sclk_post_en.hw, + [AUD_CLKID_MST_E_SCLK_POST_EN] = &mst_e_sclk_post_en.hw, + [AUD_CLKID_MST_F_SCLK_POST_EN] = &mst_f_sclk_post_en.hw, + [AUD_CLKID_MST_A_SCLK] = &mst_a_sclk.hw, + [AUD_CLKID_MST_B_SCLK] = &mst_b_sclk.hw, + [AUD_CLKID_MST_C_SCLK] = &mst_c_sclk.hw, + [AUD_CLKID_MST_D_SCLK] = &mst_d_sclk.hw, + [AUD_CLKID_MST_E_SCLK] = &mst_e_sclk.hw, + [AUD_CLKID_MST_F_SCLK] = &mst_f_sclk.hw, + [AUD_CLKID_MST_A_LRCLK_DIV] = &mst_a_lrclk_div.hw, + [AUD_CLKID_MST_B_LRCLK_DIV] = &mst_b_lrclk_div.hw, + [AUD_CLKID_MST_C_LRCLK_DIV] = &mst_c_lrclk_div.hw, + [AUD_CLKID_MST_D_LRCLK_DIV] = &mst_d_lrclk_div.hw, + [AUD_CLKID_MST_E_LRCLK_DIV] = &mst_e_lrclk_div.hw, + [AUD_CLKID_MST_F_LRCLK_DIV] = &mst_f_lrclk_div.hw, + [AUD_CLKID_MST_A_LRCLK] = &mst_a_lrclk.hw, + [AUD_CLKID_MST_B_LRCLK] = &mst_b_lrclk.hw, + [AUD_CLKID_MST_C_LRCLK] = &mst_c_lrclk.hw, + [AUD_CLKID_MST_D_LRCLK] = &mst_d_lrclk.hw, + [AUD_CLKID_MST_E_LRCLK] = &mst_e_lrclk.hw, + [AUD_CLKID_MST_F_LRCLK] = &mst_f_lrclk.hw, + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &tdmin_a_sclk_sel.hw, + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &tdmin_b_sclk_sel.hw, + [AUD_CLKID_TDMIN_C_SCLK_SEL] = &tdmin_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &tdmin_lb_sclk_sel.hw, + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &tdmout_a_sclk_sel.hw, + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &tdmout_b_sclk_sel.hw, + [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &tdmout_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &tdmin_a_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &tdmin_b_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &tdmin_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &tdmin_lb_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &tdmout_a_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &tdmout_b_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &tdmout_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &tdmin_a_sclk_post_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &tdmin_b_sclk_post_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &tdmin_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &tdmin_lb_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &tdmout_a_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &tdmout_b_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &tdmout_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_A_SCLK] = &tdmin_a_sclk.hw, + [AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw, + [AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw, + [AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw, + [AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw, + [AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw, + [AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw, + [AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw, + [AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw, + [AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw, + [AUD_CLKID_TDMIN_LB_LRCLK] = &tdmin_lb_lrclk.hw, + [AUD_CLKID_TDMOUT_A_LRCLK] = &tdmout_a_lrclk.hw, + [AUD_CLKID_TDMOUT_B_LRCLK] = &tdmout_b_lrclk.hw, + [AUD_CLKID_TDMOUT_C_LRCLK] = &tdmout_c_lrclk.hw, + [AUD_CLKID_TDM_MCLK_PAD0] = &g12a_tdm_mclk_pad_0.hw, + [AUD_CLKID_TDM_MCLK_PAD1] = &g12a_tdm_mclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD0] = &g12a_tdm_lrclk_pad_0.hw, + [AUD_CLKID_TDM_LRCLK_PAD1] = &g12a_tdm_lrclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD2] = &g12a_tdm_lrclk_pad_2.hw, + [AUD_CLKID_TDM_SCLK_PAD0] = &g12a_tdm_sclk_pad_0.hw, + [AUD_CLKID_TDM_SCLK_PAD1] = &g12a_tdm_sclk_pad_1.hw, + [AUD_CLKID_TDM_SCLK_PAD2] = &g12a_tdm_sclk_pad_2.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -750,139 +847,139 @@ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = { * feel the need to have separate AXG/G12A regmap tables. */ static struct clk_regmap *const aud_clk_regmaps[] = { - &aud_ddr_arb, - &aud_pdm, - &aud_tdmin_a, - &aud_tdmin_b, - &aud_tdmin_c, - &aud_tdmin_lb, - &aud_tdmout_a, - &aud_tdmout_b, - &aud_tdmout_c, - &aud_frddr_a, - &aud_frddr_b, - &aud_frddr_c, - &aud_toddr_a, - &aud_toddr_b, - &aud_toddr_c, - &aud_loopback, - &aud_spdifin, - &aud_spdifout, - &aud_resample, - &aud_power_detect, - &aud_spdifout_b, - &aud_mst_a_mclk_sel, - &aud_mst_b_mclk_sel, - &aud_mst_c_mclk_sel, - &aud_mst_d_mclk_sel, - &aud_mst_e_mclk_sel, - &aud_mst_f_mclk_sel, - &aud_mst_a_mclk_div, - &aud_mst_b_mclk_div, - &aud_mst_c_mclk_div, - &aud_mst_d_mclk_div, - &aud_mst_e_mclk_div, - &aud_mst_f_mclk_div, - &aud_mst_a_mclk, - &aud_mst_b_mclk, - &aud_mst_c_mclk, - &aud_mst_d_mclk, - &aud_mst_e_mclk, - &aud_mst_f_mclk, - &aud_spdifout_clk_sel, - &aud_spdifout_clk_div, - &aud_spdifout_clk, - &aud_spdifin_clk_sel, - &aud_spdifin_clk_div, - &aud_spdifin_clk, - &aud_pdm_dclk_sel, - &aud_pdm_dclk_div, - &aud_pdm_dclk, - &aud_pdm_sysclk_sel, - &aud_pdm_sysclk_div, - &aud_pdm_sysclk, - &aud_mst_a_sclk_pre_en, - &aud_mst_b_sclk_pre_en, - &aud_mst_c_sclk_pre_en, - &aud_mst_d_sclk_pre_en, - &aud_mst_e_sclk_pre_en, - &aud_mst_f_sclk_pre_en, - &aud_mst_a_sclk_div, - &aud_mst_b_sclk_div, - &aud_mst_c_sclk_div, - &aud_mst_d_sclk_div, - &aud_mst_e_sclk_div, - &aud_mst_f_sclk_div, - &aud_mst_a_sclk_post_en, - &aud_mst_b_sclk_post_en, - &aud_mst_c_sclk_post_en, - &aud_mst_d_sclk_post_en, - &aud_mst_e_sclk_post_en, - &aud_mst_f_sclk_post_en, - &aud_mst_a_sclk, - &aud_mst_b_sclk, - &aud_mst_c_sclk, - &aud_mst_d_sclk, - &aud_mst_e_sclk, - &aud_mst_f_sclk, - &aud_mst_a_lrclk_div, - &aud_mst_b_lrclk_div, - &aud_mst_c_lrclk_div, - &aud_mst_d_lrclk_div, - &aud_mst_e_lrclk_div, - &aud_mst_f_lrclk_div, - &aud_mst_a_lrclk, - &aud_mst_b_lrclk, - &aud_mst_c_lrclk, - &aud_mst_d_lrclk, - &aud_mst_e_lrclk, - &aud_mst_f_lrclk, - &aud_tdmin_a_sclk_sel, - &aud_tdmin_b_sclk_sel, - &aud_tdmin_c_sclk_sel, - &aud_tdmin_lb_sclk_sel, - &aud_tdmout_a_sclk_sel, - &aud_tdmout_b_sclk_sel, - &aud_tdmout_c_sclk_sel, - &aud_tdmin_a_sclk_pre_en, - &aud_tdmin_b_sclk_pre_en, - &aud_tdmin_c_sclk_pre_en, - &aud_tdmin_lb_sclk_pre_en, - &aud_tdmout_a_sclk_pre_en, - &aud_tdmout_b_sclk_pre_en, - &aud_tdmout_c_sclk_pre_en, - &aud_tdmin_a_sclk_post_en, - &aud_tdmin_b_sclk_post_en, - &aud_tdmin_c_sclk_post_en, - &aud_tdmin_lb_sclk_post_en, - &aud_tdmout_a_sclk_post_en, - &aud_tdmout_b_sclk_post_en, - &aud_tdmout_c_sclk_post_en, - &aud_tdmin_a_sclk, - &aud_tdmin_b_sclk, - &aud_tdmin_c_sclk, - &aud_tdmin_lb_sclk, - &aud_tdmout_a_sclk, - &aud_tdmout_b_sclk, - &aud_tdmout_c_sclk, - &aud_tdmin_a_lrclk, - &aud_tdmin_b_lrclk, - &aud_tdmin_c_lrclk, - &aud_tdmin_lb_lrclk, - &aud_tdmout_a_lrclk, - &aud_tdmout_b_lrclk, - &aud_tdmout_c_lrclk, - &aud_spdifout_b_clk_sel, - &aud_spdifout_b_clk_div, - &aud_spdifout_b_clk, - &aud_tdm_mclk_pad_0, - &aud_tdm_mclk_pad_1, - &aud_tdm_lrclk_pad_0, - &aud_tdm_lrclk_pad_1, - &aud_tdm_lrclk_pad_2, - &aud_tdm_sclk_pad_0, - &aud_tdm_sclk_pad_1, - &aud_tdm_sclk_pad_2, + &ddr_arb, + &pdm, + &tdmin_a, + &tdmin_b, + &tdmin_c, + &tdmin_lb, + &tdmout_a, + &tdmout_b, + &tdmout_c, + &frddr_a, + &frddr_b, + &frddr_c, + &toddr_a, + &toddr_b, + &toddr_c, + &loopback, + &spdifin, + &spdifout, + &resample, + &power_detect, + &spdifout_b, + &mst_a_mclk_sel, + &mst_b_mclk_sel, + &mst_c_mclk_sel, + &mst_d_mclk_sel, + &mst_e_mclk_sel, + &mst_f_mclk_sel, + &mst_a_mclk_div, + &mst_b_mclk_div, + &mst_c_mclk_div, + &mst_d_mclk_div, + &mst_e_mclk_div, + &mst_f_mclk_div, + &mst_a_mclk, + &mst_b_mclk, + &mst_c_mclk, + &mst_d_mclk, + &mst_e_mclk, + &mst_f_mclk, + &spdifout_clk_sel, + &spdifout_clk_div, + &spdifout_clk, + &spdifin_clk_sel, + &spdifin_clk_div, + &spdifin_clk, + &pdm_dclk_sel, + &pdm_dclk_div, + &pdm_dclk, + &pdm_sysclk_sel, + &pdm_sysclk_div, + &pdm_sysclk, + &mst_a_sclk_pre_en, + &mst_b_sclk_pre_en, + &mst_c_sclk_pre_en, + &mst_d_sclk_pre_en, + &mst_e_sclk_pre_en, + &mst_f_sclk_pre_en, + &mst_a_sclk_div, + &mst_b_sclk_div, + &mst_c_sclk_div, + &mst_d_sclk_div, + &mst_e_sclk_div, + &mst_f_sclk_div, + &mst_a_sclk_post_en, + &mst_b_sclk_post_en, + &mst_c_sclk_post_en, + &mst_d_sclk_post_en, + &mst_e_sclk_post_en, + &mst_f_sclk_post_en, + &mst_a_sclk, + &mst_b_sclk, + &mst_c_sclk, + &mst_d_sclk, + &mst_e_sclk, + &mst_f_sclk, + &mst_a_lrclk_div, + &mst_b_lrclk_div, + &mst_c_lrclk_div, + &mst_d_lrclk_div, + &mst_e_lrclk_div, + &mst_f_lrclk_div, + &mst_a_lrclk, + &mst_b_lrclk, + &mst_c_lrclk, + &mst_d_lrclk, + &mst_e_lrclk, + &mst_f_lrclk, + &tdmin_a_sclk_sel, + &tdmin_b_sclk_sel, + &tdmin_c_sclk_sel, + &tdmin_lb_sclk_sel, + &tdmout_a_sclk_sel, + &tdmout_b_sclk_sel, + &tdmout_c_sclk_sel, + &tdmin_a_sclk_pre_en, + &tdmin_b_sclk_pre_en, + &tdmin_c_sclk_pre_en, + &tdmin_lb_sclk_pre_en, + &tdmout_a_sclk_pre_en, + &tdmout_b_sclk_pre_en, + &tdmout_c_sclk_pre_en, + &tdmin_a_sclk_post_en, + &tdmin_b_sclk_post_en, + &tdmin_c_sclk_post_en, + &tdmin_lb_sclk_post_en, + &tdmout_a_sclk_post_en, + &tdmout_b_sclk_post_en, + &tdmout_c_sclk_post_en, + &tdmin_a_sclk, + &tdmin_b_sclk, + &tdmin_c_sclk, + &tdmin_lb_sclk, + &tdmout_a_sclk, + &tdmout_b_sclk, + &tdmout_c_sclk, + &tdmin_a_lrclk, + &tdmin_b_lrclk, + &tdmin_c_lrclk, + &tdmin_lb_lrclk, + &tdmout_a_lrclk, + &tdmout_b_lrclk, + &tdmout_c_lrclk, + &spdifout_b_clk_sel, + &spdifout_b_clk_div, + &spdifout_b_clk, + &g12a_tdm_mclk_pad_0, + &g12a_tdm_mclk_pad_1, + &g12a_tdm_lrclk_pad_0, + &g12a_tdm_lrclk_pad_1, + &g12a_tdm_lrclk_pad_2, + &g12a_tdm_sclk_pad_0, + &g12a_tdm_sclk_pad_1, + &g12a_tdm_sclk_pad_2, }; static int devm_clk_get_enable(struct device *dev, char *id) From cf52db456fd02dc7a145a4f181c8490a1dfa26d9 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 2 Oct 2019 11:15:28 +0200 Subject: [PATCH 030/160] clk: meson: axg-audio: provide clk top signal name The peripheral clock on the sm1 goes through some muxes and dividers before reaching the audio gates. To model that, without repeating our self too much, the "top" clock signal is introduced and will serve as a the parent of the gates. On the axg and g12a, the top clock is just a pass-through to the audio peripheral clock provided by the main controller. Reviewed-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 18 +++++++++++++++--- drivers/clk/meson/axg-audio.h | 3 ++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index ce8836776d1c..1a4c50a29ad7 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -74,9 +74,7 @@ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_data = &(const struct clk_parent_data) { \ - .fw_name = "pclk", \ - }, \ + .parent_names = (const char *[]){ "aud_top" }, \ .num_parents = 1, \ }, \ } @@ -504,6 +502,18 @@ static struct clk_regmap tdmout_c_lrclk = AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); /* AXG/G12A Clocks */ +static struct clk_hw axg_aud_top = { + .init = &(struct clk_init_data) { + /* Provide aud_top signal name on axg and g12a */ + .name = "aud_top", + .ops = &(const struct clk_ops) {}, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "pclk", + }, + .num_parents = 1, + }, +}; + static struct clk_regmap mst_a_mclk_sel = AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); static struct clk_regmap mst_b_mclk_sel = @@ -691,6 +701,7 @@ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { [AUD_CLKID_TDMOUT_A_LRCLK] = &tdmout_a_lrclk.hw, [AUD_CLKID_TDMOUT_B_LRCLK] = &tdmout_b_lrclk.hw, [AUD_CLKID_TDMOUT_C_LRCLK] = &tdmout_c_lrclk.hw, + [AUD_CLKID_TOP] = &axg_aud_top, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -835,6 +846,7 @@ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = { [AUD_CLKID_TDM_SCLK_PAD0] = &g12a_tdm_sclk_pad_0.hw, [AUD_CLKID_TDM_SCLK_PAD1] = &g12a_tdm_sclk_pad_1.hw, [AUD_CLKID_TDM_SCLK_PAD2] = &g12a_tdm_sclk_pad_2.hw, + [AUD_CLKID_TOP] = &axg_aud_top, [NR_CLKS] = NULL, }, .num = NR_CLKS, diff --git a/drivers/clk/meson/axg-audio.h b/drivers/clk/meson/axg-audio.h index c00e28b2e1a9..a4956837f597 100644 --- a/drivers/clk/meson/axg-audio.h +++ b/drivers/clk/meson/axg-audio.h @@ -116,9 +116,10 @@ #define AUD_CLKID_SPDIFOUT_B_CLK_SEL 153 #define AUD_CLKID_SPDIFOUT_B_CLK_DIV 154 + /* include the CLKIDs which are part of the DT bindings */ #include -#define NR_CLKS 163 +#define NR_CLKS 164 #endif /*__AXG_AUDIO_CLKC_H */ From be4fe445a6d5a6b15676912cff3dd0437d55f1e2 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 2 Oct 2019 11:15:29 +0200 Subject: [PATCH 031/160] clk: meson: axg_audio: add sm1 support Add sm1 support the axg audio clock controllers. This new version is indeed derived from the previous generation, as always, adding a few new clocks to the mix. The number of gates now exceeds 32 and do not fit in a single register. Unfortunately, designers chose to introduce the new gate register immediately after the original one, at the beginning of the register space, shifting all the master clock register offsets. The sm1 also introduce a few mux and divider on the top clock path, possibly to lower the peripheral clocks of the audio blocks if necessary. Reviewed-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 582 ++++++++++++++++++++++++++++++++-- drivers/clk/meson/axg-audio.h | 22 +- 2 files changed, 574 insertions(+), 30 deletions(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 1a4c50a29ad7..46e8713c9bc3 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -66,9 +66,9 @@ }, \ } -#define AUD_PCLK_GATE(_name, _bit) { \ +#define AUD_PCLK_GATE(_name, _reg, _bit) { \ .data = &(struct clk_regmap_gate_data){ \ - .offset = (AUDIO_CLK_GATE_EN), \ + .offset = (_reg), \ .bit_idx = (_bit), \ }, \ .hw.init = &(struct clk_init_data) { \ @@ -290,30 +290,50 @@ static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = { }; #define AUD_TDM_PAD_CTRL(_name, _reg, _shift, _parents) \ - AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents, \ + AUD_MUX(_name, _reg, 0x7, _shift, 0, _parents, \ CLK_SET_RATE_NO_REPARENT) /* Common Clocks */ -static struct clk_regmap ddr_arb = AUD_PCLK_GATE(ddr_arb, 0); -static struct clk_regmap pdm = AUD_PCLK_GATE(pdm, 1); -static struct clk_regmap tdmin_a = AUD_PCLK_GATE(tdmin_a, 2); -static struct clk_regmap tdmin_b = AUD_PCLK_GATE(tdmin_b, 3); -static struct clk_regmap tdmin_c = AUD_PCLK_GATE(tdmin_c, 4); -static struct clk_regmap tdmin_lb = AUD_PCLK_GATE(tdmin_lb, 5); -static struct clk_regmap tdmout_a = AUD_PCLK_GATE(tdmout_a, 6); -static struct clk_regmap tdmout_b = AUD_PCLK_GATE(tdmout_b, 7); -static struct clk_regmap tdmout_c = AUD_PCLK_GATE(tdmout_c, 8); -static struct clk_regmap frddr_a = AUD_PCLK_GATE(frddr_a, 9); -static struct clk_regmap frddr_b = AUD_PCLK_GATE(frddr_b, 10); -static struct clk_regmap frddr_c = AUD_PCLK_GATE(frddr_c, 11); -static struct clk_regmap toddr_a = AUD_PCLK_GATE(toddr_a, 12); -static struct clk_regmap toddr_b = AUD_PCLK_GATE(toddr_b, 13); -static struct clk_regmap toddr_c = AUD_PCLK_GATE(toddr_c, 14); -static struct clk_regmap loopback = AUD_PCLK_GATE(loopback, 15); -static struct clk_regmap spdifin = AUD_PCLK_GATE(spdifin, 16); -static struct clk_regmap spdifout = AUD_PCLK_GATE(spdifout, 17); -static struct clk_regmap resample = AUD_PCLK_GATE(resample, 18); -static struct clk_regmap power_detect = AUD_PCLK_GATE(power_detect, 19); +static struct clk_regmap ddr_arb = + AUD_PCLK_GATE(ddr_arb, AUDIO_CLK_GATE_EN, 0); +static struct clk_regmap pdm = + AUD_PCLK_GATE(pdm, AUDIO_CLK_GATE_EN, 1); +static struct clk_regmap tdmin_a = + AUD_PCLK_GATE(tdmin_a, AUDIO_CLK_GATE_EN, 2); +static struct clk_regmap tdmin_b = + AUD_PCLK_GATE(tdmin_b, AUDIO_CLK_GATE_EN, 3); +static struct clk_regmap tdmin_c = + AUD_PCLK_GATE(tdmin_c, AUDIO_CLK_GATE_EN, 4); +static struct clk_regmap tdmin_lb = + AUD_PCLK_GATE(tdmin_lb, AUDIO_CLK_GATE_EN, 5); +static struct clk_regmap tdmout_a = + AUD_PCLK_GATE(tdmout_a, AUDIO_CLK_GATE_EN, 6); +static struct clk_regmap tdmout_b = + AUD_PCLK_GATE(tdmout_b, AUDIO_CLK_GATE_EN, 7); +static struct clk_regmap tdmout_c = + AUD_PCLK_GATE(tdmout_c, AUDIO_CLK_GATE_EN, 8); +static struct clk_regmap frddr_a = + AUD_PCLK_GATE(frddr_a, AUDIO_CLK_GATE_EN, 9); +static struct clk_regmap frddr_b = + AUD_PCLK_GATE(frddr_b, AUDIO_CLK_GATE_EN, 10); +static struct clk_regmap frddr_c = + AUD_PCLK_GATE(frddr_c, AUDIO_CLK_GATE_EN, 11); +static struct clk_regmap toddr_a = + AUD_PCLK_GATE(toddr_a, AUDIO_CLK_GATE_EN, 12); +static struct clk_regmap toddr_b = + AUD_PCLK_GATE(toddr_b, AUDIO_CLK_GATE_EN, 13); +static struct clk_regmap toddr_c = + AUD_PCLK_GATE(toddr_c, AUDIO_CLK_GATE_EN, 14); +static struct clk_regmap loopback = + AUD_PCLK_GATE(loopback, AUDIO_CLK_GATE_EN, 15); +static struct clk_regmap spdifin = + AUD_PCLK_GATE(spdifin, AUDIO_CLK_GATE_EN, 16); +static struct clk_regmap spdifout = + AUD_PCLK_GATE(spdifout, AUDIO_CLK_GATE_EN, 17); +static struct clk_regmap resample = + AUD_PCLK_GATE(resample, AUDIO_CLK_GATE_EN, 18); +static struct clk_regmap power_detect = + AUD_PCLK_GATE(power_detect, AUDIO_CLK_GATE_EN, 19); static struct clk_regmap spdifout_clk_sel = AUD_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); @@ -572,7 +592,185 @@ static struct clk_regmap g12a_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL( sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data); /* G12a/SM1 clocks */ -static struct clk_regmap spdifout_b = AUD_PCLK_GATE(spdifout_b, 21); +static struct clk_regmap toram = + AUD_PCLK_GATE(toram, AUDIO_CLK_GATE_EN, 20); +static struct clk_regmap spdifout_b = + AUD_PCLK_GATE(spdifout_b, AUDIO_CLK_GATE_EN, 21); +static struct clk_regmap eqdrc = + AUD_PCLK_GATE(eqdrc, AUDIO_CLK_GATE_EN, 22); + +/* SM1 Clocks */ +static struct clk_regmap sm1_clk81_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = AUDIO_CLK81_EN, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_clk81_en", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "pclk", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap sm1_sysclk_a_div = { + .data = &(struct clk_regmap_div_data){ + .offset = AUDIO_CLK81_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_a_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_clk81_en.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap sm1_sysclk_a_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = AUDIO_CLK81_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_a_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_sysclk_a_div.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap sm1_sysclk_b_div = { + .data = &(struct clk_regmap_div_data){ + .offset = AUDIO_CLK81_CTRL, + .shift = 16, + .width = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_b_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_clk81_en.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap sm1_sysclk_b_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = AUDIO_CLK81_CTRL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "aud_sysclk_b_en", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_sysclk_b_div.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_hw *sm1_aud_top_parents[] = { + &sm1_sysclk_a_en.hw, + &sm1_sysclk_b_en.hw, +}; + +static struct clk_regmap sm1_aud_top = { + .data = &(struct clk_regmap_mux_data){ + .offset = AUDIO_CLK81_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "aud_top", + .ops = &clk_regmap_mux_ops, + .parent_hws = sm1_aud_top_parents, + .num_parents = ARRAY_SIZE(sm1_aud_top_parents), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap resample_b = + AUD_PCLK_GATE(resample_b, AUDIO_CLK_GATE_EN, 26); +static struct clk_regmap tovad = + AUD_PCLK_GATE(tovad, AUDIO_CLK_GATE_EN, 27); +static struct clk_regmap locker = + AUD_PCLK_GATE(locker, AUDIO_CLK_GATE_EN, 28); +static struct clk_regmap spdifin_lb = + AUD_PCLK_GATE(spdifin_lb, AUDIO_CLK_GATE_EN, 29); +static struct clk_regmap frddr_d = + AUD_PCLK_GATE(frddr_d, AUDIO_CLK_GATE_EN1, 0); +static struct clk_regmap toddr_d = + AUD_PCLK_GATE(toddr_d, AUDIO_CLK_GATE_EN1, 1); +static struct clk_regmap loopback_b = + AUD_PCLK_GATE(loopback_b, AUDIO_CLK_GATE_EN1, 2); + +static struct clk_regmap sm1_mst_a_mclk_sel = + AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL); +static struct clk_regmap sm1_mst_b_mclk_sel = + AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_SM1_MCLK_B_CTRL); +static struct clk_regmap sm1_mst_c_mclk_sel = + AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_SM1_MCLK_C_CTRL); +static struct clk_regmap sm1_mst_d_mclk_sel = + AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_SM1_MCLK_D_CTRL); +static struct clk_regmap sm1_mst_e_mclk_sel = + AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL); +static struct clk_regmap sm1_mst_f_mclk_sel = + AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL); + +static struct clk_regmap sm1_mst_a_mclk_div = + AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL); +static struct clk_regmap sm1_mst_b_mclk_div = + AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_SM1_MCLK_B_CTRL); +static struct clk_regmap sm1_mst_c_mclk_div = + AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_SM1_MCLK_C_CTRL); +static struct clk_regmap sm1_mst_d_mclk_div = + AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_SM1_MCLK_D_CTRL); +static struct clk_regmap sm1_mst_e_mclk_div = + AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL); +static struct clk_regmap sm1_mst_f_mclk_div = + AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL); + +static struct clk_regmap sm1_mst_a_mclk = + AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_SM1_MCLK_A_CTRL); +static struct clk_regmap sm1_mst_b_mclk = + AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_SM1_MCLK_B_CTRL); +static struct clk_regmap sm1_mst_c_mclk = + AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_SM1_MCLK_C_CTRL); +static struct clk_regmap sm1_mst_d_mclk = + AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_SM1_MCLK_D_CTRL); +static struct clk_regmap sm1_mst_e_mclk = + AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_SM1_MCLK_E_CTRL); +static struct clk_regmap sm1_mst_f_mclk = + AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_SM1_MCLK_F_CTRL); + +static struct clk_regmap sm1_tdm_mclk_pad_0 = AUD_TDM_PAD_CTRL( + tdm_mclk_pad_0, AUDIO_SM1_MST_PAD_CTRL0, 0, mclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_mclk_pad_1 = AUD_TDM_PAD_CTRL( + tdm_mclk_pad_1, AUDIO_SM1_MST_PAD_CTRL0, 4, mclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_lrclk_pad_0 = AUD_TDM_PAD_CTRL( + tdm_lrclk_pad_0, AUDIO_SM1_MST_PAD_CTRL1, 16, lrclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_lrclk_pad_1 = AUD_TDM_PAD_CTRL( + tdm_lrclk_pad_1, AUDIO_SM1_MST_PAD_CTRL1, 20, lrclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_lrclk_pad_2 = AUD_TDM_PAD_CTRL( + tdm_lrclk_pad_2, AUDIO_SM1_MST_PAD_CTRL1, 24, lrclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_sclk_pad_0 = AUD_TDM_PAD_CTRL( + tdm_sclk_pad_0, AUDIO_SM1_MST_PAD_CTRL1, 0, sclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_sclk_pad_1 = AUD_TDM_PAD_CTRL( + tdm_sclk_pad_1, AUDIO_SM1_MST_PAD_CTRL1, 4, sclk_pad_ctrl_parent_data); +static struct clk_regmap sm1_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL( + tdm_sclk_pad_2, AUDIO_SM1_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data); /* * Array of all clocks provided by this provider @@ -852,13 +1050,172 @@ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = { .num = NR_CLKS, }; +/* + * Array of all SM1 clocks provided by this provider + * The input clocks of the controller will be populated at runtime + */ +static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = { + .hws = { + [AUD_CLKID_DDR_ARB] = &ddr_arb.hw, + [AUD_CLKID_PDM] = &pdm.hw, + [AUD_CLKID_TDMIN_A] = &tdmin_a.hw, + [AUD_CLKID_TDMIN_B] = &tdmin_b.hw, + [AUD_CLKID_TDMIN_C] = &tdmin_c.hw, + [AUD_CLKID_TDMIN_LB] = &tdmin_lb.hw, + [AUD_CLKID_TDMOUT_A] = &tdmout_a.hw, + [AUD_CLKID_TDMOUT_B] = &tdmout_b.hw, + [AUD_CLKID_TDMOUT_C] = &tdmout_c.hw, + [AUD_CLKID_FRDDR_A] = &frddr_a.hw, + [AUD_CLKID_FRDDR_B] = &frddr_b.hw, + [AUD_CLKID_FRDDR_C] = &frddr_c.hw, + [AUD_CLKID_TODDR_A] = &toddr_a.hw, + [AUD_CLKID_TODDR_B] = &toddr_b.hw, + [AUD_CLKID_TODDR_C] = &toddr_c.hw, + [AUD_CLKID_LOOPBACK] = &loopback.hw, + [AUD_CLKID_SPDIFIN] = &spdifin.hw, + [AUD_CLKID_SPDIFOUT] = &spdifout.hw, + [AUD_CLKID_RESAMPLE] = &resample.hw, + [AUD_CLKID_SPDIFOUT_B] = &spdifout_b.hw, + [AUD_CLKID_MST_A_MCLK_SEL] = &sm1_mst_a_mclk_sel.hw, + [AUD_CLKID_MST_B_MCLK_SEL] = &sm1_mst_b_mclk_sel.hw, + [AUD_CLKID_MST_C_MCLK_SEL] = &sm1_mst_c_mclk_sel.hw, + [AUD_CLKID_MST_D_MCLK_SEL] = &sm1_mst_d_mclk_sel.hw, + [AUD_CLKID_MST_E_MCLK_SEL] = &sm1_mst_e_mclk_sel.hw, + [AUD_CLKID_MST_F_MCLK_SEL] = &sm1_mst_f_mclk_sel.hw, + [AUD_CLKID_MST_A_MCLK_DIV] = &sm1_mst_a_mclk_div.hw, + [AUD_CLKID_MST_B_MCLK_DIV] = &sm1_mst_b_mclk_div.hw, + [AUD_CLKID_MST_C_MCLK_DIV] = &sm1_mst_c_mclk_div.hw, + [AUD_CLKID_MST_D_MCLK_DIV] = &sm1_mst_d_mclk_div.hw, + [AUD_CLKID_MST_E_MCLK_DIV] = &sm1_mst_e_mclk_div.hw, + [AUD_CLKID_MST_F_MCLK_DIV] = &sm1_mst_f_mclk_div.hw, + [AUD_CLKID_MST_A_MCLK] = &sm1_mst_a_mclk.hw, + [AUD_CLKID_MST_B_MCLK] = &sm1_mst_b_mclk.hw, + [AUD_CLKID_MST_C_MCLK] = &sm1_mst_c_mclk.hw, + [AUD_CLKID_MST_D_MCLK] = &sm1_mst_d_mclk.hw, + [AUD_CLKID_MST_E_MCLK] = &sm1_mst_e_mclk.hw, + [AUD_CLKID_MST_F_MCLK] = &sm1_mst_f_mclk.hw, + [AUD_CLKID_SPDIFOUT_CLK_SEL] = &spdifout_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_CLK_DIV] = &spdifout_clk_div.hw, + [AUD_CLKID_SPDIFOUT_CLK] = &spdifout_clk.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_SEL] = &spdifout_b_clk_sel.hw, + [AUD_CLKID_SPDIFOUT_B_CLK_DIV] = &spdifout_b_clk_div.hw, + [AUD_CLKID_SPDIFOUT_B_CLK] = &spdifout_b_clk.hw, + [AUD_CLKID_SPDIFIN_CLK_SEL] = &spdifin_clk_sel.hw, + [AUD_CLKID_SPDIFIN_CLK_DIV] = &spdifin_clk_div.hw, + [AUD_CLKID_SPDIFIN_CLK] = &spdifin_clk.hw, + [AUD_CLKID_PDM_DCLK_SEL] = &pdm_dclk_sel.hw, + [AUD_CLKID_PDM_DCLK_DIV] = &pdm_dclk_div.hw, + [AUD_CLKID_PDM_DCLK] = &pdm_dclk.hw, + [AUD_CLKID_PDM_SYSCLK_SEL] = &pdm_sysclk_sel.hw, + [AUD_CLKID_PDM_SYSCLK_DIV] = &pdm_sysclk_div.hw, + [AUD_CLKID_PDM_SYSCLK] = &pdm_sysclk.hw, + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &mst_a_sclk_pre_en.hw, + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &mst_b_sclk_pre_en.hw, + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &mst_c_sclk_pre_en.hw, + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &mst_d_sclk_pre_en.hw, + [AUD_CLKID_MST_E_SCLK_PRE_EN] = &mst_e_sclk_pre_en.hw, + [AUD_CLKID_MST_F_SCLK_PRE_EN] = &mst_f_sclk_pre_en.hw, + [AUD_CLKID_MST_A_SCLK_DIV] = &mst_a_sclk_div.hw, + [AUD_CLKID_MST_B_SCLK_DIV] = &mst_b_sclk_div.hw, + [AUD_CLKID_MST_C_SCLK_DIV] = &mst_c_sclk_div.hw, + [AUD_CLKID_MST_D_SCLK_DIV] = &mst_d_sclk_div.hw, + [AUD_CLKID_MST_E_SCLK_DIV] = &mst_e_sclk_div.hw, + [AUD_CLKID_MST_F_SCLK_DIV] = &mst_f_sclk_div.hw, + [AUD_CLKID_MST_A_SCLK_POST_EN] = &mst_a_sclk_post_en.hw, + [AUD_CLKID_MST_B_SCLK_POST_EN] = &mst_b_sclk_post_en.hw, + [AUD_CLKID_MST_C_SCLK_POST_EN] = &mst_c_sclk_post_en.hw, + [AUD_CLKID_MST_D_SCLK_POST_EN] = &mst_d_sclk_post_en.hw, + [AUD_CLKID_MST_E_SCLK_POST_EN] = &mst_e_sclk_post_en.hw, + [AUD_CLKID_MST_F_SCLK_POST_EN] = &mst_f_sclk_post_en.hw, + [AUD_CLKID_MST_A_SCLK] = &mst_a_sclk.hw, + [AUD_CLKID_MST_B_SCLK] = &mst_b_sclk.hw, + [AUD_CLKID_MST_C_SCLK] = &mst_c_sclk.hw, + [AUD_CLKID_MST_D_SCLK] = &mst_d_sclk.hw, + [AUD_CLKID_MST_E_SCLK] = &mst_e_sclk.hw, + [AUD_CLKID_MST_F_SCLK] = &mst_f_sclk.hw, + [AUD_CLKID_MST_A_LRCLK_DIV] = &mst_a_lrclk_div.hw, + [AUD_CLKID_MST_B_LRCLK_DIV] = &mst_b_lrclk_div.hw, + [AUD_CLKID_MST_C_LRCLK_DIV] = &mst_c_lrclk_div.hw, + [AUD_CLKID_MST_D_LRCLK_DIV] = &mst_d_lrclk_div.hw, + [AUD_CLKID_MST_E_LRCLK_DIV] = &mst_e_lrclk_div.hw, + [AUD_CLKID_MST_F_LRCLK_DIV] = &mst_f_lrclk_div.hw, + [AUD_CLKID_MST_A_LRCLK] = &mst_a_lrclk.hw, + [AUD_CLKID_MST_B_LRCLK] = &mst_b_lrclk.hw, + [AUD_CLKID_MST_C_LRCLK] = &mst_c_lrclk.hw, + [AUD_CLKID_MST_D_LRCLK] = &mst_d_lrclk.hw, + [AUD_CLKID_MST_E_LRCLK] = &mst_e_lrclk.hw, + [AUD_CLKID_MST_F_LRCLK] = &mst_f_lrclk.hw, + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &tdmin_a_sclk_sel.hw, + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &tdmin_b_sclk_sel.hw, + [AUD_CLKID_TDMIN_C_SCLK_SEL] = &tdmin_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &tdmin_lb_sclk_sel.hw, + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &tdmout_a_sclk_sel.hw, + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &tdmout_b_sclk_sel.hw, + [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &tdmout_c_sclk_sel.hw, + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &tdmin_a_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &tdmin_b_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &tdmin_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &tdmin_lb_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &tdmout_a_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &tdmout_b_sclk_pre_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &tdmout_c_sclk_pre_en.hw, + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &tdmin_a_sclk_post_en.hw, + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &tdmin_b_sclk_post_en.hw, + [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &tdmin_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &tdmin_lb_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &tdmout_a_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &tdmout_b_sclk_post_en.hw, + [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &tdmout_c_sclk_post_en.hw, + [AUD_CLKID_TDMIN_A_SCLK] = &tdmin_a_sclk.hw, + [AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw, + [AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw, + [AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw, + [AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw, + [AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw, + [AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw, + [AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw, + [AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw, + [AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw, + [AUD_CLKID_TDMIN_LB_LRCLK] = &tdmin_lb_lrclk.hw, + [AUD_CLKID_TDMOUT_A_LRCLK] = &tdmout_a_lrclk.hw, + [AUD_CLKID_TDMOUT_B_LRCLK] = &tdmout_b_lrclk.hw, + [AUD_CLKID_TDMOUT_C_LRCLK] = &tdmout_c_lrclk.hw, + [AUD_CLKID_TDM_MCLK_PAD0] = &sm1_tdm_mclk_pad_0.hw, + [AUD_CLKID_TDM_MCLK_PAD1] = &sm1_tdm_mclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD0] = &sm1_tdm_lrclk_pad_0.hw, + [AUD_CLKID_TDM_LRCLK_PAD1] = &sm1_tdm_lrclk_pad_1.hw, + [AUD_CLKID_TDM_LRCLK_PAD2] = &sm1_tdm_lrclk_pad_2.hw, + [AUD_CLKID_TDM_SCLK_PAD0] = &sm1_tdm_sclk_pad_0.hw, + [AUD_CLKID_TDM_SCLK_PAD1] = &sm1_tdm_sclk_pad_1.hw, + [AUD_CLKID_TDM_SCLK_PAD2] = &sm1_tdm_sclk_pad_2.hw, + [AUD_CLKID_TOP] = &sm1_aud_top.hw, + [AUD_CLKID_TORAM] = &toram.hw, + [AUD_CLKID_EQDRC] = &eqdrc.hw, + [AUD_CLKID_RESAMPLE_B] = &resample_b.hw, + [AUD_CLKID_TOVAD] = &tovad.hw, + [AUD_CLKID_LOCKER] = &locker.hw, + [AUD_CLKID_SPDIFIN_LB] = &spdifin_lb.hw, + [AUD_CLKID_FRDDR_D] = &frddr_d.hw, + [AUD_CLKID_TODDR_D] = &toddr_d.hw, + [AUD_CLKID_LOOPBACK_B] = &loopback_b.hw, + [AUD_CLKID_CLK81_EN] = &sm1_clk81_en.hw, + [AUD_CLKID_SYSCLK_A_DIV] = &sm1_sysclk_a_div.hw, + [AUD_CLKID_SYSCLK_A_EN] = &sm1_sysclk_a_en.hw, + [AUD_CLKID_SYSCLK_B_DIV] = &sm1_sysclk_b_div.hw, + [AUD_CLKID_SYSCLK_B_EN] = &sm1_sysclk_b_en.hw, + [NR_CLKS] = NULL, + }, + .num = NR_CLKS, +}; + + /* Convenience table to populate regmap in .probe() * Note that this table is shared between both AXG and G12A, * with spdifout_b clocks being exclusive to G12A. Since those * clocks are not declared within the AXG onecell table, we do not * feel the need to have separate AXG/G12A regmap tables. */ -static struct clk_regmap *const aud_clk_regmaps[] = { +static struct clk_regmap *const axg_clk_regmaps[] = { &ddr_arb, &pdm, &tdmin_a, @@ -992,6 +1349,158 @@ static struct clk_regmap *const aud_clk_regmaps[] = { &g12a_tdm_sclk_pad_0, &g12a_tdm_sclk_pad_1, &g12a_tdm_sclk_pad_2, + &toram, + &eqdrc, +}; + +static struct clk_regmap *const sm1_clk_regmaps[] = { + &ddr_arb, + &pdm, + &tdmin_a, + &tdmin_b, + &tdmin_c, + &tdmin_lb, + &tdmout_a, + &tdmout_b, + &tdmout_c, + &frddr_a, + &frddr_b, + &frddr_c, + &toddr_a, + &toddr_b, + &toddr_c, + &loopback, + &spdifin, + &spdifout, + &resample, + &spdifout_b, + &sm1_mst_a_mclk_sel, + &sm1_mst_b_mclk_sel, + &sm1_mst_c_mclk_sel, + &sm1_mst_d_mclk_sel, + &sm1_mst_e_mclk_sel, + &sm1_mst_f_mclk_sel, + &sm1_mst_a_mclk_div, + &sm1_mst_b_mclk_div, + &sm1_mst_c_mclk_div, + &sm1_mst_d_mclk_div, + &sm1_mst_e_mclk_div, + &sm1_mst_f_mclk_div, + &sm1_mst_a_mclk, + &sm1_mst_b_mclk, + &sm1_mst_c_mclk, + &sm1_mst_d_mclk, + &sm1_mst_e_mclk, + &sm1_mst_f_mclk, + &spdifout_clk_sel, + &spdifout_clk_div, + &spdifout_clk, + &spdifin_clk_sel, + &spdifin_clk_div, + &spdifin_clk, + &pdm_dclk_sel, + &pdm_dclk_div, + &pdm_dclk, + &pdm_sysclk_sel, + &pdm_sysclk_div, + &pdm_sysclk, + &mst_a_sclk_pre_en, + &mst_b_sclk_pre_en, + &mst_c_sclk_pre_en, + &mst_d_sclk_pre_en, + &mst_e_sclk_pre_en, + &mst_f_sclk_pre_en, + &mst_a_sclk_div, + &mst_b_sclk_div, + &mst_c_sclk_div, + &mst_d_sclk_div, + &mst_e_sclk_div, + &mst_f_sclk_div, + &mst_a_sclk_post_en, + &mst_b_sclk_post_en, + &mst_c_sclk_post_en, + &mst_d_sclk_post_en, + &mst_e_sclk_post_en, + &mst_f_sclk_post_en, + &mst_a_sclk, + &mst_b_sclk, + &mst_c_sclk, + &mst_d_sclk, + &mst_e_sclk, + &mst_f_sclk, + &mst_a_lrclk_div, + &mst_b_lrclk_div, + &mst_c_lrclk_div, + &mst_d_lrclk_div, + &mst_e_lrclk_div, + &mst_f_lrclk_div, + &mst_a_lrclk, + &mst_b_lrclk, + &mst_c_lrclk, + &mst_d_lrclk, + &mst_e_lrclk, + &mst_f_lrclk, + &tdmin_a_sclk_sel, + &tdmin_b_sclk_sel, + &tdmin_c_sclk_sel, + &tdmin_lb_sclk_sel, + &tdmout_a_sclk_sel, + &tdmout_b_sclk_sel, + &tdmout_c_sclk_sel, + &tdmin_a_sclk_pre_en, + &tdmin_b_sclk_pre_en, + &tdmin_c_sclk_pre_en, + &tdmin_lb_sclk_pre_en, + &tdmout_a_sclk_pre_en, + &tdmout_b_sclk_pre_en, + &tdmout_c_sclk_pre_en, + &tdmin_a_sclk_post_en, + &tdmin_b_sclk_post_en, + &tdmin_c_sclk_post_en, + &tdmin_lb_sclk_post_en, + &tdmout_a_sclk_post_en, + &tdmout_b_sclk_post_en, + &tdmout_c_sclk_post_en, + &tdmin_a_sclk, + &tdmin_b_sclk, + &tdmin_c_sclk, + &tdmin_lb_sclk, + &tdmout_a_sclk, + &tdmout_b_sclk, + &tdmout_c_sclk, + &tdmin_a_lrclk, + &tdmin_b_lrclk, + &tdmin_c_lrclk, + &tdmin_lb_lrclk, + &tdmout_a_lrclk, + &tdmout_b_lrclk, + &tdmout_c_lrclk, + &spdifout_b_clk_sel, + &spdifout_b_clk_div, + &spdifout_b_clk, + &sm1_tdm_mclk_pad_0, + &sm1_tdm_mclk_pad_1, + &sm1_tdm_lrclk_pad_0, + &sm1_tdm_lrclk_pad_1, + &sm1_tdm_lrclk_pad_2, + &sm1_tdm_sclk_pad_0, + &sm1_tdm_sclk_pad_1, + &sm1_tdm_sclk_pad_2, + &sm1_aud_top, + &toram, + &eqdrc, + &resample_b, + &tovad, + &locker, + &spdifin_lb, + &frddr_d, + &toddr_d, + &loopback_b, + &sm1_clk81_en, + &sm1_sysclk_a_div, + &sm1_sysclk_a_en, + &sm1_sysclk_b_div, + &sm1_sysclk_b_en, }; static int devm_clk_get_enable(struct device *dev, char *id) @@ -1110,6 +1619,8 @@ static const struct regmap_config axg_audio_regmap_cfg = { }; struct audioclk_data { + struct clk_regmap *const *regmap_clks; + unsigned int regmap_clk_num; struct clk_hw_onecell_data *hw_onecell_data; unsigned int reset_offset; unsigned int reset_num; @@ -1153,8 +1664,8 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) } /* Populate regmap for the regmap backed clocks */ - for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++) - aud_clk_regmaps[i]->map = map; + for (i = 0; i < data->regmap_clk_num; i++) + data->regmap_clks[i]->map = map; /* Take care to skip the registered input clocks */ for (i = AUD_CLKID_DDR_ARB; i < data->hw_onecell_data->num; i++) { @@ -1198,15 +1709,27 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) } static const struct audioclk_data axg_audioclk_data = { + .regmap_clks = axg_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps), .hw_onecell_data = &axg_audio_hw_onecell_data, }; static const struct audioclk_data g12a_audioclk_data = { + .regmap_clks = axg_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps), .hw_onecell_data = &g12a_audio_hw_onecell_data, .reset_offset = AUDIO_SW_RESET, .reset_num = 26, }; +static const struct audioclk_data sm1_audioclk_data = { + .regmap_clks = sm1_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(sm1_clk_regmaps), + .hw_onecell_data = &sm1_audio_hw_onecell_data, + .reset_offset = AUDIO_SM1_SW_RESET0, + .reset_num = 39, +}; + static const struct of_device_id clkc_match_table[] = { { .compatible = "amlogic,axg-audio-clkc", @@ -1214,6 +1737,9 @@ static const struct of_device_id clkc_match_table[] = { }, { .compatible = "amlogic,g12a-audio-clkc", .data = &g12a_audioclk_data + }, { + .compatible = "amlogic,sm1-audio-clkc", + .data = &sm1_audioclk_data }, {} }; MODULE_DEVICE_TABLE(of, clkc_match_table); @@ -1227,6 +1753,6 @@ static struct platform_driver axg_audio_driver = { }; module_platform_driver(axg_audio_driver); -MODULE_DESCRIPTION("Amlogic AXG/G12A Audio Clock driver"); +MODULE_DESCRIPTION("Amlogic AXG/G12A/SM1 Audio Clock driver"); MODULE_AUTHOR("Jerome Brunet "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/meson/axg-audio.h b/drivers/clk/meson/axg-audio.h index a4956837f597..fd65a7d0704b 100644 --- a/drivers/clk/meson/axg-audio.h +++ b/drivers/clk/meson/axg-audio.h @@ -50,6 +50,20 @@ #define AUDIO_CLK_PDMIN_CTRL1 0x0B0 #define AUDIO_CLK_SPDIFOUT_B_CTRL 0x0B4 +/* SM1 introduce new register and some shifts :( */ +#define AUDIO_CLK_GATE_EN1 0x004 +#define AUDIO_SM1_MCLK_A_CTRL 0x008 +#define AUDIO_SM1_MCLK_B_CTRL 0x00C +#define AUDIO_SM1_MCLK_C_CTRL 0x010 +#define AUDIO_SM1_MCLK_D_CTRL 0x014 +#define AUDIO_SM1_MCLK_E_CTRL 0x018 +#define AUDIO_SM1_MCLK_F_CTRL 0x01C +#define AUDIO_SM1_MST_PAD_CTRL0 0x020 +#define AUDIO_SM1_MST_PAD_CTRL1 0x024 +#define AUDIO_SM1_SW_RESET0 0x028 +#define AUDIO_SM1_SW_RESET1 0x02C +#define AUDIO_CLK81_CTRL 0x030 +#define AUDIO_CLK81_EN 0x034 /* * CLKID index values * These indices are entirely contrived and do not map onto the hardware. @@ -115,11 +129,15 @@ #define AUD_CLKID_TDMOUT_C_SCLK_POST_EN 150 #define AUD_CLKID_SPDIFOUT_B_CLK_SEL 153 #define AUD_CLKID_SPDIFOUT_B_CLK_DIV 154 - +#define AUD_CLKID_CLK81_EN 173 +#define AUD_CLKID_SYSCLK_A_DIV 174 +#define AUD_CLKID_SYSCLK_B_DIV 175 +#define AUD_CLKID_SYSCLK_A_EN 176 +#define AUD_CLKID_SYSCLK_B_EN 177 /* include the CLKIDs which are part of the DT bindings */ #include -#define NR_CLKS 164 +#define NR_CLKS 178 #endif /*__AXG_AUDIO_CLKC_H */ From f0b1d7f2e7c2348ae4c856dffb6172c80a023483 Mon Sep 17 00:00:00 2001 From: Laurentiu Palcu Date: Wed, 2 Oct 2019 17:04:53 +0300 Subject: [PATCH 032/160] clk: imx8mq: Add VIDEO2_PLL clock This clock is needed by DCSS when high resolutions are used. Signed-off-by: Laurentiu Palcu CC: Abel Vesa Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mq.c | 4 ++++ include/dt-bindings/clock/imx8mq-clock.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 41fc9c63356e..05ece7b5da54 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -38,6 +38,7 @@ static const char * const sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", }; static const char * const sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", }; static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", }; static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", }; +static const char * const video2_pll_out_sels[] = {"video2_pll1_ref_sel", }; /* CCM ROOT */ static const char * const imx8mq_a53_sels[] = {"osc_25m", "arm_pll_out", "sys2_pll_500m", "sys2_pll_1000m", @@ -311,6 +312,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) clks[IMX8MQ_SYS2_PLL1_REF_SEL] = imx_clk_mux("sys2_pll1_ref_sel", base + 0x3c, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_ARM_PLL_REF_DIV] = imx_clk_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6); clks[IMX8MQ_GPU_PLL_REF_DIV] = imx_clk_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6); @@ -346,6 +348,8 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_sccg_pll("sys2_pll_out", sys2_pll_out_sels, ARRAY_SIZE(sys2_pll_out_sels), 0, 0, 1, base + 0x3c, CLK_IS_CRITICAL); clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL); clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL); + clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); + /* SYS PLL fixed output */ clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h index 65463673d25e..35b9ed9d62d8 100644 --- a/include/dt-bindings/clock/imx8mq-clock.h +++ b/include/dt-bindings/clock/imx8mq-clock.h @@ -403,5 +403,7 @@ #define IMX8MQ_CLK_SNVS_ROOT 264 #define IMX8MQ_CLK_GIC 265 -#define IMX8MQ_CLK_END 266 +#define IMX8MQ_VIDEO2_PLL1_REF_SEL 266 + +#define IMX8MQ_CLK_END 267 #endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */ From 8f2d3c1759d19232edf1e9ef43d40a44e31493d6 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 8 Oct 2019 15:19:08 +0800 Subject: [PATCH 033/160] clk: imx: clk-pll14xx: Make two variables static Fix sparse warnings: drivers/clk/imx/clk-pll14xx.c:44:37: warning: symbol 'imx_pll1416x_tbl' was not declared. Should it be static? drivers/clk/imx/clk-pll14xx.c:57:37: warning: symbol 'imx_pll1443x_tbl' was not declared. Should it be static? Reported-by: Hulk Robot Signed-off-by: YueHaibing Reviewed-by: Anson Huang Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-pll14xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 7faad6065785..5c458199060a 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -41,7 +41,7 @@ struct clk_pll14xx { #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) -const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { +static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { PLL_1416X_RATE(1800000000U, 225, 3, 0), PLL_1416X_RATE(1600000000U, 200, 3, 0), PLL_1416X_RATE(1500000000U, 375, 3, 1), @@ -54,7 +54,7 @@ const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { PLL_1416X_RATE(600000000U, 300, 3, 2), }; -const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { +static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { PLL_1443X_RATE(650000000U, 325, 3, 2, 0), PLL_1443X_RATE(594000000U, 198, 2, 2, 0), PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), From 50bf025b75902d326fdb8078be3d278e1b693576 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 14 Oct 2019 22:43:16 +0800 Subject: [PATCH 034/160] clk: meson: axg-audio: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 46e8713c9bc3..53715e36326c 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -1632,7 +1632,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) const struct audioclk_data *data; struct axg_audio_reset_data *rst; struct regmap *map; - struct resource *res; void __iomem *regs; struct clk_hw *hw; int ret, i; @@ -1641,8 +1640,7 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) if (!data) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs = devm_ioremap_resource(dev, res); + regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) return PTR_ERR(regs); From b8cb1ef95b6e2b67f06f5254d01d5411cf2c79ae Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 19:51:17 +0800 Subject: [PATCH 035/160] clk: ast2600: remove unused variable 'eclk_parent_names' drivers/clk/clk-ast2600.c:119:27: warning: eclk_parent_names defined but not used [-Wunused-const-variable=] It is never used, so can be removed. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015115117.23504-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-ast2600.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index 1c1bb39bb04e..ebaafb57a24f 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -116,8 +116,6 @@ static const struct aspeed_gate_data aspeed_g6_gates[] = { [ASPEED_CLK_GATE_FSICLK] = { 62, 59, "fsiclk-gate", NULL, 0 }, /* FSI */ }; -static const char * const eclk_parent_names[] = { "mpll", "hpll", "dpll" }; - static const struct clk_div_table ast2600_eclk_div_table[] = { { 0x0, 2 }, { 0x1, 2 }, From 727e12cde9f6d888205db027fc8bf90ece61c6b2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 15 Oct 2019 07:05:53 +0000 Subject: [PATCH 036/160] clk: imx: imx8mn: drop unused pll enum The PLL enum definition is not used, so drop it. Signed-off-by: Peng Fan Link: https://lkml.kernel.org/r/1571122989-29361-1-git-send-email-peng.fan@nxp.com Signed-off-by: Stephen Boyd --- drivers/clk/imx/clk-imx8mn.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 47a4b44ba3cb..ccd05321f043 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -25,20 +25,6 @@ static u32 share_count_disp; static u32 share_count_pdm; static u32 share_count_nand; -enum { - ARM_PLL, - GPU_PLL, - VPU_PLL, - SYS_PLL1, - SYS_PLL2, - SYS_PLL3, - DRAM_PLL, - AUDIO_PLL1, - AUDIO_PLL2, - VIDEO_PLL2, - NR_PLLS, -}; - static const struct imx_pll14xx_rate_table imx8mn_pll1416x_tbl[] = { PLL_1416X_RATE(1800000000U, 225, 3, 0), PLL_1416X_RATE(1600000000U, 200, 3, 0), From 4d3a369510dda6336534c4364910312f432c54a5 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 14 Oct 2019 22:36:42 +0800 Subject: [PATCH 037/160] clk: bcm2835: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191014143642.24552-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-bcm2835-aux.c | 4 +--- drivers/clk/bcm/clk-bcm2835.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c index b6d07ca0164f..290a2846a86b 100644 --- a/drivers/clk/bcm/clk-bcm2835-aux.c +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -19,7 +19,6 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev) struct clk_hw_onecell_data *onecell; const char *parent; struct clk *parent_clk; - struct resource *res; void __iomem *reg, *gate; parent_clk = devm_clk_get(dev, NULL); @@ -27,8 +26,7 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev) return PTR_ERR(parent_clk); parent = __clk_get_name(parent_clk); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - reg = devm_ioremap_resource(dev, res); + reg = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 802e488fd3c3..ded13ccf768e 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -2192,7 +2192,6 @@ static int bcm2835_clk_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct clk_hw **hws; struct bcm2835_cprman *cprman; - struct resource *res; const struct bcm2835_clk_desc *desc; const size_t asize = ARRAY_SIZE(clk_desc_array); const struct cprman_plat_data *pdata; @@ -2211,8 +2210,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev) spin_lock_init(&cprman->regs_lock); cprman->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - cprman->regs = devm_ioremap_resource(dev, res); + cprman->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(cprman->regs)) return PTR_ERR(cprman->regs); From 75cc0a123c90c8e3bfd8d279395d0bd558670424 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 14 Oct 2019 22:40:14 +0800 Subject: [PATCH 038/160] clk: hisilicon: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191014144014.20644-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/reset.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c index 2e22fea2a2e7..93cee17db8b1 100644 --- a/drivers/clk/hisilicon/reset.c +++ b/drivers/clk/hisilicon/reset.c @@ -90,14 +90,12 @@ static const struct reset_control_ops hisi_reset_ops = { struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev) { struct hisi_reset_controller *rstc; - struct resource *res; rstc = devm_kmalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL); if (!rstc) return NULL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - rstc->membase = devm_ioremap_resource(&pdev->dev, res); + rstc->membase = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rstc->membase)) return NULL; From 1f8f3c6b35b235fea7fa72846a6b2c8af7596607 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 14 Oct 2019 22:44:07 +0800 Subject: [PATCH 039/160] clk: davinci: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191014144407.23264-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/davinci/pll.c | 4 +--- drivers/clk/davinci/psc.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c index 1ac11b6a47a3..8a23d5dfd1f8 100644 --- a/drivers/clk/davinci/pll.c +++ b/drivers/clk/davinci/pll.c @@ -910,7 +910,6 @@ static int davinci_pll_probe(struct platform_device *pdev) struct davinci_pll_platform_data *pdata; const struct of_device_id *of_id; davinci_pll_init pll_init = NULL; - struct resource *res; void __iomem *base; of_id = of_match_device(davinci_pll_of_match, dev); @@ -930,8 +929,7 @@ static int davinci_pll_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index 5b69e24a224f..7387e7f6276e 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -531,7 +531,6 @@ static int davinci_psc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const struct of_device_id *of_id; const struct davinci_psc_init_data *init_data = NULL; - struct resource *res; void __iomem *base; int ret; @@ -546,8 +545,7 @@ static int davinci_psc_probe(struct platform_device *pdev) return -EINVAL; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From 73c3bf70b37b429d9bc8b428128235b6e5932b24 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 19:26:44 +0800 Subject: [PATCH 040/160] clk: mediatek: mt2712: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015112644.19816-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt2712.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c index 354c26f663b4..a3bd9a107209 100644 --- a/drivers/clk/mediatek/clk-mt2712.c +++ b/drivers/clk/mediatek/clk-mt2712.c @@ -1306,9 +1306,8 @@ static int clk_mt2712_top_probe(struct platform_device *pdev) int r, i; struct device_node *node = pdev->dev.of_node; void __iomem *base; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { pr_err("%s(): ioremap failed\n", __func__); return PTR_ERR(base); @@ -1394,9 +1393,8 @@ static int clk_mt2712_mcu_probe(struct platform_device *pdev) int r; struct device_node *node = pdev->dev.of_node; void __iomem *base; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { pr_err("%s(): ioremap failed\n", __func__); return PTR_ERR(base); From 71ae814181749381436d6c8ca2cccba3ca899ac1 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 20:10:35 +0800 Subject: [PATCH 041/160] clk: mediatek: mt6779: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015121035.24736-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt6779.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c index 608a9a6621a3..9766cccf5844 100644 --- a/drivers/clk/mediatek/clk-mt6779.c +++ b/drivers/clk/mediatek/clk-mt6779.c @@ -1225,12 +1225,11 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev) static int clk_mt6779_top_probe(struct platform_device *pdev) { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); void __iomem *base; struct clk_onecell_data *clk_data; struct device_node *node = pdev->dev.of_node; - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From 067de0a647a0018030dbe503666a793e37d9fd7f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 20:14:21 +0800 Subject: [PATCH 042/160] clk: mediatek: mt8183: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015121421.26144-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt8183.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c index 51c8d5c9a030..5046852eb0fd 100644 --- a/drivers/clk/mediatek/clk-mt8183.c +++ b/drivers/clk/mediatek/clk-mt8183.c @@ -1189,11 +1189,10 @@ CLK_OF_DECLARE_DRIVER(mt8183_topckgen, "mediatek,mt8183-topckgen", static int clk_mt8183_top_probe(struct platform_device *pdev) { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); void __iomem *base; struct device_node *node = pdev->dev.of_node; - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -1262,9 +1261,8 @@ static int clk_mt8183_mcu_probe(struct platform_device *pdev) struct clk_onecell_data *clk_data; struct device_node *node = pdev->dev.of_node; void __iomem *base; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From ed4e1bbb44111466fd2cdbe2ed25ce030aa4288b Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 20:17:35 +0800 Subject: [PATCH 043/160] clk: mediatek: mt7622: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015121735.26228-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt7622.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c index 8190dab179d7..ef5947e15c75 100644 --- a/drivers/clk/mediatek/clk-mt7622.c +++ b/drivers/clk/mediatek/clk-mt7622.c @@ -614,9 +614,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) struct clk_onecell_data *clk_data; void __iomem *base; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -695,9 +694,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) void __iomem *base; int r; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From aa136002ae227468d75dd2f82f1a4baa3558a7d4 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 20:42:26 +0800 Subject: [PATCH 044/160] clk: mediatek: mt7629: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015124226.25792-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt7629.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c index d6233994af5a..b73bdf152836 100644 --- a/drivers/clk/mediatek/clk-mt7629.c +++ b/drivers/clk/mediatek/clk-mt7629.c @@ -574,9 +574,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) struct clk_onecell_data *clk_data; void __iomem *base; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -626,9 +625,8 @@ static int mtk_pericfg_init(struct platform_device *pdev) void __iomem *base; int r; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From 0b17159de2c3be6a6b48b40f9c2c370dbdef456f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 20:47:28 +0800 Subject: [PATCH 045/160] clk: mediatek: mt6797: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015124728.25072-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt6797.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c index f62b0428da0e..f35389a11af1 100644 --- a/drivers/clk/mediatek/clk-mt6797.c +++ b/drivers/clk/mediatek/clk-mt6797.c @@ -385,9 +385,8 @@ static int mtk_topckgen_init(struct platform_device *pdev) struct clk_onecell_data *clk_data; void __iomem *base; struct device_node *node = pdev->dev.of_node; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From 21ec8679c2cbb874885b11f7bc1c7e4d6e673c1b Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 22:22:59 +0800 Subject: [PATCH 046/160] clk: axs10x: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015142259.17216-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/axs10x/i2s_pll_clock.c | 4 +--- drivers/clk/axs10x/pll_clock.c | 7 ++----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/clk/axs10x/i2s_pll_clock.c b/drivers/clk/axs10x/i2s_pll_clock.c index 71c2e9519ca8..e9da0e69bf6c 100644 --- a/drivers/clk/axs10x/i2s_pll_clock.c +++ b/drivers/clk/axs10x/i2s_pll_clock.c @@ -172,14 +172,12 @@ static int i2s_pll_clk_probe(struct platform_device *pdev) struct clk *clk; struct i2s_pll_clk *pll_clk; struct clk_init_data init; - struct resource *mem; pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); if (!pll_clk) return -ENOMEM; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pll_clk->base = devm_ioremap_resource(dev, mem); + pll_clk->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pll_clk->base)) return PTR_ERR(pll_clk->base); diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c index aba787b2e771..500345d99adb 100644 --- a/drivers/clk/axs10x/pll_clock.c +++ b/drivers/clk/axs10x/pll_clock.c @@ -221,7 +221,6 @@ static int axs10x_pll_clk_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const char *parent_name; struct axs10x_pll_clk *pll_clk; - struct resource *mem; struct clk_init_data init = { }; int ret; @@ -229,13 +228,11 @@ static int axs10x_pll_clk_probe(struct platform_device *pdev) if (!pll_clk) return -ENOMEM; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pll_clk->base = devm_ioremap_resource(dev, mem); + pll_clk->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pll_clk->base)) return PTR_ERR(pll_clk->base); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - pll_clk->lock = devm_ioremap_resource(dev, mem); + pll_clk->lock = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(pll_clk->lock)) return PTR_ERR(pll_clk->lock); From 56a57321395e13172f315036234c28cf95f943d3 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 15 Oct 2019 22:24:24 +0800 Subject: [PATCH 047/160] clk: s3c2410: use devm_platform_ioremap_resource() to simplify code Use devm_platform_ioremap_resource() to simplify the code a bit. This is detected by coccinelle. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191015142424.25944-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/samsung/clk-s3c2410-dclk.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c index 1281672cb00e..7dad9098e897 100644 --- a/drivers/clk/samsung/clk-s3c2410-dclk.c +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c @@ -238,7 +238,6 @@ static SIMPLE_DEV_PM_OPS(s3c24xx_dclk_pm_ops, static int s3c24xx_dclk_probe(struct platform_device *pdev) { struct s3c24xx_dclk *s3c24xx_dclk; - struct resource *mem; struct s3c24xx_dclk_drv_data *dclk_variant; struct clk_hw **clk_table; int ret, i; @@ -257,8 +256,7 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev) platform_set_drvdata(pdev, s3c24xx_dclk); spin_lock_init(&s3c24xx_dclk->dclk_lock); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem); + s3c24xx_dclk->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(s3c24xx_dclk->base)) return PTR_ERR(s3c24xx_dclk->base); From 793ee798cc47abb41e9215d97cc38cb9e050e969 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Tue, 8 Oct 2019 15:41:39 +0800 Subject: [PATCH 048/160] clk: sprd: Change to use devm_platform_ioremap_resource() Use the new helper that wraps the calls to platform_get_resource() and devm_ioremap_resource() together, which can simpify the code. Signed-off-by: Baolin Wang Link: https://lkml.kernel.org/r/841d26a2adb4bf3b4423f82a41dd3f1346413db6.1570520268.git.baolin.wang@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/sprd/common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c index 9d56eac43832..37186963d618 100644 --- a/drivers/clk/sprd/common.c +++ b/drivers/clk/sprd/common.c @@ -42,7 +42,6 @@ int sprd_clk_regmap_init(struct platform_device *pdev, void __iomem *base; struct device_node *node = pdev->dev.of_node; struct regmap *regmap; - struct resource *res; if (of_find_property(node, "sprd,syscon", NULL)) { regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); @@ -51,8 +50,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev, return PTR_ERR(regmap); } } else { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); From 8e7b71f8a9750be1ca15f0285142a6aa000755a0 Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 11 Oct 2019 18:59:27 +0530 Subject: [PATCH 049/160] dt-bindings: clock: qcom: Add QCOM Q6SSTOP clock controller bindings Add devicetree binding for the Q6SSTOP clock controller found in QCS404. Signed-off-by: Govind Singh Link: https://lkml.kernel.org/r/20191011132928.9388-2-govinds@codeaurora.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../bindings/clock/qcom,q6sstopcc.yaml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,q6sstopcc.yaml diff --git a/Documentation/devicetree/bindings/clock/qcom,q6sstopcc.yaml b/Documentation/devicetree/bindings/clock/qcom,q6sstopcc.yaml new file mode 100644 index 000000000000..bbaaf1e2a203 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,q6sstopcc.yaml @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,q6sstopcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Q6SSTOP clock Controller + +maintainers: + - Govind Singh + +properties: + compatible: + const: "qcom,qcs404-q6sstopcc" + + reg: + items: + - description: Q6SSTOP clocks register region + - description: Q6SSTOP_TCSR register region + + clocks: + items: + - description: ahb clock for the q6sstopCC + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + - clocks + - '#clock-cells' + +additionalProperties: false + +examples: + - | + q6sstopcc: clock-controller@7500000 { + compatible = "qcom,qcs404-q6sstopcc"; + reg = <0x07500000 0x4e000>, <0x07550000 0x10000>; + clocks = <&gcc 141>; + #clock-cells = <1>; + }; From 7aee839ed27d813a3adcf9da3a19b60b6581f867 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:13 +0200 Subject: [PATCH 050/160] clk: renesas: rcar-gen2: Switch Z clock to .determine_rate() As the .round_rate() callback returns a long clock rate, it cannot return clock rates that do not fit in signed long, but do fit in unsigned long. Hence switch the Z clock on R-Car Gen2 from the old .round_rate() callback to the newer .determine_rate() callback, which does not suffer from this limitation. This includes implementing range checking. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20190830134515.11925-7-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen2-cpg.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index c378505830f0..d4fa3dc3e2a2 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -63,19 +63,22 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, return div_u64((u64)parent_rate * mult, 32); } -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cpg_z_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long prate = *parent_rate; - unsigned int mult; + unsigned long prate = req->best_parent_rate; + unsigned int min_mult, max_mult, mult; - if (!prate) - prate = 1; + min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL); + max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL); + if (max_mult < min_mult) + return -EINVAL; - mult = div64_ul(rate * 32ULL, prate); - mult = clamp(mult, 1U, 32U); + mult = div64_ul(req->rate * 32ULL, prate); + mult = clamp(mult, min_mult, max_mult); - return div_u64((u64)*parent_rate * mult, 32); + req->rate = div_u64((u64)prate * mult, 32); + return 0; } static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -126,7 +129,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops cpg_z_clk_ops = { .recalc_rate = cpg_z_clk_recalc_rate, - .round_rate = cpg_z_clk_round_rate, + .determine_rate = cpg_z_clk_determine_rate, .set_rate = cpg_z_clk_set_rate, }; From df98719f033cf5903febf036ffdeb5b0f77a0fda Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:14 +0200 Subject: [PATCH 051/160] clk: renesas: rcar-gen3: Switch Z clocks to .determine_rate() As the .round_rate() callback returns a long clock rate, it cannot return clock rates that do not fit in signed long, but do fit in unsigned long. Hence switch the Z clocks on R-Car Gen3 from the old .round_rate() callback to the newer .determine_rate() callback, which does not suffer from this limitation. This includes implementing range checking. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20190830134515.11925-8-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen3-cpg.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 39cd0c4e4e79..4c2821afd365 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -114,18 +114,24 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, 32 * zclk->fixed_div); } -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cpg_z_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int min_mult, max_mult, mult; unsigned long prate; - unsigned int mult; - prate = *parent_rate / zclk->fixed_div; - mult = div64_ul(rate * 32ULL, prate); - mult = clamp(mult, 1U, 32U); + prate = req->best_parent_rate / zclk->fixed_div; + min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL); + max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL); + if (max_mult < min_mult) + return -EINVAL; - return div_u64((u64)prate * mult, 32); + mult = div64_ul(req->rate * 32ULL, prate); + mult = clamp(mult, min_mult, max_mult); + + req->rate = div_u64((u64)prate * mult, 32); + return 0; } static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -172,7 +178,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops cpg_z_clk_ops = { .recalc_rate = cpg_z_clk_recalc_rate, - .round_rate = cpg_z_clk_round_rate, + .determine_rate = cpg_z_clk_determine_rate, .set_rate = cpg_z_clk_set_rate, }; From 362c79f75c9ff129935d30279812a0d9c63eb76b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 30 Aug 2019 15:45:15 +0200 Subject: [PATCH 052/160] clk: renesas: rcar-gen3: Switch SD clocks to .determine_rate() As the .round_rate() callback returns a long clock rate, it cannot return clock rates that do not fit in signed long, but do fit in unsigned long. Hence switch the SD clocks on R-Car Gen3 from the old .round_rate() callback to the newer .determine_rate() callback, which does not suffer from this limitation. This includes implementing range checking. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20190830134515.11925-9-geert+renesas@glider.be --- drivers/clk/renesas/rcar-gen3-cpg.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 4c2821afd365..c97b647db9b6 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -315,8 +315,8 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, clock->div_table[clock->cur_div_idx].div); } -static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cpg_sd_clock_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { unsigned long best_rate = ULONG_MAX, diff_min = ULONG_MAX; struct sd_clock *clock = to_sd_clock(hw); @@ -324,19 +324,24 @@ static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, unsigned int i; for (i = 0; i < clock->div_num; i++) { - calc_rate = DIV_ROUND_CLOSEST(*parent_rate, + calc_rate = DIV_ROUND_CLOSEST(req->best_parent_rate, clock->div_table[i].div); - diff = calc_rate > rate ? calc_rate - rate : rate - calc_rate; + if (calc_rate < req->min_rate || calc_rate > req->max_rate) + continue; + + diff = calc_rate > req->rate ? calc_rate - req->rate + : req->rate - calc_rate; if (diff < diff_min) { best_rate = calc_rate; diff_min = diff; } } - if (best_rate > LONG_MAX) + if (best_rate == ULONG_MAX) return -EINVAL; - return best_rate; + req->rate = best_rate; + return 0; } static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, @@ -367,7 +372,7 @@ static const struct clk_ops cpg_sd_clock_ops = { .disable = cpg_sd_clock_disable, .is_enabled = cpg_sd_clock_is_enabled, .recalc_rate = cpg_sd_clock_recalc_rate, - .round_rate = cpg_sd_clock_round_rate, + .determine_rate = cpg_sd_clock_determine_rate, .set_rate = cpg_sd_clock_set_rate, }; From b04383b6a5588906ffd059a6a9f5344a9c6df58a Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Wed, 16 Oct 2019 11:57:37 +0000 Subject: [PATCH 053/160] clk: imx8mq: Define gates for pll1/2 fixed dividers On imx8mq there are 9 fixed-factor dividers for SYS_PLL1 and SYS_PLL2 each with their own gate but these gates are not currently defined in the clock tree. Add them between sys1/2_pll_out and the fixed dividers. Signed-off-by: Leonard Crestez Reviewed-by: Abel Vesa Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mq.c | 59 ++++++++++++++++-------- include/dt-bindings/clock/imx8mq-clock.h | 22 ++++++++- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 05ece7b5da54..43af92525efb 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -350,26 +350,47 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL); clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); - /* SYS PLL fixed output */ - clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); - clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); - clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8); - clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6); - clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5); - clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4); - clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3); - clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2); - clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1); + /* SYS PLL1 fixed output */ + clks[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9); + clks[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11); + clks[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13); + clks[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15); + clks[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17); + clks[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19); + clks[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21); + clks[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23); + clks[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25); - clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20); - clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10); - clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8); - clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6); - clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5); - clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4); - clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3); - clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2); - clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1); + clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20); + clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10); + clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8); + clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6); + clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5); + clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4); + clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3); + clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2); + clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1); + + /* SYS PLL2 fixed output */ + clks[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9); + clks[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11); + clks[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13); + clks[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15); + clks[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17); + clks[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19); + clks[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21); + clks[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23); + clks[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25); + + clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20); + clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10); + clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8); + clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6); + clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5); + clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4); + clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3); + clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2); + clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1); np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h index 35b9ed9d62d8..3bab9b21c8d7 100644 --- a/include/dt-bindings/clock/imx8mq-clock.h +++ b/include/dt-bindings/clock/imx8mq-clock.h @@ -405,5 +405,25 @@ #define IMX8MQ_VIDEO2_PLL1_REF_SEL 266 -#define IMX8MQ_CLK_END 267 +#define IMX8MQ_SYS1_PLL_40M_CG 267 +#define IMX8MQ_SYS1_PLL_80M_CG 268 +#define IMX8MQ_SYS1_PLL_100M_CG 269 +#define IMX8MQ_SYS1_PLL_133M_CG 270 +#define IMX8MQ_SYS1_PLL_160M_CG 271 +#define IMX8MQ_SYS1_PLL_200M_CG 272 +#define IMX8MQ_SYS1_PLL_266M_CG 273 +#define IMX8MQ_SYS1_PLL_400M_CG 274 +#define IMX8MQ_SYS1_PLL_800M_CG 275 +#define IMX8MQ_SYS2_PLL_50M_CG 276 +#define IMX8MQ_SYS2_PLL_100M_CG 277 +#define IMX8MQ_SYS2_PLL_125M_CG 278 +#define IMX8MQ_SYS2_PLL_166M_CG 279 +#define IMX8MQ_SYS2_PLL_200M_CG 280 +#define IMX8MQ_SYS2_PLL_250M_CG 281 +#define IMX8MQ_SYS2_PLL_333M_CG 282 +#define IMX8MQ_SYS2_PLL_500M_CG 283 +#define IMX8MQ_SYS2_PLL_1000M_CG 284 + +#define IMX8MQ_CLK_END 285 + #endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */ From 3e4947acad32e6abf1ef3259a42fb4d690e4819a Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Wed, 16 Oct 2019 11:57:39 +0000 Subject: [PATCH 054/160] clk: imx8mm: Define gates for pll1/2 fixed dividers On imx8mm there are 9 fixed-factor dividers for SYS_PLL1 and SYS_PLL2 each with their own gate. Only one of these gates (the one "dividing" by one) is currently defined and it's incorrectly set as the parent of all the fixed-factor dividers. Add the other 8 gates to the clock tree between sys_pll1/2_bypass and the fixed dividers. Signed-off-by: Leonard Crestez Reviewed-by: Abel Vesa Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mm.c | 57 ++++++++++++++++-------- include/dt-bindings/clock/imx8mm-clock.h | 19 +++++++- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 04876ec66127..bbd212eb904e 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -360,29 +360,48 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); - clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); - clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); - /* SYS PLL fixed output */ - clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); - clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); - clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); - clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); - clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); - clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); - clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); - clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); + /* SYS PLL1 fixed output */ + clks[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1_bypass", base + 0x94, 27); + clks[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1_bypass", base + 0x94, 25); + clks[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1_bypass", base + 0x94, 23); + clks[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1_bypass", base + 0x94, 21); + clks[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1_bypass", base + 0x94, 19); + clks[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1_bypass", base + 0x94, 17); + clks[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1_bypass", base + 0x94, 15); + clks[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1_bypass", base + 0x94, 13); + clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); + + clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); + clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); + clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); + clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); + clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); + clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); + clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); + clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); - clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); - clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); - clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); - clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); - clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); - clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); - clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); - clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); + /* SYS PLL2 fixed output */ + clks[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2_bypass", base + 0x104, 27); + clks[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2_bypass", base + 0x104, 25); + clks[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2_bypass", base + 0x104, 23); + clks[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2_bypass", base + 0x104, 21); + clks[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2_bypass", base + 0x104, 19); + clks[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2_bypass", base + 0x104, 17); + clks[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2_bypass", base + 0x104, 15); + clks[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2_bypass", base + 0x104, 13); + clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); + + clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); + clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); + clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); + clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); + clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); + clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); + clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); + clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); np = dev->of_node; diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h index 07e6c686f3ef..edeece2289f0 100644 --- a/include/dt-bindings/clock/imx8mm-clock.h +++ b/include/dt-bindings/clock/imx8mm-clock.h @@ -248,6 +248,23 @@ #define IMX8MM_CLK_SNVS_ROOT 228 #define IMX8MM_CLK_GIC 229 -#define IMX8MM_CLK_END 230 +#define IMX8MM_SYS_PLL1_40M_CG 230 +#define IMX8MM_SYS_PLL1_80M_CG 231 +#define IMX8MM_SYS_PLL1_100M_CG 232 +#define IMX8MM_SYS_PLL1_133M_CG 233 +#define IMX8MM_SYS_PLL1_160M_CG 234 +#define IMX8MM_SYS_PLL1_200M_CG 235 +#define IMX8MM_SYS_PLL1_266M_CG 236 +#define IMX8MM_SYS_PLL1_400M_CG 237 +#define IMX8MM_SYS_PLL2_50M_CG 238 +#define IMX8MM_SYS_PLL2_100M_CG 239 +#define IMX8MM_SYS_PLL2_125M_CG 240 +#define IMX8MM_SYS_PLL2_166M_CG 241 +#define IMX8MM_SYS_PLL2_200M_CG 242 +#define IMX8MM_SYS_PLL2_250M_CG 243 +#define IMX8MM_SYS_PLL2_333M_CG 244 +#define IMX8MM_SYS_PLL2_500M_CG 245 + +#define IMX8MM_CLK_END 246 #endif From e8688fe8df7d01f43586b4bb74b2fa92f56c5ee8 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Wed, 16 Oct 2019 11:57:40 +0000 Subject: [PATCH 055/160] clk: imx8mn: Define gates for pll1/2 fixed dividers On imx8mn there are 9 fixed-factor dividers for SYS_PLL1 and SYS_PLL2 each with their own gate. Only one of these gates (the one "dividing" by one) is currently defined and it's incorrectly set as the parent of all the fixed-factor dividers. Add the other 8 gates to the clock tree between sys_pll1/2_bypass and the fixed dividers. Signed-off-by: Leonard Crestez Reviewed-by: Abel Vesa Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mn.c | 57 ++++++++++++++++-------- include/dt-bindings/clock/imx8mn-clock.h | 19 +++++++- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 7a5590b967d5..edc9c35669e6 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -371,29 +371,48 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) clks[IMX8MN_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11); clks[IMX8MN_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11); clks[IMX8MN_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11); - clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); - clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); - /* SYS PLL fixed output */ - clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); - clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); - clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); - clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); - clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); - clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); - clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); - clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); + /* SYS PLL1 fixed output */ + clks[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1_bypass", base + 0x94, 27); + clks[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1_bypass", base + 0x94, 25); + clks[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1_bypass", base + 0x94, 23); + clks[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1_bypass", base + 0x94, 21); + clks[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1_bypass", base + 0x94, 19); + clks[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1_bypass", base + 0x94, 17); + clks[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1_bypass", base + 0x94, 15); + clks[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1_bypass", base + 0x94, 13); + clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); + + clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); + clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); + clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8); + clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6); + clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5); + clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4); + clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3); + clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2); clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); - clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); - clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); - clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); - clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); - clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); - clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); - clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); - clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); + /* SYS PLL2 fixed output */ + clks[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2_bypass", base + 0x104, 27); + clks[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2_bypass", base + 0x104, 25); + clks[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2_bypass", base + 0x104, 23); + clks[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2_bypass", base + 0x104, 21); + clks[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2_bypass", base + 0x104, 19); + clks[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2_bypass", base + 0x104, 17); + clks[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2_bypass", base + 0x104, 15); + clks[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2_bypass", base + 0x104, 13); + clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); + + clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); + clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); + clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8); + clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6); + clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5); + clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4); + clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3); + clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); clks[IMX8MN_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); np = dev->of_node; diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h index d7b201652f4c..0f2b8423ce1d 100644 --- a/include/dt-bindings/clock/imx8mn-clock.h +++ b/include/dt-bindings/clock/imx8mn-clock.h @@ -211,6 +211,23 @@ #define IMX8MN_CLK_GPU_CORE_ROOT 193 #define IMX8MN_CLK_GIC 194 -#define IMX8MN_CLK_END 195 +#define IMX8MN_SYS_PLL1_40M_CG 195 +#define IMX8MN_SYS_PLL1_80M_CG 196 +#define IMX8MN_SYS_PLL1_100M_CG 197 +#define IMX8MN_SYS_PLL1_133M_CG 198 +#define IMX8MN_SYS_PLL1_160M_CG 199 +#define IMX8MN_SYS_PLL1_200M_CG 200 +#define IMX8MN_SYS_PLL1_266M_CG 201 +#define IMX8MN_SYS_PLL1_400M_CG 202 +#define IMX8MN_SYS_PLL2_50M_CG 203 +#define IMX8MN_SYS_PLL2_100M_CG 204 +#define IMX8MN_SYS_PLL2_125M_CG 205 +#define IMX8MN_SYS_PLL2_166M_CG 206 +#define IMX8MN_SYS_PLL2_200M_CG 207 +#define IMX8MN_SYS_PLL2_250M_CG 208 +#define IMX8MN_SYS_PLL2_333M_CG 209 +#define IMX8MN_SYS_PLL2_500M_CG 210 + +#define IMX8MN_CLK_END 211 #endif From c332481f62fa2f29af234bf85846268a5a0b173e Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 24 Oct 2019 01:58:37 +0000 Subject: [PATCH 056/160] clk: imx: imx8mm: mark sys_pll1/2 as fixed clock According Architecture definition guide, SYS_PLL1 is fixed at 800MHz, SYS_PLL2 is fixed at 1000MHz, so let's use imx_clk_fixed to register the clocks and drop code that could change the rate. Reviewed-by: Abel Vesa Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mm.c | 46 ++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index bbd212eb904e..ef307145e5d3 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -34,8 +34,6 @@ static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; -static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", }; -static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; /* CCM ROOT */ @@ -325,8 +323,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); @@ -336,8 +332,8 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); - clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx_1416x_pll); - clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx_1416x_pll); + clks[IMX8MM_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000); + clks[IMX8MM_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000); clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); /* PLL bypass out */ @@ -348,8 +344,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT); clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); /* PLL out gate */ @@ -363,15 +357,15 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); /* SYS PLL1 fixed output */ - clks[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1_bypass", base + 0x94, 27); - clks[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1_bypass", base + 0x94, 25); - clks[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1_bypass", base + 0x94, 23); - clks[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1_bypass", base + 0x94, 21); - clks[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1_bypass", base + 0x94, 19); - clks[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1_bypass", base + 0x94, 17); - clks[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1_bypass", base + 0x94, 15); - clks[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1_bypass", base + 0x94, 13); - clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); + clks[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); + clks[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); + clks[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); + clks[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); + clks[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); + clks[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); + clks[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); + clks[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); + clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); @@ -384,15 +378,15 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); /* SYS PLL2 fixed output */ - clks[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2_bypass", base + 0x104, 27); - clks[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2_bypass", base + 0x104, 25); - clks[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2_bypass", base + 0x104, 23); - clks[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2_bypass", base + 0x104, 21); - clks[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2_bypass", base + 0x104, 19); - clks[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2_bypass", base + 0x104, 17); - clks[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2_bypass", base + 0x104, 15); - clks[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2_bypass", base + 0x104, 13); - clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); + clks[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); + clks[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); + clks[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); + clks[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); + clks[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); + clks[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); + clks[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); + clks[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); + clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); From 3f44344868cfcd76b2ca0fe334a76a17a120cdd9 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 24 Oct 2019 01:58:42 +0000 Subject: [PATCH 057/160] clk: imx: imx8mn: mark sys_pll1/2 as fixed clock According Architecture definition guide, SYS_PLL1 is fixed at 800MHz, SYS_PLL2 is fixed at 1000MHz, so let's use imx_clk_fixed to register the clocks and drop code that could change the rate. Reviewed-by: Abel Vesa Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mn.c | 46 ++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index edc9c35669e6..def10a4da603 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -47,8 +47,6 @@ static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_se static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; -static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", }; -static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", @@ -336,8 +334,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) clks[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MN_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); @@ -347,8 +343,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); - clks[IMX8MN_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx_1416x_pll); - clks[IMX8MN_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx_1416x_pll); + clks[IMX8MN_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000); + clks[IMX8MN_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000); clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); /* PLL bypass out */ @@ -359,8 +355,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) clks[IMX8MN_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); clks[IMX8MN_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); clks[IMX8MN_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 28, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX8MN_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 28, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT); clks[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); /* PLL out gate */ @@ -374,15 +368,15 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11); /* SYS PLL1 fixed output */ - clks[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1_bypass", base + 0x94, 27); - clks[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1_bypass", base + 0x94, 25); - clks[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1_bypass", base + 0x94, 23); - clks[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1_bypass", base + 0x94, 21); - clks[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1_bypass", base + 0x94, 19); - clks[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1_bypass", base + 0x94, 17); - clks[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1_bypass", base + 0x94, 15); - clks[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1_bypass", base + 0x94, 13); - clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 11); + clks[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27); + clks[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25); + clks[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23); + clks[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21); + clks[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19); + clks[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17); + clks[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15); + clks[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13); + clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20); clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10); @@ -395,15 +389,15 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); /* SYS PLL2 fixed output */ - clks[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2_bypass", base + 0x104, 27); - clks[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2_bypass", base + 0x104, 25); - clks[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2_bypass", base + 0x104, 23); - clks[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2_bypass", base + 0x104, 21); - clks[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2_bypass", base + 0x104, 19); - clks[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2_bypass", base + 0x104, 17); - clks[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2_bypass", base + 0x104, 15); - clks[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2_bypass", base + 0x104, 13); - clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 11); + clks[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27); + clks[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25); + clks[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23); + clks[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21); + clks[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19); + clks[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17); + clks[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15); + clks[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13); + clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20); clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10); From 7858d31beffe178b0e775f13af1917ac60273112 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 24 Oct 2019 01:58:47 +0000 Subject: [PATCH 058/160] clk: imx: imx8mq: mark sys1/2_pll as fixed clock According Architecture definition guide, SYS1_PLL is fixed at 800MHz, SYS2_PLL is fixed at 1000MHz, so let's use imx_clk_fixed to register the clocks and drop code that could change the rate. Reviewed-by: Abel Vesa Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mq.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 43af92525efb..4a5dbc4366a5 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -34,8 +34,6 @@ static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; -static const char * const sys1_pll_out_sels[] = {"sys1_pll1_ref_sel", }; -static const char * const sys2_pll_out_sels[] = {"sys1_pll1_ref_sel", "sys2_pll1_ref_sel", }; static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", }; static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", }; static const char * const video2_pll_out_sels[] = {"video2_pll1_ref_sel", }; @@ -308,8 +306,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) clks[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_SYS1_PLL1_REF_SEL] = imx_clk_mux("sys1_pll1_ref_sel", base + 0x30, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MQ_SYS2_PLL1_REF_SEL] = imx_clk_mux("sys2_pll1_ref_sel", base + 0x3c, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); @@ -344,8 +340,8 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21); clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21); - clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_sccg_pll("sys1_pll_out", sys1_pll_out_sels, ARRAY_SIZE(sys1_pll_out_sels), 0, 0, 0, base + 0x30, CLK_IS_CRITICAL); - clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_sccg_pll("sys2_pll_out", sys2_pll_out_sels, ARRAY_SIZE(sys2_pll_out_sels), 0, 0, 1, base + 0x3c, CLK_IS_CRITICAL); + clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_fixed("sys1_pll_out", 800000000); + clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_fixed("sys2_pll_out", 1000000000); clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL); clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL); clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); From 96ac93a7c4bea4eb4186425795c00937d2dd6085 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Mon, 14 Oct 2019 08:56:05 +0800 Subject: [PATCH 059/160] clk: imx7ulp: Correct system clock source option #7 In the latest reference manual Rev.0,06/2019, the SCS's option #7 is no longer from upll, it is reserved, update clock driver accordingly. Fixes: b1260067ac3d ("clk: imx: add imx7ulp clk driver") Signed-off-by: Anson Huang Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx7ulp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index 2022d9bead91..b2c58661168e 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -24,7 +24,7 @@ static const char * const spll_pfd_sels[] = { "spll_pfd0", "spll_pfd1", "spll_pf static const char * const spll_sels[] = { "spll", "spll_pfd_sel", }; static const char * const apll_pfd_sels[] = { "apll_pfd0", "apll_pfd1", "apll_pfd2", "apll_pfd3", }; static const char * const apll_sels[] = { "apll", "apll_pfd_sel", }; -static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "upll", }; +static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "dummy", }; static const char * const ddr_sels[] = { "apll_pfd_sel", "upll", }; static const char * const nic_sels[] = { "firc", "ddr_clk", }; static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", }; From 2e2b928a04bd74ea410da72bd60e1c5b06398276 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 11 Oct 2019 17:09:00 +0800 Subject: [PATCH 060/160] clk: imx7ulp: Correct DDR clock mux options In the latest reference manual Rev.0,06/2019, the DDR clock mux is extended to 2 bits, and the clock options are also changed, correct them accordingly. Fixes: b1260067ac3d ("clk: imx: add imx7ulp clk driver") Signed-off-by: Anson Huang Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx7ulp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index b2c58661168e..c4b78a2d12b1 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -25,7 +25,7 @@ static const char * const spll_sels[] = { "spll", "spll_pfd_sel", }; static const char * const apll_pfd_sels[] = { "apll_pfd0", "apll_pfd1", "apll_pfd2", "apll_pfd3", }; static const char * const apll_sels[] = { "apll", "apll_pfd_sel", }; static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "dummy", }; -static const char * const ddr_sels[] = { "apll_pfd_sel", "upll", }; +static const char * const ddr_sels[] = { "apll_pfd_sel", "dummy", "dummy", "dummy", }; static const char * const nic_sels[] = { "firc", "ddr_clk", }; static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", }; static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "mpll", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", }; @@ -118,7 +118,7 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) clks[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); clks[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); clks[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels)); - clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 1, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); + clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); clks[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT); clks[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT); From fc09a36a8798c6eec60fe4f78f6797c3d026a3c5 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 24 Oct 2019 02:38:22 +0000 Subject: [PATCH 061/160] clk: imx: imx7d: use imx_obtain_fixed_clk_hw to simplify code imx_obtain_fixed_clk_hw could be used to simplify code to replace __clk_get_hw(of_clk_get_by_name(node, "name")) Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx7d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index fbea774ef687..0c9f7adb41ae 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -403,8 +403,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) hws = clk_hw_data->hws; hws[IMX7D_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX7D_OSC_24M_CLK] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); - hws[IMX7D_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); + hws[IMX7D_OSC_24M_CLK] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); + hws[IMX7D_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); base = of_iomap(np, 0); From 184f9eb6c9a09bb4b348a046c5ceedd47a385065 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 24 Oct 2019 02:59:32 +0000 Subject: [PATCH 062/160] clk: imx: imx6sll: use imx_obtain_fixed_clk_hw to simplify code imx_obtain_fixed_clk_hw could be used to simplify code to replace __clk_get_hw(of_clk_get_by_name(node, "name")) Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6sll.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c index 5f3e92c09a5e..8e8288bda4d0 100644 --- a/drivers/clk/imx/clk-imx6sll.c +++ b/drivers/clk/imx/clk-imx6sll.c @@ -107,12 +107,12 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) hws[IMX6SLL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX6SLL_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); - hws[IMX6SLL_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); + hws[IMX6SLL_CLK_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); + hws[IMX6SLL_CLK_OSC] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); /* ipp_di clock is external input */ - hws[IMX6SLL_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); - hws[IMX6SLL_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); + hws[IMX6SLL_CLK_IPP_DI0] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di0"); + hws[IMX6SLL_CLK_IPP_DI1] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di1"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop"); base = of_iomap(np, 0); From 8e1de35d4cebeabcd7a8619f0af34cf2444dc34b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 24 Oct 2019 02:59:37 +0000 Subject: [PATCH 063/160] clk: imx: imx6sx: use imx_obtain_fixed_clk_hw to simplify code imx_obtain_fixed_clk_hw could be used to simplify code to replace __clk_get_hw(of_clk_get_by_name(node, "name")) Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6sx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index c4685c01929a..89ba71271e5c 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -139,16 +139,16 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) hws[IMX6SX_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX6SX_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); - hws[IMX6SX_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); + hws[IMX6SX_CLK_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); + hws[IMX6SX_CLK_OSC] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); /* ipp_di clock is external input */ - hws[IMX6SX_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); - hws[IMX6SX_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); + hws[IMX6SX_CLK_IPP_DI0] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di0"); + hws[IMX6SX_CLK_IPP_DI1] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di1"); /* Clock source from external clock via CLK1/2 PAD */ - hws[IMX6SX_CLK_ANACLK1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "anaclk1")); - hws[IMX6SX_CLK_ANACLK2] = __clk_get_hw(of_clk_get_by_name(ccm_node, "anaclk2")); + hws[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clk_hw(ccm_node, "anaclk1"); + hws[IMX6SX_CLK_ANACLK2] = imx_obtain_fixed_clk_hw(ccm_node, "anaclk2"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); base = of_iomap(np, 0); From 8f5d481959a04ad81cc928c698ebe6a9dae23971 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 24 Oct 2019 02:59:42 +0000 Subject: [PATCH 064/160] clk: imx: imx6ul: use imx_obtain_fixed_clk_hw to simplify code imx_obtain_fixed_clk_hw could be used to simplify code to replace __clk_get_hw(of_clk_get_by_name(node, "name")) Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx6ul.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index bc931988fe7b..dafc8806b03e 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -126,12 +126,12 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6UL_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0); - hws[IMX6UL_CLK_CKIL] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ckil")); - hws[IMX6UL_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(ccm_node, "osc")); + hws[IMX6UL_CLK_CKIL] = imx_obtain_fixed_clk_hw(ccm_node, "ckil"); + hws[IMX6UL_CLK_OSC] = imx_obtain_fixed_clk_hw(ccm_node, "osc"); /* ipp_di clock is external input */ - hws[IMX6UL_CLK_IPP_DI0] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di0")); - hws[IMX6UL_CLK_IPP_DI1] = __clk_get_hw(of_clk_get_by_name(ccm_node, "ipp_di1")); + hws[IMX6UL_CLK_IPP_DI0] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di0"); + hws[IMX6UL_CLK_IPP_DI1] = imx_obtain_fixed_clk_hw(ccm_node, "ipp_di1"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-anatop"); base = of_iomap(np, 0); From 72b2429d40d878bfdd066b9401c9a5cbb2a755d3 Mon Sep 17 00:00:00 2001 From: Fancy Fang Date: Mon, 28 Oct 2019 08:07:59 +0000 Subject: [PATCH 065/160] clk: imx7ulp: do not export out IMX7ULP_CLK_MIPI_PLL clock The mipi pll clock comes from the MIPI PHY PLL output, so it should not be a fixed clock. MIPI PHY PLL is in the MIPI DSI space, and it is used as the bit clock for transferring the pixel data out and its output clock is configured according to the display mode. So it should be used only for MIPI DSI and not be exported out for other usages. Signed-off-by: Fancy Fang Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/clock/imx7ulp-clock.txt | 1 - drivers/clk/imx/clk-imx7ulp.c | 3 +-- include/dt-bindings/clock/imx7ulp-clock.h | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/imx7ulp-clock.txt b/Documentation/devicetree/bindings/clock/imx7ulp-clock.txt index a4f8cd478f92..93d89adb7afe 100644 --- a/Documentation/devicetree/bindings/clock/imx7ulp-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx7ulp-clock.txt @@ -82,7 +82,6 @@ pcc2: pcc2@403f0000 { <&scg1 IMX7ULP_CLK_APLL_PFD0>, <&scg1 IMX7ULP_CLK_UPLL>, <&scg1 IMX7ULP_CLK_SOSC_BUS_CLK>, - <&scg1 IMX7ULP_CLK_MIPI_PLL>, <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>, <&scg1 IMX7ULP_CLK_ROSC>, <&scg1 IMX7ULP_CLK_SPLL_BUS_CLK>; diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index c4b78a2d12b1..3fdf3d494f0a 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -28,7 +28,7 @@ static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dumm static const char * const ddr_sels[] = { "apll_pfd_sel", "dummy", "dummy", "dummy", }; static const char * const nic_sels[] = { "firc", "ddr_clk", }; static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", }; -static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "mpll", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", }; +static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "dummy", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", }; static const char * const arm_sels[] = { "divcore", "dummy", "dummy", "hsrun_divcore", }; /* used by sosc/sirc/firc/ddr/spll/apll dividers */ @@ -75,7 +75,6 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) clks[IMX7ULP_CLK_SOSC] = imx_obtain_fixed_clk_hw(np, "sosc"); clks[IMX7ULP_CLK_SIRC] = imx_obtain_fixed_clk_hw(np, "sirc"); clks[IMX7ULP_CLK_FIRC] = imx_obtain_fixed_clk_hw(np, "firc"); - clks[IMX7ULP_CLK_MIPI_PLL] = imx_obtain_fixed_clk_hw(np, "mpll"); clks[IMX7ULP_CLK_UPLL] = imx_obtain_fixed_clk_hw(np, "upll"); /* SCG1 */ diff --git a/include/dt-bindings/clock/imx7ulp-clock.h b/include/dt-bindings/clock/imx7ulp-clock.h index 6f66f9005c81..38145bdcd975 100644 --- a/include/dt-bindings/clock/imx7ulp-clock.h +++ b/include/dt-bindings/clock/imx7ulp-clock.h @@ -49,6 +49,7 @@ #define IMX7ULP_CLK_NIC1_DIV 36 #define IMX7ULP_CLK_NIC1_BUS_DIV 37 #define IMX7ULP_CLK_NIC1_EXT_DIV 38 +/* IMX7ULP_CLK_MIPI_PLL is unsupported and shouldn't be used in DT */ #define IMX7ULP_CLK_MIPI_PLL 39 #define IMX7ULP_CLK_SIRC 40 #define IMX7ULP_CLK_SOSC_BUS_CLK 41 From f1edb498bd9f25936ae3540a8dbd86e6019fdb95 Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 1 Oct 2019 18:25:46 +0000 Subject: [PATCH 066/160] clk: hi6220: use CLK_OF_DECLARE_DRIVER As now we also need to probe in the reset driver as well. Cc: Michael Turquette Cc: Stephen Boyd Cc: Allison Randal Cc: Peter Griffin Cc: linux-clk@vger.kernel.org Signed-off-by: Peter Griffin Signed-off-by: John Stultz Link: https://lkml.kernel.org/r/20191001182546.70090-1-john.stultz@linaro.org [sboyd@kernel.org: Add comment about reset driver] Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/clk-hi6220.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c index b2c5b6bbb1c1..e7cdf72d4b06 100644 --- a/drivers/clk/hisilicon/clk-hi6220.c +++ b/drivers/clk/hisilicon/clk-hi6220.c @@ -86,7 +86,8 @@ static void __init hi6220_clk_ao_init(struct device_node *np) hisi_clk_register_gate_sep(hi6220_separated_gate_clks_ao, ARRAY_SIZE(hi6220_separated_gate_clks_ao), clk_data_ao); } -CLK_OF_DECLARE(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init); +/* Allow reset driver to probe as well */ +CLK_OF_DECLARE_DRIVER(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init); /* clocks in sysctrl */ From b92981de92cbbb93c80bbe800d6c3b32f0911641 Mon Sep 17 00:00:00 2001 From: Marian Mihailescu Date: Tue, 29 Oct 2019 11:17:58 +1030 Subject: [PATCH 067/160] clk: samsung: exynos5420: Add VPLL rate table Add new table rate for VPLL for Exynos 542x SoC required to support Mali GPU clock frequencies. Signed-off-by: Marian Mihailescu Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5420.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 31466cd1842f..bbd7baab0899 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -1437,6 +1437,17 @@ static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = { PLL_36XX_RATE(24 * MHZ, 32768001U, 131, 3, 5, 4719), }; +static const struct samsung_pll_rate_table exynos5420_vpll_24mhz_tbl[] = { + PLL_35XX_RATE(24 * MHZ, 600000000U, 200, 2, 2), + PLL_35XX_RATE(24 * MHZ, 543000000U, 181, 2, 2), + PLL_35XX_RATE(24 * MHZ, 480000000U, 160, 2, 2), + PLL_35XX_RATE(24 * MHZ, 420000000U, 140, 2, 2), + PLL_35XX_RATE(24 * MHZ, 350000000U, 175, 3, 2), + PLL_35XX_RATE(24 * MHZ, 266000000U, 266, 3, 3), + PLL_35XX_RATE(24 * MHZ, 177000000U, 118, 2, 3), + PLL_35XX_RATE(24 * MHZ, 100000000U, 200, 3, 4), +}; + static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, APLL_CON0, NULL), @@ -1561,6 +1572,7 @@ static void __init exynos5x_clk_init(struct device_node *np, exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; + exynos5x_plls[vpll].rate_table = exynos5420_vpll_24mhz_tbl; } if (soc == EXYNOS5420) From e21be0d1d7bd7f78a77613f6bcb6965e72b22fc1 Mon Sep 17 00:00:00 2001 From: Marian Mihailescu Date: Tue, 29 Oct 2019 11:20:25 +1030 Subject: [PATCH 068/160] clk: samsung: exynos5420: Preserve CPU clocks configuration during suspend/resume Save and restore top PLL related configuration registers for big (APLL) and LITTLE (KPLL) cores during suspend/resume cycle. So far, CPU clocks were reset to default values after suspend/resume cycle and performance after system resume was affected when performance governor has been selected. Fixes: 773424326b51 ("clk: samsung: exynos5420: add more registers to restore list") Signed-off-by: Marian Mihailescu Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5420.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index bbd7baab0899..53bbd656a3f6 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -165,6 +165,8 @@ static const unsigned long exynos5x_clk_regs[] __initconst = { GATE_BUS_CPU, GATE_SCLK_CPU, CLKOUT_CMU_CPU, + APLL_CON0, + KPLL_CON0, CPLL_CON0, DPLL_CON0, EPLL_CON0, From 45f10dabb56bc5dee52df47dccd3bfab1e58eea1 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 25 Oct 2019 11:34:35 +0200 Subject: [PATCH 069/160] clk: samsung: exynos5420: Add SET_RATE_PARENT flag to clocks on G3D path Add CLK_SET_RATE_PARENT flag to all clocks on the path from VPLL to G3D, so the G3D MALI driver can simply adjust the rate of its clock by doing a single clk_set_rate() call, without the need to know the whole clock topology in Exynos542x SoCs. Suggested-by: Marian Mihailescu Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5420.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 53bbd656a3f6..3a991ca1ee36 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -613,7 +613,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { MUX(0, "mout_aclk66", mout_group1_p, SRC_TOP1, 8, 2), MUX(0, "mout_aclk166", mout_group1_p, SRC_TOP1, 24, 2), - MUX(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1), + MUX_F(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1, + CLK_SET_RATE_PARENT, 0), MUX(0, "mout_user_aclk400_isp", mout_user_aclk400_isp_p, SRC_TOP3, 0, 1), @@ -655,8 +656,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { SRC_TOP5, 8, 1), MUX(0, "mout_user_aclk266_g2d", mout_user_aclk266_g2d_p, SRC_TOP5, 12, 1), - MUX(CLK_MOUT_G3D, "mout_user_aclk_g3d", mout_user_aclk_g3d_p, - SRC_TOP5, 16, 1), + MUX_F(CLK_MOUT_G3D, "mout_user_aclk_g3d", mout_user_aclk_g3d_p, + SRC_TOP5, 16, 1, CLK_SET_RATE_PARENT, 0), MUX(0, "mout_user_aclk300_jpeg", mout_user_aclk300_jpeg_p, SRC_TOP5, 20, 1), MUX(CLK_MOUT_USER_ACLK300_DISP1, "mout_user_aclk300_disp1", @@ -665,7 +666,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { mout_user_aclk300_gscl_p, SRC_TOP5, 28, 1), MUX(0, "mout_sclk_mpll", mout_mpll_p, SRC_TOP6, 0, 1), - MUX(CLK_MOUT_VPLL, "mout_sclk_vpll", mout_vpll_p, SRC_TOP6, 4, 1), + MUX_F(CLK_MOUT_VPLL, "mout_sclk_vpll", mout_vpll_p, SRC_TOP6, 4, 1, + CLK_SET_RATE_PARENT, 0), MUX(CLK_MOUT_SCLK_SPLL, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), @@ -709,7 +711,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { SRC_TOP12, 8, 1), MUX(0, "mout_sw_aclk266_g2d", mout_sw_aclk266_g2d_p, SRC_TOP12, 12, 1), - MUX(0, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p, SRC_TOP12, 16, 1), + MUX_F(0, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p, SRC_TOP12, 16, 1, + CLK_SET_RATE_PARENT, 0), MUX(0, "mout_sw_aclk300_jpeg", mout_sw_aclk300_jpeg_p, SRC_TOP12, 20, 1), MUX(CLK_MOUT_SW_ACLK300, "mout_sw_aclk300_disp1", @@ -806,8 +809,8 @@ static const struct samsung_div_clock exynos5x_div_clks[] __initconst = { DIV_TOP2, 8, 3), DIV(CLK_DOUT_ACLK266_G2D, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), - DIV(CLK_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, - 16, 3), + DIV_F(CLK_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, + 16, 3, CLK_SET_RATE_PARENT, 0), DIV(CLK_DOUT_ACLK300_JPEG, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), DIV(CLK_DOUT_ACLK300_DISP1, "dout_aclk300_disp1", @@ -1255,7 +1258,8 @@ static struct exynos5_subcmu_reg_dump exynos5x_gsc_suspend_regs[] = { }; static const struct samsung_gate_clock exynos5x_g3d_gate_clks[] __initconst = { - GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), + GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, + CLK_SET_RATE_PARENT, 0), }; static struct exynos5_subcmu_reg_dump exynos5x_g3d_suspend_regs[] = { From cdc2d6685c13cc736b4c1c70b184638897c5c46f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 29 Oct 2019 20:14:44 +0100 Subject: [PATCH 070/160] dt-bindings: clock: tegra: Rename SOR0_LVDS to SOR0_OUT Tegra186 and later call this clock SOR0_OUT. Rename it on Tegra124 and Tegra210 to make the names consistent. Keep the old name for now to keep device trees buildable until they have all been converted. Signed-off-by: Thierry Reding --- include/dt-bindings/clock/tegra124-car-common.h | 3 ++- include/dt-bindings/clock/tegra210-car.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/dt-bindings/clock/tegra124-car-common.h b/include/dt-bindings/clock/tegra124-car-common.h index 4331f1df6ebe..0c4f5be0a742 100644 --- a/include/dt-bindings/clock/tegra124-car-common.h +++ b/include/dt-bindings/clock/tegra124-car-common.h @@ -337,7 +337,8 @@ #define TEGRA124_CLK_CLK_OUT_3_MUX 308 /* 309 */ /* 310 */ -#define TEGRA124_CLK_SOR0_LVDS 311 +#define TEGRA124_CLK_SOR0_LVDS 311 /* deprecated */ +#define TEGRA124_CLK_SOR0_OUT 311 #define TEGRA124_CLK_XUSB_SS_DIV2 312 #define TEGRA124_CLK_PLL_M_UD 313 diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h index 6b77e721f6b1..0bfbfc912c68 100644 --- a/include/dt-bindings/clock/tegra210-car.h +++ b/include/dt-bindings/clock/tegra210-car.h @@ -391,7 +391,8 @@ #define TEGRA210_CLK_CLK_OUT_3_MUX 358 #define TEGRA210_CLK_DSIA_MUX 359 #define TEGRA210_CLK_DSIB_MUX 360 -#define TEGRA210_CLK_SOR0_LVDS 361 +#define TEGRA210_CLK_SOR0_LVDS 361 /* deprecated */ +#define TEGRA210_CLK_SOR0_OUT 361 #define TEGRA210_CLK_XUSB_SS_DIV2 362 #define TEGRA210_CLK_PLL_M_UD 363 From bbbbd246ee12f5d41aeac3d1b470f7b5b735574c Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Thu, 17 Oct 2019 11:53:48 +0100 Subject: [PATCH 071/160] clk: rockchip: make clk_half_divider_ops static The clk_half_divider_ops is not used outside or declared outside of drivers/clk/rockchip/clk-half-divider.c so make it static to avoid the following warning: drivers/clk/rockchip/clk-half-divider.c:142:22: warning: symbol 'clk_half_divider_ops' was not declared. Should it be static? Signed-off-by: Ben Dooks Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20191017105348.8061-1-ben.dooks@codethink.co.uk Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-half-divider.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c index ba9f00dc9740..b333fc28c94b 100644 --- a/drivers/clk/rockchip/clk-half-divider.c +++ b/drivers/clk/rockchip/clk-half-divider.c @@ -139,12 +139,11 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -const struct clk_ops clk_half_divider_ops = { +static const struct clk_ops clk_half_divider_ops = { .recalc_rate = clk_half_divider_recalc_rate, .round_rate = clk_half_divider_round_rate, .set_rate = clk_half_divider_set_rate, }; -EXPORT_SYMBOL_GPL(clk_half_divider_ops); /** * Register a clock branch. From 581eb61a9465e1b9fc1df1a8912100702d7c2f31 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:04 +0300 Subject: [PATCH 072/160] clk: ti: clkctrl: fix setting up clkctrl clocks Apply the proper register function for clkctrl clocks, so they get registered under the clk_hw_omap list also. This allows checking their type runtime. Signed-off-by: Tero Kristo --- drivers/clk/ti/clkctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 975995eea15c..a914df2e9e1b 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -622,7 +622,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) init.ops = &omap4_clkctrl_clk_ops; hw->hw.init = &init; - clk = ti_clk_register(NULL, &hw->hw, init.name); + clk = ti_clk_register_omap_hw(NULL, &hw->hw, init.name); if (IS_ERR_OR_NULL(clk)) goto cleanup; From 22a6564f716b0746b5a05add3f9f37549f89244e Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:05 +0300 Subject: [PATCH 073/160] clk: ti: clkctrl: convert to use bit helper macros instead of bitops This improves the readibility of the code slightly, and makes modifying the flags bit simpler. Signed-off-by: Tero Kristo --- drivers/clk/ti/clkctrl.c | 8 ++++---- include/linux/clk/ti.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index a914df2e9e1b..d904a9a7626a 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -24,7 +24,7 @@ #include #include "clock.h" -#define NO_IDLEST 0x1 +#define NO_IDLEST 0 #define OMAP4_MODULEMODE_MASK 0x3 @@ -158,7 +158,7 @@ static int _omap4_clkctrl_clk_enable(struct clk_hw *hw) ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); - if (clk->flags & NO_IDLEST) + if (test_bit(NO_IDLEST, &clk->flags)) return 0; /* Wait until module is enabled */ @@ -187,7 +187,7 @@ static void _omap4_clkctrl_clk_disable(struct clk_hw *hw) ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); - if (clk->flags & NO_IDLEST) + if (test_bit(NO_IDLEST, &clk->flags)) goto exit; /* Wait until module is disabled */ @@ -596,7 +596,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) if (reg_data->flags & CLKF_HW_SUP) hw->enable_bit = MODULEMODE_HWCTRL; if (reg_data->flags & CLKF_NO_IDLEST) - hw->flags |= NO_IDLEST; + set_bit(NO_IDLEST, &hw->flags); if (reg_data->clkdm_name) hw->clkdm_name = reg_data->clkdm_name; diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 1e8ef96555ce..bb2c5af9082a 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -153,7 +153,7 @@ struct clk_hw_omap { u8 fixed_div; struct clk_omap_reg enable_reg; u8 enable_bit; - u8 flags; + unsigned long flags; struct clk_omap_reg clksel_reg; struct dpll_data *dpll_data; const char *clkdm_name; From 2209b72d41993c13de220b82c830b482925322b9 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:06 +0300 Subject: [PATCH 074/160] clk: ti: clkctrl: add new exported API for checking standby info Standby status is provided for certain clkctrl clocks to see if the given module has entered standby or not. This is mostly needed by remoteproc code to see if the remoteproc has entered standby and the clock can be turned off safely. Signed-off-by: Tero Kristo --- drivers/clk/ti/clkctrl.c | 33 +++++++++++++++++++++++++++++++++ include/linux/clk/ti.h | 1 + 2 files changed, 34 insertions(+) diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index d904a9a7626a..d6cb41b55800 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -34,6 +34,9 @@ #define OMAP4_IDLEST_MASK (0x3 << 16) #define OMAP4_IDLEST_SHIFT 16 +#define OMAP4_STBYST_MASK BIT(18) +#define OMAP4_STBYST_SHIFT 18 + #define CLKCTRL_IDLEST_FUNCTIONAL 0x0 #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 #define CLKCTRL_IDLEST_DISABLED 0x3 @@ -647,3 +650,33 @@ cleanup: } CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl", _ti_omap4_clkctrl_setup); + +/** + * ti_clk_is_in_standby - Check if clkctrl clock is in standby or not + * @clk: clock to check standby status for + * + * Finds whether the provided clock is in standby mode or not. Returns + * true if the provided clock is a clkctrl type clock and it is in standby, + * false otherwise. + */ +bool ti_clk_is_in_standby(struct clk *clk) +{ + struct clk_hw *hw; + struct clk_hw_omap *hwclk; + u32 val; + + hw = __clk_get_hw(clk); + + if (!omap2_clk_is_hw_omap(hw)) + return false; + + hwclk = to_clk_hw_omap(hw); + + val = ti_clk_ll_ops->clk_readl(&hwclk->enable_reg); + + if (val & OMAP4_STBYST_MASK) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(ti_clk_is_in_standby); diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index bb2c5af9082a..c62f6fa6763d 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -298,6 +298,7 @@ struct ti_clk_features { void ti_clk_setup_features(struct ti_clk_features *features); const struct ti_clk_features *ti_clk_get_features(void); +bool ti_clk_is_in_standby(struct clk *clk); int omap3_noncore_dpll_save_context(struct clk_hw *hw); void omap3_noncore_dpll_restore_context(struct clk_hw *hw); From 2d5f60afd2b6fa9c583c4f01989f734e00e090ae Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:07 +0300 Subject: [PATCH 075/160] dt-bindings: clk: add omap5 iva clkctrl definitions OMAP5 device contains an IVA subsystem (Image and Video Accelerator.) IVA subsystem clkctrl definitions are currently missing, so add them. Signed-off-by: Tero Kristo --- include/dt-bindings/clock/omap5.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dt-bindings/clock/omap5.h b/include/dt-bindings/clock/omap5.h index e5411938983c..ba672064ccb4 100644 --- a/include/dt-bindings/clock/omap5.h +++ b/include/dt-bindings/clock/omap5.h @@ -86,6 +86,10 @@ #define OMAP5_UART5_CLKCTRL OMAP5_CLKCTRL_INDEX(0x170) #define OMAP5_UART6_CLKCTRL OMAP5_CLKCTRL_INDEX(0x178) +/* iva clocks */ +#define OMAP5_IVA_CLKCTRL OMAP5_CLKCTRL_INDEX(0x20) +#define OMAP5_SL2IF_CLKCTRL OMAP5_CLKCTRL_INDEX(0x28) + /* dss clocks */ #define OMAP5_DSS_CORE_CLKCTRL OMAP5_CLKCTRL_INDEX(0x20) From 25999e6172a3ec6bb4b1f5a77471532c209937cc Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:08 +0300 Subject: [PATCH 076/160] clk: ti: omap5: add IVA subsystem clkctrl data Add clkctrl data for the IVA subsystem (Image and Video Accelerator.) Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-54xx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c index e675e27f1203..b89dc0d6f836 100644 --- a/drivers/clk/ti/clk-54xx.c +++ b/drivers/clk/ti/clk-54xx.c @@ -286,6 +286,12 @@ static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst { 0 }, }; +static const struct omap_clkctrl_reg_data omap5_iva_clkctrl_regs[] __initconst = { + { OMAP5_IVA_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" }, + { OMAP5_SL2IF_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" }, + { 0 }, +}; + static const char * const omap5_dss_dss_clk_parents[] __initconst = { "dpll_per_h12x2_ck", NULL, @@ -502,6 +508,7 @@ const struct omap_clkctrl_data omap5_clkctrl_data[] __initconst = { { 0x4a008d20, omap5_l4cfg_clkctrl_regs }, { 0x4a008e20, omap5_l3instr_clkctrl_regs }, { 0x4a009020, omap5_l4per_clkctrl_regs }, + { 0x4a009220, omap5_iva_clkctrl_regs }, { 0x4a009420, omap5_dss_clkctrl_regs }, { 0x4a009520, omap5_gpu_clkctrl_regs }, { 0x4a009620, omap5_l3init_clkctrl_regs }, From 9063ea469c406fae7c60d2ea4d80f1101dd401eb Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:09 +0300 Subject: [PATCH 077/160] clk: ti: dra7xx: Drop idlest polling from IPU & DSP clkctrl clocks The IPU and DSP remote processor cores and their corresponding MMUs on DRA7 SoCs have hardreset lines associated with them and are controlled by a PRCM reset line each. Any clkctrl enable/disable operations cannot be checked for module enabled/disabled status independent of the reset operation, and this causes some unwanted timeouts in the kernel and unbalanced states for these clocks. These details should be handled by the driver integration code itself. Add the CLKF_NO_IDLEST flag to both the IPU and DSP clkctrl clocks so that these module status checks are skipped. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-7xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index b57fe09b428b..94e69cdc2bd2 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -25,7 +25,7 @@ static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data dra7_dsp1_clkctrl_regs[] __initconst = { - { DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" }, + { DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_dsp_m2_ck" }, { 0 }, }; @@ -41,7 +41,7 @@ static const struct omap_clkctrl_bit_data dra7_mmu_ipu1_bit_data[] __initconst = }; static const struct omap_clkctrl_reg_data dra7_ipu1_clkctrl_regs[] __initconst = { - { DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP, "ipu1-clkctrl:0000:24" }, + { DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP | CLKF_NO_IDLEST, "ipu1-clkctrl:0000:24" }, { 0 }, }; @@ -137,7 +137,7 @@ static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data dra7_dsp2_clkctrl_regs[] __initconst = { - { DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" }, + { DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_dsp_m2_ck" }, { 0 }, }; @@ -164,7 +164,7 @@ static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initcons }; static const struct omap_clkctrl_reg_data dra7_ipu2_clkctrl_regs[] __initconst = { - { DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" }, + { DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_core_h22x2_ck" }, { 0 }, }; From e1799d451a872cc9b0e0a96d820fc599e2b30a44 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Thu, 12 Sep 2019 16:26:10 +0300 Subject: [PATCH 078/160] clk: ti: omap4: Drop idlest polling from IPU & DSP clkctrl clocks The IPU and DSP remote processor cores and their corresponding MMUs on OMAP4 SoCs have hardreset lines associated with them and are controlled by a PRCM reset line each. Any clkctrl enable/disable operations cannot be checked for module enabled/disabled status independent of the reset operation, and this causes some unwanted timeouts in the kernel and unbalanced states for these clocks. These details should be handled by the driver integration code itself. Add the CLKF_NO_IDLEST flag to both the IPU and DSP clkctrl clocks so that these module status checks are skipped. Signed-off-by: Suman Anna Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-44xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c index b10ed0429091..2b4dab632318 100644 --- a/drivers/clk/ti/clk-44xx.c +++ b/drivers/clk/ti/clk-44xx.c @@ -37,7 +37,7 @@ static const struct omap_clkctrl_reg_data omap4_mpuss_clkctrl_regs[] __initconst }; static const struct omap_clkctrl_reg_data omap4_tesla_clkctrl_regs[] __initconst = { - { OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m4x2_ck" }, + { OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_iva_m4x2_ck" }, { 0 }, }; @@ -219,7 +219,7 @@ static const struct omap_clkctrl_reg_data omap4_l3_2_clkctrl_regs[] __initconst }; static const struct omap_clkctrl_reg_data omap4_ducati_clkctrl_regs[] __initconst = { - { OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "ducati_clk_mux_ck" }, + { OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "ducati_clk_mux_ck" }, { 0 }, }; From 95a62bf2dbfb8c1fa44f92e2d0116628695fa9bd Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Thu, 12 Sep 2019 16:26:11 +0300 Subject: [PATCH 079/160] clk: ti: omap5: Drop idlest polling from IPU & DSP clkctrl clocks The IPU and DSP remote processor cores and their corresponding MMUs on OMAP5 SoCs have hardreset lines associated with them and are controlled by a PRCM reset line each. Any clkctrl enable/disable operations cannot be checked for module enabled/disabled status independent of the reset operation, and this causes some unwanted timeouts in the kernel and unbalanced states for these clocks. These details should be handled by the driver integration code itself. Add the CLKF_NO_IDLEST flag to both the IPU and DSP clkctrl clocks so that these module status checks are skipped. Signed-off-by: Suman Anna Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-54xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c index b89dc0d6f836..c9608e5d993a 100644 --- a/drivers/clk/ti/clk-54xx.c +++ b/drivers/clk/ti/clk-54xx.c @@ -31,7 +31,7 @@ static const struct omap_clkctrl_reg_data omap5_mpu_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data omap5_dsp_clkctrl_regs[] __initconst = { - { OMAP5_MMU_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h11x2_ck" }, + { OMAP5_MMU_DSP_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_iva_h11x2_ck" }, { 0 }, }; @@ -145,7 +145,7 @@ static const struct omap_clkctrl_reg_data omap5_l3main2_clkctrl_regs[] __initcon }; static const struct omap_clkctrl_reg_data omap5_ipu_clkctrl_regs[] __initconst = { - { OMAP5_MMU_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" }, + { OMAP5_MMU_IPU_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_core_h22x2_ck" }, { 0 }, }; From caf00b53678f172a80217d297e83346f337b427c Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:12 +0300 Subject: [PATCH 080/160] clk: ti: am43xx: drop idlest polling from pruss clkctrl clock The PRUSS modules on AM43xx SoCs have a hardreset line and are controlled by a PRCM reset line. Any clkctrl enable/disable operations cannot be checked for module enabled/disabled status independent of the reset operation, and this causes some unwanted timeouts in the kernel and unbalanced states for the PRUSS clocks. These details should be handled by the driver integration code itself. Add the CLKF_NO_IDLEST flag to the PRUSS clkctrl clock so that these module status checks are skipped. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-43xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index 2782d91838ac..7ec8fe6aa7c1 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c @@ -126,7 +126,7 @@ static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = { }; static const struct omap_clkctrl_reg_data am4_pruss_ocp_clkctrl_regs[] __initconst = { - { AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" }, + { AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "pruss_ocp_gclk" }, { 0 }, }; From 4d0030bdb47b703bebe4796d5c16beb776c6950f Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 12 Sep 2019 16:26:13 +0300 Subject: [PATCH 081/160] clk: ti: am33xx: drop idlest polling from pruss clkctrl clock The PRUSS module on AM33xx SoCs has a hardreset line and is controlled by a PRCM reset line. Any clkctrl enable/disable operations cannot be checked for module enabled/disabled status independent of the reset operation, and this causes some unwanted timeouts in the kernel and unbalanced states for the PRUSS clocks. These details should be handled by the driver integration code itself. Add the CLKF_NO_IDLEST flag to the PRUSS clkctrl clock so that these module status checks are skipped. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-33xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c index a360d3109555..935efb66b389 100644 --- a/drivers/clk/ti/clk-33xx.c +++ b/drivers/clk/ti/clk-33xx.c @@ -107,7 +107,7 @@ static const struct omap_clkctrl_reg_data am3_l4hs_clkctrl_regs[] __initconst = }; static const struct omap_clkctrl_reg_data am3_pruss_ocp_clkctrl_regs[] __initconst = { - { AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" }, + { AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "pruss_ocp_gclk" }, { 0 }, }; From 194071817898897c65ffb5ae59d6d686ca13452c Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 7 Oct 2019 15:26:03 +0300 Subject: [PATCH 082/160] clk: ti: am33xx: drop idlest polling from gfx clock Due to the way ti sysc and hardreset line control is now implemented, it is not possible to poll the clock status for gfx clock independent of hardreset line control. Thus, add a flag to prevent handling this status bit from clock driver. Correct sequencing of events is guaranteed by ti-sysc bus driver. Reported-by: Tony Lindgren Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-33xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c index 935efb66b389..e001b9bcb6bf 100644 --- a/drivers/clk/ti/clk-33xx.c +++ b/drivers/clk/ti/clk-33xx.c @@ -217,7 +217,7 @@ static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst }; static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = { - { AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "gfx_fck_div_ck" }, { 0 }, }; From ece3e465b80a05c994783c7161e3d49035064f71 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 7 Oct 2019 15:26:04 +0300 Subject: [PATCH 083/160] clk: ti: am43xx: drop idlest polling from gfx clock Due to the way ti sysc and hardreset line control is now implemented, it is not possible to poll the clock status for gfx clock independent of hardreset line control. Thus, add a flag to prevent handling this status bit from clock driver. Correct sequencing of events is guaranteed by ti-sysc bus driver. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk-43xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index 7ec8fe6aa7c1..af3e7805769e 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c @@ -73,7 +73,7 @@ static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = { }; static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = { - { AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "gfx_fck_div_ck" }, { 0 }, }; From fbbc18591585bf74031dd6474b2937f87063e959 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 2 Oct 2019 15:06:08 +0300 Subject: [PATCH 084/160] clk: ti: divider: cleanup _register_divider and ti_clk_get_div_table Cleanup couple of TI divider clock internal APIs. These currently pass huge amount of parameters, which makes it difficult to track what is going on. Abstract most of these under struct clk_omap_div which gets passed over the APIs. Signed-off-by: Tero Kristo Tested-by: Adam Ford --- drivers/clk/ti/divider.c | 113 ++++++++++++++------------------------- 1 file changed, 41 insertions(+), 72 deletions(-) diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 6cb863c13648..1b181f89ddc6 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -310,47 +310,26 @@ const struct clk_ops ti_clk_divider_ops = { .restore_context = clk_divider_restore_context, }; -static struct clk *_register_divider(struct device *dev, const char *name, - const char *parent_name, - unsigned long flags, - struct clk_omap_reg *reg, - u8 shift, u8 width, s8 latch, - u8 clk_divider_flags, - const struct clk_div_table *table) +static struct clk *_register_divider(struct device_node *node, + u32 flags, + struct clk_omap_divider *div) { - struct clk_omap_divider *div; struct clk *clk; struct clk_init_data init; + const char *parent_name; - if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { - if (width + shift > 16) { - pr_warn("divider value exceeds LOWORD field\n"); - return ERR_PTR(-EINVAL); - } - } + parent_name = of_clk_get_parent_name(node, 0); - /* allocate the divider */ - div = kzalloc(sizeof(*div), GFP_KERNEL); - if (!div) - return ERR_PTR(-ENOMEM); - - init.name = name; + init.name = node->name; init.ops = &ti_clk_divider_ops; init.flags = flags; init.parent_names = (parent_name ? &parent_name : NULL); init.num_parents = (parent_name ? 1 : 0); - /* struct clk_divider assignments */ - memcpy(&div->reg, reg, sizeof(*reg)); - div->shift = shift; - div->width = width; - div->latch = latch; - div->flags = clk_divider_flags; div->hw.init = &init; - div->table = table; /* register the clock */ - clk = ti_clk_register(dev, &div->hw, name); + clk = ti_clk_register(NULL, &div->hw, node->name); if (IS_ERR(clk)) kfree(div); @@ -425,8 +404,8 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, return 0; } -static struct clk_div_table * -__init ti_clk_get_div_table(struct device_node *node) +static int __init ti_clk_get_div_table(struct device_node *node, + struct clk_omap_divider *div) { struct clk_div_table *table; const __be32 *divspec; @@ -438,7 +417,7 @@ __init ti_clk_get_div_table(struct device_node *node) divspec = of_get_property(node, "ti,dividers", &num_div); if (!divspec) - return NULL; + return 0; num_div /= 4; @@ -453,13 +432,12 @@ __init ti_clk_get_div_table(struct device_node *node) if (!valid_div) { pr_err("no valid dividers for %pOFn table\n", node); - return ERR_PTR(-EINVAL); + return -EINVAL; } table = kcalloc(valid_div + 1, sizeof(*table), GFP_KERNEL); - if (!table) - return ERR_PTR(-ENOMEM); + return -ENOMEM; valid_div = 0; @@ -472,7 +450,9 @@ __init ti_clk_get_div_table(struct device_node *node) } } - return table; + div->table = table; + + return 0; } static int _get_divider_width(struct device_node *node, @@ -520,46 +500,43 @@ static int _get_divider_width(struct device_node *node, } static int __init ti_clk_divider_populate(struct device_node *node, - struct clk_omap_reg *reg, const struct clk_div_table **table, - u32 *flags, u8 *div_flags, u8 *width, u8 *shift, s8 *latch) + struct clk_omap_divider *div, + u32 *flags) { u32 val; int ret; - ret = ti_clk_get_reg_addr(node, 0, reg); + ret = ti_clk_get_reg_addr(node, 0, &div->reg); if (ret) return ret; if (!of_property_read_u32(node, "ti,bit-shift", &val)) - *shift = val; + div->shift = val; else - *shift = 0; + div->shift = 0; - if (latch) { - if (!of_property_read_u32(node, "ti,latch-bit", &val)) - *latch = val; - else - *latch = -EINVAL; - } + if (!of_property_read_u32(node, "ti,latch-bit", &val)) + div->latch = val; + else + div->latch = -EINVAL; *flags = 0; - *div_flags = 0; + div->flags = 0; if (of_property_read_bool(node, "ti,index-starts-at-one")) - *div_flags |= CLK_DIVIDER_ONE_BASED; + div->flags |= CLK_DIVIDER_ONE_BASED; if (of_property_read_bool(node, "ti,index-power-of-two")) - *div_flags |= CLK_DIVIDER_POWER_OF_TWO; + div->flags |= CLK_DIVIDER_POWER_OF_TWO; if (of_property_read_bool(node, "ti,set-rate-parent")) *flags |= CLK_SET_RATE_PARENT; - *table = ti_clk_get_div_table(node); + ret = ti_clk_get_div_table(node, div); + if (ret) + return ret; - if (IS_ERR(*table)) - return PTR_ERR(*table); - - *width = _get_divider_width(node, *table, *div_flags); + div->width = _get_divider_width(node, div->table, div->flags); return 0; } @@ -573,24 +550,17 @@ static int __init ti_clk_divider_populate(struct device_node *node, static void __init of_ti_divider_clk_setup(struct device_node *node) { struct clk *clk; - const char *parent_name; - struct clk_omap_reg reg; - u8 clk_divider_flags = 0; - u8 width = 0; - u8 shift = 0; - s8 latch = -EINVAL; - const struct clk_div_table *table = NULL; u32 flags = 0; + struct clk_omap_divider *div; - parent_name = of_clk_get_parent_name(node, 0); + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return; - if (ti_clk_divider_populate(node, ®, &table, &flags, - &clk_divider_flags, &width, &shift, &latch)) + if (ti_clk_divider_populate(node, div, &flags)) goto cleanup; - clk = _register_divider(NULL, node->name, parent_name, flags, ®, - shift, width, latch, clk_divider_flags, table); - + clk = _register_divider(node, flags, div); if (!IS_ERR(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); of_ti_clk_autoidle_setup(node); @@ -598,22 +568,21 @@ static void __init of_ti_divider_clk_setup(struct device_node *node) } cleanup: - kfree(table); + kfree(div->table); + kfree(div); } CLK_OF_DECLARE(divider_clk, "ti,divider-clock", of_ti_divider_clk_setup); static void __init of_ti_composite_divider_clk_setup(struct device_node *node) { struct clk_omap_divider *div; - u32 val; + u32 tmp; div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) return; - if (ti_clk_divider_populate(node, &div->reg, &div->table, &val, - &div->flags, &div->width, &div->shift, - NULL) < 0) + if (ti_clk_divider_populate(node, div, &tmp)) goto cleanup; if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER)) From a229965cfeab8ea8bb79086d6f59ac9a57de66fe Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 2 Oct 2019 15:06:09 +0300 Subject: [PATCH 085/160] clk: ti: divider: cleanup ti_clk_parse_divider_data API Cleanup the ti_clk_parse_divider_data to pass the divider data struct directly instead of individual values of it. This makes it easier to modify the implementation later on. Signed-off-by: Tero Kristo Tested-by: Adam Ford --- drivers/clk/ti/clkctrl.c | 2 +- drivers/clk/ti/clock.h | 3 +-- drivers/clk/ti/divider.c | 18 +++++++----------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index d6cb41b55800..b8ae8c44d761 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -383,7 +383,7 @@ _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider, if (ti_clk_parse_divider_data((int *)div_data->dividers, 0, div_data->max_div, div_flags, - &div->width, &div->table)) { + div)) { pr_err("%s: Data parsing for %pOF:%04x:%d failed\n", __func__, node, offset, data->bit); kfree(div); diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index e4b8392ff63c..f6b6876dfdee 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -220,8 +220,7 @@ void ti_clk_latch(struct clk_omap_reg *reg, s8 shift); struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, - u8 flags, u8 *width, - const struct clk_div_table **table); + u8 flags, struct clk_omap_divider *div); int ti_clk_get_reg_addr(struct device_node *node, int index, struct clk_omap_reg *reg); diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 1b181f89ddc6..2c53096b7229 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -338,8 +338,7 @@ static struct clk *_register_divider(struct device_node *node, } int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, - u8 flags, u8 *width, - const struct clk_div_table **table) + u8 flags, struct clk_omap_divider *divider) { int valid_div = 0; u32 val; @@ -363,8 +362,7 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, val++; } - *width = fls(val); - *table = NULL; + divider->width = fls(val); return 0; } @@ -382,24 +380,22 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, num_dividers = i; tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL); - if (!tmp) { - *table = ERR_PTR(-ENOMEM); + if (!tmp) return -ENOMEM; - } valid_div = 0; - *width = 0; + divider->width = 0; for (i = 0; i < num_dividers; i++) if (div_table[i] > 0) { tmp[valid_div].div = div_table[i]; tmp[valid_div].val = i; valid_div++; - *width = i; + divider->width = i; } - *width = fls(*width); - *table = tmp; + divider->width = fls(divider->width); + divider->table = tmp; return 0; } From 8ffea6eef4ace7e207fc2fe852d2019d93f51d1a Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 2 Oct 2019 15:06:10 +0300 Subject: [PATCH 086/160] clk: ti: divider: convert to use min,max,mask instead of width The existing width field used to check divider validity does not provide enough protection against bad values. For example, if max divider value is 4, the smallest all-1 bitmask that can hold this value is 7, which allows values higher than 4 to be used. This typically causes unpredictable results with hardware. So far this issue hasn't been noticed as most of the dividers actually have maximum values which fit the whole bitfield, but there are certain clocks for which this is a problem, like dpll4_m4 divider on omap3 devices. Thus, convert the whole validity logic to use min,max and mask values for determining if a specific divider is valid or not. This prevents the odd cases where bad value would otherwise be written to a divider config register. Signed-off-by: Tero Kristo Tested-by: Adam Ford --- drivers/clk/ti/clock.h | 4 +- drivers/clk/ti/divider.c | 161 +++++++++++++++++---------------------- 2 files changed, 74 insertions(+), 91 deletions(-) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index f6b6876dfdee..e6995c04001e 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -20,9 +20,11 @@ struct clk_omap_divider { struct clk_hw hw; struct clk_omap_reg reg; u8 shift; - u8 width; u8 flags; s8 latch; + u16 min; + u16 max; + u16 mask; const struct clk_div_table *table; u32 context; }; diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 2c53096b7229..28080df92f72 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -26,30 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define div_mask(d) ((1 << ((d)->width)) - 1) - -static unsigned int _get_table_maxdiv(const struct clk_div_table *table) -{ - unsigned int maxdiv = 0; - const struct clk_div_table *clkt; - - for (clkt = table; clkt->div; clkt++) - if (clkt->div > maxdiv) - maxdiv = clkt->div; - return maxdiv; -} - -static unsigned int _get_maxdiv(struct clk_omap_divider *divider) -{ - if (divider->flags & CLK_DIVIDER_ONE_BASED) - return div_mask(divider); - if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) - return 1 << div_mask(divider); - if (divider->table) - return _get_table_maxdiv(divider->table); - return div_mask(divider) + 1; -} - static unsigned int _get_table_div(const struct clk_div_table *table, unsigned int val) { @@ -61,6 +37,34 @@ static unsigned int _get_table_div(const struct clk_div_table *table, return 0; } +static void _setup_mask(struct clk_omap_divider *divider) +{ + u16 mask; + u32 max_val; + const struct clk_div_table *clkt; + + if (divider->table) { + max_val = 0; + + for (clkt = divider->table; clkt->div; clkt++) + if (clkt->val > max_val) + max_val = clkt->val; + } else { + max_val = divider->max; + + if (!(divider->flags & CLK_DIVIDER_ONE_BASED) && + !(divider->flags & CLK_DIVIDER_POWER_OF_TWO)) + max_val--; + } + + if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) + mask = fls(max_val) - 1; + else + mask = max_val; + + divider->mask = (1 << fls(mask)) - 1; +} + static unsigned int _get_div(struct clk_omap_divider *divider, unsigned int val) { if (divider->flags & CLK_DIVIDER_ONE_BASED) @@ -101,7 +105,7 @@ static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw, unsigned int div, val; val = ti_clk_ll_ops->clk_readl(÷r->reg) >> divider->shift; - val &= div_mask(divider); + val &= divider->mask; div = _get_div(divider, val); if (!div) { @@ -180,7 +184,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, if (!rate) rate = 1; - maxdiv = _get_maxdiv(divider); + maxdiv = divider->max; if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { parent_rate = *best_parent_rate; @@ -219,7 +223,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, } if (!bestdiv) { - bestdiv = _get_maxdiv(divider); + bestdiv = divider->max; *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1); } @@ -249,17 +253,16 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, divider = to_clk_omap_divider(hw); div = DIV_ROUND_UP(parent_rate, rate); + + if (div > divider->max) + div = divider->max; + if (div < divider->min) + div = divider->min; + value = _get_val(divider, div); - if (value > div_mask(divider)) - value = div_mask(divider); - - if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { - val = div_mask(divider) << (divider->shift + 16); - } else { - val = ti_clk_ll_ops->clk_readl(÷r->reg); - val &= ~(div_mask(divider) << divider->shift); - } + val = ti_clk_ll_ops->clk_readl(÷r->reg); + val &= ~(divider->mask << divider->shift); val |= value << divider->shift; ti_clk_ll_ops->clk_writel(val, ÷r->reg); @@ -280,7 +283,7 @@ static int clk_divider_save_context(struct clk_hw *hw) u32 val; val = ti_clk_ll_ops->clk_readl(÷r->reg) >> divider->shift; - divider->context = val & div_mask(divider); + divider->context = val & divider->mask; return 0; } @@ -297,7 +300,7 @@ static void clk_divider_restore_context(struct clk_hw *hw) u32 val; val = ti_clk_ll_ops->clk_readl(÷r->reg); - val &= ~(div_mask(divider) << divider->shift); + val &= ~(divider->mask << divider->shift); val |= divider->context << divider->shift; ti_clk_ll_ops->clk_writel(val, ÷r->reg); } @@ -341,29 +344,14 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, u8 flags, struct clk_omap_divider *divider) { int valid_div = 0; - u32 val; - int div; int i; struct clk_div_table *tmp; + u16 min_div = 0; if (!div_table) { - if (flags & CLKF_INDEX_STARTS_AT_ONE) - val = 1; - else - val = 0; - - div = 1; - - while (div < max_div) { - if (flags & CLKF_INDEX_POWER_OF_TWO) - div <<= 1; - else - div++; - val++; - } - - divider->width = fls(val); - + divider->min = 1; + divider->max = max_div; + _setup_mask(divider); return 0; } @@ -384,18 +372,22 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, return -ENOMEM; valid_div = 0; - divider->width = 0; for (i = 0; i < num_dividers; i++) if (div_table[i] > 0) { tmp[valid_div].div = div_table[i]; tmp[valid_div].val = i; valid_div++; - divider->width = i; + if (div_table[i] > max_div) + max_div = div_table[i]; + if (!min_div || div_table[i] < min_div) + min_div = div_table[i]; } - divider->width = fls(divider->width); + divider->min = min_div; + divider->max = max_div; divider->table = tmp; + _setup_mask(divider); return 0; } @@ -451,16 +443,15 @@ static int __init ti_clk_get_div_table(struct device_node *node, return 0; } -static int _get_divider_width(struct device_node *node, - const struct clk_div_table *table, - u8 flags) +static int _populate_divider_min_max(struct device_node *node, + struct clk_omap_divider *divider) { - u32 min_div; - u32 max_div; - u32 val = 0; - u32 div; + u32 min_div = 0; + u32 max_div = 0; + u32 val; + const struct clk_div_table *clkt; - if (!table) { + if (!divider->table) { /* Clk divider table not provided, determine min/max divs */ if (of_property_read_u32(node, "ti,min-div", &min_div)) min_div = 1; @@ -469,30 +460,22 @@ static int _get_divider_width(struct device_node *node, pr_err("no max-div for %pOFn!\n", node); return -EINVAL; } - - /* Determine bit width for the field */ - if (flags & CLK_DIVIDER_ONE_BASED) - val = 1; - - div = min_div; - - while (div < max_div) { - if (flags & CLK_DIVIDER_POWER_OF_TWO) - div <<= 1; - else - div++; - val++; - } } else { - div = 0; - while (table[div].div) { - val = table[div].val; - div++; + for (clkt = divider->table; clkt->div; clkt++) { + val = clkt->div; + if (val > max_div) + max_div = val; + if (!min_div || val < min_div) + min_div = val; } } - return fls(val); + divider->min = min_div; + divider->max = max_div; + _setup_mask(divider); + + return 0; } static int __init ti_clk_divider_populate(struct device_node *node, @@ -532,9 +515,7 @@ static int __init ti_clk_divider_populate(struct device_node *node, if (ret) return ret; - div->width = _get_divider_width(node, div->table, div->flags); - - return 0; + return _populate_divider_min_max(node, div); } /** From f5869190667951720f8c1ec4638bff4c682a3a4e Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Wed, 2 Oct 2019 15:06:11 +0300 Subject: [PATCH 087/160] ARM: dts: omap3: fix DPLL4 M4 divider max value The maximum divider value for DPLL4 M4 divider appears wrong. For most OMAP3 family SoCs this is 16, but it is defined as 32, which is maybe only valid for omap36xx. To avoid any overflows in trying to write this register, set the max to 16 for all omap3 family, except omap36xx. For omap36xx the maximum is set to 31, as it appears value 32 is not working properly. Signed-off-by: Tero Kristo Tested-by: Adam Ford Acked-by: Tony Lindgren --- arch/arm/boot/dts/omap36xx-clocks.dtsi | 4 ++++ arch/arm/boot/dts/omap3xxx-clocks.dtsi | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap36xx-clocks.dtsi b/arch/arm/boot/dts/omap36xx-clocks.dtsi index e66fc57ec35d..4e9cc9003594 100644 --- a/arch/arm/boot/dts/omap36xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap36xx-clocks.dtsi @@ -105,3 +105,7 @@ <&mcbsp4_ick>, <&uart4_fck>; }; }; + +&dpll4_m4_ck { + ti,max-div = <31>; +}; diff --git a/arch/arm/boot/dts/omap3xxx-clocks.dtsi b/arch/arm/boot/dts/omap3xxx-clocks.dtsi index 685c82a9d03e..0656c32439d2 100644 --- a/arch/arm/boot/dts/omap3xxx-clocks.dtsi +++ b/arch/arm/boot/dts/omap3xxx-clocks.dtsi @@ -416,7 +416,7 @@ #clock-cells = <0>; compatible = "ti,divider-clock"; clocks = <&dpll4_ck>; - ti,max-div = <32>; + ti,max-div = <16>; reg = <0x0e40>; ti,index-starts-at-one; }; From 5b468cc4b88073356f79cf779207d64b65a914f0 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Thu, 10 Oct 2019 12:36:54 +1030 Subject: [PATCH 088/160] dt-bindings: clock: Add AST2500 RMII RCLK definitions The AST2500 has an explicit gate for the RMII RCLK for each of the two MACs. Signed-off-by: Andrew Jeffery Reviewed-by: Joel Stanley Acked-by: Rob Herring Signed-off-by: Joel Stanley --- include/dt-bindings/clock/aspeed-clock.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h index f43738607d77..9ff4f6e4558c 100644 --- a/include/dt-bindings/clock/aspeed-clock.h +++ b/include/dt-bindings/clock/aspeed-clock.h @@ -39,6 +39,8 @@ #define ASPEED_CLK_BCLK 33 #define ASPEED_CLK_MPLL 34 #define ASPEED_CLK_24M 35 +#define ASPEED_CLK_MAC1RCLK 36 +#define ASPEED_CLK_MAC2RCLK 37 #define ASPEED_RESET_XDMA 0 #define ASPEED_RESET_MCTP 1 From d8d9ad83a497f78edd4016df0919a49628dcafbc Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Thu, 10 Oct 2019 12:37:24 +1030 Subject: [PATCH 089/160] dt-bindings: clock: Add AST2600 RMII RCLK gate definitions The AST2600 has an explicit gate for the RMII RCLK for each of the four MACs. Signed-off-by: Andrew Jeffery Reviewed-by: Joel Stanley Acked-by: Rob Herring Signed-off-by: Joel Stanley --- include/dt-bindings/clock/ast2600-clock.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h index 38074a5f7296..62b9520a00fd 100644 --- a/include/dt-bindings/clock/ast2600-clock.h +++ b/include/dt-bindings/clock/ast2600-clock.h @@ -83,6 +83,10 @@ #define ASPEED_CLK_MAC12 64 #define ASPEED_CLK_MAC34 65 #define ASPEED_CLK_USBPHY_40M 66 +#define ASPEED_CLK_MAC1RCLK 67 +#define ASPEED_CLK_MAC2RCLK 68 +#define ASPEED_CLK_MAC3RCLK 69 +#define ASPEED_CLK_MAC4RCLK 70 /* Only list resets here that are not part of a gate */ #define ASPEED_RESET_ADC 55 From 640f9606dce1d482ed87590c2d582004ea23ab09 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 23 Oct 2019 14:29:11 +0200 Subject: [PATCH 090/160] dt-bindings: power: Add r8a77961 SYSC power domain definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add power domain indices for the R-Car M3-W+ (R8A77961) SoC. Based on Rev. 2.00 of the R-Car Series, 3rd Generation, Hardware User’s Manual (Jul. 31, 2019). Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Reviewed-by: Rob Herring Reviewed-by: Eugeniu Rosca Link: https://lore.kernel.org/r/20191023122911.12166-6-geert+renesas@glider.be --- include/dt-bindings/power/r8a77961-sysc.h | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 include/dt-bindings/power/r8a77961-sysc.h diff --git a/include/dt-bindings/power/r8a77961-sysc.h b/include/dt-bindings/power/r8a77961-sysc.h new file mode 100644 index 000000000000..7a3800996f7c --- /dev/null +++ b/include/dt-bindings/power/r8a77961-sysc.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2019 Glider bvba + */ +#ifndef __DT_BINDINGS_POWER_R8A77961_SYSC_H__ +#define __DT_BINDINGS_POWER_R8A77961_SYSC_H__ + +/* + * These power domain indices match the numbers of the interrupt bits + * representing the power areas in the various Interrupt Registers + * (e.g. SYSCISR, Interrupt Status Register) + */ + +#define R8A77961_PD_CA57_CPU0 0 +#define R8A77961_PD_CA57_CPU1 1 +#define R8A77961_PD_CA53_CPU0 5 +#define R8A77961_PD_CA53_CPU1 6 +#define R8A77961_PD_CA53_CPU2 7 +#define R8A77961_PD_CA53_CPU3 8 +#define R8A77961_PD_CA57_SCU 12 +#define R8A77961_PD_CR7 13 +#define R8A77961_PD_A3VC 14 +#define R8A77961_PD_3DG_A 17 +#define R8A77961_PD_3DG_B 18 +#define R8A77961_PD_CA53_SCU 21 +#define R8A77961_PD_A3IR 24 +#define R8A77961_PD_A2VC1 26 + +/* Always-on power area */ +#define R8A77961_PD_ALWAYS_ON 32 + +#endif /* __DT_BINDINGS_POWER_R8A77961_SYSC_H__ */ From 0b05ad22a27998f842cbbc3f285bac05e2c30f4c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 23 Oct 2019 14:29:39 +0200 Subject: [PATCH 091/160] dt-bindings: clock: Add r8a77961 CPG Core Clock Definitions Add all Clock Pulse Generator Core Clock Outputs for the Renesas R-Car M3-W+ (R8A77961) SoC, as listed in Table 8.2b ("List of Clocks [R-Car M3-W/R-Car M3-W+]") of the R-Car Series, 3rd Generation Hardware User's Manual (Rev. 2.00, Jul. 31, 2019). A gap is added for CSIREF, to preserve compatibility with the definitions for R-Car M3-W (R8A77960). Note that internal CPG clocks (S0, S1, S2, S3, SDSRC, SSPSRC, and POST2) are not included, as they are used as internal clock sources only, and never referenced from DT. Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20191023122941.12342-3-geert+renesas@glider.be --- include/dt-bindings/clock/r8a77961-cpg-mssr.h | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 include/dt-bindings/clock/r8a77961-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a77961-cpg-mssr.h b/include/dt-bindings/clock/r8a77961-cpg-mssr.h new file mode 100644 index 000000000000..7921d785546d --- /dev/null +++ b/include/dt-bindings/clock/r8a77961-cpg-mssr.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * Copyright (C) 2019 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A77961_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A77961_CPG_MSSR_H__ + +#include + +/* r8a77961 CPG Core Clocks */ +#define R8A77961_CLK_Z 0 +#define R8A77961_CLK_Z2 1 +#define R8A77961_CLK_ZR 2 +#define R8A77961_CLK_ZG 3 +#define R8A77961_CLK_ZTR 4 +#define R8A77961_CLK_ZTRD2 5 +#define R8A77961_CLK_ZT 6 +#define R8A77961_CLK_ZX 7 +#define R8A77961_CLK_S0D1 8 +#define R8A77961_CLK_S0D2 9 +#define R8A77961_CLK_S0D3 10 +#define R8A77961_CLK_S0D4 11 +#define R8A77961_CLK_S0D6 12 +#define R8A77961_CLK_S0D8 13 +#define R8A77961_CLK_S0D12 14 +#define R8A77961_CLK_S1D1 15 +#define R8A77961_CLK_S1D2 16 +#define R8A77961_CLK_S1D4 17 +#define R8A77961_CLK_S2D1 18 +#define R8A77961_CLK_S2D2 19 +#define R8A77961_CLK_S2D4 20 +#define R8A77961_CLK_S3D1 21 +#define R8A77961_CLK_S3D2 22 +#define R8A77961_CLK_S3D4 23 +#define R8A77961_CLK_LB 24 +#define R8A77961_CLK_CL 25 +#define R8A77961_CLK_ZB3 26 +#define R8A77961_CLK_ZB3D2 27 +#define R8A77961_CLK_ZB3D4 28 +#define R8A77961_CLK_CR 29 +#define R8A77961_CLK_CRD2 30 +#define R8A77961_CLK_SD0H 31 +#define R8A77961_CLK_SD0 32 +#define R8A77961_CLK_SD1H 33 +#define R8A77961_CLK_SD1 34 +#define R8A77961_CLK_SD2H 35 +#define R8A77961_CLK_SD2 36 +#define R8A77961_CLK_SD3H 37 +#define R8A77961_CLK_SD3 38 +#define R8A77961_CLK_SSP2 39 +#define R8A77961_CLK_SSP1 40 +#define R8A77961_CLK_SSPRS 41 +#define R8A77961_CLK_RPC 42 +#define R8A77961_CLK_RPCD2 43 +#define R8A77961_CLK_MSO 44 +#define R8A77961_CLK_CANFD 45 +#define R8A77961_CLK_HDMI 46 +#define R8A77961_CLK_CSI0 47 +/* CLK_CSIREF was removed */ +#define R8A77961_CLK_CP 49 +#define R8A77961_CLK_CPEX 50 +#define R8A77961_CLK_R 51 +#define R8A77961_CLK_OSC 52 + +#endif /* __DT_BINDINGS_CLOCK_R8A77961_CPG_MSSR_H__ */ From c99b23eb5a983c02355f4e3f0234b6f92a69be7b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 16 Oct 2019 16:52:07 +0200 Subject: [PATCH 092/160] dt-bindings: clock: renesas: Remove R-Car Gen2 legacy DT bindings As of commit 362b334b17943d84 ("ARM: dts: r8a7791: Convert to new CPG/MSSR bindings"), all upstream R-Car Gen2 device tree source files use the unified "Renesas Clock Pulse Generator / Module Standby and Software Reset" DT bindings. Hence remove the old R-Car Gen2 DT bindings describing a hierarchical representation of the various CPG and MSTP clocks. Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Link: https://lore.kernel.org/r/20191016145207.29779-1-geert+renesas@glider.be --- .../clock/renesas,rcar-gen2-cpg-clocks.txt | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt deleted file mode 100644 index f8c05bb4116e..000000000000 --- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt +++ /dev/null @@ -1,60 +0,0 @@ -* Renesas R-Car Gen2 Clock Pulse Generator (CPG) - -The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs -and several fixed ratio dividers. -The CPG also provides a Clock Domain for SoC devices, in combination with the -CPG Module Stop (MSTP) Clocks. - -Required Properties: - - - compatible: Must be one of - - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG - - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG - - "renesas,r8a7792-cpg-clocks" for the r8a7792 CPG - - "renesas,r8a7793-cpg-clocks" for the r8a7793 CPG - - "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG - and "renesas,rcar-gen2-cpg-clocks" as a fallback. - - - reg: Base address and length of the memory resource used by the CPG - - - clocks: References to the parent clocks: first to the EXTAL clock, second - to the USB_EXTAL clock - - #clock-cells: Must be 1 - - clock-output-names: The names of the clocks. Supported clocks are "main", - "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", "rcan", and - "adsp" - - #power-domain-cells: Must be 0 - -SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed -through an MSTP clock should refer to the CPG device node in their -"power-domains" property, as documented by the generic PM domain bindings in -Documentation/devicetree/bindings/power/power_domain.txt. - - -Examples --------- - - - CPG device node: - - cpg_clocks: cpg_clocks@e6150000 { - compatible = "renesas,r8a7790-cpg-clocks", - "renesas,rcar-gen2-cpg-clocks"; - reg = <0 0xe6150000 0 0x1000>; - clocks = <&extal_clk &usb_extal_clk>; - #clock-cells = <1>; - clock-output-names = "main", "pll0, "pll1", "pll3", - "lb", "qspi", "sdh", "sd0", "sd1", "z", - "rcan", "adsp"; - #power-domain-cells = <0>; - }; - - - - CPG/MSTP Clock Domain member device node: - - thermal@e61f0000 { - compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal"; - reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp5_clks R8A7790_CLK_THERMAL>; - power-domains = <&cpg_clocks>; - }; From 830dbce7c76ea529decac7d23b808c1e7da3d891 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 16 Oct 2019 16:56:50 +0200 Subject: [PATCH 093/160] dt-bindings: clock: renesas: rcar-usb2-clock-sel: Fix typo in example The documented compatible value for R-Car H3 is "renesas,r8a7795-rcar-usb2-clock-sel", not "renesas,r8a77950-rcar-usb2-clock-sel". Fixes: 311accb64570db45 ("clk: renesas: rcar-usb2-clock-sel: Add R-Car USB 2.0 clock selector PHY") Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Acked-by: Rob Herring Link: https://lore.kernel.org/r/20191016145650.30003-1-geert+renesas@glider.be --- .../devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt index e96e085271c1..83f6c6a7c41c 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt @@ -46,7 +46,7 @@ Required properties: Example (R-Car H3): usb2_clksel: clock-controller@e6590630 { - compatible = "renesas,r8a77950-rcar-usb2-clock-sel", + compatible = "renesas,r8a7795-rcar-usb2-clock-sel", "renesas,rcar-gen3-usb2-clock-sel"; reg = <0 0xe6590630 0 0x02>; clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>; From f00d1b16232fbb141048bba7616adba949f46d7b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 16 Oct 2019 17:07:11 +0200 Subject: [PATCH 094/160] clk: renesas: r8a77965: Remove superfluous semicolon There is no need to terminate a function with a semicolon. Remove it. Reported-by: Biju Das Fixes: 7ce36da900c0a2ff ("clk: renesas: cpg-mssr: Add support for R-Car M3-N") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20191016150711.30305-1-geert+renesas@glider.be --- drivers/clk/renesas/r8a77965-cpg-mssr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index b4e8c5b7d515..b3af4da2ca74 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -323,7 +323,7 @@ static int __init r8a77965_cpg_mssr_init(struct device *dev) } return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); -}; +} const struct cpg_mssr_info r8a77965_cpg_mssr_info __initconst = { /* Core Clocks */ From e751a25b4eecef0b1b305872027ae64d3b82569f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 23 Oct 2019 14:29:38 +0200 Subject: [PATCH 095/160] dt-bindings: clock: renesas: cpg-mssr: Document r8a77961 support Add DT binding documentation for the Clock Pulse Generator / Module Standby and Software Reset block in the Renesas R-Car M3-W+ (R8A77961) SoC. Update all references to R-Car M3-W from "r8a7796" to "r8a77960", to avoid confusion between R-Car M3-W (R8A77960) and M3-W+. Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20191023122941.12342-2-geert+renesas@glider.be --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index b5edebeb12b4..d67f57e0dfd2 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -27,7 +27,8 @@ Required Properties: - "renesas,r8a7793-cpg-mssr" for the r8a7793 SoC (R-Car M2-N) - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) - - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) + - "renesas,r8a7796-cpg-mssr" for the r8a77960 SoC (R-Car M3-W) + - "renesas,r8a77961-cpg-mssr" for the r8a77961 SoC (R-Car M3-W+) - "renesas,r8a77965-cpg-mssr" for the r8a77965 SoC (R-Car M3-N) - "renesas,r8a77970-cpg-mssr" for the r8a77970 SoC (R-Car V3M) - "renesas,r8a77980-cpg-mssr" for the r8a77980 SoC (R-Car V3H) @@ -42,10 +43,10 @@ Required Properties: - clock-names: List of external parent clock names. Valid names are: - "extal" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1, r8a774b1, r8a774c0, r8a7790, r8a7791, r8a7792, r8a7793, - r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, - r8a77990, r8a77995) - - "extalr" (r8a774a1, r8a774b1, r8a7795, r8a7796, r8a77965, r8a77970, - r8a77980) + r8a7794, r8a7795, r8a77960, r8a77961, r8a77965, r8a77970, + r8a77980, r8a77990, r8a77995) + - "extalr" (r8a774a1, r8a774b1, r8a7795, r8a77960, r8a77961, r8a77965, + r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, r8a7794) From 92d1ebae9abf1cd9460d8d0b3354262102a13634 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 23 Oct 2019 14:29:40 +0200 Subject: [PATCH 096/160] clk: renesas: Rename CLK_R8A7796 to CLK_R8A77960 Rename CONFIG_CLK_R8A7796 for R-Car M3-W (R8A77960) to CONFIG_CLK_R8A77960, to avoid confusion with R-Car M3-W+ (R8A77961), which will use CONFIG_CLK_R8A77961. Extend the dependency of CONFIG_CLK_R8A77960 from CONFIG_ARCH_R8A7796 to CONFIG_ARCH_R8A77960, to relax dependencies for a future rename of the SoC configuration symbol. Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20191023122941.12342-4-geert+renesas@glider.be --- drivers/clk/renesas/Kconfig | 4 ++-- drivers/clk/renesas/Makefile | 2 +- drivers/clk/renesas/renesas-cpg-mssr.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index be03bb748012..a48f75ec1400 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -21,7 +21,7 @@ config CLK_RENESAS select CLK_R8A7792 if ARCH_R8A7792 select CLK_R8A7794 if ARCH_R8A7794 select CLK_R8A7795 if ARCH_R8A7795 - select CLK_R8A7796 if ARCH_R8A7796 + select CLK_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796 select CLK_R8A77965 if ARCH_R8A77965 select CLK_R8A77970 if ARCH_R8A77970 select CLK_R8A77980 if ARCH_R8A77980 @@ -109,7 +109,7 @@ config CLK_R8A7795 bool "R-Car H3 clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG -config CLK_R8A7796 +config CLK_R8A77960 bool "R-Car M3-W clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index ef0fdd00d2b7..58211d0f04bf 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_CLK_R8A7791) += r8a7791-cpg-mssr.o obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o -obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77960) += 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 diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 35966678148e..c2f96e63498e 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -749,7 +749,7 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a7795_cpg_mssr_info, }, #endif -#ifdef CONFIG_CLK_R8A7796 +#ifdef CONFIG_CLK_R8A77960 { .compatible = "renesas,r8a7796-cpg-mssr", .data = &r8a7796_cpg_mssr_info, From 2ba738d56db4ddb1c17e418cb501d303a8b481d2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 23 Oct 2019 14:29:41 +0200 Subject: [PATCH 097/160] clk: renesas: r8a7796: Add R8A77961 CPG/MSSR support Add support for the R-Car M3-W+ (R8A77961) SoC to the Renesas Clock Pulse Generator / Module Standby and Software Reset driver. R-Car M3-W+ is very similar to R-Car M3-W (R8A77960), which allows for both SoCs to share a driver. R-Car M3-W+ lacks a few modules, so their clocks must be nullified. Based on a patch in the BSP by Takeshi Kihara . Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20191023122941.12342-5-geert+renesas@glider.be --- drivers/clk/renesas/Kconfig | 5 +++++ drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a7796-cpg-mssr.c | 24 ++++++++++++++++++++---- drivers/clk/renesas/renesas-cpg-mssr.c | 6 ++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index a48f75ec1400..4cd846bc98cc 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -22,6 +22,7 @@ config CLK_RENESAS select CLK_R8A7794 if ARCH_R8A7794 select CLK_R8A7795 if ARCH_R8A7795 select CLK_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796 + select CLK_R8A77961 if ARCH_R8A77961 select CLK_R8A77965 if ARCH_R8A77965 select CLK_R8A77970 if ARCH_R8A77970 select CLK_R8A77980 if ARCH_R8A77980 @@ -113,6 +114,10 @@ config CLK_R8A77960 bool "R-Car M3-W clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A77961 + bool "R-Car M3-W+ clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A77965 bool "R-Car M3-N clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 58211d0f04bf..4a722bc5aac7 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o obj-$(CONFIG_CLK_R8A77960) += r8a7796-cpg-mssr.o +obj-$(CONFIG_CLK_R8A77961) += 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 diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 90cc6a102602..e8420d3ada94 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -1,9 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* - * r8a7796 Clock Pulse Generator / Module Standby and Software Reset + * r8a7796 (R-Car M3-W/W+) Clock Pulse Generator / Module Standby and Software + * Reset * - * Copyright (C) 2016 Glider bvba - * Copyright (C) 2018 Renesas Electronics Corp. + * Copyright (C) 2016-2019 Glider bvba + * Copyright (C) 2018-2019 Renesas Electronics Corp. * * Based on r8a7795-cpg-mssr.c * @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -116,7 +118,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_BASE("r", R8A7796_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; -static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { +static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = { DEF_MOD("fdp1-0", 119, R8A7796_CLK_S0D1), DEF_MOD("scif5", 202, R8A7796_CLK_S3D4), DEF_MOD("scif4", 203, R8A7796_CLK_S3D4), @@ -304,6 +306,14 @@ static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { { 2, 192, 1, 192, 1, 32, }, }; + /* + * Fixups for R-Car M3-W+ + */ + +static const unsigned int r8a77961_mod_nullify[] __initconst = { + MOD_CLK_ID(617), /* FCPCI0 */ +}; + static int __init r8a7796_cpg_mssr_init(struct device *dev) { const struct rcar_gen3_cpg_pll_config *cpg_pll_config; @@ -320,6 +330,12 @@ static int __init r8a7796_cpg_mssr_init(struct device *dev) return -EINVAL; } + if (of_device_is_compatible(dev->of_node, "renesas,r8a77961-cpg-mssr")) + mssr_mod_nullify(r8a7796_mod_clks, + ARRAY_SIZE(r8a7796_mod_clks), + r8a77961_mod_nullify, + ARRAY_SIZE(r8a77961_mod_nullify)); + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); } diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index c2f96e63498e..a2663fbbd7a5 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -755,6 +755,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a7796_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A77961 + { + .compatible = "renesas,r8a77961-cpg-mssr", + .data = &r8a7796_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A77965 { .compatible = "renesas,r8a77965-cpg-mssr", From bceed71ba13116de4b1459c2c6db47d927b48e68 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Oct 2019 03:08:34 +0000 Subject: [PATCH 098/160] clk: imx: imx8mq: fix sys3_pll_out_sels It is not correct that sys3_pll_out use sys2_pll1_ref_sel as parent. According to the current imx_clk_sccg_pll design, it uses both bypass1/2, however set bypass2 as 1 is not correct, because it will make sys[x]_pll_out use wrong parent and might access wrong registers. So correct bypass2 to 0 and fix sys3_pll_out_sels. Fixes: e9dda4af685f ("clk: imx: Refactor entire sccg pll clk") Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/clk/imx/clk-imx8mq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 4a5dbc4366a5..5f10a606d836 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -34,7 +34,7 @@ static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; -static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", "sys2_pll1_ref_sel", }; +static const char * const sys3_pll_out_sels[] = {"sys3_pll1_ref_sel", }; static const char * const dram_pll_out_sels[] = {"dram_pll1_ref_sel", }; static const char * const video2_pll_out_sels[] = {"video2_pll1_ref_sel", }; @@ -342,7 +342,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_fixed("sys1_pll_out", 800000000); clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_fixed("sys2_pll_out", 1000000000); - clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 1, base + 0x48, CLK_IS_CRITICAL); + clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, base + 0x48, CLK_IS_CRITICAL); clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL); clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); From 4441b57ec27e35a86337b3197c62b3d6be9695b2 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 24 Oct 2019 00:13:28 +0200 Subject: [PATCH 099/160] clk: sunxi-ng: h3: Export MBUS clock MBUS clock will be referenced in MBUS controller node. Export it. Acked-by: Maxime Ripard Acked-by: Rob Herring Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-h3.h | 4 ---- include/dt-bindings/clock/sun8i-h3-ccu.h | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h index b6e2680ef354..d8c38447e11b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h @@ -48,10 +48,6 @@ /* Some more module clocks are exported */ -#define CLK_MBUS 113 - -/* And the GPU module clock is exported */ - #define CLK_NUMBER_H3 (CLK_GPU + 1) #define CLK_NUMBER_H5 (CLK_BUS_SCR1 + 1) diff --git a/include/dt-bindings/clock/sun8i-h3-ccu.h b/include/dt-bindings/clock/sun8i-h3-ccu.h index c5f7e9a70968..30d2d15373a2 100644 --- a/include/dt-bindings/clock/sun8i-h3-ccu.h +++ b/include/dt-bindings/clock/sun8i-h3-ccu.h @@ -143,7 +143,7 @@ #define CLK_AVS 110 #define CLK_HDMI 111 #define CLK_HDMI_DDC 112 - +#define CLK_MBUS 113 #define CLK_GPU 114 /* New clocks imported in H5 */ From 762539d6999caa1d9a916a4ce72004977b2433cf Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Tue, 17 Sep 2019 10:18:59 +0200 Subject: [PATCH 100/160] clk: rockchip: Add div50 clock-ids for sdmmc on px30 and nandc EMMC and SDIO already have these clock-ids (still unused) only sdmmc is missing them, so fix that. Signed-off-by: Finley Xiao Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20190917081903.25139-1-heiko@sntech.de --- include/dt-bindings/clock/px30-cru.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/px30-cru.h b/include/dt-bindings/clock/px30-cru.h index 00101479f7c4..5b1416fcde6f 100644 --- a/include/dt-bindings/clock/px30-cru.h +++ b/include/dt-bindings/clock/px30-cru.h @@ -85,6 +85,8 @@ #define SCLK_EMMC_DIV50 83 #define SCLK_DDRCLK 84 #define SCLK_UART1_SRC 85 +#define SCLK_SDMMC_DIV 86 +#define SCLK_SDMMC_DIV50 87 /* dclk gates */ #define DCLK_VOPB 150 From e40781098f56dab52e92b7651d87b38805536d28 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Tue, 17 Sep 2019 10:19:00 +0200 Subject: [PATCH 101/160] clk: rockchip: Add div50 clocks for px30 sdmmc, emmc, sdio and nandc Some IPs, such as NAND, EMMC, SDIO and SDMMC need clock of 50% duty cycle, divfree50 can generate clock of 50% duty cycle even in odd value divisor. Signed-off-by: Finley Xiao Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20190917081903.25139-2-heiko@sntech.de --- drivers/clk/rockchip/clk-px30.c | 44 ++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index 3a501896b280..a973394f3d65 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c @@ -167,6 +167,10 @@ PNAME(mux_uart5_p) = { "clk_uart5_src", "clk_uart5_np5", "clk_uart5_frac" }; PNAME(mux_cif_out_p) = { "xin24m", "dummy_cpll", "npll", "usb480m" }; PNAME(mux_dclk_vopb_p) = { "dclk_vopb_src", "dclk_vopb_frac", "xin24m" }; PNAME(mux_dclk_vopl_p) = { "dclk_vopl_src", "dclk_vopl_frac", "xin24m" }; +PNAME(mux_nandc_p) = { "clk_nandc_div", "clk_nandc_div50" }; +PNAME(mux_sdio_p) = { "clk_sdio_div", "clk_sdio_div50" }; +PNAME(mux_emmc_p) = { "clk_emmc_div", "clk_emmc_div50" }; +PNAME(mux_sdmmc_p) = { "clk_sdmmc_div", "clk_sdmmc_div50" }; PNAME(mux_gmac_p) = { "clk_gmac_src", "gmac_clkin" }; PNAME(mux_gmac_rmii_sel_p) = { "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx_div2" }; PNAME(mux_rtc32k_pmu_p) = { "xin32k", "pmu_pvtm_32k", "clk_rtc32k_frac", }; @@ -460,16 +464,40 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { /* PD_MMC_NAND */ GATE(HCLK_MMC_NAND, "hclk_mmc_nand", "hclk_peri_pre", 0, PX30_CLKGATE_CON(6), 0, GFLAGS), - COMPOSITE(SCLK_NANDC, "clk_nandc", mux_gpll_cpll_npll_p, 0, + COMPOSITE(SCLK_NANDC_DIV, "clk_nandc_div", mux_gpll_cpll_npll_p, 0, PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, + PX30_CLKGATE_CON(5), 11, GFLAGS), + COMPOSITE(SCLK_NANDC_DIV50, "clk_nandc_div50", mux_gpll_cpll_npll_p, 0, + PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 8, 5, DFLAGS, + PX30_CLKGATE_CON(5), 12, GFLAGS), + COMPOSITE_NODIV(SCLK_NANDC, "clk_nandc", mux_nandc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(15), 15, 1, MFLAGS, PX30_CLKGATE_CON(5), 13, GFLAGS), - COMPOSITE(SCLK_SDIO, "clk_sdio", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_SDIO_DIV, "clk_sdio_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(18), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 1, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_SDIO_DIV50, "clk_sdio_div50", + mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(18), 14, 2, MFLAGS, + PX30_CLKSEL_CON(19), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 2, GFLAGS), + COMPOSITE_NODIV(SCLK_SDIO, "clk_sdio", mux_sdio_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(19), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 3, GFLAGS), - COMPOSITE(SCLK_EMMC, "clk_emmc", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_EMMC_DIV, "clk_emmc_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(20), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_EMMC_DIV50, "clk_emmc_div50", mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(20), 14, 2, MFLAGS, + PX30_CLKSEL_CON(21), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 5, GFLAGS), + COMPOSITE_NODIV(SCLK_EMMC, "clk_emmc", mux_emmc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(21), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(SCLK_SFC, "clk_sfc", mux_gpll_cpll_p, 0, @@ -494,8 +522,16 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { /* PD_SDCARD */ GATE(0, "hclk_sdmmc_pre", "hclk_peri_pre", 0, PX30_CLKGATE_CON(6), 12, GFLAGS), - COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_SDMMC_DIV, "clk_sdmmc_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(16), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 13, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_SDMMC_DIV50, "clk_sdmmc_div50", mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(16), 14, 2, MFLAGS, + PX30_CLKSEL_CON(17), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 14, GFLAGS), + COMPOSITE_NODIV(SCLK_SDMMC, "clk_sdmmc", mux_sdmmc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(17), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 15, GFLAGS), /* PD_USB */ From 7990660f36bea5fc2d610e0b0b73dd57ce1682b0 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 17 Sep 2019 10:19:01 +0200 Subject: [PATCH 102/160] clk: rockchip: move px30 critical clocks to correct clock controller The clocks in the px30 critical clock section are from the regular cru not the pmucru, so move them to the correct place. Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20190917081903.25139-3-heiko@sntech.de --- drivers/clk/rockchip/clk-px30.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index a973394f3d65..5c77da1e3abc 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c @@ -976,7 +976,7 @@ static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = { GATE(0, "pclk_cru_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 8, GFLAGS), }; -static const char *const px30_pmucru_critical_clocks[] __initconst = { +static const char *const px30_cru_critical_clocks[] __initconst = { "aclk_bus_pre", "pclk_bus_pre", "hclk_bus_pre", @@ -1021,6 +1021,9 @@ static void __init px30_clk_init(struct device_node *np) &px30_cpuclk_data, px30_cpuclk_rates, ARRAY_SIZE(px30_cpuclk_rates)); + rockchip_clk_protect_critical(px30_cru_critical_clocks, + ARRAY_SIZE(px30_cru_critical_clocks)); + rockchip_register_softrst(np, 12, reg_base + PX30_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); @@ -1053,9 +1056,6 @@ static void __init px30_pmu_clk_init(struct device_node *np) rockchip_clk_register_branches(ctx, px30_clk_pmu_branches, ARRAY_SIZE(px30_clk_pmu_branches)); - rockchip_clk_protect_critical(px30_pmucru_critical_clocks, - ARRAY_SIZE(px30_pmucru_critical_clocks)); - rockchip_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(px30_cru_pmu, "rockchip,px30-pmucru", px30_pmu_clk_init); From 8a88550fe7bb9c3cf051ceb3b130b1014fd5dcb4 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 17 Sep 2019 10:19:02 +0200 Subject: [PATCH 103/160] clk: rockchip: add video-related niu clocks as critical on px30 Video-In and -Out interconnect clocks need to stay on all the time for the peripheral to work and we do not model the actual interconnect at this point. So mark them as critical for now. Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20190917081903.25139-4-heiko@sntech.de --- drivers/clk/rockchip/clk-px30.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index 5c77da1e3abc..7a8bc416c947 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c @@ -803,25 +803,25 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { GATE(0, "pclk_cpu_hoost", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 7, GFLAGS), /* PD_VI */ - GATE(0, "aclk_vi_niu", "aclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 15, GFLAGS), + GATE(0, "aclk_vi_niu", "aclk_vi_pre", 0, PX30_CLKGATE_CON(4), 15, GFLAGS), GATE(ACLK_CIF, "aclk_cif", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 1, GFLAGS), GATE(ACLK_ISP, "aclk_isp", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 3, GFLAGS), - GATE(0, "hclk_vi_niu", "hclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 0, GFLAGS), + GATE(0, "hclk_vi_niu", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 0, GFLAGS), GATE(HCLK_CIF, "hclk_cif", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 2, GFLAGS), GATE(HCLK_ISP, "hclk_isp", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 4, GFLAGS), /* PD_VO */ - GATE(0, "aclk_vo_niu", "aclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 0, GFLAGS), + GATE(0, "aclk_vo_niu", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 0, GFLAGS), GATE(ACLK_VOPB, "aclk_vopb", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 3, GFLAGS), GATE(ACLK_RGA, "aclk_rga", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 7, GFLAGS), GATE(ACLK_VOPL, "aclk_vopl", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 5, GFLAGS), - GATE(0, "hclk_vo_niu", "hclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 1, GFLAGS), + GATE(0, "hclk_vo_niu", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 1, GFLAGS), GATE(HCLK_VOPB, "hclk_vopb", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 4, GFLAGS), GATE(HCLK_RGA, "hclk_rga", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 8, GFLAGS), GATE(HCLK_VOPL, "hclk_vopl", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 6, GFLAGS), - GATE(0, "pclk_vo_niu", "pclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 2, GFLAGS), + GATE(0, "pclk_vo_niu", "pclk_vo_pre", 0, PX30_CLKGATE_CON(3), 2, GFLAGS), GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vo_pre", 0, PX30_CLKGATE_CON(3), 9, GFLAGS), /* PD_BUS */ @@ -986,6 +986,11 @@ static const char *const px30_cru_critical_clocks[] __initconst = { "pclk_top_pre", "pclk_pmu_pre", "hclk_usb_niu", + "pclk_vo_niu", + "aclk_vo_niu", + "hclk_vo_niu", + "aclk_vi_niu", + "hclk_vi_niu", "pll_npll", "usb480m", "clk_uart2", From 3b0b4ebfd761943179fe03b107f66c72c3b5c8d4 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 17 Sep 2019 10:19:03 +0200 Subject: [PATCH 104/160] clk: rockchip: protect the pclk_usb_grf as critical on px30 Make this clock a real critical clock, so that writes to the usbphy grf always succeed. Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20190917081903.25139-5-heiko@sntech.de --- drivers/clk/rockchip/clk-px30.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index 7a8bc416c947..6fb9c98b7d24 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c @@ -799,7 +799,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { GATE(0, "pclk_ddrphy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 3, GFLAGS), GATE(PCLK_MIPIDSIPHY, "pclk_mipidsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 4, GFLAGS), GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 5, GFLAGS), - GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 6, GFLAGS), + GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 6, GFLAGS), GATE(0, "pclk_cpu_hoost", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 7, GFLAGS), /* PD_VI */ @@ -995,6 +995,7 @@ static const char *const px30_cru_critical_clocks[] __initconst = { "usb480m", "clk_uart2", "pclk_uart2", + "pclk_usb_grf", }; static void __init px30_clk_init(struct device_node *np) From 6cdef2738db031bfd06e3bc1c7d3c8cd16846d9e Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 11 Oct 2019 18:59:28 +0530 Subject: [PATCH 105/160] clk: qcom: Add Q6SSTOP clock controller for QCS404 Add support for the Q6SSTOP clock control used on qcs404 based devices. This would allow wcss remoteproc driver to control the required WCSS Q6SSTOP clock/reset controls to bring the subsystem out of reset and shutdown the WCSS Q6DSP. Signed-off-by: Govind Singh Link: https://lkml.kernel.org/r/20191011132928.9388-3-govinds@codeaurora.org [sboyd@kernel.org: Sort makefile] Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/q6sstop-qcs404.c | 223 ++++++++++++++++++ .../dt-bindings/clock/qcom,q6sstopcc-qcs404.h | 18 ++ 4 files changed, 250 insertions(+) create mode 100644 drivers/clk/qcom/q6sstop-qcs404.c create mode 100644 include/dt-bindings/clock/qcom,q6sstopcc-qcs404.h diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 32dbb4f09492..5e2ef37168f7 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -248,6 +248,14 @@ config QCS_TURING_404 Support for the Turing Clock Controller on QCS404, provides clocks and resets for the Turing subsystem. +config QCS_Q6SSTOP_404 + tristate "QCS404 Q6SSTOP Clock Controller" + select QCS_GCC_404 + help + Support for the Q6SSTOP clock controller on QCS404 devices. + Say Y if you want to use the Q6SSTOP branch clocks of the WCSS clock + controller to reset the Q6SSTOP subsystem. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 4a813b4055d0..5ba05e2066c2 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o +obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o diff --git a/drivers/clk/qcom/q6sstop-qcs404.c b/drivers/clk/qcom/q6sstop-qcs404.c new file mode 100644 index 000000000000..723f932fbf7d --- /dev/null +++ b/drivers/clk/qcom/q6sstop-qcs404.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-regmap.h" +#include "clk-branch.h" +#include "common.h" +#include "reset.h" + +static struct clk_branch lcc_ahbfabric_cbc_clk = { + .halt_reg = 0x1b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_ahbfabric_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_ahbs_cbc_clk = { + .halt_reg = 0x22000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x22000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_ahbs_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_tcm_slave_cbc_clk = { + .halt_reg = 0x1c000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x1c000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_tcm_slave_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_ahbm_cbc_clk = { + .halt_reg = 0x22004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x22004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_ahbm_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_axim_cbc_clk = { + .halt_reg = 0x1c004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x1c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_axim_cbc_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch lcc_q6ss_bcr_sleep_clk = { + .halt_reg = 0x6004, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x6004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "lcc_q6ss_bcr_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* TCSR clock */ +static struct clk_branch tcsr_lcc_csr_cbcr_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "tcsr_lcc_csr_cbcr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct regmap_config q6sstop_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +static struct clk_regmap *q6sstop_qcs404_clocks[] = { + [LCC_AHBFABRIC_CBC_CLK] = &lcc_ahbfabric_cbc_clk.clkr, + [LCC_Q6SS_AHBS_CBC_CLK] = &lcc_q6ss_ahbs_cbc_clk.clkr, + [LCC_Q6SS_TCM_SLAVE_CBC_CLK] = &lcc_q6ss_tcm_slave_cbc_clk.clkr, + [LCC_Q6SS_AHBM_CBC_CLK] = &lcc_q6ss_ahbm_cbc_clk.clkr, + [LCC_Q6SS_AXIM_CBC_CLK] = &lcc_q6ss_axim_cbc_clk.clkr, + [LCC_Q6SS_BCR_SLEEP_CLK] = &lcc_q6ss_bcr_sleep_clk.clkr, +}; + +static const struct qcom_reset_map q6sstop_qcs404_resets[] = { + [Q6SSTOP_BCR_RESET] = { 0x6000 }, +}; + +static const struct qcom_cc_desc q6sstop_qcs404_desc = { + .config = &q6sstop_regmap_config, + .clks = q6sstop_qcs404_clocks, + .num_clks = ARRAY_SIZE(q6sstop_qcs404_clocks), + .resets = q6sstop_qcs404_resets, + .num_resets = ARRAY_SIZE(q6sstop_qcs404_resets), +}; + +static struct clk_regmap *tcsr_qcs404_clocks[] = { + [TCSR_Q6SS_LCC_CBCR_CLK] = &tcsr_lcc_csr_cbcr_clk.clkr, +}; + +static const struct qcom_cc_desc tcsr_qcs404_desc = { + .config = &q6sstop_regmap_config, + .clks = tcsr_qcs404_clocks, + .num_clks = ARRAY_SIZE(tcsr_qcs404_clocks), +}; + +static const struct of_device_id q6sstopcc_qcs404_match_table[] = { + { .compatible = "qcom,qcs404-q6sstopcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, q6sstopcc_qcs404_match_table); + +static int q6sstopcc_qcs404_probe(struct platform_device *pdev) +{ + const struct qcom_cc_desc *desc; + int ret; + + pm_runtime_enable(&pdev->dev); + ret = pm_clk_create(&pdev->dev); + if (ret) + goto disable_pm_runtime; + + ret = pm_clk_add(&pdev->dev, NULL); + if (ret < 0) { + dev_err(&pdev->dev, "failed to acquire iface clock\n"); + goto destroy_pm_clk; + } + + q6sstop_regmap_config.name = "q6sstop_tcsr"; + desc = &tcsr_qcs404_desc; + + ret = qcom_cc_probe_by_index(pdev, 1, desc); + if (ret) + goto destroy_pm_clk; + + q6sstop_regmap_config.name = "q6sstop_cc"; + desc = &q6sstop_qcs404_desc; + + ret = qcom_cc_probe_by_index(pdev, 0, desc); + if (ret) + goto destroy_pm_clk; + + return 0; + +destroy_pm_clk: + pm_clk_destroy(&pdev->dev); + +disable_pm_runtime: + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static int q6sstopcc_qcs404_remove(struct platform_device *pdev) +{ + pm_clk_destroy(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static const struct dev_pm_ops q6sstopcc_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static struct platform_driver q6sstopcc_qcs404_driver = { + .probe = q6sstopcc_qcs404_probe, + .remove = q6sstopcc_qcs404_remove, + .driver = { + .name = "qcs404-q6sstopcc", + .of_match_table = q6sstopcc_qcs404_match_table, + .pm = &q6sstopcc_pm_ops, + }, +}; + +module_platform_driver(q6sstopcc_qcs404_driver); + +MODULE_DESCRIPTION("QTI QCS404 Q6SSTOP Clock Controller Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/clock/qcom,q6sstopcc-qcs404.h b/include/dt-bindings/clock/qcom,q6sstopcc-qcs404.h new file mode 100644 index 000000000000..c6f5290f0914 --- /dev/null +++ b/include/dt-bindings/clock/qcom,q6sstopcc-qcs404.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_Q6SSTOP_QCS404_H +#define _DT_BINDINGS_CLK_Q6SSTOP_QCS404_H + +#define LCC_AHBFABRIC_CBC_CLK 0 +#define LCC_Q6SS_AHBS_CBC_CLK 1 +#define LCC_Q6SS_TCM_SLAVE_CBC_CLK 2 +#define LCC_Q6SS_AHBM_CBC_CLK 3 +#define LCC_Q6SS_AXIM_CBC_CLK 4 +#define LCC_Q6SS_BCR_SLEEP_CLK 5 +#define TCSR_Q6SS_LCC_CBCR_CLK 6 + +#define Q6SSTOP_BCR_RESET 1 +#endif From 57b2364d0ece3e38cd80ad0d87ff4b7c73ec474f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 25 Oct 2019 17:33:32 +0800 Subject: [PATCH 106/160] clk: qcom: remove unneeded semicolon remove unneeded semicolon. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191025093332.27592-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rcg2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index b98b81ef43a1..99c4bfa5365f 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -206,7 +206,7 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, break; default: return -EINVAL; - }; + } if (!f) return -EINVAL; @@ -319,7 +319,7 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate, break; default: return -EINVAL; - }; + } if (!f) return -EINVAL; From 1a1c78217a779eadc6ef75d0dfb5f33088c6b481 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 14 Oct 2019 15:53:04 +0530 Subject: [PATCH 107/160] clk: qcom: rcg: update the DFS macro for RCG Update the init data name for each of the dynamic frequency switch controlled clock associated with the RCG clock name, so that it can be generated as per the hardware plan. Thus update the macro accordingly. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/20191014102308.27441-2-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rcg.h | 2 +- drivers/clk/qcom/gcc-sdm845.c | 96 +++++++++++++++++------------------ 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index c25b57c3cbc8..78358b81d249 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -168,7 +168,7 @@ struct clk_rcg_dfs_data { }; #define DEFINE_RCG_DFS(r) \ - { .rcg = &r##_src, .init = &r##_init } + { .rcg = &r, .init = &r##_init } extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, const struct clk_rcg_dfs_data *rcgs, diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index 95be125c3bdd..d2142fe46a8e 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -408,7 +408,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { { } }; -static struct clk_init_data gcc_qupv3_wrap0_s0_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -421,10 +421,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s1_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -437,10 +437,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s2_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -453,10 +453,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s3_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -469,10 +469,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s4_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -485,10 +485,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s5_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -501,10 +501,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s6_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { .name = "gcc_qupv3_wrap0_s6_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -517,10 +517,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap0_s7_clk_init = { +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { .name = "gcc_qupv3_wrap0_s7_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -533,10 +533,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s0_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { .name = "gcc_qupv3_wrap1_s0_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -549,10 +549,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s1_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { .name = "gcc_qupv3_wrap1_s1_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -565,10 +565,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s2_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { .name = "gcc_qupv3_wrap1_s2_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -581,10 +581,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s3_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { .name = "gcc_qupv3_wrap1_s3_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -597,10 +597,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s4_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { .name = "gcc_qupv3_wrap1_s4_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -613,10 +613,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s5_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { .name = "gcc_qupv3_wrap1_s5_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -629,10 +629,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s6_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { .name = "gcc_qupv3_wrap1_s6_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -645,10 +645,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init, }; -static struct clk_init_data gcc_qupv3_wrap1_s7_clk_init = { +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { .name = "gcc_qupv3_wrap1_s7_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, @@ -661,7 +661,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, }; static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { @@ -3577,22 +3577,22 @@ static const struct of_device_id gcc_sdm845_match_table[] = { MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table); static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk), - DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), }; static int gcc_sdm845_probe(struct platform_device *pdev) From ffe37ede0a9eb524162c683f48da8558d5323ddb Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 14 Oct 2019 15:53:05 +0530 Subject: [PATCH 108/160] clk: qcom: common: Return NULL from clk_hw OF provider Return NULL in the cases where the clk_hw is not registered with the clock provider, but the clock consumer still requests for a clock id. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/20191014102308.27441-3-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 28ddc747d703..caba81d18c70 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -218,7 +218,7 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, return ERR_PTR(-EINVAL); } - return cc->rclks[idx] ? &cc->rclks[idx]->hw : ERR_PTR(-ENOENT); + return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL; } int qcom_cc_really_probe(struct platform_device *pdev, From 9de7269e9703f32f742d8c88211320baaece58bc Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 14 Oct 2019 15:53:06 +0530 Subject: [PATCH 109/160] dt-bindings: clock: Add YAML schemas for the QCOM GCC clock bindings The GCC clock provider have a bunch of generic properties that are needed in a device tree. Add a YAML schemas for those. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/20191014102308.27441-4-tdas@codeaurora.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,gcc.txt | 94 ---------- .../devicetree/bindings/clock/qcom,gcc.yaml | 174 ++++++++++++++++++ 2 files changed, 174 insertions(+), 94 deletions(-) delete mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc.txt create mode 100644 Documentation/devicetree/bindings/clock/qcom,gcc.yaml diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt deleted file mode 100644 index d14362ad4132..000000000000 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ /dev/null @@ -1,94 +0,0 @@ -Qualcomm Global Clock & Reset Controller Binding ------------------------------------------------- - -Required properties : -- compatible : shall contain only one of the following: - - "qcom,gcc-apq8064" - "qcom,gcc-apq8084" - "qcom,gcc-ipq8064" - "qcom,gcc-ipq4019" - "qcom,gcc-ipq8074" - "qcom,gcc-msm8660" - "qcom,gcc-msm8916" - "qcom,gcc-msm8960" - "qcom,gcc-msm8974" - "qcom,gcc-msm8974pro" - "qcom,gcc-msm8974pro-ac" - "qcom,gcc-msm8994" - "qcom,gcc-msm8996" - "qcom,gcc-msm8998" - "qcom,gcc-mdm9615" - "qcom,gcc-qcs404" - "qcom,gcc-sdm630" - "qcom,gcc-sdm660" - "qcom,gcc-sdm845" - "qcom,gcc-sm8150" - -- reg : shall contain base register location and length -- #clock-cells : shall contain 1 -- #reset-cells : shall contain 1 - -Optional properties : -- #power-domain-cells : shall contain 1 -- Qualcomm TSENS (thermal sensor device) on some devices can -be part of GCC and hence the TSENS properties can also be -part of the GCC/clock-controller node. -For more details on the TSENS properties please refer -Documentation/devicetree/bindings/thermal/qcom-tsens.txt -- protected-clocks : Protected clock specifier list as per common clock - binding. - -For SM8150 only: - - clocks: a list of phandles and clock-specifier pairs, - one for each entry in clock-names. - - clock-names: "bi_tcxo" (required) - "sleep_clk" (optional) - "aud_ref_clock" (optional) - -Example: - clock-controller@900000 { - compatible = "qcom,gcc-msm8960"; - reg = <0x900000 0x4000>; - #clock-cells = <1>; - #reset-cells = <1>; - #power-domain-cells = <1>; - }; - -Example of GCC with TSENS properties: - clock-controller@900000 { - compatible = "qcom,gcc-apq8064"; - reg = <0x00900000 0x4000>; - nvmem-cells = <&tsens_calib>, <&tsens_backup>; - nvmem-cell-names = "calib", "calib_backup"; - #clock-cells = <1>; - #reset-cells = <1>; - #thermal-sensor-cells = <1>; - }; - -Example of GCC with protected-clocks properties: - clock-controller@100000 { - compatible = "qcom,gcc-sdm845"; - reg = <0x100000 0x1f0000>; - #clock-cells = <1>; - #reset-cells = <1>; - #power-domain-cells = <1>; - protected-clocks = , - , - , - , - ; - }; - -Example of GCC with clocks - gcc: clock-controller@100000 { - compatible = "qcom,gcc-sm8150"; - reg = <0x00100000 0x1f0000>; - #clock-cells = <1>; - #reset-cells = <1>; - #power-domain-cells = <1>; - clock-names = "bi_tcxo", - "sleep_clk"; - clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, - <&sleep_clk>; - }; diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml new file mode 100644 index 000000000000..b3ef1e24e91a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml @@ -0,0 +1,174 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/bindings/clock/qcom,gcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller Binding + +maintainers: + - Stephen Boyd + - Taniya Das + +description: | + Qualcomm global clock control module which supports the clocks, resets and + power domains. + +properties: + compatible : + enum: + - qcom,gcc-apq8064 + - qcom,gcc-apq8084 + - qcom,gcc-ipq8064 + - qcom,gcc-ipq4019 + - qcom,gcc-ipq8074 + - qcom,gcc-msm8660 + - qcom,gcc-msm8916 + - qcom,gcc-msm8960 + - qcom,gcc-msm8974 + - qcom,gcc-msm8974pro + - qcom,gcc-msm8974pro-ac + - qcom,gcc-msm8994 + - qcom,gcc-msm8996 + - qcom,gcc-msm8998 + - qcom,gcc-mdm9615 + - qcom,gcc-qcs404 + - qcom,gcc-sdm630 + - qcom,gcc-sdm660 + - qcom,gcc-sdm845 + - qcom,gcc-sm8150 + + clocks: + minItems: 1 + maxItems: 3 + items: + - description: Board XO source + - description: Board active XO source + - description: Sleep clock source + + clock-names: + minItems: 1 + maxItems: 3 + items: + - const: bi_tcxo + - const: bi_tcxo_ao + - const: sleep_clk + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + + nvmem-cells: + minItems: 1 + maxItems: 2 + description: + Qualcomm TSENS (thermal sensor device) on some devices can + be part of GCC and hence the TSENS properties can also be part + of the GCC/clock-controller node. + For more details on the TSENS properties please refer + Documentation/devicetree/bindings/thermal/qcom-tsens.txt + + nvmem-cell-names: + minItems: 1 + maxItems: 2 + description: + Names for each nvmem-cells specified. + items: + - const: calib + - const: calib_backup + + 'thermal-sensor-cells': + const: 1 + + protected-clocks: + description: + Protected clock specifier list as per common clock binding + +required: + - compatible + - reg + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +if: + properties: + compatible: + contains: + const: qcom,gcc-apq8064 + +then: + required: + - nvmem-cells + - nvmem-cell-names + - '#thermal-sensor-cells' + +else: + if: + properties: + compatible: + contains: + enum: + - qcom,gcc-sm8150 + then: + required: + - clocks + - clock-names + + +examples: + # Example for GCC for MSM8960: + - | + clock-controller@900000 { + compatible = "qcom,gcc-msm8960"; + reg = <0x900000 0x4000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + + # Example of GCC with TSENS properties: + - | + clock-controller@900000 { + compatible = "qcom,gcc-apq8064"; + reg = <0x00900000 0x4000>; + nvmem-cells = <&tsens_calib>, <&tsens_backup>; + nvmem-cell-names = "calib", "calib_backup"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + #thermal-sensor-cells = <1>; + }; + + # Example of GCC with protected-clocks properties: + - | + clock-controller@100000 { + compatible = "qcom,gcc-sdm845"; + reg = <0x100000 0x1f0000>; + protected-clocks = <187>, <188>, <189>, <190>, <191>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + # Example of GCC with clock node properties for SM8150: + - | + clock-controller@100000 { + compatible = "qcom,gcc-sm8150"; + reg = <0x00100000 0x1f0000>; + clocks = <&rpmhcc 0>, <&rpmhcc 1>, <&sleep_clk>; + clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... From 8b9e0562f330ac20f0e77c0feb38cc7953274d7f Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 14 Oct 2019 15:53:07 +0530 Subject: [PATCH 110/160] dt-bindings: clock: Add sc7180 GCC clock binding Add device tree bindings for global clock subsystem clock controller for Qualcomm Technology Inc's SC7180 SoCs. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/20191014102308.27441-5-tdas@codeaurora.org Reviewed-by: Rob Herring [sboyd@kernel.org: Reword subject to make sc7180 specific, sort compatible] Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,gcc.yaml | 14 ++ include/dt-bindings/clock/qcom,gcc-sc7180.h | 155 ++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,gcc-sc7180.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml index b3ef1e24e91a..e73a56fb60ca 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml @@ -33,6 +33,7 @@ properties: - qcom,gcc-msm8998 - qcom,gcc-mdm9615 - qcom,gcc-qcs404 + - qcom,gcc-sc7180 - qcom,gcc-sdm630 - qcom,gcc-sdm660 - qcom,gcc-sdm845 @@ -118,6 +119,7 @@ else: contains: enum: - qcom,gcc-sm8150 + - qcom,gcc-sc7180 then: required: - clocks @@ -171,4 +173,16 @@ examples: #reset-cells = <1>; #power-domain-cells = <1>; }; + + # Example of GCC with clock nodes properties for SC7180: + - | + clock-controller@100000 { + compatible = "qcom,gcc-sc7180"; + reg = <0x100000 0x1f0000>; + clocks = <&rpmhcc 0>, <&rpmhcc 1>; + clock-names = "bi_tcxo", "bi_tcxo_ao"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; ... diff --git a/include/dt-bindings/clock/qcom,gcc-sc7180.h b/include/dt-bindings/clock/qcom,gcc-sc7180.h new file mode 100644 index 000000000000..e8029b2e92d7 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sc7180.h @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SC7180_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SC7180_H + +/* GCC clocks */ +#define GCC_GPLL0_MAIN_DIV_CDIV 0 +#define GPLL0 1 +#define GPLL0_OUT_EVEN 2 +#define GPLL1 3 +#define GPLL4 4 +#define GPLL6 5 +#define GPLL7 6 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 7 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK 8 +#define GCC_BOOT_ROM_AHB_CLK 9 +#define GCC_CAMERA_AHB_CLK 10 +#define GCC_CAMERA_HF_AXI_CLK 11 +#define GCC_CAMERA_THROTTLE_HF_AXI_CLK 12 +#define GCC_CAMERA_XO_CLK 13 +#define GCC_CE1_AHB_CLK 14 +#define GCC_CE1_AXI_CLK 15 +#define GCC_CE1_CLK 16 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 17 +#define GCC_CPUSS_AHB_CLK 18 +#define GCC_CPUSS_AHB_CLK_SRC 19 +#define GCC_CPUSS_GNOC_CLK 20 +#define GCC_CPUSS_RBCPR_CLK 21 +#define GCC_DDRSS_GPU_AXI_CLK 22 +#define GCC_DISP_AHB_CLK 23 +#define GCC_DISP_GPLL0_CLK_SRC 24 +#define GCC_DISP_GPLL0_DIV_CLK_SRC 25 +#define GCC_DISP_HF_AXI_CLK 26 +#define GCC_DISP_THROTTLE_HF_AXI_CLK 27 +#define GCC_DISP_XO_CLK 28 +#define GCC_GP1_CLK 29 +#define GCC_GP1_CLK_SRC 30 +#define GCC_GP2_CLK 31 +#define GCC_GP2_CLK_SRC 32 +#define GCC_GP3_CLK 33 +#define GCC_GP3_CLK_SRC 34 +#define GCC_GPU_CFG_AHB_CLK 35 +#define GCC_GPU_GPLL0_CLK_SRC 36 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 37 +#define GCC_GPU_MEMNOC_GFX_CLK 38 +#define GCC_GPU_SNOC_DVM_GFX_CLK 39 +#define GCC_NPU_AXI_CLK 40 +#define GCC_NPU_BWMON_AXI_CLK 41 +#define GCC_NPU_BWMON_DMA_CFG_AHB_CLK 42 +#define GCC_NPU_BWMON_DSP_CFG_AHB_CLK 43 +#define GCC_NPU_CFG_AHB_CLK 44 +#define GCC_NPU_DMA_CLK 45 +#define GCC_NPU_GPLL0_CLK_SRC 46 +#define GCC_NPU_GPLL0_DIV_CLK_SRC 47 +#define GCC_PDM2_CLK 48 +#define GCC_PDM2_CLK_SRC 49 +#define GCC_PDM_AHB_CLK 50 +#define GCC_PDM_XO4_CLK 51 +#define GCC_PRNG_AHB_CLK 52 +#define GCC_QSPI_CNOC_PERIPH_AHB_CLK 53 +#define GCC_QSPI_CORE_CLK 54 +#define GCC_QSPI_CORE_CLK_SRC 55 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 56 +#define GCC_QUPV3_WRAP0_CORE_CLK 57 +#define GCC_QUPV3_WRAP0_S0_CLK 58 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 59 +#define GCC_QUPV3_WRAP0_S1_CLK 60 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 61 +#define GCC_QUPV3_WRAP0_S2_CLK 62 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 63 +#define GCC_QUPV3_WRAP0_S3_CLK 64 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 65 +#define GCC_QUPV3_WRAP0_S4_CLK 66 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 67 +#define GCC_QUPV3_WRAP0_S5_CLK 68 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 69 +#define GCC_QUPV3_WRAP1_CORE_2X_CLK 70 +#define GCC_QUPV3_WRAP1_CORE_CLK 71 +#define GCC_QUPV3_WRAP1_S0_CLK 72 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 73 +#define GCC_QUPV3_WRAP1_S1_CLK 74 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 75 +#define GCC_QUPV3_WRAP1_S2_CLK 76 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 77 +#define GCC_QUPV3_WRAP1_S3_CLK 78 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 79 +#define GCC_QUPV3_WRAP1_S4_CLK 80 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 81 +#define GCC_QUPV3_WRAP1_S5_CLK 82 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 83 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 84 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 85 +#define GCC_QUPV3_WRAP_1_M_AHB_CLK 86 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 87 +#define GCC_SDCC1_AHB_CLK 88 +#define GCC_SDCC1_APPS_CLK 89 +#define GCC_SDCC1_APPS_CLK_SRC 90 +#define GCC_SDCC1_ICE_CORE_CLK 91 +#define GCC_SDCC1_ICE_CORE_CLK_SRC 92 +#define GCC_SDCC2_AHB_CLK 93 +#define GCC_SDCC2_APPS_CLK 94 +#define GCC_SDCC2_APPS_CLK_SRC 95 +#define GCC_SYS_NOC_CPUSS_AHB_CLK 96 +#define GCC_UFS_MEM_CLKREF_CLK 97 +#define GCC_UFS_PHY_AHB_CLK 98 +#define GCC_UFS_PHY_AXI_CLK 99 +#define GCC_UFS_PHY_AXI_CLK_SRC 100 +#define GCC_UFS_PHY_ICE_CORE_CLK 101 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 102 +#define GCC_UFS_PHY_PHY_AUX_CLK 103 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 104 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 105 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 106 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 107 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 108 +#define GCC_USB30_PRIM_MASTER_CLK 109 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 110 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 111 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 112 +#define GCC_USB30_PRIM_SLEEP_CLK 113 +#define GCC_USB3_PRIM_CLKREF_CLK 114 +#define GCC_USB3_PRIM_PHY_AUX_CLK 115 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 116 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 117 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 118 +#define GCC_USB_PHY_CFG_AHB2PHY_CLK 119 +#define GCC_VIDEO_AHB_CLK 120 +#define GCC_VIDEO_AXI_CLK 121 +#define GCC_VIDEO_GPLL0_DIV_CLK_SRC 122 +#define GCC_VIDEO_THROTTLE_AXI_CLK 123 +#define GCC_VIDEO_XO_CLK 124 + +/* GCC resets */ +#define GCC_QUSB2PHY_PRIM_BCR 0 +#define GCC_QUSB2PHY_SEC_BCR 1 +#define GCC_UFS_PHY_BCR 2 +#define GCC_USB30_PRIM_BCR 3 +#define GCC_USB3_DP_PHY_PRIM_BCR 4 +#define GCC_USB3_DP_PHY_SEC_BCR 5 +#define GCC_USB3_PHY_PRIM_BCR 6 +#define GCC_USB3_PHY_SEC_BCR 7 +#define GCC_USB3PHY_PHY_PRIM_BCR 8 +#define GCC_USB3PHY_PHY_SEC_BCR 9 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 10 + +/* GCC GDSCRs */ +#define UFS_PHY_GDSC 0 +#define USB30_PRIM_GDSC 1 +#define HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC 2 +#define HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC 3 + +#endif From 17269568f72670e97b19b14897137a8f5c21c09b Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 14 Oct 2019 15:53:08 +0530 Subject: [PATCH 111/160] clk: qcom: Add Global Clock controller (GCC) driver for SC7180 Add support for the global clock controller found on SC7180 based devices. This should allow most non-multimedia device drivers to probe and control their clocks. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/20191014102308.27441-6-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-sc7180.c | 2450 +++++++++++++++++++++++++++++++++ 3 files changed, 2460 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sc7180.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 5e2ef37168f7..5d8cc03457ca 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -227,6 +227,15 @@ config QCS_GCC_404 Say Y if you want to use multimedia devices or peripheral devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. +config SC_GCC_7180 + tristate "SC7180 Global Clock Controller" + select QCOM_GDSC + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on SC7180 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, UFS, SDCC, etc. + config SDM_CAMCC_845 tristate "SDM845 Camera Clock Controller" select SDM_GCC_845 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 5ba05e2066c2..80a30976abe8 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o +obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o diff --git a/drivers/clk/qcom/gcc-sc7180.c b/drivers/clk/qcom/gcc-sc7180.c new file mode 100644 index 000000000000..38424e63bcae --- /dev/null +++ b/drivers/clk/qcom/gcc-sc7180.c @@ -0,0 +1,2450 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_EVEN, + P_GPLL0_OUT_MAIN, + P_GPLL1_OUT_MAIN, + P_GPLL4_OUT_MAIN, + P_GPLL6_OUT_MAIN, + P_GPLL7_OUT_MAIN, + P_SLEEP_CLK, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_even", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_fixed_factor gcc_pll0_main_div_cdiv = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gcc_pll0_main_div_cdiv", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll1 = { + .offset = 0x01000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x76000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll6 = { + .offset = 0x13000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gpll6", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll7 = { + .offset = 0x27000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll7", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct clk_parent_data gcc_parent_data_0_ao[] = { + { .fw_name = "bi_tcxo_ao", .name = "bi_tcxo_ao" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_MAIN, 2 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL1_OUT_MAIN, 4 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll1.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "sleep_clk", .name = "sleep_clk" }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll7.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "sleep_clk", .name = "sleep_clk" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, +}; + +static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { + .cmd_rcgr = 0x48014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk_src", + .parent_data = gcc_parent_data_0_ao, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(200000000, P_GPLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_EVEN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = { + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qspi_core_clk_src = { + .cmd_rcgr = 0x4b00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_qspi_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(102400000, P_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_EVEN, 2.5, 0, 0), + F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x17034, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x17164, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x17294, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x173c4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x174f4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x17624, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18018, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { + .cmd_rcgr = 0x18278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x183a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x184d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { + F(144000, P_BI_TCXO, 16, 3, 25), + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(20000000, P_GPLL0_OUT_EVEN, 5, 1, 3), + F(25000000, P_GPLL0_OUT_EVEN, 6, 1, 2), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x12028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x12010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1400c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = 5, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x77048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x77098, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x77060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0xf01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(20000000, P_GPLL0_OUT_EVEN, 15, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0xf034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb3_prim_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0xf060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_usb3_prim_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x82024, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x82024, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x82024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0x8201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_ahb_clk = { + .halt_reg = 0xb008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0xb020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_throttle_hf_axi_clk = { + .halt_reg = 0xb080, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb080, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_throttle_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_xo_clk = { + .halt_reg = 0xb02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_ahb_clk = { + .halt_reg = 0x4100c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x4100c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_axi_clk = { + .halt_reg = 0x41008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_clk = { + .halt_reg = 0x41004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x502c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x502c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +/* For CPUSS functionality the AHB clock needs to be left enabled */ +static struct clk_branch gcc_cpuss_ahb_clk = { + .halt_reg = 0x48000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_rbcpr_clk = { + .halt_reg = 0x48008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_rbcpr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_gpu_axi_clk = { + .halt_reg = 0x4452c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4452c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0xb024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_throttle_hf_axi_clk = { + .halt_reg = 0xb084, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb084, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_throttle_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_xo_clk = { + .halt_reg = 0xb030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x7100c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7100c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x71018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_axi_clk = { + .halt_reg = 0x4d008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_axi_clk = { + .halt_reg = 0x73008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x73008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_dma_cfg_ahb_clk = { + .halt_reg = 0x73018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x73018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_dma_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_bwmon_dsp_cfg_ahb_clk = { + .halt_reg = 0x7301c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7301c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_bwmon_dsp_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_cfg_ahb_clk = { + .halt_reg = 0x4d004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_dma_clk = { + .halt_reg = 0x4d1a0, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4d1a0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4d1a0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_dma_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x34004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = { + .halt_reg = 0x4b004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4b004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_cnoc_periph_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_core_clk = { + .halt_reg = 0x4b008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qspi_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x17014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0x1700c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x17030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x17160, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x17290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x173c0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x174f0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x17620, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0x18008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x18014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x18144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(23), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x18274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x183a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x184d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x18604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x17008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { + .halt_reg = 0x1800c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x18010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x18010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x12008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x1200c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x12040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x12040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +/* For CPUSS functionality the SYS NOC clock needs to be left enabled */ +static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { + .halt_reg = 0x4144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_cpuss_ahb_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_mem_clkref_clk = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_mem_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x77014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x77038, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77038, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x77090, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x77094, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77094, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x7701c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x7701c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x77018, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x7708c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7708c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7708c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0xf010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0xf018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0xf014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_clk = { + .halt_reg = 0x8c010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0xf050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0xf054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0xf058, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0xf058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { + .halt_reg = 0x6a004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x6a004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_phy_cfg_ahb2phy_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi_clk = { + .halt_reg = 0xb01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_gpll0_div_clk_src", + .parent_data = &(const struct clk_parent_data){ + .hw = &gcc_pll0_main_div_cdiv.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_throttle_axi_clk = { + .halt_reg = 0xb07c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb07c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_throttle_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_xo_clk = { + .halt_reg = 0xb028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc ufs_phy_gdsc = { + .gdscr = 0x77004, + .pd = { + .name = "ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc usb30_prim_gdsc = { + .gdscr = 0x0f004, + .pd = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { + .gdscr = 0x7d040, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON | VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = { + .gdscr = 0x7d044, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON | VOTABLE, +}; + +static struct gdsc *gcc_sc7180_gdscs[] = { + [UFS_PHY_GDSC] = &ufs_phy_gdsc, + [USB30_PRIM_GDSC] = &usb30_prim_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = + &hlos1_vote_mmnoc_mmu_tbu_sf_gdsc, +}; + + +static struct clk_hw *gcc_sc7180_hws[] = { + [GCC_GPLL0_MAIN_DIV_CDIV] = &gcc_pll0_main_div_cdiv.hw, +}; + +static struct clk_regmap *gcc_sc7180_clocks[] = { + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr, + [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, + [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, + [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, + [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, + [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, + [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, + [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, + [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr, + [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_THROTTLE_HF_AXI_CLK] = &gcc_disp_throttle_hf_axi_clk.clkr, + [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr, + [GCC_NPU_BWMON_AXI_CLK] = &gcc_npu_bwmon_axi_clk.clkr, + [GCC_NPU_BWMON_DMA_CFG_AHB_CLK] = &gcc_npu_bwmon_dma_cfg_ahb_clk.clkr, + [GCC_NPU_BWMON_DSP_CFG_AHB_CLK] = &gcc_npu_bwmon_dsp_cfg_ahb_clk.clkr, + [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr, + [GCC_NPU_DMA_CLK] = &gcc_npu_dma_clk.clkr, + [GCC_NPU_GPLL0_CLK_SRC] = &gcc_npu_gpll0_clk_src.clkr, + [GCC_NPU_GPLL0_DIV_CLK_SRC] = &gcc_npu_gpll0_div_clk_src.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, + [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, + [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, + [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = + &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = + &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, + [GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr, + [GCC_VIDEO_GPLL0_DIV_CLK_SRC] = &gcc_video_gpll0_div_clk_src.clkr, + [GCC_VIDEO_THROTTLE_AXI_CLK] = &gcc_video_throttle_axi_clk.clkr, + [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, + [GPLL6] = &gpll6.clkr, + [GPLL7] = &gpll7.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL1] = &gpll1.clkr, +}; + +static const struct qcom_reset_map gcc_sc7180_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = { 0x26000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x26004 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, +}; + +static struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), +}; + +static const struct regmap_config gcc_sc7180_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x18208c, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sc7180_desc = { + .config = &gcc_sc7180_regmap_config, + .clk_hws = gcc_sc7180_hws, + .num_clk_hws = ARRAY_SIZE(gcc_sc7180_hws), + .clks = gcc_sc7180_clocks, + .num_clks = ARRAY_SIZE(gcc_sc7180_clocks), + .resets = gcc_sc7180_resets, + .num_resets = ARRAY_SIZE(gcc_sc7180_resets), + .gdscs = gcc_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sc7180_gdscs), +}; + +static const struct of_device_id gcc_sc7180_match_table[] = { + { .compatible = "qcom,gcc-sc7180" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sc7180_match_table); + +static int gcc_sc7180_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gcc_sc7180_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * Disable the GPLL0 active input to MM blocks, NPU + * and GPU via MISC registers. + */ + regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); + regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); + regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + + /* + * Keep the clocks always-ON + * GCC_CPUSS_GNOC_CLK, GCC_VIDEO_AHB_CLK, GCC_DISP_AHB_CLK + * GCC_GPU_CFG_AHB_CLK + */ + regmap_update_bits(regmap, 0x48004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); + + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + + return qcom_cc_really_probe(pdev, &gcc_sc7180_desc, regmap); +} + +static struct platform_driver gcc_sc7180_driver = { + .probe = gcc_sc7180_probe, + .driver = { + .name = "gcc-sc7180", + .of_match_table = gcc_sc7180_match_table, + }, +}; + +static int __init gcc_sc7180_init(void) +{ + return platform_driver_register(&gcc_sc7180_driver); +} +core_initcall(gcc_sc7180_init); + +static void __exit gcc_sc7180_exit(void) +{ + platform_driver_unregister(&gcc_sc7180_driver); +} +module_exit(gcc_sc7180_exit); + +MODULE_DESCRIPTION("QTI GCC SC7180 Driver"); +MODULE_LICENSE("GPL v2"); From 681a6ad5c009e53f175db537f79314cbe6c7c816 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 29 Oct 2019 23:18:17 +0530 Subject: [PATCH 112/160] dt-bindings: clock: Add YAML schemas for the QCOM RPMHCC clock bindings The RPMHCC clock provider have a bunch of generic properties that are needed in a device tree. Add a YAML schemas for those. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/1572371299-16774-2-git-send-email-tdas@codeaurora.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../bindings/clock/qcom,rpmh-clk.txt | 27 ----------- .../bindings/clock/qcom,rpmhcc.yaml | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+), 27 deletions(-) delete mode 100644 Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt create mode 100644 Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt b/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt deleted file mode 100644 index 365bbde599b1..000000000000 --- a/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt +++ /dev/null @@ -1,27 +0,0 @@ -Qualcomm Technologies, Inc. RPMh Clocks -------------------------------------------------------- - -Resource Power Manager Hardened (RPMh) manages shared resources on -some Qualcomm Technologies Inc. SoCs. It accepts clock requests from -other hardware subsystems via RSC to control clocks. - -Required properties : -- compatible : must be one of: - "qcom,sdm845-rpmh-clk" - "qcom,sm8150-rpmh-clk" - -- #clock-cells : must contain 1 -- clocks: a list of phandles and clock-specifier pairs, - one for each entry in clock-names. -- clock-names: Parent board clock: "xo". - -Example : - -#include - - &apps_rsc { - rpmhcc: clock-controller { - compatible = "qcom,sdm845-rpmh-clk"; - #clock-cells = <1>; - }; - }; diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml new file mode 100644 index 000000000000..f25d76fc96ba --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/bindings/clock/qcom,rpmhcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. RPMh Clocks Bindings + +maintainers: + - Taniya Das + +description: | + Resource Power Manager Hardened (RPMh) manages shared resources on + some Qualcomm Technologies Inc. SoCs. It accepts clock requests from + other hardware subsystems via RSC to control clocks. + +properties: + compatible: + enum: + - qcom,sdm845-rpmh-clk + - qcom,sm8150-rpmh-clk + + clocks: + maxItems: 1 + + clock-names: + items: + - const: xo + + '#clock-cells': + const: 1 + +required: + - compatible + - '#clock-cells' + +examples: + # Example for GCC for SDM845: The below node should be defined inside + # &apps_rsc node. + - | + #include + rpmhcc: clock-controller { + compatible = "qcom,sdm845-rpmh-clk"; + clocks = <&xo_board>; + clock-names = "xo"; + #clock-cells = <1>; + }; +... From 36b355c84042d0d7d3bedbcdf7b92b3e5f187060 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 29 Oct 2019 23:18:18 +0530 Subject: [PATCH 113/160] dt-bindings: clock: Introduce RPMHCC bindings for SC7180 Add compatible for SC7180 RPMHCC. Signed-off-by: Taniya Das Acked-by: Rob Herring Link: https://lkml.kernel.org/r/1572371299-16774-3-git-send-email-tdas@codeaurora.org [sboyd@kernel.org: Sort compatible list] Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml index f25d76fc96ba..94e2f14eb967 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml @@ -17,6 +17,7 @@ description: | properties: compatible: enum: + - qcom,sc7180-rpmh-clk - qcom,sdm845-rpmh-clk - qcom,sm8150-rpmh-clk From eee28109f871ea43f65cb19f429ed95ddda79343 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 29 Oct 2019 23:18:19 +0530 Subject: [PATCH 114/160] clk: qcom: clk-rpmh: Add support for RPMHCC for SC7180 Add support for clock RPMh driver to vote for ARC and VRM managed clock resources. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/1572371299-16774-4-git-send-email-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rpmh.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 96a36f6ff667..7301c7739f29 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -391,6 +391,24 @@ static const struct clk_rpmh_desc clk_rpmh_sm8150 = { .num_clks = ARRAY_SIZE(sm8150_rpmh_clocks), }; +static struct clk_hw *sc7180_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, + [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw, + [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw, + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, + [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, + [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw, + [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_sc7180 = { + .clks = sc7180_rpmh_clocks, + .num_clks = ARRAY_SIZE(sc7180_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -471,6 +489,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, + { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, { } }; MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); From 95183d381a4445cb5e3edbc678a4b6267e50a738 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Thu, 7 Nov 2019 11:21:36 -0800 Subject: [PATCH 115/160] clk: qcom: Enumerate clocks and reset needed to boot the 8998 modem We need to control five additional clocks and a reset inorder to boot the modem on msm8998. If we can boot the modem, we have a place to run the wlan firmware and get wifi up and running. Signed-off-by: Jeffrey Hugo Link: https://lkml.kernel.org/r/20191107192136.5880-1-jeffrey.l.hugo@gmail.com Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-msm8998.c | 72 ++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-msm8998.h | 6 ++ 2 files changed, 78 insertions(+) diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index 091acd59c1d6..cf31b5d03270 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c @@ -1266,6 +1266,72 @@ static struct clk_branch gcc_bimc_mss_q6_axi_clk = { }, }; +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x8a000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_snoc_axi_clk = { + .halt_reg = 0x8a03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { + .halt_reg = 0x8a004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mnoc_bimc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_gpll0_div_clk_src", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_blsp1_ahb_clk = { .halt_reg = 0x17004, .halt_check = BRANCH_HALT_VOTED, @@ -2832,6 +2898,11 @@ static struct clk_regmap *gcc_msm8998_clocks[] = { [GCC_USB3_CLKREF_CLK] = &gcc_usb3_clkref_clk.clkr, [GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr, [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr, + [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, }; static struct gdsc *gcc_msm8998_gdscs[] = { @@ -2928,6 +2999,7 @@ static const struct qcom_reset_map gcc_msm8998_resets[] = { [GCC_GPU_BCR] = { 0x71000 }, [GCC_SPSS_BCR] = { 0x72000 }, [GCC_OBT_ODT_BCR] = { 0x73000 }, + [GCC_MSS_RESTART] = { 0x79000 }, [GCC_VS_BCR] = { 0x7a000 }, [GCC_MSS_VS_RESET] = { 0x7a100 }, [GCC_GPU_VS_RESET] = { 0x7a104 }, diff --git a/include/dt-bindings/clock/qcom,gcc-msm8998.h b/include/dt-bindings/clock/qcom,gcc-msm8998.h index ab376262fcea..de1d8a1f5966 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8998.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8998.h @@ -177,6 +177,11 @@ #define GCC_UFS_CLKREF_CLK 168 #define GCC_PCIE_CLKREF_CLK 169 #define GCC_RX1_USB2_CLKREF_CLK 170 +#define GCC_MSS_CFG_AHB_CLK 171 +#define GCC_BOOT_ROM_AHB_CLK 172 +#define GCC_MSS_GPLL0_DIV_CLK_SRC 173 +#define GCC_MSS_SNOC_AXI_CLK 174 +#define GCC_MSS_MNOC_BIMC_AXI_CLK 175 #define PCIE_0_GDSC 0 #define UFS_GDSC 1 @@ -290,5 +295,6 @@ #define GCC_MSMPU_BCR 105 #define GCC_QUSB2PHY_PRIM_BCR 106 #define GCC_QUSB2PHY_SEC_BCR 107 +#define GCC_MSS_RESTART 108 #endif From ba1d366de261981c0dd04fac44d2ce3a5eba2eaa Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Thu, 7 Nov 2019 11:06:15 -0800 Subject: [PATCH 116/160] clk: qcom: smd: Add missing pnoc clock When MSM8998 support was added, and analysis was done to determine what clocks would be consumed. That analysis had a flaw, which caused the pnoc to be skipped. The pnoc clock needs to be on to access the uart for the console. The clock is on from boot, but has no consumer votes in the RPM. When we attempt to boot the modem, it causes the RPM to turn off pnoc, which kills our access to the console and causes CPU hangs. We need pnoc to be defined, so that clk_smd_rpm_handoff() will put in an implicit vote for linux and prevent issues when booting modem. Hopefully pnoc can be consumed by the interconnect framework in future so that Linux can rely on explicit votes. Fixes: 6131dc81211c ("clk: qcom: smd: Add support for MSM8998 rpm clocks") Signed-off-by: Jeffrey Hugo Link: https://lkml.kernel.org/r/20191107190615.5656-1-jeffrey.l.hugo@gmail.com Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-smd-rpm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index fef5e8157061..930fa4a4c52a 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -648,6 +648,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { }; /* msm8998 */ +DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); DEFINE_CLK_SMD_RPM(msm8998, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); @@ -670,6 +671,8 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6); static struct clk_smd_rpm *msm8998_clks[] = { + [RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk, [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk, [RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk, [RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk, From efd164b5520afd6fb2883b68e0d408a7de29c491 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Thu, 31 Oct 2019 11:57:15 -0700 Subject: [PATCH 117/160] clk: qcom: Allow constant ratio freq tables for rcg Some RCGs (the gfx_3d_src_clk in msm8998 for example) are basically just some constant ratio from the input across the entire frequency range. It would be great if we could specify the frequency table as a single entry constant ratio instead of a long list, ie: { .src = P_GPUPLL0_OUT_EVEN, .pre_div = 3 }, { } So, lets support that. We need to fix a corner case in qcom_find_freq() where if the freq table is non-null, but has no frequencies, we end up returning an "entry" before the table array, which is bad. Then, we need ignore the freq from the table, and instead base everything on the requested freq. Suggested-by: Stephen Boyd Signed-off-by: Jeffrey Hugo Link: https://lkml.kernel.org/r/20191031185715.15504-1-jeffrey.l.hugo@gmail.com Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rcg2.c | 2 ++ drivers/clk/qcom/common.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 99c4bfa5365f..8f4b9bec2956 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -220,6 +220,8 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, if (clk_flags & CLK_SET_RATE_PARENT) { rate = f->freq; if (f->pre_div) { + if (!rate) + rate = req->rate; rate /= 2; rate *= f->pre_div + 1; } diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index caba81d18c70..60d2a78d1395 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -29,6 +29,9 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate) if (!f) return NULL; + if (!f->freq) + return f; + for (; f->freq; f++) if (rate <= f->freq) return f; From 3f7df5baa2593d86c0dd206c3e63a76fce0efa4b Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Thu, 31 Oct 2019 11:57:33 -0700 Subject: [PATCH 118/160] clk: qcom: Add MSM8998 GPU Clock Controller (GPUCC) driver The GPUCC manages the clocks for the Adreno GPU found on MSM8998. Signed-off-by: Jeffrey Hugo Link: https://lkml.kernel.org/r/20191031185733.15553-1-jeffrey.l.hugo@gmail.com Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-msm8998.c | 338 +++++++++++++++++++++++++++++++ 3 files changed, 348 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-msm8998.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 5d8cc03457ca..3b33ef129274 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -220,6 +220,15 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config MSM_GPUCC_8998 + tristate "MSM8998 Graphics Clock Controller" + select MSM_GCC_8998 + select QCOM_GDSC + help + Support for the graphics clock controller on MSM8998 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config QCS_GCC_404 tristate "QCS404 Global Clock Controller" help diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 80a30976abe8..d899661d0f44 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o obj-$(CONFIG_MSM_GCC_8998) += gcc-msm8998.o +obj-$(CONFIG_MSM_GPUCC_8998) += gpucc-msm8998.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c new file mode 100644 index 000000000000..e5e2492b20c5 --- /dev/null +++ b/drivers/clk/qcom/gpucc-msm8998.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, Jeffrey Hugo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-alpha-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_XO, + P_GPLL0, + P_GPUPLL0_OUT_EVEN, +}; + +/* Instead of going directly to the block, XO is routed through this branch */ +static struct clk_branch gpucc_cxo_clk = { + .halt_reg = 0x1020, + .clkr = { + .enable_reg = 0x1020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpucc_cxo_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + .name = "xo" + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_IS_CRITICAL, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, + { } +}; + +static struct clk_alpha_pll gpupll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpupll0", + .parent_hws = (const struct clk_hw *[]){ &gpucc_cxo_clk.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpupll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpupll0_out_even", + .parent_hws = (const struct clk_hw *[]){ &gpupll0.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static const struct parent_map gpu_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 5 }, +}; + +static const struct clk_parent_data gpu_xo_gpll0[] = { + { .hw = &gpucc_cxo_clk.clkr.hw }, + { .fw_name = "gpll0", .name = "gpll0" }, +}; + +static const struct parent_map gpu_xo_gpupll0_map[] = { + { P_XO, 0 }, + { P_GPUPLL0_OUT_EVEN, 1 }, +}; + +static const struct clk_parent_data gpu_xo_gpupll0[] = { + { .hw = &gpucc_cxo_clk.clkr.hw }, + { .hw = &gpupll0_out_even.clkr.hw }, +}; + +static const struct freq_tbl ftbl_rbcpr_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 12, 0, 0), + { } +}; + +static struct clk_rcg2 rbcpr_clk_src = { + .cmd_rcgr = 0x1030, + .hid_width = 5, + .parent_map = gpu_xo_gpll0_map, + .freq_tbl = ftbl_rbcpr_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rbcpr_clk_src", + .parent_data = gpu_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gfx3d_clk_src[] = { + { .src = P_GPUPLL0_OUT_EVEN, .pre_div = 3 }, + { } +}; + +static struct clk_rcg2 gfx3d_clk_src = { + .cmd_rcgr = 0x1070, + .hid_width = 5, + .parent_map = gpu_xo_gpupll0_map, + .freq_tbl = ftbl_gfx3d_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk_src", + .parent_data = gpu_xo_gpupll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + }, +}; + +static const struct freq_tbl ftbl_rbbmtimer_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 rbbmtimer_clk_src = { + .cmd_rcgr = 0x10b0, + .hid_width = 5, + .parent_map = gpu_xo_gpll0_map, + .freq_tbl = ftbl_rbbmtimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "rbbmtimer_clk_src", + .parent_data = gpu_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gfx3d_isense_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(40000000, P_GPLL0, 15, 0, 0), + F(200000000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gfx3d_isense_clk_src = { + .cmd_rcgr = 0x1100, + .hid_width = 5, + .parent_map = gpu_xo_gpll0_map, + .freq_tbl = ftbl_gfx3d_isense_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gfx3d_isense_clk_src", + .parent_data = gpu_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch rbcpr_clk = { + .halt_reg = 0x1054, + .clkr = { + .enable_reg = 0x1054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "rbcpr_clk", + .parent_hws = (const struct clk_hw *[]){ &rbcpr_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gfx3d_clk = { + .halt_reg = 0x1098, + .clkr = { + .enable_reg = 0x1098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_clk", + .parent_hws = (const struct clk_hw *[]){ &gfx3d_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch rbbmtimer_clk = { + .halt_reg = 0x10d0, + .clkr = { + .enable_reg = 0x10d0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "rbbmtimer_clk", + .parent_hws = (const struct clk_hw *[]){ &rbbmtimer_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gfx3d_isense_clk = { + .halt_reg = 0x1124, + .clkr = { + .enable_reg = 0x1124, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gfx3d_isense_clk", + .parent_hws = (const struct clk_hw *[]){ &gfx3d_isense_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cx_gdsc = { + .gdscr = 0x1004, + .pd = { + .name = "gpu_cx", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc gpu_gx_gdsc = { + .gdscr = 0x1094, + .clamp_io_ctrl = 0x130, + .pd = { + .name = "gpu_gx", + }, + .parent = &gpu_cx_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | AON_RESET, +}; + +static struct clk_regmap *gpucc_msm8998_clocks[] = { + [GPUPLL0] = &gpupll0.clkr, + [GPUPLL0_OUT_EVEN] = &gpupll0_out_even.clkr, + [RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr, + [GFX3D_ISENSE_CLK_SRC] = &gfx3d_isense_clk_src.clkr, + [RBCPR_CLK] = &rbcpr_clk.clkr, + [GFX3D_CLK] = &gfx3d_clk.clkr, + [RBBMTIMER_CLK] = &rbbmtimer_clk.clkr, + [GFX3D_ISENSE_CLK] = &gfx3d_isense_clk.clkr, + [GPUCC_CXO_CLK] = &gpucc_cxo_clk.clkr, +}; + +static struct gdsc *gpucc_msm8998_gdscs[] = { + [GPU_CX_GDSC] = &gpu_cx_gdsc, + [GPU_GX_GDSC] = &gpu_gx_gdsc, +}; + +static const struct qcom_reset_map gpucc_msm8998_resets[] = { + [GPU_CX_BCR] = { 0x1000 }, + [RBCPR_BCR] = { 0x1050 }, + [GPU_GX_BCR] = { 0x1090 }, + [GPU_ISENSE_BCR] = { 0x1120 }, +}; + +static const struct regmap_config gpucc_msm8998_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gpucc_msm8998_desc = { + .config = &gpucc_msm8998_regmap_config, + .clks = gpucc_msm8998_clocks, + .num_clks = ARRAY_SIZE(gpucc_msm8998_clocks), + .resets = gpucc_msm8998_resets, + .num_resets = ARRAY_SIZE(gpucc_msm8998_resets), + .gdscs = gpucc_msm8998_gdscs, + .num_gdscs = ARRAY_SIZE(gpucc_msm8998_gdscs), +}; + +static const struct of_device_id gpucc_msm8998_match_table[] = { + { .compatible = "qcom,msm8998-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpucc_msm8998_match_table); + +static int gpucc_msm8998_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gpucc_msm8998_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* force periph logic on to avoid perf counter corruption */ + regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(13), BIT(13)); + /* tweak droop detector (GPUCC_GPU_DD_WRAP_CTRL) to reduce leakage */ + regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(0), BIT(0)); + + return qcom_cc_really_probe(pdev, &gpucc_msm8998_desc, regmap); +} + +static struct platform_driver gpucc_msm8998_driver = { + .probe = gpucc_msm8998_probe, + .driver = { + .name = "gpucc-msm8998", + .of_match_table = gpucc_msm8998_match_table, + }, +}; +module_platform_driver(gpucc_msm8998_driver); + +MODULE_DESCRIPTION("QCOM GPUCC MSM8998 Driver"); +MODULE_LICENSE("GPL v2"); From e620a1e061c4738e26c3edf2abaae7842532cd80 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Fri, 27 Sep 2019 20:51:10 +0200 Subject: [PATCH 119/160] drivers/clk: convert VL struct to struct_size There are a few manually-calculated variable-length struct allocations left, this converts them to use struct_size. Found with the following git grep command git grep -A1 'kzalloc.*sizeof[^_].*+' Signed-off-by: Stephen Kitt Link: https://lkml.kernel.org/r/20190927185110.29897-1-steve@sk2.org Acked-by: Gustavo A. R. Silva [sboyd@kernel.org: Add grep command] Signed-off-by: Stephen Boyd --- drivers/clk/at91/sckc.c | 3 +-- drivers/clk/imgtec/clk-boston.c | 3 +-- drivers/clk/ingenic/tcu.c | 3 +-- drivers/clk/mvebu/ap-cpu-clk.c | 4 ++-- drivers/clk/mvebu/cp110-system-controller.c | 4 ++-- drivers/clk/samsung/clk.c | 3 +-- drivers/clk/uniphier/clk-uniphier-core.c | 3 +-- 7 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index 9bfe9a28294a..5ad6180449cb 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -478,8 +478,7 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) if (IS_ERR(slow_osc)) goto unregister_slow_rc; - clk_data = kzalloc(sizeof(*clk_data) + (2 * sizeof(struct clk_hw *)), - GFP_KERNEL); + clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL); if (!clk_data) goto unregister_slow_osc; diff --git a/drivers/clk/imgtec/clk-boston.c b/drivers/clk/imgtec/clk-boston.c index 33ab4ff61165..b00cbd045af5 100644 --- a/drivers/clk/imgtec/clk-boston.c +++ b/drivers/clk/imgtec/clk-boston.c @@ -58,8 +58,7 @@ static void __init clk_boston_setup(struct device_node *np) cpu_div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK1DIV); cpu_freq = mult_frac(in_freq, mul, cpu_div); - onecell = kzalloc(sizeof(*onecell) + - (BOSTON_CLK_COUNT * sizeof(struct clk_hw *)), + onecell = kzalloc(struct_size(onecell, hws, BOSTON_CLK_COUNT), GFP_KERNEL); if (!onecell) return; diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index a1a5f9cb439e..ad7daa494fd4 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -358,8 +358,7 @@ static int __init ingenic_tcu_probe(struct device_node *np) } } - tcu->clocks = kzalloc(sizeof(*tcu->clocks) + - sizeof(*tcu->clocks->hws) * TCU_CLK_COUNT, + tcu->clocks = kzalloc(struct_size(tcu->clocks, hws, TCU_CLK_COUNT), GFP_KERNEL); if (!tcu->clocks) { ret = -ENOMEM; diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index af5e5acad370..6b394302c76a 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -274,8 +274,8 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) if (!ap_cpu_clk) return -ENOMEM; - ap_cpu_data = devm_kzalloc(dev, sizeof(*ap_cpu_data) + - sizeof(struct clk_hw *) * nclusters, + ap_cpu_data = devm_kzalloc(dev, struct_size(ap_cpu_data, hws, + nclusters), GFP_KERNEL); if (!ap_cpu_data) return -ENOMEM; diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index 808463276145..84c8900542e4 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -235,8 +235,8 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, if (ret) return ret; - cp110_clk_data = devm_kzalloc(dev, sizeof(*cp110_clk_data) + - sizeof(struct clk_hw *) * CP110_CLK_NUM, + cp110_clk_data = devm_kzalloc(dev, struct_size(cp110_clk_data, hws, + CP110_CLK_NUM), GFP_KERNEL); if (!cp110_clk_data) return -ENOMEM; diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index e544a38106dd..dad31308c071 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -60,8 +60,7 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np, struct samsung_clk_provider *ctx; int i; - ctx = kzalloc(sizeof(struct samsung_clk_provider) + - sizeof(*ctx->clk_data.hws) * nr_clks, GFP_KERNEL); + ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_clks), GFP_KERNEL); if (!ctx) panic("could not allocate clock provider context.\n"); diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c index c6aaca73cf86..12380236d7ab 100644 --- a/drivers/clk/uniphier/clk-uniphier-core.c +++ b/drivers/clk/uniphier/clk-uniphier-core.c @@ -64,8 +64,7 @@ static int uniphier_clk_probe(struct platform_device *pdev) for (p = data; p->name; p++) clk_num = max(clk_num, p->idx + 1); - hw_data = devm_kzalloc(dev, - sizeof(*hw_data) + clk_num * sizeof(struct clk_hw *), + hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, clk_num), GFP_KERNEL); if (!hw_data) return -ENOMEM; From 3696eebd810cf084b3662d3c3b85cd84b61090f3 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Thu, 10 Oct 2019 12:37:25 +1030 Subject: [PATCH 120/160] clk: ast2600: Add RMII RCLK gates for all four MACs RCLK is a fixed 50MHz clock derived from HPLL/HCLK that is described by a single gate for each MAC. Signed-off-by: Andrew Jeffery Link: https://lkml.kernel.org/r/20191010020725.3990-3-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Stephen Boyd --- drivers/clk/clk-ast2600.c | 47 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index 1c1bb39bb04e..85acc7cdc83c 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -15,7 +15,7 @@ #include "clk-aspeed.h" -#define ASPEED_G6_NUM_CLKS 67 +#define ASPEED_G6_NUM_CLKS 71 #define ASPEED_G6_SILICON_REV 0x004 @@ -40,6 +40,9 @@ #define ASPEED_G6_STRAP1 0x500 +#define ASPEED_MAC12_CLK_DLY 0x340 +#define ASPEED_MAC34_CLK_DLY 0x350 + /* Globally visible clocks */ static DEFINE_SPINLOCK(aspeed_g6_clk_lock); @@ -485,6 +488,11 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_SDIO] = hw; + /* MAC1/2 RMII 50MHz RCLK */ + hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0, 50000000); + if (IS_ERR(hw)) + return PTR_ERR(hw); + /* MAC1/2 AHB bus clock divider */ hw = clk_hw_register_divider_table(dev, "mac12", "hpll", 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1, 16, 3, 0, @@ -494,6 +502,27 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_MAC12] = hw; + /* RMII1 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0, + scu_g6_base + ASPEED_MAC12_CLK_DLY, 29, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw; + + /* RMII2 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0, + scu_g6_base + ASPEED_MAC12_CLK_DLY, 30, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw; + + /* MAC1/2 RMII 50MHz RCLK */ + hw = clk_hw_register_fixed_rate(dev, "mac34rclk", "hclk", 0, 50000000); + if (IS_ERR(hw)) + return PTR_ERR(hw); + /* MAC3/4 AHB bus clock divider */ hw = clk_hw_register_divider_table(dev, "mac34", "hpll", 0, scu_g6_base + 0x310, 24, 3, 0, @@ -503,6 +532,22 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_MAC34] = hw; + /* RMII3 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac3rclk", "mac34rclk", 0, + scu_g6_base + ASPEED_MAC34_CLK_DLY, 29, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC3RCLK] = hw; + + /* RMII4 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac4rclk", "mac34rclk", 0, + scu_g6_base + ASPEED_MAC34_CLK_DLY, 30, 0, + &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_g6_clk_data->hws[ASPEED_CLK_MAC4RCLK] = hw; + /* LPC Host (LHCLK) clock divider */ hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0, From 7f6ac72946b88b89ee44c1c527aa8591ac5ffcbe Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Sat, 19 Oct 2019 16:06:34 +0200 Subject: [PATCH 121/160] clk/ti/adpll: allocate room for terminating null The buffer allocated in ti_adpll_clk_get_name doesn't account for the terminating null. This patch switches to devm_kasprintf to avoid overflowing. Signed-off-by: Stephen Kitt Link: https://lkml.kernel.org/r/20191019140634.15596-1-steve@sk2.org Acked-by: Tony Lindgren Signed-off-by: Stephen Boyd --- drivers/clk/ti/adpll.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index fdfb90058504..bb2f2836dab2 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -194,15 +194,8 @@ static const char *ti_adpll_clk_get_name(struct ti_adpll_data *d, if (err) return NULL; } else { - const char *base_name = "adpll"; - char *buf; - - buf = devm_kzalloc(d->dev, 8 + 1 + strlen(base_name) + 1 + - strlen(postfix), GFP_KERNEL); - if (!buf) - return NULL; - sprintf(buf, "%08lx.%s.%s", d->pa, base_name, postfix); - name = buf; + name = devm_kasprintf(d->dev, GFP_KERNEL, "%08lx.adpll.%s", + d->pa, postfix); } return name; From f5790382edef4e97514dc7af75344b06b8cac3ee Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 7 Nov 2019 13:40:18 -0800 Subject: [PATCH 122/160] clk: qcom: rpmh: Reuse sdm845 clks for sm8150 The SM8150 list of clks is almost the same as the list for SDM845, except there isn't an IPA clk. Just point to the SDM845 clks from the SM8150 list for now so we can reduce the amount of struct bloat in this driver. Suggested-by: Vinod Koul Cc: Taniya Das Signed-off-by: Stephen Boyd Link: https://lkml.kernel.org/r/20191107214018.184105-1-sboyd@kernel.org Reviewed-by: Vinod Koul --- drivers/clk/qcom/clk-rpmh.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 7301c7739f29..2dbbe47e8d4f 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -334,13 +334,14 @@ static const struct clk_ops clk_rpmh_bcm_ops = { .recalc_rate = clk_rpmh_bcm_recalc_rate, }; -/* Resource name must match resource id present in cmd-db. */ +/* Resource name must match resource id present in cmd-db */ DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); +DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1); DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0"); static struct clk_hw *sdm845_rpmh_clocks[] = { @@ -364,26 +365,19 @@ static const struct clk_rpmh_desc clk_rpmh_sdm845 = { .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks), }; -DEFINE_CLK_RPMH_ARC(sm8150, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); -DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); -DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); -DEFINE_CLK_RPMH_VRM(sm8150, rf_clk1, rf_clk1_ao, "rfclka1", 1); -DEFINE_CLK_RPMH_VRM(sm8150, rf_clk2, rf_clk2_ao, "rfclka2", 1); -DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1); - static struct clk_hw *sm8150_rpmh_clocks[] = { - [RPMH_CXO_CLK] = &sm8150_bi_tcxo.hw, - [RPMH_CXO_CLK_A] = &sm8150_bi_tcxo_ao.hw, - [RPMH_LN_BB_CLK2] = &sm8150_ln_bb_clk2.hw, - [RPMH_LN_BB_CLK2_A] = &sm8150_ln_bb_clk2_ao.hw, - [RPMH_LN_BB_CLK3] = &sm8150_ln_bb_clk3.hw, - [RPMH_LN_BB_CLK3_A] = &sm8150_ln_bb_clk3_ao.hw, - [RPMH_RF_CLK1] = &sm8150_rf_clk1.hw, - [RPMH_RF_CLK1_A] = &sm8150_rf_clk1_ao.hw, - [RPMH_RF_CLK2] = &sm8150_rf_clk2.hw, - [RPMH_RF_CLK2_A] = &sm8150_rf_clk2_ao.hw, - [RPMH_RF_CLK3] = &sm8150_rf_clk3.hw, - [RPMH_RF_CLK3_A] = &sm8150_rf_clk3_ao.hw, + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, + [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw, + [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw, + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, + [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, + [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw, + [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, + [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, + [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, }; static const struct clk_rpmh_desc clk_rpmh_sm8150 = { From fc59462c5ce60da119568fac325c92fc6b7c6175 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 8 Nov 2019 09:17:18 +0200 Subject: [PATCH 123/160] clk: clk-gpio: propagate rate change to parent For an external clock source, which is gated via a GPIO, the rate change should typically be propagated to the parent clock. The situation where we are requiring this propagation, is when an external clock is connected to override an internal clock (which typically has a fixed rate). The external clock can have a different rate than the internal one, and may also be variable, thus requiring the rate propagation. This rate change wasn't propagated until now, and it's unclear about cases where this shouldn't be propagated. Thus, it's unclear whether this is fixing a bug, or extending the current driver behavior. Also, it's unsure about whether this may break any existing setups; in the case that it does, a device-tree property may be added to disable this flag. Signed-off-by: Michael Hennerich Signed-off-by: Alexandru Ardelean Link: https://lkml.kernel.org/r/20191108071718.17985-1-alexandru.ardelean@analog.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 9d930edd6516..13304cf5f2a8 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -280,7 +280,7 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) else clk = clk_register_gpio_gate(&pdev->dev, node->name, parent_names ? parent_names[0] : NULL, gpiod, - 0); + CLK_SET_RATE_PARENT); if (IS_ERR(clk)) return PTR_ERR(clk); From d9b86cc48283112f06738d45031b88bd3f9ecb92 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:52 -0700 Subject: [PATCH 124/160] clk: Add API to get index of the clock parent This patch adds a new clk_hw_get_parent_index() function that can be used to retrieve the index of a given clock's parent. This can be useful for restoring a clock on system resume. Reviewed-by: Thierry Reding Reviewed-by: Dmitry Osipenko Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/clk.c | 18 ++++++++++++++++++ include/linux/clk-provider.h | 1 + 2 files changed, 19 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 1c677d7f7f53..f8ed6e613436 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1674,6 +1674,24 @@ static int clk_fetch_parent_index(struct clk_core *core, return i; } +/** + * clk_hw_get_parent_index - return the index of the parent clock + * @hw: clk_hw associated with the clk being consumed + * + * Fetches and returns the index of parent clock. Returns -EINVAL if the given + * clock does not have a current parent. + */ +int clk_hw_get_parent_index(struct clk_hw *hw) +{ + struct clk_hw *parent = clk_hw_get_parent(hw); + + if (WARN_ON(parent == NULL)) + return -EINVAL; + + return clk_fetch_parent_index(hw->core, parent->core); +} +EXPORT_SYMBOL_GPL(clk_hw_get_parent_index); + /* * Update the orphan status of @core and all its children. */ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 2fdfe8061363..caf4b9df16eb 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -818,6 +818,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index); +int clk_hw_get_parent_index(struct clk_hw *hw); int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent); unsigned int __clk_get_enable_count(struct clk *clk); unsigned long clk_hw_get_rate(const struct clk_hw *hw); From ed1a2459e20c0dfc9d184230c480ace439bececb Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Mon, 12 Aug 2019 00:00:29 +0300 Subject: [PATCH 125/160] clk: tegra: Add Tegra20/30 EMC clock implementation A proper External Memory Controller clock rounding and parent selection functionality is required by the EMC drivers, it is not available using the generic clock implementation because only the Memory Controller driver is aware of what clock rates are actually available for a particular device. EMC drivers will have to register a Tegra-specific CLK-API callback which will perform rounding of a requested rate. EMC clock users won't be able to request EMC clock by getting -EPROBE_DEFER until EMC driver is probed and the callback is set up. The functionality is somewhat similar to the clk-emc.c which serves Tegra124+ SoCs. The later HW generations support more parent clock sources and the HW configuration / integration with the EMC drivers differs a tad from the older gens, hence it's not really worth to try to squash everything into a single source file. Acked-by: Peter De Schrijver Signed-off-by: Dmitry Osipenko Acked-by: Stephen Boyd Signed-off-by: Thierry Reding --- drivers/clk/tegra/Makefile | 2 + drivers/clk/tegra/clk-tegra20-emc.c | 293 ++++++++++++++++++++++++++++ drivers/clk/tegra/clk-tegra20.c | 55 ++---- drivers/clk/tegra/clk-tegra30.c | 38 ++-- drivers/clk/tegra/clk.h | 3 + include/linux/clk/tegra.h | 11 ++ 6 files changed, 350 insertions(+), 52 deletions(-) create mode 100644 drivers/clk/tegra/clk-tegra20-emc.c diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index 4812e45c2214..df966ca06788 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -17,7 +17,9 @@ obj-y += clk-tegra-fixed.o obj-y += clk-tegra-super-gen4.o obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o +obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20-emc.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o +obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra20-emc.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o obj-$(CONFIG_TEGRA_CLK_DFLL) += clk-tegra124-dfll-fcpu.o diff --git a/drivers/clk/tegra/clk-tegra20-emc.c b/drivers/clk/tegra/clk-tegra20-emc.c new file mode 100644 index 000000000000..03bf0009a33c --- /dev/null +++ b/drivers/clk/tegra/clk-tegra20-emc.c @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Based on drivers/clk/tegra/clk-emc.c + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * Author: Dmitry Osipenko + * Copyright (C) 2019 GRATE-DRIVER project + */ + +#define pr_fmt(fmt) "tegra-emc-clk: " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +#define CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK GENMASK(7, 0) +#define CLK_SOURCE_EMC_2X_CLK_SRC_MASK GENMASK(31, 30) +#define CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT 30 + +#define MC_EMC_SAME_FREQ BIT(16) +#define USE_PLLM_UD BIT(29) + +#define EMC_SRC_PLL_M 0 +#define EMC_SRC_PLL_C 1 +#define EMC_SRC_PLL_P 2 +#define EMC_SRC_CLK_M 3 + +static const char * const emc_parent_clk_names[] = { + "pll_m", "pll_c", "pll_p", "clk_m", +}; + +struct tegra_clk_emc { + struct clk_hw hw; + void __iomem *reg; + bool mc_same_freq; + bool want_low_jitter; + + tegra20_clk_emc_round_cb *round_cb; + void *cb_arg; +}; + +static inline struct tegra_clk_emc *to_tegra_clk_emc(struct clk_hw *hw) +{ + return container_of(hw, struct tegra_clk_emc, hw); +} + +static unsigned long emc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + u32 val, div; + + val = readl_relaxed(emc->reg); + div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + + return DIV_ROUND_UP(parent_rate * 2, div + 2); +} + +static u8 emc_get_parent(struct clk_hw *hw) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + + return readl_relaxed(emc->reg) >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; +} + +static int emc_set_parent(struct clk_hw *hw, u8 index) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + u32 val, div; + + val = readl_relaxed(emc->reg); + val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK; + val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; + + div = val & CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) + val |= USE_PLLM_UD; + else + val &= ~USE_PLLM_UD; + + if (emc->mc_same_freq) + val |= MC_EMC_SAME_FREQ; + else + val &= ~MC_EMC_SAME_FREQ; + + writel_relaxed(val, emc->reg); + + fence_udelay(1, emc->reg); + + return 0; +} + +static int emc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + unsigned int index; + u32 val, div; + + div = div_frac_get(rate, parent_rate, 8, 1, 0); + + val = readl_relaxed(emc->reg); + val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + val |= div; + + index = val >> CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; + + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) + val |= USE_PLLM_UD; + else + val &= ~USE_PLLM_UD; + + if (emc->mc_same_freq) + val |= MC_EMC_SAME_FREQ; + else + val &= ~MC_EMC_SAME_FREQ; + + writel_relaxed(val, emc->reg); + + fence_udelay(1, emc->reg); + + return 0; +} + +static int emc_set_rate_and_parent(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate, + u8 index) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + u32 val, div; + + div = div_frac_get(rate, parent_rate, 8, 1, 0); + + val = readl_relaxed(emc->reg); + + val &= ~CLK_SOURCE_EMC_2X_CLK_SRC_MASK; + val |= index << CLK_SOURCE_EMC_2X_CLK_SRC_SHIFT; + + val &= ~CLK_SOURCE_EMC_2X_CLK_DIVISOR_MASK; + val |= div; + + if (index == EMC_SRC_PLL_M && div == 0 && emc->want_low_jitter) + val |= USE_PLLM_UD; + else + val &= ~USE_PLLM_UD; + + if (emc->mc_same_freq) + val |= MC_EMC_SAME_FREQ; + else + val &= ~MC_EMC_SAME_FREQ; + + writel_relaxed(val, emc->reg); + + fence_udelay(1, emc->reg); + + return 0; +} + +static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct tegra_clk_emc *emc = to_tegra_clk_emc(hw); + struct clk_hw *parent_hw; + unsigned long divided_rate; + unsigned long parent_rate; + unsigned int i; + long emc_rate; + int div; + + emc_rate = emc->round_cb(req->rate, req->min_rate, req->max_rate, + emc->cb_arg); + if (emc_rate < 0) + return emc_rate; + + for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) { + parent_hw = clk_hw_get_parent_by_index(hw, i); + + if (req->best_parent_hw == parent_hw) + parent_rate = req->best_parent_rate; + else + parent_rate = clk_hw_get_rate(parent_hw); + + if (emc_rate > parent_rate) + continue; + + div = div_frac_get(emc_rate, parent_rate, 8, 1, 0); + divided_rate = DIV_ROUND_UP(parent_rate * 2, div + 2); + + if (divided_rate != emc_rate) + continue; + + req->best_parent_rate = parent_rate; + req->best_parent_hw = parent_hw; + req->rate = emc_rate; + break; + } + + if (i == ARRAY_SIZE(emc_parent_clk_names)) { + pr_err_once("can't find parent for rate %lu emc_rate %lu\n", + req->rate, emc_rate); + return -EINVAL; + } + + return 0; +} + +static const struct clk_ops tegra_clk_emc_ops = { + .recalc_rate = emc_recalc_rate, + .get_parent = emc_get_parent, + .set_parent = emc_set_parent, + .set_rate = emc_set_rate, + .set_rate_and_parent = emc_set_rate_and_parent, + .determine_rate = emc_determine_rate, +}; + +void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, + void *cb_arg) +{ + struct clk *clk = __clk_lookup("emc"); + struct tegra_clk_emc *emc; + struct clk_hw *hw; + + if (clk) { + hw = __clk_get_hw(clk); + emc = to_tegra_clk_emc(hw); + + emc->round_cb = round_cb; + emc->cb_arg = cb_arg; + } +} + +bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw) +{ + return to_tegra_clk_emc(emc_hw)->round_cb != NULL; +} + +struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter) +{ + struct tegra_clk_emc *emc; + struct clk_init_data init; + struct clk *clk; + + emc = kzalloc(sizeof(*emc), GFP_KERNEL); + if (!emc) + return NULL; + + /* + * EMC stands for External Memory Controller. + * + * We don't want EMC clock to be disabled ever by gating its + * parent and whatnot because system is busted immediately in that + * case, hence the clock is marked as critical. + */ + init.name = "emc"; + init.ops = &tegra_clk_emc_ops; + init.flags = CLK_IS_CRITICAL; + init.parent_names = emc_parent_clk_names; + init.num_parents = ARRAY_SIZE(emc_parent_clk_names); + + emc->reg = ioaddr; + emc->hw.init = &init; + emc->want_low_jitter = low_jitter; + + clk = clk_register(NULL, &emc->hw); + if (IS_ERR(clk)) { + kfree(emc); + return NULL; + } + + return clk; +} + +int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same) +{ + struct tegra_clk_emc *emc; + struct clk_hw *hw; + + if (!emc_clk) + return -EINVAL; + + hw = __clk_get_hw(emc_clk); + emc = to_tegra_clk_emc(hw); + emc->mc_same_freq = same; + + return 0; +} diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index bcd871134f45..cceefbd67a3b 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -130,8 +130,6 @@ static struct cpu_clk_suspend_context { static void __iomem *clk_base; static void __iomem *pmc_base; -static DEFINE_SPINLOCK(emc_lock); - #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \ @@ -760,7 +758,6 @@ static const char *pwm_parents[] = { "pll_p", "pll_c", "audio", "clk_m", static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; static const char *mux_pllpdc_clkm[] = { "pll_p", "pll_d_out0", "pll_c", "clk_m" }; -static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX("i2s1", i2s1_parents, CLK_SOURCE_I2S1, 11, TEGRA_PERIPH_ON_APB, TEGRA20_CLK_I2S1), @@ -787,41 +784,6 @@ static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = { TEGRA_INIT_DATA_NODIV("disp2", mux_pllpdc_clkm, CLK_SOURCE_DISP2, 30, 2, 26, 0, TEGRA20_CLK_DISP2), }; -static void __init tegra20_emc_clk_init(void) -{ - const u32 use_pllm_ud = BIT(29); - struct clk *clk; - u32 emc_reg; - - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, - ARRAY_SIZE(mux_pllmcp_clkm), - CLK_SET_RATE_NO_REPARENT, - clk_base + CLK_SOURCE_EMC, - 30, 2, 0, &emc_lock); - - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, - &emc_lock); - clks[TEGRA20_CLK_MC] = clk; - - /* un-divided pll_m_out0 is currently unsupported */ - emc_reg = readl_relaxed(clk_base + CLK_SOURCE_EMC); - if (emc_reg & use_pllm_ud) { - pr_err("%s: un-divided PllM_out0 used as clock source\n", - __func__); - return; - } - - /* - * Note that 'emc_mux' source and 'emc' rate shouldn't be changed at - * the same time due to a HW bug, this won't happen because we're - * defining 'emc_mux' and 'emc' as distinct clocks. - */ - clk = tegra_clk_register_divider("emc", "emc_mux", - clk_base + CLK_SOURCE_EMC, CLK_IS_CRITICAL, - TEGRA_DIVIDER_INT, 0, 8, 1, &emc_lock); - clks[TEGRA20_CLK_EMC] = clk; -} - static void __init tegra20_periph_clk_init(void) { struct tegra_periph_init_data *data; @@ -835,7 +797,13 @@ static void __init tegra20_periph_clk_init(void) clks[TEGRA20_CLK_AC97] = clk; /* emc */ - tegra20_emc_clk_init(); + clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, false); + + clks[TEGRA20_CLK_EMC] = clk; + + clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC, + NULL); + clks[TEGRA20_CLK_MC] = clk; /* dsi */ clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, @@ -1115,6 +1083,8 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, if (IS_ERR(clk)) return clk; + hw = __clk_get_hw(clk); + /* * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent * clock is created by the pinctrl driver. It is possible for clk user @@ -1124,13 +1094,16 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, */ if (clkspec->args[0] == TEGRA20_CLK_CDEV1 || clkspec->args[0] == TEGRA20_CLK_CDEV2) { - hw = __clk_get_hw(clk); - parent_hw = clk_hw_get_parent(hw); if (!parent_hw) return ERR_PTR(-EPROBE_DEFER); } + if (clkspec->args[0] == TEGRA20_CLK_EMC) { + if (!tegra20_clk_emc_driver_available(hw)) + return ERR_PTR(-EPROBE_DEFER); + } + return clk; } diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 7b4c6a488527..95b0e4a16dd5 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -151,7 +151,6 @@ static unsigned long input_freq; static DEFINE_SPINLOCK(cml_lock); static DEFINE_SPINLOCK(pll_d_lock); -static DEFINE_SPINLOCK(emc_lock); #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ @@ -808,7 +807,7 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true }, [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true }, [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true }, - [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = true }, + [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = false }, }; static const char *pll_e_parents[] = { "pll_ref", "pll_p" }; @@ -995,7 +994,6 @@ static void __init tegra30_super_clk_init(void) static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p", "clk_m" }; static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" }; -static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" }; static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p", "clk_m" }; static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" }; @@ -1044,14 +1042,12 @@ static void __init tegra30_periph_clk_init(void) clks[TEGRA30_CLK_AFI] = clk; /* emc */ - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, - ARRAY_SIZE(mux_pllmcp_clkm), - CLK_SET_RATE_NO_REPARENT, - clk_base + CLK_SOURCE_EMC, - 30, 2, 0, &emc_lock); + clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, true); - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, - &emc_lock); + clks[TEGRA30_CLK_EMC] = clk; + + clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC, + NULL); clks[TEGRA30_CLK_MC] = clk; /* cml0 */ @@ -1302,6 +1298,26 @@ static struct tegra_audio_clk_info tegra30_audio_plls[] = { { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" }, }; +static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec, + void *data) +{ + struct clk_hw *hw; + struct clk *clk; + + clk = of_clk_src_onecell_get(clkspec, data); + if (IS_ERR(clk)) + return clk; + + hw = __clk_get_hw(clk); + + if (clkspec->args[0] == TEGRA30_CLK_EMC) { + if (!tegra20_clk_emc_driver_available(hw)) + return ERR_PTR(-EPROBE_DEFER); + } + + return clk; +} + static void __init tegra30_clock_init(struct device_node *np) { struct device_node *node; @@ -1345,7 +1361,7 @@ static void __init tegra30_clock_init(struct device_node *np) tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); - tegra_add_of_provider(np, of_clk_src_onecell_get); + tegra_add_of_provider(np, tegra30_clk_src_onecell_get); tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); tegra_clk_apply_init_table = tegra30_clock_apply_init_table; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 905bf1096558..20b3ee123050 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -838,4 +838,7 @@ int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, udelay(delay); \ } while (0) +bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw); +struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter); + #endif /* TEGRA_CLK_H */ diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index b8aef62cc3f5..6a7cbc3cfadc 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -119,4 +119,15 @@ extern void tegra210_put_utmipll_in_iddq(void); extern void tegra210_put_utmipll_out_iddq(void); extern int tegra210_clk_handle_mbist_war(unsigned int id); +struct clk; + +typedef long (tegra20_clk_emc_round_cb)(unsigned long rate, + unsigned long min_rate, + unsigned long max_rate, + void *arg); + +void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, + void *cb_arg); +int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same); + #endif /* __LINUX_CLK_TEGRA_H_ */ From 991a051ea5f15266903f52acb5832a596dd3da51 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 28 Jun 2019 11:06:35 +0200 Subject: [PATCH 126/160] clk: tegra: Remove last remains of TEGRA210_CLK_SOR1_SRC Later SoC generations implement this clock as SOR1_OUT. For consistency, the Tegra210 implementation was adapted to match the same name in commit 4d1dc4018573 ("dt-bindings: clock: tegra: Add sor1_out clock"). Clean up the remaining pieces by adopting the new name for the internal identifiers and remove the old alias. Note that since both SOR1_SRC and SOR1_OUT were referring to the same device tree clock ID, this does not break device tree ABI. Acked-by: Stephen Boyd Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-id.h | 2 +- drivers/clk/tegra/clk-tegra210.c | 2 +- include/dt-bindings/clock/tegra210-car.h | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index de466b4446da..ae02885c9475 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -238,7 +238,7 @@ enum clk_id { tegra_clk_sor0, tegra_clk_sor0_lvds, tegra_clk_sor1, - tegra_clk_sor1_src, + tegra_clk_sor1_out, tegra_clk_spdif, tegra_clk_spdif_2x, tegra_clk_spdif_in, diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index df172d5772d7..019287df6c12 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -2353,7 +2353,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, [tegra_clk_sor1] = { .dt_id = TEGRA210_CLK_SOR1, .present = true }, - [tegra_clk_sor1_src] = { .dt_id = TEGRA210_CLK_SOR1_SRC, .present = true }, + [tegra_clk_sor1_out] = { .dt_id = TEGRA210_CLK_SOR1_OUT, .present = true }, [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h index 0bfbfc912c68..80590c2a117e 100644 --- a/include/dt-bindings/clock/tegra210-car.h +++ b/include/dt-bindings/clock/tegra210-car.h @@ -309,7 +309,6 @@ #define TEGRA210_CLK_CLK_OUT_3 279 #define TEGRA210_CLK_BLINK 280 /* 281 */ -#define TEGRA210_CLK_SOR1_SRC 282 #define TEGRA210_CLK_SOR1_OUT 282 /* 283 */ #define TEGRA210_CLK_XUSB_HOST_SRC 284 From e5f8a107d92db30a7ad7d8d95aee59f5ad76206a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 28 Jun 2019 11:01:16 +0200 Subject: [PATCH 127/160] clk: tegra: Move SOR0 implementation to Tegra124 The SOR0 clock on Tegra210 is very different from the SOR0 clock found on Tegra124. Move the Tegra124 implementation to the Tegra124 driver so that a custom implementation can be provided on Tegra210 without clashing with the existing clock. Acked-by: Stephen Boyd Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra-periph.c | 8 ----- drivers/clk/tegra/clk-tegra124.c | 49 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 1ed85f120a1b..0d07c0ba49b6 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -262,7 +262,6 @@ static DEFINE_SPINLOCK(PLLP_OUTA_lock); static DEFINE_SPINLOCK(PLLP_OUTB_lock); static DEFINE_SPINLOCK(PLLP_OUTC_lock); -static DEFINE_SPINLOCK(sor0_lock); #define MUX_I2S_SPDIF(_id) \ static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \ @@ -587,11 +586,6 @@ static u32 mux_pllp_pllre_clkm_idx[] = { [0] = 0, [1] = 2, [2] = 3, }; -static const char *mux_clkm_plldp_sor0lvds[] = { - "clk_m", "pll_dp", "sor0_lvds", -}; -#define mux_clkm_plldp_sor0lvds_idx NULL - static const char * const mux_dmic1[] = { "pll_a_out0", "dmic1_sync_clk", "pll_p", "clk_m" }; @@ -731,14 +725,12 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("hdmi_audio", mux_pllp3_pllc_clkm, CLK_SOURCE_HDMI_AUDIO, 176, TEGRA_PERIPH_NO_RESET, tegra_clk_hdmi_audio), MUX8("clk72mhz", mux_pllp3_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz), MUX8("clk72mhz", mux_pllp_out3_pllp_pllc_clkm, CLK_SOURCE_CLK72MHZ, 177, TEGRA_PERIPH_NO_RESET, tegra_clk_clk72Mhz_8), - MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), MUX_FLAGS("csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite, CLK_IGNORE_UNUSED), MUX_FLAGS("csite", mux_pllp_pllre_clkm, CLK_SOURCE_CSITE, 73, TEGRA_PERIPH_ON_APB, tegra_clk_csite_8, CLK_IGNORE_UNUSED), NODIV("disp1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1, NULL), NODIV("disp1", mux_pllp_plld_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, 0, tegra_clk_disp1_8, NULL), NODIV("disp2", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2, NULL), NODIV("disp2", mux_pllp_plld_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, 0, tegra_clk_disp2_8, NULL), - NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), UART("uarta", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, tegra_clk_uarta), UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 0224fdc4766f..2e41141af7b5 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -27,6 +27,7 @@ #define CLK_SOURCE_CSITE 0x1d4 #define CLK_SOURCE_EMC 0x19c +#define CLK_SOURCE_SOR0 0x414 #define RST_DFLL_DVCO 0x2f4 #define DVFS_DFLL_RESET_SHIFT 0 @@ -91,6 +92,22 @@ /* Tegra CPU clock and reset control regs */ #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 +#define MASK(x) (BIT(x) - 1) + +#define MUX8_NOGATE_LOCK(_name, _parents, _offset, _clk_id, _lock) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ + 0, TEGRA_PERIPH_NO_GATE, _clk_id,\ + _parents##_idx, 0, _lock) + +#define NODIV(_name, _parents, _offset, \ + _mux_shift, _mux_mask, _clk_num, \ + _gate_flags, _clk_id, _lock) \ + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ + _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ + _clk_num, (_gate_flags) | TEGRA_PERIPH_NO_DIV,\ + _clk_id, _parents##_idx, 0, _lock) + #ifdef CONFIG_PM_SLEEP static struct cpu_clk_suspend_context { u32 clk_csite_src; @@ -110,6 +127,7 @@ static DEFINE_SPINLOCK(pll_e_lock); static DEFINE_SPINLOCK(pll_re_lock); static DEFINE_SPINLOCK(pll_u_lock); static DEFINE_SPINLOCK(emc_lock); +static DEFINE_SPINLOCK(sor0_lock); /* possible OSC frequencies in Hz */ static unsigned long tegra124_input_freq[] = { @@ -987,12 +1005,29 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "hda2hdmi", .dt_id = TEGRA124_CLK_HDA2HDMI }, }; +static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { + "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", + "pll_d2_out0", "clk_m" +}; +#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL + +static const char *mux_clkm_plldp_sor0lvds[] = { + "clk_m", "pll_dp", "sor0_lvds", +}; +#define mux_clkm_plldp_sor0lvds_idx NULL + +static struct tegra_periph_init_data tegra124_periph[] = { + MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), + NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), +}; + static struct clk **clks; static __init void tegra124_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base) { struct clk *clk; + unsigned int i; /* xusb_ss_div2 */ clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0, @@ -1033,6 +1068,20 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base, clk_register_clkdev(clk, "cml1", NULL); clks[TEGRA124_CLK_CML1] = clk; + for (i = 0; i < ARRAY_SIZE(tegra124_periph); i++) { + struct tegra_periph_init_data *init = &tegra124_periph[i]; + struct clk **clkp; + + clkp = tegra_lookup_dt_id(init->clk_id, tegra124_clks); + if (!clkp) { + pr_warn("clock %u not found\n", init->clk_id); + continue; + } + + clk = tegra_clk_register_periph_data(clk_base, init); + *clkp = clk; + } + tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params); } From da8d1a3555406275650b366460c6235f1696bf8b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 24 Jul 2019 15:50:04 +0200 Subject: [PATCH 128/160] clk: tegra: Rename sor0_lvds to sor0_out This makes Tegra124 and Tegra210 consistent with subsequent Tegra generations. Acked-by: Stephen Boyd Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-id.h | 2 +- drivers/clk/tegra/clk-tegra124.c | 12 ++++++------ drivers/clk/tegra/clk-tegra210.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index ae02885c9475..c4faebd32760 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h @@ -236,7 +236,7 @@ enum clk_id { tegra_clk_soc_therm, tegra_clk_soc_therm_8, tegra_clk_sor0, - tegra_clk_sor0_lvds, + tegra_clk_sor0_out, tegra_clk_sor1, tegra_clk_sor1_out, tegra_clk_spdif, diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 2e41141af7b5..7d231529c3a5 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -847,7 +847,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_adx1] = { .dt_id = TEGRA124_CLK_ADX1, .present = true }, [tegra_clk_dpaux] = { .dt_id = TEGRA124_CLK_DPAUX, .present = true }, [tegra_clk_sor0] = { .dt_id = TEGRA124_CLK_SOR0, .present = true }, - [tegra_clk_sor0_lvds] = { .dt_id = TEGRA124_CLK_SOR0_LVDS, .present = true }, + [tegra_clk_sor0_out] = { .dt_id = TEGRA124_CLK_SOR0_OUT, .present = true }, [tegra_clk_gpu] = { .dt_id = TEGRA124_CLK_GPU, .present = true }, [tegra_clk_amx1] = { .dt_id = TEGRA124_CLK_AMX1, .present = true }, [tegra_clk_uartb] = { .dt_id = TEGRA124_CLK_UARTB, .present = true }, @@ -1011,14 +1011,14 @@ static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { }; #define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL -static const char *mux_clkm_plldp_sor0lvds[] = { - "clk_m", "pll_dp", "sor0_lvds", +static const char *mux_clkm_plldp_sor0out[] = { + "clk_m", "pll_dp", "sor0_out", }; -#define mux_clkm_plldp_sor0lvds_idx NULL +#define mux_clkm_plldp_sor0out_idx NULL static struct tegra_periph_init_data tegra124_periph[] = { - MUX8_NOGATE_LOCK("sor0_lvds", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_lvds, &sor0_lock), - NODIV("sor0", mux_clkm_plldp_sor0lvds, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), + MUX8_NOGATE_LOCK("sor0_out", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_out, &sor0_lock), + NODIV("sor0", mux_clkm_plldp_sor0out, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), }; static struct clk **clks; diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 019287df6c12..0f0f14781b43 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -2351,7 +2351,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, [tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true }, [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, - [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, + [tegra_clk_sor0_out] = { .dt_id = TEGRA210_CLK_SOR0_OUT, .present = true }, [tegra_clk_sor1] = { .dt_id = TEGRA210_CLK_SOR1, .present = true }, [tegra_clk_sor1_out] = { .dt_id = TEGRA210_CLK_SOR1_OUT, .present = true }, [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, From 25175c806a6841149abe46168e0af12593141612 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 25 Jul 2019 18:19:00 +0200 Subject: [PATCH 129/160] clk: tegra: Reimplement SOR clock on Tegra124 In order to allow the display driver to deal uniformly with all SOR generations, implement the SOR clocks in a way that is compatible with Tegra186 and later. Acked-by: Stephen Boyd Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra124.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 7d231529c3a5..b3110d5b5a6c 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -1005,20 +1005,24 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "hda2hdmi", .dt_id = TEGRA124_CLK_HDA2HDMI }, }; -static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = { - "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c", - "pll_d2_out0", "clk_m" +static const char * const sor0_parents[] = { + "pll_p_out0", "pll_m_out0", "pll_d_out0", "pll_a_out0", "pll_c_out0", + "pll_d2_out0", "clk_m", }; -#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL -static const char *mux_clkm_plldp_sor0out[] = { - "clk_m", "pll_dp", "sor0_out", +static const char * const sor0_out_parents[] = { + "clk_m", "sor0_pad_clkout", }; -#define mux_clkm_plldp_sor0out_idx NULL static struct tegra_periph_init_data tegra124_periph[] = { - MUX8_NOGATE_LOCK("sor0_out", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_SOR0, tegra_clk_sor0_out, &sor0_lock), - NODIV("sor0", mux_clkm_plldp_sor0out, CLK_SOURCE_SOR0, 14, 3, 182, 0, tegra_clk_sor0, &sor0_lock), + TEGRA_INIT_DATA_TABLE("sor0", NULL, NULL, sor0_parents, + CLK_SOURCE_SOR0, 29, 0x7, 0, 0, 0, 0, + 0, 182, 0, tegra_clk_sor0, NULL, 0, + &sor0_lock), + TEGRA_INIT_DATA_TABLE("sor0_out", NULL, NULL, sor0_out_parents, + CLK_SOURCE_SOR0, 14, 0x1, 0, 0, 0, 0, + 0, 0, TEGRA_PERIPH_NO_GATE, tegra_clk_sor0_out, + NULL, 0, &sor0_lock), }; static struct clk **clks; From 05308d7e7bbc932025f1dafc401c73ce83c6f414 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 24 Jun 2019 17:06:13 +0200 Subject: [PATCH 130/160] clk: tegra: Reimplement SOR clocks on Tegra210 In order to allow the display driver to deal uniformly with all SOR generations, implement the SOR clocks in a way that is compatible with Tegra186 and later. Acked-by: Stephen Boyd Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra210.c | 75 ++++++++++++++++++------ include/dt-bindings/clock/tegra210-car.h | 6 +- 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 0f0f14781b43..d55f3da4287a 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -33,6 +33,7 @@ #define CLK_SOURCE_CSITE 0x1d4 #define CLK_SOURCE_EMC 0x19c #define CLK_SOURCE_SOR1 0x410 +#define CLK_SOURCE_SOR0 0x414 #define CLK_SOURCE_LA 0x1f8 #define CLK_SOURCE_SDMMC2 0x154 #define CLK_SOURCE_SDMMC4 0x164 @@ -298,6 +299,7 @@ static DEFINE_SPINLOCK(pll_d_lock); static DEFINE_SPINLOCK(pll_e_lock); static DEFINE_SPINLOCK(pll_re_lock); static DEFINE_SPINLOCK(pll_u_lock); +static DEFINE_SPINLOCK(sor0_lock); static DEFINE_SPINLOCK(sor1_lock); static DEFINE_SPINLOCK(emc_lock); static DEFINE_MUTEX(lvl2_ovr_lock); @@ -2551,7 +2553,6 @@ static struct tegra_devclk devclks[] __initdata = { { .con_id = "pll_c4_out2", .dt_id = TEGRA210_CLK_PLL_C4_OUT2 }, { .con_id = "pll_c4_out3", .dt_id = TEGRA210_CLK_PLL_C4_OUT3 }, { .con_id = "dpaux", .dt_id = TEGRA210_CLK_DPAUX }, - { .con_id = "sor0", .dt_id = TEGRA210_CLK_SOR0 }, }; static struct tegra_audio_clk_info tegra210_audio_plls[] = { @@ -2915,15 +2916,31 @@ static int tegra210_init_pllu(void) return 0; } -static const char * const sor1_out_parents[] = { - /* - * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so - * the sor1_pad_clkout parent appears twice in the list below. This is - * merely to support clk_get_parent() if firmware happened to set - * these bits to 0b11. While not an invalid setting, code should - * always set the bits to 0b01 to select sor1_pad_clkout. - */ - "sor_safe", "sor1_pad_clkout", "sor1", "sor1_pad_clkout", +/* + * The SOR hardware blocks are driven by two clocks: a module clock that is + * used to access registers and a pixel clock that is sourced from the same + * pixel clock that also drives the head attached to the SOR. The module + * clock is typically called sorX (with X being the SOR instance) and the + * pixel clock is called sorX_out. The source for the SOR pixel clock is + * referred to as the "parent" clock. + * + * On Tegra186 and newer, clocks are provided by the BPMP. Unfortunately the + * BPMP implementation for the SOR clocks doesn't exactly match the above in + * some aspects. For example, the SOR module is really clocked by the pad or + * sor_safe clocks, but BPMP models the sorX clock as being sourced by the + * pixel clocks. Conversely the sorX_out clock is sourced by the sor_safe or + * pad clocks on BPMP. + * + * In order to allow the display driver to deal with all SoC generations in + * a unified way, implement the BPMP semantics in this driver. + */ + +static const char * const sor0_parents[] = { + "pll_d_out0", +}; + +static const char * const sor0_out_parents[] = { + "sor_safe", "sor0_pad_clkout", }; static const char * const sor1_parents[] = { @@ -2932,11 +2949,39 @@ static const char * const sor1_parents[] = { static u32 sor1_parents_idx[] = { 0, 2, 5, 6 }; +static const char * const sor1_out_parents[] = { + /* + * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so + * the sor1_pad_clkout parent appears twice in the list below. This is + * merely to support clk_get_parent() if firmware happened to set + * these bits to 0b11. While not an invalid setting, code should + * always set the bits to 0b01 to select sor1_pad_clkout. + */ + "sor_safe", "sor1_pad_clkout", "sor1_out", "sor1_pad_clkout", +}; + static struct tegra_periph_init_data tegra210_periph[] = { + /* + * On Tegra210, the sor0 clock doesn't have a mux it bitfield 31:29, + * but it is hardwired to the pll_d_out0 clock. + */ + TEGRA_INIT_DATA_TABLE("sor0", NULL, NULL, sor0_parents, + CLK_SOURCE_SOR0, 29, 0x0, 0, 0, 0, 0, + 0, 182, 0, tegra_clk_sor0, NULL, 0, + &sor0_lock), + TEGRA_INIT_DATA_TABLE("sor0_out", NULL, NULL, sor0_out_parents, + CLK_SOURCE_SOR0, 14, 0x1, 0, 0, 0, 0, + 0, 0, TEGRA_PERIPH_NO_GATE, tegra_clk_sor0_out, + NULL, 0, &sor0_lock), TEGRA_INIT_DATA_TABLE("sor1", NULL, NULL, sor1_parents, CLK_SOURCE_SOR1, 29, 0x7, 0, 0, 8, 1, - TEGRA_DIVIDER_ROUND_UP, 183, 0, tegra_clk_sor1, - sor1_parents_idx, 0, &sor1_lock), + TEGRA_DIVIDER_ROUND_UP, 183, 0, + tegra_clk_sor1, sor1_parents_idx, 0, + &sor1_lock), + TEGRA_INIT_DATA_TABLE("sor1_out", NULL, NULL, sor1_out_parents, + CLK_SOURCE_SOR1, 14, 0x3, 0, 0, 0, 0, + 0, 0, TEGRA_PERIPH_NO_GATE, + tegra_clk_sor1_out, NULL, 0, &sor1_lock), }; static const char * const la_parents[] = { @@ -2969,12 +3014,6 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base, 1, 17, 207); clks[TEGRA210_CLK_DPAUX1] = clk; - clk = clk_register_mux_table(NULL, "sor1_out", sor1_out_parents, - ARRAY_SIZE(sor1_out_parents), 0, - clk_base + CLK_SOURCE_SOR1, 14, 0x3, - 0, NULL, &sor1_lock); - clks[TEGRA210_CLK_SOR1_OUT] = clk; - /* pll_d_dsi_out */ clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h index 80590c2a117e..44f60623f99b 100644 --- a/include/dt-bindings/clock/tegra210-car.h +++ b/include/dt-bindings/clock/tegra210-car.h @@ -308,7 +308,8 @@ #define TEGRA210_CLK_CLK_OUT_2 278 #define TEGRA210_CLK_CLK_OUT_3 279 #define TEGRA210_CLK_BLINK 280 -/* 281 */ +#define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */ +#define TEGRA210_CLK_SOR0_OUT 281 #define TEGRA210_CLK_SOR1_OUT 282 /* 283 */ #define TEGRA210_CLK_XUSB_HOST_SRC 284 @@ -390,8 +391,7 @@ #define TEGRA210_CLK_CLK_OUT_3_MUX 358 #define TEGRA210_CLK_DSIA_MUX 359 #define TEGRA210_CLK_DSIB_MUX 360 -#define TEGRA210_CLK_SOR0_LVDS 361 /* deprecated */ -#define TEGRA210_CLK_SOR0_OUT 361 +/* 361 */ #define TEGRA210_CLK_XUSB_SS_DIV2 362 #define TEGRA210_CLK_PLL_M_UD 363 From d64422d93dca8fb630a132b0c24680c82c51788b Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:48 -0700 Subject: [PATCH 131/160] clk: tegra: divider: Save and restore divider rate This patch implements context restore for clock divider. During system suspend, core power goes off and looses the settings of the Tegra CAR controller registers. So on resume, clock dividers are restored back for normal operation. Acked-by: Thierry Reding Reviewed-by: Dmitry Osipenko Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-divider.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index e76731fb7d69..ca0de5f11f84 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c @@ -109,10 +109,21 @@ static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static void clk_divider_restore_context(struct clk_hw *hw) +{ + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = clk_hw_get_rate(parent); + unsigned long rate = clk_hw_get_rate(hw); + + if (clk_frac_div_set_rate(hw, rate, parent_rate) < 0) + WARN_ON(1); +} + const struct clk_ops tegra_clk_frac_div_ops = { .recalc_rate = clk_frac_div_recalc_rate, .set_rate = clk_frac_div_set_rate, .round_rate = clk_frac_div_round_rate, + .restore_context = clk_divider_restore_context, }; struct clk *tegra_clk_register_divider(const char *name, From fa62228240ec5f53bbdef6d4d821518541dc92c0 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:49 -0700 Subject: [PATCH 132/160] clk: tegra: pllout: Save and restore pllout context This patch implements save and restore of pllout context. During system suspend, core power goes off and looses the settings of the Tegra CAR controller registers. So during suspend entry the state of pllout is saved and on resume it is restored back to have pllout in same state as before suspend. pllout rate is saved and restore in clock divider so it will be at same rate as before suspend when pllout state is restored. Acked-by: Thierry Reding Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll-out.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c index 35f2bf00e1e6..d8bf89a81e6d 100644 --- a/drivers/clk/tegra/clk-pll-out.c +++ b/drivers/clk/tegra/clk-pll-out.c @@ -69,10 +69,19 @@ static void clk_pll_out_disable(struct clk_hw *hw) spin_unlock_irqrestore(pll_out->lock, flags); } +static void tegra_clk_pll_out_restore_context(struct clk_hw *hw) +{ + if (!__clk_get_enable_count(hw->clk)) + clk_pll_out_disable(hw); + else + clk_pll_out_enable(hw); +} + const struct clk_ops tegra_clk_pll_out_ops = { .is_enabled = clk_pll_out_is_enabled, .enable = clk_pll_out_enable, .disable = clk_pll_out_disable, + .restore_context = tegra_clk_pll_out_restore_context, }; struct clk *tegra_clk_register_pll_out(const char *name, From bc0b3a60fe19610d649a62879dd318d133ed10c0 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:50 -0700 Subject: [PATCH 133/160] clk: tegra: pll: Save and restore pll context This patch implements save and restore of PLL context. During system suspend, core power goes off and looses the settings of the Tegra CAR controller registers. So during resume, pll context is restored based on cached rate and state. Acked-by: Thierry Reding Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-pll.c | 86 +++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 1583f5fc992f..531c2b3d814e 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1008,6 +1008,27 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw, return rate; } +static void tegra_clk_pll_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = clk_hw_get_rate(parent); + unsigned long rate = clk_hw_get_rate(hw); + + if (clk_pll_is_enabled(hw)) + return; + + if (pll->params->set_defaults) + pll->params->set_defaults(pll); + + clk_pll_set_rate(hw, rate, parent_rate); + + if (!__clk_get_enable_count(hw->clk)) + clk_pll_disable(hw); + else + clk_pll_enable(hw); +} + const struct clk_ops tegra_clk_pll_ops = { .is_enabled = clk_pll_is_enabled, .enable = clk_pll_enable, @@ -1015,6 +1036,7 @@ const struct clk_ops tegra_clk_pll_ops = { .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_round_rate, .set_rate = clk_pll_set_rate, + .restore_context = tegra_clk_pll_restore_context, }; const struct clk_ops tegra_clk_plle_ops = { @@ -1802,6 +1824,27 @@ out: return ret; } + +static void _clk_plle_tegra_init_parent(struct tegra_clk_pll *pll) +{ + u32 val, val_aux; + + /* ensure parent is set to pll_ref */ + val = pll_readl_base(pll); + val_aux = pll_readl(pll->params->aux_reg, pll); + + if (val & PLL_BASE_ENABLE) { + if ((val_aux & PLLE_AUX_PLLRE_SEL) || + (val_aux & PLLE_AUX_PLLP_SEL)) + WARN(1, "pll_e enabled with unsupported parent %s\n", + (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : + "pll_re_vco"); + } else { + val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); + pll_writel(val_aux, pll->params->aux_reg, pll); + fence_udelay(1, pll->clk_base); + } +} #endif static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, @@ -2214,27 +2257,12 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name, { struct tegra_clk_pll *pll; struct clk *clk; - u32 val, val_aux; pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); - /* ensure parent is set to pll_re_vco */ - - val = pll_readl_base(pll); - val_aux = pll_readl(pll_params->aux_reg, pll); - - if (val & PLL_BASE_ENABLE) { - if ((val_aux & PLLE_AUX_PLLRE_SEL) || - (val_aux & PLLE_AUX_PLLP_SEL)) - WARN(1, "pll_e enabled with unsupported parent %s\n", - (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : - "pll_re_vco"); - } else { - val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); - pll_writel(val_aux, pll_params->aux_reg, pll); - } + _clk_plle_tegra_init_parent(pll); clk = _tegra_clk_register_pll(pll, name, parent_name, flags, &tegra_clk_plle_tegra114_ops); @@ -2276,6 +2304,7 @@ static const struct clk_ops tegra_clk_pllss_ops = { .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_ramp_round_rate, .set_rate = clk_pllxc_set_rate, + .restore_context = tegra_clk_pll_restore_context, }; struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name, @@ -2520,11 +2549,19 @@ out: spin_unlock_irqrestore(pll->lock, flags); } +static void tegra_clk_plle_t210_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_pll *pll = to_clk_pll(hw); + + _clk_plle_tegra_init_parent(pll); +} + static const struct clk_ops tegra_clk_plle_tegra210_ops = { .is_enabled = clk_plle_tegra210_is_enabled, .enable = clk_plle_tegra210_enable, .disable = clk_plle_tegra210_disable, .recalc_rate = clk_pll_recalc_rate, + .restore_context = tegra_clk_plle_t210_restore_context, }; struct clk *tegra_clk_register_plle_tegra210(const char *name, @@ -2535,27 +2572,12 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name, { struct tegra_clk_pll *pll; struct clk *clk; - u32 val, val_aux; pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); if (IS_ERR(pll)) return ERR_CAST(pll); - /* ensure parent is set to pll_re_vco */ - - val = pll_readl_base(pll); - val_aux = pll_readl(pll_params->aux_reg, pll); - - if (val & PLLE_BASE_ENABLE) { - if ((val_aux & PLLE_AUX_PLLRE_SEL) || - (val_aux & PLLE_AUX_PLLP_SEL)) - WARN(1, "pll_e enabled with unsupported parent %s\n", - (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : - "pll_re_vco"); - } else { - val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL); - pll_writel(val_aux, pll_params->aux_reg, pll); - } + _clk_plle_tegra_init_parent(pll); clk = _tegra_clk_register_pll(pll, name, parent_name, flags, &tegra_clk_plle_tegra210_ops); From 50d4da9b10edb885b2c5f95750e96b3695fa7c04 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:51 -0700 Subject: [PATCH 134/160] clk: tegra: Support for OSC context save and restore This patch adds support for saving OSC clock frequency and the drive-strength during OSC clock init and creates an API to restore OSC control register value from the saved context. This API is invoked by Tegra210 clock driver during system resume to restore the OSC clock settings. Acked-by: Thierry Reding Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra-fixed.c | 15 +++++++++++++++ drivers/clk/tegra/clk.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c index 8d91b2b191cf..7c6c8abfcde6 100644 --- a/drivers/clk/tegra/clk-tegra-fixed.c +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -17,6 +17,10 @@ #define OSC_CTRL 0x50 #define OSC_CTRL_OSC_FREQ_SHIFT 28 #define OSC_CTRL_PLL_REF_DIV_SHIFT 26 +#define OSC_CTRL_MASK (0x3f2 | \ + (0xf << OSC_CTRL_OSC_FREQ_SHIFT)) + +static u32 osc_ctrl_ctx; int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, unsigned long *input_freqs, unsigned int num, @@ -29,6 +33,7 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, unsigned osc_idx; val = readl_relaxed(clk_base + OSC_CTRL); + osc_ctrl_ctx = val & OSC_CTRL_MASK; osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT; if (osc_idx < num) @@ -96,3 +101,13 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) *dt_clk = clk; } } + +void tegra_clk_osc_resume(void __iomem *clk_base) +{ + u32 val; + + val = readl_relaxed(clk_base + OSC_CTRL) & ~OSC_CTRL_MASK; + val |= osc_ctrl_ctx; + writel_relaxed(val, clk_base + OSC_CTRL); + fence_udelay(2, clk_base); +} diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 20b3ee123050..7c956ce521d6 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -829,6 +829,7 @@ u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, u8 frac_width, u8 flags); +void tegra_clk_osc_resume(void __iomem *clk_base); /* Combined read fence with delay */ From 2b8cfd6b52cbf951d9b90862d95b8473d34d02ee Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:53 -0700 Subject: [PATCH 135/160] clk: tegra: periph: Add restore_context support This patch implements restore_context support for clk-periph and clk-sdmmc-mux clock operations to restore clock parent and rates on system resume. During system suspend, core power goes off and looses the context of the Tegra clock controller registers. So on system resume, clocks parent and rate are restored back to the context before suspend based on cached data. Acked-by: Thierry Reding Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-periph.c | 21 +++++++++++++++++++++ drivers/clk/tegra/clk-sdmmc-mux.c | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 58437da25156..67620c7ecd9e 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -3,6 +3,7 @@ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. */ +#include #include #include #include @@ -99,6 +100,23 @@ static void clk_periph_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static void clk_periph_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_periph *periph = to_clk_periph(hw); + const struct clk_ops *div_ops = periph->div_ops; + struct clk_hw *div_hw = &periph->divider.hw; + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV)) + div_ops->restore_context(div_hw); + + clk_periph_set_parent(hw, parent_id); +} + const struct clk_ops tegra_clk_periph_ops = { .get_parent = clk_periph_get_parent, .set_parent = clk_periph_set_parent, @@ -108,6 +126,7 @@ const struct clk_ops tegra_clk_periph_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .restore_context = clk_periph_restore_context, }; static const struct clk_ops tegra_clk_periph_nodiv_ops = { @@ -116,6 +135,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .restore_context = clk_periph_restore_context, }; static const struct clk_ops tegra_clk_periph_no_gate_ops = { @@ -124,6 +144,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = { .recalc_rate = clk_periph_recalc_rate, .round_rate = clk_periph_round_rate, .set_rate = clk_periph_set_rate, + .restore_context = clk_periph_restore_context, }; static struct clk *_tegra_clk_register_periph(const char *name, diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c index a5cd3e31dbae..316912d3b1a4 100644 --- a/drivers/clk/tegra/clk-sdmmc-mux.c +++ b/drivers/clk/tegra/clk-sdmmc-mux.c @@ -194,6 +194,21 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static void clk_sdmmc_mux_restore_context(struct clk_hw *hw) +{ + struct clk_hw *parent = clk_hw_get_parent(hw); + unsigned long parent_rate = clk_hw_get_rate(parent); + unsigned long rate = clk_hw_get_rate(hw); + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + clk_sdmmc_mux_set_parent(hw, parent_id); + clk_sdmmc_mux_set_rate(hw, rate, parent_rate); +} + static const struct clk_ops tegra_clk_sdmmc_mux_ops = { .get_parent = clk_sdmmc_mux_get_parent, .set_parent = clk_sdmmc_mux_set_parent, @@ -203,6 +218,7 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = { .is_enabled = clk_sdmmc_mux_is_enabled, .enable = clk_sdmmc_mux_enable, .disable = clk_sdmmc_mux_disable, + .restore_context = clk_sdmmc_mux_restore_context, }; struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, From 68a14a5634dacb37d18618d62f0410f1ec69ab28 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:54 -0700 Subject: [PATCH 136/160] clk: tegra: clk-super: Fix to enable PLLP branches to CPU This patch has a fix to enable PLLP branches to CPU before changing the CPU cluster clock source to PLLP for Gen5 Super clock and disables PLLP branches to CPU when not in use. During system suspend entry and exit, CPU source will be switched to PLLP and this needs PLLP branches to be enabled to CPU prior to the switch. On system resume, warmboot code enables PLLP branches to CPU and powers up the CPU with PLLP clock source. Acked-by: Thierry Reding Reviewed-by: Dmitry Osipenko Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-super.c | 14 ++++++++++++++ drivers/clk/tegra/clk-tegra-super-gen4.c | 7 ++++++- drivers/clk/tegra/clk.c | 14 ++++++++++++++ drivers/clk/tegra/clk.h | 5 +++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index 39ef31b46df5..e2a1e95a8db7 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -28,6 +28,9 @@ #define super_state_to_src_shift(m, s) ((m->width * s)) #define super_state_to_src_mask(m) (((1 << m->width) - 1)) +#define CCLK_SRC_PLLP_OUT0 4 +#define CCLK_SRC_PLLP_OUT4 5 + static u8 clk_super_get_parent(struct clk_hw *hw) { struct tegra_clk_super_mux *mux = to_clk_super_mux(hw); @@ -97,12 +100,23 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index) if (index == mux->div2_index) index = mux->pllx_index; } + + /* enable PLLP branches to CPU before selecting PLLP source */ + if ((mux->flags & TEGRA210_CPU_CLK) && + (index == CCLK_SRC_PLLP_OUT0 || index == CCLK_SRC_PLLP_OUT4)) + tegra_clk_set_pllp_out_cpu(true); + val &= ~((super_state_to_src_mask(mux)) << shift); val |= (index & (super_state_to_src_mask(mux))) << shift; writel_relaxed(val, mux->reg); udelay(2); + /* disable PLLP branches to CPU if not used */ + if ((mux->flags & TEGRA210_CPU_CLK) && + index != CCLK_SRC_PLLP_OUT0 && index != CCLK_SRC_PLLP_OUT4) + tegra_clk_set_pllp_out_cpu(false); + out: if (mux->lock) spin_unlock_irqrestore(mux->lock, flags); diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c index cdfe7c9697e1..5760c978bef7 100644 --- a/drivers/clk/tegra/clk-tegra-super-gen4.c +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c @@ -180,7 +180,7 @@ static void __init tegra_super_clk_init(void __iomem *clk_base, gen_info->num_cclk_g_parents, CLK_SET_RATE_PARENT, clk_base + CCLKG_BURST_POLICY, - 0, 4, 8, 0, NULL); + TEGRA210_CPU_CLK, 4, 8, 0, NULL); } else { clk = tegra_clk_register_super_mux("cclk_g", gen_info->cclk_g_parents, @@ -196,6 +196,11 @@ static void __init tegra_super_clk_init(void __iomem *clk_base, dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks); if (dt_clk) { if (gen_info->gen == gen5) { + /* + * TEGRA210_CPU_CLK flag is not needed for cclk_lp as + * cluster switching is not currently supported on + * Tegra210 and also cpu_lp is not used. + */ clk = tegra_clk_register_super_mux("cclk_lp", gen_info->cclk_lp_parents, gen_info->num_cclk_lp_parents, diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 573e3c967ae1..eb08047fd02f 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -23,6 +23,7 @@ #define CLK_OUT_ENB_W 0x364 #define CLK_OUT_ENB_X 0x280 #define CLK_OUT_ENB_Y 0x298 +#define CLK_ENB_PLLP_OUT_CPU BIT(31) #define CLK_OUT_ENB_SET_L 0x320 #define CLK_OUT_ENB_CLR_L 0x324 #define CLK_OUT_ENB_SET_H 0x328 @@ -199,6 +200,19 @@ const struct tegra_clk_periph_regs *get_reg_bank(int clkid) } } +void tegra_clk_set_pllp_out_cpu(bool enable) +{ + u32 val; + + val = readl_relaxed(clk_base + CLK_OUT_ENB_Y); + if (enable) + val |= CLK_ENB_PLLP_OUT_CPU; + else + val &= ~CLK_ENB_PLLP_OUT_CPU; + + writel_relaxed(val, clk_base + CLK_OUT_ENB_Y); +} + struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) { clk_base = regs; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 7c956ce521d6..21bb0f24c6c1 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -669,6 +669,9 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base, * Flags: * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates * that this is LP cluster clock. + * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5 + * super mux parent using PLLP branches. To use PLLP branches to CPU, need + * to configure additional bit PLLP_OUT_CPU in the clock registers. */ struct tegra_clk_super_mux { struct clk_hw hw; @@ -685,6 +688,7 @@ struct tegra_clk_super_mux { #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw) #define TEGRA_DIVIDER_2 BIT(0) +#define TEGRA210_CPU_CLK BIT(1) extern const struct clk_ops tegra_clk_super_ops; struct clk *tegra_clk_register_super_mux(const char *name, @@ -830,6 +834,7 @@ int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, u8 frac_width, u8 flags); void tegra_clk_osc_resume(void __iomem *clk_base); +void tegra_clk_set_pllp_out_cpu(bool enable); /* Combined read fence with delay */ From f8fd97521d6381b4a19b1b88692a426a79fe1794 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:55 -0700 Subject: [PATCH 137/160] clk: tegra: clk-super: Add restore-context support This patch implements restore_context for clk_super_mux and clk_super. During system supend, core power goes off the and context of Tegra CAR registers is lost. So on system resume, context of super clock registers are restored to have them in same state as before suspend. Acked-by: Thierry Reding Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-super.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index e2a1e95a8db7..6099c6e9acd4 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -124,9 +124,21 @@ out: return err; } +static void clk_super_mux_restore_context(struct clk_hw *hw) +{ + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + clk_super_set_parent(hw, parent_id); +} + static const struct clk_ops tegra_clk_super_mux_ops = { .get_parent = clk_super_get_parent, .set_parent = clk_super_set_parent, + .restore_context = clk_super_mux_restore_context, }; static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate, @@ -162,12 +174,27 @@ static int clk_super_set_rate(struct clk_hw *hw, unsigned long rate, return super->div_ops->set_rate(div_hw, rate, parent_rate); } +static void clk_super_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_super_mux *super = to_clk_super_mux(hw); + struct clk_hw *div_hw = &super->frac_div.hw; + int parent_id; + + parent_id = clk_hw_get_parent_index(hw); + if (WARN_ON(parent_id < 0)) + return; + + super->div_ops->restore_context(div_hw); + clk_super_set_parent(hw, parent_id); +} + const struct clk_ops tegra_clk_super_ops = { .get_parent = clk_super_get_parent, .set_parent = clk_super_set_parent, .set_rate = clk_super_set_rate, .round_rate = clk_super_round_rate, .recalc_rate = clk_super_recalc_rate, + .restore_context = clk_super_restore_context, }; struct clk *tegra_clk_register_super_mux(const char *name, From a99d744d8c9ca7e00adeb14dd11971b4b5b8271f Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:56 -0700 Subject: [PATCH 138/160] clk: tegra: clk-dfll: Add suspend and resume support This patch implements DFLL suspend and resume operation. During system suspend entry, CPU clock will switch CPU to safe clock source of PLLP and disables DFLL clock output. DFLL driver suspend confirms DFLL disable state and errors out on being active. DFLL is re-initialized during the DFLL driver resume as it goes through complete reset during suspend entry. Acked-by: Thierry Reding Reviewed-by: Dmitry Osipenko Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-dfll.c | 56 ++++++++++++++++++++++ drivers/clk/tegra/clk-dfll.h | 2 + drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 1 + 3 files changed, 59 insertions(+) diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index f8688c2ddf1a..c051d92c2bbf 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -1487,6 +1487,7 @@ static int dfll_init(struct tegra_dfll *td) td->last_unrounded_rate = 0; pm_runtime_enable(td->dev); + pm_runtime_irq_safe(td->dev); pm_runtime_get_sync(td->dev); dfll_set_mode(td, DFLL_DISABLED); @@ -1513,6 +1514,61 @@ di_err1: return ret; } +/** + * tegra_dfll_suspend - check DFLL is disabled + * @dev: DFLL device * + * + * DFLL clock should be disabled by the CPUFreq driver. So, make + * sure it is disabled and disable all clocks needed by the DFLL. + */ +int tegra_dfll_suspend(struct device *dev) +{ + struct tegra_dfll *td = dev_get_drvdata(dev); + + if (dfll_is_running(td)) { + dev_err(td->dev, "DFLL still enabled while suspending\n"); + return -EBUSY; + } + + reset_control_assert(td->dvco_rst); + + return 0; +} +EXPORT_SYMBOL(tegra_dfll_suspend); + +/** + * tegra_dfll_resume - reinitialize DFLL on resume + * @dev: DFLL instance + * + * DFLL is disabled and reset during suspend and resume. + * So, reinitialize the DFLL IP block back for use. + * DFLL clock is enabled later in closed loop mode by CPUFreq + * driver before switching its clock source to DFLL output. + */ +int tegra_dfll_resume(struct device *dev) +{ + struct tegra_dfll *td = dev_get_drvdata(dev); + + reset_control_deassert(td->dvco_rst); + + pm_runtime_get_sync(td->dev); + + dfll_set_mode(td, DFLL_DISABLED); + dfll_set_default_params(td); + + if (td->soc->init_clock_trimmers) + td->soc->init_clock_trimmers(); + + dfll_set_open_loop_config(td); + + dfll_init_out_if(td); + + pm_runtime_put_sync(td->dev); + + return 0; +} +EXPORT_SYMBOL(tegra_dfll_resume); + /* * DT data fetch */ diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h index 1b14ebe7268b..fb209eb5f365 100644 --- a/drivers/clk/tegra/clk-dfll.h +++ b/drivers/clk/tegra/clk-dfll.h @@ -42,5 +42,7 @@ int tegra_dfll_register(struct platform_device *pdev, struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev); int tegra_dfll_runtime_suspend(struct device *dev); int tegra_dfll_runtime_resume(struct device *dev); +int tegra_dfll_suspend(struct device *dev); +int tegra_dfll_resume(struct device *dev); #endif /* __DRIVERS_CLK_TEGRA_CLK_DFLL_H */ diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c index e84b6d52cbbd..2ac2679d696d 100644 --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c @@ -631,6 +631,7 @@ static int tegra124_dfll_fcpu_remove(struct platform_device *pdev) static const struct dev_pm_ops tegra124_dfll_pm_ops = { SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend, tegra_dfll_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(tegra_dfll_suspend, tegra_dfll_resume) }; static struct platform_driver tegra124_dfll_fcpu_driver = { From f68cbb35788e3d4e76638e4cc4cc1df9cac03587 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:58 -0700 Subject: [PATCH 139/160] clk: tegra: Use fence_udelay() during PLLU init This patch uses fence_udelay rather than udelay during PLLU initialization to ensure writes to clock registers happens before waiting for specified delay. Acked-by: Thierry Reding Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra210.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index d55f3da4287a..134ba423103d 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -2842,7 +2842,7 @@ static int tegra210_enable_pllu(void) reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]); reg &= ~BIT(pllu.params->iddq_bit_idx); writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]); - udelay(5); + fence_udelay(5, clk_base); reg = readl_relaxed(clk_base + PLLU_BASE); reg &= ~GENMASK(20, 0); @@ -2850,7 +2850,7 @@ static int tegra210_enable_pllu(void) reg |= fentry->n << 8; reg |= fentry->p << 16; writel(reg, clk_base + PLLU_BASE); - udelay(1); + fence_udelay(1, clk_base); reg |= PLL_ENABLE; writel(reg, clk_base + PLLU_BASE); @@ -2896,12 +2896,12 @@ static int tegra210_init_pllu(void) reg = readl_relaxed(clk_base + XUSB_PLL_CFG0); reg &= ~XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK; writel_relaxed(reg, clk_base + XUSB_PLL_CFG0); - udelay(1); + fence_udelay(1, clk_base); reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0); reg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE; writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0); - udelay(1); + fence_udelay(1, clk_base); reg = readl_relaxed(clk_base + PLLU_BASE); reg &= ~PLLU_BASE_CLKENABLE_USB; From 3214be6cb1e487b0f8c3bb2eac9b06df07a07e06 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:41:59 -0700 Subject: [PATCH 140/160] clk: tegra: Share clk and rst register defines with Tegra clock driver Move CLK_OUT_ENB and RST_DEVICES registers to clk.h to share these with Tegra clock driver. Signed-off-by: Sowjanya Komatineni Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk.c | 45 ----------------------------------------- drivers/clk/tegra/clk.h | 45 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index eb08047fd02f..33ac88ee324a 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -16,51 +16,6 @@ #include "clk.h" -#define CLK_OUT_ENB_L 0x010 -#define CLK_OUT_ENB_H 0x014 -#define CLK_OUT_ENB_U 0x018 -#define CLK_OUT_ENB_V 0x360 -#define CLK_OUT_ENB_W 0x364 -#define CLK_OUT_ENB_X 0x280 -#define CLK_OUT_ENB_Y 0x298 -#define CLK_ENB_PLLP_OUT_CPU BIT(31) -#define CLK_OUT_ENB_SET_L 0x320 -#define CLK_OUT_ENB_CLR_L 0x324 -#define CLK_OUT_ENB_SET_H 0x328 -#define CLK_OUT_ENB_CLR_H 0x32c -#define CLK_OUT_ENB_SET_U 0x330 -#define CLK_OUT_ENB_CLR_U 0x334 -#define CLK_OUT_ENB_SET_V 0x440 -#define CLK_OUT_ENB_CLR_V 0x444 -#define CLK_OUT_ENB_SET_W 0x448 -#define CLK_OUT_ENB_CLR_W 0x44c -#define CLK_OUT_ENB_SET_X 0x284 -#define CLK_OUT_ENB_CLR_X 0x288 -#define CLK_OUT_ENB_SET_Y 0x29c -#define CLK_OUT_ENB_CLR_Y 0x2a0 - -#define RST_DEVICES_L 0x004 -#define RST_DEVICES_H 0x008 -#define RST_DEVICES_U 0x00C -#define RST_DEVICES_V 0x358 -#define RST_DEVICES_W 0x35C -#define RST_DEVICES_X 0x28C -#define RST_DEVICES_Y 0x2a4 -#define RST_DEVICES_SET_L 0x300 -#define RST_DEVICES_CLR_L 0x304 -#define RST_DEVICES_SET_H 0x308 -#define RST_DEVICES_CLR_H 0x30c -#define RST_DEVICES_SET_U 0x310 -#define RST_DEVICES_CLR_U 0x314 -#define RST_DEVICES_SET_V 0x430 -#define RST_DEVICES_CLR_V 0x434 -#define RST_DEVICES_SET_W 0x438 -#define RST_DEVICES_CLR_W 0x43c -#define RST_DEVICES_SET_X 0x290 -#define RST_DEVICES_CLR_X 0x294 -#define RST_DEVICES_SET_Y 0x2a8 -#define RST_DEVICES_CLR_Y 0x2ac - /* Global data of Tegra CPU CAR ops */ static struct tegra_cpu_car_ops dummy_car_ops; struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 21bb0f24c6c1..3bb3d5f7b760 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -10,6 +10,51 @@ #include #include +#define CLK_OUT_ENB_L 0x010 +#define CLK_OUT_ENB_H 0x014 +#define CLK_OUT_ENB_U 0x018 +#define CLK_OUT_ENB_V 0x360 +#define CLK_OUT_ENB_W 0x364 +#define CLK_OUT_ENB_X 0x280 +#define CLK_OUT_ENB_Y 0x298 +#define CLK_ENB_PLLP_OUT_CPU BIT(31) +#define CLK_OUT_ENB_SET_L 0x320 +#define CLK_OUT_ENB_CLR_L 0x324 +#define CLK_OUT_ENB_SET_H 0x328 +#define CLK_OUT_ENB_CLR_H 0x32c +#define CLK_OUT_ENB_SET_U 0x330 +#define CLK_OUT_ENB_CLR_U 0x334 +#define CLK_OUT_ENB_SET_V 0x440 +#define CLK_OUT_ENB_CLR_V 0x444 +#define CLK_OUT_ENB_SET_W 0x448 +#define CLK_OUT_ENB_CLR_W 0x44c +#define CLK_OUT_ENB_SET_X 0x284 +#define CLK_OUT_ENB_CLR_X 0x288 +#define CLK_OUT_ENB_SET_Y 0x29c +#define CLK_OUT_ENB_CLR_Y 0x2a0 + +#define RST_DEVICES_L 0x004 +#define RST_DEVICES_H 0x008 +#define RST_DEVICES_U 0x00C +#define RST_DEVICES_V 0x358 +#define RST_DEVICES_W 0x35C +#define RST_DEVICES_X 0x28C +#define RST_DEVICES_Y 0x2a4 +#define RST_DEVICES_SET_L 0x300 +#define RST_DEVICES_CLR_L 0x304 +#define RST_DEVICES_SET_H 0x308 +#define RST_DEVICES_CLR_H 0x30c +#define RST_DEVICES_SET_U 0x310 +#define RST_DEVICES_CLR_U 0x314 +#define RST_DEVICES_SET_V 0x430 +#define RST_DEVICES_CLR_V 0x434 +#define RST_DEVICES_SET_W 0x438 +#define RST_DEVICES_CLR_W 0x43c +#define RST_DEVICES_SET_X 0x290 +#define RST_DEVICES_CLR_X 0x294 +#define RST_DEVICES_SET_Y 0x2a8 +#define RST_DEVICES_CLR_Y 0x2ac + /** * struct tegra_clk_sync_source - external clock source from codec * From 535f296d47de327287fe65b5843713bd9b01a267 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Fri, 16 Aug 2019 12:42:00 -0700 Subject: [PATCH 141/160] clk: tegra: Add suspend and resume support on Tegra210 All the CAR controller settings are lost on suspend when core power goes off. This implement saving and restoring context for all PLLs and clocks during system suspend and resume to have the clocks back to same state for normal operation. Clock driver suspend and resume are registered as syscore_ops as clocks restore need to happen before the other drivers resume to have all their clocks back to the same state as before suspend. Signed-off-by: Sowjanya Komatineni Reviewed-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra210.c | 96 ++++++++++++++++++++++++++++++-- drivers/clk/tegra/clk.c | 55 ++++++++++++++++++ drivers/clk/tegra/clk.h | 16 ++++++ 3 files changed, 163 insertions(+), 4 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 134ba423103d..d038fed3945d 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -9,13 +9,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include @@ -221,11 +221,15 @@ #define CLK_M_DIVISOR_SHIFT 2 #define CLK_M_DIVISOR_MASK 0x3 +#define CLK_MASK_ARM 0x44 +#define MISC_CLK_ENB 0x48 + #define RST_DFLL_DVCO 0x2f4 #define DVFS_DFLL_RESET_SHIFT 0 #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac +#define CPU_SOFTRST_CTRL 0x380 #define LVL2_CLK_GATE_OVRA 0xf8 #define LVL2_CLK_GATE_OVRC 0x3a0 @@ -2826,6 +2830,7 @@ static int tegra210_enable_pllu(void) struct tegra_clk_pll_freq_table *fentry; struct tegra_clk_pll pllu; u32 reg; + int ret; for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) { if (fentry->input_rate == pll_ref_freq) @@ -2854,9 +2859,14 @@ static int tegra210_enable_pllu(void) reg |= PLL_ENABLE; writel(reg, clk_base + PLLU_BASE); - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg, - reg & PLL_BASE_LOCK, 2, 1000); - if (!(reg & PLL_BASE_LOCK)) { + /* + * During clocks resume, same PLLU init and enable sequence get + * executed. So, readx_poll_timeout_atomic can't be used here as it + * uses ktime_get() and timekeeping resume doesn't happen by that + * time. So, using tegra210_wait_for_mask for PLL LOCK. + */ + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK); + if (ret) { pr_err("Timed out waiting for PLL_U to lock\n"); return -ETIMEDOUT; } @@ -3326,6 +3336,77 @@ static void tegra210_disable_cpu_clock(u32 cpu) } #ifdef CONFIG_PM_SLEEP +#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) + ((_off) * 4)) +#define car_writel(_val, _base, _off) \ + writel_relaxed(_val, clk_base + (_base) + ((_off) * 4)) + +static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx; +static u32 cpu_softrst_ctx[3]; + +static int tegra210_clk_suspend(void) +{ + unsigned int i; + + clk_save_context(); + + /* + * Save the bootloader configured clock registers SPARE_REG0, + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL. + */ + spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0); + misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB); + clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM); + + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) + cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i); + + tegra_clk_periph_suspend(); + return 0; +} + +static void tegra210_clk_resume(void) +{ + unsigned int i; + + tegra_clk_osc_resume(clk_base); + + /* + * Restore the bootloader configured clock registers SPARE_REG0, + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context. + */ + writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0); + writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB); + writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM); + + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) + car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i); + + /* + * Tegra clock programming sequence recommends peripheral clock to + * be enabled prior to changing its clock source and divider to + * prevent glitchless frequency switch. + * So, enable all peripheral clocks before restoring their source + * and dividers. + */ + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_L, clk_base + CLK_OUT_ENB_L); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_H, clk_base + CLK_OUT_ENB_H); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_U, clk_base + CLK_OUT_ENB_U); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_V, clk_base + CLK_OUT_ENB_V); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_W, clk_base + CLK_OUT_ENB_W); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_X, clk_base + CLK_OUT_ENB_X); + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_Y, clk_base + CLK_OUT_ENB_Y); + + /* wait for all writes to happen to have all the clocks enabled */ + fence_udelay(2, clk_base); + + /* restore PLLs and all peripheral clock rates */ + tegra210_init_pllu(); + clk_restore_context(); + + /* restore saved context of peripheral clocks and reset state */ + tegra_clk_periph_resume(); +} + static void tegra210_cpu_clock_suspend(void) { /* switch coresite to clk_m, save off original source */ @@ -3341,6 +3422,11 @@ static void tegra210_cpu_clock_resume(void) } #endif +static struct syscore_ops tegra_clk_syscore_ops = { + .suspend = tegra210_clk_suspend, + .resume = tegra210_clk_resume, +}; + static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { .wait_for_reset = tegra210_wait_cpu_in_reset, .disable_clock = tegra210_disable_cpu_clock, @@ -3625,5 +3711,7 @@ static void __init tegra210_clock_init(struct device_node *np) tegra210_mbist_clk_init(); tegra_cpu_car_ops = &tegra210_cpu_car_ops; + + register_syscore_ops(&tegra_clk_syscore_ops); } CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 33ac88ee324a..e6bd6d1ea012 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -22,6 +22,7 @@ struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; int *periph_clk_enb_refcnt; static int periph_banks; +static u32 *periph_state_ctx; static struct clk **clks; static int clk_num; static struct clk_onecell_data clk_data; @@ -168,6 +169,52 @@ void tegra_clk_set_pllp_out_cpu(bool enable) writel_relaxed(val, clk_base + CLK_OUT_ENB_Y); } +void tegra_clk_periph_suspend(void) +{ + unsigned int i, idx; + + idx = 0; + for (i = 0; i < periph_banks; i++, idx++) + periph_state_ctx[idx] = + readl_relaxed(clk_base + periph_regs[i].enb_reg); + + for (i = 0; i < periph_banks; i++, idx++) + periph_state_ctx[idx] = + readl_relaxed(clk_base + periph_regs[i].rst_reg); +} + +void tegra_clk_periph_resume(void) +{ + unsigned int i, idx; + + idx = 0; + for (i = 0; i < periph_banks; i++, idx++) + writel_relaxed(periph_state_ctx[idx], + clk_base + periph_regs[i].enb_reg); + /* + * All non-boot peripherals will be in reset state on resume. + * Wait for 5us of reset propagation delay before de-asserting + * the peripherals based on the saved context. + */ + fence_udelay(5, clk_base); + + for (i = 0; i < periph_banks; i++, idx++) + writel_relaxed(periph_state_ctx[idx], + clk_base + periph_regs[i].rst_reg); + + fence_udelay(2, clk_base); +} + +static int tegra_clk_periph_ctx_init(int banks) +{ + periph_state_ctx = kcalloc(2 * banks, sizeof(*periph_state_ctx), + GFP_KERNEL); + if (!periph_state_ctx) + return -ENOMEM; + + return 0; +} + struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) { clk_base = regs; @@ -189,6 +236,14 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) clk_num = num; + if (IS_ENABLED(CONFIG_PM_SLEEP)) { + if (tegra_clk_periph_ctx_init(banks)) { + kfree(periph_clk_enb_refcnt); + kfree(clks); + return NULL; + } + } + return clks; } diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 3bb3d5f7b760..416a6b09f6a3 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -55,6 +55,20 @@ #define RST_DEVICES_SET_Y 0x2a8 #define RST_DEVICES_CLR_Y 0x2ac +/* + * Tegra CLK_OUT_ENB registers have some undefined bits which are not used and + * any accidental write of 1 to these bits can cause PSLVERR. + * So below are the valid mask defines for each CLK_OUT_ENB register used to + * turn ON only the valid clocks. + */ +#define TEGRA210_CLK_ENB_VLD_MSK_L 0xdcd7dff9 +#define TEGRA210_CLK_ENB_VLD_MSK_H 0x87d1f3e7 +#define TEGRA210_CLK_ENB_VLD_MSK_U 0xf3fed3fa +#define TEGRA210_CLK_ENB_VLD_MSK_V 0xffc18cfb +#define TEGRA210_CLK_ENB_VLD_MSK_W 0x793fb7ff +#define TEGRA210_CLK_ENB_VLD_MSK_X 0x3fe66fff +#define TEGRA210_CLK_ENB_VLD_MSK_Y 0xfc1fc7ff + /** * struct tegra_clk_sync_source - external clock source from codec * @@ -880,6 +894,8 @@ int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, u8 frac_width, u8 flags); void tegra_clk_osc_resume(void __iomem *clk_base); void tegra_clk_set_pllp_out_cpu(bool enable); +void tegra_clk_periph_suspend(void); +void tegra_clk_periph_resume(void); /* Combined read fence with delay */ From 204ce75b897035447f29b1ec4423f9f25baf8a60 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Mon, 23 Sep 2019 00:52:03 +0300 Subject: [PATCH 142/160] clk: tegra: Optimize PLLX restore on Tegra20/30 There is no need to re-configure PLLX if its configuration in unchanged on return from suspend / cpuidle, this saves 300us if PLLX is already enabled (common case for cpuidle). Signed-off-by: Dmitry Osipenko Acked-by: Peter De Schrijver Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra20.c | 23 +++++++++++++++-------- drivers/clk/tegra/clk-tegra30.c | 23 +++++++++++++++-------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index cceefbd67a3b..4d8222f5c638 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -955,6 +955,7 @@ static void tegra20_cpu_clock_suspend(void) static void tegra20_cpu_clock_resume(void) { unsigned int reg, policy; + u32 misc, base; /* Is CPU complex already running on PLLX? */ reg = readl(clk_base + CCLK_BURST_POLICY); @@ -968,15 +969,21 @@ static void tegra20_cpu_clock_resume(void) BUG(); if (reg != CCLK_BURST_POLICY_PLLX) { - /* restore PLLX settings if CPU is on different PLL */ - writel(tegra20_cpu_clk_sctx.pllx_misc, - clk_base + PLLX_MISC); - writel(tegra20_cpu_clk_sctx.pllx_base, - clk_base + PLLX_BASE); + misc = readl_relaxed(clk_base + PLLX_MISC); + base = readl_relaxed(clk_base + PLLX_BASE); - /* wait for PLL stabilization if PLLX was enabled */ - if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30)) - udelay(300); + if (misc != tegra20_cpu_clk_sctx.pllx_misc || + base != tegra20_cpu_clk_sctx.pllx_base) { + /* restore PLLX settings if CPU is on different PLL */ + writel(tegra20_cpu_clk_sctx.pllx_misc, + clk_base + PLLX_MISC); + writel(tegra20_cpu_clk_sctx.pllx_base, + clk_base + PLLX_BASE); + + /* wait for PLL stabilization if PLLX was enabled */ + if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30)) + udelay(300); + } } /* diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 95b0e4a16dd5..c8bc18e4d7e5 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1163,6 +1163,7 @@ static void tegra30_cpu_clock_suspend(void) static void tegra30_cpu_clock_resume(void) { unsigned int reg, policy; + u32 misc, base; /* Is CPU complex already running on PLLX? */ reg = readl(clk_base + CLK_RESET_CCLK_BURST); @@ -1176,15 +1177,21 @@ static void tegra30_cpu_clock_resume(void) BUG(); if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) { - /* restore PLLX settings if CPU is on different PLL */ - writel(tegra30_cpu_clk_sctx.pllx_misc, - clk_base + CLK_RESET_PLLX_MISC); - writel(tegra30_cpu_clk_sctx.pllx_base, - clk_base + CLK_RESET_PLLX_BASE); + misc = readl_relaxed(clk_base + CLK_RESET_PLLX_MISC); + base = readl_relaxed(clk_base + CLK_RESET_PLLX_BASE); - /* wait for PLL stabilization if PLLX was enabled */ - if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) - udelay(300); + if (misc != tegra30_cpu_clk_sctx.pllx_misc || + base != tegra30_cpu_clk_sctx.pllx_base) { + /* restore PLLX settings if CPU is on different PLL */ + writel(tegra30_cpu_clk_sctx.pllx_misc, + clk_base + CLK_RESET_PLLX_MISC); + writel(tegra30_cpu_clk_sctx.pllx_base, + clk_base + CLK_RESET_PLLX_BASE); + + /* wait for PLL stabilization if PLLX was enabled */ + if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30)) + udelay(300); + } } /* From 5699d160550b1e480c920f8182bd4b73b8c9ae43 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 15 Oct 2019 20:00:06 +0300 Subject: [PATCH 143/160] clk: tegra: Add missing stubs for the case of !CONFIG_PM_SLEEP The new CPUIDLE driver uses the Tegra's CLK API and that driver won't strictly depend on CONFIG_PM_SLEEP, hence add the required stubs in order to allow compiling of the new driver with the CONFIG_PM_SLEEP=n. Signed-off-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- include/linux/clk/tegra.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index 6a7cbc3cfadc..2b1b35240074 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void) tegra_cpu_car_ops->resume(); } +#else +static inline bool tegra_cpu_rail_off_ready(void) +{ + return false; +} + +static inline void tegra_cpu_clock_suspend(void) +{ +} + +static inline void tegra_cpu_clock_resume(void) +{ +} #endif extern void tegra210_xusb_pll_hw_control_enable(void); From 07b293c5b01483f3c65372e72e62a2ee559ce1cf Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 30 Oct 2019 20:56:50 +0800 Subject: [PATCH 144/160] clk: tegra: Fix build error without CONFIG_PM_SLEEP If CONFIG_PM_SLEEP is n, build fails: drivers/clk/tegra/clk-tegra210.c:3426:13: error: tegra210_clk_suspend undeclared here (not in a function); did you mean tegra_clk_ndspeed? .suspend = tegra210_clk_suspend, ^~~~~~~~~~~~~~~~~~~~ tegra_clk_ndspeed drivers/clk/tegra/clk-tegra210.c:3427:12: error: tegra210_clk_resume undeclared here (not in a function); did you mean tegra210_clk_suspend? .resume = tegra210_clk_resume, Use ifdef to guard this. Reported-by: Hulk Robot Fixes: 27d10d548c04 ("clk: tegra: Add suspend and resume support on Tegra210") Signed-off-by: YueHaibing Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra210.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index d038fed3945d..762cd186f714 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -3423,8 +3423,10 @@ static void tegra210_cpu_clock_resume(void) #endif static struct syscore_ops tegra_clk_syscore_ops = { +#ifdef CONFIG_PM_SLEEP .suspend = tegra210_clk_suspend, .resume = tegra210_clk_resume, +#endif }; static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { From 3bdf364ada330e15842e1aa94f0738005d29667e Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 11 Nov 2019 22:04:20 +0800 Subject: [PATCH 145/160] clk: armada-xp: remove unused code drivers/clk/mvebu/armada-xp.c:171:38: warning: mv98dx3236_coreclks defined but not used [-Wunused-const-variable=] drivers/clk/mvebu/armada-xp.c:213:41: warning: mv98dx3236_gating_desc defined but not used [-Wunused-const-variable=] They are not used since commit 337072604224 ("clk: mvebu: Expand mv98dx3236-core-clock support"). Reported-by: Hulk Robot Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191111140420.36092-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-xp.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c index fa1568279c23..45665655a258 100644 --- a/drivers/clk/mvebu/armada-xp.c +++ b/drivers/clk/mvebu/armada-xp.c @@ -50,12 +50,6 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar) return 250000000; } -/* MV98DX3236 TCLK frequency is fixed to 200MHz */ -static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar) -{ - return 200000000; -} - static const u32 axp_cpu_freqs[] __initconst = { 1000000000, 1066000000, @@ -93,12 +87,6 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar) return cpu_freq; } -/* MV98DX3236 CLK frequency is fixed to 800MHz */ -static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar) -{ - return 800000000; -} - static const int axp_nbclk_ratios[32][2] __initconst = { {0, 1}, {1, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 1}, {2, 3}, @@ -168,11 +156,6 @@ static const struct coreclk_soc_desc axp_coreclks = { .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), }; -static const struct coreclk_soc_desc mv98dx3236_coreclks = { - .get_tclk_freq = mv98dx3236_get_tclk_freq, - .get_cpu_freq = mv98dx3236_get_cpu_freq, -}; - /* * Clock Gating Control */ @@ -210,15 +193,6 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = { { } }; -static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = { - { "ge1", NULL, 3, 0 }, - { "ge0", NULL, 4, 0 }, - { "pex00", NULL, 5, 0 }, - { "sdio", NULL, 17, 0 }, - { "xor0", NULL, 22, 0 }, - { } -}; - static void __init axp_clk_init(struct device_node *np) { struct device_node *cgnp = From 9629dbdabd1983ef53f125336e1d62d77b1620f9 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Tue, 8 Oct 2019 15:41:38 +0800 Subject: [PATCH 146/160] clk: sprd: Use IS_ERR() to validate the return value of syscon_regmap_lookup_by_phandle() The syscon_regmap_lookup_by_phandle() will never return NULL, thus use IS_ERR() to validate the return value instead of IS_ERR_OR_NULL(). Fixes: d41f59fd92f2 ("clk: sprd: Add common infrastructure") Signed-off-by: Baolin Wang Link: https://lkml.kernel.org/r/1995139bee5248ff3e9d46dc715968f212cfc4cc.1570520268.git.baolin.wang@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/sprd/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c index 9d56eac43832..7ad5ba26dfba 100644 --- a/drivers/clk/sprd/common.c +++ b/drivers/clk/sprd/common.c @@ -46,7 +46,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev, if (of_find_property(node, "sprd,syscon", NULL)) { regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); - if (IS_ERR_OR_NULL(regmap)) { + if (IS_ERR(regmap)) { pr_err("%s: failed to get syscon regmap\n", __func__); return PTR_ERR(regmap); } From 46acbcb4849b2ca2e6e975e7c8130c1d61c8fd0c Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 26 Oct 2019 21:44:20 +0200 Subject: [PATCH 147/160] clk: pxa: fix one of the pxa RTC clocks The pxa27x platforms have a single IP with 2 drivers, sa1100-rtc and rtc-pxa drivers. A previous patch fixed the sa1100-rtc case, but the pxa-rtc wasn't fixed. This patch completes the previous one. Fixes: 8b6d10345e16 ("clk: pxa: add missing pxa27x clocks for Irda and sa1100-rtc") Signed-off-by: Robert Jarzmik Link: https://lkml.kernel.org/r/20191026194420.11918-1-robert.jarzmik@free.fr Signed-off-by: Stephen Boyd --- drivers/clk/pxa/clk-pxa27x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 287fdeae7c7c..7b123105b5de 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -459,6 +459,7 @@ struct dummy_clk { }; static struct dummy_clk dummy_clks[] __initdata = { DUMMY_CLK(NULL, "pxa27x-gpio", "osc_32_768khz"), + DUMMY_CLK(NULL, "pxa-rtc", "osc_32_768khz"), DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"), DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"), }; From a31414e8c98dadbe0d31804804090e78ab1e0e9f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 9 Nov 2019 11:42:26 +0800 Subject: [PATCH 148/160] clk: tegra: Use match_string() helper to simplify the code match_string() returns the array index of a matching string. Use it instead of the open-coded implementation. Signed-off-by: YueHaibing Link: https://lkml.kernel.org/r/20191109034226.21044-1-yuehaibing@huawei.com Signed-off-by: Stephen Boyd --- drivers/clk/tegra/clk-emc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index ea39caf3d762..745f9faa98d8 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c @@ -403,20 +403,16 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, } timing->parent_index = 0xff; - for (i = 0; i < ARRAY_SIZE(emc_parent_clk_names); i++) { - if (!strcmp(emc_parent_clk_names[i], - __clk_get_name(timing->parent))) { - timing->parent_index = i; - break; - } - } - if (timing->parent_index == 0xff) { + i = match_string(emc_parent_clk_names, ARRAY_SIZE(emc_parent_clk_names), + __clk_get_name(timing->parent)); + if (i < 0) { pr_err("timing %pOF: %s is not a valid parent\n", node, __clk_get_name(timing->parent)); clk_put(timing->parent); return -EINVAL; } + timing->parent_index = i; return 0; } From 0b24748c3b26b9e55d195e11c7e9bed843ebff99 Mon Sep 17 00:00:00 2001 From: Zhou Yanjie Date: Sun, 10 Nov 2019 17:28:21 +0800 Subject: [PATCH 149/160] dt-bindings: clock: Add X1000 bindings. Add the clock bindings for the X1000 Soc from Ingenic. Signed-off-by: Zhou Yanjie Link: https://lkml.kernel.org/r/1573378102-72380-2-git-send-email-zhouyanjie@zoho.com Reviewed-by: Paul Cercueil Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/ingenic,cgu.txt | 1 + include/dt-bindings/clock/x1000-cgu.h | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 include/dt-bindings/clock/x1000-cgu.h diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.txt b/Documentation/devicetree/bindings/clock/ingenic,cgu.txt index ba5a442026b7..75598e655067 100644 --- a/Documentation/devicetree/bindings/clock/ingenic,cgu.txt +++ b/Documentation/devicetree/bindings/clock/ingenic,cgu.txt @@ -11,6 +11,7 @@ Required properties: * ingenic,jz4725b-cgu * ingenic,jz4770-cgu * ingenic,jz4780-cgu + * ingenic,x1000-cgu - reg : The address & length of the CGU registers. - clocks : List of phandle & clock specifiers for clocks external to the CGU. Two such external clocks should be specified - first the external crystal diff --git a/include/dt-bindings/clock/x1000-cgu.h b/include/dt-bindings/clock/x1000-cgu.h new file mode 100644 index 000000000000..bbaebaf7adb9 --- /dev/null +++ b/include/dt-bindings/clock/x1000-cgu.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This header provides clock numbers for the ingenic,x1000-cgu DT binding. + * + * They are roughly ordered as: + * - external clocks + * - PLLs + * - muxes/dividers in the order they appear in the x1000 programmers manual + * - gates in order of their bit in the CLKGR* registers + */ + +#ifndef __DT_BINDINGS_CLOCK_X1000_CGU_H__ +#define __DT_BINDINGS_CLOCK_X1000_CGU_H__ + +#define X1000_CLK_EXCLK 0 +#define X1000_CLK_RTCLK 1 +#define X1000_CLK_APLL 2 +#define X1000_CLK_MPLL 3 +#define X1000_CLK_SCLKA 4 +#define X1000_CLK_CPUMUX 5 +#define X1000_CLK_CPU 6 +#define X1000_CLK_L2CACHE 7 +#define X1000_CLK_AHB0 8 +#define X1000_CLK_AHB2PMUX 9 +#define X1000_CLK_AHB2 10 +#define X1000_CLK_PCLK 11 +#define X1000_CLK_DDR 12 +#define X1000_CLK_MAC 13 +#define X1000_CLK_MSCMUX 14 +#define X1000_CLK_MSC0 15 +#define X1000_CLK_MSC1 16 +#define X1000_CLK_SSIPLL 17 +#define X1000_CLK_SSIMUX 18 +#define X1000_CLK_SFC 19 +#define X1000_CLK_I2C0 20 +#define X1000_CLK_I2C1 21 +#define X1000_CLK_I2C2 22 +#define X1000_CLK_UART0 23 +#define X1000_CLK_UART1 24 +#define X1000_CLK_UART2 25 +#define X1000_CLK_SSI 26 +#define X1000_CLK_PDMA 27 + +#endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */ From b9df3997bb3e144e1e86d9da934b82f98c28865a Mon Sep 17 00:00:00 2001 From: Zhou Yanjie Date: Sun, 10 Nov 2019 17:28:22 +0800 Subject: [PATCH 150/160] clk: Ingenic: Add CGU driver for X1000. Add support for the clocks provided by the CGU in the Ingenic X1000 SoC, making use of the cgu code to do the heavy lifting. Signed-off-by: Zhou Yanjie Link: https://lkml.kernel.org/r/1573378102-72380-3-git-send-email-zhouyanjie@zoho.com Reviewed-by: Paul Cercueil Signed-off-by: Stephen Boyd --- drivers/clk/ingenic/Kconfig | 10 ++ drivers/clk/ingenic/Makefile | 1 + drivers/clk/ingenic/x1000-cgu.c | 274 ++++++++++++++++++++++++++++++++ 3 files changed, 285 insertions(+) create mode 100644 drivers/clk/ingenic/x1000-cgu.c diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig index 1cb489959a99..fb7b39961703 100644 --- a/drivers/clk/ingenic/Kconfig +++ b/drivers/clk/ingenic/Kconfig @@ -45,6 +45,16 @@ config INGENIC_CGU_JZ4780 If building for a JZ4780 SoC, you want to say Y here. +config INGENIC_CGU_X1000 + bool "Ingenic X1000 CGU driver" + default MACH_X1000 + select INGENIC_CGU_COMMON + help + Support the clocks provided by the CGU hardware on Ingenic X1000 + and compatible SoCs. + + If building for a X1000 SoC, you want to say Y here. + config INGENIC_TCU_CLK bool "Ingenic JZ47xx TCU clocks driver" default MACH_INGENIC diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile index 097220b05131..8b1dad9b74a7 100644 --- a/drivers/clk/ingenic/Makefile +++ b/drivers/clk/ingenic/Makefile @@ -4,4 +4,5 @@ obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o +obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c new file mode 100644 index 000000000000..b22d87b3f555 --- /dev/null +++ b/drivers/clk/ingenic/x1000-cgu.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * X1000 SoC CGU driver + * Copyright (c) 2019 Zhou Yanjie + */ + +#include +#include +#include +#include +#include "cgu.h" +#include "pm.h" + +/* CGU register offsets */ +#define CGU_REG_CPCCR 0x00 +#define CGU_REG_APLL 0x10 +#define CGU_REG_MPLL 0x14 +#define CGU_REG_CLKGR 0x20 +#define CGU_REG_OPCR 0x24 +#define CGU_REG_DDRCDR 0x2c +#define CGU_REG_MACCDR 0x54 +#define CGU_REG_I2SCDR 0x60 +#define CGU_REG_LPCDR 0x64 +#define CGU_REG_MSC0CDR 0x68 +#define CGU_REG_I2SCDR1 0x70 +#define CGU_REG_SSICDR 0x74 +#define CGU_REG_CIMCDR 0x7c +#define CGU_REG_PCMCDR 0x84 +#define CGU_REG_MSC1CDR 0xa4 +#define CGU_REG_CMP_INTR 0xb0 +#define CGU_REG_CMP_INTRE 0xb4 +#define CGU_REG_DRCG 0xd0 +#define CGU_REG_CPCSR 0xd4 +#define CGU_REG_PCMCDR1 0xe0 +#define CGU_REG_MACPHYC 0xe8 + +/* bits within the OPCR register */ +#define OPCR_SPENDN0 BIT(7) +#define OPCR_SPENDN1 BIT(6) + +static struct ingenic_cgu *cgu; + +static const s8 pll_od_encoding[8] = { + 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, +}; + +static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { + + /* External clocks */ + + [X1000_CLK_EXCLK] = { "ext", CGU_CLK_EXT }, + [X1000_CLK_RTCLK] = { "rtc", CGU_CLK_EXT }, + + /* PLLs */ + + [X1000_CLK_APLL] = { + "apll", CGU_CLK_PLL, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .pll = { + .reg = CGU_REG_APLL, + .m_shift = 24, + .m_bits = 7, + .m_offset = 1, + .n_shift = 18, + .n_bits = 5, + .n_offset = 1, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .bypass_bit = 9, + .enable_bit = 8, + .stable_bit = 10, + }, + }, + + [X1000_CLK_MPLL] = { + "mpll", CGU_CLK_PLL, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .pll = { + .reg = CGU_REG_MPLL, + .m_shift = 24, + .m_bits = 7, + .m_offset = 1, + .n_shift = 18, + .n_bits = 5, + .n_offset = 1, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .bypass_bit = 6, + .enable_bit = 7, + .stable_bit = 0, + }, + }, + + /* Muxes & dividers */ + + [X1000_CLK_SCLKA] = { + "sclk_a", CGU_CLK_MUX, + .parents = { -1, X1000_CLK_EXCLK, X1000_CLK_APLL, -1 }, + .mux = { CGU_REG_CPCCR, 30, 2 }, + }, + + [X1000_CLK_CPUMUX] = { + "cpu_mux", CGU_CLK_MUX, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_CPCCR, 28, 2 }, + }, + + [X1000_CLK_CPU] = { + "cpu", CGU_CLK_DIV, + .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, + }, + + [X1000_CLK_L2CACHE] = { + "l2cache", CGU_CLK_DIV, + .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, + }, + + [X1000_CLK_AHB0] = { + "ahb0", CGU_CLK_MUX | CGU_CLK_DIV, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_CPCCR, 26, 2 }, + .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 }, + }, + + [X1000_CLK_AHB2PMUX] = { + "ahb2_apb_mux", CGU_CLK_MUX, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_CPCCR, 24, 2 }, + }, + + [X1000_CLK_AHB2] = { + "ahb2", CGU_CLK_DIV, + .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 }, + }, + + [X1000_CLK_PCLK] = { + "pclk", CGU_CLK_DIV, + .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, + .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 }, + }, + + [X1000_CLK_DDR] = { + "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, + .mux = { CGU_REG_DDRCDR, 30, 2 }, + .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 31 }, + }, + + [X1000_CLK_MAC] = { + "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL}, + .mux = { CGU_REG_MACCDR, 31, 1 }, + .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 25 }, + }, + + [X1000_CLK_MSCMUX] = { + "msc_mux", CGU_CLK_MUX, + .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL}, + .mux = { CGU_REG_MSC0CDR, 31, 1 }, + }, + + [X1000_CLK_MSC0] = { + "msc0", CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, + .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 4 }, + }, + + [X1000_CLK_MSC1] = { + "msc1", CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, + .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, + .gate = { CGU_REG_CLKGR, 5 }, + }, + + [X1000_CLK_SSIPLL] = { + "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, + .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 }, + .mux = { CGU_REG_SSICDR, 31, 1 }, + .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, + }, + + [X1000_CLK_SSIMUX] = { + "ssi_mux", CGU_CLK_MUX, + .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 }, + .mux = { CGU_REG_SSICDR, 30, 1 }, + }, + + /* Gate-only clocks */ + + [X1000_CLK_SFC] = { + "sfc", CGU_CLK_GATE, + .parents = { X1000_CLK_SSIPLL, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 2 }, + }, + + [X1000_CLK_I2C0] = { + "i2c0", CGU_CLK_GATE, + .parents = { X1000_CLK_PCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 7 }, + }, + + [X1000_CLK_I2C1] = { + "i2c1", CGU_CLK_GATE, + .parents = { X1000_CLK_PCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 8 }, + }, + + [X1000_CLK_I2C2] = { + "i2c2", CGU_CLK_GATE, + .parents = { X1000_CLK_PCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 9 }, + }, + + [X1000_CLK_UART0] = { + "uart0", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 14 }, + }, + + [X1000_CLK_UART1] = { + "uart1", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 15 }, + }, + + [X1000_CLK_UART2] = { + "uart2", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 16 }, + }, + + [X1000_CLK_SSI] = { + "ssi", CGU_CLK_GATE, + .parents = { X1000_CLK_SSIMUX, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 19 }, + }, + + [X1000_CLK_PDMA] = { + "pdma", CGU_CLK_GATE, + .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR, 21 }, + }, +}; + +static void __init x1000_cgu_init(struct device_node *np) +{ + int retval; + + cgu = ingenic_cgu_new(x1000_cgu_clocks, + ARRAY_SIZE(x1000_cgu_clocks), np); + if (!cgu) { + pr_err("%s: failed to initialise CGU\n", __func__); + return; + } + + retval = ingenic_cgu_register_clocks(cgu); + if (retval) { + pr_err("%s: failed to register CGU Clocks\n", __func__); + return; + } + + ingenic_cgu_register_syscore_ops(cgu); +} +CLK_OF_DECLARE(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init); From 8247470772beb38822f226c99a2ed8c195f6b438 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Tue, 22 Oct 2019 12:41:53 +0530 Subject: [PATCH 151/160] clk: Fix memory leak in clk_unregister() Memory allocated in alloc_clk() for 'struct clk' and 'const char *con_id' while invoking clk_register() is never freed in clk_unregister(), resulting in kmemleak showing the following backtrace. backtrace: [<00000000546f5dd0>] kmem_cache_alloc+0x18c/0x270 [<0000000073a32862>] alloc_clk+0x30/0x70 [<0000000082942480>] __clk_register+0xc8/0x760 [<000000005c859fca>] devm_clk_register+0x54/0xb0 [<00000000868834a8>] 0xffff800008c60950 [<00000000d5a80534>] platform_drv_probe+0x50/0xa0 [<000000001b3889fc>] really_probe+0x108/0x348 [<00000000953fa60a>] driver_probe_device+0x58/0x100 [<0000000008acc17c>] device_driver_attach+0x6c/0x90 [<0000000022813df3>] __driver_attach+0x84/0xc8 [<00000000448d5443>] bus_for_each_dev+0x74/0xc8 [<00000000294aa93f>] driver_attach+0x20/0x28 [<00000000e5e52626>] bus_add_driver+0x148/0x1f0 [<000000001de21efc>] driver_register+0x60/0x110 [<00000000af07c068>] __platform_driver_register+0x40/0x48 [<0000000060fa80ee>] 0xffff800008c66020 Fix it here. Cc: Tomi Valkeinen Cc: Tero Kristo Signed-off-by: Kishon Vijay Abraham I Link: https://lkml.kernel.org/r/20191022071153.21118-1-kishon@ti.com Fixes: 1df4046a93e0 ("clk: Combine __clk_get() and __clk_create_clk()") Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 1c677d7f7f53..2f2eea26c375 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3879,6 +3879,7 @@ void clk_unregister(struct clk *clk) __func__, clk->core->name); kref_put(&clk->core->ref, __clk_release); + free_clk(clk); unlock: clk_prepare_unlock(); } From 564f86d384755e3fbb5c00703d3695df89c1e049 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 4 Oct 2019 11:48:25 +0200 Subject: [PATCH 152/160] clk: mark clk_disable_unused() as __init clk_disable_unused is only called once, as a late_initcall, so reclaim a bit of memory by marking it (and the functions and data it is the sole user of) as __init/__initdata. This moves ~1900 bytes from .text to .init.text for a imx_v6_v7_defconfig. Signed-off-by: Rasmus Villemoes Link: https://lkml.kernel.org/r/20191004094826.8320-1-linux@rasmusvillemoes.dk Reviewed-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 2f2eea26c375..8fafdad9403e 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1187,7 +1187,7 @@ static void clk_core_disable_unprepare(struct clk_core *core) clk_core_unprepare_lock(core); } -static void clk_unprepare_unused_subtree(struct clk_core *core) +static void __init clk_unprepare_unused_subtree(struct clk_core *core) { struct clk_core *child; @@ -1217,7 +1217,7 @@ static void clk_unprepare_unused_subtree(struct clk_core *core) clk_pm_runtime_put(core); } -static void clk_disable_unused_subtree(struct clk_core *core) +static void __init clk_disable_unused_subtree(struct clk_core *core) { struct clk_core *child; unsigned long flags; @@ -1263,7 +1263,7 @@ unprepare_out: clk_core_disable_unprepare(core->parent); } -static bool clk_ignore_unused; +static bool clk_ignore_unused __initdata; static int __init clk_ignore_unused_setup(char *__unused) { clk_ignore_unused = true; @@ -1271,7 +1271,7 @@ static int __init clk_ignore_unused_setup(char *__unused) } __setup("clk_ignore_unused", clk_ignore_unused_setup); -static int clk_disable_unused(void) +static int __init clk_disable_unused(void) { struct clk_core *core; From 8f39f22f73b3066623d488d3a54dd669575b56dc Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 21 Nov 2019 11:07:26 +0100 Subject: [PATCH 153/160] MAINTAINERS: Update section for Ux500 clock drivers There's no longer any need host a tree solely to serve changes for the Ux500 clock driver, thus drop this from the corresponding section and use the common clk tree instead. Moreover, let's also add the generic linux-clk mailing list and rename the section header. Cc: Linus Walleij Signed-off-by: Ulf Hansson Link: https://lkml.kernel.org/r/20191121100726.17725-1-ulf.hansson@linaro.org Reviewed-by: Linus Walleij Signed-off-by: Stephen Boyd --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 296de2b51c83..753a84cfd753 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2490,10 +2490,10 @@ F: drivers/reset/reset-uniphier.c F: drivers/tty/serial/8250/8250_uniphier.c N: uniphier -ARM/Ux500 CLOCK FRAMEWORK SUPPORT +Ux500 CLOCK DRIVERS M: Ulf Hansson +L: linux-clk@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -T: git git://git.linaro.org/people/ulfh/clk.git S: Maintained F: drivers/clk/ux500/ From cd94eade0b2ab7673a97223d09406abf668b7f73 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 13 Nov 2019 16:19:25 -0800 Subject: [PATCH 154/160] clk: ingenic: Allow drivers to be built with COMPILE_TEST We don't need the MIPS architecture or even a MIPS compiler to compile test these drivers. Let's add a COMPILE_TEST possibility on the menuconfig here so that we can build these drivers on more configurations. Cc: Paul Cercueil Signed-off-by: Stephen Boyd Link: https://lkml.kernel.org/r/20191114001925.159276-1-sboyd@kernel.org Reviewed-by: Paul Cercueil --- drivers/clk/ingenic/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig index fb7b39961703..b4555b465ea6 100644 --- a/drivers/clk/ingenic/Kconfig +++ b/drivers/clk/ingenic/Kconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only menu "Ingenic SoCs drivers" - depends on MIPS + depends on MIPS || COMPILE_TEST config INGENIC_CGU_COMMON bool From cc819cf8d4760fac260e91dcf5c432abece3fcd2 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 15 Nov 2019 21:58:55 +0530 Subject: [PATCH 155/160] clk: Zero init clk_init_data in helpers The clk_init_data struct needs to be initialized to zero for the new parent_map implementation to work correctly. Otherwise, the member which is available first will get processed. Signed-off-by: Manivannan Sadhasivam Link: https://lkml.kernel.org/r/20191115162901.17456-2-manivannan.sadhasivam@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/clk-composite.c | 2 +- drivers/clk/clk-divider.c | 2 +- drivers/clk/clk-fixed-rate.c | 2 +- drivers/clk/clk-gate.c | 2 +- drivers/clk/clk-mux.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 4f13a681ddfc..28aaf4a3b28a 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -207,7 +207,7 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, unsigned long flags) { struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_composite *composite; struct clk_ops *clk_composite_ops; int ret; diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 3f9ff78c4a2a..098b2b01f0af 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -471,7 +471,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name, { struct clk_divider *div; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index a7e4aef7a376..2c4486c09040 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -58,7 +58,7 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev, { struct clk_fixed_rate *fixed; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; /* allocate fixed-rate clock */ diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 1b99fc962745..670053c58c1a 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -141,7 +141,7 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, { struct clk_gate *gate; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 66e91f740508..570b6e5b603b 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -153,7 +153,7 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, { struct clk_mux *mux; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; u8 width = 0; int ret; From d8549bcd0529fcbd064c0e106f0a8806cab7546f Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 15 Nov 2019 21:58:56 +0530 Subject: [PATCH 156/160] clk: Add clk_hw_unregister_composite helper function definition This function has been delcared but not defined anywhere. Hence, this commit adds definition for it. Fixes: 49cb392d3639 ("clk: composite: Add hw based registration APIs") Signed-off-by: Manivannan Sadhasivam Link: https://lkml.kernel.org/r/20191115162901.17456-3-manivannan.sadhasivam@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/clk-composite.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 28aaf4a3b28a..3e9c3e608769 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -343,3 +343,14 @@ void clk_unregister_composite(struct clk *clk) clk_unregister(clk); kfree(composite); } + +void clk_hw_unregister_composite(struct clk_hw *hw) +{ + struct clk_composite *composite; + + composite = to_clk_composite(hw); + + clk_hw_unregister(hw); + kfree(composite); +} +EXPORT_SYMBOL_GPL(clk_hw_unregister_composite); From 7046c6b018912726947d75c4cacf03ca51267f59 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 15 Nov 2019 21:58:57 +0530 Subject: [PATCH 157/160] dt-bindings: clock: Add devicetree binding for BM1880 SoC Add YAML devicetree binding for Bitmain BM1880 SoC. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Rob Herring Link: https://lkml.kernel.org/r/20191115162901.17456-4-manivannan.sadhasivam@linaro.org Signed-off-by: Stephen Boyd --- .../bindings/clock/bitmain,bm1880-clk.yaml | 76 +++++++++++++++++ include/dt-bindings/clock/bm1880-clock.h | 82 +++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml create mode 100644 include/dt-bindings/clock/bm1880-clock.h diff --git a/Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml b/Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml new file mode 100644 index 000000000000..e63827399c1a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/bindings/clock/bitmain,bm1880-clk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bitmain BM1880 Clock Controller + +maintainers: + - Manivannan Sadhasivam + +description: | + The Bitmain BM1880 clock controller generates and supplies clock to + various peripherals within the SoC. + + This binding uses common clock bindings + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +properties: + compatible: + const: bitmain,bm1880-clk + + reg: + items: + - description: pll registers + - description: system registers + + reg-names: + items: + - const: pll + - const: sys + + clocks: + maxItems: 1 + + clock-names: + const: osc + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + # Clock controller node: + - | + clk: clock-controller@e8 { + compatible = "bitmain,bm1880-clk"; + reg = <0xe8 0x0c>, <0x800 0xb0>; + reg-names = "pll", "sys"; + clocks = <&osc>; + clock-names = "osc"; + #clock-cells = <1>; + }; + + # Example UART controller node that consumes clock generated by the clock controller: + - | + uart0: serial@58018000 { + compatible = "snps,dw-apb-uart"; + reg = <0x0 0x58018000 0x0 0x2000>; + clocks = <&clk 45>, <&clk 46>; + clock-names = "baudclk", "apb_pclk"; + interrupts = <0 9 4>; + reg-shift = <2>; + reg-io-width = <4>; + }; + +... diff --git a/include/dt-bindings/clock/bm1880-clock.h b/include/dt-bindings/clock/bm1880-clock.h new file mode 100644 index 000000000000..b46732361b25 --- /dev/null +++ b/include/dt-bindings/clock/bm1880-clock.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Device Tree binding constants for Bitmain BM1880 SoC + * + * Copyright (c) 2019 Linaro Ltd. + */ + +#ifndef __DT_BINDINGS_CLOCK_BM1880_H +#define __DT_BINDINGS_CLOCK_BM1880_H + +#define BM1880_CLK_OSC 0 +#define BM1880_CLK_MPLL 1 +#define BM1880_CLK_SPLL 2 +#define BM1880_CLK_FPLL 3 +#define BM1880_CLK_DDRPLL 4 +#define BM1880_CLK_A53 5 +#define BM1880_CLK_50M_A53 6 +#define BM1880_CLK_AHB_ROM 7 +#define BM1880_CLK_AXI_SRAM 8 +#define BM1880_CLK_DDR_AXI 9 +#define BM1880_CLK_EFUSE 10 +#define BM1880_CLK_APB_EFUSE 11 +#define BM1880_CLK_AXI5_EMMC 12 +#define BM1880_CLK_EMMC 13 +#define BM1880_CLK_100K_EMMC 14 +#define BM1880_CLK_AXI5_SD 15 +#define BM1880_CLK_SD 16 +#define BM1880_CLK_100K_SD 17 +#define BM1880_CLK_500M_ETH0 18 +#define BM1880_CLK_AXI4_ETH0 19 +#define BM1880_CLK_500M_ETH1 20 +#define BM1880_CLK_AXI4_ETH1 21 +#define BM1880_CLK_AXI1_GDMA 22 +#define BM1880_CLK_APB_GPIO 23 +#define BM1880_CLK_APB_GPIO_INTR 24 +#define BM1880_CLK_GPIO_DB 25 +#define BM1880_CLK_AXI1_MINER 26 +#define BM1880_CLK_AHB_SF 27 +#define BM1880_CLK_SDMA_AXI 28 +#define BM1880_CLK_SDMA_AUD 29 +#define BM1880_CLK_APB_I2C 30 +#define BM1880_CLK_APB_WDT 31 +#define BM1880_CLK_APB_JPEG 32 +#define BM1880_CLK_JPEG_AXI 33 +#define BM1880_CLK_AXI5_NF 34 +#define BM1880_CLK_APB_NF 35 +#define BM1880_CLK_NF 36 +#define BM1880_CLK_APB_PWM 37 +#define BM1880_CLK_DIV_0_RV 38 +#define BM1880_CLK_DIV_1_RV 39 +#define BM1880_CLK_MUX_RV 40 +#define BM1880_CLK_RV 41 +#define BM1880_CLK_APB_SPI 42 +#define BM1880_CLK_TPU_AXI 43 +#define BM1880_CLK_DIV_UART_500M 44 +#define BM1880_CLK_UART_500M 45 +#define BM1880_CLK_APB_UART 46 +#define BM1880_CLK_APB_I2S 47 +#define BM1880_CLK_AXI4_USB 48 +#define BM1880_CLK_APB_USB 49 +#define BM1880_CLK_125M_USB 50 +#define BM1880_CLK_33K_USB 51 +#define BM1880_CLK_DIV_12M_USB 52 +#define BM1880_CLK_12M_USB 53 +#define BM1880_CLK_APB_VIDEO 54 +#define BM1880_CLK_VIDEO_AXI 55 +#define BM1880_CLK_VPP_AXI 56 +#define BM1880_CLK_APB_VPP 57 +#define BM1880_CLK_DIV_0_AXI1 58 +#define BM1880_CLK_DIV_1_AXI1 59 +#define BM1880_CLK_AXI1 60 +#define BM1880_CLK_AXI2 61 +#define BM1880_CLK_AXI3 62 +#define BM1880_CLK_AXI4 63 +#define BM1880_CLK_AXI5 64 +#define BM1880_CLK_DIV_0_AXI6 65 +#define BM1880_CLK_DIV_1_AXI6 66 +#define BM1880_CLK_MUX_AXI6 67 +#define BM1880_CLK_AXI6 68 +#define BM1880_NR_CLKS 69 + +#endif /* __DT_BINDINGS_CLOCK_BM1880_H */ From 1ab4601da55be5d6374cca66f9ed9074763ca0a1 Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 15 Nov 2019 21:59:00 +0530 Subject: [PATCH 158/160] clk: Add common clock driver for BM1880 SoC Add common clock driver for Bitmain BM1880 SoC. The clock controller on BM1880 has supplies clocks to all peripherals in the form of gate clocks and composite clocks (fixed factor + gate). Signed-off-by: Manivannan Sadhasivam Link: https://lkml.kernel.org/r/20191115162901.17456-7-manivannan.sadhasivam@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/Kconfig | 7 + drivers/clk/Makefile | 1 + drivers/clk/clk-bm1880.c | 969 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 977 insertions(+) create mode 100644 drivers/clk/clk-bm1880.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c44247d0b83e..dc920daa6dbb 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -136,6 +136,13 @@ config COMMON_CLK_SI570 This driver supports Silicon Labs 570/571/598/599 programmable clock generators. +config COMMON_CLK_BM1880 + bool "Clock driver for Bitmain BM1880 SoC" + depends on ARCH_BITMAIN || COMPILE_TEST + default ARCH_BITMAIN + help + This driver supports the clocks on Bitmain BM1880 SoC. + config COMMON_CLK_CDCE706 tristate "Clock driver for TI CDCE706 clock synthesizer" depends on I2C diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 0138fb14e6f8..0696a0c1ab58 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o obj-$(CONFIG_COMMON_CLK_BD718XX) += clk-bd718x7.o +obj-$(CONFIG_COMMON_CLK_BM1880) += clk-bm1880.o obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c new file mode 100644 index 000000000000..4cd175afce9b --- /dev/null +++ b/drivers/clk/clk-bm1880.c @@ -0,0 +1,969 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Bitmain BM1880 SoC clock driver + * + * Copyright (c) 2019 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define BM1880_CLK_MPLL_CTL 0x00 +#define BM1880_CLK_SPLL_CTL 0x04 +#define BM1880_CLK_FPLL_CTL 0x08 +#define BM1880_CLK_DDRPLL_CTL 0x0c + +#define BM1880_CLK_ENABLE0 0x00 +#define BM1880_CLK_ENABLE1 0x04 +#define BM1880_CLK_SELECT 0x20 +#define BM1880_CLK_DIV0 0x40 +#define BM1880_CLK_DIV1 0x44 +#define BM1880_CLK_DIV2 0x48 +#define BM1880_CLK_DIV3 0x4c +#define BM1880_CLK_DIV4 0x50 +#define BM1880_CLK_DIV5 0x54 +#define BM1880_CLK_DIV6 0x58 +#define BM1880_CLK_DIV7 0x5c +#define BM1880_CLK_DIV8 0x60 +#define BM1880_CLK_DIV9 0x64 +#define BM1880_CLK_DIV10 0x68 +#define BM1880_CLK_DIV11 0x6c +#define BM1880_CLK_DIV12 0x70 +#define BM1880_CLK_DIV13 0x74 +#define BM1880_CLK_DIV14 0x78 +#define BM1880_CLK_DIV15 0x7c +#define BM1880_CLK_DIV16 0x80 +#define BM1880_CLK_DIV17 0x84 +#define BM1880_CLK_DIV18 0x88 +#define BM1880_CLK_DIV19 0x8c +#define BM1880_CLK_DIV20 0x90 +#define BM1880_CLK_DIV21 0x94 +#define BM1880_CLK_DIV22 0x98 +#define BM1880_CLK_DIV23 0x9c +#define BM1880_CLK_DIV24 0xa0 +#define BM1880_CLK_DIV25 0xa4 +#define BM1880_CLK_DIV26 0xa8 +#define BM1880_CLK_DIV27 0xac +#define BM1880_CLK_DIV28 0xb0 + +#define to_bm1880_pll_clk(_hw) container_of(_hw, struct bm1880_pll_hw_clock, hw) +#define to_bm1880_div_clk(_hw) container_of(_hw, struct bm1880_div_hw_clock, hw) + +static DEFINE_SPINLOCK(bm1880_clk_lock); + +struct bm1880_clock_data { + void __iomem *pll_base; + void __iomem *sys_base; + struct clk_hw_onecell_data hw_data; +}; + +struct bm1880_gate_clock { + unsigned int id; + const char *name; + const char *parent; + u32 gate_reg; + s8 gate_shift; + unsigned long flags; +}; + +struct bm1880_mux_clock { + unsigned int id; + const char *name; + const char * const *parents; + s8 num_parents; + u32 reg; + s8 shift; + unsigned long flags; +}; + +struct bm1880_div_clock { + unsigned int id; + const char *name; + u32 reg; + u8 shift; + u8 width; + u32 initval; + const struct clk_div_table *table; + unsigned long flags; +}; + +struct bm1880_div_hw_clock { + struct bm1880_div_clock div; + void __iomem *base; + spinlock_t *lock; + struct clk_hw hw; + struct clk_init_data init; +}; + +struct bm1880_composite_clock { + unsigned int id; + const char *name; + const char *parent; + const char * const *parents; + unsigned int num_parents; + unsigned long flags; + + u32 gate_reg; + u32 mux_reg; + u32 div_reg; + + s8 gate_shift; + s8 mux_shift; + s8 div_shift; + s8 div_width; + s16 div_initval; + const struct clk_div_table *table; +}; + +struct bm1880_pll_clock { + unsigned int id; + const char *name; + u32 reg; + unsigned long flags; +}; + +struct bm1880_pll_hw_clock { + struct bm1880_pll_clock pll; + void __iomem *base; + struct clk_hw hw; + struct clk_init_data init; +}; + +static const struct clk_ops bm1880_pll_ops; +static const struct clk_ops bm1880_clk_div_ops; + +#define GATE_DIV(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \ + _div_shift, _div_width, _div_initval, _table, \ + _flags) { \ + .id = _id, \ + .parent = _parent, \ + .name = _name, \ + .gate_reg = _gate_reg, \ + .gate_shift = _gate_shift, \ + .div_reg = _div_reg, \ + .div_shift = _div_shift, \ + .div_width = _div_width, \ + .div_initval = _div_initval, \ + .table = _table, \ + .mux_shift = -1, \ + .flags = _flags, \ + } + +#define GATE_MUX(_id, _name, _parents, _gate_reg, _gate_shift, \ + _mux_reg, _mux_shift, _flags) { \ + .id = _id, \ + .parents = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .name = _name, \ + .gate_reg = _gate_reg, \ + .gate_shift = _gate_shift, \ + .div_shift = -1, \ + .mux_reg = _mux_reg, \ + .mux_shift = _mux_shift, \ + .flags = _flags, \ + } + +#define CLK_PLL(_id, _name, _parent, _reg, _flags) { \ + .pll.id = _id, \ + .pll.name = _name, \ + .pll.reg = _reg, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, \ + &bm1880_pll_ops, \ + _flags), \ + } + +#define CLK_DIV(_id, _name, _parent, _reg, _shift, _width, _initval, \ + _table, _flags) { \ + .div.id = _id, \ + .div.name = _name, \ + .div.reg = _reg, \ + .div.shift = _shift, \ + .div.width = _width, \ + .div.initval = _initval, \ + .div.table = _table, \ + .hw.init = CLK_HW_INIT_HW(_name, _parent, \ + &bm1880_clk_div_ops, \ + _flags), \ + } + +static struct clk_parent_data bm1880_pll_parent[] = { + { .fw_name = "osc", .name = "osc" }, +}; + +/* + * All PLL clocks are marked as CRITICAL, hence they are very crucial + * for the functioning of the SoC + */ +static struct bm1880_pll_hw_clock bm1880_pll_clks[] = { + CLK_PLL(BM1880_CLK_MPLL, "clk_mpll", bm1880_pll_parent, + BM1880_CLK_MPLL_CTL, 0), + CLK_PLL(BM1880_CLK_SPLL, "clk_spll", bm1880_pll_parent, + BM1880_CLK_SPLL_CTL, 0), + CLK_PLL(BM1880_CLK_FPLL, "clk_fpll", bm1880_pll_parent, + BM1880_CLK_FPLL_CTL, 0), + CLK_PLL(BM1880_CLK_DDRPLL, "clk_ddrpll", bm1880_pll_parent, + BM1880_CLK_DDRPLL_CTL, 0), +}; + +/* + * Clocks marked as CRITICAL are needed for the proper functioning + * of the SoC. + */ +static const struct bm1880_gate_clock bm1880_gate_clks[] = { + { BM1880_CLK_AHB_ROM, "clk_ahb_rom", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 2, 0 }, + { BM1880_CLK_AXI_SRAM, "clk_axi_sram", "clk_axi1", + BM1880_CLK_ENABLE0, 3, 0 }, + /* + * Since this clock is sourcing the DDR memory, let's mark it as + * critical to avoid gating. + */ + { BM1880_CLK_DDR_AXI, "clk_ddr_axi", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 4, CLK_IS_CRITICAL }, + { BM1880_CLK_APB_EFUSE, "clk_apb_efuse", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 6, 0 }, + { BM1880_CLK_AXI5_EMMC, "clk_axi5_emmc", "clk_axi5", + BM1880_CLK_ENABLE0, 7, 0 }, + { BM1880_CLK_AXI5_SD, "clk_axi5_sd", "clk_axi5", + BM1880_CLK_ENABLE0, 10, 0 }, + { BM1880_CLK_AXI4_ETH0, "clk_axi4_eth0", "clk_axi4", + BM1880_CLK_ENABLE0, 14, 0 }, + { BM1880_CLK_AXI4_ETH1, "clk_axi4_eth1", "clk_axi4", + BM1880_CLK_ENABLE0, 16, 0 }, + { BM1880_CLK_AXI1_GDMA, "clk_axi1_gdma", "clk_axi1", + BM1880_CLK_ENABLE0, 17, 0 }, + /* Don't gate GPIO clocks as it is not owned by the GPIO driver */ + { BM1880_CLK_APB_GPIO, "clk_apb_gpio", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 18, CLK_IGNORE_UNUSED }, + { BM1880_CLK_APB_GPIO_INTR, "clk_apb_gpio_intr", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 19, CLK_IGNORE_UNUSED }, + { BM1880_CLK_AXI1_MINER, "clk_axi1_miner", "clk_axi1", + BM1880_CLK_ENABLE0, 21, 0 }, + { BM1880_CLK_AHB_SF, "clk_ahb_sf", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 22, 0 }, + /* + * Not sure which module this clock is sourcing but gating this clock + * prevents the system from booting. So, let's mark it as critical. + */ + { BM1880_CLK_SDMA_AXI, "clk_sdma_axi", "clk_axi5", + BM1880_CLK_ENABLE0, 23, CLK_IS_CRITICAL }, + { BM1880_CLK_APB_I2C, "clk_apb_i2c", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 25, 0 }, + { BM1880_CLK_APB_WDT, "clk_apb_wdt", "clk_mux_axi6", + BM1880_CLK_ENABLE0, 26, 0 }, + { BM1880_CLK_APB_JPEG, "clk_apb_jpeg", "clk_axi6", + BM1880_CLK_ENABLE0, 27, 0 }, + { BM1880_CLK_AXI5_NF, "clk_axi5_nf", "clk_axi5", + BM1880_CLK_ENABLE0, 29, 0 }, + { BM1880_CLK_APB_NF, "clk_apb_nf", "clk_axi6", + BM1880_CLK_ENABLE0, 30, 0 }, + { BM1880_CLK_APB_PWM, "clk_apb_pwm", "clk_mux_axi6", + BM1880_CLK_ENABLE1, 0, 0 }, + { BM1880_CLK_RV, "clk_rv", "clk_mux_rv", + BM1880_CLK_ENABLE1, 1, 0 }, + { BM1880_CLK_APB_SPI, "clk_apb_spi", "clk_mux_axi6", + BM1880_CLK_ENABLE1, 2, 0 }, + { BM1880_CLK_UART_500M, "clk_uart_500m", "clk_div_uart_500m", + BM1880_CLK_ENABLE1, 4, 0 }, + { BM1880_CLK_APB_UART, "clk_apb_uart", "clk_axi6", + BM1880_CLK_ENABLE1, 5, 0 }, + { BM1880_CLK_APB_I2S, "clk_apb_i2s", "clk_axi6", + BM1880_CLK_ENABLE1, 6, 0 }, + { BM1880_CLK_AXI4_USB, "clk_axi4_usb", "clk_axi4", + BM1880_CLK_ENABLE1, 7, 0 }, + { BM1880_CLK_APB_USB, "clk_apb_usb", "clk_axi6", + BM1880_CLK_ENABLE1, 8, 0 }, + { BM1880_CLK_12M_USB, "clk_12m_usb", "clk_div_12m_usb", + BM1880_CLK_ENABLE1, 11, 0 }, + { BM1880_CLK_APB_VIDEO, "clk_apb_video", "clk_axi6", + BM1880_CLK_ENABLE1, 12, 0 }, + { BM1880_CLK_APB_VPP, "clk_apb_vpp", "clk_axi6", + BM1880_CLK_ENABLE1, 15, 0 }, + { BM1880_CLK_AXI6, "clk_axi6", "clk_mux_axi6", + BM1880_CLK_ENABLE1, 21, 0 }, +}; + +static const char * const clk_a53_parents[] = { "clk_spll", "clk_mpll" }; +static const char * const clk_rv_parents[] = { "clk_div_1_rv", "clk_div_0_rv" }; +static const char * const clk_axi1_parents[] = { "clk_div_1_axi1", "clk_div_0_axi1" }; +static const char * const clk_axi6_parents[] = { "clk_div_1_axi6", "clk_div_0_axi6" }; + +static const struct bm1880_mux_clock bm1880_mux_clks[] = { + { BM1880_CLK_MUX_RV, "clk_mux_rv", clk_rv_parents, 2, + BM1880_CLK_SELECT, 1, 0 }, + { BM1880_CLK_MUX_AXI6, "clk_mux_axi6", clk_axi6_parents, 2, + BM1880_CLK_SELECT, 3, 0 }, +}; + +static const struct clk_div_table bm1880_div_table_0[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_1[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_2[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 255, 256 }, { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_3[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 255, 256 }, { 511, 512 }, { 0, 0 } +}; + +static const struct clk_div_table bm1880_div_table_4[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 16 }, + { 16, 17 }, { 17, 18 }, { 18, 19 }, { 19, 20 }, + { 20, 21 }, { 21, 22 }, { 22, 23 }, { 23, 24 }, + { 24, 25 }, { 25, 26 }, { 26, 27 }, { 27, 28 }, + { 28, 29 }, { 29, 30 }, { 30, 31 }, { 31, 32 }, + { 127, 128 }, { 255, 256 }, { 511, 512 }, { 65535, 65536 }, + { 0, 0 } +}; + +/* + * Clocks marked as CRITICAL are needed for the proper functioning + * of the SoC. + */ +static struct bm1880_div_hw_clock bm1880_div_clks[] = { + CLK_DIV(BM1880_CLK_DIV_0_RV, "clk_div_0_rv", &bm1880_pll_clks[1].hw, + BM1880_CLK_DIV12, 16, 5, 1, bm1880_div_table_0, 0), + CLK_DIV(BM1880_CLK_DIV_1_RV, "clk_div_1_rv", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV13, 16, 5, 1, bm1880_div_table_0, 0), + CLK_DIV(BM1880_CLK_DIV_UART_500M, "clk_div_uart_500m", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV15, 16, 7, 3, bm1880_div_table_1, 0), + CLK_DIV(BM1880_CLK_DIV_0_AXI1, "clk_div_0_axi1", &bm1880_pll_clks[0].hw, + BM1880_CLK_DIV21, 16, 5, 2, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_1_AXI1, "clk_div_1_axi1", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV22, 16, 5, 3, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_0_AXI6, "clk_div_0_axi6", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV27, 16, 5, 15, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_1_AXI6, "clk_div_1_axi6", &bm1880_pll_clks[0].hw, + BM1880_CLK_DIV28, 16, 5, 11, bm1880_div_table_0, + 0), + CLK_DIV(BM1880_CLK_DIV_12M_USB, "clk_div_12m_usb", &bm1880_pll_clks[2].hw, + BM1880_CLK_DIV18, 16, 7, 125, bm1880_div_table_1, 0), +}; + +/* + * Clocks marked as CRITICAL are all needed for the proper functioning + * of the SoC. + */ +static struct bm1880_composite_clock bm1880_composite_clks[] = { + /* + * Since clk_a53 and clk_50m_a53 clocks are sourcing the CPU core, + * let's mark them as critical to avoid gating. + */ + GATE_MUX(BM1880_CLK_A53, "clk_a53", clk_a53_parents, + BM1880_CLK_ENABLE0, 0, BM1880_CLK_SELECT, 0, + CLK_IS_CRITICAL), + GATE_DIV(BM1880_CLK_50M_A53, "clk_50m_a53", "clk_fpll", + BM1880_CLK_ENABLE0, 1, BM1880_CLK_DIV0, 16, 5, 30, + bm1880_div_table_0, CLK_IS_CRITICAL), + GATE_DIV(BM1880_CLK_EFUSE, "clk_efuse", "clk_fpll", + BM1880_CLK_ENABLE0, 5, BM1880_CLK_DIV1, 16, 7, 60, + bm1880_div_table_1, 0), + GATE_DIV(BM1880_CLK_EMMC, "clk_emmc", "clk_fpll", + BM1880_CLK_ENABLE0, 8, BM1880_CLK_DIV2, 16, 5, 15, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_100K_EMMC, "clk_100k_emmc", "clk_div_12m_usb", + BM1880_CLK_ENABLE0, 9, BM1880_CLK_DIV3, 16, 8, 120, + bm1880_div_table_2, 0), + GATE_DIV(BM1880_CLK_SD, "clk_sd", "clk_fpll", + BM1880_CLK_ENABLE0, 11, BM1880_CLK_DIV4, 16, 5, 15, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_100K_SD, "clk_100k_sd", "clk_div_12m_usb", + BM1880_CLK_ENABLE0, 12, BM1880_CLK_DIV5, 16, 8, 120, + bm1880_div_table_2, 0), + GATE_DIV(BM1880_CLK_500M_ETH0, "clk_500m_eth0", "clk_fpll", + BM1880_CLK_ENABLE0, 13, BM1880_CLK_DIV6, 16, 5, 3, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_500M_ETH1, "clk_500m_eth1", "clk_fpll", + BM1880_CLK_ENABLE0, 15, BM1880_CLK_DIV7, 16, 5, 3, + bm1880_div_table_0, 0), + /* Don't gate GPIO clocks as it is not owned by the GPIO driver */ + GATE_DIV(BM1880_CLK_GPIO_DB, "clk_gpio_db", "clk_div_12m_usb", + BM1880_CLK_ENABLE0, 20, BM1880_CLK_DIV8, 16, 16, 120, + bm1880_div_table_4, CLK_IGNORE_UNUSED), + GATE_DIV(BM1880_CLK_SDMA_AUD, "clk_sdma_aud", "clk_fpll", + BM1880_CLK_ENABLE0, 24, BM1880_CLK_DIV9, 16, 7, 61, + bm1880_div_table_1, 0), + GATE_DIV(BM1880_CLK_JPEG_AXI, "clk_jpeg_axi", "clk_fpll", + BM1880_CLK_ENABLE0, 28, BM1880_CLK_DIV10, 16, 5, 4, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_NF, "clk_nf", "clk_fpll", + BM1880_CLK_ENABLE0, 31, BM1880_CLK_DIV11, 16, 5, 30, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_TPU_AXI, "clk_tpu_axi", "clk_spll", + BM1880_CLK_ENABLE1, 3, BM1880_CLK_DIV14, 16, 5, 1, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_125M_USB, "clk_125m_usb", "clk_fpll", + BM1880_CLK_ENABLE1, 9, BM1880_CLK_DIV16, 16, 5, 12, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_33K_USB, "clk_33k_usb", "clk_div_12m_usb", + BM1880_CLK_ENABLE1, 10, BM1880_CLK_DIV17, 16, 9, 363, + bm1880_div_table_3, 0), + GATE_DIV(BM1880_CLK_VIDEO_AXI, "clk_video_axi", "clk_fpll", + BM1880_CLK_ENABLE1, 13, BM1880_CLK_DIV19, 16, 5, 4, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_VPP_AXI, "clk_vpp_axi", "clk_fpll", + BM1880_CLK_ENABLE1, 14, BM1880_CLK_DIV20, 16, 5, 4, + bm1880_div_table_0, 0), + GATE_MUX(BM1880_CLK_AXI1, "clk_axi1", clk_axi1_parents, + BM1880_CLK_ENABLE1, 15, BM1880_CLK_SELECT, 2, 0), + GATE_DIV(BM1880_CLK_AXI2, "clk_axi2", "clk_fpll", + BM1880_CLK_ENABLE1, 17, BM1880_CLK_DIV23, 16, 5, 3, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_AXI3, "clk_axi3", "clk_mux_rv", + BM1880_CLK_ENABLE1, 18, BM1880_CLK_DIV24, 16, 5, 2, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_AXI4, "clk_axi4", "clk_fpll", + BM1880_CLK_ENABLE1, 19, BM1880_CLK_DIV25, 16, 5, 6, + bm1880_div_table_0, 0), + GATE_DIV(BM1880_CLK_AXI5, "clk_axi5", "clk_fpll", + BM1880_CLK_ENABLE1, 20, BM1880_CLK_DIV26, 16, 5, 15, + bm1880_div_table_0, 0), +}; + +static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate) +{ + u64 numerator; + u32 fbdiv, fref, refdiv; + u32 postdiv1, postdiv2, denominator; + + fbdiv = (regval >> 16) & 0xfff; + fref = parent_rate; + refdiv = regval & 0x1f; + postdiv1 = (regval >> 8) & 0x7; + postdiv2 = (regval >> 12) & 0x7; + + numerator = parent_rate * fbdiv; + denominator = refdiv * postdiv1 * postdiv2; + do_div(numerator, denominator); + + return (unsigned long)numerator; +} + +static unsigned long bm1880_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw); + unsigned long rate; + u32 regval; + + regval = readl(pll_hw->base + pll_hw->pll.reg); + rate = bm1880_pll_rate_calc(regval, parent_rate); + + return rate; +} + +static const struct clk_ops bm1880_pll_ops = { + .recalc_rate = bm1880_pll_recalc_rate, +}; + +static struct clk_hw *bm1880_clk_register_pll(struct bm1880_pll_hw_clock *pll_clk, + void __iomem *sys_base) +{ + struct clk_hw *hw; + int err; + + pll_clk->base = sys_base; + hw = &pll_clk->hw; + + err = clk_hw_register(NULL, hw); + if (err) + return ERR_PTR(err); + + return hw; +} + +static void bm1880_clk_unregister_pll(struct clk_hw *hw) +{ + struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw); + + clk_hw_unregister(hw); + kfree(pll_hw); +} + +static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *pll_base = data->pll_base; + int i; + + for (i = 0; i < num_clks; i++) { + struct bm1880_pll_hw_clock *bm1880_clk = &clks[i]; + + hw = bm1880_clk_register_pll(bm1880_clk, pll_base); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, bm1880_clk->pll.name); + goto err_clk; + } + + data->hw_data.hws[clks[i].pll.id] = hw; + } + + return 0; + +err_clk: + while (i--) + bm1880_clk_unregister_pll(data->hw_data.hws[clks[i].pll.id]); + + return PTR_ERR(hw); +} + +static int bm1880_clk_register_mux(const struct bm1880_mux_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + int i; + + for (i = 0; i < num_clks; i++) { + hw = clk_hw_register_mux(NULL, clks[i].name, + clks[i].parents, + clks[i].num_parents, + clks[i].flags, + sys_base + clks[i].reg, + clks[i].shift, 1, 0, + &bm1880_clk_lock); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + goto err_clk; + } + + data->hw_data.hws[clks[i].id] = hw; + } + + return 0; + +err_clk: + while (i--) + clk_hw_unregister_mux(data->hw_data.hws[clks[i].id]); + + return PTR_ERR(hw); +} + +static unsigned long bm1880_clk_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + struct bm1880_div_clock *div = &div_hw->div; + void __iomem *reg_addr = div_hw->base + div->reg; + unsigned int val; + unsigned long rate; + + if (!(readl(reg_addr) & BIT(3))) { + val = div->initval; + } else { + val = readl(reg_addr) >> div->shift; + val &= clk_div_mask(div->width); + } + + rate = divider_recalc_rate(hw, parent_rate, val, div->table, + div->flags, div->width); + + return rate; +} + +static long bm1880_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + struct bm1880_div_clock *div = &div_hw->div; + void __iomem *reg_addr = div_hw->base + div->reg; + + if (div->flags & CLK_DIVIDER_READ_ONLY) { + u32 val; + + val = readl(reg_addr) >> div->shift; + val &= clk_div_mask(div->width); + + return divider_ro_round_rate(hw, rate, prate, div->table, + div->width, div->flags, + val); + } + + return divider_round_rate(hw, rate, prate, div->table, + div->width, div->flags); +} + +static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + struct bm1880_div_clock *div = &div_hw->div; + void __iomem *reg_addr = div_hw->base + div->reg; + unsigned long flags = 0; + int value; + u32 val; + + value = divider_get_val(rate, parent_rate, div->table, + div->width, div_hw->div.flags); + if (value < 0) + return value; + + if (div_hw->lock) + spin_lock_irqsave(div_hw->lock, flags); + else + __acquire(div_hw->lock); + + val = readl(reg_addr); + val &= ~(clk_div_mask(div->width) << div_hw->div.shift); + val |= (u32)value << div->shift; + writel(val, reg_addr); + + if (div_hw->lock) + spin_unlock_irqrestore(div_hw->lock, flags); + else + __release(div_hw->lock); + + return 0; +} + +static const struct clk_ops bm1880_clk_div_ops = { + .recalc_rate = bm1880_clk_div_recalc_rate, + .round_rate = bm1880_clk_div_round_rate, + .set_rate = bm1880_clk_div_set_rate, +}; + +static struct clk_hw *bm1880_clk_register_div(struct bm1880_div_hw_clock *div_clk, + void __iomem *sys_base) +{ + struct clk_hw *hw; + int err; + + div_clk->div.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO; + div_clk->base = sys_base; + div_clk->lock = &bm1880_clk_lock; + + hw = &div_clk->hw; + err = clk_hw_register(NULL, hw); + if (err) + return ERR_PTR(err); + + return hw; +} + +static void bm1880_clk_unregister_div(struct clk_hw *hw) +{ + struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); + + clk_hw_unregister(hw); + kfree(div_hw); +} + +static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + unsigned int i, id; + + for (i = 0; i < num_clks; i++) { + struct bm1880_div_hw_clock *bm1880_clk = &clks[i]; + + hw = bm1880_clk_register_div(bm1880_clk, sys_base); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, bm1880_clk->div.name); + goto err_clk; + } + + id = clks[i].div.id; + data->hw_data.hws[id] = hw; + } + + return 0; + +err_clk: + while (i--) + bm1880_clk_unregister_div(data->hw_data.hws[clks[i].div.id]); + + return PTR_ERR(hw); +} + +static int bm1880_clk_register_gate(const struct bm1880_gate_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + int i; + + for (i = 0; i < num_clks; i++) { + hw = clk_hw_register_gate(NULL, clks[i].name, + clks[i].parent, + clks[i].flags, + sys_base + clks[i].gate_reg, + clks[i].gate_shift, 0, + &bm1880_clk_lock); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, clks[i].name); + goto err_clk; + } + + data->hw_data.hws[clks[i].id] = hw; + } + + return 0; + +err_clk: + while (i--) + clk_hw_unregister_gate(data->hw_data.hws[clks[i].id]); + + return PTR_ERR(hw); +} + +static struct clk_hw *bm1880_clk_register_composite(struct bm1880_composite_clock *clks, + void __iomem *sys_base) +{ + struct clk_hw *hw; + struct clk_mux *mux = NULL; + struct clk_gate *gate = NULL; + struct bm1880_div_hw_clock *div_hws = NULL; + struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL; + const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL; + const char * const *parent_names; + const char *parent; + int num_parents; + int ret; + + if (clks->mux_shift >= 0) { + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + mux->reg = sys_base + clks->mux_reg; + mux->mask = 1; + mux->shift = clks->mux_shift; + mux_hw = &mux->hw; + mux_ops = &clk_mux_ops; + mux->lock = &bm1880_clk_lock; + + parent_names = clks->parents; + num_parents = clks->num_parents; + } else { + parent = clks->parent; + parent_names = &parent; + num_parents = 1; + } + + if (clks->gate_shift >= 0) { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) { + ret = -ENOMEM; + goto err_out; + } + + gate->reg = sys_base + clks->gate_reg; + gate->bit_idx = clks->gate_shift; + gate->lock = &bm1880_clk_lock; + + gate_hw = &gate->hw; + gate_ops = &clk_gate_ops; + } + + if (clks->div_shift >= 0) { + div_hws = kzalloc(sizeof(*div_hws), GFP_KERNEL); + if (!div_hws) { + ret = -ENOMEM; + goto err_out; + } + + div_hws->base = sys_base; + div_hws->div.reg = clks->div_reg; + div_hws->div.shift = clks->div_shift; + div_hws->div.width = clks->div_width; + div_hws->div.table = clks->table; + div_hws->div.initval = clks->div_initval; + div_hws->lock = &bm1880_clk_lock; + div_hws->div.flags = CLK_DIVIDER_ONE_BASED | + CLK_DIVIDER_ALLOW_ZERO; + + div_hw = &div_hws->hw; + div_ops = &bm1880_clk_div_ops; + } + + hw = clk_hw_register_composite(NULL, clks->name, parent_names, + num_parents, mux_hw, mux_ops, div_hw, + div_ops, gate_hw, gate_ops, + clks->flags); + + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_out; + } + + return hw; + +err_out: + kfree(div_hws); + kfree(gate); + kfree(mux); + + return ERR_PTR(ret); +} + +static int bm1880_clk_register_composites(struct bm1880_composite_clock *clks, + int num_clks, + struct bm1880_clock_data *data) +{ + struct clk_hw *hw; + void __iomem *sys_base = data->sys_base; + int i; + + for (i = 0; i < num_clks; i++) { + struct bm1880_composite_clock *bm1880_clk = &clks[i]; + + hw = bm1880_clk_register_composite(bm1880_clk, sys_base); + if (IS_ERR(hw)) { + pr_err("%s: failed to register clock %s\n", + __func__, bm1880_clk->name); + goto err_clk; + } + + data->hw_data.hws[clks[i].id] = hw; + } + + return 0; + +err_clk: + while (i--) + clk_hw_unregister_composite(data->hw_data.hws[clks[i].id]); + + return PTR_ERR(hw); +} + +static int bm1880_clk_probe(struct platform_device *pdev) +{ + struct bm1880_clock_data *clk_data; + void __iomem *pll_base, *sys_base; + struct device *dev = &pdev->dev; + struct resource *res; + int num_clks, i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pll_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pll_base)) + return PTR_ERR(pll_base); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + sys_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(sys_base)) + return PTR_ERR(sys_base); + + num_clks = ARRAY_SIZE(bm1880_pll_clks) + + ARRAY_SIZE(bm1880_div_clks) + + ARRAY_SIZE(bm1880_mux_clks) + + ARRAY_SIZE(bm1880_composite_clks) + + ARRAY_SIZE(bm1880_gate_clks); + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws, + num_clks), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->pll_base = pll_base; + clk_data->sys_base = sys_base; + + for (i = 0; i < num_clks; i++) + clk_data->hw_data.hws[i] = ERR_PTR(-ENOENT); + + clk_data->hw_data.num = num_clks; + + bm1880_clk_register_plls(bm1880_pll_clks, + ARRAY_SIZE(bm1880_pll_clks), + clk_data); + + bm1880_clk_register_divs(bm1880_div_clks, + ARRAY_SIZE(bm1880_div_clks), + clk_data); + + bm1880_clk_register_mux(bm1880_mux_clks, + ARRAY_SIZE(bm1880_mux_clks), + clk_data); + + bm1880_clk_register_composites(bm1880_composite_clks, + ARRAY_SIZE(bm1880_composite_clks), + clk_data); + + bm1880_clk_register_gate(bm1880_gate_clks, + ARRAY_SIZE(bm1880_gate_clks), + clk_data); + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + &clk_data->hw_data); +} + +static const struct of_device_id bm1880_of_match[] = { + { .compatible = "bitmain,bm1880-clk", }, + {} +}; +MODULE_DEVICE_TABLE(of, bm1880_of_match); + +static struct platform_driver bm1880_clk_driver = { + .driver = { + .name = "bm1880-clk", + .of_match_table = bm1880_of_match, + }, + .probe = bm1880_clk_probe, +}; +module_platform_driver(bm1880_clk_driver); + +MODULE_AUTHOR("Manivannan Sadhasivam "); +MODULE_DESCRIPTION("Clock driver for Bitmain BM1880 SoC"); +MODULE_LICENSE("GPL v2"); From 1e4fb2c0cb3443bf7d2606b6d571bd75879d098e Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Fri, 15 Nov 2019 21:59:01 +0530 Subject: [PATCH 159/160] MAINTAINERS: Add entry for BM1880 SoC clock driver Add MAINTAINERS entry for Bitmain BM1880 SoC clock driver. Signed-off-by: Manivannan Sadhasivam Link: https://lkml.kernel.org/r/20191115162901.17456-8-manivannan.sadhasivam@linaro.org Signed-off-by: Stephen Boyd --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 296de2b51c83..15752f2e6297 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1529,8 +1529,10 @@ M: Manivannan Sadhasivam L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm64/boot/dts/bitmain/ +F: drivers/clk/clk-bm1880.c F: drivers/pinctrl/pinctrl-bm1880.c F: Documentation/devicetree/bindings/arm/bitmain.yaml +F: Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml F: Documentation/devicetree/bindings/pinctrl/bitmain,bm1880-pinctrl.txt ARM/CALXEDA HIGHBANK ARCHITECTURE From 801b787a693ba643b23608cf2bf8dcfab3608795 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Thu, 10 Oct 2019 12:36:55 +1030 Subject: [PATCH 160/160] clk: aspeed: Add RMII RCLK gates for both AST2500 MACs RCLK is a fixed 50MHz clock derived from HPLL that is described by a single gate for each MAC. Signed-off-by: Andrew Jeffery Link: https://lkml.kernel.org/r/20191010020655.3776-3-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Stephen Boyd --- drivers/clk/clk-aspeed.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c index abf06fb6453e..411ff5fb2c07 100644 --- a/drivers/clk/clk-aspeed.c +++ b/drivers/clk/clk-aspeed.c @@ -14,7 +14,7 @@ #include "clk-aspeed.h" -#define ASPEED_NUM_CLKS 36 +#define ASPEED_NUM_CLKS 38 #define ASPEED_RESET2_OFFSET 32 @@ -28,6 +28,7 @@ #define AST2400_HPLL_BYPASS_EN BIT(17) #define ASPEED_MISC_CTRL 0x2c #define UART_DIV13_EN BIT(12) +#define ASPEED_MAC_CLK_DLY 0x48 #define ASPEED_STRAP 0x70 #define CLKIN_25MHZ_EN BIT(23) #define AST2400_CLK_SOURCE_SEL BIT(18) @@ -462,6 +463,30 @@ static int aspeed_clk_probe(struct platform_device *pdev) return PTR_ERR(hw); aspeed_clk_data->hws[ASPEED_CLK_MAC] = hw; + if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-scu")) { + /* RMII 50MHz RCLK */ + hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0, + 50000000); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + /* RMII1 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0, + scu_base + ASPEED_MAC_CLK_DLY, 29, 0, + &aspeed_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw; + + /* RMII2 50MHz (RCLK) output enable */ + hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0, + scu_base + ASPEED_MAC_CLK_DLY, 30, 0, + &aspeed_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + aspeed_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw; + } + /* LPC Host (LHCLK) clock divider */ hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0, scu_base + ASPEED_CLK_SELECTION, 20, 3, 0,