From e63b063ecd248ad9f54a961ddf2a6d97da944456 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Sun, 12 May 2019 22:57:43 +0200 Subject: [PATCH 01/18] clk: meson: fix MPLL 50M binding id typo MPLL_5OM (the capital letter o) should indeed be MPLL_50M (the number) Fix this before it gets used. Fixes: 25db146aa726 ("dt-bindings: clk: meson: add g12a periph clock controller bindings") Reported-by: Martin Blumenstingl Acked-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 4 ++-- drivers/clk/meson/g12a.h | 2 +- include/dt-bindings/clock/g12a-clkc.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 739f64fdf1e3..206fafd299ea 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -2734,8 +2734,8 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = { [CLKID_MALI_1_DIV] = &g12a_mali_1_div.hw, [CLKID_MALI_1] = &g12a_mali_1.hw, [CLKID_MALI] = &g12a_mali.hw, - [CLKID_MPLL_5OM_DIV] = &g12a_mpll_50m_div.hw, - [CLKID_MPLL_5OM] = &g12a_mpll_50m.hw, + [CLKID_MPLL_50M_DIV] = &g12a_mpll_50m_div.hw, + [CLKID_MPLL_50M] = &g12a_mpll_50m.hw, [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index 39c41af70804..bcc05cd9882f 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -166,7 +166,7 @@ #define CLKID_HDMI_DIV 167 #define CLKID_MALI_0_DIV 170 #define CLKID_MALI_1_DIV 173 -#define CLKID_MPLL_5OM_DIV 176 +#define CLKID_MPLL_50M_DIV 176 #define CLKID_SYS_PLL_DIV16_EN 178 #define CLKID_SYS_PLL_DIV16 179 #define CLKID_CPU_CLK_DYN0_SEL 180 diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h index 82c9e0c020b2..e10470ed7c4f 100644 --- a/include/dt-bindings/clock/g12a-clkc.h +++ b/include/dt-bindings/clock/g12a-clkc.h @@ -130,7 +130,7 @@ #define CLKID_MALI_1_SEL 172 #define CLKID_MALI_1 174 #define CLKID_MALI 175 -#define CLKID_MPLL_5OM 177 +#define CLKID_MPLL_50M 177 #define CLKID_CPU_CLK 187 #define CLKID_PCIE_PLL 201 #define CLKID_VDEC_1 204 From 3ff46efbcd90d3d469de8eddaf03d12293aaa50c Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 12 May 2019 21:43:00 +0200 Subject: [PATCH 02/18] clk: meson: meson8b: fix a typo in the VPU parent names array variable The variable which holds the parent names for the VPU clocks has a typo in it. Fix this typo to make the variable naming in the driver consistent. No functional changes. Fixes: 41785ce562491d ("clk: meson: meson8b: add the VPU clock trees") Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 37cf0f01bb5d..62cd3a7f1f65 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -1761,7 +1761,7 @@ static struct clk_regmap meson8m2_gp_pll = { }, }; -static const char * const mmeson8b_vpu_0_1_parent_names[] = { +static const char * const meson8b_vpu_0_1_parent_names[] = { "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" }; @@ -1778,8 +1778,8 @@ static struct clk_regmap meson8b_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = mmeson8b_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(mmeson8b_vpu_0_1_parent_names), + .parent_names = meson8b_vpu_0_1_parent_names, + .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1837,8 +1837,8 @@ static struct clk_regmap meson8b_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = mmeson8b_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(mmeson8b_vpu_0_1_parent_names), + .parent_names = meson8b_vpu_0_1_parent_names, + .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names), .flags = CLK_SET_RATE_PARENT, }, }; From f9b3eeebef6aabaa37a351715374de53b6da860c Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 May 2019 14:31:09 +0200 Subject: [PATCH 03/18] clk: meson: mpll: properly handle spread spectrum The bit 'SSEN' available on some MPLL DSS outputs is not related to the fractional part of the divider but to the function called 'Spread Spectrum'. This function might be used to solve EM issues by adding a jitter on clock signal. This widens the signal spectrum and weakens the peaks in it. While spread spectrum might be useful for some application, it is problematic for others, such as audio. This patch introduce a new flag to the MPLL driver to enable (or not) the spread spectrum function. Fixes: 1f737ffa13ef ("clk: meson: mpll: fix mpll0 fractional part ignored") Tested-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/clk-mpll.c | 9 ++++++--- drivers/clk/meson/clk-mpll.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c index f76850d99e59..d3f42e086431 100644 --- a/drivers/clk/meson/clk-mpll.c +++ b/drivers/clk/meson/clk-mpll.c @@ -119,9 +119,12 @@ static int mpll_set_rate(struct clk_hw *hw, meson_parm_write(clk->map, &mpll->sdm, sdm); meson_parm_write(clk->map, &mpll->sdm_en, 1); - /* Set additional fractional part enable if required */ - if (MESON_PARM_APPLICABLE(&mpll->ssen)) - meson_parm_write(clk->map, &mpll->ssen, 1); + /* Set spread spectrum if possible */ + if (MESON_PARM_APPLICABLE(&mpll->ssen)) { + unsigned int ss = + mpll->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0; + meson_parm_write(clk->map, &mpll->ssen, ss); + } /* Set the integer divider part */ meson_parm_write(clk->map, &mpll->n2, n2); diff --git a/drivers/clk/meson/clk-mpll.h b/drivers/clk/meson/clk-mpll.h index cf79340006dd..0f948430fed4 100644 --- a/drivers/clk/meson/clk-mpll.h +++ b/drivers/clk/meson/clk-mpll.h @@ -23,6 +23,7 @@ struct meson_clk_mpll_data { }; #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) +#define CLK_MESON_MPLL_SPREAD_SPECTRUM BIT(1) extern const struct clk_ops meson_clk_mpll_ro_ops; extern const struct clk_ops meson_clk_mpll_ops; From 8925dbd03bb29b1b0de30ac4e02c18faf8ddc9db Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 May 2019 14:31:10 +0200 Subject: [PATCH 04/18] clk: meson: gxbb: no spread spectrum on mpll0 The documentation says there is an SSEN bit on mpll0 but, after testing it, no spread spectrum function appears to be enabled by this bit on any of the MPLLs. Let's remove it until we know more Fixes: 1f737ffa13ef ("clk: meson: mpll: fix mpll0 fractional part ignored") Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 29ffb4fde714..dab16d9b1af8 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -679,11 +679,6 @@ static struct clk_regmap gxbb_mpll0_div = { .shift = 16, .width = 9, }, - .ssen = { - .reg_off = HHI_MPLL_CNTL, - .shift = 25, - .width = 1, - }, .lock = &meson_clk_lock, }, .hw.init = &(struct clk_init_data){ From dc4e62d373f881cbf51513296a6db7806516a01a Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 May 2019 14:31:11 +0200 Subject: [PATCH 05/18] clk: meson: axg: spread spectrum is on mpll2 After testing, it appears that the SSEN bit controls the spread spectrum function on MPLL2, not MPLL0. Fixes: 78b4af312f91 ("clk: meson-axg: add clock controller drivers") Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 7a8ef80e5f2c..3ddd0efc9ee0 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -469,11 +469,6 @@ static struct clk_regmap axg_mpll0_div = { .shift = 16, .width = 9, }, - .ssen = { - .reg_off = HHI_MPLL_CNTL, - .shift = 25, - .width = 1, - }, .misc = { .reg_off = HHI_PLL_TOP_MISC, .shift = 0, @@ -568,6 +563,11 @@ static struct clk_regmap axg_mpll2_div = { .shift = 16, .width = 9, }, + .ssen = { + .reg_off = HHI_MPLL_CNTL, + .shift = 25, + .width = 1, + }, .misc = { .reg_off = HHI_PLL_TOP_MISC, .shift = 2, From 19855c8276fec011afd8617a634eb62a29e6b871 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 May 2019 14:31:12 +0200 Subject: [PATCH 06/18] clk: meson: mpll: add init callback and regs Until now (gx and axg), the mpll setting on boot (whatever the bootloader) was good enough to generate a clean fractional division. It is not the case on the g12a. While moving away from the vendor u-boot, it was noticed the fractional part of the divider was no longer applied. Like on the pll, some magic settings need to applied on the mpll register. This change adds the ability to do that on the mpll driver. Signed-off-by: Jerome Brunet --- drivers/clk/meson/clk-mpll.c | 35 ++++++++++++++++++++++++----------- drivers/clk/meson/clk-mpll.h | 2 ++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c index d3f42e086431..2d39a8bc367c 100644 --- a/drivers/clk/meson/clk-mpll.c +++ b/drivers/clk/meson/clk-mpll.c @@ -115,8 +115,30 @@ static int mpll_set_rate(struct clk_hw *hw, else __acquire(mpll->lock); - /* Enable and set the fractional part */ + /* Set the fractional part */ meson_parm_write(clk->map, &mpll->sdm, sdm); + + /* Set the integer divider part */ + meson_parm_write(clk->map, &mpll->n2, n2); + + if (mpll->lock) + spin_unlock_irqrestore(mpll->lock, flags); + else + __release(mpll->lock); + + return 0; +} + +static void mpll_init(struct clk_hw *hw) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk); + + if (mpll->init_count) + regmap_multi_reg_write(clk->map, mpll->init_regs, + mpll->init_count); + + /* Enable the fractional part */ meson_parm_write(clk->map, &mpll->sdm_en, 1); /* Set spread spectrum if possible */ @@ -126,19 +148,9 @@ static int mpll_set_rate(struct clk_hw *hw, meson_parm_write(clk->map, &mpll->ssen, ss); } - /* Set the integer divider part */ - meson_parm_write(clk->map, &mpll->n2, n2); - /* Set the magic misc bit if required */ if (MESON_PARM_APPLICABLE(&mpll->misc)) meson_parm_write(clk->map, &mpll->misc, 1); - - if (mpll->lock) - spin_unlock_irqrestore(mpll->lock, flags); - else - __release(mpll->lock); - - return 0; } const struct clk_ops meson_clk_mpll_ro_ops = { @@ -151,6 +163,7 @@ const struct clk_ops meson_clk_mpll_ops = { .recalc_rate = mpll_recalc_rate, .round_rate = mpll_round_rate, .set_rate = mpll_set_rate, + .init = mpll_init, }; EXPORT_SYMBOL_GPL(meson_clk_mpll_ops); diff --git a/drivers/clk/meson/clk-mpll.h b/drivers/clk/meson/clk-mpll.h index 0f948430fed4..a991d568c43a 100644 --- a/drivers/clk/meson/clk-mpll.h +++ b/drivers/clk/meson/clk-mpll.h @@ -18,6 +18,8 @@ struct meson_clk_mpll_data { struct parm n2; struct parm ssen; struct parm misc; + const struct reg_sequence *init_regs; + unsigned int init_count; spinlock_t *lock; u8 flags; }; From 76d3fc38a06b4b2aa9a64a0e6a0bbe605d23991e Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 May 2019 14:31:13 +0200 Subject: [PATCH 07/18] clk: meson: g12a: add mpll register init sequences Add the required init of each MPLL of the g12a. Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 206fafd299ea..eda4990610c8 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -1001,6 +1001,10 @@ static struct clk_fixed_factor g12a_mpll_prediv = { }, }; +static const struct reg_sequence g12a_mpll0_init_regs[] = { + { .reg = HHI_MPLL_CNTL2, .def = 0x40000033 }, +}; + static struct clk_regmap g12a_mpll0_div = { .data = &(struct meson_clk_mpll_data){ .sdm = { @@ -1024,6 +1028,8 @@ static struct clk_regmap g12a_mpll0_div = { .width = 1, }, .lock = &meson_clk_lock, + .init_regs = g12a_mpll0_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll0_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "mpll0_div", @@ -1047,6 +1053,10 @@ static struct clk_regmap g12a_mpll0 = { }, }; +static const struct reg_sequence g12a_mpll1_init_regs[] = { + { .reg = HHI_MPLL_CNTL4, .def = 0x40000033 }, +}; + static struct clk_regmap g12a_mpll1_div = { .data = &(struct meson_clk_mpll_data){ .sdm = { @@ -1070,6 +1080,8 @@ static struct clk_regmap g12a_mpll1_div = { .width = 1, }, .lock = &meson_clk_lock, + .init_regs = g12a_mpll1_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll1_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "mpll1_div", @@ -1093,6 +1105,10 @@ static struct clk_regmap g12a_mpll1 = { }, }; +static const struct reg_sequence g12a_mpll2_init_regs[] = { + { .reg = HHI_MPLL_CNTL6, .def = 0x40000033 }, +}; + static struct clk_regmap g12a_mpll2_div = { .data = &(struct meson_clk_mpll_data){ .sdm = { @@ -1116,6 +1132,8 @@ static struct clk_regmap g12a_mpll2_div = { .width = 1, }, .lock = &meson_clk_lock, + .init_regs = g12a_mpll2_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll2_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "mpll2_div", @@ -1139,6 +1157,10 @@ static struct clk_regmap g12a_mpll2 = { }, }; +static const struct reg_sequence g12a_mpll3_init_regs[] = { + { .reg = HHI_MPLL_CNTL8, .def = 0x40000033 }, +}; + static struct clk_regmap g12a_mpll3_div = { .data = &(struct meson_clk_mpll_data){ .sdm = { @@ -1162,6 +1184,8 @@ static struct clk_regmap g12a_mpll3_div = { .width = 1, }, .lock = &meson_clk_lock, + .init_regs = g12a_mpll3_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll3_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "mpll3_div", From 19a18d42bf557b8420a55e0fce7be5aec9f8ef8c Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 May 2019 14:31:14 +0200 Subject: [PATCH 08/18] clk: meson: eeclk: add init regs Like the PLL and MPLL, the controller may require some magic setting to be applied on startup. This is needed when the initial setting is not applied by the boot ROM. The controller need to do it when the setting applies to several clock, like all the MPLLs in the case of g12a. Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson-eeclk.c | 3 +++ drivers/clk/meson/meson-eeclk.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c index 37a34c9c3885..6ba2094be257 100644 --- a/drivers/clk/meson/meson-eeclk.c +++ b/drivers/clk/meson/meson-eeclk.c @@ -34,6 +34,9 @@ int meson_eeclkc_probe(struct platform_device *pdev) return PTR_ERR(map); } + if (data->init_count) + regmap_multi_reg_write(map, data->init_regs, data->init_count); + input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0); if (IS_ERR(input)) { ret = PTR_ERR(input); diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h index 1b809b1419fe..9ab5d6fa7ccb 100644 --- a/drivers/clk/meson/meson-eeclk.h +++ b/drivers/clk/meson/meson-eeclk.h @@ -17,6 +17,8 @@ struct platform_device; struct meson_eeclkc_data { struct clk_regmap *const *regmap_clks; unsigned int regmap_clk_num; + const struct reg_sequence *init_regs; + unsigned int init_count; struct clk_hw_onecell_data *hw_onecell_data; }; From a9f7b1993b709ffbbeeaeff232701639ca31ef95 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 13 May 2019 14:31:15 +0200 Subject: [PATCH 09/18] clk: meson: g12a: add controller register init Add the MPLL common register initial setting Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index eda4990610c8..9df90bab9a84 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -2992,10 +2992,16 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12a_vdec_hevcf, }; +static const struct reg_sequence g12a_init_regs[] = { + { .reg = HHI_MPLL_CNTL0, .def = 0x00000543 }, +}; + static const struct meson_eeclkc_data g12a_clkc_data = { .regmap_clks = g12a_clk_regmaps, .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), - .hw_onecell_data = &g12a_hw_onecell_data + .hw_onecell_data = &g12a_hw_onecell_data, + .init_regs = g12a_init_regs, + .init_count = ARRAY_SIZE(g12a_init_regs), }; static const struct of_device_id clkc_match_table[] = { From a987be182c309f565a2d3545f2e9c9a4f8d07a4d Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 20 May 2019 22:03:16 +0200 Subject: [PATCH 10/18] dt-bindings: clock: meson8b: add the audio clocks The audio controllers on Meson8, Meson8b and Meson8m2 use similar (potentially the same) audio clocks as GXBB, GXL and GXM. Add the CLKID_CTS_AMCLK, CLKID_CTS_MCLK_I958 and CLKID_CTS_I958 clock IDs so they can be used for the audio controllers. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- include/dt-bindings/clock/meson8b-clkc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h index 47556539f0ee..68862aaf977e 100644 --- a/include/dt-bindings/clock/meson8b-clkc.h +++ b/include/dt-bindings/clock/meson8b-clkc.h @@ -112,5 +112,8 @@ #define CLKID_VDEC_HCODEC 199 #define CLKID_VDEC_2 202 #define CLKID_VDEC_HEVC 206 +#define CLKID_CTS_AMCLK 209 +#define CLKID_CTS_MCLK_I958 212 +#define CLKID_CTS_I958 213 #endif /* __MESON8B_CLKC_H */ From f278f05e748cdce3d7994c5de7cc2f02cc185f65 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 20 May 2019 22:03:17 +0200 Subject: [PATCH 11/18] clk: meson: meson8b: add the cts_amclk clocks Add the I2S master clock also referred as cts_amclk. The setup for this clock is identical to GXBB, so this ports commit 4087bd4b21702d ("clk: meson: gxbb: add cts_amclk") to the Meson8/Meson8b/Meson8m2 clock driver. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 65 +++++++++++++++++++++++++++++++++++++ drivers/clk/meson/meson8b.h | 5 ++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 62cd3a7f1f65..e00f42e7fc46 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -2153,6 +2153,59 @@ static struct clk_regmap meson8b_vdec_hevc = { }, }; +/* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ +static const char * const meson8b_cts_amclk_parent_names[] = { + "mpll0", "mpll1", "mpll2" +}; + +static u32 meson8b_cts_amclk_mux_table[] = { 1, 2, 3 }; + +static struct clk_regmap meson8b_cts_amclk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_AUD_CLK_CNTL, + .mask = 0x3, + .shift = 9, + .table = meson8b_cts_amclk_mux_table, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_amclk_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = meson8b_cts_amclk_parent_names, + .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_names), + }, +}; + +static struct clk_regmap meson8b_cts_amclk_div = { + .data = &(struct clk_regmap_div_data) { + .offset = HHI_AUD_CLK_CNTL, + .shift = 0, + .width = 8, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_amclk_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "cts_amclk_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_cts_amclk = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_AUD_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_amclk", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "cts_amclk_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); @@ -2432,6 +2485,9 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = { [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, + [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, + [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, + [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2641,6 +2697,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, + [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, + [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, + [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2852,6 +2911,9 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = { [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw, [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw, [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw, + [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, + [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, + [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -3041,6 +3103,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_vdec_hevc_div, &meson8b_vdec_hevc_en, &meson8b_vdec_hevc, + &meson8b_cts_amclk, + &meson8b_cts_amclk_sel, + &meson8b_cts_amclk_div, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index ed37196187e6..03efa47e800f 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -30,6 +30,7 @@ #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */ #define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */ #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ +#define HHI_AUD_CLK_CNTL 0x178 /* 0x5e offset in data sheet */ #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ #define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ @@ -171,8 +172,10 @@ #define CLKID_VDEC_HEVC_SEL 203 #define CLKID_VDEC_HEVC_DIV 204 #define CLKID_VDEC_HEVC_EN 205 +#define CLKID_CTS_AMCLK_SEL 207 +#define CLKID_CTS_AMCLK_DIV 208 -#define CLK_NR_CLKS 207 +#define CLK_NR_CLKS 210 /* * include the CLKID and RESETID that have From c39c24c1cae2476629c83e63afb19c3ff8987abf Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 20 May 2019 22:03:18 +0200 Subject: [PATCH 12/18] clk: meson: meson8b: add the cts_mclk_i958 clocks Add the SPDIF master clock also referred as cts_mclk_i958. The setup for this clock is identical to GXBB, so this ports commit 3c277c247eabeb ("clk: meson: gxbb: add cts_mclk_i958") to the Meson8/Meson8b/Meson8m2 clock driver. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 65 +++++++++++++++++++++++++++++++++++++ drivers/clk/meson/meson8b.h | 5 ++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index e00f42e7fc46..13ce1783eead 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -2206,6 +2206,59 @@ static struct clk_regmap meson8b_cts_amclk = { }, }; +/* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ +static const char * const meson8b_cts_mclk_i958_parent_names[] = { + "mpll0", "mpll1", "mpll2" +}; + +static u32 meson8b_cts_mclk_i958_mux_table[] = { 1, 2, 3 }; + +static struct clk_regmap meson8b_cts_mclk_i958_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_AUD_CLK_CNTL2, + .mask = 0x3, + .shift = 25, + .table = meson8b_cts_mclk_i958_mux_table, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_mclk_i958_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = meson8b_cts_mclk_i958_parent_names, + .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_names), + }, +}; + +static struct clk_regmap meson8b_cts_mclk_i958_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_AUD_CLK_CNTL2, + .shift = 16, + .width = 8, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_mclk_i958_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_cts_mclk_i958 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_AUD_CLK_CNTL2, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_mclk_i958", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "cts_mclk_i958_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); @@ -2488,6 +2541,9 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = { [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, + [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, + [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, + [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2700,6 +2756,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, + [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, + [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, + [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2914,6 +2973,9 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = { [CLKID_CTS_AMCLK_SEL] = &meson8b_cts_amclk_sel.hw, [CLKID_CTS_AMCLK_DIV] = &meson8b_cts_amclk_div.hw, [CLKID_CTS_AMCLK] = &meson8b_cts_amclk.hw, + [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, + [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, + [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -3106,6 +3168,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_cts_amclk, &meson8b_cts_amclk_sel, &meson8b_cts_amclk_div, + &meson8b_cts_mclk_i958_sel, + &meson8b_cts_mclk_i958_div, + &meson8b_cts_mclk_i958, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index 03efa47e800f..c3787418088e 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -32,6 +32,7 @@ #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ #define HHI_AUD_CLK_CNTL 0x178 /* 0x5e offset in data sheet */ #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ +#define HHI_AUD_CLK_CNTL2 0x190 /* 0x64 offset in data sheet */ #define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ #define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ @@ -174,8 +175,10 @@ #define CLKID_VDEC_HEVC_EN 205 #define CLKID_CTS_AMCLK_SEL 207 #define CLKID_CTS_AMCLK_DIV 208 +#define CLKID_CTS_MCLK_I958_SEL 210 +#define CLKID_CTS_MCLK_I958_DIV 211 -#define CLK_NR_CLKS 210 +#define CLK_NR_CLKS 213 /* * include the CLKID and RESETID that have From 174806aa9a8e051d3757ee5e673a3966221e4c3c Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Mon, 20 May 2019 22:03:19 +0200 Subject: [PATCH 13/18] clk: meson: meson8b: add the cts_i958 clock Add the cts_i958 clock to control the clock source of the spdif output block. It is used to select whether the clock source of the spdif output is cts_amclk (when data are taken from i2s buffer) or the cts_mclk_i958 (when data are taken from the spdif buffer). The setup for this clock is identical to GXBB, so this ports commit 7eaa44f6207fb6 ("clk: meson: gxbb: add cts_i958 clock") to the Meson8/Meson8b/Meson8m2 clock driver. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 24 ++++++++++++++++++++++++ drivers/clk/meson/meson8b.h | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 13ce1783eead..537219fa573e 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -2259,6 +2259,26 @@ static struct clk_regmap meson8b_cts_mclk_i958 = { }, }; +static struct clk_regmap meson8b_cts_i958 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_AUD_CLK_CNTL2, + .mask = 0x1, + .shift = 27, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_i958", + .ops = &clk_regmap_mux_ops, + .parent_names = (const char *[]){ "cts_amclk", + "cts_mclk_i958" }, + .num_parents = 2, + /* + * The parent is specific to origin of the audio data. Let the + * consumer choose the appropriate parent. + */ + .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); @@ -2544,6 +2564,7 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = { [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, + [CLKID_CTS_I958] = &meson8b_cts_i958.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2759,6 +2780,7 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, + [CLKID_CTS_I958] = &meson8b_cts_i958.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2976,6 +2998,7 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = { [CLKID_CTS_MCLK_I958_SEL] = &meson8b_cts_mclk_i958_sel.hw, [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, + [CLKID_CTS_I958] = &meson8b_cts_i958.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -3171,6 +3194,7 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_cts_mclk_i958_sel, &meson8b_cts_mclk_i958_div, &meson8b_cts_mclk_i958, + &meson8b_cts_i958, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index c3787418088e..c889fbeec30f 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -178,7 +178,7 @@ #define CLKID_CTS_MCLK_I958_SEL 210 #define CLKID_CTS_MCLK_I958_DIV 211 -#define CLK_NR_CLKS 213 +#define CLK_NR_CLKS 214 /* * include the CLKID and RESETID that have From 6e47ef34db571e3eebda46ddaddae00d369df5f9 Mon Sep 17 00:00:00 2001 From: Guillaume La Roque Date: Fri, 12 Apr 2019 12:02:20 +0200 Subject: [PATCH 14/18] dt-bindings: clk: g12a-clkc: add Temperature Sensor clock IDs Add clock ids used by the temperature sensors of the G12A Socs Reviewed-by: Martin Blumenstingl Acked-by: Rob Herring Signed-off-by: Guillaume La Roque Signed-off-by: Jerome Brunet [fixed commit message] --- include/dt-bindings/clock/g12a-clkc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h index 82c9e0c020b2..cfda463091b7 100644 --- a/include/dt-bindings/clock/g12a-clkc.h +++ b/include/dt-bindings/clock/g12a-clkc.h @@ -136,5 +136,6 @@ #define CLKID_VDEC_1 204 #define CLKID_VDEC_HEVC 207 #define CLKID_VDEC_HEVCF 210 +#define CLKID_TS 212 #endif /* __G12A_CLKC_H */ From ad517d5298cf47ba1a2a92587a3287113baeec0a Mon Sep 17 00:00:00 2001 From: Guillaume La Roque Date: Fri, 12 Apr 2019 12:02:21 +0200 Subject: [PATCH 15/18] clk: meson-g12a: add temperature sensor clocks Add the TS clocks used by two temperature sensors Reviewed-by: Martin Blumenstingl Signed-off-by: Guillaume La Roque Signed-off-by: Jerome Brunet [fixed commit description] --- drivers/clk/meson/g12a.c | 31 +++++++++++++++++++++++++++++++ drivers/clk/meson/g12a.h | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 9df90bab9a84..c9769621d209 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -2504,6 +2504,33 @@ static struct clk_regmap g12a_mali = { }, }; +static struct clk_regmap g12a_ts_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_TS_CLK_CNTL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts_div", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "xtal" }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_ts = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_TS_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "ts_div" }, + .num_parents = 1, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1); @@ -2793,6 +2820,8 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = { [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel.hw, [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div.hw, [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, + [CLKID_TS_DIV] = &g12a_ts_div.hw, + [CLKID_TS] = &g12a_ts.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -2990,6 +3019,8 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12a_vdec_hevcf_sel, &g12a_vdec_hevcf_div, &g12a_vdec_hevcf, + &g12a_ts_div, + &g12a_ts, }; static const struct reg_sequence g12a_init_regs[] = { diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index bcc05cd9882f..bda1501ba671 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -195,8 +195,9 @@ #define CLKID_VDEC_HEVC_DIV 206 #define CLKID_VDEC_HEVCF_SEL 208 #define CLKID_VDEC_HEVCF_DIV 209 +#define CLKID_TS_DIV 211 -#define NR_CLKS 211 +#define NR_CLKS 213 /* include the CLKIDs that have been made part of the DT binding */ #include From 7391d7f4b0690a98c5bf6a113c33400e2d29d9f8 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 28 May 2019 10:07:56 +0200 Subject: [PATCH 16/18] dt-bindings: clk: meson: add g12b periph clock controller bindings Update the documentation to support clock driver for the Amlogic G12B SoC. G12B clock driver is very close, the main differences are : - the clock tree is duplicated for the both clusters, and the SYS_PLL are swapped between the clusters - G12B has additional clocks like for CSI an other components Reviewed-by: Rob Herring Reviewed-by: Martin Blumenstingl Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt index 5c8b105be4d6..6eaa52092313 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt @@ -10,6 +10,7 @@ Required Properties: "amlogic,gxl-clkc" for GXL and GXM SoC, "amlogic,axg-clkc" for AXG SoC. "amlogic,g12a-clkc" for G12A SoC. + "amlogic,g12b-clkc" for G12B SoC. - clocks : list of clock phandle, one for each entry clock-names. - clock-names : should contain the following: * "xtal": the platform xtal From d43628e9bca69e02efba5041d4bd26d013637e0c Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 28 May 2019 10:07:57 +0200 Subject: [PATCH 17/18] clk: meson: g12a: Add support for G12B CPUB clocks Update the Meson G12A Clock driver to support the Amlogic G12B SoC. G12B clock driver is very close, the main differences are : - the clock tree is duplicated for the both clusters, and the SYS_PLL are swapped between the clusters - G12B has additional clocks like for CSI an other components Here only the cpu clock tree is handled. Reviewed-by: Martin Blumenstingl Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 762 +++++++++++++++++++++++++++++++++++++++ drivers/clk/meson/g12a.h | 40 +- 2 files changed, 801 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index c9769621d209..3ab83e5497a0 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -150,6 +150,57 @@ static struct clk_regmap g12a_sys_pll = { }, }; +static struct clk_regmap g12b_sys1_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys1_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12b_sys1_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS1_PLL_CNTL0, + .shift = 16, + .width = 3, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys1_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "sys1_pll_dco" }, + .num_parents = 1, + }, +}; + static struct clk_regmap g12a_sys_pll_div16_en = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, @@ -167,6 +218,23 @@ static struct clk_regmap g12a_sys_pll_div16_en = { }, }; +static struct clk_regmap g12b_sys1_pll_div16_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "sys1_pll_div16_en", + .ops = &clk_regmap_gate_ro_ops, + .parent_names = (const char *[]){ "sys1_pll" }, + .num_parents = 1, + /* + * This clock is used to debug the sys_pll range + * Linux should not change it at runtime + */ + }, +}; + static struct clk_fixed_factor g12a_sys_pll_div16 = { .mult = 1, .div = 16, @@ -178,6 +246,17 @@ static struct clk_fixed_factor g12a_sys_pll_div16 = { }, }; +static struct clk_fixed_factor g12b_sys1_pll_div16 = { + .mult = 1, + .div = 16, + .hw.init = &(struct clk_init_data){ + .name = "sys1_pll_div16", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "sys1_pll_div16_en" }, + .num_parents = 1, + }, +}; + /* Datasheet names this field as "premux0" */ static struct clk_regmap g12a_cpu_clk_premux0 = { .data = &(struct clk_regmap_mux_data){ @@ -306,6 +385,150 @@ static struct clk_regmap g12a_cpu_clk = { }, }; +/* Datasheet names this field as "Final_mux_sel" */ +static struct clk_regmap g12b_cpu_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x1, + .shift = 11, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpu_clk_dyn", + "sys1_pll" }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "premux0" */ +static struct clk_regmap g12b_cpub_clk_premux0 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .mask = 0x3, + .shift = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_dyn0_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ IN_PREFIX "xtal", + "fclk_div2", + "fclk_div3" }, + .num_parents = 3, + }, +}; + +/* Datasheet names this field as "mux0_divn_tcnt" */ +static struct clk_regmap g12b_cpub_clk_mux0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .shift = 4, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_dyn0_div", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_dyn0_sel" }, + .num_parents = 1, + }, +}; + +/* Datasheet names this field as "postmux0" */ +static struct clk_regmap g12b_cpub_clk_postmux0 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .mask = 0x1, + .shift = 2, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_dyn0", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_dyn0_sel", + "cpub_clk_dyn0_div" }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "premux1" */ +static struct clk_regmap g12b_cpub_clk_premux1 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_dyn1_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ IN_PREFIX "xtal", + "fclk_div2", + "fclk_div3" }, + .num_parents = 3, + }, +}; + +/* Datasheet names this field as "Mux1_divn_tcnt" */ +static struct clk_regmap g12b_cpub_clk_mux1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .shift = 20, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_dyn1_div", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_dyn1_sel" }, + .num_parents = 1, + }, +}; + +/* Datasheet names this field as "postmux1" */ +static struct clk_regmap g12b_cpub_clk_postmux1 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .mask = 0x1, + .shift = 18, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_dyn1", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_dyn1_sel", + "cpub_clk_dyn1_div" }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "Final_dyn_mux_sel" */ +static struct clk_regmap g12b_cpub_clk_dyn = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .mask = 0x1, + .shift = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_dyn", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_dyn0", + "cpub_clk_dyn1" }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "Final_mux_sel" */ +static struct clk_regmap g12b_cpub_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL, + .mask = 0x1, + .shift = 11, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_dyn", + "sys_pll" }, + .num_parents = 2, + }, +}; + static struct clk_regmap g12a_cpu_clk_div16_en = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, @@ -323,6 +546,23 @@ static struct clk_regmap g12a_cpu_clk_div16_en = { }, }; +static struct clk_regmap g12b_cpub_clk_div16_en = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .bit_idx = 1, + }, + .hw.init = &(struct clk_init_data) { + .name = "cpub_clk_div16_en", + .ops = &clk_regmap_gate_ro_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + /* + * This clock is used to debug the cpu_clk range + * Linux should not change it at runtime + */ + }, +}; + static struct clk_fixed_factor g12a_cpu_clk_div16 = { .mult = 1, .div = 16, @@ -334,6 +574,17 @@ static struct clk_fixed_factor g12a_cpu_clk_div16 = { }, }; +static struct clk_fixed_factor g12b_cpub_clk_div16 = { + .mult = 1, + .div = 16, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div16", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk_div16_en" }, + .num_parents = 1, + }, +}; + static struct clk_regmap g12a_cpu_clk_apb_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, @@ -462,6 +713,240 @@ static struct clk_regmap g12a_cpu_clk_trace = { }, }; +static struct clk_fixed_factor g12b_cpub_clk_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div2", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12b_cpub_clk_div3 = { + .mult = 1, + .div = 3, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div3", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12b_cpub_clk_div4 = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div4", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12b_cpub_clk_div5 = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div5", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12b_cpub_clk_div6 = { + .mult = 1, + .div = 6, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div6", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12b_cpub_clk_div7 = { + .mult = 1, + .div = 7, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div7", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12b_cpub_clk_div8 = { + .mult = 1, + .div = 8, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_div8", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "cpub_clk" }, + .num_parents = 1, + }, +}; + +static u32 mux_table_cpub[] = { 1, 2, 3, 4, 5, 6, 7 }; +static struct clk_regmap g12b_cpub_clk_apb_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .mask = 7, + .shift = 3, + .table = mux_table_cpub, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_apb_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_div2", + "cpub_clk_div3", + "cpub_clk_div4", + "cpub_clk_div5", + "cpub_clk_div6", + "cpub_clk_div7", + "cpub_clk_div8" }, + .num_parents = 7, + }, +}; + +static struct clk_regmap g12b_cpub_clk_apb = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .bit_idx = 16, + .flags = CLK_GATE_SET_TO_DISABLE, + }, + .hw.init = &(struct clk_init_data) { + .name = "cpub_clk_apb", + .ops = &clk_regmap_gate_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_apb_sel" }, + .num_parents = 1, + /* + * This clock is set by the ROM monitor code, + * Linux should not change it at runtime + */ + }, +}; + +static struct clk_regmap g12b_cpub_clk_atb_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .mask = 7, + .shift = 6, + .table = mux_table_cpub, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_atb_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_div2", + "cpub_clk_div3", + "cpub_clk_div4", + "cpub_clk_div5", + "cpub_clk_div6", + "cpub_clk_div7", + "cpub_clk_div8" }, + .num_parents = 7, + }, +}; + +static struct clk_regmap g12b_cpub_clk_atb = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .bit_idx = 17, + .flags = CLK_GATE_SET_TO_DISABLE, + }, + .hw.init = &(struct clk_init_data) { + .name = "cpub_clk_atb", + .ops = &clk_regmap_gate_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_atb_sel" }, + .num_parents = 1, + /* + * This clock is set by the ROM monitor code, + * Linux should not change it at runtime + */ + }, +}; + +static struct clk_regmap g12b_cpub_clk_axi_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .mask = 7, + .shift = 9, + .table = mux_table_cpub, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_axi_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_div2", + "cpub_clk_div3", + "cpub_clk_div4", + "cpub_clk_div5", + "cpub_clk_div6", + "cpub_clk_div7", + "cpub_clk_div8" }, + .num_parents = 7, + }, +}; + +static struct clk_regmap g12b_cpub_clk_axi = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .bit_idx = 18, + .flags = CLK_GATE_SET_TO_DISABLE, + }, + .hw.init = &(struct clk_init_data) { + .name = "cpub_clk_axi", + .ops = &clk_regmap_gate_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_axi_sel" }, + .num_parents = 1, + /* + * This clock is set by the ROM monitor code, + * Linux should not change it at runtime + */ + }, +}; + +static struct clk_regmap g12b_cpub_clk_trace_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .mask = 7, + .shift = 20, + .table = mux_table_cpub, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpub_clk_trace_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_div2", + "cpub_clk_div3", + "cpub_clk_div4", + "cpub_clk_div5", + "cpub_clk_div6", + "cpub_clk_div7", + "cpub_clk_div8" }, + .num_parents = 7, + }, +}; + +static struct clk_regmap g12b_cpub_clk_trace = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SYS_CPUB_CLK_CNTL1, + .bit_idx = 23, + .flags = CLK_GATE_SET_TO_DISABLE, + }, + .hw.init = &(struct clk_init_data) { + .name = "cpub_clk_trace", + .ops = &clk_regmap_gate_ro_ops, + .parent_names = (const char *[]){ "cpub_clk_trace_sel" }, + .num_parents = 1, + /* + * This clock is set by the ROM monitor code, + * Linux should not change it at runtime + */ + }, +}; + static const struct pll_mult_range g12a_gp0_pll_mult_range = { .min = 55, .max = 255, @@ -2827,6 +3312,255 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = { .num = NR_CLKS, }; +static struct clk_hw_onecell_data g12b_hw_onecell_data = { + .hws = { + [CLKID_SYS_PLL] = &g12a_sys_pll.hw, + [CLKID_FIXED_PLL] = &g12a_fixed_pll.hw, + [CLKID_FCLK_DIV2] = &g12a_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &g12a_fclk_div3.hw, + [CLKID_FCLK_DIV4] = &g12a_fclk_div4.hw, + [CLKID_FCLK_DIV5] = &g12a_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &g12a_fclk_div7.hw, + [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5.hw, + [CLKID_GP0_PLL] = &g12a_gp0_pll.hw, + [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel.hw, + [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div.hw, + [CLKID_CLK81] = &g12a_clk81.hw, + [CLKID_MPLL0] = &g12a_mpll0.hw, + [CLKID_MPLL1] = &g12a_mpll1.hw, + [CLKID_MPLL2] = &g12a_mpll2.hw, + [CLKID_MPLL3] = &g12a_mpll3.hw, + [CLKID_DDR] = &g12a_ddr.hw, + [CLKID_DOS] = &g12a_dos.hw, + [CLKID_AUDIO_LOCKER] = &g12a_audio_locker.hw, + [CLKID_MIPI_DSI_HOST] = &g12a_mipi_dsi_host.hw, + [CLKID_ETH_PHY] = &g12a_eth_phy.hw, + [CLKID_ISA] = &g12a_isa.hw, + [CLKID_PL301] = &g12a_pl301.hw, + [CLKID_PERIPHS] = &g12a_periphs.hw, + [CLKID_SPICC0] = &g12a_spicc_0.hw, + [CLKID_I2C] = &g12a_i2c.hw, + [CLKID_SANA] = &g12a_sana.hw, + [CLKID_SD] = &g12a_sd.hw, + [CLKID_RNG0] = &g12a_rng0.hw, + [CLKID_UART0] = &g12a_uart0.hw, + [CLKID_SPICC1] = &g12a_spicc_1.hw, + [CLKID_HIU_IFACE] = &g12a_hiu_reg.hw, + [CLKID_MIPI_DSI_PHY] = &g12a_mipi_dsi_phy.hw, + [CLKID_ASSIST_MISC] = &g12a_assist_misc.hw, + [CLKID_SD_EMMC_A] = &g12a_emmc_a.hw, + [CLKID_SD_EMMC_B] = &g12a_emmc_b.hw, + [CLKID_SD_EMMC_C] = &g12a_emmc_c.hw, + [CLKID_AUDIO_CODEC] = &g12a_audio_codec.hw, + [CLKID_AUDIO] = &g12a_audio.hw, + [CLKID_ETH] = &g12a_eth_core.hw, + [CLKID_DEMUX] = &g12a_demux.hw, + [CLKID_AUDIO_IFIFO] = &g12a_audio_ififo.hw, + [CLKID_ADC] = &g12a_adc.hw, + [CLKID_UART1] = &g12a_uart1.hw, + [CLKID_G2D] = &g12a_g2d.hw, + [CLKID_RESET] = &g12a_reset.hw, + [CLKID_PCIE_COMB] = &g12a_pcie_comb.hw, + [CLKID_PARSER] = &g12a_parser.hw, + [CLKID_USB] = &g12a_usb_general.hw, + [CLKID_PCIE_PHY] = &g12a_pcie_phy.hw, + [CLKID_AHB_ARB0] = &g12a_ahb_arb0.hw, + [CLKID_AHB_DATA_BUS] = &g12a_ahb_data_bus.hw, + [CLKID_AHB_CTRL_BUS] = &g12a_ahb_ctrl_bus.hw, + [CLKID_HTX_HDCP22] = &g12a_htx_hdcp22.hw, + [CLKID_HTX_PCLK] = &g12a_htx_pclk.hw, + [CLKID_BT656] = &g12a_bt656.hw, + [CLKID_USB1_DDR_BRIDGE] = &g12a_usb1_to_ddr.hw, + [CLKID_MMC_PCLK] = &g12a_mmc_pclk.hw, + [CLKID_UART2] = &g12a_uart2.hw, + [CLKID_VPU_INTR] = &g12a_vpu_intr.hw, + [CLKID_GIC] = &g12a_gic.hw, + [CLKID_SD_EMMC_A_CLK0_SEL] = &g12a_sd_emmc_a_clk0_sel.hw, + [CLKID_SD_EMMC_A_CLK0_DIV] = &g12a_sd_emmc_a_clk0_div.hw, + [CLKID_SD_EMMC_A_CLK0] = &g12a_sd_emmc_a_clk0.hw, + [CLKID_SD_EMMC_B_CLK0_SEL] = &g12a_sd_emmc_b_clk0_sel.hw, + [CLKID_SD_EMMC_B_CLK0_DIV] = &g12a_sd_emmc_b_clk0_div.hw, + [CLKID_SD_EMMC_B_CLK0] = &g12a_sd_emmc_b_clk0.hw, + [CLKID_SD_EMMC_C_CLK0_SEL] = &g12a_sd_emmc_c_clk0_sel.hw, + [CLKID_SD_EMMC_C_CLK0_DIV] = &g12a_sd_emmc_c_clk0_div.hw, + [CLKID_SD_EMMC_C_CLK0] = &g12a_sd_emmc_c_clk0.hw, + [CLKID_MPLL0_DIV] = &g12a_mpll0_div.hw, + [CLKID_MPLL1_DIV] = &g12a_mpll1_div.hw, + [CLKID_MPLL2_DIV] = &g12a_mpll2_div.hw, + [CLKID_MPLL3_DIV] = &g12a_mpll3_div.hw, + [CLKID_FCLK_DIV2_DIV] = &g12a_fclk_div2_div.hw, + [CLKID_FCLK_DIV3_DIV] = &g12a_fclk_div3_div.hw, + [CLKID_FCLK_DIV4_DIV] = &g12a_fclk_div4_div.hw, + [CLKID_FCLK_DIV5_DIV] = &g12a_fclk_div5_div.hw, + [CLKID_FCLK_DIV7_DIV] = &g12a_fclk_div7_div.hw, + [CLKID_FCLK_DIV2P5_DIV] = &g12a_fclk_div2p5_div.hw, + [CLKID_HIFI_PLL] = &g12a_hifi_pll.hw, + [CLKID_VCLK2_VENCI0] = &g12a_vclk2_venci0.hw, + [CLKID_VCLK2_VENCI1] = &g12a_vclk2_venci1.hw, + [CLKID_VCLK2_VENCP0] = &g12a_vclk2_vencp0.hw, + [CLKID_VCLK2_VENCP1] = &g12a_vclk2_vencp1.hw, + [CLKID_VCLK2_VENCT0] = &g12a_vclk2_venct0.hw, + [CLKID_VCLK2_VENCT1] = &g12a_vclk2_venct1.hw, + [CLKID_VCLK2_OTHER] = &g12a_vclk2_other.hw, + [CLKID_VCLK2_ENCI] = &g12a_vclk2_enci.hw, + [CLKID_VCLK2_ENCP] = &g12a_vclk2_encp.hw, + [CLKID_DAC_CLK] = &g12a_dac_clk.hw, + [CLKID_AOCLK] = &g12a_aoclk_gate.hw, + [CLKID_IEC958] = &g12a_iec958_gate.hw, + [CLKID_ENC480P] = &g12a_enc480p.hw, + [CLKID_RNG1] = &g12a_rng1.hw, + [CLKID_VCLK2_ENCT] = &g12a_vclk2_enct.hw, + [CLKID_VCLK2_ENCL] = &g12a_vclk2_encl.hw, + [CLKID_VCLK2_VENCLMMC] = &g12a_vclk2_venclmmc.hw, + [CLKID_VCLK2_VENCL] = &g12a_vclk2_vencl.hw, + [CLKID_VCLK2_OTHER1] = &g12a_vclk2_other1.hw, + [CLKID_FIXED_PLL_DCO] = &g12a_fixed_pll_dco.hw, + [CLKID_SYS_PLL_DCO] = &g12a_sys_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &g12a_gp0_pll_dco.hw, + [CLKID_HIFI_PLL_DCO] = &g12a_hifi_pll_dco.hw, + [CLKID_DMA] = &g12a_dma.hw, + [CLKID_EFUSE] = &g12a_efuse.hw, + [CLKID_ROM_BOOT] = &g12a_rom_boot.hw, + [CLKID_RESET_SEC] = &g12a_reset_sec.hw, + [CLKID_SEC_AHB_APB3] = &g12a_sec_ahb_apb3.hw, + [CLKID_MPLL_PREDIV] = &g12a_mpll_prediv.hw, + [CLKID_VPU_0_SEL] = &g12a_vpu_0_sel.hw, + [CLKID_VPU_0_DIV] = &g12a_vpu_0_div.hw, + [CLKID_VPU_0] = &g12a_vpu_0.hw, + [CLKID_VPU_1_SEL] = &g12a_vpu_1_sel.hw, + [CLKID_VPU_1_DIV] = &g12a_vpu_1_div.hw, + [CLKID_VPU_1] = &g12a_vpu_1.hw, + [CLKID_VPU] = &g12a_vpu.hw, + [CLKID_VAPB_0_SEL] = &g12a_vapb_0_sel.hw, + [CLKID_VAPB_0_DIV] = &g12a_vapb_0_div.hw, + [CLKID_VAPB_0] = &g12a_vapb_0.hw, + [CLKID_VAPB_1_SEL] = &g12a_vapb_1_sel.hw, + [CLKID_VAPB_1_DIV] = &g12a_vapb_1_div.hw, + [CLKID_VAPB_1] = &g12a_vapb_1.hw, + [CLKID_VAPB_SEL] = &g12a_vapb_sel.hw, + [CLKID_VAPB] = &g12a_vapb.hw, + [CLKID_HDMI_PLL_DCO] = &g12a_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &g12a_hdmi_pll_od.hw, + [CLKID_HDMI_PLL_OD2] = &g12a_hdmi_pll_od2.hw, + [CLKID_HDMI_PLL] = &g12a_hdmi_pll.hw, + [CLKID_VID_PLL] = &g12a_vid_pll_div.hw, + [CLKID_VID_PLL_SEL] = &g12a_vid_pll_sel.hw, + [CLKID_VID_PLL_DIV] = &g12a_vid_pll.hw, + [CLKID_VCLK_SEL] = &g12a_vclk_sel.hw, + [CLKID_VCLK2_SEL] = &g12a_vclk2_sel.hw, + [CLKID_VCLK_INPUT] = &g12a_vclk_input.hw, + [CLKID_VCLK2_INPUT] = &g12a_vclk2_input.hw, + [CLKID_VCLK_DIV] = &g12a_vclk_div.hw, + [CLKID_VCLK2_DIV] = &g12a_vclk2_div.hw, + [CLKID_VCLK] = &g12a_vclk.hw, + [CLKID_VCLK2] = &g12a_vclk2.hw, + [CLKID_VCLK_DIV1] = &g12a_vclk_div1.hw, + [CLKID_VCLK_DIV2_EN] = &g12a_vclk_div2_en.hw, + [CLKID_VCLK_DIV4_EN] = &g12a_vclk_div4_en.hw, + [CLKID_VCLK_DIV6_EN] = &g12a_vclk_div6_en.hw, + [CLKID_VCLK_DIV12_EN] = &g12a_vclk_div12_en.hw, + [CLKID_VCLK2_DIV1] = &g12a_vclk2_div1.hw, + [CLKID_VCLK2_DIV2_EN] = &g12a_vclk2_div2_en.hw, + [CLKID_VCLK2_DIV4_EN] = &g12a_vclk2_div4_en.hw, + [CLKID_VCLK2_DIV6_EN] = &g12a_vclk2_div6_en.hw, + [CLKID_VCLK2_DIV12_EN] = &g12a_vclk2_div12_en.hw, + [CLKID_VCLK_DIV2] = &g12a_vclk_div2.hw, + [CLKID_VCLK_DIV4] = &g12a_vclk_div4.hw, + [CLKID_VCLK_DIV6] = &g12a_vclk_div6.hw, + [CLKID_VCLK_DIV12] = &g12a_vclk_div12.hw, + [CLKID_VCLK2_DIV2] = &g12a_vclk2_div2.hw, + [CLKID_VCLK2_DIV4] = &g12a_vclk2_div4.hw, + [CLKID_VCLK2_DIV6] = &g12a_vclk2_div6.hw, + [CLKID_VCLK2_DIV12] = &g12a_vclk2_div12.hw, + [CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel.hw, + [CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel.hw, + [CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel.hw, + [CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel.hw, + [CLKID_CTS_ENCI] = &g12a_cts_enci.hw, + [CLKID_CTS_ENCP] = &g12a_cts_encp.hw, + [CLKID_CTS_VDAC] = &g12a_cts_vdac.hw, + [CLKID_HDMI_TX] = &g12a_hdmi_tx.hw, + [CLKID_HDMI_SEL] = &g12a_hdmi_sel.hw, + [CLKID_HDMI_DIV] = &g12a_hdmi_div.hw, + [CLKID_HDMI] = &g12a_hdmi.hw, + [CLKID_MALI_0_SEL] = &g12a_mali_0_sel.hw, + [CLKID_MALI_0_DIV] = &g12a_mali_0_div.hw, + [CLKID_MALI_0] = &g12a_mali_0.hw, + [CLKID_MALI_1_SEL] = &g12a_mali_1_sel.hw, + [CLKID_MALI_1_DIV] = &g12a_mali_1_div.hw, + [CLKID_MALI_1] = &g12a_mali_1.hw, + [CLKID_MALI] = &g12a_mali.hw, + [CLKID_MPLL_50M_DIV] = &g12a_mpll_50m_div.hw, + [CLKID_MPLL_50M] = &g12a_mpll_50m.hw, + [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, + [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, + [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, + [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw, + [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw, + [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw, + [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw, + [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw, + [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw, + [CLKID_CPU_CLK] = &g12b_cpu_clk.hw, + [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw, + [CLKID_CPU_CLK_DIV16] = &g12a_cpu_clk_div16.hw, + [CLKID_CPU_CLK_APB_DIV] = &g12a_cpu_clk_apb_div.hw, + [CLKID_CPU_CLK_APB] = &g12a_cpu_clk_apb.hw, + [CLKID_CPU_CLK_ATB_DIV] = &g12a_cpu_clk_atb_div.hw, + [CLKID_CPU_CLK_ATB] = &g12a_cpu_clk_atb.hw, + [CLKID_CPU_CLK_AXI_DIV] = &g12a_cpu_clk_axi_div.hw, + [CLKID_CPU_CLK_AXI] = &g12a_cpu_clk_axi.hw, + [CLKID_CPU_CLK_TRACE_DIV] = &g12a_cpu_clk_trace_div.hw, + [CLKID_CPU_CLK_TRACE] = &g12a_cpu_clk_trace.hw, + [CLKID_PCIE_PLL_DCO] = &g12a_pcie_pll_dco.hw, + [CLKID_PCIE_PLL_DCO_DIV2] = &g12a_pcie_pll_dco_div2.hw, + [CLKID_PCIE_PLL_OD] = &g12a_pcie_pll_od.hw, + [CLKID_PCIE_PLL] = &g12a_pcie_pll.hw, + [CLKID_VDEC_1_SEL] = &g12a_vdec_1_sel.hw, + [CLKID_VDEC_1_DIV] = &g12a_vdec_1_div.hw, + [CLKID_VDEC_1] = &g12a_vdec_1.hw, + [CLKID_VDEC_HEVC_SEL] = &g12a_vdec_hevc_sel.hw, + [CLKID_VDEC_HEVC_DIV] = &g12a_vdec_hevc_div.hw, + [CLKID_VDEC_HEVC] = &g12a_vdec_hevc.hw, + [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel.hw, + [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div.hw, + [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, + [CLKID_TS_DIV] = &g12a_ts_div.hw, + [CLKID_TS] = &g12a_ts.hw, + [CLKID_SYS1_PLL_DCO] = &g12b_sys1_pll_dco.hw, + [CLKID_SYS1_PLL] = &g12b_sys1_pll.hw, + [CLKID_SYS1_PLL_DIV16_EN] = &g12b_sys1_pll_div16_en.hw, + [CLKID_SYS1_PLL_DIV16] = &g12b_sys1_pll_div16.hw, + [CLKID_CPUB_CLK_DYN0_SEL] = &g12b_cpub_clk_premux0.hw, + [CLKID_CPUB_CLK_DYN0_DIV] = &g12b_cpub_clk_mux0_div.hw, + [CLKID_CPUB_CLK_DYN0] = &g12b_cpub_clk_postmux0.hw, + [CLKID_CPUB_CLK_DYN1_SEL] = &g12b_cpub_clk_premux1.hw, + [CLKID_CPUB_CLK_DYN1_DIV] = &g12b_cpub_clk_mux1_div.hw, + [CLKID_CPUB_CLK_DYN1] = &g12b_cpub_clk_postmux1.hw, + [CLKID_CPUB_CLK_DYN] = &g12b_cpub_clk_dyn.hw, + [CLKID_CPUB_CLK] = &g12b_cpub_clk.hw, + [CLKID_CPUB_CLK_DIV16_EN] = &g12b_cpub_clk_div16_en.hw, + [CLKID_CPUB_CLK_DIV16] = &g12b_cpub_clk_div16.hw, + [CLKID_CPUB_CLK_DIV2] = &g12b_cpub_clk_div2.hw, + [CLKID_CPUB_CLK_DIV3] = &g12b_cpub_clk_div3.hw, + [CLKID_CPUB_CLK_DIV4] = &g12b_cpub_clk_div4.hw, + [CLKID_CPUB_CLK_DIV5] = &g12b_cpub_clk_div5.hw, + [CLKID_CPUB_CLK_DIV6] = &g12b_cpub_clk_div6.hw, + [CLKID_CPUB_CLK_DIV7] = &g12b_cpub_clk_div7.hw, + [CLKID_CPUB_CLK_DIV8] = &g12b_cpub_clk_div8.hw, + [CLKID_CPUB_CLK_APB_SEL] = &g12b_cpub_clk_apb_sel.hw, + [CLKID_CPUB_CLK_APB] = &g12b_cpub_clk_apb.hw, + [CLKID_CPUB_CLK_ATB_SEL] = &g12b_cpub_clk_atb_sel.hw, + [CLKID_CPUB_CLK_ATB] = &g12b_cpub_clk_atb.hw, + [CLKID_CPUB_CLK_AXI_SEL] = &g12b_cpub_clk_axi_sel.hw, + [CLKID_CPUB_CLK_AXI] = &g12b_cpub_clk_axi.hw, + [CLKID_CPUB_CLK_TRACE_SEL] = &g12b_cpub_clk_trace_sel.hw, + [CLKID_CPUB_CLK_TRACE] = &g12b_cpub_clk_trace.hw, + [NR_CLKS] = NULL, + }, + .num = NR_CLKS, +}; + /* Convenience table to populate regmap in .probe */ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12a_clk81, @@ -3021,6 +3755,27 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12a_vdec_hevcf, &g12a_ts_div, &g12a_ts, + &g12b_cpu_clk, + &g12b_sys1_pll_dco, + &g12b_sys1_pll, + &g12b_sys1_pll_div16_en, + &g12b_cpub_clk_premux0, + &g12b_cpub_clk_mux0_div, + &g12b_cpub_clk_postmux0, + &g12b_cpub_clk_premux1, + &g12b_cpub_clk_mux1_div, + &g12b_cpub_clk_postmux1, + &g12b_cpub_clk_dyn, + &g12b_cpub_clk, + &g12b_cpub_clk_div16_en, + &g12b_cpub_clk_apb_sel, + &g12b_cpub_clk_apb, + &g12b_cpub_clk_atb_sel, + &g12b_cpub_clk_atb, + &g12b_cpub_clk_axi_sel, + &g12b_cpub_clk_axi, + &g12b_cpub_clk_trace_sel, + &g12b_cpub_clk_trace, }; static const struct reg_sequence g12a_init_regs[] = { @@ -3035,8 +3790,15 @@ static const struct meson_eeclkc_data g12a_clkc_data = { .init_count = ARRAY_SIZE(g12a_init_regs), }; +static const struct meson_eeclkc_data g12b_clkc_data = { + .regmap_clks = g12a_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), + .hw_onecell_data = &g12b_hw_onecell_data +}; + static const struct of_device_id clkc_match_table[] = { { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data }, + { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data }, {} }; diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index bda1501ba671..c8aed31fbe17 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -69,6 +69,8 @@ #define HHI_VDEC4_CLK_CNTL 0x1EC #define HHI_HDCP22_CLK_CNTL 0x1F0 #define HHI_VAPBCLK_CNTL 0x1F4 +#define HHI_SYS_CPUB_CLK_CNTL1 0x200 +#define HHI_SYS_CPUB_CLK_CNTL 0x208 #define HHI_VPU_CLKB_CNTL 0x20C #define HHI_GEN_CLK_CNTL 0x228 #define HHI_VDIN_MEAS_CLK_CNTL 0x250 @@ -102,6 +104,13 @@ #define HHI_HDMI_PLL_CNTL5 0x334 #define HHI_HDMI_PLL_CNTL6 0x338 #define HHI_SPICC_CLK_CNTL 0x3dc +#define HHI_SYS1_PLL_CNTL0 0x380 +#define HHI_SYS1_PLL_CNTL1 0x384 +#define HHI_SYS1_PLL_CNTL2 0x388 +#define HHI_SYS1_PLL_CNTL3 0x38c +#define HHI_SYS1_PLL_CNTL4 0x390 +#define HHI_SYS1_PLL_CNTL5 0x394 +#define HHI_SYS1_PLL_CNTL6 0x398 /* * CLKID index values @@ -196,8 +205,37 @@ #define CLKID_VDEC_HEVCF_SEL 208 #define CLKID_VDEC_HEVCF_DIV 209 #define CLKID_TS_DIV 211 +#define CLKID_SYS1_PLL_DCO 213 +#define CLKID_SYS1_PLL 214 +#define CLKID_SYS1_PLL_DIV16_EN 215 +#define CLKID_SYS1_PLL_DIV16 216 +#define CLKID_CPUB_CLK_DYN0_SEL 217 +#define CLKID_CPUB_CLK_DYN0_DIV 218 +#define CLKID_CPUB_CLK_DYN0 219 +#define CLKID_CPUB_CLK_DYN1_SEL 220 +#define CLKID_CPUB_CLK_DYN1_DIV 221 +#define CLKID_CPUB_CLK_DYN1 222 +#define CLKID_CPUB_CLK_DYN 223 +#define CLKID_CPUB_CLK 224 +#define CLKID_CPUB_CLK_DIV16_EN 225 +#define CLKID_CPUB_CLK_DIV16 226 +#define CLKID_CPUB_CLK_DIV2 227 +#define CLKID_CPUB_CLK_DIV3 228 +#define CLKID_CPUB_CLK_DIV4 229 +#define CLKID_CPUB_CLK_DIV5 230 +#define CLKID_CPUB_CLK_DIV6 231 +#define CLKID_CPUB_CLK_DIV7 232 +#define CLKID_CPUB_CLK_DIV8 233 +#define CLKID_CPUB_CLK_APB_SEL 234 +#define CLKID_CPUB_CLK_APB 235 +#define CLKID_CPUB_CLK_ATB_SEL 236 +#define CLKID_CPUB_CLK_ATB 237 +#define CLKID_CPUB_CLK_AXI_SEL 238 +#define CLKID_CPUB_CLK_AXI 239 +#define CLKID_CPUB_CLK_TRACE_SEL 240 +#define CLKID_CPUB_CLK_TRACE 241 -#define NR_CLKS 213 +#define NR_CLKS 242 /* include the CLKIDs that have been made part of the DT binding */ #include From eda91833f099277998814105c77b5b12cbfab6db Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 28 May 2019 10:07:58 +0200 Subject: [PATCH 18/18] clk: meson: g12a: mark fclk_div3 as critical On Amlogic Meson G12b platform, the fclk_div3 seems to be necessary for the system to operate correctly. Disabling it cause the entire system to freeze, including peripherals. Let's mark this clock as critical, fixing boot on G12b platforms. Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 3ab83e5497a0..db1c4ed9d54e 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -1350,6 +1350,16 @@ static struct clk_regmap g12a_fclk_div3 = { .ops = &clk_regmap_gate_ops, .parent_names = (const char *[]){ "fclk_div3_div" }, .num_parents = 1, + /* + * This clock is used by the resident firmware and is required + * by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_IS_CRITICAL, }, };