clk: qcom: cpu-8996: simplify the cpu_clk_notifier_cb
authorDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Fri, 13 Jan 2023 12:05:37 +0000 (14:05 +0200)
committerBjorn Andersson <andersson@kernel.org>
Thu, 19 Jan 2023 04:50:00 +0000 (22:50 -0600)
- Do not use the Alt PLL completely. Switch to smux when necessary to
  prevent overvolting
- Restore the parent in case the rate change aborts for some reason
- Do not duplicate resetting the parent in set_parent operation.

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Link: https://lore.kernel.org/r/20230113120544.59320-8-dmitry.baryshkov@linaro.org
drivers/clk/qcom/clk-cpu-8996.c

index 7e5246ca7e7fcd735688ca49e4a77b07fad3f7ae..cc7ece6a77026a91119d10231965dc6ef519c242 100644 (file)
@@ -506,27 +506,35 @@ static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
 {
        struct clk_cpu_8996_pmux *cpuclk = to_clk_cpu_8996_pmux_nb(nb);
        struct clk_notifier_data *cnd = data;
-       int ret;
 
        switch (event) {
        case PRE_RATE_CHANGE:
-               ret = clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw, ALT_INDEX);
                qcom_cpu_clk_msm8996_acd_init(base);
+
+               /*
+                * Avoid overvolting. clk_core_set_rate_nolock() walks from top
+                * to bottom, so it will change the rate of the PLL before
+                * chaging the parent of PMUX. This can result in pmux getting
+                * clocked twice the expected rate.
+                *
+                * Manually switch to PLL/2 here.
+                */
+               if (cnd->new_rate < DIV_2_THRESHOLD &&
+                   cnd->old_rate > DIV_2_THRESHOLD)
+                       clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw, SMUX_INDEX);
+
                break;
-       case POST_RATE_CHANGE:
-               if (cnd->new_rate < DIV_2_THRESHOLD)
-                       ret = clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw,
-                                                          SMUX_INDEX);
-               else
-                       ret = clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw,
-                                                          ACD_INDEX);
+       case ABORT_RATE_CHANGE:
+               /* Revert manual change */
+               if (cnd->new_rate < DIV_2_THRESHOLD &&
+                   cnd->old_rate > DIV_2_THRESHOLD)
+                       clk_cpu_8996_pmux_set_parent(&cpuclk->clkr.hw, ACD_INDEX);
                break;
        default:
-               ret = 0;
                break;
        }
 
-       return notifier_from_errno(ret);
+       return NOTIFY_OK;
 };
 
 static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)