From b60521eff227ef459e03879cbea2b2bd85a8d7af Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 11 Jan 2025 17:54:18 +0100 Subject: [PATCH 01/63] clk: qcom: gcc-x1e80100: Unregister GCC_GPU_CFG_AHB_CLK/GCC_DISP_XO_CLK The GPU clock is required for CPU access to GPUSS registers. It was previously decided (on this and many more platforms) that the added overhead/hassle introduced by keeping track of it would not bring much measurable improvement in the power department. The display clock is basically the same story over again. Now, we're past that discussion and this commit is not trying to change that. Instead, the clocks are both force-enabled in .probe *and* registered with the common clock framework, resulting in them being toggled off after ignore_unused. Unregister said clocks to fix breakage when clk_ignore_unused is absent (as it should be). Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250111-topic-x1e_fixups-v1-1-77dc39237c12@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-x1e80100.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index 7288af845434..009f39139b64 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -2564,19 +2564,6 @@ static struct clk_branch gcc_disp_hf_axi_clk = { }, }; -static struct clk_branch gcc_disp_xo_clk = { - .halt_reg = 0x27018, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x27018, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "gcc_disp_xo_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gp1_clk = { .halt_reg = 0x64000, .halt_check = BRANCH_HALT, @@ -2631,21 +2618,6 @@ static struct clk_branch gcc_gp3_clk = { }, }; -static struct clk_branch gcc_gpu_cfg_ahb_clk = { - .halt_reg = 0x71004, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x71004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x71004, - .enable_mask = BIT(0), - .hw.init = &(const struct clk_init_data) { - .name = "gcc_gpu_cfg_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_gpll0_cph_clk_src = { .halt_check = BRANCH_HALT_DELAY, .clkr = { @@ -6268,7 +6240,6 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_CNOC_PCIE_TUNNEL_CLK] = &gcc_cnoc_pcie_tunnel_clk.clkr, [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, - [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, @@ -6281,7 +6252,6 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_GPLL7] = &gcc_gpll7.clkr, [GCC_GPLL8] = &gcc_gpll8.clkr, [GCC_GPLL9] = &gcc_gpll9.clkr, - [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, [GCC_GPU_GPLL0_CPH_CLK_SRC] = &gcc_gpu_gpll0_cph_clk_src.clkr, [GCC_GPU_GPLL0_DIV_CPH_CLK_SRC] = &gcc_gpu_gpll0_div_cph_clk_src.clkr, [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, From 52b10b591f83dc6d9a1d6c2dc89433470a787ecd Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 22 Jan 2025 22:26:12 +0000 Subject: [PATCH 02/63] clk: qcom: camcc-sm8250: Use clk_rcg2_shared_ops for some RCGs Update some RCGs on the sm8250 camera clock controller to use clk_rcg2_shared_ops. The shared_ops ensure the RCGs get parked to the XO during clock disable to prevent the clocks from locking up when the GDSC is enabled. These mirror similar fixes for other controllers such as commit e5c359f70e4b ("clk: qcom: camcc: Update the clock ops for the SC7180"). Signed-off-by: Jordan Crouse Reviewed-by: Dmitry Baryshkov Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20250122222612.32351-1-jorcrous@amazon.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sm8250.c | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index 34d2f17520dc..450ddbebd35f 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -411,7 +411,7 @@ static struct clk_rcg2 cam_cc_bps_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -433,7 +433,7 @@ static struct clk_rcg2 cam_cc_camnoc_axi_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -454,7 +454,7 @@ static struct clk_rcg2 cam_cc_cci_0_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -469,7 +469,7 @@ static struct clk_rcg2 cam_cc_cci_1_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -490,7 +490,7 @@ static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -511,7 +511,7 @@ static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -526,7 +526,7 @@ static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -556,7 +556,7 @@ static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -571,7 +571,7 @@ static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -586,7 +586,7 @@ static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -611,7 +611,7 @@ static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -634,7 +634,7 @@ static struct clk_rcg2 cam_cc_fd_core_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -649,7 +649,7 @@ static struct clk_rcg2 cam_cc_icp_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -673,7 +673,7 @@ static struct clk_rcg2 cam_cc_ife_0_clk_src = { .parent_data = cam_cc_parent_data_2, .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -710,7 +710,7 @@ static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -734,7 +734,7 @@ static struct clk_rcg2 cam_cc_ife_1_clk_src = { .parent_data = cam_cc_parent_data_3, .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -749,7 +749,7 @@ static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -771,7 +771,7 @@ static struct clk_rcg2 cam_cc_ife_lite_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -786,7 +786,7 @@ static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -810,7 +810,7 @@ static struct clk_rcg2 cam_cc_ipe_0_clk_src = { .parent_data = cam_cc_parent_data_4, .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -825,7 +825,7 @@ static struct clk_rcg2 cam_cc_jpeg_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -847,7 +847,7 @@ static struct clk_rcg2 cam_cc_mclk0_clk_src = { .parent_data = cam_cc_parent_data_1, .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -862,7 +862,7 @@ static struct clk_rcg2 cam_cc_mclk1_clk_src = { .parent_data = cam_cc_parent_data_1, .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -877,7 +877,7 @@ static struct clk_rcg2 cam_cc_mclk2_clk_src = { .parent_data = cam_cc_parent_data_1, .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -892,7 +892,7 @@ static struct clk_rcg2 cam_cc_mclk3_clk_src = { .parent_data = cam_cc_parent_data_1, .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -907,7 +907,7 @@ static struct clk_rcg2 cam_cc_mclk4_clk_src = { .parent_data = cam_cc_parent_data_1, .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -922,7 +922,7 @@ static struct clk_rcg2 cam_cc_mclk5_clk_src = { .parent_data = cam_cc_parent_data_1, .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -993,7 +993,7 @@ static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { .parent_data = cam_cc_parent_data_0, .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; From 0e6dfde439df0bb977cddd3cf7fff150a084a9bf Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 17 Jan 2025 13:54:07 +0000 Subject: [PATCH 03/63] clk: qcom: gdsc: Release pm subdomains in reverse add order gdsc_unregister() should release subdomains in the reverse order to the order in which those subdomains were added. I've made this patch a standalone patch because it facilitates a subsequent fix to stable. Fixes: 1b771839de05 ("clk: qcom: gdsc: enable optional power domain support") Cc: stable@vger.kernel.org Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20250117-b4-linux-next-24-11-18-clock-multiple-power-domains-v10-1-13f2bb656dad@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gdsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index fa5fe4c2a2ee..bc1b1e37bf42 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -571,7 +571,7 @@ void gdsc_unregister(struct gdsc_desc *desc) size_t num = desc->num; /* Remove subdomains */ - for (i = 0; i < num; i++) { + for (i = num - 1; i >= 0; i--) { if (!scs[i]) continue; if (scs[i]->parent) From 65a733464553ea192797b889d1533a1a37216f32 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 17 Jan 2025 13:54:08 +0000 Subject: [PATCH 04/63] clk: qcom: gdsc: Capture pm_genpd_add_subdomain result code Adding a new clause to this if/else I noticed the existing usage of pm_genpd_add_subdomain() wasn't capturing and returning the result code. pm_genpd_add_subdomain() returns an int and can fail. Capture that result code and throw it up the call stack if something goes wrong. Fixes: 1b771839de05 ("clk: qcom: gdsc: enable optional power domain support") Cc: stable@vger.kernel.org Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20250117-b4-linux-next-24-11-18-clock-multiple-power-domains-v10-2-13f2bb656dad@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gdsc.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index bc1b1e37bf42..fdedf6dfe7b9 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -506,6 +506,23 @@ err_disable_supply: return ret; } +static void gdsc_pm_subdomain_remove(struct gdsc_desc *desc, size_t num) +{ + struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; + int i; + + /* Remove subdomains */ + for (i = num - 1; i >= 0; i--) { + if (!scs[i]) + continue; + if (scs[i]->parent) + pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); + else if (!IS_ERR_OR_NULL(dev->pm_domain)) + pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); + } +} + int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev, struct regmap *regmap) { @@ -555,30 +572,27 @@ int gdsc_register(struct gdsc_desc *desc, if (!scs[i]) continue; if (scs[i]->parent) - pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); + ret = pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); else if (!IS_ERR_OR_NULL(dev->pm_domain)) - pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); + ret = pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); + if (ret) + goto err_pm_subdomain_remove; } return of_genpd_add_provider_onecell(dev->of_node, data); + +err_pm_subdomain_remove: + gdsc_pm_subdomain_remove(desc, i); + + return ret; } void gdsc_unregister(struct gdsc_desc *desc) { - int i; struct device *dev = desc->dev; - struct gdsc **scs = desc->scs; size_t num = desc->num; - /* Remove subdomains */ - for (i = num - 1; i >= 0; i--) { - if (!scs[i]) - continue; - if (scs[i]->parent) - pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); - else if (!IS_ERR_OR_NULL(dev->pm_domain)) - pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); - } + gdsc_pm_subdomain_remove(desc, num); of_genpd_del_provider(dev->of_node); } From ed5a0d065fe87d7f64e2aa67191bc73299b830bd Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 17 Jan 2025 13:54:09 +0000 Subject: [PATCH 05/63] clk: qcom: common: Add support for power-domain attachment Right now we support one power-domain per clock controller. These single power-domains are switched on by the driver platform logic. However when we have multiple power-domains attached to a clock-controller that list of power-domains must be handled outside of driver platform logic. Use devm_pm_domain_attach_list() to automatically hook the list of given power-domains in the dtsi for the clock-controller driver. Signed-off-by: Bryan O'Donoghue Reviewed-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20250117-b4-linux-next-24-11-18-clock-multiple-power-domains-v10-3-13f2bb656dad@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 33cc1f73c69d..b79e6a73b53a 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -22,6 +22,7 @@ struct qcom_cc { struct qcom_reset_controller reset; struct clk_regmap **rclks; size_t num_rclks; + struct dev_pm_domain_list *pd_list; }; const @@ -299,6 +300,10 @@ int qcom_cc_really_probe(struct device *dev, if (!cc) return -ENOMEM; + ret = devm_pm_domain_attach_list(dev, NULL, &cc->pd_list); + if (ret < 0 && ret != -EEXIST) + return ret; + reset = &cc->reset; reset->rcdev.of_node = dev->of_node; reset->rcdev.ops = &qcom_reset_ops; From b489235b4dc01ff2b53995c03f30726fb1ea8005 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 17 Jan 2025 13:54:10 +0000 Subject: [PATCH 06/63] clk: qcom: Support attaching GDSCs to multiple parents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a clock-controller lists multiple power-domains we need make each GDSC a subdomain of each of the clock-controller's listed power-domains. GDSCs without an explicitly defined parent should be a subdomain of each of the clock-controller's listed power-domains. GDSCs with an explicitly defined parent should attach only to the parent GDSC and not the listed power-domains. Any votes will trickle through the hierarchy up to the external power-domains. ======================================== :: arch/arm64/boot/dts/example.dtsi :: ======================================== clockcc: clock-controller@0 { compat ="qcom,example-clockcc"; power-domains = <&pd_a, &pd_b>; } ======================================== :: drivers/clk/qcom/example-clockcc.c :: ======================================== static struct gdsc parent_gdsc = { .pd = { .name = "parent_gdsc", }, }; static struct gdsc child0_gdsc = { .pd = { .name = "child0_gdsc", }, .parent = &parent_gdsc.pd, }; static struct gdsc child1_gdsc = { .pd = { .name = "child1_gdsc", }, .parent = &parent_gdsc.pd, }; ======================================== :: power-subdomains :: ======================================== pm-domain::pd_a └── pm-subdomain::clockcc::parent_gdsc ├── pm-subdomain::clockcc::child0_gdsc └── pm-subdomain::clockcc::child1_gdsc pm-domain::pd_b └── pm-subdomain::clockcc::parent_gdsc ├── pm-subdomain::clockcc::child1_gdsc └── pm-subdomain::clockcc::child2_gdsc The performance states will percolate through the pm-domain hierarchy to the domains that handle the relevant states. Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20250117-b4-linux-next-24-11-18-clock-multiple-power-domains-v10-4-13f2bb656dad@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/common.c | 1 + drivers/clk/qcom/gdsc.c | 35 +++++++++++++++++++++++++++++++++++ drivers/clk/qcom/gdsc.h | 1 + 3 files changed, 37 insertions(+) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index b79e6a73b53a..9e3380fd7181 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -323,6 +323,7 @@ int qcom_cc_really_probe(struct device *dev, scd->dev = dev; scd->scs = desc->gdscs; scd->num = desc->num_gdscs; + scd->pd_list = cc->pd_list; ret = gdsc_register(scd, &reset->rcdev, regmap); if (ret) return ret; diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index fdedf6dfe7b9..7687661491f1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -506,6 +506,36 @@ err_disable_supply: return ret; } +static int gdsc_add_subdomain_list(struct dev_pm_domain_list *pd_list, + struct generic_pm_domain *subdomain) +{ + int i, ret; + + for (i = 0; i < pd_list->num_pds; i++) { + struct device *dev = pd_list->pd_devs[i]; + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); + + ret = pm_genpd_add_subdomain(genpd, subdomain); + if (ret) + return ret; + } + + return 0; +} + +static void gdsc_remove_subdomain_list(struct dev_pm_domain_list *pd_list, + struct generic_pm_domain *subdomain) +{ + int i; + + for (i = 0; i < pd_list->num_pds; i++) { + struct device *dev = pd_list->pd_devs[i]; + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); + + pm_genpd_remove_subdomain(genpd, subdomain); + } +} + static void gdsc_pm_subdomain_remove(struct gdsc_desc *desc, size_t num) { struct device *dev = desc->dev; @@ -520,6 +550,8 @@ static void gdsc_pm_subdomain_remove(struct gdsc_desc *desc, size_t num) pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); else if (!IS_ERR_OR_NULL(dev->pm_domain)) pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); + else if (desc->pd_list) + gdsc_remove_subdomain_list(desc->pd_list, &scs[i]->pd); } } @@ -575,6 +607,9 @@ int gdsc_register(struct gdsc_desc *desc, ret = pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); else if (!IS_ERR_OR_NULL(dev->pm_domain)) ret = pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); + else if (desc->pd_list) + ret = gdsc_add_subdomain_list(desc->pd_list, &scs[i]->pd); + if (ret) goto err_pm_subdomain_remove; } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 1e2779b823d1..dd843e86c05b 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -80,6 +80,7 @@ struct gdsc_desc { struct device *dev; struct gdsc **scs; size_t num; + struct dev_pm_domain_list *pd_list; }; #ifdef CONFIG_QCOM_GDSC From 7a243e1b814a02ab40793026ef64223155d86395 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 12 Feb 2025 21:01:35 +0100 Subject: [PATCH 07/63] clk: qcom: clk-alpha-pll: Do not use random stack value for recalc rate If regmap_read() fails, random stack value was used in calculating new frequency in recalc_rate() callbacks. Such failure is really not expected as these are all MMIO reads, however code should be here correct and bail out. This also avoids possible warning on uninitialized value. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250212-b4-clk-qcom-clean-v3-1-499f37444f5d@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-alpha-pll.c | 52 ++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 9a65d14acf71..cec0afea8e44 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -709,14 +709,19 @@ clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 alpha_width = pll_alpha_width(pll); - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) + return 0; + + if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) + return 0; - regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); if (ctl & PLL_ALPHA_EN) { - regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low); + if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low)) + return 0; if (alpha_width > 32) { - regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), - &high); + if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), + &high)) + return 0; a = (u64)high << 32 | low; } else { a = low & GENMASK(alpha_width - 1, 0); @@ -942,8 +947,11 @@ alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 l, alpha = 0, ctl, alpha_m, alpha_n; - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); - regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) + return 0; + + if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) + return 0; if (ctl & PLL_ALPHA_EN) { regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &alpha); @@ -1137,8 +1145,11 @@ clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 l, frac, alpha_width = pll_alpha_width(pll); - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); - regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac); + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) + return 0; + + if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac)) + return 0; return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); } @@ -1196,7 +1207,8 @@ clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); u32 ctl; - regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); + if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) + return 0; ctl >>= PLL_POST_DIV_SHIFT; ctl &= PLL_POST_DIV_MASK(pll); @@ -1412,8 +1424,11 @@ static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw, struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 l, frac, alpha_width = pll_alpha_width(pll); - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); - regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac); + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) + return 0; + + if (regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac)) + return 0; return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); } @@ -1563,7 +1578,8 @@ clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) struct regmap *regmap = pll->clkr.regmap; u32 i, div = 1, val; - regmap_read(regmap, PLL_USER_CTL(pll), &val); + if (regmap_read(regmap, PLL_USER_CTL(pll), &val)) + return 0; val >>= pll->post_div_shift; val &= PLL_POST_DIV_MASK(pll); @@ -2484,9 +2500,12 @@ static unsigned long alpha_pll_lucid_evo_recalc_rate(struct clk_hw *hw, struct regmap *regmap = pll->clkr.regmap; u32 l, frac; - regmap_read(regmap, PLL_L_VAL(pll), &l); + if (regmap_read(regmap, PLL_L_VAL(pll), &l)) + return 0; l &= LUCID_EVO_PLL_L_VAL_MASK; - regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac); + + if (regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac)) + return 0; return alpha_pll_calc_rate(parent_rate, l, frac, pll_alpha_width(pll)); } @@ -2699,7 +2718,8 @@ static unsigned long clk_rivian_evo_pll_recalc_rate(struct clk_hw *hw, struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); u32 l; - regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); + if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) + return 0; return parent_rate * l; } From 691621dfadbf0f2afa34dbfe24b54c1fa5c33473 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 12 Feb 2025 21:01:36 +0100 Subject: [PATCH 08/63] clk: qcom: Drop unused header includes Drivers should include only headers they use so drop: 1. of.h and of_address.h: When no OF call is used (of_device_id is coming from mod_devicetable.h). 2. clk.h, property.h and reset-controller.h: No calls to clock consumer or reset framework, no fwnode/property calls. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250212-b4-clk-qcom-clean-v3-2-499f37444f5d@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sa8775p.c | 1 - drivers/clk/qcom/camcc-sc7180.c | 1 - drivers/clk/qcom/camcc-sc7280.c | 1 - drivers/clk/qcom/camcc-sm4450.c | 1 - drivers/clk/qcom/camcc-sm7150.c | 1 - drivers/clk/qcom/camcc-sm8150.c | 1 - drivers/clk/qcom/camcc-sm8250.c | 1 - drivers/clk/qcom/dispcc-qcm2290.c | 1 - drivers/clk/qcom/dispcc-sc8280xp.c | 2 -- drivers/clk/qcom/dispcc-sdm845.c | 1 - drivers/clk/qcom/dispcc-sm4450.c | 1 - drivers/clk/qcom/dispcc-sm6115.c | 1 - drivers/clk/qcom/dispcc-sm7150.c | 1 - drivers/clk/qcom/dispcc-sm8250.c | 1 - drivers/clk/qcom/dispcc-sm8450.c | 2 -- drivers/clk/qcom/dispcc-sm8550.c | 2 -- drivers/clk/qcom/dispcc0-sa8775p.c | 1 - drivers/clk/qcom/dispcc1-sa8775p.c | 1 - drivers/clk/qcom/gcc-msm8960.c | 1 - drivers/clk/qcom/gcc-msm8974.c | 1 - drivers/clk/qcom/gpucc-msm8998.c | 2 -- drivers/clk/qcom/gpucc-sdm660.c | 4 +--- drivers/clk/qcom/gpucc-sm4450.c | 1 - drivers/clk/qcom/gpucc-sm8350.c | 1 - drivers/clk/qcom/kpss-xcc.c | 1 - drivers/clk/qcom/krait-cc.c | 1 - drivers/clk/qcom/lpasscc-sdm845.c | 1 - drivers/clk/qcom/lpasscorecc-sc7180.c | 1 - drivers/clk/qcom/lpasscorecc-sc7280.c | 1 - drivers/clk/qcom/mmcc-apq8084.c | 1 - drivers/clk/qcom/mmcc-msm8960.c | 3 --- drivers/clk/qcom/mmcc-msm8974.c | 1 - drivers/clk/qcom/mmcc-msm8994.c | 2 -- drivers/clk/qcom/mmcc-msm8996.c | 3 --- drivers/clk/qcom/mmcc-msm8998.c | 2 -- drivers/clk/qcom/mmcc-sdm660.c | 5 ----- 36 files changed, 1 insertion(+), 52 deletions(-) diff --git a/drivers/clk/qcom/camcc-sa8775p.c b/drivers/clk/qcom/camcc-sa8775p.c index c04801a5af35..1df86da41940 100644 --- a/drivers/clk/qcom/camcc-sa8775p.c +++ b/drivers/clk/qcom/camcc-sa8775p.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c index 10e924cd533d..a69b70ab1a70 100644 --- a/drivers/clk/qcom/camcc-sc7180.c +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/camcc-sc7280.c b/drivers/clk/qcom/camcc-sc7280.c index accd257632df..5a9992a5b5ba 100644 --- a/drivers/clk/qcom/camcc-sc7280.c +++ b/drivers/clk/qcom/camcc-sc7280.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/camcc-sm4450.c b/drivers/clk/qcom/camcc-sm4450.c index f8503ced3d05..e51590d89a3c 100644 --- a/drivers/clk/qcom/camcc-sm4450.c +++ b/drivers/clk/qcom/camcc-sm4450.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c index 39033a6bb616..4a3baf5d8e85 100644 --- a/drivers/clk/qcom/camcc-sm7150.c +++ b/drivers/clk/qcom/camcc-sm7150.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/camcc-sm8150.c b/drivers/clk/qcom/camcc-sm8150.c index bb3009818ad7..ed96dcb885b3 100644 --- a/drivers/clk/qcom/camcc-sm8150.c +++ b/drivers/clk/qcom/camcc-sm8150.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index 450ddbebd35f..4e20530d2ddf 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -7,7 +7,6 @@ #include #include #include -#include #include diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c index d7bb1399e102..f72e9585b4fb 100644 --- a/drivers/clk/qcom/dispcc-qcm2290.c +++ b/drivers/clk/qcom/dispcc-qcm2290.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/dispcc-sc8280xp.c b/drivers/clk/qcom/dispcc-sc8280xp.c index f1ca9ae0b33f..0a810fc847ce 100644 --- a/drivers/clk/qcom/dispcc-sc8280xp.c +++ b/drivers/clk/qcom/dispcc-sc8280xp.c @@ -7,11 +7,9 @@ #include #include #include -#include #include #include #include -#include #include diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c index e6139e8f74dc..94079c54333f 100644 --- a/drivers/clk/qcom/dispcc-sdm845.c +++ b/drivers/clk/qcom/dispcc-sdm845.c @@ -7,7 +7,6 @@ #include #include #include -#include #include diff --git a/drivers/clk/qcom/dispcc-sm4450.c b/drivers/clk/qcom/dispcc-sm4450.c index 98ba016bc57f..465725f9bfeb 100644 --- a/drivers/clk/qcom/dispcc-sm4450.c +++ b/drivers/clk/qcom/dispcc-sm4450.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/dispcc-sm6115.c b/drivers/clk/qcom/dispcc-sm6115.c index 2b236d52b29f..89f14cfd9233 100644 --- a/drivers/clk/qcom/dispcc-sm6115.c +++ b/drivers/clk/qcom/dispcc-sm6115.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c index d32bd7df1433..bdfff246ed3f 100644 --- a/drivers/clk/qcom/dispcc-sm7150.c +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index 884bbd3fb305..1f48e79acfac 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -8,7 +8,6 @@ #include #include #include -#include #include diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c index a1f183e6c636..96987d8445cb 100644 --- a/drivers/clk/qcom/dispcc-sm8450.c +++ b/drivers/clk/qcom/dispcc-sm8450.c @@ -4,12 +4,10 @@ * Copyright (c) 2022, Linaro Ltd. */ -#include #include #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm8550.c b/drivers/clk/qcom/dispcc-sm8550.c index e41d4104d770..4c5feb96ae53 100644 --- a/drivers/clk/qcom/dispcc-sm8550.c +++ b/drivers/clk/qcom/dispcc-sm8550.c @@ -4,12 +4,10 @@ * Copyright (c) 2023, Linaro Ltd. */ -#include #include #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/dispcc0-sa8775p.c b/drivers/clk/qcom/dispcc0-sa8775p.c index 6e399b5f1383..bf9de92a5dd2 100644 --- a/drivers/clk/qcom/dispcc0-sa8775p.c +++ b/drivers/clk/qcom/dispcc0-sa8775p.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/dispcc1-sa8775p.c b/drivers/clk/qcom/dispcc1-sa8775p.c index 30ccea59415a..cd2f2eb7ffb4 100644 --- a/drivers/clk/qcom/dispcc1-sa8775p.c +++ b/drivers/clk/qcom/dispcc1-sa8775p.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index 9ddce11db6df..c2e4fa5d63ad 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index b32e66714951..92ad35cfb75e 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c index 9efeab2691ba..066793e47f79 100644 --- a/drivers/clk/qcom/gpucc-msm8998.c +++ b/drivers/clk/qcom/gpucc-msm8998.c @@ -8,10 +8,8 @@ #include #include #include -#include #include #include -#include #include diff --git a/drivers/clk/qcom/gpucc-sdm660.c b/drivers/clk/qcom/gpucc-sdm660.c index 3ae1b80e38d9..6d37b3d8d1a4 100644 --- a/drivers/clk/qcom/gpucc-sdm660.c +++ b/drivers/clk/qcom/gpucc-sdm660.c @@ -6,15 +6,13 @@ */ #include -#include #include #include #include #include #include -#include #include -#include + #include #include "clk-alpha-pll.h" diff --git a/drivers/clk/qcom/gpucc-sm4450.c b/drivers/clk/qcom/gpucc-sm4450.c index a14d0bb031ac..34c7ba0c7d55 100644 --- a/drivers/clk/qcom/gpucc-sm4450.c +++ b/drivers/clk/qcom/gpucc-sm4450.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/gpucc-sm8350.c b/drivers/clk/qcom/gpucc-sm8350.c index f3b6bdc24485..6d2660bdd825 100644 --- a/drivers/clk/qcom/gpucc-sm8350.c +++ b/drivers/clk/qcom/gpucc-sm8350.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c index e7cfa8d22044..97bfb21a5e5e 100644 --- a/drivers/clk/qcom/kpss-xcc.c +++ b/drivers/clk/qcom/kpss-xcc.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c index ae325f4e1047..f29d6dd1f3ac 100644 --- a/drivers/clk/qcom/krait-cc.c +++ b/drivers/clk/qcom/krait-cc.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/lpasscc-sdm845.c b/drivers/clk/qcom/lpasscc-sdm845.c index 7040da952728..5c1ea75f9ba8 100644 --- a/drivers/clk/qcom/lpasscc-sdm845.c +++ b/drivers/clk/qcom/lpasscc-sdm845.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 726c6378752f..605516d03993 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/lpasscorecc-sc7280.c b/drivers/clk/qcom/lpasscorecc-sc7280.c index b0888cd2460b..56882c202376 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7280.c +++ b/drivers/clk/qcom/lpasscorecc-sc7280.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index cc03722596a4..3affa525b875 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index 20d1c43f35d9..a23440e13b71 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -8,13 +8,10 @@ #include #include #include -#include #include -#include #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index 169e85f60550..f2e802cf6afc 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8994.c b/drivers/clk/qcom/mmcc-msm8994.c index f70d080bf51c..0a273630e852 100644 --- a/drivers/clk/qcom/mmcc-msm8994.c +++ b/drivers/clk/qcom/mmcc-msm8994.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index a742f848e4ee..3426e3dde924 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -8,11 +8,8 @@ #include #include #include -#include #include #include -#include -#include #include diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c index 5738445a8656..5c37be700fa7 100644 --- a/drivers/clk/qcom/mmcc-msm8998.c +++ b/drivers/clk/qcom/mmcc-msm8998.c @@ -8,10 +8,8 @@ #include #include #include -#include #include #include -#include #include diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index 98ba5b4518fb..b3beeabe39ed 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -9,14 +9,9 @@ #include #include #include -#include #include -#include #include #include -#include -#include - #include From 1e9f7d9169c55c06e84cdd33bc1107e873910d94 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 12 Feb 2025 21:01:37 +0100 Subject: [PATCH 09/63] clk: qcom: Add missing header includes Include mod_devicetable.h for the 'struct of_device_id' and clk-provider.h for the 'struct clk_hw'. Reviewed-by: Taniya Das Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250212-b4-clk-qcom-clean-v3-3-499f37444f5d@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sc7180.c | 1 + drivers/clk/qcom/camcc-sc7280.c | 1 + drivers/clk/qcom/camcc-sdm845.c | 1 + drivers/clk/qcom/camcc-sm6350.c | 1 + drivers/clk/qcom/camcc-sm8150.c | 1 + drivers/clk/qcom/camcc-sm8250.c | 1 + drivers/clk/qcom/dispcc-qcm2290.c | 2 ++ drivers/clk/qcom/dispcc-sc7180.c | 1 + drivers/clk/qcom/dispcc-sc7280.c | 1 + drivers/clk/qcom/dispcc-sc8280xp.c | 1 + drivers/clk/qcom/dispcc-sdm845.c | 1 + drivers/clk/qcom/dispcc-sm6115.c | 2 ++ drivers/clk/qcom/dispcc-sm6125.c | 1 + drivers/clk/qcom/dispcc-sm6350.c | 1 + drivers/clk/qcom/dispcc-sm6375.c | 1 + drivers/clk/qcom/dispcc-sm8250.c | 1 + drivers/clk/qcom/dispcc-sm8450.c | 1 + drivers/clk/qcom/dispcc-sm8550.c | 1 + drivers/clk/qcom/gpucc-msm8998.c | 1 + drivers/clk/qcom/gpucc-sar2130p.c | 1 + drivers/clk/qcom/gpucc-sc7180.c | 1 + drivers/clk/qcom/gpucc-sc7280.c | 1 + drivers/clk/qcom/gpucc-sc8280xp.c | 1 + drivers/clk/qcom/gpucc-sdm660.c | 1 + drivers/clk/qcom/gpucc-sdm845.c | 1 + drivers/clk/qcom/gpucc-sm6350.c | 1 + drivers/clk/qcom/gpucc-sm8150.c | 1 + drivers/clk/qcom/gpucc-sm8250.c | 1 + drivers/clk/qcom/gpucc-sm8350.c | 1 + drivers/clk/qcom/mmcc-apq8084.c | 1 + drivers/clk/qcom/mmcc-msm8960.c | 1 + drivers/clk/qcom/mmcc-msm8974.c | 1 + drivers/clk/qcom/mmcc-msm8994.c | 1 + drivers/clk/qcom/mmcc-msm8996.c | 1 + drivers/clk/qcom/mmcc-msm8998.c | 1 + drivers/clk/qcom/mmcc-sdm660.c | 1 + 36 files changed, 38 insertions(+) diff --git a/drivers/clk/qcom/camcc-sc7180.c b/drivers/clk/qcom/camcc-sc7180.c index a69b70ab1a70..5031df813b4a 100644 --- a/drivers/clk/qcom/camcc-sc7180.c +++ b/drivers/clk/qcom/camcc-sc7180.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/camcc-sc7280.c b/drivers/clk/qcom/camcc-sc7280.c index 5a9992a5b5ba..55545f5fdb98 100644 --- a/drivers/clk/qcom/camcc-sc7280.c +++ b/drivers/clk/qcom/camcc-sc7280.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c index 40022a10f8c0..cf60e8dd292a 100644 --- a/drivers/clk/qcom/camcc-sdm845.c +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c index f6634cc8663e..1871970fb046 100644 --- a/drivers/clk/qcom/camcc-sm6350.c +++ b/drivers/clk/qcom/camcc-sm6350.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/camcc-sm8150.c b/drivers/clk/qcom/camcc-sm8150.c index ed96dcb885b3..f105534cb318 100644 --- a/drivers/clk/qcom/camcc-sm8150.c +++ b/drivers/clk/qcom/camcc-sm8150.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c index 4e20530d2ddf..6da89c49ba3d 100644 --- a/drivers/clk/qcom/camcc-sm8250.c +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-qcm2290.c b/drivers/clk/qcom/dispcc-qcm2290.c index f72e9585b4fb..6d88d067337f 100644 --- a/drivers/clk/qcom/dispcc-qcm2290.c +++ b/drivers/clk/qcom/dispcc-qcm2290.c @@ -4,8 +4,10 @@ * Copyright (c) 2021, Linaro Ltd. */ +#include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sc7180.c b/drivers/clk/qcom/dispcc-sc7180.c index 4710247be530..ab1a8d419863 100644 --- a/drivers/clk/qcom/dispcc-sc7180.c +++ b/drivers/clk/qcom/dispcc-sc7180.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c index db0745954894..8bdf57734a3d 100644 --- a/drivers/clk/qcom/dispcc-sc7280.c +++ b/drivers/clk/qcom/dispcc-sc7280.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sc8280xp.c b/drivers/clk/qcom/dispcc-sc8280xp.c index 0a810fc847ce..34fae823423a 100644 --- a/drivers/clk/qcom/dispcc-sc8280xp.c +++ b/drivers/clk/qcom/dispcc-sc8280xp.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c index 94079c54333f..2f9e9665d7e9 100644 --- a/drivers/clk/qcom/dispcc-sdm845.c +++ b/drivers/clk/qcom/dispcc-sdm845.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm6115.c b/drivers/clk/qcom/dispcc-sm6115.c index 89f14cfd9233..8ae25d51db94 100644 --- a/drivers/clk/qcom/dispcc-sm6115.c +++ b/drivers/clk/qcom/dispcc-sm6115.c @@ -5,8 +5,10 @@ * Copyright (c) 2021, Linaro Ltd. */ +#include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm6125.c b/drivers/clk/qcom/dispcc-sm6125.c index 51c7492816fb..851d38a487d3 100644 --- a/drivers/clk/qcom/dispcc-sm6125.c +++ b/drivers/clk/qcom/dispcc-sm6125.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c index 2bc6b5f99f57..e703ecf00e44 100644 --- a/drivers/clk/qcom/dispcc-sm6350.c +++ b/drivers/clk/qcom/dispcc-sm6350.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm6375.c b/drivers/clk/qcom/dispcc-sm6375.c index 167dd369a794..ec9dbb1f4a7c 100644 --- a/drivers/clk/qcom/dispcc-sm6375.c +++ b/drivers/clk/qcom/dispcc-sm6375.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index 1f48e79acfac..8f433e1e7028 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c index 96987d8445cb..0b76cddbeb94 100644 --- a/drivers/clk/qcom/dispcc-sm8450.c +++ b/drivers/clk/qcom/dispcc-sm8450.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/dispcc-sm8550.c b/drivers/clk/qcom/dispcc-sm8550.c index 4c5feb96ae53..a373c92a10aa 100644 --- a/drivers/clk/qcom/dispcc-sm8550.c +++ b/drivers/clk/qcom/dispcc-sm8550.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c index 066793e47f79..7fce70503141 100644 --- a/drivers/clk/qcom/gpucc-msm8998.c +++ b/drivers/clk/qcom/gpucc-msm8998.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sar2130p.c b/drivers/clk/qcom/gpucc-sar2130p.c index dd72b2a48c42..c2903179ac85 100644 --- a/drivers/clk/qcom/gpucc-sar2130p.c +++ b/drivers/clk/qcom/gpucc-sar2130p.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c index 08f3983d016f..a7bf44544b95 100644 --- a/drivers/clk/qcom/gpucc-sc7180.c +++ b/drivers/clk/qcom/gpucc-sc7180.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c index bd699a624517..f81289fa719d 100644 --- a/drivers/clk/qcom/gpucc-sc7280.c +++ b/drivers/clk/qcom/gpucc-sc7280.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sc8280xp.c b/drivers/clk/qcom/gpucc-sc8280xp.c index c96be61e3f47..913e17f10196 100644 --- a/drivers/clk/qcom/gpucc-sc8280xp.c +++ b/drivers/clk/qcom/gpucc-sc8280xp.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sdm660.c b/drivers/clk/qcom/gpucc-sdm660.c index 6d37b3d8d1a4..28db307b6717 100644 --- a/drivers/clk/qcom/gpucc-sdm660.c +++ b/drivers/clk/qcom/gpucc-sdm660.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c index ef26690cf504..0d63b110a1fb 100644 --- a/drivers/clk/qcom/gpucc-sdm845.c +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sm6350.c b/drivers/clk/qcom/gpucc-sm6350.c index 1e12ad8948db..35ed0500bc59 100644 --- a/drivers/clk/qcom/gpucc-sm6350.c +++ b/drivers/clk/qcom/gpucc-sm6350.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c index d711464a71b6..7ce91208c0bc 100644 --- a/drivers/clk/qcom/gpucc-sm8150.c +++ b/drivers/clk/qcom/gpucc-sm8150.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sm8250.c b/drivers/clk/qcom/gpucc-sm8250.c index 113b486a6d2f..ca0a1681d352 100644 --- a/drivers/clk/qcom/gpucc-sm8250.c +++ b/drivers/clk/qcom/gpucc-sm8250.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/qcom/gpucc-sm8350.c b/drivers/clk/qcom/gpucc-sm8350.c index 6d2660bdd825..4025dab0a1ca 100644 --- a/drivers/clk/qcom/gpucc-sm8350.c +++ b/drivers/clk/qcom/gpucc-sm8350.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index 3affa525b875..2d334977d783 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index a23440e13b71..cd3c9f8455e5 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index f2e802cf6afc..12bbc49c87af 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8994.c b/drivers/clk/qcom/mmcc-msm8994.c index 0a273630e852..7c0b959a4aa2 100644 --- a/drivers/clk/qcom/mmcc-msm8994.c +++ b/drivers/clk/qcom/mmcc-msm8994.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index 3426e3dde924..7d67c6f73fe1 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c index 5c37be700fa7..e2f198213b21 100644 --- a/drivers/clk/qcom/mmcc-msm8998.c +++ b/drivers/clk/qcom/mmcc-msm8998.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index b3beeabe39ed..e5bdcc75a36e 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include From d81901a5406eaf65a097b80ab48edc398de598a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 12 Feb 2025 17:32:43 +0100 Subject: [PATCH 10/63] clk: qcom: dispcc-sm8750: Allow dumping regmap Reading few registers at the end of the block (e.g. 0x10000, 0x10004) results in synchronous external abort, so limit the regmap to the last readable register which allows dumping the regs for debugging. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250212163243.237658-1-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sm8750.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/dispcc-sm8750.c b/drivers/clk/qcom/dispcc-sm8750.c index 0358dff91da5..a532d9ad9dd3 100644 --- a/drivers/clk/qcom/dispcc-sm8750.c +++ b/drivers/clk/qcom/dispcc-sm8750.c @@ -1883,7 +1883,7 @@ static const struct regmap_config disp_cc_sm8750_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x11014, + .max_register = 0xf004, /* 0x10000, 0x10004 and maybe others are for TZ */ .fast_io = true, }; From ee9fdb415639032d1bb1b59b83f210958e29764f Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Wed, 12 Feb 2025 18:04:09 +0100 Subject: [PATCH 11/63] dt-bindings: clock: qcom,rpmcc: Add SDM429 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the qcom,rpmcc-sdm429 compatible and add BB_CLK3 clock definition. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250212-sdm429-rpm-v1-1-0a24ac19a478@mainlining.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml | 2 ++ include/dt-bindings/clock/qcom,rpmcc.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml index be3835e2e043..90cd3feab5fa 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml @@ -44,6 +44,7 @@ properties: - qcom,rpmcc-msm8998 - qcom,rpmcc-qcm2290 - qcom,rpmcc-qcs404 + - qcom,rpmcc-sdm429 - qcom,rpmcc-sdm660 - qcom,rpmcc-sm6115 - qcom,rpmcc-sm6125 @@ -123,6 +124,7 @@ allOf: - qcom,rpmcc-msm8998 - qcom,rpmcc-qcm2290 - qcom,rpmcc-qcs404 + - qcom,rpmcc-sdm429 - qcom,rpmcc-sdm660 - qcom,rpmcc-sm6115 - qcom,rpmcc-sm6125 diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h index 46309c9953b2..1477a75e7f6d 100644 --- a/include/dt-bindings/clock/qcom,rpmcc.h +++ b/include/dt-bindings/clock/qcom,rpmcc.h @@ -170,5 +170,9 @@ #define RPM_SMD_BIMC_FREQ_LOG 124 #define RPM_SMD_LN_BB_CLK_PIN 125 #define RPM_SMD_LN_BB_A_CLK_PIN 126 +#define RPM_SMD_BB_CLK3 127 +#define RPM_SMD_BB_CLK3_A 128 +#define RPM_SMD_BB_CLK3_PIN 129 +#define RPM_SMD_BB_CLK3_A_PIN 130 #endif From fd77406f30d06d1d5243e6f56e9ada27a057f00c Mon Sep 17 00:00:00 2001 From: Daniil Titov Date: Wed, 12 Feb 2025 18:04:10 +0100 Subject: [PATCH 12/63] clk: qcom: smd-rpm: Add clocks for SDM429 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SDM429 has mostly the same rpm clocks as MSM8953, but lacks RF_CLK3 and IPA_CLK and additionally has the BB_CLK3. Signed-off-by: Daniil Titov Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20250212-sdm429-rpm-v1-2-0a24ac19a478@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-smd-rpm.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 29ef08a9d50b..3fbaa646286f 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -486,6 +486,7 @@ DEFINE_CLK_SMD_RPM(qup, QCOM_SMD_RPM_QUP_CLK, 0); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(bb_clk1, 1, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(bb_clk2, 2, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(bb_clk3, 3, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(ln_bb_clk1, 1, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(ln_bb_clk2, 2, 19200000); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(ln_bb_clk3, 3, 19200000); @@ -1046,6 +1047,36 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = { .num_icc_clks = ARRAY_SIZE(msm8998_icc_clks), }; +static struct clk_smd_rpm *sdm429_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, + [RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &clk_smd_rpm_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &clk_smd_rpm_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &clk_smd_rpm_bb_clk2_a, + [RPM_SMD_BB_CLK3] = &clk_smd_rpm_bb_clk3, + [RPM_SMD_BB_CLK3_A] = &clk_smd_rpm_bb_clk3_a, + [RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a, + [RPM_SMD_DIV_CLK2] = &clk_smd_rpm_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &clk_smd_rpm_div_clk2_a, + [RPM_SMD_BB_CLK1_PIN] = &clk_smd_rpm_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &clk_smd_rpm_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &clk_smd_rpm_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &clk_smd_rpm_bb_clk2_a_pin, + [RPM_SMD_BB_CLK3_PIN] = &clk_smd_rpm_bb_clk3_pin, + [RPM_SMD_BB_CLK3_A_PIN] = &clk_smd_rpm_bb_clk3_a_pin, +}; + +static const struct rpm_smd_clk_desc rpm_clk_sdm429 = { + .clks = sdm429_clks, + .num_clks = ARRAY_SIZE(sdm429_clks), + .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, + .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), +}; + static struct clk_smd_rpm *sdm660_clks[] = { [RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a, @@ -1276,6 +1307,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 }, { .compatible = "qcom,rpmcc-qcm2290", .data = &rpm_clk_qcm2290 }, { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, + { .compatible = "qcom,rpmcc-sdm429", .data = &rpm_clk_sdm429 }, { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 }, { .compatible = "qcom,rpmcc-sm6115", .data = &rpm_clk_sm6115 }, { .compatible = "qcom,rpmcc-sm6125", .data = &rpm_clk_sm6125 }, From 1ae674f0871722215a684b4c8e1e20a7912ec7e4 Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Mon, 3 Feb 2025 09:34:24 +0300 Subject: [PATCH 13/63] dt-bindings: clock: gcc-sdm660: Add missing SDCC resets Add resets for eMMC/SD card blocks that were missed during initial driver submission. Signed-off-by: Alexey Minnekhanov Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250203063427.358327-2-alexeymin@postmarketos.org Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,gcc-sdm660.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/qcom,gcc-sdm660.h b/include/dt-bindings/clock/qcom,gcc-sdm660.h index df8a6f3d367e..74c22f67da21 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm660.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm660.h @@ -153,5 +153,7 @@ #define GCC_USB_30_BCR 7 #define GCC_USB_PHY_CFG_AHB2PHY_BCR 8 #define GCC_MSS_RESTART 9 +#define GCC_SDCC1_BCR 10 +#define GCC_SDCC2_BCR 11 #endif From f95c37c339ab3917485fd7333be8de07331ff573 Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Mon, 3 Feb 2025 09:34:24 +0300 Subject: [PATCH 14/63] dt-bindings: clock: gcc-sdm660: Add missing SDCC resets Add resets for eMMC/SD card blocks that were missed during initial driver submission. Signed-off-by: Alexey Minnekhanov Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250203063427.358327-2-alexeymin@postmarketos.org Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,gcc-sdm660.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dt-bindings/clock/qcom,gcc-sdm660.h b/include/dt-bindings/clock/qcom,gcc-sdm660.h index df8a6f3d367e..74c22f67da21 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm660.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm660.h @@ -153,5 +153,7 @@ #define GCC_USB_30_BCR 7 #define GCC_USB_PHY_CFG_AHB2PHY_BCR 8 #define GCC_MSS_RESTART 9 +#define GCC_SDCC1_BCR 10 +#define GCC_SDCC2_BCR 11 #endif From 497457f61fd6d375c7615926956793286f631f7f Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Mon, 3 Feb 2025 09:34:25 +0300 Subject: [PATCH 15/63] clk: qcom: gcc-sdm660: Add missing SDCC block resets This will allow linux to properly reset eMMC/SD blocks. Signed-off-by: Alexey Minnekhanov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250203063427.358327-3-alexeymin@postmarketos.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sdm660.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index df79298a1a25..01a76f1b5b4c 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -2420,6 +2420,8 @@ static struct gdsc *gcc_sdm660_gdscs[] = { static const struct qcom_reset_map gcc_sdm660_resets[] = { [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC1_BCR] = { 0x16000 }, [GCC_UFS_BCR] = { 0x75000 }, [GCC_USB3_DP_PHY_BCR] = { 0x50028 }, [GCC_USB3_PHY_BCR] = { 0x50020 }, From 5eac348182d2b5ed1066459abedb7bc6b5466f81 Mon Sep 17 00:00:00 2001 From: Ajit Pandey Date: Tue, 28 Jan 2025 17:08:35 +0530 Subject: [PATCH 16/63] clk: qcom: clk-branch: Fix invert halt status bit check for votable clocks BRANCH_HALT_ENABLE and BRANCH_HALT_ENABLE_VOTED flags are used to check halt status of branch clocks, which have an inverted logic for the halt bit in CBCR register. However, the current logic in the _check_halt() method only compares the BRANCH_HALT_ENABLE flags, ignoring the votable branch clocks. Update the logic to correctly handle the invert logic for votable clocks using the BRANCH_HALT_ENABLE_VOTED flags. Fixes: 9092d1083a62 ("clk: qcom: branch: Extend the invert logic for branch2 clocks") Cc: stable@vger.kernel.org Signed-off-by: Ajit Pandey Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250128-push_fix-v1-1-fafec6747881@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/clk-branch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index 229480c5b075..0f10090d4ae6 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -28,7 +28,7 @@ static bool clk_branch_in_hwcg_mode(const struct clk_branch *br) static bool clk_branch_check_halt(const struct clk_branch *br, bool enabling) { - bool invert = (br->halt_check == BRANCH_HALT_ENABLE); + bool invert = (br->halt_check & BRANCH_HALT_ENABLE); u32 val; regmap_read(br->clkr.regmap, br->halt_reg, &val); @@ -44,7 +44,7 @@ static bool clk_branch2_check_halt(const struct clk_branch *br, bool enabling) { u32 val; u32 mask; - bool invert = (br->halt_check == BRANCH_HALT_ENABLE); + bool invert = (br->halt_check & BRANCH_HALT_ENABLE); mask = CBCR_NOC_FSM_STATUS; mask |= CBCR_CLK_OFF; From 4b28beb882a0a1af0ce47a8a87e7877a3ae6ad36 Mon Sep 17 00:00:00 2001 From: Manikanta Mylavarapu Date: Fri, 24 Jan 2025 11:39:14 +0530 Subject: [PATCH 17/63] clk: qcom: ipq5424: fix software and hardware flow control error of UART MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The UART’s software and hardware flow control are currently not functioning correctly. For software flow control, the following error is encountered: qcom_geni_serial 1a80000.serial: Couldn't find suitable clock rate for 56000000, 3500000, 2500000, 1152000, 921600, 19200 During hardware flow control testing, a “Retry 0: Got ZCAN error” is observed. To address these issues, update the UART frequency table to include all supported frequencies according to the frequency plan. Fixes: 21b5d5a4a311 ("clk: qcom: add Global Clock controller (GCC) driver for IPQ5424 SoC") Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20250124060914.1564681-1-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index d5b218b76e29..37b1a3ff8f4e 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -592,13 +592,19 @@ static struct clk_rcg2 gcc_qupv3_spi1_clk_src = { }; static const struct freq_tbl ftbl_gcc_qupv3_uart0_clk_src[] = { - F(960000, P_XO, 10, 2, 5), - F(4800000, P_XO, 5, 0, 0), - F(9600000, P_XO, 2, 4, 5), - F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5), + F(3686400, P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 144, 15625), + F(7372800, P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 288, 15625), + F(14745600, P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 576, 15625), F(24000000, P_XO, 1, 0, 0), F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2), - F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0), + F(32000000, P_GPLL0_OUT_MAIN, 1, 1, 25), + F(40000000, P_GPLL0_OUT_MAIN, 1, 1, 20), + F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 500), + F(48000000, P_GPLL0_OUT_MAIN, 1, 3, 50), + F(51200000, P_GPLL0_OUT_MAIN, 1, 8, 125), + F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 100), + F(58982400, P_GPLL0_OUT_MAIN, 1, 1152, 15625), + F(60000000, P_GPLL0_OUT_MAIN, 1, 3, 40), F(64000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0), { } }; From 5d02941c83997b58e8fc15390290c7c6975acaff Mon Sep 17 00:00:00 2001 From: Karl Chan Date: Tue, 8 Oct 2024 00:34:12 +0800 Subject: [PATCH 18/63] clk: qcom: ipq5018: allow it to be bulid on arm32 There are some ipq5018 based device's firmware only can able to boot arm32 but the clock driver dont allow it to be compiled on arm32. Therefore allow GCC for IPQ5018 to be selected when building ARM32 kernel Signed-off-by: Karl Chan Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20241007163414.32458-4-exxxxkc@getgoogleoff.me [bjorn: Updated commit message, per Dmitry's suggestion] Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 69bbf62ba3cd..d470ed007854 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -217,7 +217,7 @@ config IPQ_GCC_4019 config IPQ_GCC_5018 tristate "IPQ5018 Global Clock Controller" - depends on ARM64 || COMPILE_TEST + depends on ARM || ARM64 || COMPILE_TEST help Support for global clock controller on ipq5018 devices. Say Y if you want to use peripheral devices such as UART, SPI, From 6c9edce7a0e91c33ac800a83e160da6475c4bdab Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 9 Jan 2025 14:27:44 +0530 Subject: [PATCH 19/63] dt-bindings: clock: qcom: Add GPU clocks for QCS8300 The QCS8300 GPU clock controller is a derivative of SA8775P, but has few additional clocks and minor differences. Hence, reuse gpucc bindings of SA8775P and add additional clocks required for QCS8300. Acked-by: Krzysztof Kozlowski Signed-off-by: Imran Shaik Link: https://lore.kernel.org/r/20250109-qcs8300-mm-patches-new-v4-1-63e8ac268b02@quicinc.com Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,gpucc.yaml | 3 +++ include/dt-bindings/clock/qcom,qcs8300-gpucc.h | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,qcs8300-gpucc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml index 0858fd635282..4cdff6161bf0 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml @@ -8,6 +8,7 @@ title: Qualcomm Graphics Clock & Reset Controller maintainers: - Taniya Das + - Imran Shaik description: | Qualcomm graphics clock control module provides the clocks, resets and power @@ -23,10 +24,12 @@ description: | include/dt-bindings/clock/qcom,gpucc-sm8150.h include/dt-bindings/clock/qcom,gpucc-sm8250.h include/dt-bindings/clock/qcom,gpucc-sm8350.h + include/dt-bindings/clock/qcom,qcs8300-gpucc.h properties: compatible: enum: + - qcom,qcs8300-gpucc - qcom,sdm845-gpucc - qcom,sa8775p-gpucc - qcom,sc7180-gpucc diff --git a/include/dt-bindings/clock/qcom,qcs8300-gpucc.h b/include/dt-bindings/clock/qcom,qcs8300-gpucc.h new file mode 100644 index 000000000000..afa187467b4c --- /dev/null +++ b/include/dt-bindings/clock/qcom,qcs8300-gpucc.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPUCC_QCS8300_H +#define _DT_BINDINGS_CLK_QCOM_GPUCC_QCS8300_H + +#include "qcom,sa8775p-gpucc.h" + +/* QCS8300 introduces below new clocks compared to SA8775P */ + +/* GPU_CC clocks */ +#define GPU_CC_CX_ACCU_SHIFT_CLK 23 +#define GPU_CC_GX_ACCU_SHIFT_CLK 24 + +#endif From 25abbf6b8b9cbfa8e42c3ab44c642818b3adc7a2 Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 9 Jan 2025 14:27:46 +0530 Subject: [PATCH 20/63] dt-bindings: clock: qcom: Add CAMCC clocks for QCS8300 The QCS8300 camera clock controller is a derivative of SA8775P, but has an additional clock and minor differences. Hence, reuse the SA8775P camera bindings and add additional clock required for QCS8300. Reviewed-by: Vladimir Zapolskiy Acked-by: Krzysztof Kozlowski Signed-off-by: Imran Shaik Link: https://lore.kernel.org/r/20250109-qcs8300-mm-patches-new-v4-3-63e8ac268b02@quicinc.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,sa8775p-camcc.yaml | 6 +++++- include/dt-bindings/clock/qcom,qcs8300-camcc.h | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 include/dt-bindings/clock/qcom,qcs8300-camcc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sa8775p-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sa8775p-camcc.yaml index 36a60d8f5ae3..81623f59d11d 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sa8775p-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sa8775p-camcc.yaml @@ -8,16 +8,20 @@ title: Qualcomm Camera Clock & Reset Controller on SA8775P maintainers: - Taniya Das + - Imran Shaik description: | Qualcomm camera clock control module provides the clocks, resets and power domains on SA8775p. - See also: include/dt-bindings/clock/qcom,sa8775p-camcc.h + See also: + include/dt-bindings/clock/qcom,qcs8300-camcc.h + include/dt-bindings/clock/qcom,sa8775p-camcc.h properties: compatible: enum: + - qcom,qcs8300-camcc - qcom,sa8775p-camcc clocks: diff --git a/include/dt-bindings/clock/qcom,qcs8300-camcc.h b/include/dt-bindings/clock/qcom,qcs8300-camcc.h new file mode 100644 index 000000000000..fc535c847859 --- /dev/null +++ b/include/dt-bindings/clock/qcom,qcs8300-camcc.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_QCS8300_CAM_CC_H +#define _DT_BINDINGS_CLK_QCOM_QCS8300_CAM_CC_H + +#include "qcom,sa8775p-camcc.h" + +/* QCS8300 introduces below new clocks compared to SA8775P */ + +/* CAM_CC clocks */ +#define CAM_CC_TITAN_TOP_ACCU_SHIFT_CLK 86 + +#endif From 329497fb54d8180b8f93df1889ba3aca093d62fe Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 9 Jan 2025 14:27:48 +0530 Subject: [PATCH 21/63] dt-bindings: clock: qcom: Add QCS8300 video clock controller The QCS8300 video clock controller is a derivative of SA8775P, but QCS8300 has minor difference. Hence, reuse the SA8775P videocc bindings for QCS8300 platform. Acked-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Signed-off-by: Imran Shaik Link: https://lore.kernel.org/r/20250109-qcs8300-mm-patches-new-v4-5-63e8ac268b02@quicinc.com Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,sa8775p-videocc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,sa8775p-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sa8775p-videocc.yaml index 928131bff4c1..07e5d811d816 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sa8775p-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sa8775p-videocc.yaml @@ -18,6 +18,7 @@ description: | properties: compatible: enum: + - qcom,qcs8300-videocc - qcom,sa8775p-videocc clocks: From 165a5dce03ecc3d5ce41ebb2947d5fdf93412dce Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 9 Jan 2025 14:27:45 +0530 Subject: [PATCH 22/63] clk: qcom: Add support for GPU Clock Controller on QCS8300 The QCS8300 GPU clock controller is a derivative of SA8775P, but has few additional clocks and minor differences. Hence, add support for QCS8300 GPU clock controller, by extending the SA8775P GPUCC. Reviewed-by: Dmitry Baryshkov Signed-off-by: Imran Shaik Link: https://lore.kernel.org/r/20250109-qcs8300-mm-patches-new-v4-2-63e8ac268b02@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gpucc-sa8775p.c | 49 +++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gpucc-sa8775p.c b/drivers/clk/qcom/gpucc-sa8775p.c index f8a8ac343d70..78cad622cb5a 100644 --- a/drivers/clk/qcom/gpucc-sa8775p.c +++ b/drivers/clk/qcom/gpucc-sa8775p.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include "clk-alpha-pll.h" #include "clk-branch.h" @@ -317,6 +317,24 @@ static struct clk_branch gpu_cc_crc_ahb_clk = { }, }; +static struct clk_branch gpu_cc_cx_accu_shift_clk = { + .halt_reg = 0x95e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x95e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "gpu_cc_cx_accu_shift_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gpu_cc_cx_ff_clk = { .halt_reg = 0x914c, .halt_check = BRANCH_HALT, @@ -420,6 +438,24 @@ static struct clk_branch gpu_cc_demet_clk = { }, }; +static struct clk_branch gpu_cc_gx_accu_shift_clk = { + .halt_reg = 0x95e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x95e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "gpu_cc_gx_accu_shift_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { .halt_reg = 0x7000, .halt_check = BRANCH_HALT_VOTED, @@ -499,6 +535,7 @@ static struct clk_regmap *gpu_cc_sa8775p_clocks[] = { [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, [GPU_CC_CB_CLK] = &gpu_cc_cb_clk.clkr, [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_ACCU_SHIFT_CLK] = NULL, [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr, [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, @@ -508,6 +545,7 @@ static struct clk_regmap *gpu_cc_sa8775p_clocks[] = { [GPU_CC_DEMET_DIV_CLK_SRC] = &gpu_cc_demet_div_clk_src.clkr, [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr, [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GX_ACCU_SHIFT_CLK] = NULL, [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr, [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, @@ -583,6 +621,7 @@ static const struct qcom_cc_desc gpu_cc_sa8775p_desc = { }; static const struct of_device_id gpu_cc_sa8775p_match_table[] = { + { .compatible = "qcom,qcs8300-gpucc" }, { .compatible = "qcom,sa8775p-gpucc" }, { } }; @@ -596,6 +635,14 @@ static int gpu_cc_sa8775p_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); + if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcs8300-gpucc")) { + gpu_cc_pll0_config.l = 0x31; + gpu_cc_pll0_config.alpha = 0xe555; + + gpu_cc_sa8775p_clocks[GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr; + gpu_cc_sa8775p_clocks[GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr; + } + clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); From 63847e845c56d936abfc495fa8e192234f7a1f8f Mon Sep 17 00:00:00 2001 From: Imran Shaik Date: Thu, 9 Jan 2025 14:27:49 +0530 Subject: [PATCH 23/63] clk: qcom: Add support for Video Clock Controller on QCS8300 The QCS8300 Video clock controller is a derivative of SA8775P, but has a minor difference. Hence add support for QCS8300 Video clock controller by extending the SA8775P VideoCC. Reviewed-by: Dmitry Baryshkov Acked-by: Krzysztof Kozlowski Signed-off-by: Imran Shaik Link: https://lore.kernel.org/r/20250109-qcs8300-mm-patches-new-v4-6-63e8ac268b02@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/videocc-sa8775p.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/clk/qcom/videocc-sa8775p.c b/drivers/clk/qcom/videocc-sa8775p.c index bf5de411fd5d..db492984fd7d 100644 --- a/drivers/clk/qcom/videocc-sa8775p.c +++ b/drivers/clk/qcom/videocc-sa8775p.c @@ -523,6 +523,7 @@ static struct qcom_cc_desc video_cc_sa8775p_desc = { }; static const struct of_device_id video_cc_sa8775p_match_table[] = { + { .compatible = "qcom,qcs8300-videocc" }, { .compatible = "qcom,sa8775p-videocc" }, { } }; @@ -550,6 +551,13 @@ static int video_cc_sa8775p_probe(struct platform_device *pdev) clk_lucid_evo_pll_configure(&video_pll0, regmap, &video_pll0_config); clk_lucid_evo_pll_configure(&video_pll1, regmap, &video_pll1_config); + /* + * Set mvs0c clock divider to div-3 to make the mvs0 and + * mvs0c clocks to run at the same frequency on QCS8300 + */ + if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcs8300-videocc")) + regmap_write(regmap, video_cc_mvs0c_div2_div_clk_src.reg, 2); + /* Keep some clocks always enabled */ qcom_branch_set_clk_en(regmap, 0x80ec); /* VIDEO_CC_AHB_CLK */ qcom_branch_set_clk_en(regmap, 0x8144); /* VIDEO_CC_SLEEP_CLK */ From c240648b78f9cbb76052959c099ea94ab6cba893 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Thu, 13 Feb 2025 11:22:47 -0600 Subject: [PATCH 24/63] dt-bindings: clock: sun50i-h616-ccu: Add LCD TCON clk and reset Add the required clock and reset bindings for the LCD TCON. Signed-off-by: Chris Morgan Acked-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20250213172248.158447-2-macroalpha82@gmail.com Signed-off-by: Chen-Yu Tsai --- include/dt-bindings/clock/sun50i-h616-ccu.h | 4 ++++ include/dt-bindings/reset/sun50i-h616-ccu.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/include/dt-bindings/clock/sun50i-h616-ccu.h b/include/dt-bindings/clock/sun50i-h616-ccu.h index ebb146ab7f8c..6889405f9fec 100644 --- a/include/dt-bindings/clock/sun50i-h616-ccu.h +++ b/include/dt-bindings/clock/sun50i-h616-ccu.h @@ -113,5 +113,9 @@ #define CLK_BUS_HDCP 127 #define CLK_PLL_SYSTEM_32K 128 #define CLK_BUS_GPADC 129 +#define CLK_TCON_LCD0 130 +#define CLK_BUS_TCON_LCD0 131 +#define CLK_TCON_LCD1 132 +#define CLK_BUS_TCON_LCD1 133 #endif /* _DT_BINDINGS_CLK_SUN50I_H616_H_ */ diff --git a/include/dt-bindings/reset/sun50i-h616-ccu.h b/include/dt-bindings/reset/sun50i-h616-ccu.h index ed177c04afdd..81b1eba2a7f7 100644 --- a/include/dt-bindings/reset/sun50i-h616-ccu.h +++ b/include/dt-bindings/reset/sun50i-h616-ccu.h @@ -67,5 +67,7 @@ #define RST_BUS_HDCP 58 #define RST_BUS_KEYADC 59 #define RST_BUS_GPADC 60 +#define RST_BUS_TCON_LCD0 61 +#define RST_BUS_TCON_LCD1 62 #endif /* _DT_BINDINGS_RESET_SUN50I_H616_H_ */ From 730feeaea72f1260548e57d35dd49603cd86a7e4 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Thu, 13 Feb 2025 11:22:48 -0600 Subject: [PATCH 25/63] clk: sunxi-ng: h616: Add clock/reset for LCD TCON Add the required clock and reset which is used for the LCD TCON. Please note that these clocks are exposed on the T507, H616, and H700; however the H616 does not expose an LCD controller for which these clocks are needed. Signed-off-by: Chris Morgan Reviewed-by: Andre Przywara Reviewed-by: Jernej Skrabec Tested-by: Ryan Walklin Link: https://patch.msgid.link/20250213172248.158447-3-macroalpha82@gmail.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 24 ++++++++++++++++++++++++ drivers/clk/sunxi-ng/ccu-sun50i-h616.h | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c index 190816c35da9..40ab6873b797 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c @@ -645,6 +645,20 @@ static const char * const tcon_tv_parents[] = { "pll-video0", "pll-video0-4x", "pll-video1", "pll-video1-4x" }; +static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", + tcon_tv_parents, 0xb60, + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); +static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", + tcon_tv_parents, 0xb64, + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3", + 0xb7c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb3", + 0xb7c, BIT(1), 0); static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_tv_parents, 0xb80, 0, 4, /* M */ @@ -855,8 +869,12 @@ static struct ccu_common *sun50i_h616_ccu_clks[] = { &hdmi_cec_clk.common, &bus_hdmi_clk.common, &bus_tcon_top_clk.common, + &tcon_lcd0_clk.common, + &tcon_lcd1_clk.common, &tcon_tv0_clk.common, &tcon_tv1_clk.common, + &bus_tcon_lcd0_clk.common, + &bus_tcon_lcd1_clk.common, &bus_tcon_tv0_clk.common, &bus_tcon_tv1_clk.common, &tve0_clk.common, @@ -989,8 +1007,12 @@ static struct clk_hw_onecell_data sun50i_h616_hw_clks = { [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw, + [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, + [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw, [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw, + [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw, + [CLK_BUS_TCON_LCD1] = &bus_tcon_lcd1_clk.common.hw, [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw, [CLK_BUS_TCON_TV1] = &bus_tcon_tv1_clk.common.hw, [CLK_TVE0] = &tve0_clk.common.hw, @@ -1062,6 +1084,8 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = { [RST_BUS_HDMI] = { 0xb1c, BIT(16) }, [RST_BUS_HDMI_SUB] = { 0xb1c, BIT(17) }, [RST_BUS_TCON_TOP] = { 0xb5c, BIT(16) }, + [RST_BUS_TCON_LCD0] = { 0xb7c, BIT(16) }, + [RST_BUS_TCON_LCD1] = { 0xb7c, BIT(17) }, [RST_BUS_TCON_TV0] = { 0xb9c, BIT(16) }, [RST_BUS_TCON_TV1] = { 0xb9c, BIT(17) }, [RST_BUS_TVE_TOP] = { 0xbbc, BIT(16) }, diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.h b/drivers/clk/sunxi-ng/ccu-sun50i-h616.h index a75803b49f6a..7056f293a8e0 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.h @@ -51,6 +51,6 @@ #define CLK_BUS_DRAM 56 -#define CLK_NUMBER (CLK_BUS_GPADC + 1) +#define CLK_NUMBER (CLK_BUS_TCON_LCD1 + 1) #endif /* _CCU_SUN50I_H616_H_ */ From eb963d7948ce6571939c6875424b557b25f16610 Mon Sep 17 00:00:00 2001 From: Philippe Simons Date: Thu, 20 Feb 2025 12:38:08 +0100 Subject: [PATCH 26/63] clk: sunxi-ng: h616: Reparent GPU clock during frequency changes The H616 manual does not state that the GPU PLL supports dynamic frequency configuration, so we must take extra care when changing the frequency. Currently any attempt to do device DVFS on the GPU lead to panfrost various ooops, and GPU hangs. The manual describes the algorithm for changing the PLL frequency, which the CPU PLL notifier code already support, so we reuse that to reparent the GPU clock to GPU1 clock during frequency changes. Signed-off-by: Philippe Simons Reviewed-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250220113808.1122414-2-simons.philippe@gmail.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 36 +++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c index 40ab6873b797..daa462c7d477 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c @@ -328,10 +328,16 @@ static SUNXI_CCU_M_WITH_MUX_GATE(gpu0_clk, "gpu0", gpu0_parents, 0x670, 24, 1, /* mux */ BIT(31), /* gate */ CLK_SET_RATE_PARENT); + +/* + * This clk is needed as a temporary fall back during GPU PLL freq changes. + * Set CLK_IS_CRITICAL flag to prevent from being disabled. + */ +#define SUN50I_H616_GPU_CLK1_REG 0x674 static SUNXI_CCU_M_WITH_GATE(gpu1_clk, "gpu1", "pll-periph0-2x", 0x674, 0, 2, /* M */ BIT(31),/* gate */ - 0); + CLK_IS_CRITICAL); static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2", 0x67c, BIT(0), 0); @@ -1144,6 +1150,19 @@ static struct ccu_pll_nb sun50i_h616_pll_cpu_nb = { .lock = BIT(28), }; +static struct ccu_mux_nb sun50i_h616_gpu_nb = { + .common = &gpu0_clk.common, + .cm = &gpu0_clk.mux, + .delay_us = 1, /* manual doesn't really say */ + .bypass_index = 1, /* GPU_CLK1@400MHz */ +}; + +static struct ccu_pll_nb sun50i_h616_pll_gpu_nb = { + .common = &pll_gpu_clk.common, + .enable = BIT(29), /* LOCK_ENABLE */ + .lock = BIT(28), +}; + static int sun50i_h616_ccu_probe(struct platform_device *pdev) { void __iomem *reg; @@ -1194,6 +1213,14 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev) val |= BIT(0); writel(val, reg + SUN50I_H616_PLL_AUDIO_REG); + /* + * Set the input-divider for the gpu1 clock to 3, to reach a safe 400 MHz. + */ + val = readl(reg + SUN50I_H616_GPU_CLK1_REG); + val &= ~GENMASK(1, 0); + val |= 2; + writel(val, reg + SUN50I_H616_GPU_CLK1_REG); + /* * First clock parent (osc32K) is unusable for CEC. But since there * is no good way to force parent switch (both run with same frequency), @@ -1214,6 +1241,13 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev) /* Re-lock the CPU PLL after any rate changes */ ccu_pll_notifier_register(&sun50i_h616_pll_cpu_nb); + /* Reparent GPU during GPU PLL rate changes */ + ccu_mux_notifier_register(pll_gpu_clk.common.hw.clk, + &sun50i_h616_gpu_nb); + + /* Re-lock the GPU PLL after any rate changes */ + ccu_pll_notifier_register(&sun50i_h616_pll_gpu_nb); + return 0; } From 53fc6fe160c1b941e531a35e3a2e6d2aaef86999 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Tue, 4 Mar 2025 00:39:36 +0200 Subject: [PATCH 27/63] dt-bindings: clock: qcom: sm8450-camcc: Remove qcom,x1e80100-camcc leftover Qualcomm x1e80100-camcc was moved to its own dt bindings description file, however a small leftover was left, remove it. Fixes: 7ec95ff9abf4 ("dt-bindings: clock: move qcom,x1e80100-camcc to its own file") Signed-off-by: Vladimir Zapolskiy Link: https://lore.kernel.org/r/20250303223936.1780441-1-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index b88b6c9b399a..9e79f8fec437 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -64,7 +64,6 @@ allOf: - qcom,sc8280xp-camcc - qcom,sm8450-camcc - qcom,sm8550-camcc - - qcom,x1e80100-camcc then: required: - required-opps From 0f358f1ad56d781642b00454b57e4f35c4d74295 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 28 Feb 2025 15:59:38 +0100 Subject: [PATCH 28/63] clk: qcom: camcc: Constify 'struct qcom_cc_desc' 'struct qcom_cc_desc' is passed to qcom_cc_map() and qcom_cc_really_probe() only as pointer to const, so make the memory const for safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250228-clk-qcom-const-v1-1-611ab80d45e4@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/camcc-sa8775p.c | 2 +- drivers/clk/qcom/camcc-sc8280xp.c | 2 +- drivers/clk/qcom/camcc-sm4450.c | 2 +- drivers/clk/qcom/camcc-sm8150.c | 2 +- drivers/clk/qcom/camcc-sm8550.c | 2 +- drivers/clk/qcom/camcc-sm8650.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/qcom/camcc-sa8775p.c b/drivers/clk/qcom/camcc-sa8775p.c index 1df86da41940..11bd2e234811 100644 --- a/drivers/clk/qcom/camcc-sa8775p.c +++ b/drivers/clk/qcom/camcc-sa8775p.c @@ -1800,7 +1800,7 @@ static const struct regmap_config cam_cc_sa8775p_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc cam_cc_sa8775p_desc = { +static const struct qcom_cc_desc cam_cc_sa8775p_desc = { .config = &cam_cc_sa8775p_regmap_config, .clks = cam_cc_sa8775p_clocks, .num_clks = ARRAY_SIZE(cam_cc_sa8775p_clocks), diff --git a/drivers/clk/qcom/camcc-sc8280xp.c b/drivers/clk/qcom/camcc-sc8280xp.c index 479964f91608..18f5a3eb313e 100644 --- a/drivers/clk/qcom/camcc-sc8280xp.c +++ b/drivers/clk/qcom/camcc-sc8280xp.c @@ -2987,7 +2987,7 @@ static const struct regmap_config camcc_sc8280xp_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc camcc_sc8280xp_desc = { +static const struct qcom_cc_desc camcc_sc8280xp_desc = { .config = &camcc_sc8280xp_regmap_config, .clks = camcc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(camcc_sc8280xp_clocks), diff --git a/drivers/clk/qcom/camcc-sm4450.c b/drivers/clk/qcom/camcc-sm4450.c index e51590d89a3c..6170d5ad9cbf 100644 --- a/drivers/clk/qcom/camcc-sm4450.c +++ b/drivers/clk/qcom/camcc-sm4450.c @@ -1640,7 +1640,7 @@ static const struct regmap_config cam_cc_sm4450_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc cam_cc_sm4450_desc = { +static const struct qcom_cc_desc cam_cc_sm4450_desc = { .config = &cam_cc_sm4450_regmap_config, .clks = cam_cc_sm4450_clocks, .num_clks = ARRAY_SIZE(cam_cc_sm4450_clocks), diff --git a/drivers/clk/qcom/camcc-sm8150.c b/drivers/clk/qcom/camcc-sm8150.c index f105534cb318..62aadb27c50e 100644 --- a/drivers/clk/qcom/camcc-sm8150.c +++ b/drivers/clk/qcom/camcc-sm8150.c @@ -2094,7 +2094,7 @@ static const struct regmap_config cam_cc_sm8150_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc cam_cc_sm8150_desc = { +static const struct qcom_cc_desc cam_cc_sm8150_desc = { .config = &cam_cc_sm8150_regmap_config, .clks = cam_cc_sm8150_clocks, .num_clks = ARRAY_SIZE(cam_cc_sm8150_clocks), diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c index eac850bb690a..871155783c79 100644 --- a/drivers/clk/qcom/camcc-sm8550.c +++ b/drivers/clk/qcom/camcc-sm8550.c @@ -3487,7 +3487,7 @@ static const struct regmap_config cam_cc_sm8550_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc cam_cc_sm8550_desc = { +static const struct qcom_cc_desc cam_cc_sm8550_desc = { .config = &cam_cc_sm8550_regmap_config, .clks = cam_cc_sm8550_clocks, .num_clks = ARRAY_SIZE(cam_cc_sm8550_clocks), diff --git a/drivers/clk/qcom/camcc-sm8650.c b/drivers/clk/qcom/camcc-sm8650.c index a37e52a67ed4..0ccd6de8ba78 100644 --- a/drivers/clk/qcom/camcc-sm8650.c +++ b/drivers/clk/qcom/camcc-sm8650.c @@ -3517,7 +3517,7 @@ static const struct regmap_config cam_cc_sm8650_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc cam_cc_sm8650_desc = { +static const struct qcom_cc_desc cam_cc_sm8650_desc = { .config = &cam_cc_sm8650_regmap_config, .clks = cam_cc_sm8650_clocks, .num_clks = ARRAY_SIZE(cam_cc_sm8650_clocks), From 1801cee7c6607dbf638d9e1e6a198c9b3e2bda90 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 28 Feb 2025 15:59:39 +0100 Subject: [PATCH 29/63] clk: qcom: dispcc: Constify 'struct qcom_cc_desc' 'struct qcom_cc_desc' is passed to qcom_cc_map() and qcom_cc_really_probe() only as pointer to const, so make the memory const for safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250228-clk-qcom-const-v1-2-611ab80d45e4@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/dispcc-sc8280xp.c | 4 ++-- drivers/clk/qcom/dispcc-sm4450.c | 2 +- drivers/clk/qcom/dispcc-sm8450.c | 2 +- drivers/clk/qcom/dispcc-sm8550.c | 2 +- drivers/clk/qcom/dispcc-sm8750.c | 2 +- drivers/clk/qcom/dispcc0-sa8775p.c | 2 +- drivers/clk/qcom/dispcc1-sa8775p.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/clk/qcom/dispcc-sc8280xp.c b/drivers/clk/qcom/dispcc-sc8280xp.c index 34fae823423a..5903a759d4af 100644 --- a/drivers/clk/qcom/dispcc-sc8280xp.c +++ b/drivers/clk/qcom/dispcc-sc8280xp.c @@ -3113,7 +3113,7 @@ static const struct regmap_config disp_cc_sc8280xp_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc disp0_cc_sc8280xp_desc = { +static const struct qcom_cc_desc disp0_cc_sc8280xp_desc = { .config = &disp_cc_sc8280xp_regmap_config, .clks = disp0_cc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(disp0_cc_sc8280xp_clocks), @@ -3123,7 +3123,7 @@ static struct qcom_cc_desc disp0_cc_sc8280xp_desc = { .num_gdscs = ARRAY_SIZE(disp0_cc_sc8280xp_gdscs), }; -static struct qcom_cc_desc disp1_cc_sc8280xp_desc = { +static const struct qcom_cc_desc disp1_cc_sc8280xp_desc = { .config = &disp_cc_sc8280xp_regmap_config, .clks = disp1_cc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(disp1_cc_sc8280xp_clocks), diff --git a/drivers/clk/qcom/dispcc-sm4450.c b/drivers/clk/qcom/dispcc-sm4450.c index 465725f9bfeb..e8752d01c8e6 100644 --- a/drivers/clk/qcom/dispcc-sm4450.c +++ b/drivers/clk/qcom/dispcc-sm4450.c @@ -721,7 +721,7 @@ static const struct regmap_config disp_cc_sm4450_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc disp_cc_sm4450_desc = { +static const struct qcom_cc_desc disp_cc_sm4450_desc = { .config = &disp_cc_sm4450_regmap_config, .clks = disp_cc_sm4450_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm4450_clocks), diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c index 0b76cddbeb94..9ce9fd28e55b 100644 --- a/drivers/clk/qcom/dispcc-sm8450.c +++ b/drivers/clk/qcom/dispcc-sm8450.c @@ -1779,7 +1779,7 @@ static const struct regmap_config disp_cc_sm8450_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc disp_cc_sm8450_desc = { +static const struct qcom_cc_desc disp_cc_sm8450_desc = { .config = &disp_cc_sm8450_regmap_config, .clks = disp_cc_sm8450_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm8450_clocks), diff --git a/drivers/clk/qcom/dispcc-sm8550.c b/drivers/clk/qcom/dispcc-sm8550.c index a373c92a10aa..f27140c649f5 100644 --- a/drivers/clk/qcom/dispcc-sm8550.c +++ b/drivers/clk/qcom/dispcc-sm8550.c @@ -1745,7 +1745,7 @@ static const struct regmap_config disp_cc_sm8550_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc disp_cc_sm8550_desc = { +static const struct qcom_cc_desc disp_cc_sm8550_desc = { .config = &disp_cc_sm8550_regmap_config, .clks = disp_cc_sm8550_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm8550_clocks), diff --git a/drivers/clk/qcom/dispcc-sm8750.c b/drivers/clk/qcom/dispcc-sm8750.c index a532d9ad9dd3..b46836ae6ae7 100644 --- a/drivers/clk/qcom/dispcc-sm8750.c +++ b/drivers/clk/qcom/dispcc-sm8750.c @@ -1887,7 +1887,7 @@ static const struct regmap_config disp_cc_sm8750_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc disp_cc_sm8750_desc = { +static const struct qcom_cc_desc disp_cc_sm8750_desc = { .config = &disp_cc_sm8750_regmap_config, .clks = disp_cc_sm8750_clocks, .num_clks = ARRAY_SIZE(disp_cc_sm8750_clocks), diff --git a/drivers/clk/qcom/dispcc0-sa8775p.c b/drivers/clk/qcom/dispcc0-sa8775p.c index bf9de92a5dd2..aeda9cf4bfee 100644 --- a/drivers/clk/qcom/dispcc0-sa8775p.c +++ b/drivers/clk/qcom/dispcc0-sa8775p.c @@ -1417,7 +1417,7 @@ static const struct regmap_config disp_cc_0_sa8775p_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc disp_cc_0_sa8775p_desc = { +static const struct qcom_cc_desc disp_cc_0_sa8775p_desc = { .config = &disp_cc_0_sa8775p_regmap_config, .clks = disp_cc_0_sa8775p_clocks, .num_clks = ARRAY_SIZE(disp_cc_0_sa8775p_clocks), diff --git a/drivers/clk/qcom/dispcc1-sa8775p.c b/drivers/clk/qcom/dispcc1-sa8775p.c index cd2f2eb7ffb4..cd55d1c11902 100644 --- a/drivers/clk/qcom/dispcc1-sa8775p.c +++ b/drivers/clk/qcom/dispcc1-sa8775p.c @@ -1417,7 +1417,7 @@ static const struct regmap_config disp_cc_1_sa8775p_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc disp_cc_1_sa8775p_desc = { +static const struct qcom_cc_desc disp_cc_1_sa8775p_desc = { .config = &disp_cc_1_sa8775p_regmap_config, .clks = disp_cc_1_sa8775p_clocks, .num_clks = ARRAY_SIZE(disp_cc_1_sa8775p_clocks), From b9fe89a100ab1a31f56c91682de402c9aeb2f701 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 28 Feb 2025 15:59:40 +0100 Subject: [PATCH 30/63] clk: qcom: gpucc: Constify 'struct qcom_cc_desc' 'struct qcom_cc_desc' is passed to qcom_cc_map() and qcom_cc_really_probe() only as pointer to const, so make the memory const for safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250228-clk-qcom-const-v1-3-611ab80d45e4@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gpucc-sc8280xp.c | 2 +- drivers/clk/qcom/gpucc-x1p42100.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gpucc-sc8280xp.c b/drivers/clk/qcom/gpucc-sc8280xp.c index 913e17f10196..2645612f1cac 100644 --- a/drivers/clk/qcom/gpucc-sc8280xp.c +++ b/drivers/clk/qcom/gpucc-sc8280xp.c @@ -416,7 +416,7 @@ static const struct regmap_config gpu_cc_sc8280xp_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc gpu_cc_sc8280xp_desc = { +static const struct qcom_cc_desc gpu_cc_sc8280xp_desc = { .config = &gpu_cc_sc8280xp_regmap_config, .clks = gpu_cc_sc8280xp_clocks, .num_clks = ARRAY_SIZE(gpu_cc_sc8280xp_clocks), diff --git a/drivers/clk/qcom/gpucc-x1p42100.c b/drivers/clk/qcom/gpucc-x1p42100.c index dba783339613..4031d3ff560a 100644 --- a/drivers/clk/qcom/gpucc-x1p42100.c +++ b/drivers/clk/qcom/gpucc-x1p42100.c @@ -523,7 +523,7 @@ static const struct regmap_config gpu_cc_x1p42100_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc gpu_cc_x1p42100_desc = { +static const struct qcom_cc_desc gpu_cc_x1p42100_desc = { .config = &gpu_cc_x1p42100_regmap_config, .clks = gpu_cc_x1p42100_clocks, .num_clks = ARRAY_SIZE(gpu_cc_x1p42100_clocks), From a8e4ab5bdeeadf873a36f904066185acb1540021 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 28 Feb 2025 15:59:41 +0100 Subject: [PATCH 31/63] clk: qcom: videocc: Constify 'struct qcom_cc_desc' 'struct qcom_cc_desc' is passed to qcom_cc_map() and qcom_cc_really_probe() only as pointer to const, so make the memory const for safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250228-clk-qcom-const-v1-4-611ab80d45e4@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/videocc-sa8775p.c | 2 +- drivers/clk/qcom/videocc-sm8350.c | 2 +- drivers/clk/qcom/videocc-sm8450.c | 2 +- drivers/clk/qcom/videocc-sm8550.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/videocc-sa8775p.c b/drivers/clk/qcom/videocc-sa8775p.c index db492984fd7d..2476201dcd20 100644 --- a/drivers/clk/qcom/videocc-sa8775p.c +++ b/drivers/clk/qcom/videocc-sa8775p.c @@ -512,7 +512,7 @@ static const struct regmap_config video_cc_sa8775p_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc video_cc_sa8775p_desc = { +static const struct qcom_cc_desc video_cc_sa8775p_desc = { .config = &video_cc_sa8775p_regmap_config, .clks = video_cc_sa8775p_clocks, .num_clks = ARRAY_SIZE(video_cc_sa8775p_clocks), diff --git a/drivers/clk/qcom/videocc-sm8350.c b/drivers/clk/qcom/videocc-sm8350.c index 874d4da95ff8..057a9474894a 100644 --- a/drivers/clk/qcom/videocc-sm8350.c +++ b/drivers/clk/qcom/videocc-sm8350.c @@ -510,7 +510,7 @@ static const struct regmap_config video_cc_sm8350_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc video_cc_sm8350_desc = { +static const struct qcom_cc_desc video_cc_sm8350_desc = { .config = &video_cc_sm8350_regmap_config, .clks = video_cc_sm8350_clocks, .num_clks = ARRAY_SIZE(video_cc_sm8350_clocks), diff --git a/drivers/clk/qcom/videocc-sm8450.c b/drivers/clk/qcom/videocc-sm8450.c index f26c7eccb62e..2e11dcffb664 100644 --- a/drivers/clk/qcom/videocc-sm8450.c +++ b/drivers/clk/qcom/videocc-sm8450.c @@ -415,7 +415,7 @@ static const struct regmap_config video_cc_sm8450_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc video_cc_sm8450_desc = { +static const struct qcom_cc_desc video_cc_sm8450_desc = { .config = &video_cc_sm8450_regmap_config, .clks = video_cc_sm8450_clocks, .num_clks = ARRAY_SIZE(video_cc_sm8450_clocks), diff --git a/drivers/clk/qcom/videocc-sm8550.c b/drivers/clk/qcom/videocc-sm8550.c index 7c25a50cfa97..fcfe0cade6d0 100644 --- a/drivers/clk/qcom/videocc-sm8550.c +++ b/drivers/clk/qcom/videocc-sm8550.c @@ -519,7 +519,7 @@ static const struct regmap_config video_cc_sm8550_regmap_config = { .fast_io = true, }; -static struct qcom_cc_desc video_cc_sm8550_desc = { +static const struct qcom_cc_desc video_cc_sm8550_desc = { .config = &video_cc_sm8550_regmap_config, .clks = video_cc_sm8550_clocks, .num_clks = ARRAY_SIZE(video_cc_sm8550_clocks), From 8b75c2973997e66fd897b7e87b5ba2f3d683e94b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 5 Mar 2025 20:00:29 +0100 Subject: [PATCH 32/63] clk: qcom: gcc-sm8650: Do not turn off USB GDSCs during gdsc_disable() With PWRSTS_OFF_ON, USB GDSCs are turned off during gdsc_disable(). This can happen during scenarios such as system suspend and breaks the resume of USB controller from suspend. So use PWRSTS_RET_ON to indicate the GDSC driver to not turn off the GDSCs during gdsc_disable() and allow the hardware to transition the GDSCs to retention when the parent domain enters low power state during system suspend. Fixes: c58225b7e3d7 ("clk: qcom: add the SM8650 Global Clock Controller driver, part 1") Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20250305-topic-sm8650-upstream-fix-usb-suspend-v1-1-649036ab0557@linaro.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-sm8650.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c index 9dd5c48f33be..fa1672c4e7d8 100644 --- a/drivers/clk/qcom/gcc-sm8650.c +++ b/drivers/clk/qcom/gcc-sm8650.c @@ -3497,7 +3497,7 @@ static struct gdsc usb30_prim_gdsc = { .pd = { .name = "usb30_prim_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; @@ -3506,7 +3506,7 @@ static struct gdsc usb3_phy_gdsc = { .pd = { .name = "usb3_phy_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; From 45717804b75eda8a76eacc04509ca4d68dd2caaf Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:15 +0000 Subject: [PATCH 33/63] clk: sunxi-ng: mp: introduce dual-divider clock The Allwinner A523 SoC introduces some new MP-style mod clock, where the second "P" divider is an actual numerical divider value, and not the numbers of bits to shift (1..32 instead of 1,2,4,8). The rest of the clock is the same as the existing MP clock, so enhance the existing code to accommodate for this. Introduce the new CCU feature bit CCU_FEATURE_DUAL_DIV to mark an MP clock as having two dividers, and change the dividing and encoding code to differentiate the two cases. Signed-off-by: Andre Przywara Reviewed-by: Chen-Yu Tsai Link: https://patch.msgid.link/20250307002628.10684-2-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu_common.h | 1 + drivers/clk/sunxi-ng/ccu_mp.c | 51 +++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h index dd330426a6e5..50fd26832967 100644 --- a/drivers/clk/sunxi-ng/ccu_common.h +++ b/drivers/clk/sunxi-ng/ccu_common.h @@ -19,6 +19,7 @@ #define CCU_FEATURE_SIGMA_DELTA_MOD BIT(7) #define CCU_FEATURE_KEY_FIELD BIT(8) #define CCU_FEATURE_CLOSEST_RATE BIT(9) +#define CCU_FEATURE_DUAL_DIV BIT(10) /* MMC timing mode switch bit */ #define CCU_MMC_NEW_TIMING_MODE BIT(30) diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index 2bb8987ddcc2..354c981943b6 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -10,15 +10,23 @@ #include "ccu_gate.h" #include "ccu_mp.h" +static unsigned int next_div(unsigned int div, bool shift) +{ + if (shift) + return div << 1; + return div + 1; +} + static unsigned long ccu_mp_find_best(unsigned long parent, unsigned long rate, unsigned int max_m, unsigned int max_p, + bool shift, unsigned int *m, unsigned int *p) { unsigned long best_rate = 0; unsigned int best_m = 0, best_p = 0; unsigned int _m, _p; - for (_p = 1; _p <= max_p; _p <<= 1) { + for (_p = 1; _p <= max_p; _p = next_div(_p, shift)) { for (_m = 1; _m <= max_m; _m++) { unsigned long tmp_rate = parent / _p / _m; @@ -43,7 +51,8 @@ static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw, unsigned long *parent, unsigned long rate, unsigned int max_m, - unsigned int max_p) + unsigned int max_p, + bool shift) { unsigned long parent_rate_saved; unsigned long parent_rate, now; @@ -60,7 +69,7 @@ static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw, maxdiv = max_m * max_p; maxdiv = min(ULONG_MAX / rate, maxdiv); - for (_p = 1; _p <= max_p; _p <<= 1) { + for (_p = 1; _p <= max_p; _p = next_div(_p, shift)) { for (_m = 1; _m <= max_m; _m++) { div = _m * _p; @@ -103,18 +112,26 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, struct ccu_mp *cmp = data; unsigned int max_m, max_p; unsigned int m, p; + bool shift = true; if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) rate *= cmp->fixed_post_div; + if (cmp->common.features & CCU_FEATURE_DUAL_DIV) + shift = false; + max_m = cmp->m.max ?: 1 << cmp->m.width; - max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); + if (shift) + max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); + else + max_p = cmp->p.max ?: 1 << cmp->p.width; if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) { - rate = ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); + rate = ccu_mp_find_best(*parent_rate, rate, max_m, max_p, shift, + &m, &p); } else { rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate, - max_m, max_p); + max_m, max_p, shift); } if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) @@ -167,7 +184,11 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw, p = reg >> cmp->p.shift; p &= (1 << cmp->p.width) - 1; - rate = (parent_rate >> p) / m; + if (cmp->common.features & CCU_FEATURE_DUAL_DIV) + rate = (parent_rate / p) / m; + else + rate = (parent_rate >> p) / m; + if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= cmp->fixed_post_div; @@ -190,20 +211,27 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long flags; unsigned int max_m, max_p; unsigned int m, p; + bool shift = true; u32 reg; + if (cmp->common.features & CCU_FEATURE_DUAL_DIV) + shift = false; + /* Adjust parent_rate according to pre-dividers */ parent_rate = ccu_mux_helper_apply_prediv(&cmp->common, &cmp->mux, -1, parent_rate); max_m = cmp->m.max ?: 1 << cmp->m.width; - max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); + if (shift) + max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); + else + max_p = cmp->p.max ?: 1 << cmp->p.width; /* Adjust target rate according to post-dividers */ if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) rate = rate * cmp->fixed_post_div; - ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p); + ccu_mp_find_best(parent_rate, rate, max_m, max_p, shift, &m, &p); spin_lock_irqsave(cmp->common.lock, flags); @@ -211,7 +239,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift); reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift); reg |= (m - cmp->m.offset) << cmp->m.shift; - reg |= ilog2(p) << cmp->p.shift; + if (shift) + reg |= ilog2(p) << cmp->p.shift; + else + reg |= (p - cmp->p.offset) << cmp->p.shift; writel(reg, cmp->common.base + cmp->common.reg); From cdbb9d0d09db4cd09d23fec02d3b458664bc3d38 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:16 +0000 Subject: [PATCH 34/63] clk: sunxi-ng: mp: provide wrappers for setting feature flags So far our sunxi clock instantiation macros set the required clock features depending on the clock type, but the new "dual divider MP clock" requires us to pass that piece of information in by the user. Add new wrapper macros that allow to specify a "features" field, to allow marking those dual-divider clocks accordingly. Also add two convenience macros that deal with the most common cases. Signed-off-by: Andre Przywara Acked-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-3-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu_mp.h | 58 ++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu_mp.h b/drivers/clk/sunxi-ng/ccu_mp.h index 6e50f3728fb5..b35aeec70484 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.h +++ b/drivers/clk/sunxi-ng/ccu_mp.h @@ -82,11 +82,35 @@ struct ccu_mp { _muxshift, _muxwidth, \ 0, _flags) -#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _pshift, _pwidth, \ - _muxshift, _muxwidth, \ - _gate, _flags) \ +#define SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _postdiv, \ + _flags) \ + struct ccu_mp _struct = { \ + .enable = _gate, \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ + .fixed_post_div = _postdiv, \ + .common = { \ + .reg = _reg, \ + .features = CCU_FEATURE_FIXED_POSTDIV | \ + CCU_FEATURE_DUAL_DIV, \ + .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ + _parents, \ + &ccu_mp_ops, \ + _flags), \ + } \ + } + +#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _features, \ + _flags) \ struct ccu_mp _struct = { \ .enable = _gate, \ .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ @@ -94,6 +118,7 @@ struct ccu_mp { .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ .common = { \ .reg = _reg, \ + .features = _features, \ .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ _parents, \ &ccu_mp_ops, \ @@ -101,6 +126,29 @@ struct ccu_mp { } \ } +#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags) \ + SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents, \ + _reg, _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags, 0) + +#define SUNXI_CCU_DUALDIV_MUX_GATE(_struct, _name, _parents, _reg, \ + _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags) \ + SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(_struct, _name, _parents, \ + _reg, _mshift, _mwidth, \ + _pshift, _pwidth, \ + _muxshift, _muxwidth, \ + _gate, _flags, \ + CCU_FEATURE_DUAL_DIV) + #define SUNXI_CCU_MP_DATA_WITH_MUX(_struct, _name, _parents, _reg, \ _mshift, _mwidth, \ _pshift, _pwidth, \ From e16b9b71f40f603d5cbdcf02007c05ee03cb2be7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:17 +0000 Subject: [PATCH 35/63] clk: sunxi-ng: Add support for update bit Some clocks in the Allwinner A523 SoC contain an "update bit" (bit 27), which must be set to apply any register changes, namely the mux selector, the divider and the gate bit. Add a new CCU feature bit to mark those clocks, and set bit 27 whenever we are applying any changes. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-4-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu_common.h | 4 ++++ drivers/clk/sunxi-ng/ccu_div.c | 2 ++ drivers/clk/sunxi-ng/ccu_gate.c | 4 ++++ drivers/clk/sunxi-ng/ccu_mux.c | 2 ++ 4 files changed, 12 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h index 50fd26832967..bbec283b9d99 100644 --- a/drivers/clk/sunxi-ng/ccu_common.h +++ b/drivers/clk/sunxi-ng/ccu_common.h @@ -20,10 +20,14 @@ #define CCU_FEATURE_KEY_FIELD BIT(8) #define CCU_FEATURE_CLOSEST_RATE BIT(9) #define CCU_FEATURE_DUAL_DIV BIT(10) +#define CCU_FEATURE_UPDATE_BIT BIT(11) /* MMC timing mode switch bit */ #define CCU_MMC_NEW_TIMING_MODE BIT(30) +/* Some clocks need this bit to actually apply register changes */ +#define CCU_SUNXI_UPDATE_BIT BIT(27) + struct device_node; struct ccu_common { diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index 7f4691f09e01..916d6da6d8a3 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c @@ -106,6 +106,8 @@ static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate, reg = readl(cd->common.base + cd->common.reg); reg &= ~GENMASK(cd->div.width + cd->div.shift - 1, cd->div.shift); + if (cd->common.features & CCU_FEATURE_UPDATE_BIT) + reg |= CCU_SUNXI_UPDATE_BIT; writel(reg | (val << cd->div.shift), cd->common.base + cd->common.reg); diff --git a/drivers/clk/sunxi-ng/ccu_gate.c b/drivers/clk/sunxi-ng/ccu_gate.c index ac52fd6bff67..474a9e8831f8 100644 --- a/drivers/clk/sunxi-ng/ccu_gate.c +++ b/drivers/clk/sunxi-ng/ccu_gate.c @@ -20,6 +20,8 @@ void ccu_gate_helper_disable(struct ccu_common *common, u32 gate) spin_lock_irqsave(common->lock, flags); reg = readl(common->base + common->reg); + if (common->features & CCU_FEATURE_UPDATE_BIT) + reg |= CCU_SUNXI_UPDATE_BIT; writel(reg & ~gate, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); @@ -44,6 +46,8 @@ int ccu_gate_helper_enable(struct ccu_common *common, u32 gate) spin_lock_irqsave(common->lock, flags); reg = readl(common->base + common->reg); + if (common->features & CCU_FEATURE_UPDATE_BIT) + reg |= CCU_SUNXI_UPDATE_BIT; writel(reg | gate, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index d7ffbdeee9e0..74f9e98a5d35 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c @@ -197,6 +197,8 @@ int ccu_mux_helper_set_parent(struct ccu_common *common, /* The key field always reads as zero. */ if (common->features & CCU_FEATURE_KEY_FIELD) reg |= CCU_MUX_KEY_VALUE; + if (common->features & CCU_FEATURE_UPDATE_BIT) + reg |= CCU_SUNXI_UPDATE_BIT; reg &= ~GENMASK(cm->width + cm->shift - 1, cm->shift); writel(reg | (index << cm->shift), common->base + common->reg); From 52dbf84857f051df38f6de3f0c7b7f4506e7ad25 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:18 +0000 Subject: [PATCH 36/63] dt-bindings: clk: sunxi-ng: document two Allwinner A523 CCUs The Allwinner A523/T527 SoCs have four CCUs, this adds the binding for the main and the PRCM R-CCU. The source clock list differs in some annoying details, and folding this into the existing Allwinner CCU clock binding document gets quite unwieldy, so create a new document for these CCUs. Add the new compatible string, along with the required input clock lists. This conditionally describes the input clock lists, to make adding support for the other two CCUs easier. Also add the DT binding headers, listing all the clocks with their ID numbers. Signed-off-by: Andre Przywara Reviewed-by: Rob Herring (Arm) Link: https://patch.msgid.link/20250307002628.10684-5-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- .../clock/allwinner,sun55i-a523-ccu.yaml | 103 ++++++++++ include/dt-bindings/clock/sun55i-a523-ccu.h | 189 ++++++++++++++++++ include/dt-bindings/clock/sun55i-a523-r-ccu.h | 37 ++++ include/dt-bindings/reset/sun55i-a523-ccu.h | 88 ++++++++ include/dt-bindings/reset/sun55i-a523-r-ccu.h | 25 +++ 5 files changed, 442 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/allwinner,sun55i-a523-ccu.yaml create mode 100644 include/dt-bindings/clock/sun55i-a523-ccu.h create mode 100644 include/dt-bindings/clock/sun55i-a523-r-ccu.h create mode 100644 include/dt-bindings/reset/sun55i-a523-ccu.h create mode 100644 include/dt-bindings/reset/sun55i-a523-r-ccu.h diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun55i-a523-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun55i-a523-ccu.yaml new file mode 100644 index 000000000000..f5f62e9a10a1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/allwinner,sun55i-a523-ccu.yaml @@ -0,0 +1,103 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/allwinner,sun55i-a523-ccu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Allwinner A523 Clock Control Unit + +maintainers: + - Andre Przywara + +properties: + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + compatible: + enum: + - allwinner,sun55i-a523-ccu + - allwinner,sun55i-a523-r-ccu + + reg: + maxItems: 1 + + clocks: + minItems: 4 + maxItems: 5 + + clock-names: + minItems: 4 + maxItems: 5 + +required: + - "#clock-cells" + - "#reset-cells" + - compatible + - reg + - clocks + - clock-names + +allOf: + - if: + properties: + compatible: + enum: + - allwinner,sun55i-a523-ccu + + then: + properties: + clocks: + items: + - description: High Frequency Oscillator (usually at 24MHz) + - description: Low Frequency Oscillator (usually at 32kHz) + - description: Internal Oscillator + - description: Low Frequency Oscillator fanout + + clock-names: + items: + - const: hosc + - const: losc + - const: iosc + - const: losc-fanout + + - if: + properties: + compatible: + enum: + - allwinner,sun55i-a523-r-ccu + + then: + properties: + clocks: + items: + - description: High Frequency Oscillator (usually at 24MHz) + - description: Low Frequency Oscillator (usually at 32kHz) + - description: Internal Oscillator + - description: Peripherals PLL + - description: Audio PLL + + clock-names: + items: + - const: hosc + - const: losc + - const: iosc + - const: pll-periph + - const: pll-audio + +additionalProperties: false + +examples: + - | + clock-controller@2001000 { + compatible = "allwinner,sun55i-a523-ccu"; + reg = <0x02001000 0x1000>; + clocks = <&osc24M>, <&osc32k>, <&iosc>, <&r_ccu 1>; + clock-names = "hosc", "losc", "iosc", "losc-fanout"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + +... diff --git a/include/dt-bindings/clock/sun55i-a523-ccu.h b/include/dt-bindings/clock/sun55i-a523-ccu.h new file mode 100644 index 000000000000..c8259ac5ada7 --- /dev/null +++ b/include/dt-bindings/clock/sun55i-a523-ccu.h @@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024 Arm Ltd. + */ + +#ifndef _DT_BINDINGS_CLK_SUN55I_A523_CCU_H_ +#define _DT_BINDINGS_CLK_SUN55I_A523_CCU_H_ + +#define CLK_PLL_DDR0 0 +#define CLK_PLL_PERIPH0_4X 1 +#define CLK_PLL_PERIPH0_2X 2 +#define CLK_PLL_PERIPH0_800M 3 +#define CLK_PLL_PERIPH0_480M 4 +#define CLK_PLL_PERIPH0_600M 5 +#define CLK_PLL_PERIPH0_400M 6 +#define CLK_PLL_PERIPH0_300M 7 +#define CLK_PLL_PERIPH0_200M 8 +#define CLK_PLL_PERIPH0_160M 9 +#define CLK_PLL_PERIPH0_150M 10 +#define CLK_PLL_PERIPH1_4X 11 +#define CLK_PLL_PERIPH1_2X 12 +#define CLK_PLL_PERIPH1_800M 13 +#define CLK_PLL_PERIPH1_480M 14 +#define CLK_PLL_PERIPH1_600M 15 +#define CLK_PLL_PERIPH1_400M 16 +#define CLK_PLL_PERIPH1_300M 17 +#define CLK_PLL_PERIPH1_200M 18 +#define CLK_PLL_PERIPH1_160M 19 +#define CLK_PLL_PERIPH1_150M 20 +#define CLK_PLL_GPU 21 +#define CLK_PLL_VIDEO0_8X 22 +#define CLK_PLL_VIDEO0_4X 23 +#define CLK_PLL_VIDEO0_3X 24 +#define CLK_PLL_VIDEO1_8X 25 +#define CLK_PLL_VIDEO1_4X 26 +#define CLK_PLL_VIDEO1_3X 27 +#define CLK_PLL_VIDEO2_8X 28 +#define CLK_PLL_VIDEO2_4X 29 +#define CLK_PLL_VIDEO2_3X 30 +#define CLK_PLL_VIDEO3_8X 31 +#define CLK_PLL_VIDEO3_4X 32 +#define CLK_PLL_VIDEO3_3X 33 +#define CLK_PLL_VE 34 +#define CLK_PLL_AUDIO0_4X 35 +#define CLK_PLL_AUDIO0_2X 36 +#define CLK_PLL_AUDIO0 37 +#define CLK_PLL_NPU_4X 38 +#define CLK_PLL_NPU_2X 39 +#define CLK_PLL_NPU 40 +#define CLK_AHB 41 +#define CLK_APB0 42 +#define CLK_APB1 43 +#define CLK_MBUS 44 +#define CLK_DE 45 +#define CLK_BUS_DE 46 +#define CLK_DI 47 +#define CLK_BUS_DI 48 +#define CLK_G2D 49 +#define CLK_BUS_G2D 50 +#define CLK_GPU 51 +#define CLK_BUS_GPU 52 +#define CLK_CE 53 +#define CLK_BUS_CE 54 +#define CLK_BUS_CE_SYS 55 +#define CLK_VE 56 +#define CLK_BUS_VE 57 +#define CLK_BUS_DMA 58 +#define CLK_BUS_MSGBOX 59 +#define CLK_BUS_SPINLOCK 60 +#define CLK_HSTIMER0 61 +#define CLK_HSTIMER1 62 +#define CLK_HSTIMER2 63 +#define CLK_HSTIMER3 64 +#define CLK_HSTIMER4 65 +#define CLK_HSTIMER5 66 +#define CLK_BUS_HSTIMER 67 +#define CLK_BUS_DBG 68 +#define CLK_BUS_PWM0 69 +#define CLK_BUS_PWM1 70 +#define CLK_IOMMU 71 +#define CLK_BUS_IOMMU 72 +#define CLK_DRAM 73 +#define CLK_MBUS_DMA 74 +#define CLK_MBUS_VE 75 +#define CLK_MBUS_CE 76 +#define CLK_MBUS_CSI 77 +#define CLK_MBUS_ISP 78 +#define CLK_MBUS_EMAC1 79 +#define CLK_BUS_DRAM 80 +#define CLK_NAND0 81 +#define CLK_NAND1 82 +#define CLK_BUS_NAND 83 +#define CLK_MMC0 84 +#define CLK_MMC1 85 +#define CLK_MMC2 86 +#define CLK_BUS_SYSDAP 87 +#define CLK_BUS_MMC0 88 +#define CLK_BUS_MMC1 89 +#define CLK_BUS_MMC2 90 +#define CLK_BUS_UART0 91 +#define CLK_BUS_UART1 92 +#define CLK_BUS_UART2 93 +#define CLK_BUS_UART3 94 +#define CLK_BUS_UART4 95 +#define CLK_BUS_UART5 96 +#define CLK_BUS_UART6 97 +#define CLK_BUS_UART7 98 +#define CLK_BUS_I2C0 99 +#define CLK_BUS_I2C1 100 +#define CLK_BUS_I2C2 101 +#define CLK_BUS_I2C3 102 +#define CLK_BUS_I2C4 103 +#define CLK_BUS_I2C5 104 +#define CLK_BUS_CAN 105 +#define CLK_SPI0 106 +#define CLK_SPI1 107 +#define CLK_SPI2 108 +#define CLK_SPIFC 109 +#define CLK_BUS_SPI0 110 +#define CLK_BUS_SPI1 111 +#define CLK_BUS_SPI2 112 +#define CLK_BUS_SPIFC 113 +#define CLK_EMAC0_25M 114 +#define CLK_EMAC1_25M 115 +#define CLK_BUS_EMAC0 116 +#define CLK_BUS_EMAC1 117 +#define CLK_IR_RX 118 +#define CLK_BUS_IR_RX 119 +#define CLK_IR_TX 120 +#define CLK_BUS_IR_TX 121 +#define CLK_GPADC0 122 +#define CLK_GPADC1 123 +#define CLK_BUS_GPADC0 124 +#define CLK_BUS_GPADC1 125 +#define CLK_BUS_THS 126 +#define CLK_USB_OHCI0 127 +#define CLK_USB_OHCI1 128 +#define CLK_BUS_OHCI0 129 +#define CLK_BUS_OHCI1 130 +#define CLK_BUS_EHCI0 131 +#define CLK_BUS_EHCI1 132 +#define CLK_BUS_OTG 133 +#define CLK_BUS_LRADC 134 +#define CLK_PCIE_AUX 135 +#define CLK_BUS_DISPLAY0_TOP 136 +#define CLK_BUS_DISPLAY1_TOP 137 +#define CLK_HDMI_24M 138 +#define CLK_HDMI_CEC_32K 139 +#define CLK_HDMI_CEC 140 +#define CLK_BUS_HDMI 141 +#define CLK_MIPI_DSI0 142 +#define CLK_MIPI_DSI1 143 +#define CLK_BUS_MIPI_DSI0 144 +#define CLK_BUS_MIPI_DSI1 145 +#define CLK_TCON_LCD0 146 +#define CLK_TCON_LCD1 147 +#define CLK_TCON_LCD2 148 +#define CLK_COMBOPHY_DSI0 149 +#define CLK_COMBOPHY_DSI1 150 +#define CLK_BUS_TCON_LCD0 151 +#define CLK_BUS_TCON_LCD1 152 +#define CLK_BUS_TCON_LCD2 153 +#define CLK_TCON_TV0 154 +#define CLK_TCON_TV1 155 +#define CLK_BUS_TCON_TV0 156 +#define CLK_BUS_TCON_TV1 157 +#define CLK_EDP 158 +#define CLK_BUS_EDP 159 +#define CLK_LEDC 160 +#define CLK_BUS_LEDC 161 +#define CLK_CSI_TOP 162 +#define CLK_CSI_MCLK0 163 +#define CLK_CSI_MCLK1 164 +#define CLK_CSI_MCLK2 165 +#define CLK_CSI_MCLK3 166 +#define CLK_BUS_CSI 167 +#define CLK_ISP 168 +#define CLK_DSP 169 +#define CLK_FANOUT_24M 170 +#define CLK_FANOUT_12M 171 +#define CLK_FANOUT_16M 172 +#define CLK_FANOUT_25M 173 +#define CLK_FANOUT_27M 174 +#define CLK_FANOUT_PCLK 175 +#define CLK_FANOUT0 176 +#define CLK_FANOUT1 177 +#define CLK_FANOUT2 178 + +#endif /* _DT_BINDINGS_CLK_SUN55I_A523_CCU_H_ */ diff --git a/include/dt-bindings/clock/sun55i-a523-r-ccu.h b/include/dt-bindings/clock/sun55i-a523-r-ccu.h new file mode 100644 index 000000000000..365647499b9a --- /dev/null +++ b/include/dt-bindings/clock/sun55i-a523-r-ccu.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024 Arm Ltd. + */ + +#ifndef _DT_BINDINGS_CLK_SUN55I_A523_R_CCU_H_ +#define _DT_BINDINGS_CLK_SUN55I_A523_R_CCU_H_ + +#define CLK_R_AHB 0 +#define CLK_R_APB0 1 +#define CLK_R_APB1 2 +#define CLK_R_TIMER0 3 +#define CLK_R_TIMER1 4 +#define CLK_R_TIMER2 5 +#define CLK_BUS_R_TIMER 6 +#define CLK_BUS_R_TWD 7 +#define CLK_R_PWMCTRL 8 +#define CLK_BUS_R_PWMCTRL 9 +#define CLK_R_SPI 10 +#define CLK_BUS_R_SPI 11 +#define CLK_BUS_R_SPINLOCK 12 +#define CLK_BUS_R_MSGBOX 13 +#define CLK_BUS_R_UART0 14 +#define CLK_BUS_R_UART1 15 +#define CLK_BUS_R_I2C0 16 +#define CLK_BUS_R_I2C1 17 +#define CLK_BUS_R_I2C2 18 +#define CLK_BUS_R_PPU0 19 +#define CLK_BUS_R_PPU1 20 +#define CLK_BUS_R_CPU_BIST 21 +#define CLK_R_IR_RX 22 +#define CLK_BUS_R_IR_RX 23 +#define CLK_BUS_R_DMA 24 +#define CLK_BUS_R_RTC 25 +#define CLK_BUS_R_CPUCFG 26 + +#endif /* _DT_BINDINGS_CLK_SUN55I_A523_R_CCU_H_ */ diff --git a/include/dt-bindings/reset/sun55i-a523-ccu.h b/include/dt-bindings/reset/sun55i-a523-ccu.h new file mode 100644 index 000000000000..70df503f34fe --- /dev/null +++ b/include/dt-bindings/reset/sun55i-a523-ccu.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2024 Arm Ltd. + */ + +#ifndef _DT_BINDINGS_RST_SUN55I_A523_CCU_H_ +#define _DT_BINDINGS_RST_SUN55I_A523_CCU_H_ + +#define RST_MBUS 0 +#define RST_BUS_NSI 1 +#define RST_BUS_DE 2 +#define RST_BUS_DI 3 +#define RST_BUS_G2D 4 +#define RST_BUS_SYS 5 +#define RST_BUS_GPU 6 +#define RST_BUS_CE 7 +#define RST_BUS_SYS_CE 8 +#define RST_BUS_VE 9 +#define RST_BUS_DMA 10 +#define RST_BUS_MSGBOX 11 +#define RST_BUS_SPINLOCK 12 +#define RST_BUS_CPUXTIMER 13 +#define RST_BUS_DBG 14 +#define RST_BUS_PWM0 15 +#define RST_BUS_PWM1 16 +#define RST_BUS_DRAM 17 +#define RST_BUS_NAND 18 +#define RST_BUS_MMC0 19 +#define RST_BUS_MMC1 20 +#define RST_BUS_MMC2 21 +#define RST_BUS_SYSDAP 22 +#define RST_BUS_UART0 23 +#define RST_BUS_UART1 24 +#define RST_BUS_UART2 25 +#define RST_BUS_UART3 26 +#define RST_BUS_UART4 27 +#define RST_BUS_UART5 28 +#define RST_BUS_UART6 29 +#define RST_BUS_UART7 30 +#define RST_BUS_I2C0 31 +#define RST_BUS_I2C1 32 +#define RST_BUS_I2C2 33 +#define RST_BUS_I2C3 34 +#define RST_BUS_I2C4 35 +#define RST_BUS_I2C5 36 +#define RST_BUS_CAN 37 +#define RST_BUS_SPI0 38 +#define RST_BUS_SPI1 39 +#define RST_BUS_SPI2 40 +#define RST_BUS_SPIFC 41 +#define RST_BUS_EMAC0 42 +#define RST_BUS_EMAC1 43 +#define RST_BUS_IR_RX 44 +#define RST_BUS_IR_TX 45 +#define RST_BUS_GPADC0 46 +#define RST_BUS_GPADC1 47 +#define RST_BUS_THS 48 +#define RST_USB_PHY0 49 +#define RST_USB_PHY1 50 +#define RST_BUS_OHCI0 51 +#define RST_BUS_OHCI1 52 +#define RST_BUS_EHCI0 53 +#define RST_BUS_EHCI1 54 +#define RST_BUS_OTG 55 +#define RST_BUS_3 56 +#define RST_BUS_LRADC 57 +#define RST_BUS_PCIE_USB3 58 +#define RST_BUS_DISPLAY0_TOP 59 +#define RST_BUS_DISPLAY1_TOP 60 +#define RST_BUS_HDMI_MAIN 61 +#define RST_BUS_HDMI_SUB 62 +#define RST_BUS_MIPI_DSI0 63 +#define RST_BUS_MIPI_DSI1 64 +#define RST_BUS_TCON_LCD0 65 +#define RST_BUS_TCON_LCD1 66 +#define RST_BUS_TCON_LCD2 67 +#define RST_BUS_TCON_TV0 68 +#define RST_BUS_TCON_TV1 69 +#define RST_BUS_LVDS0 70 +#define RST_BUS_LVDS1 71 +#define RST_BUS_EDP 72 +#define RST_BUS_VIDEO_OUT0 73 +#define RST_BUS_VIDEO_OUT1 74 +#define RST_BUS_LEDC 75 +#define RST_BUS_CSI 76 +#define RST_BUS_ISP 77 + +#endif /* _DT_BINDINGS_RST_SUN55I_A523_CCU_H_ */ diff --git a/include/dt-bindings/reset/sun55i-a523-r-ccu.h b/include/dt-bindings/reset/sun55i-a523-r-ccu.h new file mode 100644 index 000000000000..dd6fbb372e19 --- /dev/null +++ b/include/dt-bindings/reset/sun55i-a523-r-ccu.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024 Arm Ltd. + */ + +#ifndef _DT_BINDINGS_RST_SUN55I_A523_R_CCU_H_ +#define _DT_BINDINGS_RST_SUN55I_A523_R_CCU_H_ + +#define RST_BUS_R_TIMER 0 +#define RST_BUS_R_TWD 1 +#define RST_BUS_R_PWMCTRL 2 +#define RST_BUS_R_SPI 3 +#define RST_BUS_R_SPINLOCK 4 +#define RST_BUS_R_MSGBOX 5 +#define RST_BUS_R_UART0 6 +#define RST_BUS_R_UART1 7 +#define RST_BUS_R_I2C0 8 +#define RST_BUS_R_I2C1 9 +#define RST_BUS_R_I2C2 10 +#define RST_BUS_R_PPU1 11 +#define RST_BUS_R_IR_RX 12 +#define RST_BUS_R_RTC 13 +#define RST_BUS_R_CPUCFG 14 + +#endif /* _DT_BINDINGS_RST_SUN55I_A523_R_CCU_H_ */ From 7cae1e2b5544a6f51972458ec4360c7717ca0145 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:19 +0000 Subject: [PATCH 37/63] clk: sunxi-ng: Add support for the A523/T527 CCU PLLs Add the PLL clocks of the main CCU of the Allwinner A523 and T527 SoCs. The clocks were modelled after the A523 and T527 manual, and double checked by writing all 1's into the respective register, to spot all implemented bits. The PLL and mod clocks for the two CPU clusters and the DSU are part of a separate CCU, also most audio clocks are collected in a DSP CCU, so both of these clock groups are missing from this driver. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-6-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/Kconfig | 5 + drivers/clk/sunxi-ng/Makefile | 2 + drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 481 +++++++++++++++++++++++++ drivers/clk/sunxi-ng/ccu-sun55i-a523.h | 14 + 4 files changed, 502 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu-sun55i-a523.c create mode 100644 drivers/clk/sunxi-ng/ccu-sun55i-a523.h diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index b547198a2c65..04efbda847cf 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -52,6 +52,11 @@ config SUN50I_H6_R_CCU default y depends on ARM64 || COMPILE_TEST +config SUN55I_A523_CCU + tristate "Support for the Allwinner A523/T527 CCU" + default y + depends on ARM64 || COMPILE_TEST + config SUN4I_A10_CCU tristate "Support for the Allwinner A10/A20 CCU" default y diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 6b3ae2b620db..01a887f7824b 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU) += sun50i-a100-r-ccu.o obj-$(CONFIG_SUN50I_H6_CCU) += sun50i-h6-ccu.o obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o +obj-$(CONFIG_SUN55I_A523_CCU) += sun55i-a523-ccu.o obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o obj-$(CONFIG_SUN6I_A31_CCU) += sun6i-a31-ccu.o @@ -58,6 +59,7 @@ sun50i-a100-r-ccu-y += ccu-sun50i-a100-r.o sun50i-h6-ccu-y += ccu-sun50i-h6.o sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o sun50i-h616-ccu-y += ccu-sun50i-h616.o +sun55i-a523-ccu-y += ccu-sun55i-a523.o sun4i-a10-ccu-y += ccu-sun4i-a10.o sun5i-ccu-y += ccu-sun5i.o sun6i-a31-ccu-y += ccu-sun6i-a31.o diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c new file mode 100644 index 000000000000..455bca0c344b --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023-2024 Arm Ltd. + * Based on the D1 CCU driver: + * Copyright (c) 2020 huangzhenwei@allwinnertech.com + * Copyright (C) 2021 Samuel Holland + */ + +#include +#include +#include +#include + +#include "../clk.h" + +#include "ccu_common.h" +#include "ccu_reset.h" + +#include "ccu_div.h" +#include "ccu_gate.h" +#include "ccu_mp.h" +#include "ccu_mult.h" +#include "ccu_nk.h" +#include "ccu_nkm.h" +#include "ccu_nkmp.h" +#include "ccu_nm.h" + +#include "ccu-sun55i-a523.h" + +/* + * The 24 MHz oscillator, the root of most of the clock tree. + * .fw_name is the string used in the DT "clock-names" property, used to + * identify the corresponding clock in the "clocks" property. + */ +static const struct clk_parent_data osc24M[] = { + { .fw_name = "hosc" } +}; + +/************************************************************************** + * PLLs * + **************************************************************************/ + +/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */ +#define SUN55I_A523_PLL_DDR0_REG 0x010 +static struct ccu_nkmp pll_ddr_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x010, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-ddr0", osc24M, + &ccu_nkmp_ops, + CLK_SET_RATE_GATE | + CLK_IS_CRITICAL), + }, +}; + +/* + * There is no actual clock output with that frequency (2.4 GHz), instead it + * has multiple outputs with adjustable dividers from that base frequency. + * Model them separately as divider clocks based on that parent here. + */ +#define SUN55I_A523_PLL_PERIPH0_REG 0x020 +static struct ccu_nm pll_periph0_4x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x020, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-periph0-4x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; +/* + * Most clock-defining macros expect an *array* of parent clocks, even if + * they do not contain a muxer to select between different parents. + * The macros ending in just _HW take a simple clock pointer, but then create + * a single-entry array out of that. The macros using _HWS take such an + * array (even when it is a single entry one), this avoids having those + * helper arrays created inside *every* clock definition. + * This means for every clock that is referenced more than once it is + * useful to create such a dummy array and use _HWS. + */ +static const struct clk_hw *pll_periph0_4x_hws[] = { + &pll_periph0_4x_clk.common.hw +}; + +static SUNXI_CCU_M_HWS(pll_periph0_2x_clk, "pll-periph0-2x", + pll_periph0_4x_hws, 0x020, 16, 3, 0); +static const struct clk_hw *pll_periph0_2x_hws[] = { + &pll_periph0_2x_clk.common.hw +}; +static SUNXI_CCU_M_HWS(pll_periph0_800M_clk, "pll-periph0-800M", + pll_periph0_4x_hws, 0x020, 20, 3, 0); +static SUNXI_CCU_M_HWS(pll_periph0_480M_clk, "pll-periph0-480M", + pll_periph0_4x_hws, 0x020, 2, 3, 0); +static const struct clk_hw *pll_periph0_480M_hws[] = { + &pll_periph0_480M_clk.common.hw +}; +static CLK_FIXED_FACTOR_HWS(pll_periph0_600M_clk, "pll-periph0-600M", + pll_periph0_2x_hws, 2, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph0_400M_clk, "pll-periph0-400M", + pll_periph0_2x_hws, 3, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph0_300M_clk, "pll-periph0-300M", + pll_periph0_2x_hws, 4, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph0_200M_clk, "pll-periph0-200M", + pll_periph0_2x_hws, 6, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph0_150M_clk, "pll-periph0-150M", + pll_periph0_2x_hws, 8, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph0_160M_clk, "pll-periph0-160M", + pll_periph0_480M_hws, 3, 1, 0); + +#define SUN55I_A523_PLL_PERIPH1_REG 0x028 +static struct ccu_nm pll_periph1_4x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x028, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-periph1-4x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; + +static const struct clk_hw *pll_periph1_4x_hws[] = { + &pll_periph1_4x_clk.common.hw +}; +static SUNXI_CCU_M_HWS(pll_periph1_2x_clk, "pll-periph1-2x", + pll_periph1_4x_hws, 0x028, 16, 3, 0); +static SUNXI_CCU_M_HWS(pll_periph1_800M_clk, "pll-periph1-800M", + pll_periph1_4x_hws, 0x028, 20, 3, 0); +static SUNXI_CCU_M_HWS(pll_periph1_480M_clk, "pll-periph1-480M", + pll_periph1_4x_hws, 0x028, 2, 3, 0); + +static const struct clk_hw *pll_periph1_2x_hws[] = { + &pll_periph1_2x_clk.common.hw +}; +static CLK_FIXED_FACTOR_HWS(pll_periph1_600M_clk, "pll-periph1-600M", + pll_periph1_2x_hws, 2, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph1_400M_clk, "pll-periph1-400M", + pll_periph1_2x_hws, 3, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph1_300M_clk, "pll-periph1-300M", + pll_periph1_2x_hws, 4, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph1_200M_clk, "pll-periph1-200M", + pll_periph1_2x_hws, 6, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_periph1_150M_clk, "pll-periph1-150M", + pll_periph1_2x_hws, 8, 1, 0); +static const struct clk_hw *pll_periph1_480M_hws[] = { + &pll_periph1_480M_clk.common.hw +}; +static CLK_FIXED_FACTOR_HWS(pll_periph1_160M_clk, "pll-periph1-160M", + pll_periph1_480M_hws, 3, 1, 0); + +#define SUN55I_A523_PLL_GPU_REG 0x030 +static struct ccu_nkmp pll_gpu_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x030, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-gpu", osc24M, + &ccu_nkmp_ops, + CLK_SET_RATE_GATE), + }, +}; + +#define SUN55I_A523_PLL_VIDEO0_REG 0x040 +static struct ccu_nm pll_video0_8x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x040, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-video0-8x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; + +static const struct clk_hw *pll_video0_8x_hws[] = { + &pll_video0_8x_clk.common.hw +}; +static SUNXI_CCU_M_HWS(pll_video0_4x_clk, "pll-video0-4x", + pll_video0_8x_hws, 0x040, 0, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_video0_3x_clk, "pll-video0-3x", + pll_video0_8x_hws, 3, 1, CLK_SET_RATE_PARENT); + +#define SUN55I_A523_PLL_VIDEO1_REG 0x048 +static struct ccu_nm pll_video1_8x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x048, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-video1-8x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; + +static const struct clk_hw *pll_video1_8x_hws[] = { + &pll_video1_8x_clk.common.hw +}; +static SUNXI_CCU_M_HWS(pll_video1_4x_clk, "pll-video1-4x", + pll_video1_8x_hws, 0x048, 0, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_video1_3x_clk, "pll-video1-3x", + pll_video1_8x_hws, 3, 1, CLK_SET_RATE_PARENT); + +#define SUN55I_A523_PLL_VIDEO2_REG 0x050 +static struct ccu_nm pll_video2_8x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x050, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-video2-8x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; + +static const struct clk_hw *pll_video2_8x_hws[] = { + &pll_video2_8x_clk.common.hw +}; +static SUNXI_CCU_M_HWS(pll_video2_4x_clk, "pll-video2-4x", + pll_video2_8x_hws, 0x050, 0, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_video2_3x_clk, "pll-video2-3x", + pll_video2_8x_hws, 3, 1, CLK_SET_RATE_PARENT); + +#define SUN55I_A523_PLL_VE_REG 0x058 +static struct ccu_nkmp pll_ve_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ + .common = { + .reg = 0x058, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-ve", osc24M, + &ccu_nkmp_ops, + CLK_SET_RATE_GATE), + }, +}; + +#define SUN55I_A523_PLL_VIDEO3_REG 0x068 +static struct ccu_nm pll_video3_8x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x068, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-video3-8x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; + +static const struct clk_hw *pll_video3_8x_hws[] = { + &pll_video3_8x_clk.common.hw +}; +static SUNXI_CCU_M_HWS(pll_video3_4x_clk, "pll-video3-4x", + pll_video3_8x_hws, 0x068, 0, 1, 0); +static CLK_FIXED_FACTOR_HWS(pll_video3_3x_clk, "pll-video3-3x", + pll_video3_8x_hws, 3, 1, CLK_SET_RATE_PARENT); + +/* + * PLL_AUDIO0 has m0, m1 dividers in addition to the usual N, M factors. + * Since we only need some fixed frequency from this PLL (22.5792MHz x 4 and + * 24.576MHz x 4), ignore those dividers and force both of them to 1 (encoded + * as 0), in the probe function below. + * The M factor must be an even number to produce a 50% duty cycle output. + */ +#define SUN55I_A523_PLL_AUDIO0_REG 0x078 +static struct ccu_sdm_setting pll_audio0_sdm_table[] = { + { .rate = 90316800, .pattern = 0xc000872b, .m = 20, .n = 75 }, + { .rate = 98304000, .pattern = 0xc0004dd3, .m = 12, .n = 49 }, + +}; + +static struct ccu_nm pll_audio0_4x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(16, 6), + .sdm = _SUNXI_CCU_SDM(pll_audio0_sdm_table, BIT(24), + 0x178, BIT(31)), + .min_rate = 180000000U, + .max_rate = 3000000000U, + .common = { + .reg = 0x078, + .features = CCU_FEATURE_SIGMA_DELTA_MOD, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-audio0-4x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; + +static CLK_FIXED_FACTOR_HW(pll_audio0_2x_clk, "pll-audio0-2x", + &pll_audio0_4x_clk.common.hw, 2, 1, 0); +static CLK_FIXED_FACTOR_HW(pll_audio0_clk, "pll-audio0", + &pll_audio0_4x_clk.common.hw, 4, 1, 0); + +#define SUN55I_A523_PLL_NPU_REG 0x080 +static struct ccu_nm pll_npu_4x_clk = { + .enable = BIT(27), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT_MIN(8, 8, 11), + .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ + .common = { + .reg = 0x0080, + .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-npu-4x", + osc24M, &ccu_nm_ops, + CLK_SET_RATE_GATE), + }, +}; +static CLK_FIXED_FACTOR_HW(pll_npu_2x_clk, "pll-npu-2x", + &pll_npu_4x_clk.common.hw, 2, 1, CLK_SET_RATE_PARENT); + +static CLK_FIXED_FACTOR_HW(pll_npu_1x_clk, "pll-npu-1x", + &pll_npu_4x_clk.common.hw, 4, 1, 0); + +/* + * Contains all clocks that are controlled by a hardware register. They + * have a (sunxi) .common member, which needs to be initialised by the common + * sunxi CCU code, to be filled with the MMIO base address and the shared lock. + */ +static struct ccu_common *sun55i_a523_ccu_clks[] = { + &pll_ddr_clk.common, + &pll_periph0_4x_clk.common, + &pll_periph0_2x_clk.common, + &pll_periph0_800M_clk.common, + &pll_periph0_480M_clk.common, + &pll_periph1_4x_clk.common, + &pll_periph1_2x_clk.common, + &pll_periph1_800M_clk.common, + &pll_periph1_480M_clk.common, + &pll_gpu_clk.common, + &pll_video0_8x_clk.common, + &pll_video0_4x_clk.common, + &pll_video1_8x_clk.common, + &pll_video1_4x_clk.common, + &pll_video2_8x_clk.common, + &pll_video2_4x_clk.common, + &pll_video3_8x_clk.common, + &pll_video3_4x_clk.common, + &pll_ve_clk.common, + &pll_audio0_4x_clk.common, + &pll_npu_4x_clk.common, +}; + +static struct clk_hw_onecell_data sun55i_a523_hw_clks = { + .num = CLK_NUMBER, + .hws = { + [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw, + [CLK_PLL_PERIPH0_4X] = &pll_periph0_4x_clk.common.hw, + [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.common.hw, + [CLK_PLL_PERIPH0_800M] = &pll_periph0_800M_clk.common.hw, + [CLK_PLL_PERIPH0_480M] = &pll_periph0_480M_clk.common.hw, + [CLK_PLL_PERIPH0_600M] = &pll_periph0_600M_clk.hw, + [CLK_PLL_PERIPH0_400M] = &pll_periph0_400M_clk.hw, + [CLK_PLL_PERIPH0_300M] = &pll_periph0_300M_clk.hw, + [CLK_PLL_PERIPH0_200M] = &pll_periph0_200M_clk.hw, + [CLK_PLL_PERIPH0_160M] = &pll_periph0_160M_clk.hw, + [CLK_PLL_PERIPH0_150M] = &pll_periph0_150M_clk.hw, + [CLK_PLL_PERIPH1_4X] = &pll_periph1_4x_clk.common.hw, + [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.common.hw, + [CLK_PLL_PERIPH1_800M] = &pll_periph1_800M_clk.common.hw, + [CLK_PLL_PERIPH1_480M] = &pll_periph1_480M_clk.common.hw, + [CLK_PLL_PERIPH1_600M] = &pll_periph1_600M_clk.hw, + [CLK_PLL_PERIPH1_400M] = &pll_periph1_400M_clk.hw, + [CLK_PLL_PERIPH1_300M] = &pll_periph1_300M_clk.hw, + [CLK_PLL_PERIPH1_200M] = &pll_periph1_200M_clk.hw, + [CLK_PLL_PERIPH1_160M] = &pll_periph1_160M_clk.hw, + [CLK_PLL_PERIPH1_150M] = &pll_periph1_150M_clk.hw, + [CLK_PLL_VIDEO0_8X] = &pll_video0_8x_clk.common.hw, + [CLK_PLL_VIDEO0_4X] = &pll_video0_4x_clk.common.hw, + [CLK_PLL_VIDEO0_3X] = &pll_video0_3x_clk.hw, + [CLK_PLL_VIDEO1_8X] = &pll_video1_8x_clk.common.hw, + [CLK_PLL_VIDEO1_4X] = &pll_video1_4x_clk.common.hw, + [CLK_PLL_VIDEO1_3X] = &pll_video1_3x_clk.hw, + [CLK_PLL_VIDEO2_8X] = &pll_video2_8x_clk.common.hw, + [CLK_PLL_VIDEO2_4X] = &pll_video2_4x_clk.common.hw, + [CLK_PLL_VIDEO2_3X] = &pll_video2_3x_clk.hw, + [CLK_PLL_VIDEO3_8X] = &pll_video3_8x_clk.common.hw, + [CLK_PLL_VIDEO3_4X] = &pll_video3_4x_clk.common.hw, + [CLK_PLL_VIDEO3_3X] = &pll_video3_3x_clk.hw, + [CLK_PLL_VE] = &pll_ve_clk.common.hw, + [CLK_PLL_AUDIO0_4X] = &pll_audio0_4x_clk.common.hw, + [CLK_PLL_AUDIO0_2X] = &pll_audio0_2x_clk.hw, + [CLK_PLL_AUDIO0] = &pll_audio0_clk.hw, + [CLK_PLL_NPU_4X] = &pll_npu_4x_clk.common.hw, + [CLK_PLL_NPU_2X] = &pll_npu_2x_clk.hw, + [CLK_PLL_NPU] = &pll_npu_1x_clk.hw, + }, +}; + +static const struct sunxi_ccu_desc sun55i_a523_ccu_desc = { + .ccu_clks = sun55i_a523_ccu_clks, + .num_ccu_clks = ARRAY_SIZE(sun55i_a523_ccu_clks), + + .hw_clks = &sun55i_a523_hw_clks, +}; + +static const u32 pll_regs[] = { + SUN55I_A523_PLL_DDR0_REG, + SUN55I_A523_PLL_PERIPH0_REG, + SUN55I_A523_PLL_PERIPH1_REG, + SUN55I_A523_PLL_GPU_REG, + SUN55I_A523_PLL_VIDEO0_REG, + SUN55I_A523_PLL_VIDEO1_REG, + SUN55I_A523_PLL_VIDEO2_REG, + SUN55I_A523_PLL_VE_REG, + SUN55I_A523_PLL_VIDEO3_REG, + SUN55I_A523_PLL_AUDIO0_REG, + SUN55I_A523_PLL_NPU_REG, +}; + +static int sun55i_a523_ccu_probe(struct platform_device *pdev) +{ + void __iomem *reg; + u32 val; + int i, ret; + + reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + /* + * The PLL clock code does not model all bits, for instance it does + * not support a separate enable and gate bit. We present the + * gate bit(27) as the enable bit, but then have to set the + * PLL Enable, LDO Enable, and Lock Enable bits on all PLLs here. + */ + for (i = 0; i < ARRAY_SIZE(pll_regs); i++) { + val = readl(reg + pll_regs[i]); + val |= BIT(31) | BIT(30) | BIT(29); + writel(val, reg + pll_regs[i]); + } + + /* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */ + val = readl(reg + SUN55I_A523_PLL_AUDIO0_REG); + val &= ~(BIT(1) | BIT(0)); + writel(val, reg + SUN55I_A523_PLL_AUDIO0_REG); + + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun55i_a523_ccu_desc); + if (ret) + return ret; + + return 0; +} + +static const struct of_device_id sun55i_a523_ccu_ids[] = { + { .compatible = "allwinner,sun55i-a523-ccu" }, + { } +}; + +static struct platform_driver sun55i_a523_ccu_driver = { + .probe = sun55i_a523_ccu_probe, + .driver = { + .name = "sun55i-a523-ccu", + .suppress_bind_attrs = true, + .of_match_table = sun55i_a523_ccu_ids, + }, +}; +module_platform_driver(sun55i_a523_ccu_driver); + +MODULE_IMPORT_NS("SUNXI_CCU"); +MODULE_DESCRIPTION("Support for the Allwinner A523 CCU"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.h b/drivers/clk/sunxi-ng/ccu-sun55i-a523.h new file mode 100644 index 000000000000..fc8dd42f1b47 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2024 Arm Ltd. + */ + +#ifndef _CCU_SUN55I_A523_H +#define _CCU_SUN55I_A523_H + +#include +#include + +#define CLK_NUMBER (CLK_FANOUT2 + 1) + +#endif /* _CCU_SUN55I_A523_H */ From e6f4b4b77981feb3af06e16da073e788fe16de2a Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:20 +0000 Subject: [PATCH 38/63] clk: sunxi-ng: a523: Add support for bus clocks Add the basic bus clocks for the Allwinner A523 and T527 SoCs. This covers the AHB, APB0 and APB1 clocks. Linux is not supposed to change those clocks, but they are needed as parents for many other mod clocks. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-7-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index 455bca0c344b..c8a96b642bb1 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -331,6 +331,39 @@ static CLK_FIXED_FACTOR_HW(pll_npu_2x_clk, "pll-npu-2x", static CLK_FIXED_FACTOR_HW(pll_npu_1x_clk, "pll-npu-1x", &pll_npu_4x_clk.common.hw, 4, 1, 0); + +/************************************************************************** + * bus clocks * + **************************************************************************/ + +static const struct clk_parent_data ahb_apb0_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, + { .hw = &pll_periph0_600M_clk.hw }, +}; + +static SUNXI_CCU_M_DATA_WITH_MUX(ahb_clk, "ahb", ahb_apb0_parents, 0x510, + 0, 5, /* M */ + 24, 2, /* mux */ + 0); +static SUNXI_CCU_M_DATA_WITH_MUX(apb0_clk, "apb0", ahb_apb0_parents, 0x520, + 0, 5, /* M */ + 24, 2, /* mux */ + 0); + +static const struct clk_parent_data apb1_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, + { .hw = &pll_periph0_600M_clk.hw }, + { .hw = &pll_periph0_480M_clk.common.hw }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x524, + 0, 5, /* M */ + 24, 3, /* mux */ + 0); + /* * Contains all clocks that are controlled by a hardware register. They * have a (sunxi) .common member, which needs to be initialised by the common @@ -358,6 +391,9 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &pll_ve_clk.common, &pll_audio0_4x_clk.common, &pll_npu_4x_clk.common, + &ahb_clk.common, + &apb0_clk.common, + &apb1_clk.common, }; static struct clk_hw_onecell_data sun55i_a523_hw_clks = { @@ -403,6 +439,9 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_PLL_NPU_4X] = &pll_npu_4x_clk.common.hw, [CLK_PLL_NPU_2X] = &pll_npu_2x_clk.hw, [CLK_PLL_NPU] = &pll_npu_1x_clk.hw, + [CLK_AHB] = &ahb_clk.common.hw, + [CLK_APB0] = &apb0_clk.common.hw, + [CLK_APB1] = &apb1_clk.common.hw, }, }; From 6702d17f54a8f6c48cd6ba12282fae8c936e7944 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:21 +0000 Subject: [PATCH 39/63] clk: sunxi-ng: a523: add video mod clocks Add the clocks driving the various video subsystems of the SoC: the "DE" display engine, the "DI" deinterlacer, the "G2D" 2D graphics system, the Mali "GPU", the "VE" video engine, its associated IOMMU, as well as the clocks for the various video output drivers (HDMI, DP, LCDs). Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-8-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 238 +++++++++++++++++++++++++ 1 file changed, 238 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index c8a96b642bb1..17a4ffc0b7f5 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -364,6 +364,208 @@ static SUNXI_CCU_M_DATA_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x524, 24, 3, /* mux */ 0); + +/************************************************************************** + * mod clocks * + **************************************************************************/ + +static const struct clk_hw *de_parents[] = { + &pll_periph0_300M_clk.hw, + &pll_periph0_400M_clk.hw, + &pll_video3_4x_clk.common.hw, + &pll_video3_3x_clk.hw, +}; + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(de_clk, "de", de_parents, 0x600, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const struct clk_hw *di_parents[] = { + &pll_periph0_300M_clk.hw, + &pll_periph0_400M_clk.hw, + &pll_video0_4x_clk.common.hw, + &pll_video1_4x_clk.common.hw, +}; + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(di_clk, "di", di_parents, 0x620, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const struct clk_hw *g2d_parents[] = { + &pll_periph0_400M_clk.hw, + &pll_periph0_300M_clk.hw, + &pll_video0_4x_clk.common.hw, + &pll_video1_4x_clk.common.hw, +}; + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(g2d_clk, "g2d", g2d_parents, 0x630, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_hw *gpu_parents[] = { + &pll_gpu_clk.common.hw, + &pll_periph0_800M_clk.common.hw, + &pll_periph0_600M_clk.hw, + &pll_periph0_400M_clk.hw, + &pll_periph0_300M_clk.hw, + &pll_periph0_200M_clk.hw, +}; + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670, + 0, 4, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const struct clk_hw *ve_parents[] = { + &pll_ve_clk.common.hw, + &pll_periph0_480M_clk.common.hw, + &pll_periph0_400M_clk.hw, + &pll_periph0_300M_clk.hw, +}; +static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const struct clk_parent_data iommu_parents[] = { + { .hw = &pll_periph0_600M_clk.hw }, + { .hw = &pll_ddr_clk.common.hw }, + { .hw = &pll_periph0_480M_clk.common.hw }, + { .hw = &pll_periph0_400M_clk.hw }, + { .hw = &pll_periph0_150M_clk.hw }, + { .fw_name = "hosc" }, +}; + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(iommu_clk, "iommu", iommu_parents, + 0x7b0, + 0, 5, /* M */ + 0, 0, /* no P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT, + CCU_FEATURE_UPDATE_BIT); + +static SUNXI_CCU_GATE_DATA(hdmi_24M_clk, "hdmi-24M", osc24M, 0xb04, BIT(31), 0); + +static SUNXI_CCU_GATE_HWS_WITH_PREDIV(hdmi_cec_32k_clk, "hdmi-cec-32k", + pll_periph0_2x_hws, + 0xb10, BIT(30), 36621, 0); + +static const struct clk_parent_data hdmi_cec_parents[] = { + { .fw_name = "losc" }, + { .hw = &hdmi_cec_32k_clk.common.hw }, +}; +static SUNXI_CCU_MUX_DATA_WITH_GATE(hdmi_cec_clk, "hdmi-cec", hdmi_cec_parents, + 0xb10, + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_parent_data mipi_dsi_parents[] = { + { .fw_name = "hosc" }, + { .hw = &pll_periph0_200M_clk.hw }, + { .hw = &pll_periph0_150M_clk.hw }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(mipi_dsi0_clk, "mipi-dsi0", + mipi_dsi_parents, 0xb24, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(mipi_dsi1_clk, "mipi-dsi1", + mipi_dsi_parents, 0xb28, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_hw *tcon_parents[] = { + &pll_video0_4x_clk.common.hw, + &pll_video1_4x_clk.common.hw, + &pll_video2_4x_clk.common.hw, + &pll_video3_4x_clk.common.hw, + &pll_periph0_2x_clk.common.hw, + &pll_video0_3x_clk.hw, + &pll_video1_3x_clk.hw, +}; +static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_parents, + 0xb60, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents, + 0xb64, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const struct clk_hw *tcon_tv_parents[] = { + &pll_video0_4x_clk.common.hw, + &pll_video1_4x_clk.common.hw, + &pll_video2_4x_clk.common.hw, + &pll_video3_4x_clk.common.hw, + &pll_periph0_2x_clk.common.hw, +}; +static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_lcd2_clk, "tcon-lcd2", + tcon_tv_parents, 0xb68, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(combophy_dsi0_clk, "combophy-dsi0", + tcon_parents, 0xb6c, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(combophy_dsi1_clk, "combophy-dsi1", + tcon_parents, 0xb70, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_tv_parents, + 0xb80, + 0, 4, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_tv_parents, + 0xb84, + 0, 4, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + +static const struct clk_hw *edp_parents[] = { + &pll_video0_4x_clk.common.hw, + &pll_video1_4x_clk.common.hw, + &pll_video2_4x_clk.common.hw, + &pll_video3_4x_clk.common.hw, + &pll_periph0_2x_clk.common.hw, +}; +static SUNXI_CCU_M_HW_WITH_MUX_GATE(edp_clk, "edp", edp_parents, 0xbb0, + 0, 4, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_SET_RATE_PARENT); + /* * Contains all clocks that are controlled by a hardware register. They * have a (sunxi) .common member, which needs to be initialised by the common @@ -394,6 +596,23 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &ahb_clk.common, &apb0_clk.common, &apb1_clk.common, + &de_clk.common, + &di_clk.common, + &g2d_clk.common, + &gpu_clk.common, + &ve_clk.common, + &iommu_clk.common, + &hdmi_24M_clk.common, + &hdmi_cec_32k_clk.common, + &hdmi_cec_clk.common, + &mipi_dsi0_clk.common, + &mipi_dsi1_clk.common, + &tcon_lcd0_clk.common, + &tcon_lcd1_clk.common, + &tcon_lcd2_clk.common, + &tcon_tv0_clk.common, + &tcon_tv1_clk.common, + &edp_clk.common, }; static struct clk_hw_onecell_data sun55i_a523_hw_clks = { @@ -420,6 +639,7 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_PLL_PERIPH1_200M] = &pll_periph1_200M_clk.hw, [CLK_PLL_PERIPH1_160M] = &pll_periph1_160M_clk.hw, [CLK_PLL_PERIPH1_150M] = &pll_periph1_150M_clk.hw, + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, [CLK_PLL_VIDEO0_8X] = &pll_video0_8x_clk.common.hw, [CLK_PLL_VIDEO0_4X] = &pll_video0_4x_clk.common.hw, [CLK_PLL_VIDEO0_3X] = &pll_video0_3x_clk.hw, @@ -442,6 +662,24 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_AHB] = &ahb_clk.common.hw, [CLK_APB0] = &apb0_clk.common.hw, [CLK_APB1] = &apb1_clk.common.hw, + [CLK_DE] = &de_clk.common.hw, + [CLK_DI] = &di_clk.common.hw, + [CLK_G2D] = &g2d_clk.common.hw, + [CLK_GPU] = &gpu_clk.common.hw, + [CLK_VE] = &ve_clk.common.hw, + [CLK_HDMI_24M] = &hdmi_24M_clk.common.hw, + [CLK_HDMI_CEC_32K] = &hdmi_cec_32k_clk.common.hw, + [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, + [CLK_MIPI_DSI0] = &mipi_dsi0_clk.common.hw, + [CLK_MIPI_DSI1] = &mipi_dsi1_clk.common.hw, + [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, + [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw, + [CLK_TCON_LCD2] = &tcon_lcd2_clk.common.hw, + [CLK_COMBOPHY_DSI0] = &combophy_dsi0_clk.common.hw, + [CLK_COMBOPHY_DSI1] = &combophy_dsi1_clk.common.hw, + [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, + [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw, + [CLK_EDP] = &edp_clk.common.hw, }, }; From 74b0443a0d0ad283f20ee2985758143485942c31 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:22 +0000 Subject: [PATCH 40/63] clk: sunxi-ng: a523: add system mod clocks Add the clocks driving some core system related subsystems of the SoC: the "CE" crypto engine, the high speed timers, the DRAM and the associated MBUS clock, and the PCIe clock. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-9-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 135 +++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index 17a4ffc0b7f5..c59f3f789d05 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -364,6 +364,21 @@ static SUNXI_CCU_M_DATA_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x524, 24, 3, /* mux */ 0); +static const struct clk_parent_data mbus_parents[] = { + { .hw = &pll_ddr_clk.common.hw }, + { .hw = &pll_periph1_600M_clk.hw }, + { .hw = &pll_periph1_480M_clk.common.hw }, + { .hw = &pll_periph1_400M_clk.hw }, + { .hw = &pll_periph1_150M_clk.hw }, + { .fw_name = "hosc" }, +}; +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, + 0x540, + 0, 5, /* M */ + 0, 0, /* no P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0, CCU_FEATURE_UPDATE_BIT); /************************************************************************** * mod clocks * @@ -423,6 +438,18 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static const struct clk_parent_data ce_parents[] = { + { .fw_name = "hosc" }, + { .hw = &pll_periph0_480M_clk.common.hw }, + { .hw = &pll_periph0_400M_clk.hw }, + { .hw = &pll_periph0_300M_clk.hw }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + static const struct clk_hw *ve_parents[] = { &pll_ve_clk.common.hw, &pll_periph0_480M_clk.common.hw, @@ -435,6 +462,65 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static const struct clk_parent_data hstimer_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "iosc" }, + { .fw_name = "losc" }, + { .hw = &pll_periph0_200M_clk.hw }, +}; +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer0_clk, "hstimer0", + hstimer_parents, 0x730, + 0, 0, /* M */ + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer1_clk, "hstimer1", + hstimer_parents, + 0x734, + 0, 0, /* M */ + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer2_clk, "hstimer2", + hstimer_parents, + 0x738, + 0, 0, /* M */ + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer3_clk, "hstimer3", + hstimer_parents, + 0x73c, + 0, 0, /* M */ + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer4_clk, "hstimer4", + hstimer_parents, + 0x740, + 0, 0, /* M */ + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer5_clk, "hstimer5", + hstimer_parents, + 0x744, + 0, 0, /* M */ + 0, 3, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + static const struct clk_parent_data iommu_parents[] = { { .hw = &pll_periph0_600M_clk.hw }, { .hw = &pll_ddr_clk.common.hw }, @@ -453,6 +539,34 @@ static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(iommu_clk, "iommu", iommu_parents, CLK_SET_RATE_PARENT, CCU_FEATURE_UPDATE_BIT); +static const struct clk_parent_data dram_parents[] = { + { .hw = &pll_ddr_clk.common.hw }, + { .hw = &pll_periph0_600M_clk.hw }, + { .hw = &pll_periph0_480M_clk.common.hw }, + { .hw = &pll_periph0_400M_clk.hw }, + { .hw = &pll_periph0_150M_clk.hw }, +}; +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(dram_clk, "dram", dram_parents, + 0x800, + 0, 5, /* M */ + 0, 0, /* no P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + CLK_IS_CRITICAL, + CCU_FEATURE_UPDATE_BIT); + +static const struct clk_parent_data losc_hosc_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, +}; + +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(pcie_aux_clk, "pcie-aux", + losc_hosc_parents, 0xaa0, + 0, 5, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + static SUNXI_CCU_GATE_DATA(hdmi_24M_clk, "hdmi-24M", osc24M, 0xb04, BIT(31), 0); static SUNXI_CCU_GATE_HWS_WITH_PREDIV(hdmi_cec_32k_clk, "hdmi-cec-32k", @@ -596,12 +710,22 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &ahb_clk.common, &apb0_clk.common, &apb1_clk.common, + &mbus_clk.common, &de_clk.common, &di_clk.common, &g2d_clk.common, &gpu_clk.common, + &ce_clk.common, &ve_clk.common, + &hstimer0_clk.common, + &hstimer1_clk.common, + &hstimer2_clk.common, + &hstimer3_clk.common, + &hstimer4_clk.common, + &hstimer5_clk.common, &iommu_clk.common, + &dram_clk.common, + &pcie_aux_clk.common, &hdmi_24M_clk.common, &hdmi_cec_32k_clk.common, &hdmi_cec_clk.common, @@ -662,11 +786,22 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_AHB] = &ahb_clk.common.hw, [CLK_APB0] = &apb0_clk.common.hw, [CLK_APB1] = &apb1_clk.common.hw, + [CLK_MBUS] = &mbus_clk.common.hw, [CLK_DE] = &de_clk.common.hw, [CLK_DI] = &di_clk.common.hw, [CLK_G2D] = &g2d_clk.common.hw, [CLK_GPU] = &gpu_clk.common.hw, + [CLK_CE] = &ce_clk.common.hw, [CLK_VE] = &ve_clk.common.hw, + [CLK_HSTIMER0] = &hstimer0_clk.common.hw, + [CLK_HSTIMER1] = &hstimer1_clk.common.hw, + [CLK_HSTIMER2] = &hstimer2_clk.common.hw, + [CLK_HSTIMER3] = &hstimer3_clk.common.hw, + [CLK_HSTIMER4] = &hstimer4_clk.common.hw, + [CLK_HSTIMER5] = &hstimer5_clk.common.hw, + [CLK_IOMMU] = &iommu_clk.common.hw, + [CLK_DRAM] = &dram_clk.common.hw, + [CLK_PCIE_AUX] = &pcie_aux_clk.common.hw, [CLK_HDMI_24M] = &hdmi_24M_clk.common.hw, [CLK_HDMI_CEC_32K] = &hdmi_cec_32k_clk.common.hw, [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, From ed064e65b92a1d78d90b6b87a3d99790f88c1c83 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:23 +0000 Subject: [PATCH 41/63] clk: sunxi-ng: a523: add interface mod clocks Add the clocks driving what the user manual summarises under "interface" devices: raw NAND flash, MMC, SPI, EMAC, "IR" infrared, and the "GPADC" general purpose analogue/digital converter. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-10-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 159 +++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index c59f3f789d05..953b11f7135c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -113,6 +113,9 @@ static CLK_FIXED_FACTOR_HWS(pll_periph0_150M_clk, "pll-periph0-150M", pll_periph0_2x_hws, 8, 1, 0); static CLK_FIXED_FACTOR_HWS(pll_periph0_160M_clk, "pll-periph0-160M", pll_periph0_480M_hws, 3, 1, 0); +static const struct clk_hw *pll_periph0_150M_hws[] = { + &pll_periph0_150M_clk.hw +}; #define SUN55I_A523_PLL_PERIPH1_REG 0x028 static struct ccu_nm pll_periph1_4x_clk = { @@ -555,6 +558,132 @@ static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(dram_clk, "dram", dram_parents, CLK_IS_CRITICAL, CCU_FEATURE_UPDATE_BIT); +static const struct clk_parent_data nand_mmc_parents[] = { + { .fw_name = "hosc" }, + { .hw = &pll_periph0_400M_clk.hw }, + { .hw = &pll_periph0_300M_clk.hw }, + { .hw = &pll_periph1_400M_clk.hw }, + { .hw = &pll_periph1_300M_clk.hw }, +}; + +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(nand0_clk, "nand0", nand_mmc_parents, + 0x810, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(nand1_clk, "nand1", nand_mmc_parents, + 0x814, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc0_clk, "mmc0", nand_mmc_parents, + 0x830, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 2, /* post div */ + 0); + +static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc1_clk, "mmc1", nand_mmc_parents, + 0x834, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 2, /* post div */ + 0); + +static const struct clk_parent_data mmc2_parents[] = { + { .fw_name = "hosc" }, + { .hw = &pll_periph0_800M_clk.common.hw }, + { .hw = &pll_periph0_600M_clk.hw }, + { .hw = &pll_periph1_800M_clk.common.hw }, + { .hw = &pll_periph1_600M_clk.hw }, +}; + +static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc2_clk, "mmc2", mmc2_parents, + 0x838, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 2, /* post div */ + 0); + +static const struct clk_parent_data spi_parents[] = { + { .fw_name = "hosc" }, + { .hw = &pll_periph0_300M_clk.hw }, + { .hw = &pll_periph0_200M_clk.hw }, + { .hw = &pll_periph1_300M_clk.hw }, + { .hw = &pll_periph1_200M_clk.hw }, +}; +static SUNXI_CCU_DUALDIV_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); +static SUNXI_CCU_DUALDIV_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); +static SUNXI_CCU_DUALDIV_MUX_GATE(spi2_clk, "spi2", spi_parents, 0x948, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); +static SUNXI_CCU_DUALDIV_MUX_GATE(spifc_clk, "spifc", nand_mmc_parents, 0x950, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac0_25M_clk, "emac0-25M", + pll_periph0_150M_hws, + 0x970, BIT(31) | BIT(30), 6, 0); +static SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac1_25M_clk, "emac1-25M", + pll_periph0_150M_hws, + 0x974, BIT(31) | BIT(30), 6, 0); + +static const struct clk_parent_data ir_rx_parents[] = { + { .fw_name = "losc" }, + { .fw_name = "hosc" }, +}; + +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_rx_parents, 0x990, + 0, 5, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); +static const struct clk_parent_data ir_tx_ledc_parents[] = { + { .fw_name = "hosc" }, + { .hw = &pll_periph1_600M_clk.hw }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_tx_ledc_parents, + 0x9c0, + 0, 5, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_M_WITH_GATE(gpadc0_clk, "gpadc0", "hosc", 0x9e0, + 0, 5, /* M */ + BIT(31), /* gate */ + 0); +static SUNXI_CCU_M_WITH_GATE(gpadc1_clk, "gpadc1", "hosc", 0x9e4, + 0, 5, /* M */ + BIT(31), /* gate */ + 0); + static const struct clk_parent_data losc_hosc_parents[] = { { .fw_name = "hosc" }, { .fw_name = "losc" }, @@ -725,6 +854,21 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &hstimer5_clk.common, &iommu_clk.common, &dram_clk.common, + &nand0_clk.common, + &nand1_clk.common, + &mmc0_clk.common, + &mmc1_clk.common, + &mmc2_clk.common, + &spi0_clk.common, + &spi1_clk.common, + &spi2_clk.common, + &spifc_clk.common, + &emac0_25M_clk.common, + &emac1_25M_clk.common, + &ir_rx_clk.common, + &ir_tx_clk.common, + &gpadc0_clk.common, + &gpadc1_clk.common, &pcie_aux_clk.common, &hdmi_24M_clk.common, &hdmi_cec_32k_clk.common, @@ -801,6 +945,21 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_HSTIMER5] = &hstimer5_clk.common.hw, [CLK_IOMMU] = &iommu_clk.common.hw, [CLK_DRAM] = &dram_clk.common.hw, + [CLK_NAND0] = &nand0_clk.common.hw, + [CLK_NAND1] = &nand1_clk.common.hw, + [CLK_MMC0] = &mmc0_clk.common.hw, + [CLK_MMC1] = &mmc1_clk.common.hw, + [CLK_MMC2] = &mmc2_clk.common.hw, + [CLK_SPI0] = &spi0_clk.common.hw, + [CLK_SPI1] = &spi1_clk.common.hw, + [CLK_SPI2] = &spi2_clk.common.hw, + [CLK_SPIFC] = &spifc_clk.common.hw, + [CLK_EMAC0_25M] = &emac0_25M_clk.common.hw, + [CLK_EMAC1_25M] = &emac1_25M_clk.common.hw, + [CLK_IR_RX] = &ir_rx_clk.common.hw, + [CLK_IR_TX] = &ir_tx_clk.common.hw, + [CLK_GPADC0] = &gpadc0_clk.common.hw, + [CLK_GPADC1] = &gpadc1_clk.common.hw, [CLK_PCIE_AUX] = &pcie_aux_clk.common.hw, [CLK_HDMI_24M] = &hdmi_24M_clk.common.hw, [CLK_HDMI_CEC_32K] = &hdmi_cec_32k_clk.common.hw, From fb2c60366d3259aeb5507902e50032fb05b11895 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:24 +0000 Subject: [PATCH 42/63] clk: sunxi-ng: a523: add USB mod clocks Add the clocks driving the USB subsystem: this just covers the two clocks creating the 12 MHz rate for the OHCI (USB 1.x) device. The rest of the USB clocks are either gate clocks (added later) or created internal to the USB IP. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-11-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index 953b11f7135c..f62a32fa70e4 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -684,6 +684,59 @@ static SUNXI_CCU_M_WITH_GATE(gpadc1_clk, "gpadc1", "hosc", 0x9e4, BIT(31), /* gate */ 0); +/* + * The first parent is a 48 MHz input clock divided by 4. That 48 MHz clock is + * a 2x multiplier from osc24M synchronized by pll-periph0, and is also used by + * the OHCI module. + */ +static const struct clk_parent_data usb_ohci_parents[] = { + { .hw = &pll_periph0_4x_clk.common.hw }, + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, +}; +static const struct ccu_mux_fixed_prediv usb_ohci_predivs[] = { + { .index = 0, .div = 50 }, + { .index = 1, .div = 2 }, +}; + +static struct ccu_mux usb_ohci0_clk = { + .enable = BIT(31), + .mux = { + .shift = 24, + .width = 2, + .fixed_predivs = usb_ohci_predivs, + .n_predivs = ARRAY_SIZE(usb_ohci_predivs), + }, + .common = { + .reg = 0xa70, + .features = CCU_FEATURE_FIXED_PREDIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("usb-ohci0", + usb_ohci_parents, + &ccu_mux_ops, + 0), + }, +}; + +static struct ccu_mux usb_ohci1_clk = { + .enable = BIT(31), + .mux = { + .shift = 24, + .width = 2, + .fixed_predivs = usb_ohci_predivs, + .n_predivs = ARRAY_SIZE(usb_ohci_predivs), + }, + .common = { + .reg = 0xa74, + .features = CCU_FEATURE_FIXED_PREDIV, + .hw.init = CLK_HW_INIT_PARENTS_DATA("usb-ohci1", + usb_ohci_parents, + &ccu_mux_ops, + 0), + }, +}; + + static const struct clk_parent_data losc_hosc_parents[] = { { .fw_name = "hosc" }, { .fw_name = "losc" }, @@ -869,6 +922,8 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &ir_tx_clk.common, &gpadc0_clk.common, &gpadc1_clk.common, + &usb_ohci0_clk.common, + &usb_ohci1_clk.common, &pcie_aux_clk.common, &hdmi_24M_clk.common, &hdmi_cec_32k_clk.common, @@ -960,6 +1015,8 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_IR_TX] = &ir_tx_clk.common.hw, [CLK_GPADC0] = &gpadc0_clk.common.hw, [CLK_GPADC1] = &gpadc1_clk.common.hw, + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, + [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, [CLK_PCIE_AUX] = &pcie_aux_clk.common.hw, [CLK_HDMI_24M] = &hdmi_24M_clk.common.hw, [CLK_HDMI_CEC_32K] = &hdmi_cec_32k_clk.common.hw, From 00bc60ea24a7b31da97a3b8a833711491c285ae4 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:25 +0000 Subject: [PATCH 43/63] clk: sunxi-ng: a523: remaining mod clocks Add the remaining mod clocks, driving various parts of the SoC: the "LEDC" LED controller, the "CSI" camera interface, the "ISP" image processor, the DSP clock, and the "fanout" clocks, which allow to put clock signals on external pins. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-12-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 185 +++++++++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index f62a32fa70e4..0f28e453440a 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -862,6 +862,157 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(edp_clk, "edp", edp_parents, 0xbb0, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ir_tx_ledc_parents, + 0xbf0, + 0, 4, /* M */ + 24, 1, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_hw *csi_top_parents[] = { + &pll_periph0_300M_clk.hw, + &pll_periph0_400M_clk.hw, + &pll_periph0_480M_clk.common.hw, + &pll_video3_4x_clk.common.hw, + &pll_video3_3x_clk.hw, +}; +static SUNXI_CCU_M_HW_WITH_MUX_GATE(csi_top_clk, "csi-top", csi_top_parents, + 0xc04, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_parent_data csi_mclk_parents[] = { + { .fw_name = "hosc" }, + { .hw = &pll_video3_4x_clk.common.hw }, + { .hw = &pll_video0_4x_clk.common.hw }, + { .hw = &pll_video1_4x_clk.common.hw }, + { .hw = &pll_video2_4x_clk.common.hw }, +}; +static SUNXI_CCU_DUALDIV_MUX_GATE(csi_mclk0_clk, "csi-mclk0", csi_mclk_parents, + 0xc08, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_DUALDIV_MUX_GATE(csi_mclk1_clk, "csi-mclk1", csi_mclk_parents, + 0xc0c, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_DUALDIV_MUX_GATE(csi_mclk2_clk, "csi-mclk2", csi_mclk_parents, + 0xc10, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_DUALDIV_MUX_GATE(csi_mclk3_clk, "csi-mclk3", csi_mclk_parents, + 0xc14, + 0, 5, /* M */ + 8, 5, /* P */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_hw *isp_parents[] = { + &pll_periph0_300M_clk.hw, + &pll_periph0_400M_clk.hw, + &pll_video2_4x_clk.common.hw, + &pll_video3_4x_clk.common.hw, +}; +static SUNXI_CCU_M_HW_WITH_MUX_GATE(isp_clk, "isp", isp_parents, 0xc20, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_parent_data dsp_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, + { .hw = &pll_periph0_2x_clk.common.hw }, + { .hw = &pll_periph0_480M_clk.common.hw, }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(dsp_clk, "dsp", dsp_parents, 0xc70, + 0, 5, /* M */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 0); + +static SUNXI_CCU_GATE_DATA(fanout_24M_clk, "fanout-24M", osc24M, + 0xf30, BIT(0), 0); +static SUNXI_CCU_GATE_DATA_WITH_PREDIV(fanout_12M_clk, "fanout-12M", osc24M, + 0xf30, BIT(1), 2, 0); +static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_16M_clk, "fanout-16M", + pll_periph0_480M_hws, + 0xf30, BIT(2), 30, 0); +static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_25M_clk, "fanout-25M", + pll_periph0_2x_hws, + 0xf30, BIT(3), 48, 0); +static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_50M_clk, "fanout-50M", + pll_periph0_2x_hws, + 0xf30, BIT(4), 24, 0); + +static const struct clk_parent_data fanout_27M_parents[] = { + { .hw = &pll_video0_4x_clk.common.hw }, + { .hw = &pll_video1_4x_clk.common.hw }, + { .hw = &pll_video2_4x_clk.common.hw }, + { .hw = &pll_video3_4x_clk.common.hw }, +}; +static SUNXI_CCU_DUALDIV_MUX_GATE(fanout_27M_clk, "fanout-27M", + fanout_27M_parents, 0xf34, + 0, 5, /* div0 */ + 8, 5, /* div1 */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_parent_data fanout_pclk_parents[] = { + { .hw = &apb0_clk.common.hw } +}; +static SUNXI_CCU_DUALDIV_MUX_GATE(fanout_pclk_clk, "fanout-pclk", + fanout_pclk_parents, + 0xf38, + 0, 5, /* div0 */ + 5, 5, /* div1 */ + 0, 0, /* mux */ + BIT(31), /* gate */ + 0); + +static const struct clk_parent_data fanout_parents[] = { + { .fw_name = "losc-fanout" }, + { .hw = &fanout_12M_clk.common.hw, }, + { .hw = &fanout_16M_clk.common.hw, }, + { .hw = &fanout_24M_clk.common.hw, }, + { .hw = &fanout_25M_clk.common.hw, }, + { .hw = &fanout_27M_clk.common.hw, }, + { .hw = &fanout_pclk_clk.common.hw, }, + { .hw = &fanout_50M_clk.common.hw, }, +}; +static SUNXI_CCU_MUX_DATA_WITH_GATE(fanout0_clk, "fanout0", fanout_parents, + 0xf3c, + 0, 3, /* mux */ + BIT(21), /* gate */ + 0); +static SUNXI_CCU_MUX_DATA_WITH_GATE(fanout1_clk, "fanout1", fanout_parents, + 0xf3c, + 3, 3, /* mux */ + BIT(22), /* gate */ + 0); +static SUNXI_CCU_MUX_DATA_WITH_GATE(fanout2_clk, "fanout2", fanout_parents, + 0xf3c, + 6, 3, /* mux */ + BIT(23), /* gate */ + 0); + /* * Contains all clocks that are controlled by a hardware register. They * have a (sunxi) .common member, which needs to be initialised by the common @@ -936,6 +1087,23 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &tcon_tv0_clk.common, &tcon_tv1_clk.common, &edp_clk.common, + &ledc_clk.common, + &csi_top_clk.common, + &csi_mclk0_clk.common, + &csi_mclk1_clk.common, + &csi_mclk2_clk.common, + &csi_mclk3_clk.common, + &isp_clk.common, + &dsp_clk.common, + &fanout_24M_clk.common, + &fanout_12M_clk.common, + &fanout_16M_clk.common, + &fanout_25M_clk.common, + &fanout_27M_clk.common, + &fanout_pclk_clk.common, + &fanout0_clk.common, + &fanout1_clk.common, + &fanout2_clk.common, }; static struct clk_hw_onecell_data sun55i_a523_hw_clks = { @@ -1031,6 +1199,23 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw, [CLK_EDP] = &edp_clk.common.hw, + [CLK_LEDC] = &ledc_clk.common.hw, + [CLK_CSI_TOP] = &csi_top_clk.common.hw, + [CLK_CSI_MCLK0] = &csi_mclk0_clk.common.hw, + [CLK_CSI_MCLK1] = &csi_mclk1_clk.common.hw, + [CLK_CSI_MCLK2] = &csi_mclk2_clk.common.hw, + [CLK_CSI_MCLK3] = &csi_mclk3_clk.common.hw, + [CLK_ISP] = &isp_clk.common.hw, + [CLK_DSP] = &dsp_clk.common.hw, + [CLK_FANOUT_24M] = &fanout_24M_clk.common.hw, + [CLK_FANOUT_12M] = &fanout_12M_clk.common.hw, + [CLK_FANOUT_16M] = &fanout_16M_clk.common.hw, + [CLK_FANOUT_25M] = &fanout_25M_clk.common.hw, + [CLK_FANOUT_27M] = &fanout_27M_clk.common.hw, + [CLK_FANOUT_PCLK] = &fanout_pclk_clk.common.hw, + [CLK_FANOUT0] = &fanout0_clk.common.hw, + [CLK_FANOUT1] = &fanout1_clk.common.hw, + [CLK_FANOUT2] = &fanout2_clk.common.hw, }, }; From f3dabb29f0ca44f2053c0c3943ca6f47b248d348 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:26 +0000 Subject: [PATCH 44/63] clk: sunxi-ng: a523: add bus clock gates Add the various bus clock gates that control access to the devices' register interface. These clocks are each just one bit, typically the lower bits in some "BGR" (Bus Gate / Reset) registers, for each device group: one for all UARTs, one for all SPI interfaces, and so on. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-13-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 309 ++++++++++++++++++++++++- 1 file changed, 308 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index 0f28e453440a..736544f6a141 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -350,10 +350,13 @@ static SUNXI_CCU_M_DATA_WITH_MUX(ahb_clk, "ahb", ahb_apb0_parents, 0x510, 0, 5, /* M */ 24, 2, /* mux */ 0); +static const struct clk_hw *ahb_hws[] = { &ahb_clk.common.hw }; + static SUNXI_CCU_M_DATA_WITH_MUX(apb0_clk, "apb0", ahb_apb0_parents, 0x520, 0, 5, /* M */ 24, 2, /* mux */ 0); +static const struct clk_hw *apb0_hws[] = { &apb0_clk.common.hw }; static const struct clk_parent_data apb1_parents[] = { { .fw_name = "hosc" }, @@ -366,6 +369,7 @@ static SUNXI_CCU_M_DATA_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x524, 0, 5, /* M */ 24, 3, /* mux */ 0); +static const struct clk_hw *apb1_hws[] = { &apb1_clk.common.hw }; static const struct clk_parent_data mbus_parents[] = { { .hw = &pll_ddr_clk.common.hw }, @@ -383,8 +387,10 @@ static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, BIT(31), /* gate */ 0, CCU_FEATURE_UPDATE_BIT); +static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw }; + /************************************************************************** - * mod clocks * + * mod clocks with gates * **************************************************************************/ static const struct clk_hw *de_parents[] = { @@ -400,6 +406,8 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(de_clk, "de", de_parents, 0x600, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE_HWS(bus_de_clk, "bus-de", ahb_hws, 0x60c, BIT(0), 0); + static const struct clk_hw *di_parents[] = { &pll_periph0_300M_clk.hw, &pll_periph0_400M_clk.hw, @@ -413,6 +421,8 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(di_clk, "di", di_parents, 0x620, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE_HWS(bus_di_clk, "bus-di", ahb_hws, 0x62c, BIT(0), 0); + static const struct clk_hw *g2d_parents[] = { &pll_periph0_400M_clk.hw, &pll_periph0_300M_clk.hw, @@ -426,6 +436,8 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(g2d_clk, "g2d", g2d_parents, 0x630, BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_g2d_clk, "bus-g2d", ahb_hws, 0x63c, BIT(0), 0); + static const struct clk_hw *gpu_parents[] = { &pll_gpu_clk.common.hw, &pll_periph0_800M_clk.common.hw, @@ -441,6 +453,8 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE_HWS(bus_gpu_clk, "bus-gpu", ahb_hws, 0x67c, BIT(0), 0); + static const struct clk_parent_data ce_parents[] = { { .fw_name = "hosc" }, { .hw = &pll_periph0_480M_clk.common.hw }, @@ -453,6 +467,10 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680, BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_ce_clk, "bus-ce", ahb_hws, 0x68c, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_ce_sys_clk, "bus-ce-sys", ahb_hws, 0x68c, + BIT(1), 0); + static const struct clk_hw *ve_parents[] = { &pll_ve_clk.common.hw, &pll_periph0_480M_clk.common.hw, @@ -465,6 +483,16 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE_HWS(bus_ve_clk, "bus-ve", ahb_hws, 0x69c, BIT(0), 0); + +static SUNXI_CCU_GATE_HWS(bus_dma_clk, "bus-dma", ahb_hws, 0x70c, BIT(0), 0); + +static SUNXI_CCU_GATE_HWS(bus_msgbox_clk, "bus-msgbox", ahb_hws, 0x71c, + BIT(0), 0); + +static SUNXI_CCU_GATE_HWS(bus_spinlock_clk, "bus-spinlock", ahb_hws, 0x72c, + BIT(0), 0); + static const struct clk_parent_data hstimer_parents[] = { { .fw_name = "hosc" }, { .fw_name = "iosc" }, @@ -524,6 +552,15 @@ static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(hstimer5_clk, "hstimer5", BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_hstimer_clk, "bus-hstimer", ahb_hws, 0x74c, + BIT(0), 0); + +static SUNXI_CCU_GATE_HWS(bus_dbg_clk, "bus-dbg", ahb_hws, 0x78c, + BIT(0), 0); + +static SUNXI_CCU_GATE_HWS(bus_pwm0_clk, "bus-pwm0", apb1_hws, 0x7ac, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_pwm1_clk, "bus-pwm1", apb1_hws, 0x7ac, BIT(1), 0); + static const struct clk_parent_data iommu_parents[] = { { .hw = &pll_periph0_600M_clk.hw }, { .hw = &pll_ddr_clk.common.hw }, @@ -542,6 +579,9 @@ static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(iommu_clk, "iommu", iommu_parents, CLK_SET_RATE_PARENT, CCU_FEATURE_UPDATE_BIT); +static SUNXI_CCU_GATE_HWS(bus_iommu_clk, "bus-iommu", apb0_hws, 0x7bc, + BIT(0), 0); + static const struct clk_parent_data dram_parents[] = { { .hw = &pll_ddr_clk.common.hw }, { .hw = &pll_periph0_600M_clk.hw }, @@ -558,6 +598,26 @@ static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(dram_clk, "dram", dram_parents, CLK_IS_CRITICAL, CCU_FEATURE_UPDATE_BIT); +static SUNXI_CCU_GATE_HWS(mbus_dma_clk, "mbus-dma", mbus_hws, + 0x804, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(mbus_ve_clk, "mbus-ve", mbus_hws, + 0x804, BIT(1), 0); +static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws, + 0x804, BIT(2), 0); +static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws, + 0x804, BIT(5), 0); +static SUNXI_CCU_GATE_HWS(mbus_usb3_clk, "mbus-usb3", mbus_hws, + 0x804, BIT(6), 0); +static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws, + 0x804, BIT(8), 0); +static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws, + 0x804, BIT(9), 0); +static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws, + 0x804, BIT(12), 0); + +static SUNXI_CCU_GATE_HWS(bus_dram_clk, "bus-dram", ahb_hws, 0x80c, + BIT(0), CLK_IS_CRITICAL); + static const struct clk_parent_data nand_mmc_parents[] = { { .fw_name = "hosc" }, { .hw = &pll_periph0_400M_clk.hw }, @@ -580,6 +640,9 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE(nand1_clk, "nand1", nand_mmc_parents, BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_nand_clk, "bus-nand", ahb_hws, 0x82c, + BIT(0), 0); + static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc0_clk, "mmc0", nand_mmc_parents, 0x830, 0, 5, /* M */ @@ -615,6 +678,39 @@ static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc2_clk, "mmc2", mmc2_parents, 2, /* post div */ 0); +static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", ahb_hws, 0x84c, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_mmc1_clk, "bus-mmc1", ahb_hws, 0x84c, BIT(1), 0); +static SUNXI_CCU_GATE_HWS(bus_mmc2_clk, "bus-mmc2", ahb_hws, 0x84c, BIT(2), 0); + +static SUNXI_CCU_GATE_HWS(bus_sysdap_clk, "bus-sysdap", apb1_hws, 0x88c, + BIT(0), 0); + +static SUNXI_CCU_GATE_HWS(bus_uart0_clk, "bus-uart0", apb1_hws, 0x90c, + BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_uart1_clk, "bus-uart1", apb1_hws, 0x90c, + BIT(1), 0); +static SUNXI_CCU_GATE_HWS(bus_uart2_clk, "bus-uart2", apb1_hws, 0x90c, + BIT(2), 0); +static SUNXI_CCU_GATE_HWS(bus_uart3_clk, "bus-uart3", apb1_hws, 0x90c, + BIT(3), 0); +static SUNXI_CCU_GATE_HWS(bus_uart4_clk, "bus-uart4", apb1_hws, 0x90c, + BIT(4), 0); +static SUNXI_CCU_GATE_HWS(bus_uart5_clk, "bus-uart5", apb1_hws, 0x90c, + BIT(5), 0); +static SUNXI_CCU_GATE_HWS(bus_uart6_clk, "bus-uart6", apb1_hws, 0x90c, + BIT(6), 0); +static SUNXI_CCU_GATE_HWS(bus_uart7_clk, "bus-uart7", apb1_hws, 0x90c, + BIT(7), 0); + +static SUNXI_CCU_GATE_HWS(bus_i2c0_clk, "bus-i2c0", apb1_hws, 0x91c, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_i2c1_clk, "bus-i2c1", apb1_hws, 0x91c, BIT(1), 0); +static SUNXI_CCU_GATE_HWS(bus_i2c2_clk, "bus-i2c2", apb1_hws, 0x91c, BIT(2), 0); +static SUNXI_CCU_GATE_HWS(bus_i2c3_clk, "bus-i2c3", apb1_hws, 0x91c, BIT(3), 0); +static SUNXI_CCU_GATE_HWS(bus_i2c4_clk, "bus-i2c4", apb1_hws, 0x91c, BIT(4), 0); +static SUNXI_CCU_GATE_HWS(bus_i2c5_clk, "bus-i2c5", apb1_hws, 0x91c, BIT(5), 0); + +static SUNXI_CCU_GATE_HWS(bus_can_clk, "bus-can", apb1_hws, 0x92c, BIT(0), 0); + static const struct clk_parent_data spi_parents[] = { { .fw_name = "hosc" }, { .hw = &pll_periph0_300M_clk.hw }, @@ -646,6 +742,11 @@ static SUNXI_CCU_DUALDIV_MUX_GATE(spifc_clk, "spifc", nand_mmc_parents, 0x950, 24, 3, /* mux */ BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_spi0_clk, "bus-spi0", ahb_hws, 0x96c, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_spi1_clk, "bus-spi1", ahb_hws, 0x96c, BIT(1), 0); +static SUNXI_CCU_GATE_HWS(bus_spi2_clk, "bus-spi2", ahb_hws, 0x96c, BIT(2), 0); +static SUNXI_CCU_GATE_HWS(bus_spifc_clk, "bus-spifc", ahb_hws, 0x96c, + BIT(3), 0); static SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac0_25M_clk, "emac0-25M", pll_periph0_150M_hws, @@ -653,6 +754,10 @@ static SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac0_25M_clk, "emac0-25M", static SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac1_25M_clk, "emac1-25M", pll_periph0_150M_hws, 0x974, BIT(31) | BIT(30), 6, 0); +static SUNXI_CCU_GATE_HWS(bus_emac0_clk, "bus-emac0", ahb_hws, 0x97c, + BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_emac1_clk, "bus-emac1", ahb_hws, 0x98c, + BIT(0), 0); static const struct clk_parent_data ir_rx_parents[] = { { .fw_name = "losc" }, @@ -664,6 +769,9 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_rx_parents, 0x990, 24, 1, /* mux */ BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_ir_rx_clk, "bus-ir-rx", apb0_hws, 0x99c, + BIT(0), 0); + static const struct clk_parent_data ir_tx_ledc_parents[] = { { .fw_name = "hosc" }, { .hw = &pll_periph1_600M_clk.hw }, @@ -674,6 +782,8 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_tx_ledc_parents, 24, 1, /* mux */ BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_ir_tx_clk, "bus-ir-tx", apb0_hws, 0x9cc, + BIT(0), 0); static SUNXI_CCU_M_WITH_GATE(gpadc0_clk, "gpadc0", "hosc", 0x9e0, 0, 5, /* M */ @@ -683,6 +793,12 @@ static SUNXI_CCU_M_WITH_GATE(gpadc1_clk, "gpadc1", "hosc", 0x9e4, 0, 5, /* M */ BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_gpadc0_clk, "bus-gpadc0", ahb_hws, 0x9ec, + BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_gpadc1_clk, "bus-gpadc1", ahb_hws, 0x9ec, + BIT(1), 0); + +static SUNXI_CCU_GATE_HWS(bus_ths_clk, "bus-ths", apb0_hws, 0x9fc, BIT(0), 0); /* * The first parent is a 48 MHz input clock divided by 4. That 48 MHz clock is @@ -736,6 +852,18 @@ static struct ccu_mux usb_ohci1_clk = { }, }; +static SUNXI_CCU_GATE_HWS(bus_ohci0_clk, "bus-ohci0", ahb_hws, 0xa8c, + BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_ohci1_clk, "bus-ohci1", ahb_hws, 0xa8c, + BIT(1), 0); +static SUNXI_CCU_GATE_HWS(bus_ehci0_clk, "bus-ehci0", ahb_hws, 0xa8c, + BIT(4), 0); +static SUNXI_CCU_GATE_HWS(bus_ehci1_clk, "bus-ehci1", ahb_hws, 0xa8c, + BIT(5), 0); +static SUNXI_CCU_GATE_HWS(bus_otg_clk, "bus-otg", ahb_hws, 0xa8c, BIT(8), 0); + +static SUNXI_CCU_GATE_HWS(bus_lradc_clk, "bus-lradc", apb0_hws, 0xa9c, + BIT(0), 0); static const struct clk_parent_data losc_hosc_parents[] = { { .fw_name = "hosc" }, @@ -749,6 +877,11 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE(pcie_aux_clk, "pcie-aux", BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_display0_top_clk, "bus-display0-top", ahb_hws, + 0xabc, BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_display1_top_clk, "bus-display1-top", ahb_hws, + 0xacc, BIT(0), 0); + static SUNXI_CCU_GATE_DATA(hdmi_24M_clk, "hdmi-24M", osc24M, 0xb04, BIT(31), 0); static SUNXI_CCU_GATE_HWS_WITH_PREDIV(hdmi_cec_32k_clk, "hdmi-cec-32k", @@ -765,6 +898,8 @@ static SUNXI_CCU_MUX_DATA_WITH_GATE(hdmi_cec_clk, "hdmi-cec", hdmi_cec_parents, BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_hdmi_clk, "bus-hdmi", ahb_hws, 0xb1c, BIT(0), 0); + static const struct clk_parent_data mipi_dsi_parents[] = { { .fw_name = "hosc" }, { .hw = &pll_periph0_200M_clk.hw }, @@ -784,6 +919,12 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE(mipi_dsi1_clk, "mipi-dsi1", BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_mipi_dsi0_clk, "bus-mipi-dsi0", ahb_hws, 0xb4c, + BIT(0), 0); + +static SUNXI_CCU_GATE_HWS(bus_mipi_dsi1_clk, "bus-mipi-dsi1", ahb_hws, 0xb4c, + BIT(1), 0); + static const struct clk_hw *tcon_parents[] = { &pll_video0_4x_clk.common.hw, &pll_video1_4x_clk.common.hw, @@ -835,6 +976,13 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(combophy_dsi1_clk, "combophy-dsi1", BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE_HWS(bus_tcon_lcd0_clk, "bus-tcon-lcd0", ahb_hws, 0xb7c, + BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_tcon_lcd1_clk, "bus-tcon-lcd1", ahb_hws, 0xb7c, + BIT(1), 0); +static SUNXI_CCU_GATE_HWS(bus_tcon_lcd2_clk, "bus-tcon-lcd2", ahb_hws, 0xb7c, + BIT(2), 0); + static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_tv_parents, 0xb80, 0, 4, /* M */ @@ -849,6 +997,11 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_tv_parents, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE_HWS(bus_tcon_tv0_clk, "bus-tcon-tv0", ahb_hws, 0xb9c, + BIT(0), 0); +static SUNXI_CCU_GATE_HWS(bus_tcon_tv1_clk, "bus-tcon-tv1", ahb_hws, 0xb9c, + BIT(1), 0); + static const struct clk_hw *edp_parents[] = { &pll_video0_4x_clk.common.hw, &pll_video1_4x_clk.common.hw, @@ -862,6 +1015,8 @@ static SUNXI_CCU_M_HW_WITH_MUX_GATE(edp_clk, "edp", edp_parents, 0xbb0, BIT(31), /* gate */ CLK_SET_RATE_PARENT); +static SUNXI_CCU_GATE_HWS(bus_edp_clk, "bus-edp", ahb_hws, 0xbbc, BIT(0), 0); + static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ir_tx_ledc_parents, 0xbf0, 0, 4, /* M */ @@ -869,6 +1024,8 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ir_tx_ledc_parents, BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_ledc_clk, "bus-ledc", apb0_hws, 0xbfc, BIT(0), 0); + static const struct clk_hw *csi_top_parents[] = { &pll_periph0_300M_clk.hw, &pll_periph0_400M_clk.hw, @@ -922,6 +1079,8 @@ static SUNXI_CCU_DUALDIV_MUX_GATE(csi_mclk3_clk, "csi-mclk3", csi_mclk_parents, BIT(31), /* gate */ 0); +static SUNXI_CCU_GATE_HWS(bus_csi_clk, "bus-csi", ahb_hws, 0xc1c, BIT(0), 0); + static const struct clk_hw *isp_parents[] = { &pll_periph0_300M_clk.hw, &pll_periph0_400M_clk.hw, @@ -1045,54 +1204,130 @@ static struct ccu_common *sun55i_a523_ccu_clks[] = { &apb1_clk.common, &mbus_clk.common, &de_clk.common, + &bus_de_clk.common, &di_clk.common, + &bus_di_clk.common, &g2d_clk.common, + &bus_g2d_clk.common, &gpu_clk.common, + &bus_gpu_clk.common, &ce_clk.common, + &bus_ce_clk.common, + &bus_ce_sys_clk.common, &ve_clk.common, + &bus_ve_clk.common, + &bus_dma_clk.common, + &bus_msgbox_clk.common, + &bus_spinlock_clk.common, &hstimer0_clk.common, &hstimer1_clk.common, &hstimer2_clk.common, &hstimer3_clk.common, &hstimer4_clk.common, &hstimer5_clk.common, + &bus_hstimer_clk.common, + &bus_dbg_clk.common, + &bus_pwm0_clk.common, + &bus_pwm1_clk.common, &iommu_clk.common, + &bus_iommu_clk.common, &dram_clk.common, + &mbus_dma_clk.common, + &mbus_ve_clk.common, + &mbus_ce_clk.common, + &mbus_nand_clk.common, + &mbus_usb3_clk.common, + &mbus_csi_clk.common, + &mbus_isp_clk.common, + &mbus_gmac1_clk.common, + &bus_dram_clk.common, &nand0_clk.common, &nand1_clk.common, + &bus_nand_clk.common, &mmc0_clk.common, &mmc1_clk.common, &mmc2_clk.common, + &bus_sysdap_clk.common, + &bus_mmc0_clk.common, + &bus_mmc1_clk.common, + &bus_mmc2_clk.common, + &bus_uart0_clk.common, + &bus_uart1_clk.common, + &bus_uart2_clk.common, + &bus_uart3_clk.common, + &bus_uart4_clk.common, + &bus_uart5_clk.common, + &bus_uart6_clk.common, + &bus_uart7_clk.common, + &bus_i2c0_clk.common, + &bus_i2c1_clk.common, + &bus_i2c2_clk.common, + &bus_i2c3_clk.common, + &bus_i2c4_clk.common, + &bus_i2c5_clk.common, + &bus_can_clk.common, &spi0_clk.common, &spi1_clk.common, &spi2_clk.common, &spifc_clk.common, + &bus_spi0_clk.common, + &bus_spi1_clk.common, + &bus_spi2_clk.common, + &bus_spifc_clk.common, &emac0_25M_clk.common, &emac1_25M_clk.common, + &bus_emac0_clk.common, + &bus_emac1_clk.common, &ir_rx_clk.common, + &bus_ir_rx_clk.common, &ir_tx_clk.common, + &bus_ir_tx_clk.common, &gpadc0_clk.common, &gpadc1_clk.common, + &bus_gpadc0_clk.common, + &bus_gpadc1_clk.common, + &bus_ths_clk.common, &usb_ohci0_clk.common, &usb_ohci1_clk.common, + &bus_ohci0_clk.common, + &bus_ohci1_clk.common, + &bus_ehci0_clk.common, + &bus_ehci1_clk.common, + &bus_otg_clk.common, + &bus_lradc_clk.common, &pcie_aux_clk.common, + &bus_display0_top_clk.common, + &bus_display1_top_clk.common, &hdmi_24M_clk.common, &hdmi_cec_32k_clk.common, &hdmi_cec_clk.common, + &bus_hdmi_clk.common, &mipi_dsi0_clk.common, &mipi_dsi1_clk.common, + &bus_mipi_dsi0_clk.common, + &bus_mipi_dsi1_clk.common, &tcon_lcd0_clk.common, &tcon_lcd1_clk.common, &tcon_lcd2_clk.common, + &combophy_dsi0_clk.common, + &combophy_dsi1_clk.common, + &bus_tcon_lcd0_clk.common, + &bus_tcon_lcd1_clk.common, + &bus_tcon_lcd2_clk.common, &tcon_tv0_clk.common, &tcon_tv1_clk.common, + &bus_tcon_tv0_clk.common, + &bus_tcon_tv1_clk.common, &edp_clk.common, + &bus_edp_clk.common, &ledc_clk.common, + &bus_ledc_clk.common, &csi_top_clk.common, &csi_mclk0_clk.common, &csi_mclk1_clk.common, &csi_mclk2_clk.common, &csi_mclk3_clk.common, + &bus_csi_clk.common, &isp_clk.common, &dsp_clk.common, &fanout_24M_clk.common, @@ -1155,56 +1390,128 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { [CLK_APB1] = &apb1_clk.common.hw, [CLK_MBUS] = &mbus_clk.common.hw, [CLK_DE] = &de_clk.common.hw, + [CLK_BUS_DE] = &bus_de_clk.common.hw, [CLK_DI] = &di_clk.common.hw, + [CLK_BUS_DI] = &bus_di_clk.common.hw, [CLK_G2D] = &g2d_clk.common.hw, + [CLK_BUS_G2D] = &bus_g2d_clk.common.hw, [CLK_GPU] = &gpu_clk.common.hw, + [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, [CLK_CE] = &ce_clk.common.hw, + [CLK_BUS_CE] = &bus_ce_clk.common.hw, + [CLK_BUS_CE_SYS] = &bus_ce_sys_clk.common.hw, [CLK_VE] = &ve_clk.common.hw, + [CLK_BUS_VE] = &bus_ve_clk.common.hw, + [CLK_BUS_DMA] = &bus_dma_clk.common.hw, + [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, + [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, [CLK_HSTIMER0] = &hstimer0_clk.common.hw, [CLK_HSTIMER1] = &hstimer1_clk.common.hw, [CLK_HSTIMER2] = &hstimer2_clk.common.hw, [CLK_HSTIMER3] = &hstimer3_clk.common.hw, [CLK_HSTIMER4] = &hstimer4_clk.common.hw, [CLK_HSTIMER5] = &hstimer5_clk.common.hw, + [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, + [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, + [CLK_BUS_PWM0] = &bus_pwm0_clk.common.hw, + [CLK_BUS_PWM1] = &bus_pwm1_clk.common.hw, [CLK_IOMMU] = &iommu_clk.common.hw, + [CLK_BUS_IOMMU] = &bus_iommu_clk.common.hw, [CLK_DRAM] = &dram_clk.common.hw, + [CLK_MBUS_DMA] = &mbus_dma_clk.common.hw, + [CLK_MBUS_VE] = &mbus_ve_clk.common.hw, + [CLK_MBUS_CE] = &mbus_ce_clk.common.hw, + [CLK_MBUS_CSI] = &mbus_csi_clk.common.hw, + [CLK_MBUS_ISP] = &mbus_isp_clk.common.hw, + [CLK_MBUS_EMAC1] = &mbus_gmac1_clk.common.hw, + [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, [CLK_NAND0] = &nand0_clk.common.hw, [CLK_NAND1] = &nand1_clk.common.hw, + [CLK_BUS_NAND] = &bus_nand_clk.common.hw, [CLK_MMC0] = &mmc0_clk.common.hw, [CLK_MMC1] = &mmc1_clk.common.hw, [CLK_MMC2] = &mmc2_clk.common.hw, + [CLK_BUS_SYSDAP] = &bus_sysdap_clk.common.hw, + [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, + [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, + [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, + [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, + [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, + [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, + [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, + [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, + [CLK_BUS_UART5] = &bus_uart5_clk.common.hw, + [CLK_BUS_UART6] = &bus_uart6_clk.common.hw, + [CLK_BUS_UART7] = &bus_uart7_clk.common.hw, + [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, + [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_I2C4] = &bus_i2c4_clk.common.hw, + [CLK_BUS_I2C5] = &bus_i2c5_clk.common.hw, + [CLK_BUS_CAN] = &bus_can_clk.common.hw, [CLK_SPI0] = &spi0_clk.common.hw, [CLK_SPI1] = &spi1_clk.common.hw, [CLK_SPI2] = &spi2_clk.common.hw, [CLK_SPIFC] = &spifc_clk.common.hw, + [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, + [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, + [CLK_BUS_SPI2] = &bus_spi2_clk.common.hw, + [CLK_BUS_SPIFC] = &bus_spifc_clk.common.hw, [CLK_EMAC0_25M] = &emac0_25M_clk.common.hw, [CLK_EMAC1_25M] = &emac1_25M_clk.common.hw, + [CLK_BUS_EMAC0] = &bus_emac0_clk.common.hw, + [CLK_BUS_EMAC1] = &bus_emac1_clk.common.hw, [CLK_IR_RX] = &ir_rx_clk.common.hw, + [CLK_BUS_IR_RX] = &bus_ir_rx_clk.common.hw, [CLK_IR_TX] = &ir_tx_clk.common.hw, + [CLK_BUS_IR_TX] = &bus_ir_tx_clk.common.hw, [CLK_GPADC0] = &gpadc0_clk.common.hw, [CLK_GPADC1] = &gpadc1_clk.common.hw, + [CLK_BUS_GPADC0] = &bus_gpadc0_clk.common.hw, + [CLK_BUS_GPADC1] = &bus_gpadc1_clk.common.hw, + [CLK_BUS_THS] = &bus_ths_clk.common.hw, [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, + [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, + [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw, + [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, + [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw, + [CLK_BUS_OTG] = &bus_otg_clk.common.hw, + [CLK_BUS_LRADC] = &bus_lradc_clk.common.hw, [CLK_PCIE_AUX] = &pcie_aux_clk.common.hw, + [CLK_BUS_DISPLAY0_TOP] = &bus_display0_top_clk.common.hw, + [CLK_BUS_DISPLAY1_TOP] = &bus_display1_top_clk.common.hw, [CLK_HDMI_24M] = &hdmi_24M_clk.common.hw, [CLK_HDMI_CEC_32K] = &hdmi_cec_32k_clk.common.hw, [CLK_HDMI_CEC] = &hdmi_cec_clk.common.hw, + [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, [CLK_MIPI_DSI0] = &mipi_dsi0_clk.common.hw, [CLK_MIPI_DSI1] = &mipi_dsi1_clk.common.hw, + [CLK_BUS_MIPI_DSI0] = &bus_mipi_dsi0_clk.common.hw, + [CLK_BUS_MIPI_DSI1] = &bus_mipi_dsi1_clk.common.hw, [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw, [CLK_TCON_LCD2] = &tcon_lcd2_clk.common.hw, [CLK_COMBOPHY_DSI0] = &combophy_dsi0_clk.common.hw, [CLK_COMBOPHY_DSI1] = &combophy_dsi1_clk.common.hw, + [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw, + [CLK_BUS_TCON_LCD1] = &bus_tcon_lcd1_clk.common.hw, + [CLK_BUS_TCON_LCD2] = &bus_tcon_lcd2_clk.common.hw, [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw, + [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw, + [CLK_BUS_TCON_TV1] = &bus_tcon_tv1_clk.common.hw, [CLK_EDP] = &edp_clk.common.hw, + [CLK_BUS_EDP] = &bus_edp_clk.common.hw, [CLK_LEDC] = &ledc_clk.common.hw, + [CLK_BUS_LEDC] = &bus_ledc_clk.common.hw, [CLK_CSI_TOP] = &csi_top_clk.common.hw, [CLK_CSI_MCLK0] = &csi_mclk0_clk.common.hw, [CLK_CSI_MCLK1] = &csi_mclk1_clk.common.hw, [CLK_CSI_MCLK2] = &csi_mclk2_clk.common.hw, [CLK_CSI_MCLK3] = &csi_mclk3_clk.common.hw, + [CLK_BUS_CSI] = &bus_csi_clk.common.hw, [CLK_ISP] = &isp_clk.common.hw, [CLK_DSP] = &dsp_clk.common.hw, [CLK_FANOUT_24M] = &fanout_24M_clk.common.hw, From a36cc6cd0feb7ea656a1a33db0e6347149f50fed Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:27 +0000 Subject: [PATCH 45/63] clk: sunxi-ng: a523: add reset lines Allwinner SoCs do not contain a separate reset controller, instead the reset lines for the various devices are integrated into the "BGR" (Bus Gate / Reset) registers, for each device group: one for all UARTs, one for all SPI interfaces, and so on. The Allwinner CCU driver also doubles as a reset provider, and since the reset lines are indeed just single bits in those BGR register, we can represent them easily in an array of structs, just containing the register offset and the bit number. Add the location of the reset bits for all devices in the A523/T527 SoCs, using the existing sunxi CCU infrastructure. Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-14-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun55i-a523.c | 84 ++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c index 736544f6a141..9efb9fd24b42 100644 --- a/drivers/clk/sunxi-ng/ccu-sun55i-a523.c +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523.c @@ -1526,11 +1526,95 @@ static struct clk_hw_onecell_data sun55i_a523_hw_clks = { }, }; +static struct ccu_reset_map sun55i_a523_ccu_resets[] = { + [RST_MBUS] = { 0x540, BIT(30) }, + [RST_BUS_NSI] = { 0x54c, BIT(16) }, + [RST_BUS_DE] = { 0x60c, BIT(16) }, + [RST_BUS_DI] = { 0x62c, BIT(16) }, + [RST_BUS_G2D] = { 0x63c, BIT(16) }, + [RST_BUS_SYS] = { 0x64c, BIT(16) }, + [RST_BUS_GPU] = { 0x67c, BIT(16) }, + [RST_BUS_CE] = { 0x68c, BIT(16) }, + [RST_BUS_SYS_CE] = { 0x68c, BIT(17) }, + [RST_BUS_VE] = { 0x69c, BIT(16) }, + [RST_BUS_DMA] = { 0x70c, BIT(16) }, + [RST_BUS_MSGBOX] = { 0x71c, BIT(16) }, + [RST_BUS_SPINLOCK] = { 0x72c, BIT(16) }, + [RST_BUS_CPUXTIMER] = { 0x74c, BIT(16) }, + [RST_BUS_DBG] = { 0x78c, BIT(16) }, + [RST_BUS_PWM0] = { 0x7ac, BIT(16) }, + [RST_BUS_PWM1] = { 0x7ac, BIT(17) }, + [RST_BUS_DRAM] = { 0x80c, BIT(16) }, + [RST_BUS_NAND] = { 0x82c, BIT(16) }, + [RST_BUS_MMC0] = { 0x84c, BIT(16) }, + [RST_BUS_MMC1] = { 0x84c, BIT(17) }, + [RST_BUS_MMC2] = { 0x84c, BIT(18) }, + [RST_BUS_SYSDAP] = { 0x88c, BIT(16) }, + [RST_BUS_UART0] = { 0x90c, BIT(16) }, + [RST_BUS_UART1] = { 0x90c, BIT(17) }, + [RST_BUS_UART2] = { 0x90c, BIT(18) }, + [RST_BUS_UART3] = { 0x90c, BIT(19) }, + [RST_BUS_UART4] = { 0x90c, BIT(20) }, + [RST_BUS_UART5] = { 0x90c, BIT(21) }, + [RST_BUS_UART6] = { 0x90c, BIT(22) }, + [RST_BUS_UART7] = { 0x90c, BIT(23) }, + [RST_BUS_I2C0] = { 0x91c, BIT(16) }, + [RST_BUS_I2C1] = { 0x91c, BIT(17) }, + [RST_BUS_I2C2] = { 0x91c, BIT(18) }, + [RST_BUS_I2C3] = { 0x91c, BIT(19) }, + [RST_BUS_I2C4] = { 0x91c, BIT(20) }, + [RST_BUS_I2C5] = { 0x91c, BIT(21) }, + [RST_BUS_CAN] = { 0x92c, BIT(16) }, + [RST_BUS_SPI0] = { 0x96c, BIT(16) }, + [RST_BUS_SPI1] = { 0x96c, BIT(17) }, + [RST_BUS_SPI2] = { 0x96c, BIT(18) }, + [RST_BUS_SPIFC] = { 0x96c, BIT(19) }, + [RST_BUS_EMAC0] = { 0x97c, BIT(16) }, + [RST_BUS_EMAC1] = { 0x98c, BIT(16) | BIT(17) }, /* GMAC1-AXI */ + [RST_BUS_IR_RX] = { 0x99c, BIT(16) }, + [RST_BUS_IR_TX] = { 0x9cc, BIT(16) }, + [RST_BUS_GPADC0] = { 0x9ec, BIT(16) }, + [RST_BUS_GPADC1] = { 0x9ec, BIT(17) }, + [RST_BUS_THS] = { 0x9fc, BIT(16) }, + [RST_USB_PHY0] = { 0xa70, BIT(30) }, + [RST_USB_PHY1] = { 0xa74, BIT(30) }, + [RST_BUS_OHCI0] = { 0xa8c, BIT(16) }, + [RST_BUS_OHCI1] = { 0xa8c, BIT(17) }, + [RST_BUS_EHCI0] = { 0xa8c, BIT(20) }, + [RST_BUS_EHCI1] = { 0xa8c, BIT(21) }, + [RST_BUS_OTG] = { 0xa8c, BIT(24) }, + [RST_BUS_3] = { 0xa8c, BIT(25) }, /* BSP + register */ + [RST_BUS_LRADC] = { 0xa9c, BIT(16) }, + [RST_BUS_PCIE_USB3] = { 0xaac, BIT(16) }, + [RST_BUS_DISPLAY0_TOP] = { 0xabc, BIT(16) }, + [RST_BUS_DISPLAY1_TOP] = { 0xacc, BIT(16) }, + [RST_BUS_HDMI_MAIN] = { 0xb1c, BIT(16) }, + [RST_BUS_HDMI_SUB] = { 0xb1c, BIT(17) }, + [RST_BUS_MIPI_DSI0] = { 0xb4c, BIT(16) }, + [RST_BUS_MIPI_DSI1] = { 0xb4c, BIT(17) }, + [RST_BUS_TCON_LCD0] = { 0xb7c, BIT(16) }, + [RST_BUS_TCON_LCD1] = { 0xb7c, BIT(17) }, + [RST_BUS_TCON_LCD2] = { 0xb7c, BIT(18) }, + [RST_BUS_TCON_TV0] = { 0xb9c, BIT(16) }, + [RST_BUS_TCON_TV1] = { 0xb9c, BIT(17) }, + [RST_BUS_LVDS0] = { 0xbac, BIT(16) }, + [RST_BUS_LVDS1] = { 0xbac, BIT(17) }, + [RST_BUS_EDP] = { 0xbbc, BIT(16) }, + [RST_BUS_VIDEO_OUT0] = { 0xbcc, BIT(16) }, + [RST_BUS_VIDEO_OUT1] = { 0xbcc, BIT(17) }, + [RST_BUS_LEDC] = { 0xbfc, BIT(16) }, + [RST_BUS_CSI] = { 0xc1c, BIT(16) }, + [RST_BUS_ISP] = { 0xc2c, BIT(16) }, /* BSP + register */ +}; + static const struct sunxi_ccu_desc sun55i_a523_ccu_desc = { .ccu_clks = sun55i_a523_ccu_clks, .num_ccu_clks = ARRAY_SIZE(sun55i_a523_ccu_clks), .hw_clks = &sun55i_a523_hw_clks, + + .resets = sun55i_a523_ccu_resets, + .num_resets = ARRAY_SIZE(sun55i_a523_ccu_resets), }; static const u32 pll_regs[] = { From 8cea339cfb81eb3354b0f27ceb27e2bb107efa6d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 7 Mar 2025 00:26:28 +0000 Subject: [PATCH 46/63] clk: sunxi-ng: add support for the A523/T527 PRCM CCU The A523/T527 SoCs have clock/reset controls in the PRCM part, like many previous SoCs. For a change, the whole PRCM is documented in the A523 manual, including the system bus tree, so we can describe all those clocks correctly based on that. There layout seems to be derived from the H6 and H616 PRCM CCUs, though there are more clocks, and many clocks have subtly changed. Describe all the mod and gate clocks, including the three bus clocks (R_AHB, R_APB0, and R_APB1). Signed-off-by: Andre Przywara Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20250307002628.10684-15-andre.przywara@arm.com Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/Kconfig | 5 + drivers/clk/sunxi-ng/Makefile | 2 + drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c | 248 +++++++++++++++++++++++ drivers/clk/sunxi-ng/ccu-sun55i-a523-r.h | 14 ++ 4 files changed, 269 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c create mode 100644 drivers/clk/sunxi-ng/ccu-sun55i-a523-r.h diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 04efbda847cf..5830a9d87bf2 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -57,6 +57,11 @@ config SUN55I_A523_CCU default y depends on ARM64 || COMPILE_TEST +config SUN55I_A523_R_CCU + tristate "Support for the Allwinner A523/T527 PRCM CCU" + default y + depends on ARM64 || COMPILE_TEST + config SUN4I_A10_CCU tristate "Support for the Allwinner A10/A20 CCU" default y diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 01a887f7824b..82e471036de6 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_SUN50I_H6_CCU) += sun50i-h6-ccu.o obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o obj-$(CONFIG_SUN55I_A523_CCU) += sun55i-a523-ccu.o +obj-$(CONFIG_SUN55I_A523_R_CCU) += sun55i-a523-r-ccu.o obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o obj-$(CONFIG_SUN6I_A31_CCU) += sun6i-a31-ccu.o @@ -60,6 +61,7 @@ sun50i-h6-ccu-y += ccu-sun50i-h6.o sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o sun50i-h616-ccu-y += ccu-sun50i-h616.o sun55i-a523-ccu-y += ccu-sun55i-a523.o +sun55i-a523-r-ccu-y += ccu-sun55i-a523-r.o sun4i-a10-ccu-y += ccu-sun4i-a10.o sun5i-ccu-y += ccu-sun5i.o sun6i-a31-ccu-y += ccu-sun6i-a31.o diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c new file mode 100644 index 000000000000..b5464d8083c8 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.c @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024 Arm Ltd. + * Based on the D1 CCU driver: + * Copyright (c) 2020 huangzhenwei@allwinnertech.com + * Copyright (C) 2021 Samuel Holland + */ + +#include +#include +#include + +#include "ccu_common.h" +#include "ccu_reset.h" + +#include "ccu_gate.h" +#include "ccu_mp.h" + +#include "ccu-sun55i-a523-r.h" + +static const struct clk_parent_data r_ahb_apb_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, + { .fw_name = "pll-periph" }, + { .fw_name = "pll-audio" }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX(r_ahb_clk, "r-ahb", + r_ahb_apb_parents, 0x000, + 0, 5, /* M */ + 24, 3, /* mux */ + 0); + +static SUNXI_CCU_M_DATA_WITH_MUX(r_apb0_clk, "r-apb0", + r_ahb_apb_parents, 0x00c, + 0, 5, /* M */ + 24, 3, /* mux */ + 0); + +static SUNXI_CCU_M_DATA_WITH_MUX(r_apb1_clk, "r-apb1", + r_ahb_apb_parents, 0x010, + 0, 5, /* M */ + 24, 3, /* mux */ + 0); + +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer0, "r-timer0", + r_ahb_apb_parents, 0x100, + 0, 0, /* no M */ + 1, 3, /* P */ + 4, 3, /* mux */ + BIT(0), + 0); +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer1, "r-timer1", + r_ahb_apb_parents, 0x104, + 0, 0, /* no M */ + 1, 3, /* P */ + 4, 3, /* mux */ + BIT(0), + 0); +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer2, "r-timer2", + r_ahb_apb_parents, 0x108, + 0, 0, /* no M */ + 1, 3, /* P */ + 4, 3, /* mux */ + BIT(0), + 0); + +static SUNXI_CCU_GATE_HW(bus_r_timer_clk, "bus-r-timer", &r_ahb_clk.common.hw, + 0x11c, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_twd_clk, "bus-r-twd", &r_apb0_clk.common.hw, + 0x12c, BIT(0), 0); + +static const struct clk_parent_data r_pwmctrl_parents[] = { + { .fw_name = "hosc" }, + { .fw_name = "losc" }, + { .fw_name = "iosc" }, +}; +static SUNXI_CCU_MUX_DATA_WITH_GATE(r_pwmctrl_clk, "r-pwmctrl", + r_pwmctrl_parents, 0x130, + 24, 2, /* mux */ + BIT(31), + 0); +static SUNXI_CCU_GATE_HW(bus_r_pwmctrl_clk, "bus-r-pwmctrl", + &r_apb0_clk.common.hw, 0x13c, BIT(0), 0); + +/* SPI clock is /M/N (same as new MMC?) */ +static SUNXI_CCU_GATE_HW(bus_r_spi_clk, "bus-r-spi", + &r_ahb_clk.common.hw, 0x15c, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_spinlock_clk, "bus-r-spinlock", + &r_ahb_clk.common.hw, 0x16c, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_msgbox_clk, "bus-r-msgbox", + &r_ahb_clk.common.hw, 0x17c, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_uart0_clk, "bus-r-uart0", + &r_apb1_clk.common.hw, 0x18c, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_uart1_clk, "bus-r-uart1", + &r_apb1_clk.common.hw, 0x18c, BIT(1), 0); +static SUNXI_CCU_GATE_HW(bus_r_i2c0_clk, "bus-r-i2c0", + &r_apb1_clk.common.hw, 0x19c, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_i2c1_clk, "bus-r-i2c1", + &r_apb1_clk.common.hw, 0x19c, BIT(1), 0); +static SUNXI_CCU_GATE_HW(bus_r_i2c2_clk, "bus-r-i2c2", + &r_apb1_clk.common.hw, 0x19c, BIT(2), 0); +static SUNXI_CCU_GATE_HW(bus_r_ppu0_clk, "bus-r-ppu0", + &r_apb0_clk.common.hw, 0x1ac, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_ppu1_clk, "bus-r-ppu1", + &r_apb0_clk.common.hw, 0x1ac, BIT(1), 0); +static SUNXI_CCU_GATE_HW(bus_r_cpu_bist_clk, "bus-r-cpu-bist", + &r_apb0_clk.common.hw, 0x1bc, BIT(0), 0); + +static const struct clk_parent_data r_ir_rx_parents[] = { + { .fw_name = "losc" }, + { .fw_name = "hosc" }, +}; +static SUNXI_CCU_M_DATA_WITH_MUX_GATE(r_ir_rx_clk, "r-ir-rx", + r_ir_rx_parents, 0x1c0, + 0, 5, /* M */ + 24, 2, /* mux */ + BIT(31), /* gate */ + 0); +static SUNXI_CCU_GATE_HW(bus_r_ir_rx_clk, "bus-r-ir-rx", + &r_apb0_clk.common.hw, 0x1cc, BIT(0), 0); + +static SUNXI_CCU_GATE_HW(bus_r_dma_clk, "bus-r-dma", + &r_apb0_clk.common.hw, 0x1dc, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_rtc_clk, "bus-r-rtc", + &r_apb0_clk.common.hw, 0x20c, BIT(0), 0); +static SUNXI_CCU_GATE_HW(bus_r_cpucfg_clk, "bus-r-cpucfg", + &r_apb0_clk.common.hw, 0x22c, BIT(0), 0); + +static struct ccu_common *sun55i_a523_r_ccu_clks[] = { + &r_ahb_clk.common, + &r_apb0_clk.common, + &r_apb1_clk.common, + &r_cpu_timer0.common, + &r_cpu_timer1.common, + &r_cpu_timer2.common, + &bus_r_timer_clk.common, + &bus_r_twd_clk.common, + &r_pwmctrl_clk.common, + &bus_r_pwmctrl_clk.common, + &bus_r_spi_clk.common, + &bus_r_spinlock_clk.common, + &bus_r_msgbox_clk.common, + &bus_r_uart0_clk.common, + &bus_r_uart1_clk.common, + &bus_r_i2c0_clk.common, + &bus_r_i2c1_clk.common, + &bus_r_i2c2_clk.common, + &bus_r_ppu0_clk.common, + &bus_r_ppu1_clk.common, + &bus_r_cpu_bist_clk.common, + &r_ir_rx_clk.common, + &bus_r_ir_rx_clk.common, + &bus_r_dma_clk.common, + &bus_r_rtc_clk.common, + &bus_r_cpucfg_clk.common, +}; + +static struct clk_hw_onecell_data sun55i_a523_r_hw_clks = { + .num = CLK_NUMBER, + .hws = { + [CLK_R_AHB] = &r_ahb_clk.common.hw, + [CLK_R_APB0] = &r_apb0_clk.common.hw, + [CLK_R_APB1] = &r_apb1_clk.common.hw, + [CLK_R_TIMER0] = &r_cpu_timer0.common.hw, + [CLK_R_TIMER1] = &r_cpu_timer1.common.hw, + [CLK_R_TIMER2] = &r_cpu_timer2.common.hw, + [CLK_BUS_R_TIMER] = &bus_r_timer_clk.common.hw, + [CLK_BUS_R_TWD] = &bus_r_twd_clk.common.hw, + [CLK_R_PWMCTRL] = &r_pwmctrl_clk.common.hw, + [CLK_BUS_R_PWMCTRL] = &bus_r_pwmctrl_clk.common.hw, + [CLK_BUS_R_SPI] = &bus_r_spi_clk.common.hw, + [CLK_BUS_R_SPINLOCK] = &bus_r_spinlock_clk.common.hw, + [CLK_BUS_R_MSGBOX] = &bus_r_msgbox_clk.common.hw, + [CLK_BUS_R_UART0] = &bus_r_uart0_clk.common.hw, + [CLK_BUS_R_UART1] = &bus_r_uart1_clk.common.hw, + [CLK_BUS_R_I2C0] = &bus_r_i2c0_clk.common.hw, + [CLK_BUS_R_I2C1] = &bus_r_i2c1_clk.common.hw, + [CLK_BUS_R_I2C2] = &bus_r_i2c2_clk.common.hw, + [CLK_BUS_R_PPU0] = &bus_r_ppu0_clk.common.hw, + [CLK_BUS_R_PPU1] = &bus_r_ppu1_clk.common.hw, + [CLK_BUS_R_CPU_BIST] = &bus_r_cpu_bist_clk.common.hw, + [CLK_R_IR_RX] = &r_ir_rx_clk.common.hw, + [CLK_BUS_R_IR_RX] = &bus_r_ir_rx_clk.common.hw, + [CLK_BUS_R_DMA] = &bus_r_dma_clk.common.hw, + [CLK_BUS_R_RTC] = &bus_r_rtc_clk.common.hw, + [CLK_BUS_R_CPUCFG] = &bus_r_cpucfg_clk.common.hw, + }, +}; + +static struct ccu_reset_map sun55i_a523_r_ccu_resets[] = { + [RST_BUS_R_TIMER] = { 0x11c, BIT(16) }, + [RST_BUS_R_TWD] = { 0x12c, BIT(16) }, + [RST_BUS_R_PWMCTRL] = { 0x13c, BIT(16) }, + [RST_BUS_R_SPI] = { 0x15c, BIT(16) }, + [RST_BUS_R_SPINLOCK] = { 0x16c, BIT(16) }, + [RST_BUS_R_MSGBOX] = { 0x17c, BIT(16) }, + [RST_BUS_R_UART0] = { 0x18c, BIT(16) }, + [RST_BUS_R_UART1] = { 0x18c, BIT(17) }, + [RST_BUS_R_I2C0] = { 0x19c, BIT(16) }, + [RST_BUS_R_I2C1] = { 0x19c, BIT(17) }, + [RST_BUS_R_I2C2] = { 0x19c, BIT(18) }, + [RST_BUS_R_PPU1] = { 0x1ac, BIT(17) }, + [RST_BUS_R_IR_RX] = { 0x1cc, BIT(16) }, + [RST_BUS_R_RTC] = { 0x20c, BIT(16) }, + [RST_BUS_R_CPUCFG] = { 0x22c, BIT(16) }, +}; + +static const struct sunxi_ccu_desc sun55i_a523_r_ccu_desc = { + .ccu_clks = sun55i_a523_r_ccu_clks, + .num_ccu_clks = ARRAY_SIZE(sun55i_a523_r_ccu_clks), + + .hw_clks = &sun55i_a523_r_hw_clks, + + .resets = sun55i_a523_r_ccu_resets, + .num_resets = ARRAY_SIZE(sun55i_a523_r_ccu_resets), +}; + +static int sun55i_a523_r_ccu_probe(struct platform_device *pdev) +{ + void __iomem *reg; + + reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun55i_a523_r_ccu_desc); +} + +static const struct of_device_id sun55i_a523_r_ccu_ids[] = { + { .compatible = "allwinner,sun55i-a523-r-ccu" }, + { } +}; +MODULE_DEVICE_TABLE(of, sun55i_a523_r_ccu_ids); + +static struct platform_driver sun55i_a523_r_ccu_driver = { + .probe = sun55i_a523_r_ccu_probe, + .driver = { + .name = "sun55i-a523-r-ccu", + .suppress_bind_attrs = true, + .of_match_table = sun55i_a523_r_ccu_ids, + }, +}; +module_platform_driver(sun55i_a523_r_ccu_driver); + +MODULE_IMPORT_NS("SUNXI_CCU"); +MODULE_DESCRIPTION("Support for the Allwinner A523 PRCM CCU"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.h b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.h new file mode 100644 index 000000000000..d50f46ac4f3f --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun55i-a523-r.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2024 Arm Ltd. + */ + +#ifndef _CCU_SUN55I_A523_R_H +#define _CCU_SUN55I_A523_R_H + +#include +#include + +#define CLK_NUMBER (CLK_BUS_R_CPUCFG + 1) + +#endif /* _CCU_SUN55I_A523_R_H */ From 25708f73ff171bb4171950c9f4be5aa8504b8459 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 14 Feb 2025 09:56:59 +0530 Subject: [PATCH 47/63] clk: qcom: gdsc: Set retain_ff before moving to HW CTRL Enable the retain_ff_enable bit of GDSCR only if the GDSC is already ON. Once the GDSCR moves to HW control, SW no longer can determine the state of the GDSCR and setting the retain_ff bit could destroy all the register contents we intended to save. Therefore, move the retain_ff configuration before switching the GDSC to HW trigger mode. Cc: stable@vger.kernel.org Fixes: 173722995cdb ("clk: qcom: gdsc: Add support to enable retention of GSDCR") Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Tested-by: Imran Shaik # on QCS8300 Link: https://lore.kernel.org/r/20250214-gdsc_fixes-v1-1-73e56d68a80f@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gdsc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 7687661491f1..f3f95f4d9313 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -292,6 +292,9 @@ static int gdsc_enable(struct generic_pm_domain *domain) */ udelay(1); + if (sc->flags & RETAIN_FF_ENABLE) + gdsc_retain_ff_on(sc); + /* Turn on HW trigger mode if supported */ if (sc->flags & HW_CTRL) { ret = gdsc_hwctrl(sc, true); @@ -308,9 +311,6 @@ static int gdsc_enable(struct generic_pm_domain *domain) udelay(1); } - if (sc->flags & RETAIN_FF_ENABLE) - gdsc_retain_ff_on(sc); - return 0; } @@ -457,13 +457,6 @@ static int gdsc_init(struct gdsc *sc) goto err_disable_supply; } - /* Turn on HW trigger mode if supported */ - if (sc->flags & HW_CTRL) { - ret = gdsc_hwctrl(sc, true); - if (ret < 0) - goto err_disable_supply; - } - /* * Make sure the retain bit is set if the GDSC is already on, * otherwise we end up turning off the GDSC and destroying all @@ -471,6 +464,14 @@ static int gdsc_init(struct gdsc *sc) */ if (sc->flags & RETAIN_FF_ENABLE) gdsc_retain_ff_on(sc); + + /* Turn on HW trigger mode if supported */ + if (sc->flags & HW_CTRL) { + ret = gdsc_hwctrl(sc, true); + if (ret < 0) + goto err_disable_supply; + } + } else if (sc->flags & ALWAYS_ON) { /* If ALWAYS_ON GDSCs are not ON, turn them ON */ gdsc_enable(&sc->pd); From 172320f5ead5d1a0eed14472ce84146221c75675 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 14 Feb 2025 09:57:00 +0530 Subject: [PATCH 48/63] clk: qcom: gdsc: Update the status poll timeout for GDSC During the GDSC FSM state, the GDSC hardware waits for an ACK from the respective subsystem core. In some scenarios, this ACK can be delayed. To handle such delays, increase the GDSC status poll timeout from 1500us to 2000us as per the design recommendation. Signed-off-by: Taniya Das Reviewed-by: Imran Shaik Tested-by: Imran Shaik # on QCS8300 Link: https://lore.kernel.org/r/20250214-gdsc_fixes-v1-2-73e56d68a80f@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gdsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index f3f95f4d9313..7deabf8400cf 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -46,7 +46,7 @@ #define RETAIN_MEM BIT(14) #define RETAIN_PERIPH BIT(13) -#define STATUS_POLL_TIMEOUT_US 1500 +#define STATUS_POLL_TIMEOUT_US 2000 #define TIMEOUT_US 500 #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd) From c16e576b8aea9fe985ee9e368ea5fd37eae47b2f Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 21 Feb 2025 15:04:54 +0530 Subject: [PATCH 49/63] dt-bindings: clock: qcom: Add compatible for QCM6490 boards On the QCM6490 boards, the LPASS firmware controls the complete clock controller functionalities and associated power domains. However, only the LPASS resets required to be controlled by the high level OS. Thus, add the new QCM6490 compatible to support the reset functionality for Low Power Audio subsystem. Signed-off-by: Taniya Das Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250221-lpass_qcm6490_resets-v5-1-6be0c0949a83@quicinc.com Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml index 488d63959424..99ab9106009f 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml @@ -20,6 +20,7 @@ description: | properties: compatible: enum: + - qcom,qcm6490-lpassaudiocc - qcom,sc7280-lpassaoncc - qcom,sc7280-lpassaudiocc - qcom,sc7280-lpasscorecc @@ -68,7 +69,9 @@ allOf: properties: compatible: contains: - const: qcom,sc7280-lpassaudiocc + enum: + - qcom,qcm6490-lpassaudiocc + - qcom,sc7280-lpassaudiocc then: properties: From cdbbc480f4146cb659af97f4020601fde5fb65a7 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Fri, 21 Feb 2025 15:04:55 +0530 Subject: [PATCH 50/63] clk: qcom: lpassaudiocc-sc7280: Add support for LPASS resets for QCM6490 On the QCM6490 boards, the LPASS firmware controls the complete clock controller functionalities and associated power domains. However, only the LPASS resets required to be controlled by the high level OS. Thus, add support for the resets in the clock driver to enable the Audio SW driver to assert/deassert the audio resets as needed. Reviewed-by: Dmitry Baryshkov Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/20250221-lpass_qcm6490_resets-v5-2-6be0c0949a83@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/lpassaudiocc-sc7280.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c index 45e726477086..22169da08a51 100644 --- a/drivers/clk/qcom/lpassaudiocc-sc7280.c +++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -713,14 +714,24 @@ static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = { [LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 }, }; +static const struct regmap_config lpass_audio_cc_sc7280_reset_regmap_config = { + .name = "lpassaudio_cc_reset", + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, + .max_register = 0xc8, +}; + static const struct qcom_cc_desc lpass_audio_cc_reset_sc7280_desc = { - .config = &lpass_audio_cc_sc7280_regmap_config, + .config = &lpass_audio_cc_sc7280_reset_regmap_config, .resets = lpass_audio_cc_sc7280_resets, .num_resets = ARRAY_SIZE(lpass_audio_cc_sc7280_resets), }; static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = { - { .compatible = "qcom,sc7280-lpassaudiocc" }, + { .compatible = "qcom,qcm6490-lpassaudiocc", .data = &lpass_audio_cc_reset_sc7280_desc }, + { .compatible = "qcom,sc7280-lpassaudiocc", .data = &lpass_audio_cc_sc7280_desc }, { } }; MODULE_DEVICE_TABLE(of, lpass_audio_cc_sc7280_match_table); @@ -752,13 +763,17 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) struct regmap *regmap; int ret; + desc = device_get_match_data(&pdev->dev); + + if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcm6490-lpassaudiocc")) + return qcom_cc_probe_by_index(pdev, 1, desc); + ret = lpass_audio_setup_runtime_pm(pdev); if (ret) return ret; lpass_audio_cc_sc7280_regmap_config.name = "lpassaudio_cc"; lpass_audio_cc_sc7280_regmap_config.max_register = 0x2f000; - desc = &lpass_audio_cc_sc7280_desc; regmap = qcom_cc_map(pdev, desc); if (IS_ERR(regmap)) { @@ -772,7 +787,7 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev) regmap_write(regmap, 0x4, 0x3b); regmap_write(regmap, 0x8, 0xff05); - ret = qcom_cc_really_probe(&pdev->dev, &lpass_audio_cc_sc7280_desc, regmap); + ret = qcom_cc_really_probe(&pdev->dev, desc, regmap); if (ret) { dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n"); goto exit; From e9ed0ac3ccba65c17ed0d59c77a340a75abc317b Mon Sep 17 00:00:00 2001 From: Manikanta Mylavarapu Date: Thu, 6 Mar 2025 16:59:00 +0530 Subject: [PATCH 51/63] drivers: clk: qcom: ipq5424: fix the freq table of sdcc1_apps clock The divider values in the sdcc1_apps frequency table were incorrectly updated, assuming the frequency of gpll2_out_main to be 1152MHz. However, the frequency of the gpll2_out_main clock is actually 576MHz (gpll2/2). Due to these incorrect divider values, the sdcc1_apps clock is running at half of the expected frequency. Fixing the frequency table of sdcc1_apps allows the sdcc1_apps clock to run according to the frequency plan. Fixes: 21b5d5a4a311 ("clk: qcom: add Global Clock controller (GCC) driver for IPQ5424 SoC") Signed-off-by: Manikanta Mylavarapu Reviewed-by: Kathiravan Thirumoorthy Link: https://lore.kernel.org/r/20250306112900.3319330-1-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq5424.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c index 37b1a3ff8f4e..3d42f3d85c7a 100644 --- a/drivers/clk/qcom/gcc-ipq5424.c +++ b/drivers/clk/qcom/gcc-ipq5424.c @@ -640,11 +640,11 @@ static struct clk_rcg2 gcc_qupv3_uart1_clk_src = { static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { F(144000, P_XO, 16, 12, 125), F(400000, P_XO, 12, 1, 5), - F(24000000, P_XO, 1, 0, 0), - F(48000000, P_GPLL2_OUT_MAIN, 12, 1, 2), - F(96000000, P_GPLL2_OUT_MAIN, 6, 1, 2), + F(24000000, P_GPLL2_OUT_MAIN, 12, 1, 2), + F(48000000, P_GPLL2_OUT_MAIN, 12, 0, 0), + F(96000000, P_GPLL2_OUT_MAIN, 6, 0, 0), F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0), - F(192000000, P_GPLL2_OUT_MAIN, 6, 0, 0), + F(192000000, P_GPLL2_OUT_MAIN, 3, 0, 0), F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0), { } }; From 0079e77c08de692cb20b38e408365c830a44b1ef Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Fri, 13 Dec 2024 11:03:23 +0100 Subject: [PATCH 52/63] clk: amlogic: g12a: fix mmc A peripheral clock The bit index of the peripheral clock for mmc A is wrong This was probably not a problem for mmc A as the peripheral is likely left enabled by the bootloader. No issues has been reported so far but it could be a problem, most likely some form of conflict between the ethernet and mmc A clock, breaking ethernet on init. Use the value provided by the documentation for mmc A before this becomes an actual problem. Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller") Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20241213-amlogic-clk-g12a-mmca-fix-v1-1-5af421f58b64@baylibre.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index cfffd434e998..d978516bba34 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -4311,7 +4311,7 @@ static MESON_GATE(g12a_spicc_1, HHI_GCLK_MPEG0, 14); static MESON_GATE(g12a_hiu_reg, HHI_GCLK_MPEG0, 19); static MESON_GATE(g12a_mipi_dsi_phy, HHI_GCLK_MPEG0, 20); static MESON_GATE(g12a_assist_misc, HHI_GCLK_MPEG0, 23); -static MESON_GATE(g12a_emmc_a, HHI_GCLK_MPEG0, 4); +static MESON_GATE(g12a_emmc_a, HHI_GCLK_MPEG0, 24); static MESON_GATE(g12a_emmc_b, HHI_GCLK_MPEG0, 25); static MESON_GATE(g12a_emmc_c, HHI_GCLK_MPEG0, 26); static MESON_GATE(g12a_audio_codec, HHI_GCLK_MPEG0, 28); From 8995f8f108c3ac5ad52b12a6cfbbc7b3b32e9a58 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Fri, 13 Dec 2024 15:30:17 +0100 Subject: [PATCH 53/63] clk: amlogic: g12b: fix cluster A parent data Several clocks used by both g12a and g12b use the g12a cpu A clock hw pointer as clock parent. This is incorrect on g12b since the parents of cluster A cpu clock are different. Also the hw clock provided as parent to these children is not even registered clock on g12b. Fix the problem by reverting to the global namespace and let CCF pick the appropriate, as it is already done for other clocks, such as cpu_clk_trace_div. Fixes: 25e682a02d91 ("clk: meson: g12a: migrate to the new parent description method") Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20241213-amlogic-clk-g12a-cpua-parent-fix-v1-1-d8c0f41865fe@baylibre.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index d978516bba34..ceabebb1863d 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -1137,8 +1137,18 @@ static struct clk_regmap g12a_cpu_clk_div16_en = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_hws = (const struct clk_hw *[]) { - &g12a_cpu_clk.hw + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * G12A and G12B have different cpu clocks (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so this clock picks + * up the appropriate one. Same goes for the other + * clock using cpu cluster A clock output and present + * on both G12 variant. + */ + .name = "cpu_clk", + .index = -1, }, .num_parents = 1, /* @@ -1203,7 +1213,10 @@ static struct clk_regmap g12a_cpu_clk_apb_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_apb_div", .ops = &clk_regmap_divider_ro_ops, - .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, + .parent_data = &(const struct clk_parent_data) { + .name = "cpu_clk", + .index = -1, + }, .num_parents = 1, }, }; @@ -1237,7 +1250,10 @@ static struct clk_regmap g12a_cpu_clk_atb_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_atb_div", .ops = &clk_regmap_divider_ro_ops, - .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, + .parent_data = &(const struct clk_parent_data) { + .name = "cpu_clk", + .index = -1, + }, .num_parents = 1, }, }; @@ -1271,7 +1287,10 @@ static struct clk_regmap g12a_cpu_clk_axi_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_axi_div", .ops = &clk_regmap_divider_ro_ops, - .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, + .parent_data = &(const struct clk_parent_data) { + .name = "cpu_clk", + .index = -1, + }, .num_parents = 1, }, }; @@ -1306,13 +1325,6 @@ static struct clk_regmap g12a_cpu_clk_trace_div = { .name = "cpu_clk_trace_div", .ops = &clk_regmap_divider_ro_ops, .parent_data = &(const struct clk_parent_data) { - /* - * Note: - * G12A and G12B have different cpu_clks (with - * different struct clk_hw). We fallback to the global - * naming string mechanism so cpu_clk_trace_div picks - * up the appropriate one. - */ .name = "cpu_clk", .index = -1, }, From f38f7fe4830c5cb4eac138249225f119e7939965 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Fri, 20 Dec 2024 11:25:36 +0100 Subject: [PATCH 54/63] clk: amlogic: gxbb: drop incorrect flag on 32k clock gxbb_32k_clk_div sets CLK_DIVIDER_ROUND_CLOSEST in the init_data flag which is incorrect. This is field is not where the divider flags belong. Thankfully, CLK_DIVIDER_ROUND_CLOSEST maps to bit 4 which is an unused clock flag, so there is no unintended consequence to this error. Effectively, the clock has been used without CLK_DIVIDER_ROUND_CLOSEST so far, so just drop it. Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC") Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20241220-amlogic-clk-gxbb-32k-fixes-v1-1-baca56ecf2db@baylibre.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 8575b8485385..df9250de51dc 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -1306,7 +1306,7 @@ static struct clk_regmap gxbb_32k_clk_div = { &gxbb_32k_clk_sel.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, + .flags = CLK_SET_RATE_PARENT, }, }; From 7915d7d5407c026fa9343befb4d3343f7a345f97 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Fri, 20 Dec 2024 11:25:37 +0100 Subject: [PATCH 55/63] clk: amlogic: gxbb: drop non existing 32k clock parent The 32k clock reference a parent 'cts_slow_oscin' with a fixme note saying that this clock should be provided by AO controller. The HW probably has this clock but it does not exist at the moment in any controller implementation. Furthermore, referencing clock by the global name should be avoided whenever possible. There is no reason to keep this hack around, at least for now. Fixes: 14c735c8e308 ("clk: meson-gxbb: Add EE 32K Clock for CEC") Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20241220-amlogic-clk-gxbb-32k-fixes-v1-2-baca56ecf2db@baylibre.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index df9250de51dc..3abb44a2532b 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -1266,14 +1266,13 @@ static struct clk_regmap gxbb_cts_i958 = { }, }; +/* + * This table skips a clock named 'cts_slow_oscin' in the documentation + * This clock does not exist yet in this controller or the AO one + */ +static u32 gxbb_32k_clk_parents_val_table[] = { 0, 2, 3 }; static const struct clk_parent_data gxbb_32k_clk_parent_data[] = { { .fw_name = "xtal", }, - /* - * FIXME: This clock is provided by the ao clock controller but the - * clock is not yet part of the binding of this controller, so string - * name must be use to set this parent. - */ - { .name = "cts_slow_oscin", .index = -1 }, { .hw = &gxbb_fclk_div3.hw }, { .hw = &gxbb_fclk_div5.hw }, }; @@ -1283,6 +1282,7 @@ static struct clk_regmap gxbb_32k_clk_sel = { .offset = HHI_32K_CLK_CNTL, .mask = 0x3, .shift = 16, + .table = gxbb_32k_clk_parents_val_table, }, .hw.init = &(struct clk_init_data){ .name = "32k_clk_sel", From b3c221e752c4e46fd86d6e15153fa8c38bc3f250 Mon Sep 17 00:00:00 2001 From: Jian Hu Date: Tue, 31 Dec 2024 14:25:52 +0800 Subject: [PATCH 56/63] clk: amlogic: a1: fix a typo Fix a typo in MODULE_DESCRIPTION for a1 PLL driver, S4 should be A1. Signed-off-by: Jian Hu Reviewed-by: Dmitry Rokosov Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20241231062552.2982266-1-jian.hu@amlogic.com Signed-off-by: Jerome Brunet --- drivers/clk/meson/a1-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c index 8d7c7b4493c4..86d8159f3319 100644 --- a/drivers/clk/meson/a1-pll.c +++ b/drivers/clk/meson/a1-pll.c @@ -356,7 +356,7 @@ static struct platform_driver a1_pll_clkc_driver = { }; module_platform_driver(a1_pll_clkc_driver); -MODULE_DESCRIPTION("Amlogic S4 PLL Clock Controller driver"); +MODULE_DESCRIPTION("Amlogic A1 PLL Clock Controller driver"); MODULE_AUTHOR("Jian Hu "); MODULE_AUTHOR("Dmitry Rokosov "); MODULE_LICENSE("GPL"); From d547913e87a6a40b8690c069492cddc0cef6c573 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Tue, 4 Mar 2025 16:31:52 +0200 Subject: [PATCH 57/63] dt-bindings: clock: qcom,x1e80100-camcc: Fix the list of required-opps The switch to multiple power domains implies that the required-opps property shall be updated accordingly, a record in one property corresponds to a record in another one. Fixes: 7ec95ff9abf4 ("dt-bindings: clock: move qcom,x1e80100-camcc to its own file") Signed-off-by: Vladimir Zapolskiy Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20250304143152.1799966-1-vladimir.zapolskiy@linaro.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/clock/qcom,x1e80100-camcc.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml index 5bbbaa15a260..938a2f1ff3fc 100644 --- a/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-camcc.yaml @@ -40,9 +40,9 @@ properties: - description: A phandle to the MMCX power-domain required-opps: - maxItems: 1 - description: - A phandle to an OPP node describing MMCX performance points. + items: + - description: A phandle to an OPP node describing MXC performance points + - description: A phandle to an OPP node describing MMCX performance points required: - compatible @@ -66,7 +66,8 @@ examples: <&sleep_clk>; power-domains = <&rpmhpd RPMHPD_MXC>, <&rpmhpd RPMHPD_MMCX>; - required-opps = <&rpmhpd_opp_low_svs>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; From 000cbe3896c56bf5c625e286ff096533a6b27657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20Cz=C3=A9m=C3=A1n?= Date: Sat, 15 Mar 2025 16:26:17 +0100 Subject: [PATCH 58/63] clk: qcom: mmcc-sdm660: fix stuck video_subcore0 clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This clock can't be enable with VENUS_CORE0 GDSC turned off. But that GDSC is under HW control so it can be turned off at any moment. Instead of checking the dependent clock we can just vote for it to enable later when GDSC gets turned on. Fixes: 5db3ae8b33de6 ("clk: qcom: Add SDM660 Multimedia Clock Controller (MMCC) driver") Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20250315-clock-fix-v1-1-2efdc4920dda@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/mmcc-sdm660.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index e5bdcc75a36e..e69fc65b13da 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -2540,7 +2540,7 @@ static struct clk_branch video_core_clk = { static struct clk_branch video_subcore0_clk = { .halt_reg = 0x1048, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x1048, .enable_mask = BIT(0), From cdc59600bccf2cb4c483645438a97d4ec55f326b Mon Sep 17 00:00:00 2001 From: Vladimir Lypak Date: Sat, 15 Mar 2025 16:26:18 +0100 Subject: [PATCH 59/63] clk: qcom: gcc-msm8953: fix stuck venus0_core0 clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This clock can't be enable with VENUS_CORE0 GDSC turned off. But that GDSC is under HW control so it can be turned off at any moment. Instead of checking the dependent clock we can just vote for it to enable later when GDSC gets turned on. Fixes: 9bb6cfc3c77e6 ("clk: qcom: Add Global Clock Controller driver for MSM8953") Signed-off-by: Vladimir Lypak Signed-off-by: Barnabás Czémán Link: https://lore.kernel.org/r/20250315-clock-fix-v1-2-2efdc4920dda@mainlining.org Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-msm8953.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c index 855a61966f3e..8f29ecc74c50 100644 --- a/drivers/clk/qcom/gcc-msm8953.c +++ b/drivers/clk/qcom/gcc-msm8953.c @@ -3770,7 +3770,7 @@ static struct clk_branch gcc_venus0_axi_clk = { static struct clk_branch gcc_venus0_core0_vcodec0_clk = { .halt_reg = 0x4c02c, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x4c02c, .enable_mask = BIT(0), From 07986c5b36c479a2a42067331e0625157dc41afd Mon Sep 17 00:00:00 2001 From: Devi Priya Date: Thu, 13 Mar 2025 16:33:54 +0530 Subject: [PATCH 60/63] dt-bindings: clock: gcc-ipq9574: Add definition for GPLL0_OUT_AUX Add the definition for GPLL0_OUT_AUX clock. Acked-by: Krzysztof Kozlowski Signed-off-by: Devi Priya Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20250313110359.242491-2-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- include/dt-bindings/clock/qcom,ipq9574-gcc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/qcom,ipq9574-gcc.h b/include/dt-bindings/clock/qcom,ipq9574-gcc.h index f238aa4794a8..0e7c319897f3 100644 --- a/include/dt-bindings/clock/qcom,ipq9574-gcc.h +++ b/include/dt-bindings/clock/qcom,ipq9574-gcc.h @@ -202,4 +202,5 @@ #define GCC_PCIE1_PIPE_CLK 211 #define GCC_PCIE2_PIPE_CLK 212 #define GCC_PCIE3_PIPE_CLK 213 +#define GPLL0_OUT_AUX 214 #endif From 28300ecedce41dad239e0779d0b640349db33ec6 Mon Sep 17 00:00:00 2001 From: Devi Priya Date: Thu, 13 Mar 2025 16:33:56 +0530 Subject: [PATCH 61/63] dt-bindings: clock: Add ipq9574 NSSCC clock and reset definitions Add NSSCC clock and reset definitions for ipq9574. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Devi Priya Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20250313110359.242491-4-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- .../bindings/clock/qcom,ipq9574-nsscc.yaml | 98 +++++++++++ .../dt-bindings/clock/qcom,ipq9574-nsscc.h | 152 ++++++++++++++++++ .../dt-bindings/reset/qcom,ipq9574-nsscc.h | 134 +++++++++++++++ 3 files changed, 384 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml create mode 100644 include/dt-bindings/clock/qcom,ipq9574-nsscc.h create mode 100644 include/dt-bindings/reset/qcom,ipq9574-nsscc.h diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml new file mode 100644 index 000000000000..17252b6ea3be --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-nsscc.yaml @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,ipq9574-nsscc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Networking Sub System Clock & Reset Controller on IPQ9574 + +maintainers: + - Bjorn Andersson + - Anusha Rao + +description: | + Qualcomm networking sub system clock control module provides the clocks, + resets on IPQ9574 + + See also:: + include/dt-bindings/clock/qcom,ipq9574-nsscc.h + include/dt-bindings/reset/qcom,ipq9574-nsscc.h + +properties: + compatible: + const: qcom,ipq9574-nsscc + + clocks: + items: + - description: Board XO source + - description: CMN_PLL NSS 1200MHz (Bias PLL cc) clock source + - description: CMN_PLL PPE 353MHz (Bias PLL ubi nc) clock source + - description: GCC GPLL0 OUT AUX clock source + - description: Uniphy0 NSS Rx clock source + - description: Uniphy0 NSS Tx clock source + - description: Uniphy1 NSS Rx clock source + - description: Uniphy1 NSS Tx clock source + - description: Uniphy2 NSS Rx clock source + - description: Uniphy2 NSS Tx clock source + - description: GCC NSSCC clock source + + '#interconnect-cells': + const: 1 + + clock-names: + items: + - const: xo + - const: nss_1200 + - const: ppe_353 + - const: gpll0_out + - const: uniphy0_rx + - const: uniphy0_tx + - const: uniphy1_rx + - const: uniphy1_tx + - const: uniphy2_rx + - const: uniphy2_tx + - const: bus + +required: + - compatible + - clocks + - clock-names + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + clock-controller@39b00000 { + compatible = "qcom,ipq9574-nsscc"; + reg = <0x39b00000 0x80000>; + clocks = <&xo_board_clk>, + <&cmn_pll NSS_1200MHZ_CLK>, + <&cmn_pll PPE_353MHZ_CLK>, + <&gcc GPLL0_OUT_AUX>, + <&uniphy 0>, + <&uniphy 1>, + <&uniphy 2>, + <&uniphy 3>, + <&uniphy 4>, + <&uniphy 5>, + <&gcc GCC_NSSCC_CLK>; + clock-names = "xo", + "nss_1200", + "ppe_353", + "gpll0_out", + "uniphy0_rx", + "uniphy0_tx", + "uniphy1_rx", + "uniphy1_tx", + "uniphy2_rx", + "uniphy2_tx", + "bus"; + #clock-cells = <1>; + #reset-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/qcom,ipq9574-nsscc.h b/include/dt-bindings/clock/qcom,ipq9574-nsscc.h new file mode 100644 index 000000000000..21a16dc0e64c --- /dev/null +++ b/include/dt-bindings/clock/qcom,ipq9574-nsscc.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023, 2025 The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLOCK_IPQ_NSSCC_9574_H +#define _DT_BINDINGS_CLOCK_IPQ_NSSCC_9574_H + +#define NSS_CC_CE_APB_CLK 0 +#define NSS_CC_CE_AXI_CLK 1 +#define NSS_CC_CE_CLK_SRC 2 +#define NSS_CC_CFG_CLK_SRC 3 +#define NSS_CC_CLC_AXI_CLK 4 +#define NSS_CC_CLC_CLK_SRC 5 +#define NSS_CC_CRYPTO_CLK 6 +#define NSS_CC_CRYPTO_CLK_SRC 7 +#define NSS_CC_CRYPTO_PPE_CLK 8 +#define NSS_CC_HAQ_AHB_CLK 9 +#define NSS_CC_HAQ_AXI_CLK 10 +#define NSS_CC_HAQ_CLK_SRC 11 +#define NSS_CC_IMEM_AHB_CLK 12 +#define NSS_CC_IMEM_CLK_SRC 13 +#define NSS_CC_IMEM_QSB_CLK 14 +#define NSS_CC_INT_CFG_CLK_SRC 15 +#define NSS_CC_NSS_CSR_CLK 16 +#define NSS_CC_NSSNOC_CE_APB_CLK 17 +#define NSS_CC_NSSNOC_CE_AXI_CLK 18 +#define NSS_CC_NSSNOC_CLC_AXI_CLK 19 +#define NSS_CC_NSSNOC_CRYPTO_CLK 20 +#define NSS_CC_NSSNOC_HAQ_AHB_CLK 21 +#define NSS_CC_NSSNOC_HAQ_AXI_CLK 22 +#define NSS_CC_NSSNOC_IMEM_AHB_CLK 23 +#define NSS_CC_NSSNOC_IMEM_QSB_CLK 24 +#define NSS_CC_NSSNOC_NSS_CSR_CLK 25 +#define NSS_CC_NSSNOC_PPE_CFG_CLK 26 +#define NSS_CC_NSSNOC_PPE_CLK 27 +#define NSS_CC_NSSNOC_UBI32_AHB0_CLK 28 +#define NSS_CC_NSSNOC_UBI32_AXI0_CLK 29 +#define NSS_CC_NSSNOC_UBI32_INT0_AHB_CLK 30 +#define NSS_CC_NSSNOC_UBI32_NC_AXI0_1_CLK 31 +#define NSS_CC_NSSNOC_UBI32_NC_AXI0_CLK 32 +#define NSS_CC_PORT1_MAC_CLK 33 +#define NSS_CC_PORT1_RX_CLK 34 +#define NSS_CC_PORT1_RX_CLK_SRC 35 +#define NSS_CC_PORT1_RX_DIV_CLK_SRC 36 +#define NSS_CC_PORT1_TX_CLK 37 +#define NSS_CC_PORT1_TX_CLK_SRC 38 +#define NSS_CC_PORT1_TX_DIV_CLK_SRC 39 +#define NSS_CC_PORT2_MAC_CLK 40 +#define NSS_CC_PORT2_RX_CLK 41 +#define NSS_CC_PORT2_RX_CLK_SRC 42 +#define NSS_CC_PORT2_RX_DIV_CLK_SRC 43 +#define NSS_CC_PORT2_TX_CLK 44 +#define NSS_CC_PORT2_TX_CLK_SRC 45 +#define NSS_CC_PORT2_TX_DIV_CLK_SRC 46 +#define NSS_CC_PORT3_MAC_CLK 47 +#define NSS_CC_PORT3_RX_CLK 48 +#define NSS_CC_PORT3_RX_CLK_SRC 49 +#define NSS_CC_PORT3_RX_DIV_CLK_SRC 50 +#define NSS_CC_PORT3_TX_CLK 51 +#define NSS_CC_PORT3_TX_CLK_SRC 52 +#define NSS_CC_PORT3_TX_DIV_CLK_SRC 53 +#define NSS_CC_PORT4_MAC_CLK 54 +#define NSS_CC_PORT4_RX_CLK 55 +#define NSS_CC_PORT4_RX_CLK_SRC 56 +#define NSS_CC_PORT4_RX_DIV_CLK_SRC 57 +#define NSS_CC_PORT4_TX_CLK 58 +#define NSS_CC_PORT4_TX_CLK_SRC 59 +#define NSS_CC_PORT4_TX_DIV_CLK_SRC 60 +#define NSS_CC_PORT5_MAC_CLK 61 +#define NSS_CC_PORT5_RX_CLK 62 +#define NSS_CC_PORT5_RX_CLK_SRC 63 +#define NSS_CC_PORT5_RX_DIV_CLK_SRC 64 +#define NSS_CC_PORT5_TX_CLK 65 +#define NSS_CC_PORT5_TX_CLK_SRC 66 +#define NSS_CC_PORT5_TX_DIV_CLK_SRC 67 +#define NSS_CC_PORT6_MAC_CLK 68 +#define NSS_CC_PORT6_RX_CLK 69 +#define NSS_CC_PORT6_RX_CLK_SRC 70 +#define NSS_CC_PORT6_RX_DIV_CLK_SRC 71 +#define NSS_CC_PORT6_TX_CLK 72 +#define NSS_CC_PORT6_TX_CLK_SRC 73 +#define NSS_CC_PORT6_TX_DIV_CLK_SRC 74 +#define NSS_CC_PPE_CLK_SRC 75 +#define NSS_CC_PPE_EDMA_CFG_CLK 76 +#define NSS_CC_PPE_EDMA_CLK 77 +#define NSS_CC_PPE_SWITCH_BTQ_CLK 78 +#define NSS_CC_PPE_SWITCH_CFG_CLK 79 +#define NSS_CC_PPE_SWITCH_CLK 80 +#define NSS_CC_PPE_SWITCH_IPE_CLK 81 +#define NSS_CC_UBI0_CLK_SRC 82 +#define NSS_CC_UBI0_DIV_CLK_SRC 83 +#define NSS_CC_UBI1_CLK_SRC 84 +#define NSS_CC_UBI1_DIV_CLK_SRC 85 +#define NSS_CC_UBI2_CLK_SRC 86 +#define NSS_CC_UBI2_DIV_CLK_SRC 87 +#define NSS_CC_UBI32_AHB0_CLK 88 +#define NSS_CC_UBI32_AHB1_CLK 89 +#define NSS_CC_UBI32_AHB2_CLK 90 +#define NSS_CC_UBI32_AHB3_CLK 91 +#define NSS_CC_UBI32_AXI0_CLK 92 +#define NSS_CC_UBI32_AXI1_CLK 93 +#define NSS_CC_UBI32_AXI2_CLK 94 +#define NSS_CC_UBI32_AXI3_CLK 95 +#define NSS_CC_UBI32_CORE0_CLK 96 +#define NSS_CC_UBI32_CORE1_CLK 97 +#define NSS_CC_UBI32_CORE2_CLK 98 +#define NSS_CC_UBI32_CORE3_CLK 99 +#define NSS_CC_UBI32_INTR0_AHB_CLK 100 +#define NSS_CC_UBI32_INTR1_AHB_CLK 101 +#define NSS_CC_UBI32_INTR2_AHB_CLK 102 +#define NSS_CC_UBI32_INTR3_AHB_CLK 103 +#define NSS_CC_UBI32_NC_AXI0_CLK 104 +#define NSS_CC_UBI32_NC_AXI1_CLK 105 +#define NSS_CC_UBI32_NC_AXI2_CLK 106 +#define NSS_CC_UBI32_NC_AXI3_CLK 107 +#define NSS_CC_UBI32_UTCM0_CLK 108 +#define NSS_CC_UBI32_UTCM1_CLK 109 +#define NSS_CC_UBI32_UTCM2_CLK 110 +#define NSS_CC_UBI32_UTCM3_CLK 111 +#define NSS_CC_UBI3_CLK_SRC 112 +#define NSS_CC_UBI3_DIV_CLK_SRC 113 +#define NSS_CC_UBI_AXI_CLK_SRC 114 +#define NSS_CC_UBI_NC_AXI_BFDCD_CLK_SRC 115 +#define NSS_CC_UNIPHY_PORT1_RX_CLK 116 +#define NSS_CC_UNIPHY_PORT1_TX_CLK 117 +#define NSS_CC_UNIPHY_PORT2_RX_CLK 118 +#define NSS_CC_UNIPHY_PORT2_TX_CLK 119 +#define NSS_CC_UNIPHY_PORT3_RX_CLK 120 +#define NSS_CC_UNIPHY_PORT3_TX_CLK 121 +#define NSS_CC_UNIPHY_PORT4_RX_CLK 122 +#define NSS_CC_UNIPHY_PORT4_TX_CLK 123 +#define NSS_CC_UNIPHY_PORT5_RX_CLK 124 +#define NSS_CC_UNIPHY_PORT5_TX_CLK 125 +#define NSS_CC_UNIPHY_PORT6_RX_CLK 126 +#define NSS_CC_UNIPHY_PORT6_TX_CLK 127 +#define NSS_CC_XGMAC0_PTP_REF_CLK 128 +#define NSS_CC_XGMAC0_PTP_REF_DIV_CLK_SRC 129 +#define NSS_CC_XGMAC1_PTP_REF_CLK 130 +#define NSS_CC_XGMAC1_PTP_REF_DIV_CLK_SRC 131 +#define NSS_CC_XGMAC2_PTP_REF_CLK 132 +#define NSS_CC_XGMAC2_PTP_REF_DIV_CLK_SRC 133 +#define NSS_CC_XGMAC3_PTP_REF_CLK 134 +#define NSS_CC_XGMAC3_PTP_REF_DIV_CLK_SRC 135 +#define NSS_CC_XGMAC4_PTP_REF_CLK 136 +#define NSS_CC_XGMAC4_PTP_REF_DIV_CLK_SRC 137 +#define NSS_CC_XGMAC5_PTP_REF_CLK 138 +#define NSS_CC_XGMAC5_PTP_REF_DIV_CLK_SRC 139 +#define UBI32_PLL 140 +#define UBI32_PLL_MAIN 141 + +#endif diff --git a/include/dt-bindings/reset/qcom,ipq9574-nsscc.h b/include/dt-bindings/reset/qcom,ipq9574-nsscc.h new file mode 100644 index 000000000000..7f152e98b99c --- /dev/null +++ b/include/dt-bindings/reset/qcom,ipq9574-nsscc.h @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023, 2025 The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_RESET_IPQ_NSSCC_9574_H +#define _DT_BINDINGS_RESET_IPQ_NSSCC_9574_H + +#define EDMA_HW_RESET 0 +#define NSS_CC_CE_BCR 1 +#define NSS_CC_CLC_BCR 2 +#define NSS_CC_EIP197_BCR 3 +#define NSS_CC_HAQ_BCR 4 +#define NSS_CC_IMEM_BCR 5 +#define NSS_CC_MAC_BCR 6 +#define NSS_CC_PPE_BCR 7 +#define NSS_CC_UBI_BCR 8 +#define NSS_CC_UNIPHY_BCR 9 +#define UBI3_CLKRST_CLAMP_ENABLE 10 +#define UBI3_CORE_CLAMP_ENABLE 11 +#define UBI2_CLKRST_CLAMP_ENABLE 12 +#define UBI2_CORE_CLAMP_ENABLE 13 +#define UBI1_CLKRST_CLAMP_ENABLE 14 +#define UBI1_CORE_CLAMP_ENABLE 15 +#define UBI0_CLKRST_CLAMP_ENABLE 16 +#define UBI0_CORE_CLAMP_ENABLE 17 +#define NSSNOC_NSS_CSR_ARES 18 +#define NSS_CSR_ARES 19 +#define PPE_BTQ_ARES 20 +#define PPE_IPE_ARES 21 +#define PPE_ARES 22 +#define PPE_CFG_ARES 23 +#define PPE_EDMA_ARES 24 +#define PPE_EDMA_CFG_ARES 25 +#define CRY_PPE_ARES 26 +#define NSSNOC_PPE_ARES 27 +#define NSSNOC_PPE_CFG_ARES 28 +#define PORT1_MAC_ARES 29 +#define PORT2_MAC_ARES 30 +#define PORT3_MAC_ARES 31 +#define PORT4_MAC_ARES 32 +#define PORT5_MAC_ARES 33 +#define PORT6_MAC_ARES 34 +#define XGMAC0_PTP_REF_ARES 35 +#define XGMAC1_PTP_REF_ARES 36 +#define XGMAC2_PTP_REF_ARES 37 +#define XGMAC3_PTP_REF_ARES 38 +#define XGMAC4_PTP_REF_ARES 39 +#define XGMAC5_PTP_REF_ARES 40 +#define HAQ_AHB_ARES 41 +#define HAQ_AXI_ARES 42 +#define NSSNOC_HAQ_AHB_ARES 43 +#define NSSNOC_HAQ_AXI_ARES 44 +#define CE_APB_ARES 45 +#define CE_AXI_ARES 46 +#define NSSNOC_CE_APB_ARES 47 +#define NSSNOC_CE_AXI_ARES 48 +#define CRYPTO_ARES 49 +#define NSSNOC_CRYPTO_ARES 50 +#define NSSNOC_NC_AXI0_1_ARES 51 +#define UBI0_CORE_ARES 52 +#define UBI1_CORE_ARES 53 +#define UBI2_CORE_ARES 54 +#define UBI3_CORE_ARES 55 +#define NC_AXI0_ARES 56 +#define UTCM0_ARES 57 +#define NC_AXI1_ARES 58 +#define UTCM1_ARES 59 +#define NC_AXI2_ARES 60 +#define UTCM2_ARES 61 +#define NC_AXI3_ARES 62 +#define UTCM3_ARES 63 +#define NSSNOC_NC_AXI0_ARES 64 +#define AHB0_ARES 65 +#define INTR0_AHB_ARES 66 +#define AHB1_ARES 67 +#define INTR1_AHB_ARES 68 +#define AHB2_ARES 69 +#define INTR2_AHB_ARES 70 +#define AHB3_ARES 71 +#define INTR3_AHB_ARES 72 +#define NSSNOC_AHB0_ARES 73 +#define NSSNOC_INT0_AHB_ARES 74 +#define AXI0_ARES 75 +#define AXI1_ARES 76 +#define AXI2_ARES 77 +#define AXI3_ARES 78 +#define NSSNOC_AXI0_ARES 79 +#define IMEM_QSB_ARES 80 +#define NSSNOC_IMEM_QSB_ARES 81 +#define IMEM_AHB_ARES 82 +#define NSSNOC_IMEM_AHB_ARES 83 +#define UNIPHY_PORT1_RX_ARES 84 +#define UNIPHY_PORT1_TX_ARES 85 +#define UNIPHY_PORT2_RX_ARES 86 +#define UNIPHY_PORT2_TX_ARES 87 +#define UNIPHY_PORT3_RX_ARES 88 +#define UNIPHY_PORT3_TX_ARES 89 +#define UNIPHY_PORT4_RX_ARES 90 +#define UNIPHY_PORT4_TX_ARES 91 +#define UNIPHY_PORT5_RX_ARES 92 +#define UNIPHY_PORT5_TX_ARES 93 +#define UNIPHY_PORT6_RX_ARES 94 +#define UNIPHY_PORT6_TX_ARES 95 +#define PORT1_RX_ARES 96 +#define PORT1_TX_ARES 97 +#define PORT2_RX_ARES 98 +#define PORT2_TX_ARES 99 +#define PORT3_RX_ARES 100 +#define PORT3_TX_ARES 101 +#define PORT4_RX_ARES 102 +#define PORT4_TX_ARES 103 +#define PORT5_RX_ARES 104 +#define PORT5_TX_ARES 105 +#define PORT6_RX_ARES 106 +#define PORT6_TX_ARES 107 +#define PPE_FULL_RESET 108 +#define UNIPHY0_SOFT_RESET 109 +#define UNIPHY1_SOFT_RESET 110 +#define UNIPHY2_SOFT_RESET 111 +#define UNIPHY_PORT1_ARES 112 +#define UNIPHY_PORT2_ARES 113 +#define UNIPHY_PORT3_ARES 114 +#define UNIPHY_PORT4_ARES 115 +#define UNIPHY_PORT5_ARES 116 +#define UNIPHY_PORT6_ARES 117 +#define NSSPORT1_RESET 118 +#define NSSPORT2_RESET 119 +#define NSSPORT3_RESET 120 +#define NSSPORT4_RESET 121 +#define NSSPORT5_RESET 122 +#define NSSPORT6_RESET 123 + +#endif From 6e89ef8f697b6bad611a35570a1681f8a92aae9d Mon Sep 17 00:00:00 2001 From: Devi Priya Date: Thu, 13 Mar 2025 16:33:55 +0530 Subject: [PATCH 62/63] clk: qcom: gcc-ipq9574: Add support for gpll0_out_aux clock Add support for gpll0_out_aux clock which acts as the parent for certain networking subsystem (nss) clocks. Reviewed-by: Dmitry Baryshkov Signed-off-by: Devi Priya Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20250313110359.242491-3-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/gcc-ipq9574.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c index 6bb66a7e1fb6..6dc86e686de4 100644 --- a/drivers/clk/qcom/gcc-ipq9574.c +++ b/drivers/clk/qcom/gcc-ipq9574.c @@ -108,6 +108,20 @@ static struct clk_alpha_pll_postdiv gpll0 = { }, }; +static struct clk_alpha_pll_postdiv gpll0_out_aux = { + .offset = 0x20000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0_out_aux", + .parent_hws = (const struct clk_hw *[]) { + &gpll0_main.clkr.hw + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + }, +}; + static struct clk_alpha_pll gpll4_main = { .offset = 0x22000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], @@ -3896,6 +3910,7 @@ static struct clk_regmap *gcc_ipq9574_clks[] = { [GCC_PCIE1_PIPE_CLK] = &gcc_pcie1_pipe_clk.clkr, [GCC_PCIE2_PIPE_CLK] = &gcc_pcie2_pipe_clk.clkr, [GCC_PCIE3_PIPE_CLK] = &gcc_pcie3_pipe_clk.clkr, + [GPLL0_OUT_AUX] = &gpll0_out_aux.clkr, }; static const struct qcom_reset_map gcc_ipq9574_resets[] = { From 9bf3684e0f7e65298ff844fd81e6dc5105c67354 Mon Sep 17 00:00:00 2001 From: Devi Priya Date: Thu, 13 Mar 2025 16:33:57 +0530 Subject: [PATCH 63/63] clk: qcom: Add NSS clock Controller driver for IPQ9574 Add Networking Sub System Clock Controller (NSSCC) driver for ipq9574 based devices. Reviewed-by: Konrad Dybcio Signed-off-by: Devi Priya Signed-off-by: Manikanta Mylavarapu Link: https://lore.kernel.org/r/20250313110359.242491-5-quic_mmanikan@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/clk/qcom/Kconfig | 7 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/nsscc-ipq9574.c | 3110 ++++++++++++++++++++++++++++++ 3 files changed, 3118 insertions(+) create mode 100644 drivers/clk/qcom/nsscc-ipq9574.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index d470ed007854..7d5dac26b244 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -281,6 +281,13 @@ config IPQ_GCC_9574 i2c, USB, SD/eMMC, etc. Select this for the root clock of ipq9574. +config IPQ_NSSCC_9574 + tristate "IPQ9574 NSS Clock Controller" + depends on ARM64 || COMPILE_TEST + depends on IPQ_GCC_9574 + help + Support for NSS clock controller on ipq9574 devices. + config IPQ_NSSCC_QCA8K tristate "QCA8K(QCA8386 or QCA8084) NSS Clock Controller" depends on MDIO_BUS diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 0db2f98bcb3e..96862e99e5d4 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o obj-$(CONFIG_IPQ_GCC_9574) += gcc-ipq9574.o +obj-$(CONFIG_IPQ_NSSCC_9574) += nsscc-ipq9574.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o obj-$(CONFIG_IPQ_NSSCC_QCA8K) += nsscc-qca8k.o obj-$(CONFIG_MDM_GCC_9607) += gcc-mdm9607.o diff --git a/drivers/clk/qcom/nsscc-ipq9574.c b/drivers/clk/qcom/nsscc-ipq9574.c new file mode 100644 index 000000000000..64c6b05ff066 --- /dev/null +++ b/drivers/clk/qcom/nsscc-ipq9574.c @@ -0,0 +1,3110 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "reset.h" + +/* Need to match the order of clocks in DT binding */ +enum { + DT_XO, + DT_BIAS_PLL_CC_CLK, + DT_BIAS_PLL_UBI_NC_CLK, + DT_GCC_GPLL0_OUT_AUX, + DT_UNIPHY0_NSS_RX_CLK, + DT_UNIPHY0_NSS_TX_CLK, + DT_UNIPHY1_NSS_RX_CLK, + DT_UNIPHY1_NSS_TX_CLK, + DT_UNIPHY2_NSS_RX_CLK, + DT_UNIPHY2_NSS_TX_CLK, +}; + +enum { + P_XO, + P_BIAS_PLL_CC_CLK, + P_BIAS_PLL_UBI_NC_CLK, + P_GCC_GPLL0_OUT_AUX, + P_UBI32_PLL_OUT_MAIN, + P_UNIPHY0_NSS_RX_CLK, + P_UNIPHY0_NSS_TX_CLK, + P_UNIPHY1_NSS_RX_CLK, + P_UNIPHY1_NSS_TX_CLK, + P_UNIPHY2_NSS_RX_CLK, + P_UNIPHY2_NSS_TX_CLK, +}; + +static const struct alpha_pll_config ubi32_pll_config = { + .l = 0x3e, + .alpha = 0x6666, + .config_ctl_val = 0x200d4aa8, + .config_ctl_hi_val = 0x3c, + .main_output_mask = BIT(0), + .aux_output_mask = BIT(1), + .pre_div_val = 0x0, + .pre_div_mask = BIT(12), + .post_div_val = 0x0, + .post_div_mask = GENMASK(9, 8), + .alpha_en_mask = BIT(24), + .test_ctl_val = 0x1c0000c0, + .test_ctl_hi_val = 0x4000, +}; + +static struct clk_alpha_pll ubi32_pll_main = { + .offset = 0x28000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA], + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "ubi32_pll_main", + .parent_data = &(const struct clk_parent_data) { + .index = DT_XO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_huayra_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv ubi32_pll = { + .offset = 0x28000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA], + .width = 2, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "ubi32_pll", + .parent_hws = (const struct clk_hw *[]) { + &ubi32_pll_main.clkr.hw + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ro_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct parent_map nss_cc_parent_map_0[] = { + { P_XO, 0 }, + { P_BIAS_PLL_CC_CLK, 1 }, + { P_UNIPHY0_NSS_RX_CLK, 2 }, + { P_UNIPHY0_NSS_TX_CLK, 3 }, + { P_UNIPHY1_NSS_RX_CLK, 4 }, + { P_UNIPHY1_NSS_TX_CLK, 5 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_0[] = { + { .index = DT_XO }, + { .index = DT_BIAS_PLL_CC_CLK }, + { .index = DT_UNIPHY0_NSS_RX_CLK }, + { .index = DT_UNIPHY0_NSS_TX_CLK }, + { .index = DT_UNIPHY1_NSS_RX_CLK }, + { .index = DT_UNIPHY1_NSS_TX_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_1[] = { + { P_XO, 0 }, + { P_BIAS_PLL_UBI_NC_CLK, 1 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_BIAS_PLL_CC_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_1[] = { + { .index = DT_XO }, + { .index = DT_BIAS_PLL_UBI_NC_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_BIAS_PLL_CC_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_2[] = { + { P_XO, 0 }, + { P_UBI32_PLL_OUT_MAIN, 1 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_2[] = { + { .index = DT_XO }, + { .hw = &ubi32_pll.clkr.hw }, + { .index = DT_GCC_GPLL0_OUT_AUX }, +}; + +static const struct parent_map nss_cc_parent_map_3[] = { + { P_XO, 0 }, + { P_BIAS_PLL_CC_CLK, 1 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_3[] = { + { .index = DT_XO }, + { .index = DT_BIAS_PLL_CC_CLK }, + { .index = DT_GCC_GPLL0_OUT_AUX }, +}; + +static const struct parent_map nss_cc_parent_map_4[] = { + { P_XO, 0 }, + { P_BIAS_PLL_CC_CLK, 1 }, + { P_UNIPHY0_NSS_RX_CLK, 2 }, + { P_UNIPHY0_NSS_TX_CLK, 3 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_4[] = { + { .index = DT_XO }, + { .index = DT_BIAS_PLL_CC_CLK }, + { .index = DT_UNIPHY0_NSS_RX_CLK }, + { .index = DT_UNIPHY0_NSS_TX_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_5[] = { + { P_XO, 0 }, + { P_BIAS_PLL_CC_CLK, 1 }, + { P_UNIPHY2_NSS_RX_CLK, 2 }, + { P_UNIPHY2_NSS_TX_CLK, 3 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_5[] = { + { .index = DT_XO }, + { .index = DT_BIAS_PLL_CC_CLK }, + { .index = DT_UNIPHY2_NSS_RX_CLK }, + { .index = DT_UNIPHY2_NSS_TX_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_6[] = { + { P_XO, 0 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_BIAS_PLL_CC_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_6[] = { + { .index = DT_XO }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_BIAS_PLL_CC_CLK }, +}; + +static const struct parent_map nss_cc_parent_map_7[] = { + { P_XO, 0 }, + { P_UBI32_PLL_OUT_MAIN, 1 }, + { P_GCC_GPLL0_OUT_AUX, 2 }, + { P_BIAS_PLL_CC_CLK, 6 }, +}; + +static const struct clk_parent_data nss_cc_parent_data_7[] = { + { .index = DT_XO }, + { .hw = &ubi32_pll.clkr.hw }, + { .index = DT_GCC_GPLL0_OUT_AUX }, + { .index = DT_BIAS_PLL_CC_CLK }, +}; + +static const struct freq_tbl ftbl_nss_cc_ce_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(353000000, P_BIAS_PLL_UBI_NC_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_ce_clk_src = { + .cmd_rcgr = 0x28404, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ce_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_cfg_clk_src[] = { + F(100000000, P_GCC_GPLL0_OUT_AUX, 8, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_cfg_clk_src = { + .cmd_rcgr = 0x28104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_3, + .freq_tbl = ftbl_nss_cc_cfg_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_cfg_clk_src", + .parent_data = nss_cc_parent_data_3, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_clc_clk_src[] = { + F(533333333, P_GCC_GPLL0_OUT_AUX, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_clc_clk_src = { + .cmd_rcgr = 0x28604, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_6, + .freq_tbl = ftbl_nss_cc_clc_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_clc_clk_src", + .parent_data = nss_cc_parent_data_6, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_6), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_crypto_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(300000000, P_BIAS_PLL_CC_CLK, 4, 0, 0), + F(600000000, P_BIAS_PLL_CC_CLK, 2, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_crypto_clk_src = { + .cmd_rcgr = 0x16008, + .mnd_width = 16, + .hid_width = 5, + .parent_map = nss_cc_parent_map_3, + .freq_tbl = ftbl_nss_cc_crypto_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_crypto_clk_src", + .parent_data = nss_cc_parent_data_3, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_cc_haq_clk_src = { + .cmd_rcgr = 0x28304, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_haq_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_cc_imem_clk_src = { + .cmd_rcgr = 0xe008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_imem_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_int_cfg_clk_src[] = { + F(200000000, P_GCC_GPLL0_OUT_AUX, 4, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_int_cfg_clk_src = { + .cmd_rcgr = 0x287b4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_3, + .freq_tbl = ftbl_nss_cc_int_cfg_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_int_cfg_clk_src", + .parent_data = nss_cc_parent_data_3, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_25[] = { + C(P_UNIPHY0_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port1_rx_clk_src_125[] = { + C(P_UNIPHY0_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port1_rx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port1_rx_clk_src_25), + FMS(78125000, P_UNIPHY0_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port1_rx_clk_src_125), + FMS(312500000, P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_25[] = { + C(P_UNIPHY0_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port1_tx_clk_src_125[] = { + C(P_UNIPHY0_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port1_tx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port1_tx_clk_src_25), + FMS(78125000, P_UNIPHY0_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port1_tx_clk_src_125), + FMS(312500000, P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_25[] = { + C(P_UNIPHY1_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_125[] = { + C(P_UNIPHY1_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_312p5[] = { + C(P_UNIPHY1_NSS_RX_CLK, 1, 0, 0), + C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port5_rx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port5_rx_clk_src_25), + FMS(78125000, P_UNIPHY1_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port5_rx_clk_src_125), + FMS(156250000, P_UNIPHY1_NSS_RX_CLK, 2, 0, 0), + FM(312500000, ftbl_nss_cc_port5_rx_clk_src_312p5), + { } +}; + +static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_25[] = { + C(P_UNIPHY1_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_125[] = { + C(P_UNIPHY1_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_312p5[] = { + C(P_UNIPHY1_NSS_TX_CLK, 1, 0, 0), + C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port5_tx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port5_tx_clk_src_25), + FMS(78125000, P_UNIPHY1_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port5_tx_clk_src_125), + FMS(156250000, P_UNIPHY1_NSS_TX_CLK, 2, 0, 0), + FM(312500000, ftbl_nss_cc_port5_tx_clk_src_312p5), + { } +}; + +static const struct freq_conf ftbl_nss_cc_port6_rx_clk_src_25[] = { + C(P_UNIPHY2_NSS_RX_CLK, 12.5, 0, 0), + C(P_UNIPHY2_NSS_RX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port6_rx_clk_src_125[] = { + C(P_UNIPHY2_NSS_RX_CLK, 2.5, 0, 0), + C(P_UNIPHY2_NSS_RX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port6_rx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port6_rx_clk_src_25), + FMS(78125000, P_UNIPHY2_NSS_RX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port6_rx_clk_src_125), + FMS(156250000, P_UNIPHY2_NSS_RX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY2_NSS_RX_CLK, 1, 0, 0), + { } +}; + +static const struct freq_conf ftbl_nss_cc_port6_tx_clk_src_25[] = { + C(P_UNIPHY2_NSS_TX_CLK, 12.5, 0, 0), + C(P_UNIPHY2_NSS_TX_CLK, 5, 0, 0), +}; + +static const struct freq_conf ftbl_nss_cc_port6_tx_clk_src_125[] = { + C(P_UNIPHY2_NSS_TX_CLK, 2.5, 0, 0), + C(P_UNIPHY2_NSS_TX_CLK, 1, 0, 0), +}; + +static const struct freq_multi_tbl ftbl_nss_cc_port6_tx_clk_src[] = { + FMS(24000000, P_XO, 1, 0, 0), + FM(25000000, ftbl_nss_cc_port6_tx_clk_src_25), + FMS(78125000, P_UNIPHY2_NSS_TX_CLK, 4, 0, 0), + FM(125000000, ftbl_nss_cc_port6_tx_clk_src_125), + FMS(156250000, P_UNIPHY2_NSS_TX_CLK, 2, 0, 0), + FMS(312500000, P_UNIPHY2_NSS_TX_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_port1_rx_clk_src = { + .cmd_rcgr = 0x28110, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_rx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port1_tx_clk_src = { + .cmd_rcgr = 0x2811c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_tx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port2_rx_clk_src = { + .cmd_rcgr = 0x28128, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_rx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port2_tx_clk_src = { + .cmd_rcgr = 0x28134, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_tx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port3_rx_clk_src = { + .cmd_rcgr = 0x28140, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_rx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port3_tx_clk_src = { + .cmd_rcgr = 0x2814c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_tx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port4_rx_clk_src = { + .cmd_rcgr = 0x28158, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port4_rx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port4_tx_clk_src = { + .cmd_rcgr = 0x28164, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_4, + .freq_multi_tbl = ftbl_nss_cc_port1_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port4_tx_clk_src", + .parent_data = nss_cc_parent_data_4, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_4), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port5_rx_clk_src = { + .cmd_rcgr = 0x28170, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_multi_tbl = ftbl_nss_cc_port5_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port5_rx_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port5_tx_clk_src = { + .cmd_rcgr = 0x2817c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_0, + .freq_multi_tbl = ftbl_nss_cc_port5_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port5_tx_clk_src", + .parent_data = nss_cc_parent_data_0, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_0), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port6_rx_clk_src = { + .cmd_rcgr = 0x28188, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_5, + .freq_multi_tbl = ftbl_nss_cc_port6_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port6_rx_clk_src", + .parent_data = nss_cc_parent_data_5, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_5), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_port6_tx_clk_src = { + .cmd_rcgr = 0x28194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_5, + .freq_multi_tbl = ftbl_nss_cc_port6_tx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port6_tx_clk_src", + .parent_data = nss_cc_parent_data_5, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_5), + .ops = &clk_rcg2_fm_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ppe_clk_src = { + .cmd_rcgr = 0x28204, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ppe_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_nss_cc_ubi0_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(187200000, P_UBI32_PLL_OUT_MAIN, 8, 0, 0), + F(748800000, P_UBI32_PLL_OUT_MAIN, 2, 0, 0), + F(1497600000, P_UBI32_PLL_OUT_MAIN, 1, 0, 0), + F(1689600000, P_UBI32_PLL_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 nss_cc_ubi0_clk_src = { + .cmd_rcgr = 0x28704, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_tbl = ftbl_nss_cc_ubi0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi0_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ubi1_clk_src = { + .cmd_rcgr = 0x2870c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_tbl = ftbl_nss_cc_ubi0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi1_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ubi2_clk_src = { + .cmd_rcgr = 0x28714, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_tbl = ftbl_nss_cc_ubi0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi2_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ubi3_clk_src = { + .cmd_rcgr = 0x2871c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_2, + .freq_tbl = ftbl_nss_cc_ubi0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi3_clk_src", + .parent_data = nss_cc_parent_data_2, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ubi_axi_clk_src = { + .cmd_rcgr = 0x28724, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_7, + .freq_tbl = ftbl_nss_cc_clc_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi_axi_clk_src", + .parent_data = nss_cc_parent_data_7, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_7), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 nss_cc_ubi_nc_axi_bfdcd_clk_src = { + .cmd_rcgr = 0x2872c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = nss_cc_parent_map_1, + .freq_tbl = ftbl_nss_cc_ce_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi_nc_axi_bfdcd_clk_src", + .parent_data = nss_cc_parent_data_1, + .num_parents = ARRAY_SIZE(nss_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port1_rx_div_clk_src = { + .reg = 0x28118, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_rx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port1_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port1_tx_div_clk_src = { + .reg = 0x28124, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_tx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port1_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port2_rx_div_clk_src = { + .reg = 0x28130, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_rx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port2_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port2_tx_div_clk_src = { + .reg = 0x2813c, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_tx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port2_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port3_rx_div_clk_src = { + .reg = 0x28148, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_rx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port3_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port3_tx_div_clk_src = { + .reg = 0x28154, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_tx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port3_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port4_rx_div_clk_src = { + .reg = 0x28160, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port4_rx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port4_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port4_tx_div_clk_src = { + .reg = 0x2816c, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port4_tx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port4_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port5_rx_div_clk_src = { + .reg = 0x28178, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port5_rx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port5_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port5_tx_div_clk_src = { + .reg = 0x28184, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port5_tx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port5_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port6_rx_div_clk_src = { + .reg = 0x28190, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port6_rx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port6_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_port6_tx_div_clk_src = { + .reg = 0x2819c, + .shift = 0, + .width = 9, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port6_tx_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port6_tx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div nss_cc_ubi0_div_clk_src = { + .reg = 0x287a4, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi0_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_ubi1_div_clk_src = { + .reg = 0x287a8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi1_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_ubi2_div_clk_src = { + .reg = 0x287ac, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi2_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_ubi3_div_clk_src = { + .reg = 0x287b0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi3_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac0_ptp_ref_div_clk_src = { + .reg = 0x28214, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac0_ptp_ref_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac1_ptp_ref_div_clk_src = { + .reg = 0x28218, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac1_ptp_ref_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac2_ptp_ref_div_clk_src = { + .reg = 0x2821c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac2_ptp_ref_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac3_ptp_ref_div_clk_src = { + .reg = 0x28220, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac3_ptp_ref_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac4_ptp_ref_div_clk_src = { + .reg = 0x28224, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac4_ptp_ref_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div nss_cc_xgmac5_ptp_ref_div_clk_src = { + .reg = 0x28228, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac5_ptp_ref_div_clk_src", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch nss_cc_ce_apb_clk = { + .halt_reg = 0x2840c, + .clkr = { + .enable_reg = 0x2840c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ce_apb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ce_axi_clk = { + .halt_reg = 0x28410, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28410, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ce_axi_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_clc_axi_clk = { + .halt_reg = 0x2860c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2860c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_clc_axi_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_clc_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1601c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_crypto_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_crypto_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_crypto_ppe_clk = { + .halt_reg = 0x28240, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28240, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_crypto_ppe_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_haq_ahb_clk = { + .halt_reg = 0x2830c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2830c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_haq_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_haq_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_haq_axi_clk = { + .halt_reg = 0x28310, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28310, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_haq_axi_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_haq_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_imem_ahb_clk = { + .halt_reg = 0xe018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_imem_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_imem_qsb_clk = { + .halt_reg = 0xe010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_imem_qsb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_imem_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nss_csr_clk = { + .halt_reg = 0x281d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nss_csr_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ce_apb_clk = { + .halt_reg = 0x28414, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28414, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ce_apb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ce_axi_clk = { + .halt_reg = 0x28418, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28418, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ce_axi_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ce_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_clc_axi_clk = { + .halt_reg = 0x28610, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28610, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_clc_axi_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_clc_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_crypto_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_crypto_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_crypto_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_haq_ahb_clk = { + .halt_reg = 0x28314, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28314, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_haq_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_haq_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_haq_axi_clk = { + .halt_reg = 0x28318, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28318, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_haq_axi_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_haq_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_imem_ahb_clk = { + .halt_reg = 0xe01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_imem_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_imem_qsb_clk = { + .halt_reg = 0xe014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xe014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_imem_qsb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_imem_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_nss_csr_clk = { + .halt_reg = 0x281d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_nss_csr_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ppe_cfg_clk = { + .halt_reg = 0x28248, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28248, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ppe_cfg_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ppe_clk = { + .halt_reg = 0x28244, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28244, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ppe_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ubi32_ahb0_clk = { + .halt_reg = 0x28788, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28788, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ubi32_ahb0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ubi32_axi0_clk = { + .halt_reg = 0x287a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x287a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ubi32_axi0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ubi32_int0_ahb_clk = { + .halt_reg = 0x2878c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2878c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ubi32_int0_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_int_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ubi32_nc_axi0_1_clk = { + .halt_reg = 0x287bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x287bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ubi32_nc_axi0_1_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_nssnoc_ubi32_nc_axi0_clk = { + .halt_reg = 0x28764, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28764, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_nssnoc_ubi32_nc_axi0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_mac_clk = { + .halt_reg = 0x2824c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2824c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_mac_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_rx_clk = { + .halt_reg = 0x281a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port1_tx_clk = { + .halt_reg = 0x281a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port1_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_mac_clk = { + .halt_reg = 0x28250, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28250, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_mac_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_rx_clk = { + .halt_reg = 0x281a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port2_tx_clk = { + .halt_reg = 0x281ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port2_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_mac_clk = { + .halt_reg = 0x28254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_mac_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_rx_clk = { + .halt_reg = 0x281b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port3_tx_clk = { + .halt_reg = 0x281b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port3_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port4_mac_clk = { + .halt_reg = 0x28258, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28258, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port4_mac_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port4_rx_clk = { + .halt_reg = 0x281b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port4_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port4_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port4_tx_clk = { + .halt_reg = 0x281bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port4_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port4_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port5_mac_clk = { + .halt_reg = 0x2825c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2825c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port5_mac_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port5_rx_clk = { + .halt_reg = 0x281c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port5_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port5_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port5_tx_clk = { + .halt_reg = 0x281c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port5_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port5_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port6_mac_clk = { + .halt_reg = 0x28260, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28260, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port6_mac_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port6_rx_clk = { + .halt_reg = 0x281c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port6_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port6_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_port6_tx_clk = { + .halt_reg = 0x281cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x281cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_port6_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port6_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_edma_cfg_clk = { + .halt_reg = 0x2823c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2823c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ppe_edma_cfg_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_edma_clk = { + .halt_reg = 0x28238, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28238, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ppe_edma_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_btq_clk = { + .halt_reg = 0x2827c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2827c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ppe_switch_btq_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_cfg_clk = { + .halt_reg = 0x28234, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28234, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ppe_switch_cfg_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_clk = { + .halt_reg = 0x28230, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28230, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ppe_switch_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ppe_switch_ipe_clk = { + .halt_reg = 0x2822c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2822c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ppe_switch_ipe_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ppe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_ahb0_clk = { + .halt_reg = 0x28768, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28768, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_ahb0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_ahb1_clk = { + .halt_reg = 0x28770, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28770, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_ahb1_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_ahb2_clk = { + .halt_reg = 0x28778, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28778, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_ahb2_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_ahb3_clk = { + .halt_reg = 0x28780, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28780, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_ahb3_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_axi0_clk = { + .halt_reg = 0x28790, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28790, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_axi0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_axi1_clk = { + .halt_reg = 0x28794, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28794, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_axi1_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_axi2_clk = { + .halt_reg = 0x28798, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28798, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_axi2_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_axi3_clk = { + .halt_reg = 0x2879c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2879c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_axi3_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_core0_clk = { + .halt_reg = 0x28734, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28734, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_core0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_core1_clk = { + .halt_reg = 0x28738, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28738, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_core1_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_core2_clk = { + .halt_reg = 0x2873c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2873c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_core2_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi2_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_core3_clk = { + .halt_reg = 0x28740, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28740, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_core3_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi3_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_intr0_ahb_clk = { + .halt_reg = 0x2876c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2876c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_intr0_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_int_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_intr1_ahb_clk = { + .halt_reg = 0x28774, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28774, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_intr1_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_int_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_intr2_ahb_clk = { + .halt_reg = 0x2877c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2877c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_intr2_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_int_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_intr3_ahb_clk = { + .halt_reg = 0x28784, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28784, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_intr3_ahb_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_int_cfg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_nc_axi0_clk = { + .halt_reg = 0x28744, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28744, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_nc_axi0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_nc_axi1_clk = { + .halt_reg = 0x2874c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2874c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_nc_axi1_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_nc_axi2_clk = { + .halt_reg = 0x28754, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28754, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_nc_axi2_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_nc_axi3_clk = { + .halt_reg = 0x2875c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2875c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_nc_axi3_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_utcm0_clk = { + .halt_reg = 0x28748, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28748, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_utcm0_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_utcm1_clk = { + .halt_reg = 0x28750, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28750, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_utcm1_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_utcm2_clk = { + .halt_reg = 0x28758, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28758, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_utcm2_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_ubi32_utcm3_clk = { + .halt_reg = 0x28760, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28760, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_ubi32_utcm3_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port1_rx_clk = { + .halt_reg = 0x28904, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28904, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port1_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port1_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port1_tx_clk = { + .halt_reg = 0x28908, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28908, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port1_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port1_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port2_rx_clk = { + .halt_reg = 0x2890c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2890c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port2_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port2_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port2_tx_clk = { + .halt_reg = 0x28910, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28910, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port2_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port2_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port3_rx_clk = { + .halt_reg = 0x28914, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28914, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port3_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port3_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port3_tx_clk = { + .halt_reg = 0x28918, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28918, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port3_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port3_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port4_rx_clk = { + .halt_reg = 0x2891c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2891c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port4_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port4_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port4_tx_clk = { + .halt_reg = 0x28920, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28920, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port4_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port4_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port5_rx_clk = { + .halt_reg = 0x28924, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28924, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port5_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port5_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port5_tx_clk = { + .halt_reg = 0x28928, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28928, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port5_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port5_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port6_rx_clk = { + .halt_reg = 0x2892c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2892c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port6_rx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port6_rx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_uniphy_port6_tx_clk = { + .halt_reg = 0x28930, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28930, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_uniphy_port6_tx_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_port6_tx_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac0_ptp_ref_clk = { + .halt_reg = 0x28264, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28264, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac0_ptp_ref_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac1_ptp_ref_clk = { + .halt_reg = 0x28268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28268, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac1_ptp_ref_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac2_ptp_ref_clk = { + .halt_reg = 0x2826c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2826c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac2_ptp_ref_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac3_ptp_ref_clk = { + .halt_reg = 0x28270, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28270, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac3_ptp_ref_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_xgmac3_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac4_ptp_ref_clk = { + .halt_reg = 0x28274, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28274, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac4_ptp_ref_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_xgmac4_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch nss_cc_xgmac5_ptp_ref_clk = { + .halt_reg = 0x28278, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x28278, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "nss_cc_xgmac5_ptp_ref_clk", + .parent_data = &(const struct clk_parent_data) { + .hw = &nss_cc_xgmac5_ptp_ref_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *nss_cc_ipq9574_clocks[] = { + [NSS_CC_CE_APB_CLK] = &nss_cc_ce_apb_clk.clkr, + [NSS_CC_CE_AXI_CLK] = &nss_cc_ce_axi_clk.clkr, + [NSS_CC_CE_CLK_SRC] = &nss_cc_ce_clk_src.clkr, + [NSS_CC_CFG_CLK_SRC] = &nss_cc_cfg_clk_src.clkr, + [NSS_CC_CLC_AXI_CLK] = &nss_cc_clc_axi_clk.clkr, + [NSS_CC_CLC_CLK_SRC] = &nss_cc_clc_clk_src.clkr, + [NSS_CC_CRYPTO_CLK] = &nss_cc_crypto_clk.clkr, + [NSS_CC_CRYPTO_CLK_SRC] = &nss_cc_crypto_clk_src.clkr, + [NSS_CC_CRYPTO_PPE_CLK] = &nss_cc_crypto_ppe_clk.clkr, + [NSS_CC_HAQ_AHB_CLK] = &nss_cc_haq_ahb_clk.clkr, + [NSS_CC_HAQ_AXI_CLK] = &nss_cc_haq_axi_clk.clkr, + [NSS_CC_HAQ_CLK_SRC] = &nss_cc_haq_clk_src.clkr, + [NSS_CC_IMEM_AHB_CLK] = &nss_cc_imem_ahb_clk.clkr, + [NSS_CC_IMEM_CLK_SRC] = &nss_cc_imem_clk_src.clkr, + [NSS_CC_IMEM_QSB_CLK] = &nss_cc_imem_qsb_clk.clkr, + [NSS_CC_INT_CFG_CLK_SRC] = &nss_cc_int_cfg_clk_src.clkr, + [NSS_CC_NSS_CSR_CLK] = &nss_cc_nss_csr_clk.clkr, + [NSS_CC_NSSNOC_CE_APB_CLK] = &nss_cc_nssnoc_ce_apb_clk.clkr, + [NSS_CC_NSSNOC_CE_AXI_CLK] = &nss_cc_nssnoc_ce_axi_clk.clkr, + [NSS_CC_NSSNOC_CLC_AXI_CLK] = &nss_cc_nssnoc_clc_axi_clk.clkr, + [NSS_CC_NSSNOC_CRYPTO_CLK] = &nss_cc_nssnoc_crypto_clk.clkr, + [NSS_CC_NSSNOC_HAQ_AHB_CLK] = &nss_cc_nssnoc_haq_ahb_clk.clkr, + [NSS_CC_NSSNOC_HAQ_AXI_CLK] = &nss_cc_nssnoc_haq_axi_clk.clkr, + [NSS_CC_NSSNOC_IMEM_AHB_CLK] = &nss_cc_nssnoc_imem_ahb_clk.clkr, + [NSS_CC_NSSNOC_IMEM_QSB_CLK] = &nss_cc_nssnoc_imem_qsb_clk.clkr, + [NSS_CC_NSSNOC_NSS_CSR_CLK] = &nss_cc_nssnoc_nss_csr_clk.clkr, + [NSS_CC_NSSNOC_PPE_CFG_CLK] = &nss_cc_nssnoc_ppe_cfg_clk.clkr, + [NSS_CC_NSSNOC_PPE_CLK] = &nss_cc_nssnoc_ppe_clk.clkr, + [NSS_CC_NSSNOC_UBI32_AHB0_CLK] = &nss_cc_nssnoc_ubi32_ahb0_clk.clkr, + [NSS_CC_NSSNOC_UBI32_AXI0_CLK] = &nss_cc_nssnoc_ubi32_axi0_clk.clkr, + [NSS_CC_NSSNOC_UBI32_INT0_AHB_CLK] = + &nss_cc_nssnoc_ubi32_int0_ahb_clk.clkr, + [NSS_CC_NSSNOC_UBI32_NC_AXI0_1_CLK] = + &nss_cc_nssnoc_ubi32_nc_axi0_1_clk.clkr, + [NSS_CC_NSSNOC_UBI32_NC_AXI0_CLK] = + &nss_cc_nssnoc_ubi32_nc_axi0_clk.clkr, + [NSS_CC_PORT1_MAC_CLK] = &nss_cc_port1_mac_clk.clkr, + [NSS_CC_PORT1_RX_CLK] = &nss_cc_port1_rx_clk.clkr, + [NSS_CC_PORT1_RX_CLK_SRC] = &nss_cc_port1_rx_clk_src.clkr, + [NSS_CC_PORT1_RX_DIV_CLK_SRC] = &nss_cc_port1_rx_div_clk_src.clkr, + [NSS_CC_PORT1_TX_CLK] = &nss_cc_port1_tx_clk.clkr, + [NSS_CC_PORT1_TX_CLK_SRC] = &nss_cc_port1_tx_clk_src.clkr, + [NSS_CC_PORT1_TX_DIV_CLK_SRC] = &nss_cc_port1_tx_div_clk_src.clkr, + [NSS_CC_PORT2_MAC_CLK] = &nss_cc_port2_mac_clk.clkr, + [NSS_CC_PORT2_RX_CLK] = &nss_cc_port2_rx_clk.clkr, + [NSS_CC_PORT2_RX_CLK_SRC] = &nss_cc_port2_rx_clk_src.clkr, + [NSS_CC_PORT2_RX_DIV_CLK_SRC] = &nss_cc_port2_rx_div_clk_src.clkr, + [NSS_CC_PORT2_TX_CLK] = &nss_cc_port2_tx_clk.clkr, + [NSS_CC_PORT2_TX_CLK_SRC] = &nss_cc_port2_tx_clk_src.clkr, + [NSS_CC_PORT2_TX_DIV_CLK_SRC] = &nss_cc_port2_tx_div_clk_src.clkr, + [NSS_CC_PORT3_MAC_CLK] = &nss_cc_port3_mac_clk.clkr, + [NSS_CC_PORT3_RX_CLK] = &nss_cc_port3_rx_clk.clkr, + [NSS_CC_PORT3_RX_CLK_SRC] = &nss_cc_port3_rx_clk_src.clkr, + [NSS_CC_PORT3_RX_DIV_CLK_SRC] = &nss_cc_port3_rx_div_clk_src.clkr, + [NSS_CC_PORT3_TX_CLK] = &nss_cc_port3_tx_clk.clkr, + [NSS_CC_PORT3_TX_CLK_SRC] = &nss_cc_port3_tx_clk_src.clkr, + [NSS_CC_PORT3_TX_DIV_CLK_SRC] = &nss_cc_port3_tx_div_clk_src.clkr, + [NSS_CC_PORT4_MAC_CLK] = &nss_cc_port4_mac_clk.clkr, + [NSS_CC_PORT4_RX_CLK] = &nss_cc_port4_rx_clk.clkr, + [NSS_CC_PORT4_RX_CLK_SRC] = &nss_cc_port4_rx_clk_src.clkr, + [NSS_CC_PORT4_RX_DIV_CLK_SRC] = &nss_cc_port4_rx_div_clk_src.clkr, + [NSS_CC_PORT4_TX_CLK] = &nss_cc_port4_tx_clk.clkr, + [NSS_CC_PORT4_TX_CLK_SRC] = &nss_cc_port4_tx_clk_src.clkr, + [NSS_CC_PORT4_TX_DIV_CLK_SRC] = &nss_cc_port4_tx_div_clk_src.clkr, + [NSS_CC_PORT5_MAC_CLK] = &nss_cc_port5_mac_clk.clkr, + [NSS_CC_PORT5_RX_CLK] = &nss_cc_port5_rx_clk.clkr, + [NSS_CC_PORT5_RX_CLK_SRC] = &nss_cc_port5_rx_clk_src.clkr, + [NSS_CC_PORT5_RX_DIV_CLK_SRC] = &nss_cc_port5_rx_div_clk_src.clkr, + [NSS_CC_PORT5_TX_CLK] = &nss_cc_port5_tx_clk.clkr, + [NSS_CC_PORT5_TX_CLK_SRC] = &nss_cc_port5_tx_clk_src.clkr, + [NSS_CC_PORT5_TX_DIV_CLK_SRC] = &nss_cc_port5_tx_div_clk_src.clkr, + [NSS_CC_PORT6_MAC_CLK] = &nss_cc_port6_mac_clk.clkr, + [NSS_CC_PORT6_RX_CLK] = &nss_cc_port6_rx_clk.clkr, + [NSS_CC_PORT6_RX_CLK_SRC] = &nss_cc_port6_rx_clk_src.clkr, + [NSS_CC_PORT6_RX_DIV_CLK_SRC] = &nss_cc_port6_rx_div_clk_src.clkr, + [NSS_CC_PORT6_TX_CLK] = &nss_cc_port6_tx_clk.clkr, + [NSS_CC_PORT6_TX_CLK_SRC] = &nss_cc_port6_tx_clk_src.clkr, + [NSS_CC_PORT6_TX_DIV_CLK_SRC] = &nss_cc_port6_tx_div_clk_src.clkr, + [NSS_CC_PPE_CLK_SRC] = &nss_cc_ppe_clk_src.clkr, + [NSS_CC_PPE_EDMA_CFG_CLK] = &nss_cc_ppe_edma_cfg_clk.clkr, + [NSS_CC_PPE_EDMA_CLK] = &nss_cc_ppe_edma_clk.clkr, + [NSS_CC_PPE_SWITCH_BTQ_CLK] = &nss_cc_ppe_switch_btq_clk.clkr, + [NSS_CC_PPE_SWITCH_CFG_CLK] = &nss_cc_ppe_switch_cfg_clk.clkr, + [NSS_CC_PPE_SWITCH_CLK] = &nss_cc_ppe_switch_clk.clkr, + [NSS_CC_PPE_SWITCH_IPE_CLK] = &nss_cc_ppe_switch_ipe_clk.clkr, + [NSS_CC_UBI0_CLK_SRC] = &nss_cc_ubi0_clk_src.clkr, + [NSS_CC_UBI0_DIV_CLK_SRC] = &nss_cc_ubi0_div_clk_src.clkr, + [NSS_CC_UBI1_CLK_SRC] = &nss_cc_ubi1_clk_src.clkr, + [NSS_CC_UBI1_DIV_CLK_SRC] = &nss_cc_ubi1_div_clk_src.clkr, + [NSS_CC_UBI2_CLK_SRC] = &nss_cc_ubi2_clk_src.clkr, + [NSS_CC_UBI2_DIV_CLK_SRC] = &nss_cc_ubi2_div_clk_src.clkr, + [NSS_CC_UBI32_AHB0_CLK] = &nss_cc_ubi32_ahb0_clk.clkr, + [NSS_CC_UBI32_AHB1_CLK] = &nss_cc_ubi32_ahb1_clk.clkr, + [NSS_CC_UBI32_AHB2_CLK] = &nss_cc_ubi32_ahb2_clk.clkr, + [NSS_CC_UBI32_AHB3_CLK] = &nss_cc_ubi32_ahb3_clk.clkr, + [NSS_CC_UBI32_AXI0_CLK] = &nss_cc_ubi32_axi0_clk.clkr, + [NSS_CC_UBI32_AXI1_CLK] = &nss_cc_ubi32_axi1_clk.clkr, + [NSS_CC_UBI32_AXI2_CLK] = &nss_cc_ubi32_axi2_clk.clkr, + [NSS_CC_UBI32_AXI3_CLK] = &nss_cc_ubi32_axi3_clk.clkr, + [NSS_CC_UBI32_CORE0_CLK] = &nss_cc_ubi32_core0_clk.clkr, + [NSS_CC_UBI32_CORE1_CLK] = &nss_cc_ubi32_core1_clk.clkr, + [NSS_CC_UBI32_CORE2_CLK] = &nss_cc_ubi32_core2_clk.clkr, + [NSS_CC_UBI32_CORE3_CLK] = &nss_cc_ubi32_core3_clk.clkr, + [NSS_CC_UBI32_INTR0_AHB_CLK] = &nss_cc_ubi32_intr0_ahb_clk.clkr, + [NSS_CC_UBI32_INTR1_AHB_CLK] = &nss_cc_ubi32_intr1_ahb_clk.clkr, + [NSS_CC_UBI32_INTR2_AHB_CLK] = &nss_cc_ubi32_intr2_ahb_clk.clkr, + [NSS_CC_UBI32_INTR3_AHB_CLK] = &nss_cc_ubi32_intr3_ahb_clk.clkr, + [NSS_CC_UBI32_NC_AXI0_CLK] = &nss_cc_ubi32_nc_axi0_clk.clkr, + [NSS_CC_UBI32_NC_AXI1_CLK] = &nss_cc_ubi32_nc_axi1_clk.clkr, + [NSS_CC_UBI32_NC_AXI2_CLK] = &nss_cc_ubi32_nc_axi2_clk.clkr, + [NSS_CC_UBI32_NC_AXI3_CLK] = &nss_cc_ubi32_nc_axi3_clk.clkr, + [NSS_CC_UBI32_UTCM0_CLK] = &nss_cc_ubi32_utcm0_clk.clkr, + [NSS_CC_UBI32_UTCM1_CLK] = &nss_cc_ubi32_utcm1_clk.clkr, + [NSS_CC_UBI32_UTCM2_CLK] = &nss_cc_ubi32_utcm2_clk.clkr, + [NSS_CC_UBI32_UTCM3_CLK] = &nss_cc_ubi32_utcm3_clk.clkr, + [NSS_CC_UBI3_CLK_SRC] = &nss_cc_ubi3_clk_src.clkr, + [NSS_CC_UBI3_DIV_CLK_SRC] = &nss_cc_ubi3_div_clk_src.clkr, + [NSS_CC_UBI_AXI_CLK_SRC] = &nss_cc_ubi_axi_clk_src.clkr, + [NSS_CC_UBI_NC_AXI_BFDCD_CLK_SRC] = + &nss_cc_ubi_nc_axi_bfdcd_clk_src.clkr, + [NSS_CC_UNIPHY_PORT1_RX_CLK] = &nss_cc_uniphy_port1_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT1_TX_CLK] = &nss_cc_uniphy_port1_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT2_RX_CLK] = &nss_cc_uniphy_port2_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT2_TX_CLK] = &nss_cc_uniphy_port2_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT3_RX_CLK] = &nss_cc_uniphy_port3_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT3_TX_CLK] = &nss_cc_uniphy_port3_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT4_RX_CLK] = &nss_cc_uniphy_port4_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT4_TX_CLK] = &nss_cc_uniphy_port4_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT5_RX_CLK] = &nss_cc_uniphy_port5_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT5_TX_CLK] = &nss_cc_uniphy_port5_tx_clk.clkr, + [NSS_CC_UNIPHY_PORT6_RX_CLK] = &nss_cc_uniphy_port6_rx_clk.clkr, + [NSS_CC_UNIPHY_PORT6_TX_CLK] = &nss_cc_uniphy_port6_tx_clk.clkr, + [NSS_CC_XGMAC0_PTP_REF_CLK] = &nss_cc_xgmac0_ptp_ref_clk.clkr, + [NSS_CC_XGMAC0_PTP_REF_DIV_CLK_SRC] = + &nss_cc_xgmac0_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC1_PTP_REF_CLK] = &nss_cc_xgmac1_ptp_ref_clk.clkr, + [NSS_CC_XGMAC1_PTP_REF_DIV_CLK_SRC] = + &nss_cc_xgmac1_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC2_PTP_REF_CLK] = &nss_cc_xgmac2_ptp_ref_clk.clkr, + [NSS_CC_XGMAC2_PTP_REF_DIV_CLK_SRC] = + &nss_cc_xgmac2_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC3_PTP_REF_CLK] = &nss_cc_xgmac3_ptp_ref_clk.clkr, + [NSS_CC_XGMAC3_PTP_REF_DIV_CLK_SRC] = + &nss_cc_xgmac3_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC4_PTP_REF_CLK] = &nss_cc_xgmac4_ptp_ref_clk.clkr, + [NSS_CC_XGMAC4_PTP_REF_DIV_CLK_SRC] = + &nss_cc_xgmac4_ptp_ref_div_clk_src.clkr, + [NSS_CC_XGMAC5_PTP_REF_CLK] = &nss_cc_xgmac5_ptp_ref_clk.clkr, + [NSS_CC_XGMAC5_PTP_REF_DIV_CLK_SRC] = + &nss_cc_xgmac5_ptp_ref_div_clk_src.clkr, + [UBI32_PLL] = &ubi32_pll.clkr, + [UBI32_PLL_MAIN] = &ubi32_pll_main.clkr, +}; + +static const struct qcom_reset_map nss_cc_ipq9574_resets[] = { + [NSS_CC_CE_BCR] = { 0x28400, 0 }, + [NSS_CC_CLC_BCR] = { 0x28600, 0 }, + [NSS_CC_EIP197_BCR] = { 0x16004, 0 }, + [NSS_CC_HAQ_BCR] = { 0x28300, 0 }, + [NSS_CC_IMEM_BCR] = { 0xe004, 0 }, + [NSS_CC_MAC_BCR] = { 0x28100, 0 }, + [NSS_CC_PPE_BCR] = { 0x28200, 0 }, + [NSS_CC_UBI_BCR] = { 0x28700, 0 }, + [NSS_CC_UNIPHY_BCR] = { 0x28900, 0 }, + [UBI3_CLKRST_CLAMP_ENABLE] = { 0x28a04, 9 }, + [UBI3_CORE_CLAMP_ENABLE] = { 0x28a04, 8 }, + [UBI2_CLKRST_CLAMP_ENABLE] = { 0x28a04, 7 }, + [UBI2_CORE_CLAMP_ENABLE] = { 0x28a04, 6 }, + [UBI1_CLKRST_CLAMP_ENABLE] = { 0x28a04, 5 }, + [UBI1_CORE_CLAMP_ENABLE] = { 0x28a04, 4 }, + [UBI0_CLKRST_CLAMP_ENABLE] = { 0x28a04, 3 }, + [UBI0_CORE_CLAMP_ENABLE] = { 0x28a04, 2 }, + [NSSNOC_NSS_CSR_ARES] = { 0x28a04, 1 }, + [NSS_CSR_ARES] = { 0x28a04, 0 }, + [PPE_BTQ_ARES] = { 0x28a08, 20 }, + [PPE_IPE_ARES] = { 0x28a08, 19 }, + [PPE_ARES] = { 0x28a08, 18 }, + [PPE_CFG_ARES] = { 0x28a08, 17 }, + [PPE_EDMA_ARES] = { 0x28a08, 16 }, + [PPE_EDMA_CFG_ARES] = { 0x28a08, 15 }, + [CRY_PPE_ARES] = { 0x28a08, 14 }, + [NSSNOC_PPE_ARES] = { 0x28a08, 13 }, + [NSSNOC_PPE_CFG_ARES] = { 0x28a08, 12 }, + [PORT1_MAC_ARES] = { 0x28a08, 11 }, + [PORT2_MAC_ARES] = { 0x28a08, 10 }, + [PORT3_MAC_ARES] = { 0x28a08, 9 }, + [PORT4_MAC_ARES] = { 0x28a08, 8 }, + [PORT5_MAC_ARES] = { 0x28a08, 7 }, + [PORT6_MAC_ARES] = { 0x28a08, 6 }, + [XGMAC0_PTP_REF_ARES] = { 0x28a08, 5 }, + [XGMAC1_PTP_REF_ARES] = { 0x28a08, 4 }, + [XGMAC2_PTP_REF_ARES] = { 0x28a08, 3 }, + [XGMAC3_PTP_REF_ARES] = { 0x28a08, 2 }, + [XGMAC4_PTP_REF_ARES] = { 0x28a08, 1 }, + [XGMAC5_PTP_REF_ARES] = { 0x28a08, 0 }, + [HAQ_AHB_ARES] = { 0x28a0c, 3 }, + [HAQ_AXI_ARES] = { 0x28a0c, 2 }, + [NSSNOC_HAQ_AHB_ARES] = { 0x28a0c, 1 }, + [NSSNOC_HAQ_AXI_ARES] = { 0x28a0c, 0 }, + [CE_APB_ARES] = { 0x28a10, 3 }, + [CE_AXI_ARES] = { 0x28a10, 2 }, + [NSSNOC_CE_APB_ARES] = { 0x28a10, 1 }, + [NSSNOC_CE_AXI_ARES] = { 0x28a10, 0 }, + [CRYPTO_ARES] = { 0x28a14, 1 }, + [NSSNOC_CRYPTO_ARES] = { 0x28a14, 0 }, + [NSSNOC_NC_AXI0_1_ARES] = { 0x28a1c, 28 }, + [UBI0_CORE_ARES] = { 0x28a1c, 27 }, + [UBI1_CORE_ARES] = { 0x28a1c, 26 }, + [UBI2_CORE_ARES] = { 0x28a1c, 25 }, + [UBI3_CORE_ARES] = { 0x28a1c, 24 }, + [NC_AXI0_ARES] = { 0x28a1c, 23 }, + [UTCM0_ARES] = { 0x28a1c, 22 }, + [NC_AXI1_ARES] = { 0x28a1c, 21 }, + [UTCM1_ARES] = { 0x28a1c, 20 }, + [NC_AXI2_ARES] = { 0x28a1c, 19 }, + [UTCM2_ARES] = { 0x28a1c, 18 }, + [NC_AXI3_ARES] = { 0x28a1c, 17 }, + [UTCM3_ARES] = { 0x28a1c, 16 }, + [NSSNOC_NC_AXI0_ARES] = { 0x28a1c, 15 }, + [AHB0_ARES] = { 0x28a1c, 14 }, + [INTR0_AHB_ARES] = { 0x28a1c, 13 }, + [AHB1_ARES] = { 0x28a1c, 12 }, + [INTR1_AHB_ARES] = { 0x28a1c, 11 }, + [AHB2_ARES] = { 0x28a1c, 10 }, + [INTR2_AHB_ARES] = { 0x28a1c, 9 }, + [AHB3_ARES] = { 0x28a1c, 8 }, + [INTR3_AHB_ARES] = { 0x28a1c, 7 }, + [NSSNOC_AHB0_ARES] = { 0x28a1c, 6 }, + [NSSNOC_INT0_AHB_ARES] = { 0x28a1c, 5 }, + [AXI0_ARES] = { 0x28a1c, 4 }, + [AXI1_ARES] = { 0x28a1c, 3 }, + [AXI2_ARES] = { 0x28a1c, 2 }, + [AXI3_ARES] = { 0x28a1c, 1 }, + [NSSNOC_AXI0_ARES] = { 0x28a1c, 0 }, + [IMEM_QSB_ARES] = { 0x28a20, 3 }, + [NSSNOC_IMEM_QSB_ARES] = { 0x28a20, 2 }, + [IMEM_AHB_ARES] = { 0x28a20, 1 }, + [NSSNOC_IMEM_AHB_ARES] = { 0x28a20, 0 }, + [UNIPHY_PORT1_RX_ARES] = { 0x28a24, 23 }, + [UNIPHY_PORT1_TX_ARES] = { 0x28a24, 22 }, + [UNIPHY_PORT2_RX_ARES] = { 0x28a24, 21 }, + [UNIPHY_PORT2_TX_ARES] = { 0x28a24, 20 }, + [UNIPHY_PORT3_RX_ARES] = { 0x28a24, 19 }, + [UNIPHY_PORT3_TX_ARES] = { 0x28a24, 18 }, + [UNIPHY_PORT4_RX_ARES] = { 0x28a24, 17 }, + [UNIPHY_PORT4_TX_ARES] = { 0x28a24, 16 }, + [UNIPHY_PORT5_RX_ARES] = { 0x28a24, 15 }, + [UNIPHY_PORT5_TX_ARES] = { 0x28a24, 14 }, + [UNIPHY_PORT6_RX_ARES] = { 0x28a24, 13 }, + [UNIPHY_PORT6_TX_ARES] = { 0x28a24, 12 }, + [PORT1_RX_ARES] = { 0x28a24, 11 }, + [PORT1_TX_ARES] = { 0x28a24, 10 }, + [PORT2_RX_ARES] = { 0x28a24, 9 }, + [PORT2_TX_ARES] = { 0x28a24, 8 }, + [PORT3_RX_ARES] = { 0x28a24, 7 }, + [PORT3_TX_ARES] = { 0x28a24, 6 }, + [PORT4_RX_ARES] = { 0x28a24, 5 }, + [PORT4_TX_ARES] = { 0x28a24, 4 }, + [PORT5_RX_ARES] = { 0x28a24, 3 }, + [PORT5_TX_ARES] = { 0x28a24, 2 }, + [PORT6_RX_ARES] = { 0x28a24, 1 }, + [PORT6_TX_ARES] = { 0x28a24, 0 }, + [PPE_FULL_RESET] = { .reg = 0x28a08, .bitmask = GENMASK(20, 17) }, + [UNIPHY0_SOFT_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(23, 14) }, + [UNIPHY1_SOFT_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(15, 14) }, + [UNIPHY2_SOFT_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(13, 12) }, + [UNIPHY_PORT1_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(23, 22) }, + [UNIPHY_PORT2_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(21, 20) }, + [UNIPHY_PORT3_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(19, 18) }, + [UNIPHY_PORT4_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(17, 16) }, + [UNIPHY_PORT5_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(15, 14) }, + [UNIPHY_PORT6_ARES] = { .reg = 0x28a24, .bitmask = GENMASK(13, 12) }, + [NSSPORT1_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(11, 10) }, + [NSSPORT2_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(9, 8) }, + [NSSPORT3_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(7, 6) }, + [NSSPORT4_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(5, 4) }, + [NSSPORT5_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(3, 2) }, + [NSSPORT6_RESET] = { .reg = 0x28a24, .bitmask = GENMASK(1, 0) }, + [EDMA_HW_RESET] = { .reg = 0x28a08, .bitmask = GENMASK(16, 15) }, +}; + +static const struct regmap_config nss_cc_ipq9574_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x28a34, + .fast_io = true, +}; + +static struct qcom_icc_hws_data icc_ipq9574_nss_hws[] = { + { MASTER_NSSNOC_PPE, SLAVE_NSSNOC_PPE, NSS_CC_NSSNOC_PPE_CLK }, + { MASTER_NSSNOC_PPE_CFG, SLAVE_NSSNOC_PPE_CFG, NSS_CC_NSSNOC_PPE_CFG_CLK }, + { MASTER_NSSNOC_NSS_CSR, SLAVE_NSSNOC_NSS_CSR, NSS_CC_NSSNOC_NSS_CSR_CLK }, + { MASTER_NSSNOC_IMEM_QSB, SLAVE_NSSNOC_IMEM_QSB, NSS_CC_NSSNOC_IMEM_QSB_CLK }, + { MASTER_NSSNOC_IMEM_AHB, SLAVE_NSSNOC_IMEM_AHB, NSS_CC_NSSNOC_IMEM_AHB_CLK }, +}; + +#define IPQ_NSSCC_ID (9574 * 2) /* some unique value */ + +static const struct qcom_cc_desc nss_cc_ipq9574_desc = { + .config = &nss_cc_ipq9574_regmap_config, + .clks = nss_cc_ipq9574_clocks, + .num_clks = ARRAY_SIZE(nss_cc_ipq9574_clocks), + .resets = nss_cc_ipq9574_resets, + .num_resets = ARRAY_SIZE(nss_cc_ipq9574_resets), + .icc_hws = icc_ipq9574_nss_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq9574_nss_hws), + .icc_first_node_id = IPQ_NSSCC_ID, +}; + +static const struct dev_pm_ops nss_cc_ipq9574_pm_ops = { + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) +}; + +static const struct of_device_id nss_cc_ipq9574_match_table[] = { + { .compatible = "qcom,ipq9574-nsscc" }, + { } +}; +MODULE_DEVICE_TABLE(of, nss_cc_ipq9574_match_table); + +static int nss_cc_ipq9574_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to enable runtime PM\n"); + + ret = devm_pm_clk_create(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to create PM clock\n"); + + ret = pm_clk_add(&pdev->dev, "bus"); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to add bus clock\n"); + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Fail to resume\n"); + + regmap = qcom_cc_map(pdev, &nss_cc_ipq9574_desc); + if (IS_ERR(regmap)) { + pm_runtime_put(&pdev->dev); + return dev_err_probe(&pdev->dev, PTR_ERR(regmap), + "Fail to map clock controller registers\n"); + } + + clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config); + + ret = qcom_cc_really_probe(&pdev->dev, &nss_cc_ipq9574_desc, regmap); + pm_runtime_put(&pdev->dev); + + return ret; +} + +static struct platform_driver nss_cc_ipq9574_driver = { + .probe = nss_cc_ipq9574_probe, + .driver = { + .name = "qcom,nsscc-ipq9574", + .of_match_table = nss_cc_ipq9574_match_table, + .pm = &nss_cc_ipq9574_pm_ops, + .sync_state = icc_sync_state, + }, +}; + +module_platform_driver(nss_cc_ipq9574_driver); + +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. NSSCC IPQ9574 Driver"); +MODULE_LICENSE("GPL");