Skip to content

Commit d7a4e58

Browse files
mediatek-jitaothierryreding
authored andcommitted
pwm: mtk-disp: Adjust the clocks to avoid them mismatch
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 <[email protected]> [[email protected]: squashed in fixup patch] Signed-off-by: Thierry Reding <[email protected]>
1 parent dd8f6b2 commit d7a4e58

File tree

1 file changed

+41
-50
lines changed

1 file changed

+41
-50
lines changed

drivers/pwm/pwm-mtk-disp.c

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
7474
u64 div, rate;
7575
int err;
7676

77+
err = clk_prepare_enable(mdp->clk_main);
78+
if (err < 0) {
79+
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
80+
return err;
81+
}
82+
83+
err = clk_prepare_enable(mdp->clk_mm);
84+
if (err < 0) {
85+
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
86+
clk_disable_unprepare(mdp->clk_main);
87+
return err;
88+
}
89+
7790
/*
7891
* Find period, high_width and clk_div to suit duty_ns and period_ns.
7992
* 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,
87100
rate = clk_get_rate(mdp->clk_main);
88101
clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
89102
PWM_PERIOD_BIT_WIDTH;
90-
if (clk_div > PWM_CLKDIV_MAX)
103+
if (clk_div > PWM_CLKDIV_MAX) {
104+
clk_disable_unprepare(mdp->clk_mm);
105+
clk_disable_unprepare(mdp->clk_main);
91106
return -EINVAL;
107+
}
92108

93109
div = NSEC_PER_SEC * (clk_div + 1);
94110
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,
98114
high_width = div64_u64(rate * duty_ns, div);
99115
value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
100116

101-
err = clk_enable(mdp->clk_main);
102-
if (err < 0)
103-
return err;
104-
105-
err = clk_enable(mdp->clk_mm);
106-
if (err < 0) {
107-
clk_disable(mdp->clk_main);
108-
return err;
109-
}
110-
111117
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
112118
PWM_CLKDIV_MASK,
113119
clk_div << PWM_CLKDIV_SHIFT);
@@ -122,10 +128,21 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
122128
mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
123129
mdp->data->commit_mask,
124130
0x0);
131+
} else {
132+
/*
133+
* For MT2701, disable double buffer before writing register
134+
* and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
135+
*/
136+
mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
137+
mdp->data->bls_debug_mask,
138+
mdp->data->bls_debug_mask);
139+
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
140+
mdp->data->con0_sel,
141+
mdp->data->con0_sel);
125142
}
126143

127-
clk_disable(mdp->clk_mm);
128-
clk_disable(mdp->clk_main);
144+
clk_disable_unprepare(mdp->clk_mm);
145+
clk_disable_unprepare(mdp->clk_main);
129146

130147
return 0;
131148
}
@@ -135,13 +152,16 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
135152
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
136153
int err;
137154

138-
err = clk_enable(mdp->clk_main);
139-
if (err < 0)
155+
err = clk_prepare_enable(mdp->clk_main);
156+
if (err < 0) {
157+
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
140158
return err;
159+
}
141160

142-
err = clk_enable(mdp->clk_mm);
161+
err = clk_prepare_enable(mdp->clk_mm);
143162
if (err < 0) {
144-
clk_disable(mdp->clk_main);
163+
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
164+
clk_disable_unprepare(mdp->clk_main);
145165
return err;
146166
}
147167

@@ -158,8 +178,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
158178
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
159179
0x0);
160180

161-
clk_disable(mdp->clk_mm);
162-
clk_disable(mdp->clk_main);
181+
clk_disable_unprepare(mdp->clk_mm);
182+
clk_disable_unprepare(mdp->clk_main);
163183
}
164184

165185
static const struct pwm_ops mtk_disp_pwm_ops = {
@@ -192,55 +212,26 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
192212
if (IS_ERR(mdp->clk_mm))
193213
return PTR_ERR(mdp->clk_mm);
194214

195-
ret = clk_prepare(mdp->clk_main);
196-
if (ret < 0)
197-
return ret;
198-
199-
ret = clk_prepare(mdp->clk_mm);
200-
if (ret < 0)
201-
goto disable_clk_main;
202-
203215
mdp->chip.dev = &pdev->dev;
204216
mdp->chip.ops = &mtk_disp_pwm_ops;
205217
mdp->chip.npwm = 1;
206218

207219
ret = pwmchip_add(&mdp->chip);
208220
if (ret < 0) {
209-
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
210-
goto disable_clk_mm;
221+
dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
222+
return ret;
211223
}
212224

213225
platform_set_drvdata(pdev, mdp);
214226

215-
/*
216-
* For MT2701, disable double buffer before writing register
217-
* and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
218-
*/
219-
if (!mdp->data->has_commit) {
220-
mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
221-
mdp->data->bls_debug_mask,
222-
mdp->data->bls_debug_mask);
223-
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
224-
mdp->data->con0_sel,
225-
mdp->data->con0_sel);
226-
}
227-
228227
return 0;
229-
230-
disable_clk_mm:
231-
clk_unprepare(mdp->clk_mm);
232-
disable_clk_main:
233-
clk_unprepare(mdp->clk_main);
234-
return ret;
235228
}
236229

237230
static int mtk_disp_pwm_remove(struct platform_device *pdev)
238231
{
239232
struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
240233

241234
pwmchip_remove(&mdp->chip);
242-
clk_unprepare(mdp->clk_mm);
243-
clk_unprepare(mdp->clk_main);
244235

245236
return 0;
246237
}

0 commit comments

Comments
 (0)