OSDN Git Service

pwm: mtk-disp: Adjust the clocks to avoid them mismatch
authorJitao Shi <jitao.shi@mediatek.com>
Sun, 8 Aug 2021 13:24:29 +0000 (21:24 +0800)
committerThierry Reding <thierry.reding@gmail.com>
Thu, 2 Sep 2021 20:03:43 +0000 (22:03 +0200)
The clks "main" and "mm" are prepared in .probe() (and unprepared in
.remove()). This results in the clocks being on during suspend which
results in unnecessarily increased power consumption.

Remove the clock operations from .probe() and .remove(). Add the
clk_prepare_enable() in .enable() and the clk_disable_unprepare() in
.disable().

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
[thierry.reding@gmail.com: squashed in fixup patch]
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-mtk-disp.c

index 7b4a2b8..5817ac1 100644 (file)
@@ -74,6 +74,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        u64 div, rate;
        int err;
 
+       err = clk_prepare_enable(mdp->clk_main);
+       if (err < 0) {
+               dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
+               return err;
+       }
+
+       err = clk_prepare_enable(mdp->clk_mm);
+       if (err < 0) {
+               dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+               clk_disable_unprepare(mdp->clk_main);
+               return err;
+       }
+
        /*
         * Find period, high_width and clk_div to suit duty_ns and period_ns.
         * Calculate proper div value to keep period value in the bound.
@@ -87,8 +100,11 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        rate = clk_get_rate(mdp->clk_main);
        clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
                          PWM_PERIOD_BIT_WIDTH;
-       if (clk_div > PWM_CLKDIV_MAX)
+       if (clk_div > PWM_CLKDIV_MAX) {
+               clk_disable_unprepare(mdp->clk_mm);
+               clk_disable_unprepare(mdp->clk_main);
                return -EINVAL;
+       }
 
        div = NSEC_PER_SEC * (clk_div + 1);
        period = div64_u64(rate * period_ns, div);
@@ -98,16 +114,6 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        high_width = div64_u64(rate * duty_ns, div);
        value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
-       err = clk_enable(mdp->clk_main);
-       if (err < 0)
-               return err;
-
-       err = clk_enable(mdp->clk_mm);
-       if (err < 0) {
-               clk_disable(mdp->clk_main);
-               return err;
-       }
-
        mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
                                 PWM_CLKDIV_MASK,
                                 clk_div << PWM_CLKDIV_SHIFT);
@@ -122,10 +128,21 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
                                         mdp->data->commit_mask,
                                         0x0);
+       } else {
+               /*
+                * For MT2701, disable double buffer before writing register
+                * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
+                */
+               mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
+                                        mdp->data->bls_debug_mask,
+                                        mdp->data->bls_debug_mask);
+               mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
+                                        mdp->data->con0_sel,
+                                        mdp->data->con0_sel);
        }
 
-       clk_disable(mdp->clk_mm);
-       clk_disable(mdp->clk_main);
+       clk_disable_unprepare(mdp->clk_mm);
+       clk_disable_unprepare(mdp->clk_main);
 
        return 0;
 }
@@ -135,13 +152,16 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
        int err;
 
-       err = clk_enable(mdp->clk_main);
-       if (err < 0)
+       err = clk_prepare_enable(mdp->clk_main);
+       if (err < 0) {
+               dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
                return err;
+       }
 
-       err = clk_enable(mdp->clk_mm);
+       err = clk_prepare_enable(mdp->clk_mm);
        if (err < 0) {
-               clk_disable(mdp->clk_main);
+               dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+               clk_disable_unprepare(mdp->clk_main);
                return err;
        }
 
@@ -158,8 +178,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
                                 0x0);
 
-       clk_disable(mdp->clk_mm);
-       clk_disable(mdp->clk_main);
+       clk_disable_unprepare(mdp->clk_mm);
+       clk_disable_unprepare(mdp->clk_main);
 }
 
 static const struct pwm_ops mtk_disp_pwm_ops = {
@@ -192,46 +212,19 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(mdp->clk_mm))
                return PTR_ERR(mdp->clk_mm);
 
-       ret = clk_prepare(mdp->clk_main);
-       if (ret < 0)
-               return ret;
-
-       ret = clk_prepare(mdp->clk_mm);
-       if (ret < 0)
-               goto disable_clk_main;
-
        mdp->chip.dev = &pdev->dev;
        mdp->chip.ops = &mtk_disp_pwm_ops;
        mdp->chip.npwm = 1;
 
        ret = pwmchip_add(&mdp->chip);
        if (ret < 0) {
-               dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-               goto disable_clk_mm;
+               dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
+               return ret;
        }
 
        platform_set_drvdata(pdev, mdp);
 
-       /*
-        * For MT2701, disable double buffer before writing register
-        * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
-        */
-       if (!mdp->data->has_commit) {
-               mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
-                                        mdp->data->bls_debug_mask,
-                                        mdp->data->bls_debug_mask);
-               mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-                                        mdp->data->con0_sel,
-                                        mdp->data->con0_sel);
-       }
-
        return 0;
-
-disable_clk_mm:
-       clk_unprepare(mdp->clk_mm);
-disable_clk_main:
-       clk_unprepare(mdp->clk_main);
-       return ret;
 }
 
 static int mtk_disp_pwm_remove(struct platform_device *pdev)
@@ -239,8 +232,6 @@ static int mtk_disp_pwm_remove(struct platform_device *pdev)
        struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
 
        pwmchip_remove(&mdp->chip);
-       clk_unprepare(mdp->clk_mm);
-       clk_unprepare(mdp->clk_main);
 
        return 0;
 }