Changes since v6:
- fix commit msg of "pwm: mtk_disp: fix force reg to working reg".
Expain the reg access only when mm and main clock on.
Changes since v5:
- fix overflow.
- Seperate the reg shadow as a single patch.
Changes since v4:
- Squash the commit "move the commit to clock enabled" to "adjust the clocks to avoid them mismatch".
- Drop the useless comment about MT2701.
- Reenable the clks "mm" and "main" in .enable().
- Fix typo.
- Seperate get_state() operation as single patch.
Changes since v3:
- Seperate the clock sequence as single patch.
- Fixup the reg commit when clocks sequence changed.
- Merge the apply and get_state as single patch.
Changes since v2:
- Change commit messages to remove the clock operations for atomic APIs.
- Rebase to v5.13 rc1.
Changes since v1:
- Seperate clock operation as single patch.
- Seperate apply() as single patch.
- Seperate get_state() operation as single patch.
Jitao Shi (5):
pwm: mtk-disp: adjust the clocks to avoid them mismatch
pwm: mtk_disp: fix force reg to working reg.
pwm: mtk_disp: implement atomic API .apply()
pwm: mtk_disp: fix overflow in period and duty calcalation
pwm: mtk_disp: implement atomic API .get_state()
drivers/pwm/pwm-mtk-disp.c | 172 ++++++++++++++++++++-----------------
1 file changed, 92 insertions(+), 80 deletions(-)
--
2.25.1
Current calculation for period and high_width may have
64-bit overflow. state->period and rate are u64.
rate * state->period will overflow.
clk_div = div_u64(rate * state->period, NSEC_PER_SEC)
period = div64_u64(rate * state->period, div);
high_width = div64_u64(rate * state->duty_cycle, div);
This patch is to resolve it by using mul_u64_u64_div_u64().
Signed-off-by: Jitao Shi <[email protected]>
---
drivers/pwm/pwm-mtk-disp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 599d7dd8ecab..4f6de6f24484 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -116,7 +116,7 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
* high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
*/
rate = clk_get_rate(mdp->clk_main);
- clk_div = div_u64(rate * state->period, NSEC_PER_SEC) >>
+ clk_div = mul_u64_u64_div_u64(state->period, rate, NSEC_PER_SEC) >>
PWM_PERIOD_BIT_WIDTH;
if (clk_div > PWM_CLKDIV_MAX) {
if (!mdp->enabled) {
@@ -127,11 +127,11 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
}
div = NSEC_PER_SEC * (clk_div + 1);
- period = div64_u64(rate * state->period, div);
+ period = mul_u64_u64_div_u64(state->period, rate, div);
if (period > 0)
period--;
- high_width = div64_u64(rate * state->duty_cycle, div);
+ high_width = mul_u64_u64_div_u64(state->duty_cycle, rate, div);
value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
--
2.25.1