.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Driver for Allwinner sun4i Pulse Width Modulation Controller |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com> |
---|
5 | 6 | * |
---|
6 | | - * Licensed under GPLv2. |
---|
| 7 | + * Limitations: |
---|
| 8 | + * - When outputing the source clock directly, the PWM logic will be bypassed |
---|
| 9 | + * and the currently running period is not guaranteed to be completed |
---|
7 | 10 | */ |
---|
8 | 11 | |
---|
9 | 12 | #include <linux/bitops.h> |
---|
.. | .. |
---|
17 | 20 | #include <linux/of_device.h> |
---|
18 | 21 | #include <linux/platform_device.h> |
---|
19 | 22 | #include <linux/pwm.h> |
---|
| 23 | +#include <linux/reset.h> |
---|
20 | 24 | #include <linux/slab.h> |
---|
21 | 25 | #include <linux/spinlock.h> |
---|
22 | 26 | #include <linux/time.h> |
---|
.. | .. |
---|
73 | 77 | |
---|
74 | 78 | struct sun4i_pwm_data { |
---|
75 | 79 | bool has_prescaler_bypass; |
---|
| 80 | + bool has_direct_mod_clk_output; |
---|
76 | 81 | unsigned int npwm; |
---|
77 | 82 | }; |
---|
78 | 83 | |
---|
79 | 84 | struct sun4i_pwm_chip { |
---|
80 | 85 | struct pwm_chip chip; |
---|
| 86 | + struct clk *bus_clk; |
---|
81 | 87 | struct clk *clk; |
---|
| 88 | + struct reset_control *rst; |
---|
82 | 89 | void __iomem *base; |
---|
83 | 90 | spinlock_t ctrl_lock; |
---|
84 | 91 | const struct sun4i_pwm_data *data; |
---|
85 | 92 | unsigned long next_period[2]; |
---|
86 | | - bool needs_delay[2]; |
---|
87 | 93 | }; |
---|
88 | 94 | |
---|
89 | 95 | static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip) |
---|
.. | .. |
---|
116 | 122 | |
---|
117 | 123 | val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); |
---|
118 | 124 | |
---|
| 125 | + /* |
---|
| 126 | + * PWM chapter in H6 manual has a diagram which explains that if bypass |
---|
| 127 | + * bit is set, no other setting has any meaning. Even more, experiment |
---|
| 128 | + * proved that also enable bit is ignored in this case. |
---|
| 129 | + */ |
---|
| 130 | + if ((val & BIT_CH(PWM_BYPASS, pwm->hwpwm)) && |
---|
| 131 | + sun4i_pwm->data->has_direct_mod_clk_output) { |
---|
| 132 | + state->period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, clk_rate); |
---|
| 133 | + state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2); |
---|
| 134 | + state->polarity = PWM_POLARITY_NORMAL; |
---|
| 135 | + state->enabled = true; |
---|
| 136 | + return; |
---|
| 137 | + } |
---|
| 138 | + |
---|
119 | 139 | if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) && |
---|
120 | 140 | sun4i_pwm->data->has_prescaler_bypass) |
---|
121 | 141 | prescaler = 1; |
---|
.. | .. |
---|
138 | 158 | |
---|
139 | 159 | val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm)); |
---|
140 | 160 | |
---|
141 | | - tmp = prescaler * NSEC_PER_SEC * PWM_REG_DTY(val); |
---|
| 161 | + tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_DTY(val); |
---|
142 | 162 | state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); |
---|
143 | 163 | |
---|
144 | | - tmp = prescaler * NSEC_PER_SEC * PWM_REG_PRD(val); |
---|
| 164 | + tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_PRD(val); |
---|
145 | 165 | state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); |
---|
146 | 166 | } |
---|
147 | 167 | |
---|
148 | 168 | static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm, |
---|
149 | | - struct pwm_state *state, |
---|
150 | | - u32 *dty, u32 *prd, unsigned int *prsclr) |
---|
| 169 | + const struct pwm_state *state, |
---|
| 170 | + u32 *dty, u32 *prd, unsigned int *prsclr, |
---|
| 171 | + bool *bypass) |
---|
151 | 172 | { |
---|
152 | 173 | u64 clk_rate, div = 0; |
---|
153 | | - unsigned int pval, prescaler = 0; |
---|
| 174 | + unsigned int prescaler = 0; |
---|
154 | 175 | |
---|
155 | 176 | clk_rate = clk_get_rate(sun4i_pwm->clk); |
---|
| 177 | + |
---|
| 178 | + *bypass = sun4i_pwm->data->has_direct_mod_clk_output && |
---|
| 179 | + state->enabled && |
---|
| 180 | + (state->period * clk_rate >= NSEC_PER_SEC) && |
---|
| 181 | + (state->period * clk_rate < 2 * NSEC_PER_SEC) && |
---|
| 182 | + (state->duty_cycle * clk_rate * 2 >= NSEC_PER_SEC); |
---|
| 183 | + |
---|
| 184 | + /* Skip calculation of other parameters if we bypass them */ |
---|
| 185 | + if (*bypass) |
---|
| 186 | + return 0; |
---|
156 | 187 | |
---|
157 | 188 | if (sun4i_pwm->data->has_prescaler_bypass) { |
---|
158 | 189 | /* First, test without any prescaler when available */ |
---|
159 | 190 | prescaler = PWM_PRESCAL_MASK; |
---|
160 | | - pval = 1; |
---|
161 | 191 | /* |
---|
162 | 192 | * When not using any prescaler, the clock period in nanoseconds |
---|
163 | 193 | * is not an integer so round it half up instead of |
---|
.. | .. |
---|
172 | 202 | if (prescaler == 0) { |
---|
173 | 203 | /* Go up from the first divider */ |
---|
174 | 204 | for (prescaler = 0; prescaler < PWM_PRESCAL_MASK; prescaler++) { |
---|
175 | | - if (!prescaler_table[prescaler]) |
---|
| 205 | + unsigned int pval = prescaler_table[prescaler]; |
---|
| 206 | + |
---|
| 207 | + if (!pval) |
---|
176 | 208 | continue; |
---|
177 | | - pval = prescaler_table[prescaler]; |
---|
| 209 | + |
---|
178 | 210 | div = clk_rate; |
---|
179 | 211 | do_div(div, pval); |
---|
180 | 212 | div = div * state->period; |
---|
.. | .. |
---|
193 | 225 | *dty = div; |
---|
194 | 226 | *prsclr = prescaler; |
---|
195 | 227 | |
---|
196 | | - div = (u64)pval * NSEC_PER_SEC * *prd; |
---|
197 | | - state->period = DIV_ROUND_CLOSEST_ULL(div, clk_rate); |
---|
198 | | - |
---|
199 | | - div = (u64)pval * NSEC_PER_SEC * *dty; |
---|
200 | | - state->duty_cycle = DIV_ROUND_CLOSEST_ULL(div, clk_rate); |
---|
201 | | - |
---|
202 | 228 | return 0; |
---|
203 | 229 | } |
---|
204 | 230 | |
---|
205 | 231 | static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, |
---|
206 | | - struct pwm_state *state) |
---|
| 232 | + const struct pwm_state *state) |
---|
207 | 233 | { |
---|
208 | 234 | struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip); |
---|
209 | 235 | struct pwm_state cstate; |
---|
210 | | - u32 ctrl; |
---|
| 236 | + u32 ctrl, duty = 0, period = 0, val; |
---|
211 | 237 | int ret; |
---|
212 | | - unsigned int delay_us; |
---|
| 238 | + unsigned int delay_us, prescaler = 0; |
---|
213 | 239 | unsigned long now; |
---|
| 240 | + bool bypass; |
---|
214 | 241 | |
---|
215 | 242 | pwm_get_state(pwm, &cstate); |
---|
216 | 243 | |
---|
.. | .. |
---|
222 | 249 | } |
---|
223 | 250 | } |
---|
224 | 251 | |
---|
| 252 | + ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler, |
---|
| 253 | + &bypass); |
---|
| 254 | + if (ret) { |
---|
| 255 | + dev_err(chip->dev, "period exceeds the maximum value\n"); |
---|
| 256 | + if (!cstate.enabled) |
---|
| 257 | + clk_disable_unprepare(sun4i_pwm->clk); |
---|
| 258 | + return ret; |
---|
| 259 | + } |
---|
| 260 | + |
---|
225 | 261 | spin_lock(&sun4i_pwm->ctrl_lock); |
---|
226 | 262 | ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); |
---|
227 | 263 | |
---|
228 | | - if ((cstate.period != state->period) || |
---|
229 | | - (cstate.duty_cycle != state->duty_cycle)) { |
---|
230 | | - u32 period, duty, val; |
---|
231 | | - unsigned int prescaler; |
---|
232 | | - |
---|
233 | | - ret = sun4i_pwm_calculate(sun4i_pwm, state, |
---|
234 | | - &duty, &period, &prescaler); |
---|
235 | | - if (ret) { |
---|
236 | | - dev_err(chip->dev, "period exceeds the maximum value\n"); |
---|
237 | | - spin_unlock(&sun4i_pwm->ctrl_lock); |
---|
238 | | - if (!cstate.enabled) |
---|
239 | | - clk_disable_unprepare(sun4i_pwm->clk); |
---|
240 | | - return ret; |
---|
241 | | - } |
---|
242 | | - |
---|
243 | | - if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) { |
---|
244 | | - /* Prescaler changed, the clock has to be gated */ |
---|
245 | | - ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm); |
---|
| 264 | + if (sun4i_pwm->data->has_direct_mod_clk_output) { |
---|
| 265 | + if (bypass) { |
---|
| 266 | + ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm); |
---|
| 267 | + /* We can skip other parameter */ |
---|
246 | 268 | sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG); |
---|
247 | | - |
---|
248 | | - ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm); |
---|
249 | | - ctrl |= BIT_CH(prescaler, pwm->hwpwm); |
---|
| 269 | + spin_unlock(&sun4i_pwm->ctrl_lock); |
---|
| 270 | + return 0; |
---|
250 | 271 | } |
---|
251 | 272 | |
---|
252 | | - val = (duty & PWM_DTY_MASK) | PWM_PRD(period); |
---|
253 | | - sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm)); |
---|
254 | | - sun4i_pwm->next_period[pwm->hwpwm] = jiffies + |
---|
255 | | - usecs_to_jiffies(do_div(cstate.period, 1000) + 1); |
---|
256 | | - sun4i_pwm->needs_delay[pwm->hwpwm] = true; |
---|
| 273 | + ctrl &= ~BIT_CH(PWM_BYPASS, pwm->hwpwm); |
---|
257 | 274 | } |
---|
| 275 | + |
---|
| 276 | + if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) { |
---|
| 277 | + /* Prescaler changed, the clock has to be gated */ |
---|
| 278 | + ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm); |
---|
| 279 | + sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG); |
---|
| 280 | + |
---|
| 281 | + ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm); |
---|
| 282 | + ctrl |= BIT_CH(prescaler, pwm->hwpwm); |
---|
| 283 | + } |
---|
| 284 | + |
---|
| 285 | + val = (duty & PWM_DTY_MASK) | PWM_PRD(period); |
---|
| 286 | + sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm)); |
---|
| 287 | + sun4i_pwm->next_period[pwm->hwpwm] = jiffies + |
---|
| 288 | + nsecs_to_jiffies(cstate.period + 1000); |
---|
258 | 289 | |
---|
259 | 290 | if (state->polarity != PWM_POLARITY_NORMAL) |
---|
260 | 291 | ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm); |
---|
.. | .. |
---|
262 | 293 | ctrl |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm); |
---|
263 | 294 | |
---|
264 | 295 | ctrl |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm); |
---|
265 | | - if (state->enabled) { |
---|
| 296 | + |
---|
| 297 | + if (state->enabled) |
---|
266 | 298 | ctrl |= BIT_CH(PWM_EN, pwm->hwpwm); |
---|
267 | | - } else if (!sun4i_pwm->needs_delay[pwm->hwpwm]) { |
---|
268 | | - ctrl &= ~BIT_CH(PWM_EN, pwm->hwpwm); |
---|
269 | | - ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm); |
---|
270 | | - } |
---|
271 | 299 | |
---|
272 | 300 | sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG); |
---|
273 | 301 | |
---|
.. | .. |
---|
276 | 304 | if (state->enabled) |
---|
277 | 305 | return 0; |
---|
278 | 306 | |
---|
279 | | - if (!sun4i_pwm->needs_delay[pwm->hwpwm]) { |
---|
280 | | - clk_disable_unprepare(sun4i_pwm->clk); |
---|
281 | | - return 0; |
---|
282 | | - } |
---|
283 | | - |
---|
284 | 307 | /* We need a full period to elapse before disabling the channel. */ |
---|
285 | 308 | now = jiffies; |
---|
286 | | - if (sun4i_pwm->needs_delay[pwm->hwpwm] && |
---|
287 | | - time_before(now, sun4i_pwm->next_period[pwm->hwpwm])) { |
---|
| 309 | + if (time_before(now, sun4i_pwm->next_period[pwm->hwpwm])) { |
---|
288 | 310 | delay_us = jiffies_to_usecs(sun4i_pwm->next_period[pwm->hwpwm] - |
---|
289 | 311 | now); |
---|
290 | 312 | if ((delay_us / 500) > MAX_UDELAY_MS) |
---|
.. | .. |
---|
292 | 314 | else |
---|
293 | 315 | usleep_range(delay_us, delay_us * 2); |
---|
294 | 316 | } |
---|
295 | | - sun4i_pwm->needs_delay[pwm->hwpwm] = false; |
---|
296 | 317 | |
---|
297 | 318 | spin_lock(&sun4i_pwm->ctrl_lock); |
---|
298 | 319 | ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG); |
---|
.. | .. |
---|
327 | 348 | .npwm = 1, |
---|
328 | 349 | }; |
---|
329 | 350 | |
---|
| 351 | +static const struct sun4i_pwm_data sun50i_a64_pwm_data = { |
---|
| 352 | + .has_prescaler_bypass = true, |
---|
| 353 | + .has_direct_mod_clk_output = true, |
---|
| 354 | + .npwm = 1, |
---|
| 355 | +}; |
---|
| 356 | + |
---|
| 357 | +static const struct sun4i_pwm_data sun50i_h6_pwm_data = { |
---|
| 358 | + .has_prescaler_bypass = true, |
---|
| 359 | + .has_direct_mod_clk_output = true, |
---|
| 360 | + .npwm = 2, |
---|
| 361 | +}; |
---|
| 362 | + |
---|
330 | 363 | static const struct of_device_id sun4i_pwm_dt_ids[] = { |
---|
331 | 364 | { |
---|
332 | 365 | .compatible = "allwinner,sun4i-a10-pwm", |
---|
.. | .. |
---|
343 | 376 | }, { |
---|
344 | 377 | .compatible = "allwinner,sun8i-h3-pwm", |
---|
345 | 378 | .data = &sun4i_pwm_single_bypass, |
---|
| 379 | + }, { |
---|
| 380 | + .compatible = "allwinner,sun50i-a64-pwm", |
---|
| 381 | + .data = &sun50i_a64_pwm_data, |
---|
| 382 | + }, { |
---|
| 383 | + .compatible = "allwinner,sun50i-h6-pwm", |
---|
| 384 | + .data = &sun50i_h6_pwm_data, |
---|
346 | 385 | }, { |
---|
347 | 386 | /* sentinel */ |
---|
348 | 387 | }, |
---|
.. | .. |
---|
368 | 407 | if (IS_ERR(pwm->base)) |
---|
369 | 408 | return PTR_ERR(pwm->base); |
---|
370 | 409 | |
---|
371 | | - pwm->clk = devm_clk_get(&pdev->dev, NULL); |
---|
| 410 | + /* |
---|
| 411 | + * All hardware variants need a source clock that is divided and |
---|
| 412 | + * then feeds the counter that defines the output wave form. In the |
---|
| 413 | + * device tree this clock is either unnamed or called "mod". |
---|
| 414 | + * Some variants (e.g. H6) need another clock to access the |
---|
| 415 | + * hardware registers; this is called "bus". |
---|
| 416 | + * So we request "mod" first (and ignore the corner case that a |
---|
| 417 | + * parent provides a "mod" clock while the right one would be the |
---|
| 418 | + * unnamed one of the PWM device) and if this is not found we fall |
---|
| 419 | + * back to the first clock of the PWM. |
---|
| 420 | + */ |
---|
| 421 | + pwm->clk = devm_clk_get_optional(&pdev->dev, "mod"); |
---|
372 | 422 | if (IS_ERR(pwm->clk)) |
---|
373 | | - return PTR_ERR(pwm->clk); |
---|
| 423 | + return dev_err_probe(&pdev->dev, PTR_ERR(pwm->clk), |
---|
| 424 | + "get mod clock failed\n"); |
---|
| 425 | + |
---|
| 426 | + if (!pwm->clk) { |
---|
| 427 | + pwm->clk = devm_clk_get(&pdev->dev, NULL); |
---|
| 428 | + if (IS_ERR(pwm->clk)) |
---|
| 429 | + return dev_err_probe(&pdev->dev, PTR_ERR(pwm->clk), |
---|
| 430 | + "get unnamed clock failed\n"); |
---|
| 431 | + } |
---|
| 432 | + |
---|
| 433 | + pwm->bus_clk = devm_clk_get_optional(&pdev->dev, "bus"); |
---|
| 434 | + if (IS_ERR(pwm->bus_clk)) |
---|
| 435 | + return dev_err_probe(&pdev->dev, PTR_ERR(pwm->bus_clk), |
---|
| 436 | + "get bus clock failed\n"); |
---|
| 437 | + |
---|
| 438 | + pwm->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL); |
---|
| 439 | + if (IS_ERR(pwm->rst)) |
---|
| 440 | + return dev_err_probe(&pdev->dev, PTR_ERR(pwm->rst), |
---|
| 441 | + "get reset failed\n"); |
---|
| 442 | + |
---|
| 443 | + /* Deassert reset */ |
---|
| 444 | + ret = reset_control_deassert(pwm->rst); |
---|
| 445 | + if (ret) { |
---|
| 446 | + dev_err(&pdev->dev, "cannot deassert reset control: %pe\n", |
---|
| 447 | + ERR_PTR(ret)); |
---|
| 448 | + return ret; |
---|
| 449 | + } |
---|
| 450 | + |
---|
| 451 | + /* |
---|
| 452 | + * We're keeping the bus clock on for the sake of simplicity. |
---|
| 453 | + * Actually it only needs to be on for hardware register accesses. |
---|
| 454 | + */ |
---|
| 455 | + ret = clk_prepare_enable(pwm->bus_clk); |
---|
| 456 | + if (ret) { |
---|
| 457 | + dev_err(&pdev->dev, "cannot prepare and enable bus_clk %pe\n", |
---|
| 458 | + ERR_PTR(ret)); |
---|
| 459 | + goto err_bus; |
---|
| 460 | + } |
---|
374 | 461 | |
---|
375 | 462 | pwm->chip.dev = &pdev->dev; |
---|
376 | 463 | pwm->chip.ops = &sun4i_pwm_ops; |
---|
.. | .. |
---|
384 | 471 | ret = pwmchip_add(&pwm->chip); |
---|
385 | 472 | if (ret < 0) { |
---|
386 | 473 | dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); |
---|
387 | | - return ret; |
---|
| 474 | + goto err_pwm_add; |
---|
388 | 475 | } |
---|
389 | 476 | |
---|
390 | 477 | platform_set_drvdata(pdev, pwm); |
---|
391 | 478 | |
---|
392 | 479 | return 0; |
---|
| 480 | + |
---|
| 481 | +err_pwm_add: |
---|
| 482 | + clk_disable_unprepare(pwm->bus_clk); |
---|
| 483 | +err_bus: |
---|
| 484 | + reset_control_assert(pwm->rst); |
---|
| 485 | + |
---|
| 486 | + return ret; |
---|
393 | 487 | } |
---|
394 | 488 | |
---|
395 | 489 | static int sun4i_pwm_remove(struct platform_device *pdev) |
---|
396 | 490 | { |
---|
397 | 491 | struct sun4i_pwm_chip *pwm = platform_get_drvdata(pdev); |
---|
| 492 | + int ret; |
---|
398 | 493 | |
---|
399 | | - return pwmchip_remove(&pwm->chip); |
---|
| 494 | + ret = pwmchip_remove(&pwm->chip); |
---|
| 495 | + if (ret) |
---|
| 496 | + return ret; |
---|
| 497 | + |
---|
| 498 | + clk_disable_unprepare(pwm->bus_clk); |
---|
| 499 | + reset_control_assert(pwm->rst); |
---|
| 500 | + |
---|
| 501 | + return 0; |
---|
400 | 502 | } |
---|
401 | 503 | |
---|
402 | 504 | static struct platform_driver sun4i_pwm_driver = { |
---|