.. | .. |
---|
169 | 169 | const struct pwm_state *state) |
---|
170 | 170 | { |
---|
171 | 171 | struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); |
---|
172 | | - unsigned long period, duty; |
---|
| 172 | + unsigned long period, duty, delay_ns; |
---|
173 | 173 | unsigned long flags; |
---|
174 | 174 | u64 div; |
---|
175 | 175 | u32 ctrl; |
---|
.. | .. |
---|
191 | 191 | div = (u64)pc->clk_rate * state->duty_cycle; |
---|
192 | 192 | duty = DIV_ROUND_CLOSEST_ULL(div, dclk_div * pc->data->prescaler * NSEC_PER_SEC); |
---|
193 | 193 | |
---|
| 194 | + if (pc->data->supports_lock) { |
---|
| 195 | + div = (u64)10 * NSEC_PER_SEC * dclk_div * pc->data->prescaler; |
---|
| 196 | + delay_ns = DIV_ROUND_UP_ULL(div, pc->clk_rate); |
---|
| 197 | + } |
---|
| 198 | + |
---|
194 | 199 | local_irq_save(flags); |
---|
195 | | - /* |
---|
196 | | - * Lock the period and duty of previous configuration, then |
---|
197 | | - * change the duty and period, that would not be effective. |
---|
198 | | - */ |
---|
| 200 | + |
---|
199 | 201 | ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl); |
---|
200 | 202 | if (pc->data->vop_pwm) { |
---|
201 | 203 | if (pc->vop_pwm_en) |
---|
.. | .. |
---|
253 | 255 | } |
---|
254 | 256 | #endif |
---|
255 | 257 | |
---|
| 258 | + /* |
---|
| 259 | + * Lock the period and duty of previous configuration, then |
---|
| 260 | + * change the duty and period, that would not be effective. |
---|
| 261 | + */ |
---|
256 | 262 | if (pc->data->supports_lock) { |
---|
257 | 263 | ctrl |= PWM_LOCK_EN; |
---|
258 | 264 | writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl); |
---|
.. | .. |
---|
270 | 276 | } |
---|
271 | 277 | |
---|
272 | 278 | /* |
---|
273 | | - * Unlock and set polarity at the same time, |
---|
274 | | - * the configuration of duty, period and polarity |
---|
275 | | - * would be effective together at next period. |
---|
| 279 | + * Unlock and set polarity at the same time, the configuration of duty, |
---|
| 280 | + * period and polarity would be effective together at next period. It |
---|
| 281 | + * takes 10 dclk cycles to make sure lock works before unlocking. |
---|
276 | 282 | */ |
---|
277 | | - if (pc->data->supports_lock) |
---|
| 283 | + if (pc->data->supports_lock) { |
---|
278 | 284 | ctrl &= ~PWM_LOCK_EN; |
---|
| 285 | + ndelay(delay_ns); |
---|
| 286 | + } |
---|
279 | 287 | |
---|
280 | 288 | writel(ctrl, pc->base + pc->data->regs.ctrl); |
---|
281 | 289 | local_irq_restore(flags); |
---|