diff options
author | Stephen Boyd <sboyd@kernel.org> | 2021-08-28 21:15:35 -0700 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2021-08-28 21:15:35 -0700 |
commit | 3e061910b2a2ea2bc25861068a11df011fd3a0f8 (patch) | |
tree | 050ccf4b23b239b4d532bfb821888d462017d7a9 | |
parent | e73f0f0ee7541171d89f2e2491130c7771ba58d3 (diff) | |
parent | 86842d255b45fc2103da1cd202f5064397ed41f8 (diff) |
Merge tag 'clk-imx-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux into clk-imx
Pull i.MX clock driver updates from Abel Vesa
- Fix CLKOUT clocks on i.MX8MM and i.MX8MN by using imx_clk_hw_mux2
- Switch from .round_rate to .determine_rate in clk-divider-gate
- Fix clock tree update for TF-A controlled clocks for all i.MX8M
- Add missing M7 core clock for i.MX8MN
* tag 'clk-imx-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux:
clk: imx8mn: Add M7 core clock
clk: imx8m: fix clock tree update of TF-A managed clocks
clk: imx: clk-divider-gate: Switch to clk_divider.determine_rate
clk: imx8mn: use correct mux type for clkout path
clk: imx8mm: use correct mux type for clkout path
-rw-r--r-- | drivers/clk/imx/clk-composite-8m.c | 3 | ||||
-rw-r--r-- | drivers/clk/imx/clk-divider-gate.c | 10 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8mm.c | 11 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8mn.c | 16 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8mq.c | 7 | ||||
-rw-r--r-- | drivers/clk/imx/clk.h | 16 | ||||
-rw-r--r-- | include/dt-bindings/clock/imx8mn-clock.h | 4 |
7 files changed, 45 insertions, 22 deletions
diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 2c309e3dc8e3..04e728538cef 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -216,7 +216,8 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, div->width = PCG_PREDIV_WIDTH; divider_ops = &imx8m_clk_composite_divider_ops; mux_ops = &clk_mux_ops; - flags |= CLK_SET_PARENT_GATE; + if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED)) + flags |= CLK_SET_PARENT_GATE; } div->lock = &imx_ccm_lock; diff --git a/drivers/clk/imx/clk-divider-gate.c b/drivers/clk/imx/clk-divider-gate.c index 0322a843d245..26b210cba9be 100644 --- a/drivers/clk/imx/clk-divider-gate.c +++ b/drivers/clk/imx/clk-divider-gate.c @@ -64,10 +64,10 @@ static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw, div->flags, div->width); } -static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return clk_divider_ops.round_rate(hw, rate, prate); + return clk_divider_ops.determine_rate(hw, req); } static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate, @@ -154,12 +154,12 @@ static int clk_divider_is_enabled(struct clk_hw *hw) static const struct clk_ops clk_divider_gate_ro_ops = { .recalc_rate = clk_divider_gate_recalc_rate_ro, - .round_rate = clk_divider_round_rate, + .determine_rate = clk_divider_determine_rate, }; static const struct clk_ops clk_divider_gate_ops = { .recalc_rate = clk_divider_gate_recalc_rate, - .round_rate = clk_divider_round_rate, + .determine_rate = clk_divider_determine_rate, .set_rate = clk_divider_gate_set_rate, .enable = clk_divider_enable, .disable = clk_divider_disable, diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index f1919fafb124..e92621fa8b9c 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -407,10 +407,10 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); hws[IMX8MM_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); - hws[IMX8MM_CLK_CLKOUT1_SEL] = imx_clk_hw_mux("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MM_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); hws[IMX8MM_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4); hws[IMX8MM_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8); - hws[IMX8MM_CLK_CLKOUT2_SEL] = imx_clk_hw_mux("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MM_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); hws[IMX8MM_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4); hws[IMX8MM_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24); @@ -470,10 +470,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) /* * DRAM clocks are manipulated from TF-A outside clock framework. - * Mark with GET_RATE_NOCACHE to always read div value from hardware + * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE + * as div value should always be read from hardware */ - hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); - hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000); + hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080); /* IP */ hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100); diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 88f6630cd472..c55577604e16 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -40,6 +40,9 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", }; +static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out", + "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; + static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; @@ -402,10 +405,10 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); - hws[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_hw_mux("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); hws[IMX8MN_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4); hws[IMX8MN_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8); - hws[IMX8MN_CLK_CLKOUT2_SEL] = imx_clk_hw_mux("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MN_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); hws[IMX8MN_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4); hws[IMX8MN_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24); @@ -421,6 +424,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV]; hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV]; + hws[IMX8MN_CLK_M7_CORE] = imx8m_clk_hw_composite_core("arm_m7_core", imx8mn_m7_sels, base + 0x8080); + hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180); hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200); @@ -453,10 +458,11 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) /* * DRAM clocks are manipulated from TF-A outside clock framework. - * Mark with GET_RATE_NOCACHE to always read div value from hardware + * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE + * as div value should always be read from hardware */ - hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); - hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000); + hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080); hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500); hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index c491bc9c61ce..83cc2b1c3294 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -449,11 +449,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) /* * DRAM clocks are manipulated from TF-A outside clock framework. - * Mark with GET_RATE_NOCACHE to always read div value from hardware + * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE + * as div value should always be read from hardware */ hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); - hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE); - hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); + hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000); + hws[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080); /* IP */ hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 7571603bee23..e144f983fd8c 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -530,8 +530,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, struct clk *div, struct clk *mux, struct clk *pll, struct clk *step); -#define IMX_COMPOSITE_CORE BIT(0) -#define IMX_COMPOSITE_BUS BIT(1) +#define IMX_COMPOSITE_CORE BIT(0) +#define IMX_COMPOSITE_BUS BIT(1) +#define IMX_COMPOSITE_FW_MANAGED BIT(2) struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, const char * const *parent_names, @@ -567,6 +568,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, ARRAY_SIZE(parent_names), reg, 0, \ flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) +#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \ + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \ + flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + +#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \ + __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0) + +#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \ + __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL) + #define __imx8m_clk_composite(name, parent_names, reg, flags) \ to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags)) diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h index d24b627cb2e7..01e8bab1d767 100644 --- a/include/dt-bindings/clock/imx8mn-clock.h +++ b/include/dt-bindings/clock/imx8mn-clock.h @@ -241,6 +241,8 @@ #define IMX8MN_CLK_CLKOUT2_DIV 219 #define IMX8MN_CLK_CLKOUT2 220 -#define IMX8MN_CLK_END 221 +#define IMX8MN_CLK_M7_CORE 221 + +#define IMX8MN_CLK_END 222 #endif |