From 338f1c25269185cbea6e3dd966e5c859af2323f7 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Sat, 24 Feb 2024 14:20:45 -0600 Subject: clk: samsung: Pass actual CPU clock registers base to CPU_CLK() The documentation for struct exynos_cpuclk says .ctrl_base field should contain the controller base address. There are two different problems with that: 1. All Exynos clock drivers are actually passing CPU_SRC register offset via CPU_CLK() macro, which in turn gets assigned to mentioned .ctrl_base field. Because CPU_SRC register usually already has 0x200 offset from controller's base, all other register offsets in clk-cpu.c (like DIVs and MUXes) are specified as offsets from CPU_SRC offset, and not from controller's base. That makes things confusing and inconsistent with register offsets provided in Exynos clock drivers, also breaking the contract for .ctrl_base field as described in struct exynos_cpuclk doc. 2. Furthermore, some Exynos chips have an additional offset for the start of CPU clock registers block (inside of the CMU). There might be different reasons for that, e.g.: - The CMU contains clocks for two different CPUs (like in Exynos5420) - The CMU contains also non-CPU clocks as well (like in Exynos4) - The CPU CMU exists as a dedicated hardware block in the SoC layout, but is modelled as a part of bigger CMU in the driver (like in case of Exynos3250) That means the .ctrl_base field is actually not a controller's base, but instead it's a start address of the CPU clock registers inside of the CMU. Rework all register offsets in clk-cpu.c to be actual offsets from the CPU clock register block start, and fix offsets provided to CPU_CLK() macro in all Exynos clock drivers. Also clarify the .ctrl_base field documentation and rename it to just .base, because it doesn't really contain the CMU base. No functional change. Signed-off-by: Sam Protsenko Link: https://lore.kernel.org/r/20240224202053.25313-8-semen.protsenko@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-exynos5420.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/clk/samsung/clk-exynos5420.c') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 199843f12ae5..bd7b304d2c00 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -1555,17 +1555,17 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = { }; static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200, - exynos5420_eglclk_d), - CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200, - exynos5420_kfcclk_d), + CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, + 0x0, exynos5420_eglclk_d), + CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, + 0x28000, exynos5420_kfcclk_d), }; static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200, - exynos5800_eglclk_d), - CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200, - exynos5420_kfcclk_d), + CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, + 0x0, exynos5800_eglclk_d), + CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, + 0x28000, exynos5420_kfcclk_d), }; static const struct of_device_id ext_clk_match[] __initconst = { -- cgit v1.2.3 From 6d7d203ca6914e84166a00d0f0bdfda6cbce76a7 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Sat, 24 Feb 2024 14:20:46 -0600 Subject: clk: samsung: Pass register layout type explicitly to CLK_CPU() Use a dedicated enum field to explicitly specify which register layout should be used for the CPU clock, instead of passing it as a bit flag. This way it would be possible to keep the chip-specific data in some array, where each chip structure could be accessed by its corresponding layout index. It prepares clk-cpu.c for adding new chips support, which might have different data for different CPU clusters. No functional change. Signed-off-by: Sam Protsenko Link: https://lore.kernel.org/r/20240224202053.25313-9-semen.protsenko@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/clk/samsung/clk-cpu.c | 2 +- drivers/clk/samsung/clk-cpu.h | 12 ++++++++++-- drivers/clk/samsung/clk-exynos3250.c | 2 +- drivers/clk/samsung/clk-exynos4.c | 6 +++--- drivers/clk/samsung/clk-exynos5250.c | 3 ++- drivers/clk/samsung/clk-exynos5420.c | 8 ++++---- drivers/clk/samsung/clk-exynos5433.c | 8 ++++---- drivers/clk/samsung/clk.h | 5 ++++- 8 files changed, 29 insertions(+), 17 deletions(-) (limited to 'drivers/clk/samsung/clk-exynos5420.c') diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index 82d54b0c9040..635ab8cc54a2 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -465,7 +465,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, cpuclk->lock = &ctx->lock; cpuclk->flags = clk_data->flags; cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb; - if (clk_data->flags & CLK_CPU_HAS_E5433_REGS_LAYOUT) { + if (clk_data->reg_layout == CPUCLK_LAYOUT_E5433) { cpuclk->pre_rate_cb = exynos5433_cpuclk_pre_rate_change; cpuclk->post_rate_cb = exynos5433_cpuclk_post_rate_change; } else { diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h index ee57f3638fed..4382ab005ad3 100644 --- a/drivers/clk/samsung/clk-cpu.h +++ b/drivers/clk/samsung/clk-cpu.h @@ -12,8 +12,16 @@ #define CLK_CPU_HAS_DIV1 BIT(0) /* When ALT parent is active, debug clocks need safe divider values */ #define CLK_CPU_NEEDS_DEBUG_ALT_DIV BIT(1) -/* The CPU clock registers have Exynos5433-compatible layout */ -#define CLK_CPU_HAS_E5433_REGS_LAYOUT BIT(2) + +/** + * enum exynos_cpuclk_layout - CPU clock registers layout compatibility + * @CPUCLK_LAYOUT_E4210: Exynos4210 compatible layout + * @CPUCLK_LAYOUT_E5433: Exynos5433 compatible layout + */ +enum exynos_cpuclk_layout { + CPUCLK_LAYOUT_E4210, + CPUCLK_LAYOUT_E5433, +}; /** * struct exynos_cpuclk_cfg_data - config data to setup cpu clocks diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c index bf149fae04c3..cd4fec323a42 100644 --- a/drivers/clk/samsung/clk-exynos3250.c +++ b/drivers/clk/samsung/clk-exynos3250.c @@ -775,7 +775,7 @@ static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = { static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = { CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C, - CLK_CPU_HAS_DIV1, 0x14000, e3250_armclk_d), + CLK_CPU_HAS_DIV1, 0x14000, CPUCLK_LAYOUT_E4210, e3250_armclk_d), }; static void __init exynos3_core_down_clock(void __iomem *reg_base) diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index d5b1e9f49d8b..a026ccca7315 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -1253,19 +1253,19 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = { static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = { CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL, CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000, - e4210_armclk_d), + CPUCLK_LAYOUT_E4210, e4210_armclk_d), }; static const struct samsung_cpu_clock exynos4212_cpu_clks[] __initconst = { CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C, CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000, - e4212_armclk_d), + CPUCLK_LAYOUT_E4210, e4212_armclk_d), }; static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = { CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C, CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14000, - e4412_armclk_d), + CPUCLK_LAYOUT_E4210, e4412_armclk_d), }; /* register exynos4 clocks */ diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 58df80de52ef..e02e7c013f3d 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -777,7 +777,8 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = { static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = { CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL, - CLK_CPU_HAS_DIV1, 0x0, exynos5250_armclk_d), + CLK_CPU_HAS_DIV1, 0x0, CPUCLK_LAYOUT_E4210, + exynos5250_armclk_d), }; static const struct of_device_id ext_clk_match[] __initconst = { diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index bd7b304d2c00..c630135c686b 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -1556,16 +1556,16 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = { static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = { CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, - 0x0, exynos5420_eglclk_d), + 0x0, CPUCLK_LAYOUT_E4210, exynos5420_eglclk_d), CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, - 0x28000, exynos5420_kfcclk_d), + 0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d), }; static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = { CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, - 0x0, exynos5800_eglclk_d), + 0x0, CPUCLK_LAYOUT_E4210, exynos5800_eglclk_d), CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, - 0x28000, exynos5420_kfcclk_d), + 0x28000, CPUCLK_LAYOUT_E4210, exynos5420_kfcclk_d), }; static const struct of_device_id ext_clk_match[] __initconst = { diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index d3779eefb438..609d31a7aa52 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -3700,8 +3700,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = { CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL, - CLK_MOUT_BUS_PLL_APOLLO_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT, - 0x0, exynos5433_apolloclk_d), + CLK_MOUT_BUS_PLL_APOLLO_USER, 0, 0x0, + CPUCLK_LAYOUT_E5433, exynos5433_apolloclk_d), }; static const struct samsung_cmu_info apollo_cmu_info __initconst = { @@ -3944,8 +3944,8 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst = static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = { CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL, - CLK_MOUT_BUS_PLL_ATLAS_USER, CLK_CPU_HAS_E5433_REGS_LAYOUT, - 0x0, exynos5433_atlasclk_d), + CLK_MOUT_BUS_PLL_ATLAS_USER, 0, 0x0, + CPUCLK_LAYOUT_E5433, exynos5433_atlasclk_d), }; static const struct samsung_cmu_info atlas_cmu_info __initconst = { diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 516b716407e5..a763309e6f12 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -12,6 +12,7 @@ #include #include "clk-pll.h" +#include "clk-cpu.h" /** * struct samsung_clk_provider - information about clock provider @@ -282,10 +283,11 @@ struct samsung_cpu_clock { unsigned int alt_parent_id; unsigned long flags; int offset; + enum exynos_cpuclk_layout reg_layout; const struct exynos_cpuclk_cfg_data *cfg; }; -#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \ +#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _layout, _cfg) \ { \ .id = _id, \ .name = _name, \ @@ -293,6 +295,7 @@ struct samsung_cpu_clock { .alt_parent_id = _apid, \ .flags = _flags, \ .offset = _offset, \ + .reg_layout = _layout, \ .cfg = _cfg, \ } -- cgit v1.2.3