2021-08-08 13:30:11

by Jitao Shi

[permalink] [raw]
Subject: [PATCH v7 0/5] fix the clks on/off mismatch issue and switch pwm-mtk-disp to atomic APIs

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


2021-08-08 13:43:40

by Jitao Shi

[permalink] [raw]
Subject: [PATCH v7 4/5] pwm: mtk_disp: fix overflow in period and duty calcalation

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