1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * corePWM driver for Microchip "soft" FPGA IP cores. |
4 | * |
5 | * Copyright (c) 2021-2023 Microchip Corporation. All rights reserved. |
6 | * Author: Conor Dooley <conor.dooley@microchip.com> |
7 | * Documentation: |
8 | * https://www.microsemi.com/document-portal/doc_download/1245275-corepwm-hb |
9 | * |
10 | * Limitations: |
11 | * - If the IP block is configured without "shadow registers", all register |
12 | * writes will take effect immediately, causing glitches on the output. |
13 | * If shadow registers *are* enabled, setting the "SYNC_UPDATE" register |
14 | * notifies the core that it needs to update the registers defining the |
15 | * waveform from the contents of the "shadow registers". Otherwise, changes |
16 | * will take effective immediately, even for those channels. |
17 | * As setting the period/duty cycle takes 4 register writes, there is a window |
18 | * in which this races against the start of a new period. |
19 | * - The IP block has no concept of a duty cycle, only rising/falling edges of |
20 | * the waveform. Unfortunately, if the rising & falling edges registers have |
21 | * the same value written to them the IP block will do whichever of a rising |
22 | * or a falling edge is possible. I.E. a 50% waveform at twice the requested |
23 | * period. Therefore to get a 0% waveform, the output is set the max high/low |
24 | * time depending on polarity. |
25 | * If the duty cycle is 0%, and the requested period is less than the |
26 | * available period resolution, this will manifest as a ~100% waveform (with |
27 | * some output glitches) rather than 50%. |
28 | * - The PWM period is set for the whole IP block not per channel. The driver |
29 | * will only change the period if no other PWM output is enabled. |
30 | */ |
31 | |
32 | #include <linux/clk.h> |
33 | #include <linux/delay.h> |
34 | #include <linux/err.h> |
35 | #include <linux/io.h> |
36 | #include <linux/ktime.h> |
37 | #include <linux/math.h> |
38 | #include <linux/module.h> |
39 | #include <linux/mutex.h> |
40 | #include <linux/of.h> |
41 | #include <linux/platform_device.h> |
42 | #include <linux/pwm.h> |
43 | |
44 | #define MCHPCOREPWM_PRESCALE_MAX 0xff |
45 | #define MCHPCOREPWM_PERIOD_STEPS_MAX 0xfe |
46 | #define MCHPCOREPWM_PERIOD_MAX 0xff00 |
47 | |
48 | #define MCHPCOREPWM_PRESCALE 0x00 |
49 | #define MCHPCOREPWM_PERIOD 0x04 |
50 | #define MCHPCOREPWM_EN(i) (0x08 + 0x04 * (i)) /* 0x08, 0x0c */ |
51 | #define MCHPCOREPWM_POSEDGE(i) (0x10 + 0x08 * (i)) /* 0x10, 0x18, ..., 0x88 */ |
52 | #define MCHPCOREPWM_NEGEDGE(i) (0x14 + 0x08 * (i)) /* 0x14, 0x1c, ..., 0x8c */ |
53 | #define MCHPCOREPWM_SYNC_UPD 0xe4 |
54 | #define MCHPCOREPWM_TIMEOUT_MS 100u |
55 | |
56 | struct mchp_core_pwm_chip { |
57 | struct clk *clk; |
58 | void __iomem *base; |
59 | struct mutex lock; /* protects the shared period */ |
60 | ktime_t update_timestamp; |
61 | u32 sync_update_mask; |
62 | u16 channel_enabled; |
63 | }; |
64 | |
65 | static inline struct mchp_core_pwm_chip *to_mchp_core_pwm(struct pwm_chip *chip) |
66 | { |
67 | return pwmchip_get_drvdata(chip); |
68 | } |
69 | |
70 | static void mchp_core_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, |
71 | bool enable, u64 period) |
72 | { |
73 | struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip); |
74 | u8 channel_enable, reg_offset, shift; |
75 | |
76 | /* |
77 | * There are two adjacent 8 bit control regs, the lower reg controls |
78 | * 0-7 and the upper reg 8-15. Check if the pwm is in the upper reg |
79 | * and if so, offset by the bus width. |
80 | */ |
81 | reg_offset = MCHPCOREPWM_EN(pwm->hwpwm >> 3); |
82 | shift = pwm->hwpwm & 7; |
83 | |
84 | channel_enable = readb_relaxed(mchp_core_pwm->base + reg_offset); |
85 | channel_enable &= ~(1 << shift); |
86 | channel_enable |= (enable << shift); |
87 | |
88 | writel_relaxed(channel_enable, mchp_core_pwm->base + reg_offset); |
89 | mchp_core_pwm->channel_enabled &= ~BIT(pwm->hwpwm); |
90 | mchp_core_pwm->channel_enabled |= enable << pwm->hwpwm; |
91 | |
92 | /* |
93 | * The updated values will not appear on the bus until they have been |
94 | * applied to the waveform at the beginning of the next period. |
95 | * This is a NO-OP if the channel does not have shadow registers. |
96 | */ |
97 | if (mchp_core_pwm->sync_update_mask & (1 << pwm->hwpwm)) |
98 | mchp_core_pwm->update_timestamp = ktime_add_ns(ktime_get(), period); |
99 | } |
100 | |
101 | static void mchp_core_pwm_wait_for_sync_update(struct mchp_core_pwm_chip *mchp_core_pwm, |
102 | unsigned int channel) |
103 | { |
104 | /* |
105 | * If a shadow register is used for this PWM channel, and iff there is |
106 | * a pending update to the waveform, we must wait for it to be applied |
107 | * before attempting to read its state. Reading the registers yields |
108 | * the currently implemented settings & the new ones are only readable |
109 | * once the current period has ended. |
110 | */ |
111 | |
112 | if (mchp_core_pwm->sync_update_mask & (1 << channel)) { |
113 | ktime_t current_time = ktime_get(); |
114 | s64 remaining_ns; |
115 | u32 delay_us; |
116 | |
117 | remaining_ns = ktime_to_ns(ktime_sub(mchp_core_pwm->update_timestamp, |
118 | current_time)); |
119 | |
120 | /* |
121 | * If the update has gone through, don't bother waiting for |
122 | * obvious reasons. Otherwise wait around for an appropriate |
123 | * amount of time for the update to go through. |
124 | */ |
125 | if (remaining_ns <= 0) |
126 | return; |
127 | |
128 | delay_us = DIV_ROUND_UP_ULL(remaining_ns, NSEC_PER_USEC); |
129 | fsleep(usecs: delay_us); |
130 | } |
131 | } |
132 | |
133 | static u64 mchp_core_pwm_calc_duty(const struct pwm_state *state, u64 clk_rate, |
134 | u8 prescale, u8 period_steps) |
135 | { |
136 | u64 duty_steps, tmp; |
137 | |
138 | /* |
139 | * Calculate the duty cycle in multiples of the prescaled period: |
140 | * duty_steps = duty_in_ns / step_in_ns |
141 | * step_in_ns = (prescale * NSEC_PER_SEC) / clk_rate |
142 | * The code below is rearranged slightly to only divide once. |
143 | */ |
144 | tmp = (((u64)prescale) + 1) * NSEC_PER_SEC; |
145 | duty_steps = mul_u64_u64_div_u64(a: state->duty_cycle, mul: clk_rate, div: tmp); |
146 | |
147 | return duty_steps; |
148 | } |
149 | |
150 | static void mchp_core_pwm_apply_duty(struct pwm_chip *chip, struct pwm_device *pwm, |
151 | const struct pwm_state *state, u64 duty_steps, |
152 | u16 period_steps) |
153 | { |
154 | struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip); |
155 | u8 posedge, negedge; |
156 | u8 first_edge = 0, second_edge = duty_steps; |
157 | |
158 | /* |
159 | * Setting posedge == negedge doesn't yield a constant output, |
160 | * so that's an unsuitable setting to model duty_steps = 0. |
161 | * In that case set the unwanted edge to a value that never |
162 | * triggers. |
163 | */ |
164 | if (duty_steps == 0) |
165 | first_edge = period_steps + 1; |
166 | |
167 | if (state->polarity == PWM_POLARITY_INVERSED) { |
168 | negedge = first_edge; |
169 | posedge = second_edge; |
170 | } else { |
171 | posedge = first_edge; |
172 | negedge = second_edge; |
173 | } |
174 | |
175 | /* |
176 | * Set the sync bit which ensures that periods that already started are |
177 | * completed unaltered. At each counter reset event the values are |
178 | * updated from the shadow registers. |
179 | */ |
180 | writel_relaxed(posedge, mchp_core_pwm->base + MCHPCOREPWM_POSEDGE(pwm->hwpwm)); |
181 | writel_relaxed(negedge, mchp_core_pwm->base + MCHPCOREPWM_NEGEDGE(pwm->hwpwm)); |
182 | } |
183 | |
184 | static int mchp_core_pwm_calc_period(const struct pwm_state *state, unsigned long clk_rate, |
185 | u16 *prescale, u16 *period_steps) |
186 | { |
187 | u64 tmp; |
188 | |
189 | /* |
190 | * Calculate the period cycles and prescale values. |
191 | * The registers are each 8 bits wide & multiplied to compute the period |
192 | * using the formula: |
193 | * (prescale + 1) * (period_steps + 1) |
194 | * period = ------------------------------------- |
195 | * clk_rate |
196 | * so the maximum period that can be generated is 0x10000 times the |
197 | * period of the input clock. |
198 | * However, due to the design of the "hardware", it is not possible to |
199 | * attain a 100% duty cycle if the full range of period_steps is used. |
200 | * Therefore period_steps is restricted to 0xfe and the maximum multiple |
201 | * of the clock period attainable is (0xff + 1) * (0xfe + 1) = 0xff00 |
202 | * |
203 | * The prescale and period_steps registers operate similarly to |
204 | * CLK_DIVIDER_ONE_BASED, where the value used by the hardware is that |
205 | * in the register plus one. |
206 | * It's therefore not possible to set a period lower than 1/clk_rate, so |
207 | * if tmp is 0, abort. Without aborting, we will set a period that is |
208 | * greater than that requested and, more importantly, will trigger the |
209 | * neg-/pos-edge issue described in the limitations. |
210 | */ |
211 | tmp = mul_u64_u64_div_u64(a: state->period, mul: clk_rate, NSEC_PER_SEC); |
212 | if (tmp >= MCHPCOREPWM_PERIOD_MAX) { |
213 | *prescale = MCHPCOREPWM_PRESCALE_MAX; |
214 | *period_steps = MCHPCOREPWM_PERIOD_STEPS_MAX; |
215 | |
216 | return 0; |
217 | } |
218 | |
219 | /* |
220 | * There are multiple strategies that could be used to choose the |
221 | * prescale & period_steps values. |
222 | * Here the idea is to pick values so that the selection of duty cycles |
223 | * is as finegrain as possible, while also keeping the period less than |
224 | * that requested. |
225 | * |
226 | * A simple way to satisfy the first condition is to always set |
227 | * period_steps to its maximum value. This neatly also satisfies the |
228 | * second condition too, since using the maximum value of period_steps |
229 | * to calculate prescale actually calculates its upper bound. |
230 | * Integer division will ensure a round down, so the period will thereby |
231 | * always be less than that requested. |
232 | * |
233 | * The downside of this approach is a significant degree of inaccuracy, |
234 | * especially as tmp approaches integer multiples of |
235 | * MCHPCOREPWM_PERIOD_STEPS_MAX. |
236 | * |
237 | * As we must produce a period less than that requested, and for the |
238 | * sake of creating a simple algorithm, disallow small values of tmp |
239 | * that would need special handling. |
240 | */ |
241 | if (tmp < MCHPCOREPWM_PERIOD_STEPS_MAX + 1) |
242 | return -EINVAL; |
243 | |
244 | /* |
245 | * This "optimal" value for prescale is be calculated using the maximum |
246 | * permitted value of period_steps, 0xfe. |
247 | * |
248 | * period * clk_rate |
249 | * prescale = ------------------------- - 1 |
250 | * NSEC_PER_SEC * (0xfe + 1) |
251 | * |
252 | * |
253 | * period * clk_rate |
254 | * ------------------- was precomputed as `tmp` |
255 | * NSEC_PER_SEC |
256 | */ |
257 | *prescale = ((u16)tmp) / (MCHPCOREPWM_PERIOD_STEPS_MAX + 1) - 1; |
258 | |
259 | /* |
260 | * period_steps can be computed from prescale: |
261 | * period * clk_rate |
262 | * period_steps = ----------------------------- - 1 |
263 | * NSEC_PER_SEC * (prescale + 1) |
264 | * |
265 | * However, in this approximation, we simply use the maximum value that |
266 | * was used to compute prescale. |
267 | */ |
268 | *period_steps = MCHPCOREPWM_PERIOD_STEPS_MAX; |
269 | |
270 | return 0; |
271 | } |
272 | |
273 | static int mchp_core_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm, |
274 | const struct pwm_state *state) |
275 | { |
276 | struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip); |
277 | bool period_locked; |
278 | unsigned long clk_rate; |
279 | u64 duty_steps; |
280 | u16 prescale, period_steps; |
281 | int ret; |
282 | |
283 | if (!state->enabled) { |
284 | mchp_core_pwm_enable(chip, pwm, enable: false, period: pwm->state.period); |
285 | return 0; |
286 | } |
287 | |
288 | /* |
289 | * If clk_rate is too big, the following multiplication might overflow. |
290 | * However this is implausible, as the fabric of current FPGAs cannot |
291 | * provide clocks at a rate high enough. |
292 | */ |
293 | clk_rate = clk_get_rate(clk: mchp_core_pwm->clk); |
294 | if (clk_rate >= NSEC_PER_SEC) |
295 | return -EINVAL; |
296 | |
297 | ret = mchp_core_pwm_calc_period(state, clk_rate, prescale: &prescale, period_steps: &period_steps); |
298 | if (ret) |
299 | return ret; |
300 | |
301 | /* |
302 | * If the only thing that has changed is the duty cycle or the polarity, |
303 | * we can shortcut the calculations and just compute/apply the new duty |
304 | * cycle pos & neg edges |
305 | * As all the channels share the same period, do not allow it to be |
306 | * changed if any other channels are enabled. |
307 | * If the period is locked, it may not be possible to use a period |
308 | * less than that requested. In that case, we just abort. |
309 | */ |
310 | period_locked = mchp_core_pwm->channel_enabled & ~(1 << pwm->hwpwm); |
311 | |
312 | if (period_locked) { |
313 | u16 hw_prescale; |
314 | u16 hw_period_steps; |
315 | |
316 | hw_prescale = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_PRESCALE); |
317 | hw_period_steps = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_PERIOD); |
318 | |
319 | if ((period_steps + 1) * (prescale + 1) < |
320 | (hw_period_steps + 1) * (hw_prescale + 1)) |
321 | return -EINVAL; |
322 | |
323 | /* |
324 | * It is possible that something could have set the period_steps |
325 | * register to 0xff, which would prevent us from setting a 100% |
326 | * or 0% relative duty cycle, as explained above in |
327 | * mchp_core_pwm_calc_period(). |
328 | * The period is locked and we cannot change this, so we abort. |
329 | */ |
330 | if (hw_period_steps == MCHPCOREPWM_PERIOD_STEPS_MAX) |
331 | return -EINVAL; |
332 | |
333 | prescale = hw_prescale; |
334 | period_steps = hw_period_steps; |
335 | } |
336 | |
337 | duty_steps = mchp_core_pwm_calc_duty(state, clk_rate, prescale, period_steps); |
338 | |
339 | /* |
340 | * Because the period is not per channel, it is possible that the |
341 | * requested duty cycle is longer than the period, in which case cap it |
342 | * to the period, IOW a 100% duty cycle. |
343 | */ |
344 | if (duty_steps > period_steps) |
345 | duty_steps = period_steps + 1; |
346 | |
347 | if (!period_locked) { |
348 | writel_relaxed(prescale, mchp_core_pwm->base + MCHPCOREPWM_PRESCALE); |
349 | writel_relaxed(period_steps, mchp_core_pwm->base + MCHPCOREPWM_PERIOD); |
350 | } |
351 | |
352 | mchp_core_pwm_apply_duty(chip, pwm, state, duty_steps, period_steps); |
353 | |
354 | mchp_core_pwm_enable(chip, pwm, enable: true, period: pwm->state.period); |
355 | |
356 | return 0; |
357 | } |
358 | |
359 | static int mchp_core_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, |
360 | const struct pwm_state *state) |
361 | { |
362 | struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip); |
363 | int ret; |
364 | |
365 | mutex_lock(&mchp_core_pwm->lock); |
366 | |
367 | mchp_core_pwm_wait_for_sync_update(mchp_core_pwm, channel: pwm->hwpwm); |
368 | |
369 | ret = mchp_core_pwm_apply_locked(chip, pwm, state); |
370 | |
371 | mutex_unlock(lock: &mchp_core_pwm->lock); |
372 | |
373 | return ret; |
374 | } |
375 | |
376 | static int mchp_core_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, |
377 | struct pwm_state *state) |
378 | { |
379 | struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip); |
380 | u64 rate; |
381 | u16 prescale, period_steps; |
382 | u8 duty_steps, posedge, negedge; |
383 | |
384 | mutex_lock(&mchp_core_pwm->lock); |
385 | |
386 | mchp_core_pwm_wait_for_sync_update(mchp_core_pwm, channel: pwm->hwpwm); |
387 | |
388 | if (mchp_core_pwm->channel_enabled & (1 << pwm->hwpwm)) |
389 | state->enabled = true; |
390 | else |
391 | state->enabled = false; |
392 | |
393 | rate = clk_get_rate(clk: mchp_core_pwm->clk); |
394 | |
395 | /* |
396 | * Calculating the period: |
397 | * The registers are each 8 bits wide & multiplied to compute the period |
398 | * using the formula: |
399 | * (prescale + 1) * (period_steps + 1) |
400 | * period = ------------------------------------- |
401 | * clk_rate |
402 | * |
403 | * Note: |
404 | * The prescale and period_steps registers operate similarly to |
405 | * CLK_DIVIDER_ONE_BASED, where the value used by the hardware is that |
406 | * in the register plus one. |
407 | */ |
408 | prescale = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_PRESCALE); |
409 | period_steps = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_PERIOD); |
410 | |
411 | state->period = (period_steps + 1) * (prescale + 1); |
412 | state->period *= NSEC_PER_SEC; |
413 | state->period = DIV64_U64_ROUND_UP(state->period, rate); |
414 | |
415 | posedge = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_POSEDGE(pwm->hwpwm)); |
416 | negedge = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_NEGEDGE(pwm->hwpwm)); |
417 | |
418 | mutex_unlock(lock: &mchp_core_pwm->lock); |
419 | |
420 | if (negedge == posedge) { |
421 | state->duty_cycle = state->period; |
422 | state->period *= 2; |
423 | } else { |
424 | duty_steps = abs((s16)posedge - (s16)negedge); |
425 | state->duty_cycle = duty_steps * (prescale + 1) * NSEC_PER_SEC; |
426 | state->duty_cycle = DIV64_U64_ROUND_UP(state->duty_cycle, rate); |
427 | } |
428 | |
429 | state->polarity = negedge < posedge ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; |
430 | |
431 | return 0; |
432 | } |
433 | |
434 | static const struct pwm_ops mchp_core_pwm_ops = { |
435 | .apply = mchp_core_pwm_apply, |
436 | .get_state = mchp_core_pwm_get_state, |
437 | }; |
438 | |
439 | static const struct of_device_id mchp_core_of_match[] = { |
440 | { |
441 | .compatible = "microchip,corepwm-rtl-v4" , |
442 | }, |
443 | { /* sentinel */ } |
444 | }; |
445 | MODULE_DEVICE_TABLE(of, mchp_core_of_match); |
446 | |
447 | static int mchp_core_pwm_probe(struct platform_device *pdev) |
448 | { |
449 | struct pwm_chip *chip; |
450 | struct mchp_core_pwm_chip *mchp_core_pwm; |
451 | struct resource *regs; |
452 | int ret; |
453 | |
454 | chip = devm_pwmchip_alloc(parent: &pdev->dev, npwm: 16, sizeof_priv: sizeof(*mchp_core_pwm)); |
455 | if (IS_ERR(ptr: chip)) |
456 | return PTR_ERR(ptr: chip); |
457 | mchp_core_pwm = to_mchp_core_pwm(chip); |
458 | |
459 | mchp_core_pwm->base = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: ®s); |
460 | if (IS_ERR(ptr: mchp_core_pwm->base)) |
461 | return PTR_ERR(ptr: mchp_core_pwm->base); |
462 | |
463 | mchp_core_pwm->clk = devm_clk_get_enabled(dev: &pdev->dev, NULL); |
464 | if (IS_ERR(ptr: mchp_core_pwm->clk)) |
465 | return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: mchp_core_pwm->clk), |
466 | fmt: "failed to get PWM clock\n" ); |
467 | |
468 | if (of_property_read_u32(np: pdev->dev.of_node, propname: "microchip,sync-update-mask" , |
469 | out_value: &mchp_core_pwm->sync_update_mask)) |
470 | mchp_core_pwm->sync_update_mask = 0; |
471 | |
472 | mutex_init(&mchp_core_pwm->lock); |
473 | |
474 | chip->ops = &mchp_core_pwm_ops; |
475 | |
476 | mchp_core_pwm->channel_enabled = readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_EN(0)); |
477 | mchp_core_pwm->channel_enabled |= |
478 | readb_relaxed(mchp_core_pwm->base + MCHPCOREPWM_EN(1)) << 8; |
479 | |
480 | /* |
481 | * Enable synchronous update mode for all channels for which shadow |
482 | * registers have been synthesised. |
483 | */ |
484 | writel_relaxed(1U, mchp_core_pwm->base + MCHPCOREPWM_SYNC_UPD); |
485 | mchp_core_pwm->update_timestamp = ktime_get(); |
486 | |
487 | ret = devm_pwmchip_add(&pdev->dev, chip); |
488 | if (ret) |
489 | return dev_err_probe(dev: &pdev->dev, err: ret, fmt: "Failed to add pwmchip\n" ); |
490 | |
491 | return 0; |
492 | } |
493 | |
494 | static struct platform_driver mchp_core_pwm_driver = { |
495 | .driver = { |
496 | .name = "mchp-core-pwm" , |
497 | .of_match_table = mchp_core_of_match, |
498 | }, |
499 | .probe = mchp_core_pwm_probe, |
500 | }; |
501 | module_platform_driver(mchp_core_pwm_driver); |
502 | |
503 | MODULE_LICENSE("GPL" ); |
504 | MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>" ); |
505 | MODULE_DESCRIPTION("corePWM driver for Microchip FPGAs" ); |
506 | |