1 // SPDX-License-Identifier: GPL-2.0
3 * simple driver for PWM (Pulse Width Modulator) controller
5 * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
8 * - When disabled the output is driven to 0 independent of the configured
12 #include <linux/bitfield.h>
13 #include <linux/bitops.h>
14 #include <linux/clk.h>
15 #include <linux/delay.h>
16 #include <linux/err.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
21 #include <linux/of_device.h>
22 #include <linux/platform_device.h>
23 #include <linux/pwm.h>
24 #include <linux/slab.h>
26 #define MX3_PWMCR 0x00 /* PWM Control Register */
27 #define MX3_PWMSR 0x04 /* PWM Status Register */
28 #define MX3_PWMSAR 0x0C /* PWM Sample Register */
29 #define MX3_PWMPR 0x10 /* PWM Period Register */
31 #define MX3_PWMCR_FWM GENMASK(27, 26)
32 #define MX3_PWMCR_STOPEN BIT(25)
33 #define MX3_PWMCR_DOZEN BIT(24)
34 #define MX3_PWMCR_WAITEN BIT(23)
35 #define MX3_PWMCR_DBGEN BIT(22)
36 #define MX3_PWMCR_BCTR BIT(21)
37 #define MX3_PWMCR_HCTR BIT(20)
39 #define MX3_PWMCR_POUTC GENMASK(19, 18)
40 #define MX3_PWMCR_POUTC_NORMAL 0
41 #define MX3_PWMCR_POUTC_INVERTED 1
42 #define MX3_PWMCR_POUTC_OFF 2
44 #define MX3_PWMCR_CLKSRC GENMASK(17, 16)
45 #define MX3_PWMCR_CLKSRC_OFF 0
46 #define MX3_PWMCR_CLKSRC_IPG 1
47 #define MX3_PWMCR_CLKSRC_IPG_HIGH 2
48 #define MX3_PWMCR_CLKSRC_IPG_32K 3
50 #define MX3_PWMCR_PRESCALER GENMASK(15, 4)
52 #define MX3_PWMCR_SWR BIT(3)
54 #define MX3_PWMCR_REPEAT GENMASK(2, 1)
55 #define MX3_PWMCR_REPEAT_1X 0
56 #define MX3_PWMCR_REPEAT_2X 1
57 #define MX3_PWMCR_REPEAT_4X 2
58 #define MX3_PWMCR_REPEAT_8X 3
60 #define MX3_PWMCR_EN BIT(0)
62 #define MX3_PWMSR_FWE BIT(6)
63 #define MX3_PWMSR_CMP BIT(5)
64 #define MX3_PWMSR_ROV BIT(4)
65 #define MX3_PWMSR_FE BIT(3)
67 #define MX3_PWMSR_FIFOAV GENMASK(2, 0)
68 #define MX3_PWMSR_FIFOAV_EMPTY 0
69 #define MX3_PWMSR_FIFOAV_1WORD 1
70 #define MX3_PWMSR_FIFOAV_2WORDS 2
71 #define MX3_PWMSR_FIFOAV_3WORDS 3
72 #define MX3_PWMSR_FIFOAV_4WORDS 4
74 #define MX3_PWMCR_PRESCALER_SET(x) FIELD_PREP(MX3_PWMCR_PRESCALER, (x) - 1)
75 #define MX3_PWMCR_PRESCALER_GET(x) (FIELD_GET(MX3_PWMCR_PRESCALER, \
78 #define MX3_PWM_SWR_LOOP 5
80 /* PWMPR register value of 0xffff has the same effect as 0xfffe */
81 #define MX3_PWMPR_MAX 0xfffe
83 struct pwm_imx27_chip
{
86 void __iomem
*mmio_base
;
90 #define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip)
92 static int pwm_imx27_clk_prepare_enable(struct pwm_chip
*chip
)
94 struct pwm_imx27_chip
*imx
= to_pwm_imx27_chip(chip
);
97 ret
= clk_prepare_enable(imx
->clk_ipg
);
101 ret
= clk_prepare_enable(imx
->clk_per
);
103 clk_disable_unprepare(imx
->clk_ipg
);
110 static void pwm_imx27_clk_disable_unprepare(struct pwm_chip
*chip
)
112 struct pwm_imx27_chip
*imx
= to_pwm_imx27_chip(chip
);
114 clk_disable_unprepare(imx
->clk_per
);
115 clk_disable_unprepare(imx
->clk_ipg
);
118 static void pwm_imx27_get_state(struct pwm_chip
*chip
,
119 struct pwm_device
*pwm
, struct pwm_state
*state
)
121 struct pwm_imx27_chip
*imx
= to_pwm_imx27_chip(chip
);
122 u32 period
, prescaler
, pwm_clk
, val
;
126 ret
= pwm_imx27_clk_prepare_enable(chip
);
130 val
= readl(imx
->mmio_base
+ MX3_PWMCR
);
132 if (val
& MX3_PWMCR_EN
)
133 state
->enabled
= true;
135 state
->enabled
= false;
137 switch (FIELD_GET(MX3_PWMCR_POUTC
, val
)) {
138 case MX3_PWMCR_POUTC_NORMAL
:
139 state
->polarity
= PWM_POLARITY_NORMAL
;
141 case MX3_PWMCR_POUTC_INVERTED
:
142 state
->polarity
= PWM_POLARITY_INVERSED
;
145 dev_warn(chip
->dev
, "can't set polarity, output disconnected");
148 prescaler
= MX3_PWMCR_PRESCALER_GET(val
);
149 pwm_clk
= clk_get_rate(imx
->clk_per
);
150 pwm_clk
= DIV_ROUND_CLOSEST_ULL(pwm_clk
, prescaler
);
151 val
= readl(imx
->mmio_base
+ MX3_PWMPR
);
152 period
= val
>= MX3_PWMPR_MAX
? MX3_PWMPR_MAX
: val
;
154 /* PWMOUT (Hz) = PWMCLK / (PWMPR + 2) */
155 tmp
= NSEC_PER_SEC
* (u64
)(period
+ 2);
156 state
->period
= DIV_ROUND_CLOSEST_ULL(tmp
, pwm_clk
);
158 /* PWMSAR can be read only if PWM is enabled */
159 if (state
->enabled
) {
160 val
= readl(imx
->mmio_base
+ MX3_PWMSAR
);
161 tmp
= NSEC_PER_SEC
* (u64
)(val
);
162 state
->duty_cycle
= DIV_ROUND_CLOSEST_ULL(tmp
, pwm_clk
);
164 state
->duty_cycle
= 0;
168 pwm_imx27_clk_disable_unprepare(chip
);
171 static void pwm_imx27_sw_reset(struct pwm_chip
*chip
)
173 struct pwm_imx27_chip
*imx
= to_pwm_imx27_chip(chip
);
174 struct device
*dev
= chip
->dev
;
178 writel(MX3_PWMCR_SWR
, imx
->mmio_base
+ MX3_PWMCR
);
180 usleep_range(200, 1000);
181 cr
= readl(imx
->mmio_base
+ MX3_PWMCR
);
182 } while ((cr
& MX3_PWMCR_SWR
) &&
183 (wait_count
++ < MX3_PWM_SWR_LOOP
));
185 if (cr
& MX3_PWMCR_SWR
)
186 dev_warn(dev
, "software reset timeout\n");
189 static void pwm_imx27_wait_fifo_slot(struct pwm_chip
*chip
,
190 struct pwm_device
*pwm
)
192 struct pwm_imx27_chip
*imx
= to_pwm_imx27_chip(chip
);
193 struct device
*dev
= chip
->dev
;
194 unsigned int period_ms
;
198 sr
= readl(imx
->mmio_base
+ MX3_PWMSR
);
199 fifoav
= FIELD_GET(MX3_PWMSR_FIFOAV
, sr
);
200 if (fifoav
== MX3_PWMSR_FIFOAV_4WORDS
) {
201 period_ms
= DIV_ROUND_UP(pwm_get_period(pwm
),
205 sr
= readl(imx
->mmio_base
+ MX3_PWMSR
);
206 if (fifoav
== FIELD_GET(MX3_PWMSR_FIFOAV
, sr
))
207 dev_warn(dev
, "there is no free FIFO slot\n");
211 static int pwm_imx27_apply(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
212 const struct pwm_state
*state
)
214 unsigned long period_cycles
, duty_cycles
, prescale
;
215 struct pwm_imx27_chip
*imx
= to_pwm_imx27_chip(chip
);
216 struct pwm_state cstate
;
217 unsigned long long c
;
221 pwm_get_state(pwm
, &cstate
);
223 if (state
->enabled
) {
224 c
= clk_get_rate(imx
->clk_per
);
227 do_div(c
, 1000000000);
230 prescale
= period_cycles
/ 0x10000 + 1;
232 period_cycles
/= prescale
;
233 c
= (unsigned long long)period_cycles
* state
->duty_cycle
;
234 do_div(c
, state
->period
);
238 * according to imx pwm RM, the real period value should be
239 * PERIOD value in PWMPR plus 2.
241 if (period_cycles
> 2)
247 * Wait for a free FIFO slot if the PWM is already enabled, and
248 * flush the FIFO if the PWM was disabled and is about to be
251 if (cstate
.enabled
) {
252 pwm_imx27_wait_fifo_slot(chip
, pwm
);
254 ret
= pwm_imx27_clk_prepare_enable(chip
);
258 pwm_imx27_sw_reset(chip
);
261 writel(duty_cycles
, imx
->mmio_base
+ MX3_PWMSAR
);
262 writel(period_cycles
, imx
->mmio_base
+ MX3_PWMPR
);
264 cr
= MX3_PWMCR_PRESCALER_SET(prescale
) |
265 MX3_PWMCR_STOPEN
| MX3_PWMCR_DOZEN
| MX3_PWMCR_WAITEN
|
266 FIELD_PREP(MX3_PWMCR_CLKSRC
, MX3_PWMCR_CLKSRC_IPG_HIGH
) |
267 MX3_PWMCR_DBGEN
| MX3_PWMCR_EN
;
269 if (state
->polarity
== PWM_POLARITY_INVERSED
)
270 cr
|= FIELD_PREP(MX3_PWMCR_POUTC
,
271 MX3_PWMCR_POUTC_INVERTED
);
273 writel(cr
, imx
->mmio_base
+ MX3_PWMCR
);
274 } else if (cstate
.enabled
) {
275 writel(0, imx
->mmio_base
+ MX3_PWMCR
);
277 pwm_imx27_clk_disable_unprepare(chip
);
283 static const struct pwm_ops pwm_imx27_ops
= {
284 .apply
= pwm_imx27_apply
,
285 .get_state
= pwm_imx27_get_state
,
286 .owner
= THIS_MODULE
,
289 static const struct of_device_id pwm_imx27_dt_ids
[] = {
290 { .compatible
= "fsl,imx27-pwm", },
293 MODULE_DEVICE_TABLE(of
, pwm_imx27_dt_ids
);
295 static int pwm_imx27_probe(struct platform_device
*pdev
)
297 struct pwm_imx27_chip
*imx
;
299 imx
= devm_kzalloc(&pdev
->dev
, sizeof(*imx
), GFP_KERNEL
);
303 platform_set_drvdata(pdev
, imx
);
305 imx
->clk_ipg
= devm_clk_get(&pdev
->dev
, "ipg");
306 if (IS_ERR(imx
->clk_ipg
)) {
307 dev_err(&pdev
->dev
, "getting ipg clock failed with %ld\n",
308 PTR_ERR(imx
->clk_ipg
));
309 return PTR_ERR(imx
->clk_ipg
);
312 imx
->clk_per
= devm_clk_get(&pdev
->dev
, "per");
313 if (IS_ERR(imx
->clk_per
)) {
314 int ret
= PTR_ERR(imx
->clk_per
);
316 if (ret
!= -EPROBE_DEFER
)
318 "failed to get peripheral clock: %d\n",
324 imx
->chip
.ops
= &pwm_imx27_ops
;
325 imx
->chip
.dev
= &pdev
->dev
;
329 imx
->chip
.of_xlate
= of_pwm_xlate_with_flags
;
330 imx
->chip
.of_pwm_n_cells
= 3;
332 imx
->mmio_base
= devm_platform_ioremap_resource(pdev
, 0);
333 if (IS_ERR(imx
->mmio_base
))
334 return PTR_ERR(imx
->mmio_base
);
336 return pwmchip_add(&imx
->chip
);
339 static int pwm_imx27_remove(struct platform_device
*pdev
)
341 struct pwm_imx27_chip
*imx
;
343 imx
= platform_get_drvdata(pdev
);
345 pwm_imx27_clk_disable_unprepare(&imx
->chip
);
347 return pwmchip_remove(&imx
->chip
);
350 static struct platform_driver imx_pwm_driver
= {
353 .of_match_table
= pwm_imx27_dt_ids
,
355 .probe
= pwm_imx27_probe
,
356 .remove
= pwm_imx27_remove
,
358 module_platform_driver(imx_pwm_driver
);
360 MODULE_LICENSE("GPL v2");
361 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");