Lines Matching +full:pwm +full:- +full:period

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
22 #include <linux/pwm.h>
25 #define MX3_PWMCR 0x00 /* PWM Control Register */
26 #define MX3_PWMSR 0x04 /* PWM Status Register */
27 #define MX3_PWMSAR 0x0C /* PWM Sample Register */
28 #define MX3_PWMPR 0x10 /* PWM Period Register */
29 #define MX3_PWMCNR 0x14 /* PWM Counter Register */
74 #define MX3_PWMCR_PRESCALER_SET(x) FIELD_PREP(MX3_PWMCR_PRESCALER, (x) - 1)
103 ret = clk_prepare_enable(imx->clk_ipg); in pwm_imx27_clk_prepare_enable()
107 ret = clk_prepare_enable(imx->clk_per); in pwm_imx27_clk_prepare_enable()
109 clk_disable_unprepare(imx->clk_ipg); in pwm_imx27_clk_prepare_enable()
118 clk_disable_unprepare(imx->clk_per); in pwm_imx27_clk_disable_unprepare()
119 clk_disable_unprepare(imx->clk_ipg); in pwm_imx27_clk_disable_unprepare()
123 struct pwm_device *pwm, struct pwm_state *state) in pwm_imx27_get_state() argument
126 u32 period, prescaler, pwm_clk, val; in pwm_imx27_get_state() local
134 val = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_get_state()
137 state->enabled = true; in pwm_imx27_get_state()
139 state->enabled = false; in pwm_imx27_get_state()
143 state->polarity = PWM_POLARITY_NORMAL; in pwm_imx27_get_state()
146 state->polarity = PWM_POLARITY_INVERSED; in pwm_imx27_get_state()
149 dev_warn(chip->dev, "can't set polarity, output disconnected"); in pwm_imx27_get_state()
153 pwm_clk = clk_get_rate(imx->clk_per); in pwm_imx27_get_state()
154 val = readl(imx->mmio_base + MX3_PWMPR); in pwm_imx27_get_state()
155 period = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val; in pwm_imx27_get_state()
158 tmp = NSEC_PER_SEC * (u64)(period + 2) * prescaler; in pwm_imx27_get_state()
159 state->period = DIV_ROUND_UP_ULL(tmp, pwm_clk); in pwm_imx27_get_state()
162 * PWMSAR can be read only if PWM is enabled. If the PWM is disabled, in pwm_imx27_get_state()
165 if (state->enabled) in pwm_imx27_get_state()
166 val = readl(imx->mmio_base + MX3_PWMSAR); in pwm_imx27_get_state()
168 val = imx->duty_cycle; in pwm_imx27_get_state()
171 state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk); in pwm_imx27_get_state()
181 struct device *dev = chip->dev; in pwm_imx27_sw_reset()
185 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR); in pwm_imx27_sw_reset()
188 cr = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_sw_reset()
197 struct pwm_device *pwm) in pwm_imx27_wait_fifo_slot() argument
200 struct device *dev = chip->dev; in pwm_imx27_wait_fifo_slot()
205 sr = readl(imx->mmio_base + MX3_PWMSR); in pwm_imx27_wait_fifo_slot()
208 period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm), in pwm_imx27_wait_fifo_slot()
212 sr = readl(imx->mmio_base + MX3_PWMSR); in pwm_imx27_wait_fifo_slot()
218 static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_imx27_apply() argument
231 pwm_get_state(pwm, &cstate); in pwm_imx27_apply()
233 clkrate = clk_get_rate(imx->clk_per); in pwm_imx27_apply()
234 c = clkrate * state->period; in pwm_imx27_apply()
242 c = clkrate * state->duty_cycle; in pwm_imx27_apply()
248 * according to imx pwm RM, the real period value should be PERIOD in pwm_imx27_apply()
252 period_cycles -= 2; in pwm_imx27_apply()
257 * Wait for a free FIFO slot if the PWM is already enabled, and flush in pwm_imx27_apply()
258 * the FIFO if the PWM was disabled and is about to be enabled. in pwm_imx27_apply()
261 pwm_imx27_wait_fifo_slot(chip, pwm); in pwm_imx27_apply()
270 val = readl(imx->mmio_base + MX3_PWMPR); in pwm_imx27_apply()
272 cr = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_apply()
279 * PWM: PWM output may not function correctly if the FIFO is empty when in pwm_imx27_apply()
283 * When the PWM FIFO is empty, a new value programmed to the PWM Sample in pwm_imx27_apply()
285 * timer period has not expired. in pwm_imx27_apply()
288 * less than the previous value, and the PWM counter register in pwm_imx27_apply()
290 * the new programmed SAMPLE value, the current period will not flip in pwm_imx27_apply()
303 * to SAR even the current period is not over if FIFO is empty. in pwm_imx27_apply()
308 * |<-- old SAR -->| |<-- new SAR -->| in pwm_imx27_apply()
310 * That is the output is active for a whole period. in pwm_imx27_apply()
315 * next period. in pwm_imx27_apply()
317 * Sometime period is quite long, such as over 1 second. If add old SAR in pwm_imx27_apply()
318 * into FIFO unconditional, new SAR have to wait for next period. It in pwm_imx27_apply()
323 * in PWM will be out of data and take wrong action. in pwm_imx27_apply()
329 * the SAR register to increase the fastest PWM frequency supported. in pwm_imx27_apply()
331 * When the PWM period is longer than 2us(or <500kHz), this workaround in pwm_imx27_apply()
332 * can solve this problem. No software workaround is available if PWM in pwm_imx27_apply()
333 * period is shorter than IO write. Just try best to fill old data in pwm_imx27_apply()
340 val = FIELD_GET(MX3_PWMSR_FIFOAV, readl_relaxed(imx->mmio_base + MX3_PWMSR)); in pwm_imx27_apply()
342 if (duty_cycles < imx->duty_cycle && (cr & MX3_PWMCR_EN)) { in pwm_imx27_apply()
346 writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR); in pwm_imx27_apply()
347 writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR); in pwm_imx27_apply()
349 val = readl_relaxed(imx->mmio_base + MX3_PWMCNR); in pwm_imx27_apply()
351 * If counter is close to period, controller may roll over when in pwm_imx27_apply()
354 if ((val + c >= duty_cycles && val < imx->duty_cycle) || in pwm_imx27_apply()
356 writel_relaxed(imx->duty_cycle, imx->mmio_base + MX3_PWMSAR); in pwm_imx27_apply()
359 writel_relaxed(duty_cycles, imx->mmio_base + MX3_PWMSAR); in pwm_imx27_apply()
362 writel(period_cycles, imx->mmio_base + MX3_PWMPR); in pwm_imx27_apply()
366 * MX3_PWMSAR register can't be read (i.e. when the PWM is disabled). in pwm_imx27_apply()
368 imx->duty_cycle = duty_cycles; in pwm_imx27_apply()
375 if (state->polarity == PWM_POLARITY_INVERSED) in pwm_imx27_apply()
379 if (state->enabled) in pwm_imx27_apply()
382 writel(cr, imx->mmio_base + MX3_PWMCR); in pwm_imx27_apply()
384 if (!state->enabled) in pwm_imx27_apply()
397 { .compatible = "fsl,imx27-pwm", },
408 imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); in pwm_imx27_probe()
410 return -ENOMEM; in pwm_imx27_probe()
412 imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); in pwm_imx27_probe()
413 if (IS_ERR(imx->clk_ipg)) in pwm_imx27_probe()
414 return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_ipg), in pwm_imx27_probe()
417 imx->clk_per = devm_clk_get(&pdev->dev, "per"); in pwm_imx27_probe()
418 if (IS_ERR(imx->clk_per)) in pwm_imx27_probe()
419 return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per), in pwm_imx27_probe()
422 imx->chip.ops = &pwm_imx27_ops; in pwm_imx27_probe()
423 imx->chip.dev = &pdev->dev; in pwm_imx27_probe()
424 imx->chip.npwm = 1; in pwm_imx27_probe()
426 imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); in pwm_imx27_probe()
427 if (IS_ERR(imx->mmio_base)) in pwm_imx27_probe()
428 return PTR_ERR(imx->mmio_base); in pwm_imx27_probe()
434 /* keep clks on if pwm is running */ in pwm_imx27_probe()
435 pwmcr = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_probe()
439 return devm_pwmchip_add(&pdev->dev, &imx->chip); in pwm_imx27_probe()
444 .name = "pwm-imx27",