xref: /openbmc/linux/drivers/pwm/pwm-sun4i.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1f50a7f3dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
209853ce7SAlexandre Belloni /*
309853ce7SAlexandre Belloni  * Driver for Allwinner sun4i Pulse Width Modulation Controller
409853ce7SAlexandre Belloni  *
509853ce7SAlexandre Belloni  * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
69f28e95bSJernej Skrabec  *
79f28e95bSJernej Skrabec  * Limitations:
89f28e95bSJernej Skrabec  * - When outputing the source clock directly, the PWM logic will be bypassed
99f28e95bSJernej Skrabec  *   and the currently running period is not guaranteed to be completed
1009853ce7SAlexandre Belloni  */
1109853ce7SAlexandre Belloni 
1209853ce7SAlexandre Belloni #include <linux/bitops.h>
1309853ce7SAlexandre Belloni #include <linux/clk.h>
14c32c5c50SAlexandre Belloni #include <linux/delay.h>
1509853ce7SAlexandre Belloni #include <linux/err.h>
1609853ce7SAlexandre Belloni #include <linux/io.h>
17c32c5c50SAlexandre Belloni #include <linux/jiffies.h>
1809853ce7SAlexandre Belloni #include <linux/module.h>
1909853ce7SAlexandre Belloni #include <linux/of.h>
2009853ce7SAlexandre Belloni #include <linux/platform_device.h>
2109853ce7SAlexandre Belloni #include <linux/pwm.h>
22a7fe9856SJernej Skrabec #include <linux/reset.h>
2309853ce7SAlexandre Belloni #include <linux/slab.h>
2409853ce7SAlexandre Belloni #include <linux/spinlock.h>
2509853ce7SAlexandre Belloni #include <linux/time.h>
2609853ce7SAlexandre Belloni 
2709853ce7SAlexandre Belloni #define PWM_CTRL_REG		0x0
2809853ce7SAlexandre Belloni 
2909853ce7SAlexandre Belloni #define PWM_CH_PRD_BASE		0x4
3009853ce7SAlexandre Belloni #define PWM_CH_PRD_OFFSET	0x4
3109853ce7SAlexandre Belloni #define PWM_CH_PRD(ch)		(PWM_CH_PRD_BASE + PWM_CH_PRD_OFFSET * (ch))
3209853ce7SAlexandre Belloni 
3309853ce7SAlexandre Belloni #define PWMCH_OFFSET		15
3409853ce7SAlexandre Belloni #define PWM_PRESCAL_MASK	GENMASK(3, 0)
3509853ce7SAlexandre Belloni #define PWM_PRESCAL_OFF		0
3609853ce7SAlexandre Belloni #define PWM_EN			BIT(4)
3709853ce7SAlexandre Belloni #define PWM_ACT_STATE		BIT(5)
3809853ce7SAlexandre Belloni #define PWM_CLK_GATING		BIT(6)
3909853ce7SAlexandre Belloni #define PWM_MODE		BIT(7)
4009853ce7SAlexandre Belloni #define PWM_PULSE		BIT(8)
4109853ce7SAlexandre Belloni #define PWM_BYPASS		BIT(9)
4209853ce7SAlexandre Belloni 
4309853ce7SAlexandre Belloni #define PWM_RDY_BASE		28
4409853ce7SAlexandre Belloni #define PWM_RDY_OFFSET		1
4509853ce7SAlexandre Belloni #define PWM_RDY(ch)		BIT(PWM_RDY_BASE + PWM_RDY_OFFSET * (ch))
4609853ce7SAlexandre Belloni 
4709853ce7SAlexandre Belloni #define PWM_PRD(prd)		(((prd) - 1) << 16)
4809853ce7SAlexandre Belloni #define PWM_PRD_MASK		GENMASK(15, 0)
4909853ce7SAlexandre Belloni 
5009853ce7SAlexandre Belloni #define PWM_DTY_MASK		GENMASK(15, 0)
5109853ce7SAlexandre Belloni 
5293e0dfb2SAlexandre Belloni #define PWM_REG_PRD(reg)	((((reg) >> 16) & PWM_PRD_MASK) + 1)
5393e0dfb2SAlexandre Belloni #define PWM_REG_DTY(reg)	((reg) & PWM_DTY_MASK)
5493e0dfb2SAlexandre Belloni #define PWM_REG_PRESCAL(reg, chan)	(((reg) >> ((chan) * PWMCH_OFFSET)) & PWM_PRESCAL_MASK)
5593e0dfb2SAlexandre Belloni 
5609853ce7SAlexandre Belloni #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
5709853ce7SAlexandre Belloni 
5809853ce7SAlexandre Belloni static const u32 prescaler_table[] = {
5909853ce7SAlexandre Belloni 	120,
6009853ce7SAlexandre Belloni 	180,
6109853ce7SAlexandre Belloni 	240,
6209853ce7SAlexandre Belloni 	360,
6309853ce7SAlexandre Belloni 	480,
6409853ce7SAlexandre Belloni 	0,
6509853ce7SAlexandre Belloni 	0,
6609853ce7SAlexandre Belloni 	0,
6709853ce7SAlexandre Belloni 	12000,
6809853ce7SAlexandre Belloni 	24000,
6909853ce7SAlexandre Belloni 	36000,
7009853ce7SAlexandre Belloni 	48000,
7109853ce7SAlexandre Belloni 	72000,
7209853ce7SAlexandre Belloni 	0,
7309853ce7SAlexandre Belloni 	0,
7409853ce7SAlexandre Belloni 	0, /* Actually 1 but tested separately */
7509853ce7SAlexandre Belloni };
7609853ce7SAlexandre Belloni 
7709853ce7SAlexandre Belloni struct sun4i_pwm_data {
7809853ce7SAlexandre Belloni 	bool has_prescaler_bypass;
799f28e95bSJernej Skrabec 	bool has_direct_mod_clk_output;
80f6649f7aSHans de Goede 	unsigned int npwm;
8109853ce7SAlexandre Belloni };
8209853ce7SAlexandre Belloni 
8309853ce7SAlexandre Belloni struct sun4i_pwm_chip {
8409853ce7SAlexandre Belloni 	struct pwm_chip chip;
855b090b43SJernej Skrabec 	struct clk *bus_clk;
8609853ce7SAlexandre Belloni 	struct clk *clk;
87a7fe9856SJernej Skrabec 	struct reset_control *rst;
8809853ce7SAlexandre Belloni 	void __iomem *base;
8909853ce7SAlexandre Belloni 	spinlock_t ctrl_lock;
9009853ce7SAlexandre Belloni 	const struct sun4i_pwm_data *data;
9109853ce7SAlexandre Belloni };
9209853ce7SAlexandre Belloni 
to_sun4i_pwm_chip(struct pwm_chip * chip)9309853ce7SAlexandre Belloni static inline struct sun4i_pwm_chip *to_sun4i_pwm_chip(struct pwm_chip *chip)
9409853ce7SAlexandre Belloni {
9509853ce7SAlexandre Belloni 	return container_of(chip, struct sun4i_pwm_chip, chip);
9609853ce7SAlexandre Belloni }
9709853ce7SAlexandre Belloni 
sun4i_pwm_readl(struct sun4i_pwm_chip * chip,unsigned long offset)9809853ce7SAlexandre Belloni static inline u32 sun4i_pwm_readl(struct sun4i_pwm_chip *chip,
9909853ce7SAlexandre Belloni 				  unsigned long offset)
10009853ce7SAlexandre Belloni {
10109853ce7SAlexandre Belloni 	return readl(chip->base + offset);
10209853ce7SAlexandre Belloni }
10309853ce7SAlexandre Belloni 
sun4i_pwm_writel(struct sun4i_pwm_chip * chip,u32 val,unsigned long offset)10409853ce7SAlexandre Belloni static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
10509853ce7SAlexandre Belloni 				    u32 val, unsigned long offset)
10609853ce7SAlexandre Belloni {
10709853ce7SAlexandre Belloni 	writel(val, chip->base + offset);
10809853ce7SAlexandre Belloni }
10909853ce7SAlexandre Belloni 
sun4i_pwm_get_state(struct pwm_chip * chip,struct pwm_device * pwm,struct pwm_state * state)1106c452cffSUwe Kleine-König static int sun4i_pwm_get_state(struct pwm_chip *chip,
11193e0dfb2SAlexandre Belloni 			       struct pwm_device *pwm,
11293e0dfb2SAlexandre Belloni 			       struct pwm_state *state)
11393e0dfb2SAlexandre Belloni {
11493e0dfb2SAlexandre Belloni 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
11593e0dfb2SAlexandre Belloni 	u64 clk_rate, tmp;
11693e0dfb2SAlexandre Belloni 	u32 val;
11793e0dfb2SAlexandre Belloni 	unsigned int prescaler;
11893e0dfb2SAlexandre Belloni 
11993e0dfb2SAlexandre Belloni 	clk_rate = clk_get_rate(sun4i_pwm->clk);
120a08b318aSAndre Przywara 	if (!clk_rate)
121a08b318aSAndre Przywara 		return -EINVAL;
12293e0dfb2SAlexandre Belloni 
12393e0dfb2SAlexandre Belloni 	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
12493e0dfb2SAlexandre Belloni 
1259f28e95bSJernej Skrabec 	/*
1269f28e95bSJernej Skrabec 	 * PWM chapter in H6 manual has a diagram which explains that if bypass
1279f28e95bSJernej Skrabec 	 * bit is set, no other setting has any meaning. Even more, experiment
1289f28e95bSJernej Skrabec 	 * proved that also enable bit is ignored in this case.
1299f28e95bSJernej Skrabec 	 */
1309f28e95bSJernej Skrabec 	if ((val & BIT_CH(PWM_BYPASS, pwm->hwpwm)) &&
1319f28e95bSJernej Skrabec 	    sun4i_pwm->data->has_direct_mod_clk_output) {
1329f28e95bSJernej Skrabec 		state->period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, clk_rate);
1339f28e95bSJernej Skrabec 		state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2);
1349f28e95bSJernej Skrabec 		state->polarity = PWM_POLARITY_NORMAL;
1359f28e95bSJernej Skrabec 		state->enabled = true;
1366c452cffSUwe Kleine-König 		return 0;
1379f28e95bSJernej Skrabec 	}
1389f28e95bSJernej Skrabec 
139989ae7a5SAlexandre Belloni 	if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) &&
140989ae7a5SAlexandre Belloni 	    sun4i_pwm->data->has_prescaler_bypass)
14193e0dfb2SAlexandre Belloni 		prescaler = 1;
14293e0dfb2SAlexandre Belloni 	else
14393e0dfb2SAlexandre Belloni 		prescaler = prescaler_table[PWM_REG_PRESCAL(val, pwm->hwpwm)];
14493e0dfb2SAlexandre Belloni 
14593e0dfb2SAlexandre Belloni 	if (prescaler == 0)
146a08b318aSAndre Przywara 		return -EINVAL;
14793e0dfb2SAlexandre Belloni 
14893e0dfb2SAlexandre Belloni 	if (val & BIT_CH(PWM_ACT_STATE, pwm->hwpwm))
14993e0dfb2SAlexandre Belloni 		state->polarity = PWM_POLARITY_NORMAL;
15093e0dfb2SAlexandre Belloni 	else
15193e0dfb2SAlexandre Belloni 		state->polarity = PWM_POLARITY_INVERSED;
15293e0dfb2SAlexandre Belloni 
153989ae7a5SAlexandre Belloni 	if ((val & BIT_CH(PWM_CLK_GATING | PWM_EN, pwm->hwpwm)) ==
154989ae7a5SAlexandre Belloni 	    BIT_CH(PWM_CLK_GATING | PWM_EN, pwm->hwpwm))
15593e0dfb2SAlexandre Belloni 		state->enabled = true;
15693e0dfb2SAlexandre Belloni 	else
15793e0dfb2SAlexandre Belloni 		state->enabled = false;
15893e0dfb2SAlexandre Belloni 
15993e0dfb2SAlexandre Belloni 	val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm));
16093e0dfb2SAlexandre Belloni 
16150cc7e3eSOndrej Jirman 	tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_DTY(val);
16293e0dfb2SAlexandre Belloni 	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
16393e0dfb2SAlexandre Belloni 
16450cc7e3eSOndrej Jirman 	tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_PRD(val);
16593e0dfb2SAlexandre Belloni 	state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
1666c452cffSUwe Kleine-König 
1676c452cffSUwe Kleine-König 	return 0;
16893e0dfb2SAlexandre Belloni }
16993e0dfb2SAlexandre Belloni 
sun4i_pwm_calculate(struct sun4i_pwm_chip * sun4i_pwm,const struct pwm_state * state,u32 * dty,u32 * prd,unsigned int * prsclr,bool * bypass)170c32c5c50SAlexandre Belloni static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
17171523d18SUwe Kleine-König 			       const struct pwm_state *state,
1729f28e95bSJernej Skrabec 			       u32 *dty, u32 *prd, unsigned int *prsclr,
1739f28e95bSJernej Skrabec 			       bool *bypass)
174c32c5c50SAlexandre Belloni {
175c32c5c50SAlexandre Belloni 	u64 clk_rate, div = 0;
176f6003f94SUwe Kleine-König 	unsigned int prescaler = 0;
177c32c5c50SAlexandre Belloni 
178c32c5c50SAlexandre Belloni 	clk_rate = clk_get_rate(sun4i_pwm->clk);
179c32c5c50SAlexandre Belloni 
1809f28e95bSJernej Skrabec 	*bypass = sun4i_pwm->data->has_direct_mod_clk_output &&
1819f28e95bSJernej Skrabec 		  state->enabled &&
1829f28e95bSJernej Skrabec 		  (state->period * clk_rate >= NSEC_PER_SEC) &&
1839f28e95bSJernej Skrabec 		  (state->period * clk_rate < 2 * NSEC_PER_SEC) &&
1849f28e95bSJernej Skrabec 		  (state->duty_cycle * clk_rate * 2 >= NSEC_PER_SEC);
1859f28e95bSJernej Skrabec 
1869f28e95bSJernej Skrabec 	/* Skip calculation of other parameters if we bypass them */
1879f28e95bSJernej Skrabec 	if (*bypass)
1889f28e95bSJernej Skrabec 		return 0;
1899f28e95bSJernej Skrabec 
190c32c5c50SAlexandre Belloni 	if (sun4i_pwm->data->has_prescaler_bypass) {
191c32c5c50SAlexandre Belloni 		/* First, test without any prescaler when available */
192c32c5c50SAlexandre Belloni 		prescaler = PWM_PRESCAL_MASK;
193c32c5c50SAlexandre Belloni 		/*
194c32c5c50SAlexandre Belloni 		 * When not using any prescaler, the clock period in nanoseconds
195c32c5c50SAlexandre Belloni 		 * is not an integer so round it half up instead of
196c32c5c50SAlexandre Belloni 		 * truncating to get less surprising values.
197c32c5c50SAlexandre Belloni 		 */
198c32c5c50SAlexandre Belloni 		div = clk_rate * state->period + NSEC_PER_SEC / 2;
199c32c5c50SAlexandre Belloni 		do_div(div, NSEC_PER_SEC);
200c32c5c50SAlexandre Belloni 		if (div - 1 > PWM_PRD_MASK)
201c32c5c50SAlexandre Belloni 			prescaler = 0;
202c32c5c50SAlexandre Belloni 	}
203c32c5c50SAlexandre Belloni 
204c32c5c50SAlexandre Belloni 	if (prescaler == 0) {
205c32c5c50SAlexandre Belloni 		/* Go up from the first divider */
206c32c5c50SAlexandre Belloni 		for (prescaler = 0; prescaler < PWM_PRESCAL_MASK; prescaler++) {
207f6003f94SUwe Kleine-König 			unsigned int pval = prescaler_table[prescaler];
208f6003f94SUwe Kleine-König 
209f6003f94SUwe Kleine-König 			if (!pval)
210c32c5c50SAlexandre Belloni 				continue;
211f6003f94SUwe Kleine-König 
212c32c5c50SAlexandre Belloni 			div = clk_rate;
213c32c5c50SAlexandre Belloni 			do_div(div, pval);
214c32c5c50SAlexandre Belloni 			div = div * state->period;
215c32c5c50SAlexandre Belloni 			do_div(div, NSEC_PER_SEC);
216c32c5c50SAlexandre Belloni 			if (div - 1 <= PWM_PRD_MASK)
217c32c5c50SAlexandre Belloni 				break;
218c32c5c50SAlexandre Belloni 		}
219c32c5c50SAlexandre Belloni 
220c32c5c50SAlexandre Belloni 		if (div - 1 > PWM_PRD_MASK)
221c32c5c50SAlexandre Belloni 			return -EINVAL;
222c32c5c50SAlexandre Belloni 	}
223c32c5c50SAlexandre Belloni 
224c32c5c50SAlexandre Belloni 	*prd = div;
225c32c5c50SAlexandre Belloni 	div *= state->duty_cycle;
226c32c5c50SAlexandre Belloni 	do_div(div, state->period);
227c32c5c50SAlexandre Belloni 	*dty = div;
228c32c5c50SAlexandre Belloni 	*prsclr = prescaler;
229c32c5c50SAlexandre Belloni 
230c32c5c50SAlexandre Belloni 	return 0;
231c32c5c50SAlexandre Belloni }
232c32c5c50SAlexandre Belloni 
sun4i_pwm_apply(struct pwm_chip * chip,struct pwm_device * pwm,const struct pwm_state * state)233c32c5c50SAlexandre Belloni static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
23471523d18SUwe Kleine-König 			   const struct pwm_state *state)
235c32c5c50SAlexandre Belloni {
236c32c5c50SAlexandre Belloni 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
237c32c5c50SAlexandre Belloni 	struct pwm_state cstate;
238413c2a11SThierry Reding 	u32 ctrl, duty = 0, period = 0, val;
239c32c5c50SAlexandre Belloni 	int ret;
240413c2a11SThierry Reding 	unsigned int delay_us, prescaler = 0;
2419f28e95bSJernej Skrabec 	bool bypass;
242c32c5c50SAlexandre Belloni 
243c32c5c50SAlexandre Belloni 	pwm_get_state(pwm, &cstate);
244c32c5c50SAlexandre Belloni 
245c32c5c50SAlexandre Belloni 	if (!cstate.enabled) {
246c32c5c50SAlexandre Belloni 		ret = clk_prepare_enable(sun4i_pwm->clk);
247c32c5c50SAlexandre Belloni 		if (ret) {
248c32c5c50SAlexandre Belloni 			dev_err(chip->dev, "failed to enable PWM clock\n");
249c32c5c50SAlexandre Belloni 			return ret;
250c32c5c50SAlexandre Belloni 		}
251c32c5c50SAlexandre Belloni 	}
252c32c5c50SAlexandre Belloni 
2539f28e95bSJernej Skrabec 	ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler,
2549f28e95bSJernej Skrabec 				  &bypass);
255c32c5c50SAlexandre Belloni 	if (ret) {
256c32c5c50SAlexandre Belloni 		dev_err(chip->dev, "period exceeds the maximum value\n");
257c32c5c50SAlexandre Belloni 		if (!cstate.enabled)
258c32c5c50SAlexandre Belloni 			clk_disable_unprepare(sun4i_pwm->clk);
259c32c5c50SAlexandre Belloni 		return ret;
260c32c5c50SAlexandre Belloni 	}
261c32c5c50SAlexandre Belloni 
2623e954d96SClément Péron 	spin_lock(&sun4i_pwm->ctrl_lock);
2633e954d96SClément Péron 	ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
2643e954d96SClément Péron 
2659f28e95bSJernej Skrabec 	if (sun4i_pwm->data->has_direct_mod_clk_output) {
2669f28e95bSJernej Skrabec 		if (bypass) {
2679f28e95bSJernej Skrabec 			ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm);
2689f28e95bSJernej Skrabec 			/* We can skip other parameter */
2699f28e95bSJernej Skrabec 			sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
2709f28e95bSJernej Skrabec 			spin_unlock(&sun4i_pwm->ctrl_lock);
2719f28e95bSJernej Skrabec 			return 0;
2729f28e95bSJernej Skrabec 		}
2739f28e95bSJernej Skrabec 
2749f28e95bSJernej Skrabec 		ctrl &= ~BIT_CH(PWM_BYPASS, pwm->hwpwm);
2759f28e95bSJernej Skrabec 	}
2769f28e95bSJernej Skrabec 
277c32c5c50SAlexandre Belloni 	if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) {
278c32c5c50SAlexandre Belloni 		/* Prescaler changed, the clock has to be gated */
279c32c5c50SAlexandre Belloni 		ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
280c32c5c50SAlexandre Belloni 		sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
281c32c5c50SAlexandre Belloni 
282c32c5c50SAlexandre Belloni 		ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
283c32c5c50SAlexandre Belloni 		ctrl |= BIT_CH(prescaler, pwm->hwpwm);
284c32c5c50SAlexandre Belloni 	}
285c32c5c50SAlexandre Belloni 
286c32c5c50SAlexandre Belloni 	val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
287c32c5c50SAlexandre Belloni 	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
288c32c5c50SAlexandre Belloni 
289c32c5c50SAlexandre Belloni 	if (state->polarity != PWM_POLARITY_NORMAL)
290c32c5c50SAlexandre Belloni 		ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
291c32c5c50SAlexandre Belloni 	else
292c32c5c50SAlexandre Belloni 		ctrl |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
293c32c5c50SAlexandre Belloni 
294c32c5c50SAlexandre Belloni 	ctrl |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
295fa4d8178SClément Péron 
2966eefb79dSThierry Reding 	if (state->enabled)
297c32c5c50SAlexandre Belloni 		ctrl |= BIT_CH(PWM_EN, pwm->hwpwm);
298c32c5c50SAlexandre Belloni 
299c32c5c50SAlexandre Belloni 	sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
300c32c5c50SAlexandre Belloni 
301c32c5c50SAlexandre Belloni 	spin_unlock(&sun4i_pwm->ctrl_lock);
302c32c5c50SAlexandre Belloni 
303c32c5c50SAlexandre Belloni 	if (state->enabled)
304c32c5c50SAlexandre Belloni 		return 0;
305c32c5c50SAlexandre Belloni 
306c32c5c50SAlexandre Belloni 	/* We need a full period to elapse before disabling the channel. */
3078246b478SMax Kellermann 	delay_us = DIV_ROUND_UP_ULL(cstate.period, NSEC_PER_USEC);
308c32c5c50SAlexandre Belloni 	if ((delay_us / 500) > MAX_UDELAY_MS)
309c32c5c50SAlexandre Belloni 		msleep(delay_us / 1000 + 1);
310c32c5c50SAlexandre Belloni 	else
311c32c5c50SAlexandre Belloni 		usleep_range(delay_us, delay_us * 2);
312c32c5c50SAlexandre Belloni 
313c32c5c50SAlexandre Belloni 	spin_lock(&sun4i_pwm->ctrl_lock);
314c32c5c50SAlexandre Belloni 	ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
315c32c5c50SAlexandre Belloni 	ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
316c32c5c50SAlexandre Belloni 	ctrl &= ~BIT_CH(PWM_EN, pwm->hwpwm);
317c32c5c50SAlexandre Belloni 	sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
318c32c5c50SAlexandre Belloni 	spin_unlock(&sun4i_pwm->ctrl_lock);
319c32c5c50SAlexandre Belloni 
320c32c5c50SAlexandre Belloni 	clk_disable_unprepare(sun4i_pwm->clk);
321c32c5c50SAlexandre Belloni 
322c32c5c50SAlexandre Belloni 	return 0;
323c32c5c50SAlexandre Belloni }
324c32c5c50SAlexandre Belloni 
32509853ce7SAlexandre Belloni static const struct pwm_ops sun4i_pwm_ops = {
326c32c5c50SAlexandre Belloni 	.apply = sun4i_pwm_apply,
32793e0dfb2SAlexandre Belloni 	.get_state = sun4i_pwm_get_state,
32809853ce7SAlexandre Belloni 	.owner = THIS_MODULE,
32909853ce7SAlexandre Belloni };
33009853ce7SAlexandre Belloni 
3317b4c7c56SAndre Przywara static const struct sun4i_pwm_data sun4i_pwm_dual_nobypass = {
33209853ce7SAlexandre Belloni 	.has_prescaler_bypass = false,
333f6649f7aSHans de Goede 	.npwm = 2,
334f6649f7aSHans de Goede };
335f6649f7aSHans de Goede 
3367b4c7c56SAndre Przywara static const struct sun4i_pwm_data sun4i_pwm_dual_bypass = {
337f6649f7aSHans de Goede 	.has_prescaler_bypass = true,
338f6649f7aSHans de Goede 	.npwm = 2,
339f6649f7aSHans de Goede };
340f6649f7aSHans de Goede 
3417b4c7c56SAndre Przywara static const struct sun4i_pwm_data sun4i_pwm_single_bypass = {
34242ddcf4fSMilo Kim 	.has_prescaler_bypass = true,
34342ddcf4fSMilo Kim 	.npwm = 1,
34442ddcf4fSMilo Kim };
34542ddcf4fSMilo Kim 
346856c45d8SPeter Vasil static const struct sun4i_pwm_data sun50i_a64_pwm_data = {
347856c45d8SPeter Vasil 	.has_prescaler_bypass = true,
348856c45d8SPeter Vasil 	.has_direct_mod_clk_output = true,
349856c45d8SPeter Vasil 	.npwm = 1,
350856c45d8SPeter Vasil };
351856c45d8SPeter Vasil 
352fdd2c12eSJernej Skrabec static const struct sun4i_pwm_data sun50i_h6_pwm_data = {
353fdd2c12eSJernej Skrabec 	.has_prescaler_bypass = true,
354fdd2c12eSJernej Skrabec 	.has_direct_mod_clk_output = true,
355fdd2c12eSJernej Skrabec 	.npwm = 2,
356fdd2c12eSJernej Skrabec };
357fdd2c12eSJernej Skrabec 
35809853ce7SAlexandre Belloni static const struct of_device_id sun4i_pwm_dt_ids[] = {
35909853ce7SAlexandre Belloni 	{
36009853ce7SAlexandre Belloni 		.compatible = "allwinner,sun4i-a10-pwm",
3617b4c7c56SAndre Przywara 		.data = &sun4i_pwm_dual_nobypass,
36209853ce7SAlexandre Belloni 	}, {
363f6649f7aSHans de Goede 		.compatible = "allwinner,sun5i-a10s-pwm",
3647b4c7c56SAndre Przywara 		.data = &sun4i_pwm_dual_bypass,
365f6649f7aSHans de Goede 	}, {
366f6649f7aSHans de Goede 		.compatible = "allwinner,sun5i-a13-pwm",
3677b4c7c56SAndre Przywara 		.data = &sun4i_pwm_single_bypass,
368f6649f7aSHans de Goede 	}, {
36909853ce7SAlexandre Belloni 		.compatible = "allwinner,sun7i-a20-pwm",
3707b4c7c56SAndre Przywara 		.data = &sun4i_pwm_dual_bypass,
37109853ce7SAlexandre Belloni 	}, {
37242ddcf4fSMilo Kim 		.compatible = "allwinner,sun8i-h3-pwm",
3737b4c7c56SAndre Przywara 		.data = &sun4i_pwm_single_bypass,
37442ddcf4fSMilo Kim 	}, {
375856c45d8SPeter Vasil 		.compatible = "allwinner,sun50i-a64-pwm",
376856c45d8SPeter Vasil 		.data = &sun50i_a64_pwm_data,
377856c45d8SPeter Vasil 	}, {
378fdd2c12eSJernej Skrabec 		.compatible = "allwinner,sun50i-h6-pwm",
379fdd2c12eSJernej Skrabec 		.data = &sun50i_h6_pwm_data,
380fdd2c12eSJernej Skrabec 	}, {
38109853ce7SAlexandre Belloni 		/* sentinel */
38209853ce7SAlexandre Belloni 	},
38309853ce7SAlexandre Belloni };
38409853ce7SAlexandre Belloni MODULE_DEVICE_TABLE(of, sun4i_pwm_dt_ids);
38509853ce7SAlexandre Belloni 
sun4i_pwm_probe(struct platform_device * pdev)38609853ce7SAlexandre Belloni static int sun4i_pwm_probe(struct platform_device *pdev)
38709853ce7SAlexandre Belloni {
388c4fab452SUwe Kleine-König 	struct sun4i_pwm_chip *sun4ichip;
38993e0dfb2SAlexandre Belloni 	int ret;
39009853ce7SAlexandre Belloni 
391c4fab452SUwe Kleine-König 	sun4ichip = devm_kzalloc(&pdev->dev, sizeof(*sun4ichip), GFP_KERNEL);
392c4fab452SUwe Kleine-König 	if (!sun4ichip)
39309853ce7SAlexandre Belloni 		return -ENOMEM;
39409853ce7SAlexandre Belloni 
395c4fab452SUwe Kleine-König 	sun4ichip->data = of_device_get_match_data(&pdev->dev);
396c4fab452SUwe Kleine-König 	if (!sun4ichip->data)
397df4f6e8cSCorentin Labbe 		return -ENODEV;
398df4f6e8cSCorentin Labbe 
399c4fab452SUwe Kleine-König 	sun4ichip->base = devm_platform_ioremap_resource(pdev, 0);
400c4fab452SUwe Kleine-König 	if (IS_ERR(sun4ichip->base))
401c4fab452SUwe Kleine-König 		return PTR_ERR(sun4ichip->base);
40209853ce7SAlexandre Belloni 
403b8d74644SClément Péron 	/*
404b8d74644SClément Péron 	 * All hardware variants need a source clock that is divided and
405b8d74644SClément Péron 	 * then feeds the counter that defines the output wave form. In the
406b8d74644SClément Péron 	 * device tree this clock is either unnamed or called "mod".
407b8d74644SClément Péron 	 * Some variants (e.g. H6) need another clock to access the
408b8d74644SClément Péron 	 * hardware registers; this is called "bus".
409b8d74644SClément Péron 	 * So we request "mod" first (and ignore the corner case that a
410b8d74644SClément Péron 	 * parent provides a "mod" clock while the right one would be the
411b8d74644SClément Péron 	 * unnamed one of the PWM device) and if this is not found we fall
412b8d74644SClément Péron 	 * back to the first clock of the PWM.
413b8d74644SClément Péron 	 */
414c4fab452SUwe Kleine-König 	sun4ichip->clk = devm_clk_get_optional(&pdev->dev, "mod");
415c4fab452SUwe Kleine-König 	if (IS_ERR(sun4ichip->clk))
416c4fab452SUwe Kleine-König 		return dev_err_probe(&pdev->dev, PTR_ERR(sun4ichip->clk),
4175327f34bSKrzysztof Kozlowski 				     "get mod clock failed\n");
418b8d74644SClément Péron 
419c4fab452SUwe Kleine-König 	if (!sun4ichip->clk) {
420c4fab452SUwe Kleine-König 		sun4ichip->clk = devm_clk_get(&pdev->dev, NULL);
421c4fab452SUwe Kleine-König 		if (IS_ERR(sun4ichip->clk))
422c4fab452SUwe Kleine-König 			return dev_err_probe(&pdev->dev, PTR_ERR(sun4ichip->clk),
4235327f34bSKrzysztof Kozlowski 					     "get unnamed clock failed\n");
424b8d74644SClément Péron 	}
42509853ce7SAlexandre Belloni 
426c4fab452SUwe Kleine-König 	sun4ichip->bus_clk = devm_clk_get_optional(&pdev->dev, "bus");
427c4fab452SUwe Kleine-König 	if (IS_ERR(sun4ichip->bus_clk))
428c4fab452SUwe Kleine-König 		return dev_err_probe(&pdev->dev, PTR_ERR(sun4ichip->bus_clk),
4295327f34bSKrzysztof Kozlowski 				     "get bus clock failed\n");
4305b090b43SJernej Skrabec 
431c4fab452SUwe Kleine-König 	sun4ichip->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
432c4fab452SUwe Kleine-König 	if (IS_ERR(sun4ichip->rst))
433c4fab452SUwe Kleine-König 		return dev_err_probe(&pdev->dev, PTR_ERR(sun4ichip->rst),
4345327f34bSKrzysztof Kozlowski 				     "get reset failed\n");
435a7fe9856SJernej Skrabec 
436a7fe9856SJernej Skrabec 	/* Deassert reset */
437c4fab452SUwe Kleine-König 	ret = reset_control_deassert(sun4ichip->rst);
438a7fe9856SJernej Skrabec 	if (ret) {
439a7fe9856SJernej Skrabec 		dev_err(&pdev->dev, "cannot deassert reset control: %pe\n",
440a7fe9856SJernej Skrabec 			ERR_PTR(ret));
441a7fe9856SJernej Skrabec 		return ret;
442a7fe9856SJernej Skrabec 	}
443a7fe9856SJernej Skrabec 
4445b090b43SJernej Skrabec 	/*
4455b090b43SJernej Skrabec 	 * We're keeping the bus clock on for the sake of simplicity.
4465b090b43SJernej Skrabec 	 * Actually it only needs to be on for hardware register accesses.
4475b090b43SJernej Skrabec 	 */
448c4fab452SUwe Kleine-König 	ret = clk_prepare_enable(sun4ichip->bus_clk);
4495b090b43SJernej Skrabec 	if (ret) {
4505b090b43SJernej Skrabec 		dev_err(&pdev->dev, "cannot prepare and enable bus_clk %pe\n",
4515b090b43SJernej Skrabec 			ERR_PTR(ret));
4525b090b43SJernej Skrabec 		goto err_bus;
4535b090b43SJernej Skrabec 	}
4545b090b43SJernej Skrabec 
455c4fab452SUwe Kleine-König 	sun4ichip->chip.dev = &pdev->dev;
456c4fab452SUwe Kleine-König 	sun4ichip->chip.ops = &sun4i_pwm_ops;
457c4fab452SUwe Kleine-König 	sun4ichip->chip.npwm = sun4ichip->data->npwm;
45809853ce7SAlexandre Belloni 
459c4fab452SUwe Kleine-König 	spin_lock_init(&sun4ichip->ctrl_lock);
46009853ce7SAlexandre Belloni 
461c4fab452SUwe Kleine-König 	ret = pwmchip_add(&sun4ichip->chip);
46209853ce7SAlexandre Belloni 	if (ret < 0) {
46309853ce7SAlexandre Belloni 		dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
464a7fe9856SJernej Skrabec 		goto err_pwm_add;
46509853ce7SAlexandre Belloni 	}
46609853ce7SAlexandre Belloni 
467c4fab452SUwe Kleine-König 	platform_set_drvdata(pdev, sun4ichip);
46809853ce7SAlexandre Belloni 
46909853ce7SAlexandre Belloni 	return 0;
470a7fe9856SJernej Skrabec 
471a7fe9856SJernej Skrabec err_pwm_add:
472c4fab452SUwe Kleine-König 	clk_disable_unprepare(sun4ichip->bus_clk);
4735b090b43SJernej Skrabec err_bus:
474c4fab452SUwe Kleine-König 	reset_control_assert(sun4ichip->rst);
475a7fe9856SJernej Skrabec 
476a7fe9856SJernej Skrabec 	return ret;
47709853ce7SAlexandre Belloni }
47809853ce7SAlexandre Belloni 
sun4i_pwm_remove(struct platform_device * pdev)479*0bda6b01SUwe Kleine-König static void sun4i_pwm_remove(struct platform_device *pdev)
48009853ce7SAlexandre Belloni {
481c4fab452SUwe Kleine-König 	struct sun4i_pwm_chip *sun4ichip = platform_get_drvdata(pdev);
48209853ce7SAlexandre Belloni 
483c4fab452SUwe Kleine-König 	pwmchip_remove(&sun4ichip->chip);
484a7fe9856SJernej Skrabec 
485c4fab452SUwe Kleine-König 	clk_disable_unprepare(sun4ichip->bus_clk);
486c4fab452SUwe Kleine-König 	reset_control_assert(sun4ichip->rst);
48709853ce7SAlexandre Belloni }
48809853ce7SAlexandre Belloni 
48909853ce7SAlexandre Belloni static struct platform_driver sun4i_pwm_driver = {
49009853ce7SAlexandre Belloni 	.driver = {
49109853ce7SAlexandre Belloni 		.name = "sun4i-pwm",
49209853ce7SAlexandre Belloni 		.of_match_table = sun4i_pwm_dt_ids,
49309853ce7SAlexandre Belloni 	},
49409853ce7SAlexandre Belloni 	.probe = sun4i_pwm_probe,
495*0bda6b01SUwe Kleine-König 	.remove_new = sun4i_pwm_remove,
49609853ce7SAlexandre Belloni };
49709853ce7SAlexandre Belloni module_platform_driver(sun4i_pwm_driver);
49809853ce7SAlexandre Belloni 
49909853ce7SAlexandre Belloni MODULE_ALIAS("platform:sun4i-pwm");
50009853ce7SAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
50109853ce7SAlexandre Belloni MODULE_DESCRIPTION("Allwinner sun4i PWM driver");
50209853ce7SAlexandre Belloni MODULE_LICENSE("GPL v2");
503