From 5dc6470273063418b5409154336a447e6d8fa880 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 22 Nov 2022 10:48:44 -0800 Subject: [PATCH 1/9] clk: sunxi-ng: fix ccu_mmc_timing.c kernel-doc issues Use '-' to separate the function name and its description. Use '%' on constants in kernel-doc notation. Use the kernel-doc Return: format for function return values. Fixes this warning: ccu_mmc_timing.c:21: warning: No description found for return value of 'sunxi_ccu_set_mmc_timing_mode' Signed-off-by: Randy Dunlap Cc: Yang Li Cc: Chen-Yu Tsai Cc: Jernej Skrabec Cc: Samuel Holland Cc: linux-arm-kernel@lists.infradead.org Cc: linux-sunxi@lists.linux.dev Cc: Michael Turquette Cc: Stephen Boyd Cc: linux-clk@vger.kernel.org Acked-by: Jernej Skrabec Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/20221122184844.6794-1-rdunlap@infradead.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu_mmc_timing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_mmc_timing.c b/drivers/clk/sunxi-ng/ccu_mmc_timing.c index de33414fc5c2..23a8d44e2449 100644 --- a/drivers/clk/sunxi-ng/ccu_mmc_timing.c +++ b/drivers/clk/sunxi-ng/ccu_mmc_timing.c @@ -10,11 +10,11 @@ #include "ccu_common.h" /** - * sunxi_ccu_set_mmc_timing_mode: Configure the MMC clock timing mode + * sunxi_ccu_set_mmc_timing_mode - Configure the MMC clock timing mode * @clk: clock to be configured * @new_mode: true for new timing mode introduced in A83T and later * - * Returns 0 on success, -ENOTSUPP if the clock does not support + * Return: %0 on success, %-ENOTSUPP if the clock does not support * switching modes. */ int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode) @@ -46,8 +46,8 @@ EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode); * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode * @clk: clock to query * - * Returns 0 if the clock is in old timing mode, > 0 if it is in - * new timing mode, and -ENOTSUPP if the clock does not support + * Return: %0 if the clock is in old timing mode, > %0 if it is in + * new timing mode, and %-ENOTSUPP if the clock does not support * this function. */ int sunxi_ccu_get_mmc_timing_mode(struct clk *clk) From 5ee541ae712e74c842a324e946ef91cb19140cab Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 28 Dec 2022 22:22:30 -0600 Subject: [PATCH 2/9] clk: sunxi-ng: h3/h5: Model H3 CLK_DRAM as a fixed clock The DRAM controller clock is only allowed to change frequency while the DRAM chips are in self-refresh. To support this, changes to the CLK_DRAM mux and divider have no effect until acknowledged by the memory dynamic frequency scaling (MDFS) hardware inside the DRAM controller. (There is a SDRCLK_UPD bit in DRAM_CFG_REG which should serve a similar purpose, but this bit actually does nothing.) However, the MDFS hardware in H3 appears to be broken. Triggering a frequency change using the procedure from similar SoCs (A64/H5) hangs the hardware. Additionally, the vendor BSP specifically avoids using the MDFS hardware on H3, instead performing all DRAM PHY parameter updates and resets in software. Thus, it is effectively impossible to change the CLK_DRAM mux/divider, so those features should not be modeled. Add CLK_SET_RATE_PARENT so frequency changes apply to PLL_DDR instead. Signed-off-by: Samuel Holland Reviewed-by: Jernej Skrabec Link: https://lore.kernel.org/r/20221229042230.24532-1-samuel@sholland.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index d3fcb983c17c..bfebe8dbbe65 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -434,8 +434,13 @@ static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", static SUNXI_CCU_GATE(usb_ohci3_clk, "usb-ohci3", "osc24M", 0x0cc, BIT(19), 0); -static const char * const dram_parents[] = { "pll-ddr", "pll-periph0-2x" }; -static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents, +/* H3 has broken MDFS hardware, so the mux/divider cannot be changed. */ +static CLK_FIXED_FACTOR_HW(h3_dram_clk, "dram", + &pll_ddr_clk.common.hw, + 1, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); + +static const char * const h5_dram_parents[] = { "pll-ddr", "pll-periph0-2x" }; +static SUNXI_CCU_M_WITH_MUX(h5_dram_clk, "dram", h5_dram_parents, 0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL); static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram", @@ -592,7 +597,7 @@ static struct ccu_common *sun8i_h3_ccu_clks[] = { &usb_ohci1_clk.common, &usb_ohci2_clk.common, &usb_ohci3_clk.common, - &dram_clk.common, + &h5_dram_clk.common, &dram_ve_clk.common, &dram_csi_clk.common, &dram_deinterlace_clk.common, @@ -732,7 +737,7 @@ static struct clk_hw_onecell_data sun8i_h3_hw_clks = { [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, [CLK_USB_OHCI3] = &usb_ohci3_clk.common.hw, - [CLK_DRAM] = &dram_clk.common.hw, + [CLK_DRAM] = &h3_dram_clk.hw, [CLK_DRAM_VE] = &dram_ve_clk.common.hw, [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, [CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw, @@ -848,7 +853,7 @@ static struct clk_hw_onecell_data sun50i_h5_hw_clks = { [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, [CLK_USB_OHCI3] = &usb_ohci3_clk.common.hw, - [CLK_DRAM] = &dram_clk.common.hw, + [CLK_DRAM] = &h5_dram_clk.common.hw, [CLK_DRAM_VE] = &dram_ve_clk.common.hw, [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, [CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw, From 657f477a89acb25ba34414ac84a51a32c5013d7b Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 31 Dec 2022 11:30:55 -0600 Subject: [PATCH 3/9] clk: sunxi-ng: Avoid computing the rate twice The ccu_*_find_best() functions already compute a best_rate at the same time as the other factors. Return this value so the caller does not need to duplicate the computation. Signed-off-by: Samuel Holland Reviewed-by: Jernej Skrabec Reviewed-by: Andre Przywara Link: https://lore.kernel.org/r/20221231173055.42384-1-samuel@sholland.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu_mp.c | 11 ++++++----- drivers/clk/sunxi-ng/ccu_nk.c | 9 +++++---- drivers/clk/sunxi-ng/ccu_nkm.c | 10 +++++----- drivers/clk/sunxi-ng/ccu_nkmp.c | 10 +++++----- drivers/clk/sunxi-ng/ccu_nm.c | 9 +++++---- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index 57cf2d615148..cc94a694cb67 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -10,9 +10,9 @@ #include "ccu_gate.h" #include "ccu_mp.h" -static void ccu_mp_find_best(unsigned long parent, unsigned long rate, - unsigned int max_m, unsigned int max_p, - unsigned int *m, unsigned int *p) +static unsigned long ccu_mp_find_best(unsigned long parent, unsigned long rate, + unsigned int max_m, unsigned int max_p, + unsigned int *m, unsigned int *p) { unsigned long best_rate = 0; unsigned int best_m = 0, best_p = 0; @@ -35,6 +35,8 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate, *m = best_m; *p = best_p; + + return best_rate; } static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw, @@ -109,8 +111,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) { - ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); - rate = *parent_rate / p / m; + rate = ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); } else { rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate, max_m, max_p); diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c index c4fb82af97e8..8aa35d5804f3 100644 --- a/drivers/clk/sunxi-ng/ccu_nk.c +++ b/drivers/clk/sunxi-ng/ccu_nk.c @@ -15,8 +15,8 @@ struct _ccu_nk { unsigned long k, min_k, max_k; }; -static void ccu_nk_find_best(unsigned long parent, unsigned long rate, - struct _ccu_nk *nk) +static unsigned long ccu_nk_find_best(unsigned long parent, unsigned long rate, + struct _ccu_nk *nk) { unsigned long best_rate = 0; unsigned int best_k = 0, best_n = 0; @@ -39,6 +39,8 @@ static void ccu_nk_find_best(unsigned long parent, unsigned long rate, nk->k = best_k; nk->n = best_n; + + return best_rate; } static void ccu_nk_disable(struct clk_hw *hw) @@ -104,8 +106,7 @@ static long ccu_nk_round_rate(struct clk_hw *hw, unsigned long rate, _nk.min_k = nk->k.min ?: 1; _nk.max_k = nk->k.max ?: 1 << nk->k.width; - ccu_nk_find_best(*parent_rate, rate, &_nk); - rate = *parent_rate * _nk.n * _nk.k; + rate = ccu_nk_find_best(*parent_rate, rate, &_nk); if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV) rate = rate / nk->fixed_post_div; diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 67da2c189b53..a0978a50edae 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -16,8 +16,8 @@ struct _ccu_nkm { unsigned long m, min_m, max_m; }; -static void ccu_nkm_find_best(unsigned long parent, unsigned long rate, - struct _ccu_nkm *nkm) +static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long rate, + struct _ccu_nkm *nkm) { unsigned long best_rate = 0; unsigned long best_n = 0, best_k = 0, best_m = 0; @@ -45,6 +45,8 @@ static void ccu_nkm_find_best(unsigned long parent, unsigned long rate, nkm->n = best_n; nkm->k = best_k; nkm->m = best_m; + + return best_rate; } static void ccu_nkm_disable(struct clk_hw *hw) @@ -122,9 +124,7 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate *= nkm->fixed_post_div; - ccu_nkm_find_best(*parent_rate, rate, &_nkm); - - rate = *parent_rate * _nkm.n * _nkm.k / _nkm.m; + rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm); if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= nkm->fixed_post_div; diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index 39413cb0985c..99359a06892d 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -29,8 +29,8 @@ static unsigned long ccu_nkmp_calc_rate(unsigned long parent, return rate; } -static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, - struct _ccu_nkmp *nkmp) +static unsigned long ccu_nkmp_find_best(unsigned long parent, unsigned long rate, + struct _ccu_nkmp *nkmp) { unsigned long best_rate = 0; unsigned long best_n = 0, best_k = 0, best_m = 0, best_p = 0; @@ -65,6 +65,8 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, nkmp->k = best_k; nkmp->m = best_m; nkmp->p = best_p; + + return best_rate; } static void ccu_nkmp_disable(struct clk_hw *hw) @@ -150,10 +152,8 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, _nkmp.min_p = 1; _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); - ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); + rate = ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); - rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, - _nkmp.m, _nkmp.p); if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) rate = rate / nkmp->fixed_post_div; diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index 9ca9257f4426..c1fd11542c45 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -27,8 +27,8 @@ static unsigned long ccu_nm_calc_rate(unsigned long parent, return rate; } -static void ccu_nm_find_best(unsigned long parent, unsigned long rate, - struct _ccu_nm *nm) +static unsigned long ccu_nm_find_best(unsigned long parent, unsigned long rate, + struct _ccu_nm *nm) { unsigned long best_rate = 0; unsigned long best_n = 0, best_m = 0; @@ -52,6 +52,8 @@ static void ccu_nm_find_best(unsigned long parent, unsigned long rate, nm->n = best_n; nm->m = best_m; + + return best_rate; } static void ccu_nm_disable(struct clk_hw *hw) @@ -157,8 +159,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, _nm.min_m = 1; _nm.max_m = nm->m.max ?: 1 << nm->m.width; - ccu_nm_find_best(*parent_rate, rate, &_nm); - rate = ccu_nm_calc_rate(*parent_rate, _nm.n, _nm.m); + rate = ccu_nm_find_best(*parent_rate, rate, &_nm); if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= nm->fixed_post_div; From a26dc096f683ca27ac5e68703bfd3098b4212abd Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 31 Dec 2022 17:14:24 -0600 Subject: [PATCH 4/9] clk: sunxi-ng: Remove duplicate ARCH_SUNXI dependencies SUNXI_CCU already depends on ARCH_SUNXI, so adding the dependency to individual SoC drivers is redundant. Drivers stay disabled under COMPILE_TEST because of the `default ARCH_SUNXI` applied to SUNXI_CCU. Acked-by: Jernej Skrabec Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20221231231429.18357-2-samuel@sholland.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/Kconfig | 43 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 461537679c04..64cfa022e320 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -14,43 +14,43 @@ config SUNIV_F1C100S_CCU config SUN20I_D1_CCU tristate "Support for the Allwinner D1 CCU" - default RISCV && ARCH_SUNXI - depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST + default RISCV + depends on RISCV || COMPILE_TEST config SUN20I_D1_R_CCU tristate "Support for the Allwinner D1 PRCM CCU" - default RISCV && ARCH_SUNXI - depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST + default RISCV + depends on RISCV || COMPILE_TEST config SUN50I_A64_CCU tristate "Support for the Allwinner A64 CCU" - default ARM64 && ARCH_SUNXI - depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + default ARM64 + depends on ARM64 || COMPILE_TEST config SUN50I_A100_CCU tristate "Support for the Allwinner A100 CCU" - default ARM64 && ARCH_SUNXI - depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + default ARM64 + depends on ARM64 || COMPILE_TEST config SUN50I_A100_R_CCU tristate "Support for the Allwinner A100 PRCM CCU" - default ARM64 && ARCH_SUNXI - depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + default ARM64 + depends on ARM64 || COMPILE_TEST config SUN50I_H6_CCU tristate "Support for the Allwinner H6 CCU" - default ARM64 && ARCH_SUNXI - depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + default ARM64 + depends on ARM64 || COMPILE_TEST config SUN50I_H616_CCU tristate "Support for the Allwinner H616 CCU" - default ARM64 && ARCH_SUNXI - depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + default ARM64 + depends on ARM64 || COMPILE_TEST config SUN50I_H6_R_CCU tristate "Support for the Allwinner H6 and H616 PRCM CCU" - default ARM64 && ARCH_SUNXI - depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST + default ARM64 + depends on ARM64 || COMPILE_TEST config SUN4I_A10_CCU tristate "Support for the Allwinner A10/A20 CCU" @@ -71,8 +71,7 @@ config SUN6I_A31_CCU config SUN6I_RTC_CCU tristate "Support for the Allwinner H616/R329 RTC CCU" - default ARCH_SUNXI - depends on ARCH_SUNXI || COMPILE_TEST + default y config SUN8I_A23_CCU tristate "Support for the Allwinner A23 CCU" @@ -91,8 +90,8 @@ config SUN8I_A83T_CCU config SUN8I_H3_CCU tristate "Support for the Allwinner H3 CCU" - default MACH_SUN8I || (ARM64 && ARCH_SUNXI) - depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST + default MACH_SUN8I || ARM64 + depends on MACH_SUN8I || ARM64 || COMPILE_TEST config SUN8I_V3S_CCU tristate "Support for the Allwinner V3s CCU" @@ -101,7 +100,7 @@ config SUN8I_V3S_CCU config SUN8I_DE2_CCU tristate "Support for the Allwinner SoCs DE2 CCU" - default MACH_SUN8I || (ARM64 && ARCH_SUNXI) + default MACH_SUN8I || ARM64 config SUN8I_R40_CCU tristate "Support for the Allwinner R40 CCU" @@ -115,6 +114,6 @@ config SUN9I_A80_CCU config SUN8I_R_CCU tristate "Support for Allwinner SoCs' PRCM CCUs" - default MACH_SUN8I || (ARCH_SUNXI && ARM64) + default MACH_SUN8I || ARM64 endif From 0ff347db4c97cc16b4e428dc1db550ba3628f1e2 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 31 Dec 2022 17:14:25 -0600 Subject: [PATCH 5/9] clk: sunxi-ng: Move SoC driver conditions to dependencies Do not duplicate the same expression on the `default` line, so the two lines do not need to be kept in sync. Drivers stay disabled under COMPILE_TEST because of the `default ARCH_SUNXI` applied to SUNXI_CCU. Three drivers had no conditions. - SUN6I_RTC_CCU and SUN8I_DE2_CCU are used on current hardware regardless of CPU architecture. - SUN8I_R_CCU is only used on pre-H6 SoCs, which means no RISCV SoCs. Acked-by: Jernej Skrabec Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20221231231429.18357-3-samuel@sholland.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/Kconfig | 46 +++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 64cfa022e320..78deee2996ce 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -9,111 +9,113 @@ if SUNXI_CCU config SUNIV_F1C100S_CCU tristate "Support for the Allwinner newer F1C100s CCU" - default MACH_SUNIV + default y depends on MACH_SUNIV || COMPILE_TEST config SUN20I_D1_CCU tristate "Support for the Allwinner D1 CCU" - default RISCV + default y depends on RISCV || COMPILE_TEST config SUN20I_D1_R_CCU tristate "Support for the Allwinner D1 PRCM CCU" - default RISCV + default y depends on RISCV || COMPILE_TEST config SUN50I_A64_CCU tristate "Support for the Allwinner A64 CCU" - default ARM64 + default y depends on ARM64 || COMPILE_TEST config SUN50I_A100_CCU tristate "Support for the Allwinner A100 CCU" - default ARM64 + default y depends on ARM64 || COMPILE_TEST config SUN50I_A100_R_CCU tristate "Support for the Allwinner A100 PRCM CCU" - default ARM64 + default y depends on ARM64 || COMPILE_TEST config SUN50I_H6_CCU tristate "Support for the Allwinner H6 CCU" - default ARM64 + default y depends on ARM64 || COMPILE_TEST config SUN50I_H616_CCU tristate "Support for the Allwinner H616 CCU" - default ARM64 + default y depends on ARM64 || COMPILE_TEST config SUN50I_H6_R_CCU tristate "Support for the Allwinner H6 and H616 PRCM CCU" - default ARM64 + default y depends on ARM64 || COMPILE_TEST config SUN4I_A10_CCU tristate "Support for the Allwinner A10/A20 CCU" - default MACH_SUN4I - default MACH_SUN7I + default y depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST config SUN5I_CCU bool "Support for the Allwinner sun5i family CCM" - default MACH_SUN5I + default y depends on MACH_SUN5I || COMPILE_TEST depends on SUNXI_CCU=y config SUN6I_A31_CCU tristate "Support for the Allwinner A31/A31s CCU" - default MACH_SUN6I + default y depends on MACH_SUN6I || COMPILE_TEST config SUN6I_RTC_CCU tristate "Support for the Allwinner H616/R329 RTC CCU" default y + depends on MACH_SUN8I || ARM64 || RISCV || COMPILE_TEST config SUN8I_A23_CCU tristate "Support for the Allwinner A23 CCU" - default MACH_SUN8I + default y depends on MACH_SUN8I || COMPILE_TEST config SUN8I_A33_CCU tristate "Support for the Allwinner A33 CCU" - default MACH_SUN8I + default y depends on MACH_SUN8I || COMPILE_TEST config SUN8I_A83T_CCU tristate "Support for the Allwinner A83T CCU" - default MACH_SUN8I + default y depends on MACH_SUN8I || COMPILE_TEST config SUN8I_H3_CCU tristate "Support for the Allwinner H3 CCU" - default MACH_SUN8I || ARM64 + default y depends on MACH_SUN8I || ARM64 || COMPILE_TEST config SUN8I_V3S_CCU tristate "Support for the Allwinner V3s CCU" - default MACH_SUN8I + default y depends on MACH_SUN8I || COMPILE_TEST config SUN8I_DE2_CCU tristate "Support for the Allwinner SoCs DE2 CCU" - default MACH_SUN8I || ARM64 + default y + depends on MACH_SUN8I || ARM64 || RISCV || COMPILE_TEST config SUN8I_R40_CCU tristate "Support for the Allwinner R40 CCU" - default MACH_SUN8I + default y depends on MACH_SUN8I || COMPILE_TEST config SUN9I_A80_CCU tristate "Support for the Allwinner A80 CCU" - default MACH_SUN9I + default y depends on MACH_SUN9I || COMPILE_TEST config SUN8I_R_CCU tristate "Support for Allwinner SoCs' PRCM CCUs" - default MACH_SUN8I || ARM64 + default y + depends on MACH_SUN8I || ARM64 || COMPILE_TEST endif From f1404c72b693b9f04cc991481155628620b248b5 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 31 Dec 2022 17:14:26 -0600 Subject: [PATCH 6/9] clk: sunxi-ng: d1: Allow building for R528/T113 Allwinner released some 32-bit ARM (sun8i) SoCs which use the same CCU as D1. Allow them to reuse the driver. Acked-by: Jernej Skrabec Reviewed-by: Andre Przywara Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20221231231429.18357-4-samuel@sholland.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 78deee2996ce..b547198a2c65 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -13,14 +13,14 @@ config SUNIV_F1C100S_CCU depends on MACH_SUNIV || COMPILE_TEST config SUN20I_D1_CCU - tristate "Support for the Allwinner D1 CCU" + tristate "Support for the Allwinner D1/R528/T113 CCU" default y - depends on RISCV || COMPILE_TEST + depends on MACH_SUN8I || RISCV || COMPILE_TEST config SUN20I_D1_R_CCU - tristate "Support for the Allwinner D1 PRCM CCU" + tristate "Support for the Allwinner D1/R528/T113 PRCM CCU" default y - depends on RISCV || COMPILE_TEST + depends on MACH_SUN8I || RISCV || COMPILE_TEST config SUN50I_A64_CCU tristate "Support for the Allwinner A64 CCU" From 6ec1c73f1be7bfdcf4d95ed3ae199d139f199e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Szemz=C5=91?= Date: Sat, 31 Dec 2022 17:14:27 -0600 Subject: [PATCH 7/9] clk: sunxi-ng: d1: Mark cpux clock as critical MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some SoCs in the D1 family feature ARM CPUs instead of a RISC-V CPU. In that case, the CPUs are driven from the 'cpux' clock, so it needs to be marked as critical, since there is no consumer when DVFS is disabled. This matches the drivers for other SoCs, and the "riscv" clock in this driver. Signed-off-by: András Szemző Acked-by: Jernej Skrabec Reviewed-by: Andre Przywara Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20221231231429.18357-5-samuel@sholland.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu-sun20i-d1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c index 8ef3cdeb7962..c5a7df93602c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c +++ b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c @@ -240,7 +240,7 @@ static const struct clk_parent_data cpux_parents[] = { { .hw = &pll_periph0_800M_clk.common.hw }, }; static SUNXI_CCU_MUX_DATA(cpux_clk, "cpux", cpux_parents, - 0x500, 24, 3, CLK_SET_RATE_PARENT); + 0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); static const struct clk_hw *cpux_hws[] = { &cpux_clk.common.hw }; static SUNXI_CCU_M_HWS(cpux_axi_clk, "cpux-axi", From 925b61ba2dafa9c13c9afa9b83a45d499cd73f2f Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 31 Dec 2022 17:14:28 -0600 Subject: [PATCH 8/9] dt-bindings: clock: Add D1 CAN bus gates and resets The D1 CCU contains gates and resets for two CAN buses. While the CAN bus controllers are only documented for the T113 SoC, the CCU is the same across all SoC variants. Reviewed-by: Andre Przywara Signed-off-by: Samuel Holland Acked-by: Philipp Zabel Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221231231429.18357-6-samuel@sholland.org Signed-off-by: Jernej Skrabec --- include/dt-bindings/clock/sun20i-d1-ccu.h | 2 ++ include/dt-bindings/reset/sun20i-d1-ccu.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/dt-bindings/clock/sun20i-d1-ccu.h b/include/dt-bindings/clock/sun20i-d1-ccu.h index e3ac53315e1a..e143b9929763 100644 --- a/include/dt-bindings/clock/sun20i-d1-ccu.h +++ b/include/dt-bindings/clock/sun20i-d1-ccu.h @@ -152,5 +152,7 @@ #define CLK_FANOUT0 142 #define CLK_FANOUT1 143 #define CLK_FANOUT2 144 +#define CLK_BUS_CAN0 145 +#define CLK_BUS_CAN1 146 #endif /* _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_ */ diff --git a/include/dt-bindings/reset/sun20i-d1-ccu.h b/include/dt-bindings/reset/sun20i-d1-ccu.h index de9ff5203239..f8001cf50bf1 100644 --- a/include/dt-bindings/reset/sun20i-d1-ccu.h +++ b/include/dt-bindings/reset/sun20i-d1-ccu.h @@ -73,5 +73,7 @@ #define RST_BUS_DSP_CFG 63 #define RST_BUS_DSP_DBG 64 #define RST_BUS_RISCV_CFG 65 +#define RST_BUS_CAN0 66 +#define RST_BUS_CAN1 67 #endif /* _DT_BINDINGS_RST_SUN20I_D1_CCU_H_ */ From e6f2ffeaf58b23614cc818587aa3a4fc7c108a55 Mon Sep 17 00:00:00 2001 From: Fabien Poussin Date: Sat, 31 Dec 2022 17:14:29 -0600 Subject: [PATCH 9/9] clk: sunxi-ng: d1: Add CAN bus gates and resets The D1 CCU contains gates and resets for two CAN buses. While the CAN bus controllers are only documented for the T113 SoC, the CCU is the same across all SoC variants. Signed-off-by: Fabien Poussin Reviewed-by: Andre Przywara Signed-off-by: Samuel Holland Acked-by: Jernej Skrabec Link: https://lore.kernel.org/r/20221231231429.18357-7-samuel@sholland.org Signed-off-by: Jernej Skrabec --- drivers/clk/sunxi-ng/ccu-sun20i-d1.c | 11 +++++++++++ drivers/clk/sunxi-ng/ccu-sun20i-d1.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c index c5a7df93602c..48a8fb2c43b7 100644 --- a/drivers/clk/sunxi-ng/ccu-sun20i-d1.c +++ b/drivers/clk/sunxi-ng/ccu-sun20i-d1.c @@ -469,6 +469,11 @@ static SUNXI_CCU_GATE_HWS(bus_i2c2_clk, "bus-i2c2", apb1_hws, static SUNXI_CCU_GATE_HWS(bus_i2c3_clk, "bus-i2c3", apb1_hws, 0x91c, BIT(3), 0); +static SUNXI_CCU_GATE_HWS(bus_can0_clk, "bus-can0", apb1_hws, + 0x92c, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_can1_clk, "bus-can1", apb1_hws, + 0x92c, BIT(1), 0); + static const struct clk_parent_data spi_parents[] = { { .fw_name = "hosc" }, { .hw = &pll_periph0_clk.hw }, @@ -997,6 +1002,8 @@ static struct ccu_common *sun20i_d1_ccu_clks[] = { &bus_i2c1_clk.common, &bus_i2c2_clk.common, &bus_i2c3_clk.common, + &bus_can0_clk.common, + &bus_can1_clk.common, &spi0_clk.common, &spi1_clk.common, &bus_spi0_clk.common, @@ -1147,6 +1154,8 @@ static struct clk_hw_onecell_data sun20i_d1_hw_clks = { [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw, + [CLK_BUS_CAN0] = &bus_can0_clk.common.hw, + [CLK_BUS_CAN1] = &bus_can1_clk.common.hw, [CLK_SPI0] = &spi0_clk.common.hw, [CLK_SPI1] = &spi1_clk.common.hw, [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, @@ -1252,6 +1261,8 @@ static struct ccu_reset_map sun20i_d1_ccu_resets[] = { [RST_BUS_I2C1] = { 0x91c, BIT(17) }, [RST_BUS_I2C2] = { 0x91c, BIT(18) }, [RST_BUS_I2C3] = { 0x91c, BIT(19) }, + [RST_BUS_CAN0] = { 0x92c, BIT(16) }, + [RST_BUS_CAN1] = { 0x92c, BIT(17) }, [RST_BUS_SPI0] = { 0x96c, BIT(16) }, [RST_BUS_SPI1] = { 0x96c, BIT(17) }, [RST_BUS_EMAC] = { 0x97c, BIT(16) }, diff --git a/drivers/clk/sunxi-ng/ccu-sun20i-d1.h b/drivers/clk/sunxi-ng/ccu-sun20i-d1.h index e303176f0d4e..b14da36e2537 100644 --- a/drivers/clk/sunxi-ng/ccu-sun20i-d1.h +++ b/drivers/clk/sunxi-ng/ccu-sun20i-d1.h @@ -10,6 +10,6 @@ #include #include -#define CLK_NUMBER (CLK_FANOUT2 + 1) +#define CLK_NUMBER (CLK_BUS_CAN1 + 1) #endif /* _CCU_SUN20I_D1_H_ */