| .. | .. |
|---|
| 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); |
|---|