From cdc86e473b353c8a026a337ee9fb9e1fbbe2276b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 25 Feb 2022 17:00:02 +0800 Subject: [PATCH 01/12] clk: imx8mq: add 27m phy pll ref clock According to pll documentation, the 3rd pll ref clock should be hdmi phy 27m clock, not dummy clock. Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220225090002.2497057-3-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 83cc2b1c32947..a9e69b6355edc 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -25,7 +25,7 @@ static u32 share_count_sai6; static u32 share_count_dcss; static u32 share_count_nand; -static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", }; +static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "hdmi_phy_27m", "dummy", }; static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; From 19565ea12d61c69ef2be97a97b426ba5c55572ff Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Feb 2022 20:41:11 +0800 Subject: [PATCH 02/12] clk: imx: add mcore_booted module paratemter Add mcore_booted boot parameter which could simplify AMP clock management. To i.MX8M, there is CCM(clock control Module) to generate clock root clock, anatop(analog PLL module) to generate PLL, and CCGR (clock gating) to gate clocks to peripherals. As below: anatop->ccm->ccgr->peripheral Linux handles the clock management and the auxiliary core is under control of Linux. Although there is per hardware domain control for CCGR and CCM, auxiliary core normally only use CCGR hardware domain control to avoid linux gate off the clk to peripherals and leave CCM ana anatop to Linux. Per NXP hardware design, because CCGR already support gate to peripherals, and clk root gate power leakage is negligible. So when in AMP case, we could not register the clk root gate. Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220228124112.3974242-1-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mm.c | 2 ++ drivers/clk/imx/clk-imx8mn.c | 2 ++ drivers/clk/imx/clk-imx8mp.c | 2 ++ drivers/clk/imx/clk-imx8mq.c | 2 ++ drivers/clk/imx/clk.c | 3 +++ drivers/clk/imx/clk.h | 1 + 6 files changed, 12 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index e8cbe181ec06d..a452fd1bb8914 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -639,6 +639,8 @@ static struct platform_driver imx8mm_clk_driver = { }, }; module_platform_driver(imx8mm_clk_driver); +module_param(mcore_booted, bool, S_IRUGO); +MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not"); MODULE_AUTHOR("Bai Ping "); MODULE_DESCRIPTION("NXP i.MX8MM clock driver"); diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 92fcbab4f5bee..dc69b7464b3d2 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -594,6 +594,8 @@ static struct platform_driver imx8mn_clk_driver = { }, }; module_platform_driver(imx8mn_clk_driver); +module_param(mcore_booted, bool, S_IRUGO); +MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not"); MODULE_AUTHOR("Anson Huang "); MODULE_DESCRIPTION("NXP i.MX8MN clock driver"); diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 18f5b7c3ca9d8..250e45d9f844d 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -721,6 +721,8 @@ static struct platform_driver imx8mp_clk_driver = { }, }; module_platform_driver(imx8mp_clk_driver); +module_param(mcore_booted, bool, S_IRUGO); +MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not"); MODULE_AUTHOR("Anson Huang "); MODULE_DESCRIPTION("NXP i.MX8MP clock driver"); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index a9e69b6355edc..9f57b06b143c1 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -632,6 +632,8 @@ static struct platform_driver imx8mq_clk_driver = { }, }; module_platform_driver(imx8mq_clk_driver); +module_param(mcore_booted, bool, S_IRUGO); +MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not"); MODULE_AUTHOR("Abel Vesa "); MODULE_DESCRIPTION("NXP i.MX8MQ clock driver"); diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 7cc669934253a..4bd6ad060eea5 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -17,6 +17,9 @@ DEFINE_SPINLOCK(imx_ccm_lock); EXPORT_SYMBOL_GPL(imx_ccm_lock); +bool mcore_booted; +EXPORT_SYMBOL_GPL(mcore_booted); + void imx_unregister_clocks(struct clk *clks[], unsigned int count) { unsigned int i; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index a7cbbcd1a3f46..5061a06468df8 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -7,6 +7,7 @@ #include extern spinlock_t imx_ccm_lock; +extern bool mcore_booted; void imx_check_clocks(struct clk *clks[], unsigned int count); void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count); From bb7e897b002aaf698e4ede6332bff38e77557a4b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 28 Feb 2022 20:41:12 +0800 Subject: [PATCH 03/12] clk: imx8m: check mcore_booted before register clk If mcore_booted is true, ignore the clk root gate registration and this will simplify AMP clock management and avoid system hang unexpectly especially Linux shutdown clk used by mcore. Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220228124112.3974242-2-peng.fan@oss.nxp.com [abelvesa@kernel.org: Removed if-case for when mcore_booted is true] Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-composite-8m.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 2dfd6149e5282..cbf0d7955a00a 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -178,7 +178,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, unsigned long flags) { struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw; - struct clk_hw *div_hw, *gate_hw; + struct clk_hw *div_hw, *gate_hw = NULL; struct clk_divider *div = NULL; struct clk_gate *gate = NULL; struct clk_mux *mux = NULL; @@ -223,14 +223,17 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, div->lock = &imx_ccm_lock; div->flags = CLK_DIVIDER_ROUND_CLOSEST; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) - goto fail; + /* skip registering the gate ops if M4 is enabled */ + if (!mcore_booted) { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto fail; - gate_hw = &gate->hw; - gate->reg = reg; - gate->bit_idx = PCG_CGC_SHIFT; - gate->lock = &imx_ccm_lock; + gate_hw = &gate->hw; + gate->reg = reg; + gate->bit_idx = PCG_CGC_SHIFT; + gate->lock = &imx_ccm_lock; + } hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, mux_hw, mux_ops, div_hw, From 56fddc6996c95d846d90abf212718628056669d5 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Thu, 10 Mar 2022 17:34:04 +0800 Subject: [PATCH 04/12] clk: imx: Remove the snvs clock The SNVS moudule is not used only by the linux, it may also used by other SW component is secure world. No sense to populate it in linux, so remove it. Signed-off-by: Jacky Bai Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220310093404.236966-1-ping.bai@nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx7d.c | 1 - drivers/clk/imx/clk-imx8mm.c | 1 - drivers/clk/imx/clk-imx8mn.c | 1 - drivers/clk/imx/clk-imx8mp.c | 1 - drivers/clk/imx/clk-imx8mq.c | 1 - 5 files changed, 5 deletions(-) diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 3f6fd7ef2a68f..cbf8131c63f7e 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -782,7 +782,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) hws[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); hws[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE); hws[IMX7D_OCOTP_CLK] = imx_clk_hw_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0); - hws[IMX7D_SNVS_CLK] = imx_clk_hw_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0); hws[IMX7D_MU_ROOT_CLK] = imx_clk_hw_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0); hws[IMX7D_CAAM_CLK] = imx_clk_hw_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0); hws[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_hw_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0); diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index a452fd1bb8914..b6d275855b36b 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -560,7 +560,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) hws[IMX8MM_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); hws[IMX8MM_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); hws[IMX8MM_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); - hws[IMX8MM_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); hws[IMX8MM_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); hws[IMX8MM_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); hws[IMX8MM_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index dc69b7464b3d2..745d533d11b10 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -522,7 +522,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); hws[IMX8MN_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); hws[IMX8MN_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); - hws[IMX8MN_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); hws[IMX8MN_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); hws[IMX8MN_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 250e45d9f844d..d2e9693091cc5 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -654,7 +654,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0); hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0); hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0); - hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0); hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0); hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0); hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 9f57b06b143c1..882dcad4817d7 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -557,7 +557,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) hws[IMX8MQ_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); hws[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); hws[IMX8MQ_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); - hws[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0); hws[IMX8MQ_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); hws[IMX8MQ_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); hws[IMX8MQ_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); From 9b30501949f773777f3632d891e6defbb363daf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Thu, 17 Mar 2022 23:35:58 +0100 Subject: [PATCH 05/12] dt-bindings: imx: add clock bindings for i.MX8MN GPT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The i.MX8MN has a General Purpose Timer (GPT) just like the i.MX8MM, which already has such bindings. Add the relevant bindings for the Nano SoC too. Signed-off-by: Alvin Šipraga Acked-by: Krzysztof Kozlowski Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220317223600.175894-1-alvin@pqrs.dk Signed-off-by: Abel Vesa --- include/dt-bindings/clock/imx8mn-clock.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h index 01e8bab1d767a..07b8a282c2682 100644 --- a/include/dt-bindings/clock/imx8mn-clock.h +++ b/include/dt-bindings/clock/imx8mn-clock.h @@ -243,6 +243,20 @@ #define IMX8MN_CLK_M7_CORE 221 -#define IMX8MN_CLK_END 222 +#define IMX8MN_CLK_GPT_3M 222 +#define IMX8MN_CLK_GPT1 223 +#define IMX8MN_CLK_GPT1_ROOT 224 +#define IMX8MN_CLK_GPT2 225 +#define IMX8MN_CLK_GPT2_ROOT 226 +#define IMX8MN_CLK_GPT3 227 +#define IMX8MN_CLK_GPT3_ROOT 228 +#define IMX8MN_CLK_GPT4 229 +#define IMX8MN_CLK_GPT4_ROOT 230 +#define IMX8MN_CLK_GPT5 231 +#define IMX8MN_CLK_GPT5_ROOT 232 +#define IMX8MN_CLK_GPT6 233 +#define IMX8MN_CLK_GPT6_ROOT 234 + +#define IMX8MN_CLK_END 235 #endif From ce0fc2f00fa26310cd29e462f816a5e660754d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Thu, 17 Mar 2022 23:35:59 +0100 Subject: [PATCH 06/12] clk: imx8mn: add GPT support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the General Purpose Timer (GPT) clocks on the i.MX8MN. The i.MX8MN GPT IP block is the same as on the i.MX8MM, on which this patch is based. Signed-off-by: Alvin Šipraga Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220317223600.175894-2-alvin@pqrs.dk Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mn.c | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 745d533d11b10..d37c45b676abe 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -227,6 +227,30 @@ static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys "sys_pll1_40m", "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", }; +static const char * const imx8mn_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + +static const char * const imx8mn_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + +static const char * const imx8mn_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + +static const char * const imx8mn_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + +static const char * const imx8mn_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + +static const char * const imx8mn_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", + "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m", + "audio_pll1_out", "clk_ext1", }; + static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", }; @@ -476,6 +500,12 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400); hws[IMX8MN_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480); hws[IMX8MN_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500); + hws[IMX8MN_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mn_gpt1_sels, base + 0xb580); + hws[IMX8MN_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mn_gpt2_sels, base + 0xb600); + hws[IMX8MN_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mn_gpt3_sels, base + 0xb680); + hws[IMX8MN_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mn_gpt4_sels, base + 0xb700); + hws[IMX8MN_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mn_gpt5_sels, base + 0xb780); + hws[IMX8MN_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mn_gpt6_sels, base + 0xb800); hws[IMX8MN_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mn_wdog_sels, base + 0xb900); hws[IMX8MN_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980); hws[IMX8MN_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mn_clko1_sels, base + 0xba00); @@ -501,6 +531,12 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0); hws[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0); hws[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0); + hws[IMX8MN_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); + hws[IMX8MN_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", base + 0x4110, 0); + hws[IMX8MN_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", base + 0x4120, 0); + hws[IMX8MN_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", base + 0x4130, 0); + hws[IMX8MN_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", base + 0x4140, 0); + hws[IMX8MN_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", base + 0x4150, 0); hws[IMX8MN_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); hws[IMX8MN_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); hws[IMX8MN_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); @@ -548,6 +584,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev) hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0); hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7); + hws[IMX8MN_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8); + hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4); hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", From ed713e2bc093239ccd380c2ce8ae9e4162f5c037 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Thu, 10 Mar 2022 16:02:57 +0800 Subject: [PATCH 07/12] clk: imx: Add check for kcalloc As the potential failure of the kcalloc(), it should be better to check it in order to avoid the dereference of the NULL pointer. Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout") Signed-off-by: Jiasheng Jiang Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220310080257.1988412-1-jiasheng@iscas.ac.cn Signed-off-by: Abel Vesa --- drivers/clk/imx/clk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 4bd6ad060eea5..5582f18dd632f 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -176,6 +176,8 @@ void imx_register_uart_clocks(unsigned int clk_count) int i; imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL); + if (!imx_uart_clocks) + return; if (!of_stdout) return; From 2759f38b6c9551e4a1184131bc660d6a520a7cf4 Mon Sep 17 00:00:00 2001 From: Xiaoke Wang Date: Thu, 7 Apr 2022 15:37:22 +0800 Subject: [PATCH 08/12] clk: imx: scu: fix a potential memory leak in __imx_clk_gpr_scu() In __imx_clk_gpr_scu(), if imx_scu_clk_is_valid(rsrc_id) fails, then `clk_node` which is allocated by kzalloc() is not properly released, which may lead to memory leak. So this patch added kfree(clk_node) on the above error path before return ERR_PTR(-EINVAL). Signed-off-by: Xiaoke Wang Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/tencent_27FF59903EE6AB5C0D0E6D0A8E7059A59007@qq.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-scu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 083da31dc3ead..ed3c01d2e8ae5 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -837,8 +837,10 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na if (!clk_node) return ERR_PTR(-ENOMEM); - if (!imx_scu_clk_is_valid(rsrc_id)) + if (!imx_scu_clk_is_valid(rsrc_id)) { + kfree(clk_node); return ERR_PTR(-EINVAL); + } clk = kzalloc(sizeof(*clk), GFP_KERNEL); if (!clk) { From 39772efd98adecbd5b8c6096d465d2fcbafbde6a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 13 Mar 2022 13:39:49 +0100 Subject: [PATCH 09/12] clk: imx8mp: Add DISP2 pixel clock Add pixel clock for second LCDIFv3 interface. Both LCDIFv3 interfaces use the same set of parent clock, so deduplicate imx8mp_media_disp1_pix_sels into common imx8mp_media_disp_pix_sels and use it for both. Signed-off-by: Marek Vasut Cc: Abel Vesa Cc: Fabio Estevam Cc: NXP Linux Team Cc: Peng Fan Cc: Shawn Guo Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220313123949.207284-1-marex@denx.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp.c | 5 +++-- include/dt-bindings/clock/imx8mp-clock.h | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index d2e9693091cc5..c8a0534b5b1fb 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -358,7 +358,7 @@ static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_p "clk_ext2", "audio_pll2_out", "video_pll1_out", }; -static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", +static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", }; @@ -538,6 +538,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000); hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100); hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200); + hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300); hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1); @@ -600,7 +601,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80); hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00); hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80); - hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00); + hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00); hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80); hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00); hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80); diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h index 235c7a00d379c..e05d21bf7813e 100644 --- a/include/dt-bindings/clock/imx8mp-clock.h +++ b/include/dt-bindings/clock/imx8mp-clock.h @@ -318,7 +318,9 @@ #define IMX8MP_CLK_HSIO_AXI 311 #define IMX8MP_CLK_MEDIA_ISP 312 -#define IMX8MP_CLK_END 313 +#define IMX8MP_CLK_MEDIA_DISP2_PIX 313 + +#define IMX8MP_CLK_END 314 #define IMX8MP_CLK_AUDIOMIX_SAI1_IPG 0 #define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1 1 From bfd594b3acbd2656edcc7742e1270d09c0de9d4d Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Mon, 25 Apr 2022 09:11:17 +0800 Subject: [PATCH 10/12] clk: imx: scu: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync() usage If the device is already in a runtime PM enabled state pm_runtime_get_sync() will return 1. Also, we need to call pm_runtime_put_noidle() when pm_runtime_get_sync() fails, so use pm_runtime_resume_and_get() instead. this function will handle this. Fixes: 78edeb080330 ("clk: imx: scu: add runtime pm support") Signed-off-by: Miaoqian Lin Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220425011117.25093-1-linmq006@gmail.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-scu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index ed3c01d2e8ae5..5b022eeb838ba 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -528,7 +528,7 @@ static int imx_clk_scu_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret) { pm_genpd_remove_device(dev); pm_runtime_disable(dev); From 43896f56b59eeaf08687fa976257ae7083d01b41 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 27 Apr 2022 18:21:31 +0200 Subject: [PATCH 11/12] clk: imx8mp: add clkout1/2 support clkout1 and clkout2 allow to supply clocks from the SoC to the board, which is used by some board designs to provide reference clocks. Signed-off-by: Lucas Stach Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220427162131.3127303-1-l.stach@pengutronix.de Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp.c | 14 ++++++++++++++ include/dt-bindings/clock/imx8mp-clock.h | 9 +++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index c8a0534b5b1fb..ba058fbccecc3 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -399,6 +399,11 @@ static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "au static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; +static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "dummy", "dummy", "gpu_pll_out", "vpu_pll_out", + "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", + "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; + static struct clk_hw **hws; static struct clk_hw_onecell_data *clk_hw_data; @@ -504,6 +509,15 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); + hws[IMX8MP_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", anatop_base + 0x128, 4, 4, + imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels)); + hws[IMX8MP_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", anatop_base + 0x128, 0, 4); + hws[IMX8MP_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", anatop_base + 0x128, 8); + hws[IMX8MP_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", anatop_base + 0x128, 20, 4, + imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels)); + hws[IMX8MP_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", anatop_base + 0x128, 16, 4); + hws[IMX8MP_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", anatop_base + 0x128, 24); + hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000); hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV]; hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV]; diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h index e05d21bf7813e..9d5cc2ddde896 100644 --- a/include/dt-bindings/clock/imx8mp-clock.h +++ b/include/dt-bindings/clock/imx8mp-clock.h @@ -317,10 +317,15 @@ #define IMX8MP_CLK_AUDIO_AXI 310 #define IMX8MP_CLK_HSIO_AXI 311 #define IMX8MP_CLK_MEDIA_ISP 312 - #define IMX8MP_CLK_MEDIA_DISP2_PIX 313 +#define IMX8MP_CLK_CLKOUT1_SEL 314 +#define IMX8MP_CLK_CLKOUT1_DIV 315 +#define IMX8MP_CLK_CLKOUT1 316 +#define IMX8MP_CLK_CLKOUT2_SEL 317 +#define IMX8MP_CLK_CLKOUT2_DIV 318 +#define IMX8MP_CLK_CLKOUT2 319 -#define IMX8MP_CLK_END 314 +#define IMX8MP_CLK_END 320 #define IMX8MP_CLK_AUDIOMIX_SAI1_IPG 0 #define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1 1 From cf7f3f4fa9e57b8e9f594823e77e6cbb0ce2b254 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 7 May 2022 20:54:30 +0800 Subject: [PATCH 12/12] clk: imx8mp: fix usb_root_clk parent According to reference mannual CCGR77(usb) sources from hsio_axi, fix it. Fixes: 9c140d9926761 ("clk: imx: Add support for i.MX8MP clock driver") Signed-off-by: Peng Fan Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20220507125430.793287-1-peng.fan@oss.nxp.com Signed-off-by: Abel Vesa --- drivers/clk/imx/clk-imx8mp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index ba058fbccecc3..e89db568f5a89 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -673,7 +673,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0); hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0); hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0); - hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "osc_32k", ccm_base + 0x44d0, 0); + hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0); hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0); hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0); hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);