Lines Matching +full:imx27 +full:- +full:pwm
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 */
73 #define MX3_PWMCR_PRESCALER_SET(x) FIELD_PREP(MX3_PWMCR_PRESCALER, (x) - 1)
104 ret = clk_prepare_enable(imx->clk_ipg); in pwm_imx27_clk_prepare_enable()
108 ret = clk_prepare_enable(imx->clk_per); in pwm_imx27_clk_prepare_enable()
110 clk_disable_unprepare(imx->clk_ipg); in pwm_imx27_clk_prepare_enable()
119 clk_disable_unprepare(imx->clk_per); in pwm_imx27_clk_disable_unprepare()
120 clk_disable_unprepare(imx->clk_ipg); in pwm_imx27_clk_disable_unprepare()
124 struct pwm_device *pwm, struct pwm_state *state) in pwm_imx27_get_state() argument
135 val = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_get_state()
138 state->enabled = true; in pwm_imx27_get_state()
140 state->enabled = false; in pwm_imx27_get_state()
144 state->polarity = PWM_POLARITY_NORMAL; in pwm_imx27_get_state()
147 state->polarity = PWM_POLARITY_INVERSED; in pwm_imx27_get_state()
154 pwm_clk = clk_get_rate(imx->clk_per); in pwm_imx27_get_state()
155 val = readl(imx->mmio_base + MX3_PWMPR); in pwm_imx27_get_state()
160 state->period = DIV_ROUND_UP_ULL(tmp, pwm_clk); in pwm_imx27_get_state()
163 * PWMSAR can be read only if PWM is enabled. If the PWM is disabled, in pwm_imx27_get_state()
166 if (state->enabled) in pwm_imx27_get_state()
167 val = readl(imx->mmio_base + MX3_PWMSAR); in pwm_imx27_get_state()
169 val = imx->duty_cycle; in pwm_imx27_get_state()
172 state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk); in pwm_imx27_get_state()
186 writel(MX3_PWMCR_SWR, imx->mmio_base + MX3_PWMCR); in pwm_imx27_sw_reset()
189 cr = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_sw_reset()
198 struct pwm_device *pwm) in pwm_imx27_wait_fifo_slot() argument
206 sr = readl(imx->mmio_base + MX3_PWMSR); in pwm_imx27_wait_fifo_slot()
209 period_ms = DIV_ROUND_UP_ULL(pwm->state.period, in pwm_imx27_wait_fifo_slot()
213 sr = readl(imx->mmio_base + MX3_PWMSR); in pwm_imx27_wait_fifo_slot()
219 static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_imx27_apply() argument
229 clkrate = clk_get_rate(imx->clk_per); in pwm_imx27_apply()
230 c = clkrate * state->period; in pwm_imx27_apply()
238 c = clkrate * state->duty_cycle; in pwm_imx27_apply()
244 * according to imx pwm RM, the real period value should be PERIOD in pwm_imx27_apply()
248 period_cycles -= 2; in pwm_imx27_apply()
253 * Wait for a free FIFO slot if the PWM is already enabled, and flush in pwm_imx27_apply()
254 * the FIFO if the PWM was disabled and is about to be enabled. in pwm_imx27_apply()
256 if (pwm->state.enabled) { in pwm_imx27_apply()
257 pwm_imx27_wait_fifo_slot(chip, pwm); in pwm_imx27_apply()
266 writel(duty_cycles, imx->mmio_base + MX3_PWMSAR); in pwm_imx27_apply()
267 writel(period_cycles, imx->mmio_base + MX3_PWMPR); in pwm_imx27_apply()
271 * MX3_PWMSAR register can't be read (i.e. when the PWM is disabled). in pwm_imx27_apply()
273 imx->duty_cycle = duty_cycles; in pwm_imx27_apply()
280 if (state->polarity == PWM_POLARITY_INVERSED) in pwm_imx27_apply()
284 if (state->enabled) in pwm_imx27_apply()
287 writel(cr, imx->mmio_base + MX3_PWMCR); in pwm_imx27_apply()
289 if (!state->enabled) in pwm_imx27_apply()
301 { .compatible = "fsl,imx27-pwm", },
313 chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*imx)); in pwm_imx27_probe()
318 imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); in pwm_imx27_probe()
319 if (IS_ERR(imx->clk_ipg)) in pwm_imx27_probe()
320 return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_ipg), in pwm_imx27_probe()
323 imx->clk_per = devm_clk_get(&pdev->dev, "per"); in pwm_imx27_probe()
324 if (IS_ERR(imx->clk_per)) in pwm_imx27_probe()
325 return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per), in pwm_imx27_probe()
328 chip->ops = &pwm_imx27_ops; in pwm_imx27_probe()
330 imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); in pwm_imx27_probe()
331 if (IS_ERR(imx->mmio_base)) in pwm_imx27_probe()
332 return PTR_ERR(imx->mmio_base); in pwm_imx27_probe()
338 /* keep clks on if pwm is running */ in pwm_imx27_probe()
339 pwmcr = readl(imx->mmio_base + MX3_PWMCR); in pwm_imx27_probe()
343 return devm_pwmchip_add(&pdev->dev, chip); in pwm_imx27_probe()
348 .name = "pwm-imx27",