Message ID | 20250530-videocc-pll-multi-pd-voting-v5-0-02303b3a582d@quicinc.com |
---|---|
Headers | show |
Series | clk: qcom: Add support to attach multiple power domains in cc probe | expand |
On 30/05/2025 14:20, Jagadeesh Kona wrote: > Camera PLLs on SM8450/SM8475 require both MMCX and MXC rails to be > kept ON to configure the PLLs properly. Hence move runtime power > management, PLL configuration and enable critical clocks to > qcom_cc_really_probe() which ensures all required power domains are in > enabled state before configuring the PLLs or enabling the clocks. > > This change also removes the modelling for cam_cc_gdsc_clk and keeps it > always ON from probe since using CLK_IS_CRITICAL will prevent the clock > controller associated power domains from collapsing due to clock framework > invoking clk_pm_runtime_get() during prepare. > > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> > Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> > Signed-off-by: Jagadeesh Kona <quic_jkona@quicinc.com> > --- > drivers/clk/qcom/camcc-sm8450.c | 89 ++++++++++++++++++++--------------------- > 1 file changed, 44 insertions(+), 45 deletions(-) > > diff --git a/drivers/clk/qcom/camcc-sm8450.c b/drivers/clk/qcom/camcc-sm8450.c > index 08982737e4901c0703e19f8dd2d302e24748210c..4dd8be8cc9881c890d2e7c3a12f12816a9ab47dc 100644 > --- a/drivers/clk/qcom/camcc-sm8450.c > +++ b/drivers/clk/qcom/camcc-sm8450.c > @@ -86,6 +86,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll0_config = { > > static struct clk_alpha_pll cam_cc_pll0 = { > .offset = 0x0, > + .config = &cam_cc_pll0_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -191,6 +192,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll1_config = { > > static struct clk_alpha_pll cam_cc_pll1 = { > .offset = 0x1000, > + .config = &cam_cc_pll1_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -257,6 +259,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll2_config = { > > static struct clk_alpha_pll cam_cc_pll2 = { > .offset = 0x2000, > + .config = &cam_cc_pll2_config, > .vco_table = rivian_evo_vco, > .num_vco = ARRAY_SIZE(rivian_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO], > @@ -296,6 +299,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll3_config = { > > static struct clk_alpha_pll cam_cc_pll3 = { > .offset = 0x3000, > + .config = &cam_cc_pll3_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -368,6 +372,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll4_config = { > > static struct clk_alpha_pll cam_cc_pll4 = { > .offset = 0x4000, > + .config = &cam_cc_pll4_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -440,6 +445,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll5_config = { > > static struct clk_alpha_pll cam_cc_pll5 = { > .offset = 0x5000, > + .config = &cam_cc_pll5_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -512,6 +518,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll6_config = { > > static struct clk_alpha_pll cam_cc_pll6 = { > .offset = 0x6000, > + .config = &cam_cc_pll6_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -584,6 +591,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll7_config = { > > static struct clk_alpha_pll cam_cc_pll7 = { > .offset = 0x7000, > + .config = &cam_cc_pll7_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -656,6 +664,7 @@ static const struct alpha_pll_config sm8475_cam_cc_pll8_config = { > > static struct clk_alpha_pll cam_cc_pll8 = { > .offset = 0x8000, > + .config = &cam_cc_pll8_config, > .vco_table = lucid_evo_vco, > .num_vco = ARRAY_SIZE(lucid_evo_vco), > .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], > @@ -1476,24 +1485,6 @@ static struct clk_rcg2 cam_cc_xo_clk_src = { > }, > }; > > -static struct clk_branch cam_cc_gdsc_clk = { > - .halt_reg = 0x1320c, > - .halt_check = BRANCH_HALT, > - .clkr = { > - .enable_reg = 0x1320c, > - .enable_mask = BIT(0), > - .hw.init = &(const struct clk_init_data) { > - .name = "cam_cc_gdsc_clk", > - .parent_hws = (const struct clk_hw*[]) { > - &cam_cc_xo_clk_src.clkr.hw, > - }, > - .num_parents = 1, > - .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, > - .ops = &clk_branch2_ops, > - }, > - }, > -}; > - > static struct clk_branch cam_cc_bps_ahb_clk = { > .halt_reg = 0x1004c, > .halt_check = BRANCH_HALT, > @@ -2819,7 +2810,6 @@ static struct clk_regmap *cam_cc_sm8450_clocks[] = { > [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, > [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, > [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, > - [CAM_CC_GDSC_CLK] = &cam_cc_gdsc_clk.clkr, > [CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr, > [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, > [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, > @@ -2913,6 +2903,22 @@ static const struct qcom_reset_map cam_cc_sm8450_resets[] = { > [CAM_CC_SFE_1_BCR] = { 0x13094 }, > }; > > +static struct clk_alpha_pll *cam_cc_sm8450_plls[] = { > + &cam_cc_pll0, > + &cam_cc_pll1, > + &cam_cc_pll2, > + &cam_cc_pll3, > + &cam_cc_pll4, > + &cam_cc_pll5, > + &cam_cc_pll6, > + &cam_cc_pll7, > + &cam_cc_pll8, > +}; > + > +static u32 cam_cc_sm8450_critical_cbcrs[] = { > + 0x1320c, /* CAM_CC_GDSC_CLK */ > +}; > + > static const struct regmap_config cam_cc_sm8450_regmap_config = { > .reg_bits = 32, > .reg_stride = 4, > @@ -3021,6 +3027,13 @@ static struct gdsc *cam_cc_sm8450_gdscs[] = { > [TITAN_TOP_GDSC] = &titan_top_gdsc, > }; > > +static struct qcom_cc_driver_data cam_cc_sm8450_driver_data = { > + .alpha_plls = cam_cc_sm8450_plls, > + .num_alpha_plls = ARRAY_SIZE(cam_cc_sm8450_plls), > + .clk_cbcrs = cam_cc_sm8450_critical_cbcrs, > + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_sm8450_critical_cbcrs), > +}; > + > static const struct qcom_cc_desc cam_cc_sm8450_desc = { > .config = &cam_cc_sm8450_regmap_config, > .clks = cam_cc_sm8450_clocks, > @@ -3029,6 +3042,8 @@ static const struct qcom_cc_desc cam_cc_sm8450_desc = { > .num_resets = ARRAY_SIZE(cam_cc_sm8450_resets), > .gdscs = cam_cc_sm8450_gdscs, > .num_gdscs = ARRAY_SIZE(cam_cc_sm8450_gdscs), > + .use_rpm = true, > + .driver_data = &cam_cc_sm8450_driver_data, > }; > > static const struct of_device_id cam_cc_sm8450_match_table[] = { > @@ -3040,12 +3055,6 @@ MODULE_DEVICE_TABLE(of, cam_cc_sm8450_match_table); > > static int cam_cc_sm8450_probe(struct platform_device *pdev) > { > - struct regmap *regmap; > - > - regmap = qcom_cc_map(pdev, &cam_cc_sm8450_desc); > - if (IS_ERR(regmap)) > - return PTR_ERR(regmap); > - > if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8475-camcc")) { > /* Update CAMCC PLL0 */ > cam_cc_pll0.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE]; > @@ -3092,28 +3101,18 @@ static int cam_cc_sm8450_probe(struct platform_device *pdev) > cam_cc_pll8_out_even.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE]; > cam_cc_pll8_out_even.clkr.hw.init = &sm8475_cam_cc_pll8_out_even_init; > > - clk_lucid_ole_pll_configure(&cam_cc_pll0, regmap, &sm8475_cam_cc_pll0_config); > - clk_lucid_ole_pll_configure(&cam_cc_pll1, regmap, &sm8475_cam_cc_pll1_config); > - clk_rivian_evo_pll_configure(&cam_cc_pll2, regmap, &sm8475_cam_cc_pll2_config); > - clk_lucid_ole_pll_configure(&cam_cc_pll3, regmap, &sm8475_cam_cc_pll3_config); > - clk_lucid_ole_pll_configure(&cam_cc_pll4, regmap, &sm8475_cam_cc_pll4_config); > - clk_lucid_ole_pll_configure(&cam_cc_pll5, regmap, &sm8475_cam_cc_pll5_config); > - clk_lucid_ole_pll_configure(&cam_cc_pll6, regmap, &sm8475_cam_cc_pll6_config); > - clk_lucid_ole_pll_configure(&cam_cc_pll7, regmap, &sm8475_cam_cc_pll7_config); > - clk_lucid_ole_pll_configure(&cam_cc_pll8, regmap, &sm8475_cam_cc_pll8_config); > - } else { > - clk_lucid_evo_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config); > - clk_lucid_evo_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config); > - clk_rivian_evo_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config); > - clk_lucid_evo_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); > - clk_lucid_evo_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config); > - clk_lucid_evo_pll_configure(&cam_cc_pll5, regmap, &cam_cc_pll5_config); > - clk_lucid_evo_pll_configure(&cam_cc_pll6, regmap, &cam_cc_pll6_config); > - clk_lucid_evo_pll_configure(&cam_cc_pll7, regmap, &cam_cc_pll7_config); > - clk_lucid_evo_pll_configure(&cam_cc_pll8, regmap, &cam_cc_pll8_config); > + cam_cc_pll0.config = &sm8475_cam_cc_pll0_config; > + cam_cc_pll1.config = &sm8475_cam_cc_pll1_config; > + cam_cc_pll2.config = &sm8475_cam_cc_pll2_config; > + cam_cc_pll3.config = &sm8475_cam_cc_pll3_config; > + cam_cc_pll4.config = &sm8475_cam_cc_pll4_config; > + cam_cc_pll5.config = &sm8475_cam_cc_pll5_config; > + cam_cc_pll6.config = &sm8475_cam_cc_pll6_config; > + cam_cc_pll7.config = &sm8475_cam_cc_pll7_config; > + cam_cc_pll8.config = &sm8475_cam_cc_pll8_config; > } > > - return qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8450_desc, regmap); > + return qcom_cc_probe(pdev, &cam_cc_sm8450_desc); > } > > static struct platform_driver cam_cc_sm8450_driver = { > > -- > 2.34.1 > > Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
In recent QCOM chipsets, PLLs require more than one power domain to be kept ON to configure the PLL. But the current code doesn't enable all the required power domains while configuring the PLLs, this leads to functional issues due to suboptimal settings of PLLs. To address this, add support for handling runtime power management, configuring plls and enabling critical clocks from qcom_cc_really_probe. The clock controller can specify PLLs, critical clocks, and runtime PM requirements using the descriptor data. The code in qcom_cc_really_probe() ensures all necessary power domains are enabled before configuring PLLs or critical clocks. This series fixes the below warning reported in SM8550 venus testing due to video_cc_pll0 not properly getting configured during videocc probe [ 46.535132] Lucid PLL latch failed. Output may be unstable! The patch adding support to configure the PLLs from common code is picked from below series and updated it. https://lore.kernel.org/all/20250113-support-pll-reconfigure-v1-0-1fae6bc1062d@quicinc.com/ This series is dependent on bindings patch in below Vladimir's series, hence included the Vladimir's series patches also in this series and updated them. https://lore.kernel.org/all/20250303225521.1780611-1-vladimir.zapolskiy@linaro.org/ Signed-off-by: Jagadeesh Kona <quic_jkona@quicinc.com> --- Changes in v5: - Reversed order of patches 2 & 3 to add MXC support in SM8450 camcc bindings first and then moved SC8280XP camcc to SA8775P camcc to have single power domain support for it. - Added return code for qcom_cc_clk_pll_configure() and returned -EINVAL in case if PLL config or registers is NULL in patch 6 [Bryan] - Added separate CBCR's list for SM8650 videocc and updated clk_cbcrs list based on compatible in patch 8[Konrad] - Added R-By tags received on v4 - Link to v4: https://lore.kernel.org/r/20250515-videocc-pll-multi-pd-voting-v4-0-571c63297d01@quicinc.com Changes in v4: - Updated the SC8280XP camcc bindings patch to fix the required-opps warning reported by kernel bot - Updated the description of power-domains, required-opps of SM8450 camcc bindings as per review comments on v3 [Bryan] - Moved the PLL config checks to calling function code [Dmitry] - Removed qcom_clk_reg_setting struct and regmap_update_bits() code. Added a .clk_regs_configure() callback that clock drivers can implement if they require to update some misc register settings [Dmitry] - Moved the PLLs and CBCRs data to a separate qcom_cc_driver_data struct to avoid bloating up the CC descriptor structure - Updated the videocc and camcc driver patches to incorporate above qcom_cc_driver_data change - Updated the commit text of DT patches [Bryan] - Added the R-By, T-By tags received on v3 - Link to v3: https://lore.kernel.org/r/20250327-videocc-pll-multi-pd-voting-v3-0-895fafd62627@quicinc.com Changes in v3: - Updated the videocc bindings patch to add required-opps for MXC power domain [Dmitry] and added Bryan & Rob R/A-By tags received for this patch on v1. - Included the Vladimir's bindings patch for SM8450 camcc bindings to add multiple PD support and updated them to fix the bot warnings. - Moved SC8280XP camcc bindings to SA8775P camcc since SC8280XP only require single MMCX power domain - Split runtime PM and PLL configuration to separate patches [Dmitry] - Removed direct regmap_update_bits to configure clock CBCR's and using clock helpers to configure the CBCR registers [Dmitry, Bryan] - Added new helpers to configure all PLLs & update misc clock register settings from common code [Dmitry, Bryan] - Updated the name of qcom_clk_cfg structure to qcom_clk_reg_setting [Konrad] - Updated the fields in structure from unsigned int to u32 and added val field to this structure [Konrad] - Added a new u32 array for cbcr branch clocks & num_clk_cbcrs fields to maintain the list of critical clock cbcrs in clock controller descriptor [Konrad] - Updated the plls field to alpha_plls in descriptor structure [Konrad] - Added WARN() in PLL configure function if PLL type passed is not supported. The suggestion is to use BUG(), but updated it to WARN() to avoid checkpatch warning. [Bjorn] - Moved the pll configure and helper macros to PLL code from common code [Bjorn] - Updated camcc drivers for SM8450, SM8550, SM8650 and X1E80100 targets with support to configure PLLs from common code and added MXC power domain in corresponding camcc DT nodes. [Bryan] - Added Dmitry and Bryan R-By tags received on videocc DT node changes in v1 - Link to v2: https://lore.kernel.org/r/20250306-videocc-pll-multi-pd-voting-v2-0-0cd00612bc0e@quicinc.com Changes in v2: - Added support to handle rpm, PLL configuration and enable critical clocks from qcom_cc_really_probe() in common code as per v1 commments from Bryan, Konrad and Dmitry - Added patches to configure PLLs from common code - Updated the SM8450, SM8550 videocc patches to use the newly added support to handle rpm, configure PLLs from common code - Split the DT change for each target separately as per Dmitry comments - Added R-By and A-By tags received on v1 - Link to v1: https://lore.kernel.org/r/20250218-videocc-pll-multi-pd-voting-v1-0-cfe6289ea29b@quicinc.com --- Jagadeesh Kona (15): dt-bindings: clock: qcom,sm8450-videocc: Add MXC power domain dt-bindings: clock: qcom,sm8450-camcc: Move sc8280xp camcc to sa8775p camcc clk: qcom: common: Handle runtime power management in qcom_cc_really_probe clk: qcom: common: Add support to configure clk regs in qcom_cc_really_probe clk: qcom: videocc-sm8450: Move PLL & clk configuration to really probe clk: qcom: videocc-sm8550: Move PLL & clk configuration to really probe clk: qcom: camcc-sm8450: Move PLL & clk configuration to really probe clk: qcom: camcc-sm8550: Move PLL & clk configuration to really probe clk: qcom: camcc-sm8650: Move PLL & clk configuration to really probe clk: qcom: camcc-x1e80100: Move PLL & clk configuration to really probe arm64: dts: qcom: sm8450: Additionally manage MXC power domain in videocc arm64: dts: qcom: sm8550: Additionally manage MXC power domain in videocc arm64: dts: qcom: sm8650: Additionally manage MXC power domain in videocc arm64: dts: qcom: sm8450: Additionally manage MXC power domain in camcc arm64: dts: qcom: sm8650: Additionally manage MXC power domain in camcc Taniya Das (1): clk: qcom: clk-alpha-pll: Add support for common PLL configuration function Vladimir Zapolskiy (2): dt-bindings: clock: qcom,sm8450-camcc: Allow to specify two power domains arm64: dts: qcom: sm8550: Additionally manage MXC power domain in camcc .../bindings/clock/qcom,sa8775p-camcc.yaml | 15 ++++ .../bindings/clock/qcom,sm8450-camcc.yaml | 20 +++-- .../bindings/clock/qcom,sm8450-videocc.yaml | 18 +++-- arch/arm64/boot/dts/qcom/sm8450.dtsi | 12 ++- arch/arm64/boot/dts/qcom/sm8550.dtsi | 12 ++- arch/arm64/boot/dts/qcom/sm8650.dtsi | 6 +- drivers/clk/qcom/camcc-sm8450.c | 89 +++++++++++----------- drivers/clk/qcom/camcc-sm8550.c | 85 +++++++++++---------- drivers/clk/qcom/camcc-sm8650.c | 83 ++++++++++---------- drivers/clk/qcom/camcc-x1e80100.c | 67 ++++++++-------- drivers/clk/qcom/clk-alpha-pll.c | 57 ++++++++++++++ drivers/clk/qcom/clk-alpha-pll.h | 3 + drivers/clk/qcom/common.c | 81 +++++++++++++++++--- drivers/clk/qcom/common.h | 10 +++ drivers/clk/qcom/videocc-sm8450.c | 58 ++++++-------- drivers/clk/qcom/videocc-sm8550.c | 66 ++++++++-------- 16 files changed, 421 insertions(+), 261 deletions(-) --- base-commit: 138cfc44b3c4a5fb800388c6e27be169970fb9f7 change-id: 20250218-videocc-pll-multi-pd-voting-d614dce910e7 Best regards,