From 6778948f9de86c3cfaf36725a7c87dcff9ba247f Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 08:20:59 +0000 Subject: [PATCH] kernel_5.10 no rt --- kernel/drivers/pwm/pwm-rockchip.c | 26 +++++++++++++++++--------- 1 files changed, 17 insertions(+), 9 deletions(-) diff --git a/kernel/drivers/pwm/pwm-rockchip.c b/kernel/drivers/pwm/pwm-rockchip.c index 50e9195..fa455fb 100644 --- a/kernel/drivers/pwm/pwm-rockchip.c +++ b/kernel/drivers/pwm/pwm-rockchip.c @@ -169,7 +169,7 @@ const struct pwm_state *state) { struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); - unsigned long period, duty; + unsigned long period, duty, delay_ns; unsigned long flags; u64 div; u32 ctrl; @@ -191,11 +191,13 @@ div = (u64)pc->clk_rate * state->duty_cycle; duty = DIV_ROUND_CLOSEST_ULL(div, dclk_div * pc->data->prescaler * NSEC_PER_SEC); + if (pc->data->supports_lock) { + div = (u64)10 * NSEC_PER_SEC * dclk_div * pc->data->prescaler; + delay_ns = DIV_ROUND_UP_ULL(div, pc->clk_rate); + } + local_irq_save(flags); - /* - * Lock the period and duty of previous configuration, then - * change the duty and period, that would not be effective. - */ + ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl); if (pc->data->vop_pwm) { if (pc->vop_pwm_en) @@ -253,6 +255,10 @@ } #endif + /* + * Lock the period and duty of previous configuration, then + * change the duty and period, that would not be effective. + */ if (pc->data->supports_lock) { ctrl |= PWM_LOCK_EN; writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl); @@ -270,12 +276,14 @@ } /* - * Unlock and set polarity at the same time, - * the configuration of duty, period and polarity - * would be effective together at next period. + * Unlock and set polarity at the same time, the configuration of duty, + * period and polarity would be effective together at next period. It + * takes 10 dclk cycles to make sure lock works before unlocking. */ - if (pc->data->supports_lock) + if (pc->data->supports_lock) { ctrl &= ~PWM_LOCK_EN; + ndelay(delay_ns); + } writel(ctrl, pc->base + pc->data->regs.ctrl); local_irq_restore(flags); -- Gitblit v1.6.2