xref: /openbmc/linux/drivers/pwm/pwm-tiehrpwm.c (revision b3fd7368f8f60bc9a7ffc2a5311db5f4dbd42180)
1  /*
2   * EHRPWM PWM driver
3   *
4   * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/
5   *
6   * This program is free software; you can redistribute it and/or modify
7   * it under the terms of the GNU General Public License as published by
8   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with this program; if not, write to the Free Software
18   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19   */
20  
21  #include <linux/module.h>
22  #include <linux/platform_device.h>
23  #include <linux/pwm.h>
24  #include <linux/io.h>
25  #include <linux/err.h>
26  #include <linux/clk.h>
27  #include <linux/pm_runtime.h>
28  #include <linux/of_device.h>
29  
30  #include "pwm-tipwmss.h"
31  
32  /* EHRPWM registers and bits definitions */
33  
34  /* Time base module registers */
35  #define TBCTL			0x00
36  #define TBPRD			0x0A
37  
38  #define TBCTL_RUN_MASK		(BIT(15) | BIT(14))
39  #define TBCTL_STOP_NEXT		0
40  #define TBCTL_STOP_ON_CYCLE	BIT(14)
41  #define TBCTL_FREE_RUN		(BIT(15) | BIT(14))
42  #define TBCTL_PRDLD_MASK	BIT(3)
43  #define TBCTL_PRDLD_SHDW	0
44  #define TBCTL_PRDLD_IMDT	BIT(3)
45  #define TBCTL_CLKDIV_MASK	(BIT(12) | BIT(11) | BIT(10) | BIT(9) | \
46  				BIT(8) | BIT(7))
47  #define TBCTL_CTRMODE_MASK	(BIT(1) | BIT(0))
48  #define TBCTL_CTRMODE_UP	0
49  #define TBCTL_CTRMODE_DOWN	BIT(0)
50  #define TBCTL_CTRMODE_UPDOWN	BIT(1)
51  #define TBCTL_CTRMODE_FREEZE	(BIT(1) | BIT(0))
52  
53  #define TBCTL_HSPCLKDIV_SHIFT	7
54  #define TBCTL_CLKDIV_SHIFT	10
55  
56  #define CLKDIV_MAX		7
57  #define HSPCLKDIV_MAX		7
58  #define PERIOD_MAX		0xFFFF
59  
60  /* compare module registers */
61  #define CMPA			0x12
62  #define CMPB			0x14
63  
64  /* Action qualifier module registers */
65  #define AQCTLA			0x16
66  #define AQCTLB			0x18
67  #define AQSFRC			0x1A
68  #define AQCSFRC			0x1C
69  
70  #define AQCTL_CBU_MASK		(BIT(9) | BIT(8))
71  #define AQCTL_CBU_FRCLOW	BIT(8)
72  #define AQCTL_CBU_FRCHIGH	BIT(9)
73  #define AQCTL_CBU_FRCTOGGLE	(BIT(9) | BIT(8))
74  #define AQCTL_CAU_MASK		(BIT(5) | BIT(4))
75  #define AQCTL_CAU_FRCLOW	BIT(4)
76  #define AQCTL_CAU_FRCHIGH	BIT(5)
77  #define AQCTL_CAU_FRCTOGGLE	(BIT(5) | BIT(4))
78  #define AQCTL_PRD_MASK		(BIT(3) | BIT(2))
79  #define AQCTL_PRD_FRCLOW	BIT(2)
80  #define AQCTL_PRD_FRCHIGH	BIT(3)
81  #define AQCTL_PRD_FRCTOGGLE	(BIT(3) | BIT(2))
82  #define AQCTL_ZRO_MASK		(BIT(1) | BIT(0))
83  #define AQCTL_ZRO_FRCLOW	BIT(0)
84  #define AQCTL_ZRO_FRCHIGH	BIT(1)
85  #define AQCTL_ZRO_FRCTOGGLE	(BIT(1) | BIT(0))
86  
87  #define AQCTL_CHANA_POLNORMAL	(AQCTL_CAU_FRCLOW | AQCTL_PRD_FRCHIGH | \
88  				AQCTL_ZRO_FRCHIGH)
89  #define AQCTL_CHANA_POLINVERSED	(AQCTL_CAU_FRCHIGH | AQCTL_PRD_FRCLOW | \
90  				AQCTL_ZRO_FRCLOW)
91  #define AQCTL_CHANB_POLNORMAL	(AQCTL_CBU_FRCLOW | AQCTL_PRD_FRCHIGH | \
92  				AQCTL_ZRO_FRCHIGH)
93  #define AQCTL_CHANB_POLINVERSED	(AQCTL_CBU_FRCHIGH | AQCTL_PRD_FRCLOW | \
94  				AQCTL_ZRO_FRCLOW)
95  
96  #define AQSFRC_RLDCSF_MASK	(BIT(7) | BIT(6))
97  #define AQSFRC_RLDCSF_ZRO	0
98  #define AQSFRC_RLDCSF_PRD	BIT(6)
99  #define AQSFRC_RLDCSF_ZROPRD	BIT(7)
100  #define AQSFRC_RLDCSF_IMDT	(BIT(7) | BIT(6))
101  
102  #define AQCSFRC_CSFB_MASK	(BIT(3) | BIT(2))
103  #define AQCSFRC_CSFB_FRCDIS	0
104  #define AQCSFRC_CSFB_FRCLOW	BIT(2)
105  #define AQCSFRC_CSFB_FRCHIGH	BIT(3)
106  #define AQCSFRC_CSFB_DISSWFRC	(BIT(3) | BIT(2))
107  #define AQCSFRC_CSFA_MASK	(BIT(1) | BIT(0))
108  #define AQCSFRC_CSFA_FRCDIS	0
109  #define AQCSFRC_CSFA_FRCLOW	BIT(0)
110  #define AQCSFRC_CSFA_FRCHIGH	BIT(1)
111  #define AQCSFRC_CSFA_DISSWFRC	(BIT(1) | BIT(0))
112  
113  #define NUM_PWM_CHANNEL		2	/* EHRPWM channels */
114  
115  struct ehrpwm_context {
116  	u16 tbctl;
117  	u16 tbprd;
118  	u16 cmpa;
119  	u16 cmpb;
120  	u16 aqctla;
121  	u16 aqctlb;
122  	u16 aqsfrc;
123  	u16 aqcsfrc;
124  };
125  
126  struct ehrpwm_pwm_chip {
127  	struct pwm_chip	chip;
128  	unsigned int	clk_rate;
129  	void __iomem	*mmio_base;
130  	unsigned long period_cycles[NUM_PWM_CHANNEL];
131  	enum pwm_polarity polarity[NUM_PWM_CHANNEL];
132  	struct	clk	*tbclk;
133  	struct ehrpwm_context ctx;
134  };
135  
136  static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
137  {
138  	return container_of(chip, struct ehrpwm_pwm_chip, chip);
139  }
140  
141  static inline u16 ehrpwm_read(void __iomem *base, int offset)
142  {
143  	return readw(base + offset);
144  }
145  
146  static inline void ehrpwm_write(void __iomem *base, int offset, unsigned int val)
147  {
148  	writew(val & 0xFFFF, base + offset);
149  }
150  
151  static void ehrpwm_modify(void __iomem *base, int offset,
152  		unsigned short mask, unsigned short val)
153  {
154  	unsigned short regval;
155  
156  	regval = readw(base + offset);
157  	regval &= ~mask;
158  	regval |= val & mask;
159  	writew(regval, base + offset);
160  }
161  
162  /**
163   * set_prescale_div -	Set up the prescaler divider function
164   * @rqst_prescaler:	prescaler value min
165   * @prescale_div:	prescaler value set
166   * @tb_clk_div:		Time Base Control prescaler bits
167   */
168  static int set_prescale_div(unsigned long rqst_prescaler,
169  		unsigned short *prescale_div, unsigned short *tb_clk_div)
170  {
171  	unsigned int clkdiv, hspclkdiv;
172  
173  	for (clkdiv = 0; clkdiv <= CLKDIV_MAX; clkdiv++) {
174  		for (hspclkdiv = 0; hspclkdiv <= HSPCLKDIV_MAX; hspclkdiv++) {
175  
176  			/*
177  			 * calculations for prescaler value :
178  			 * prescale_div = HSPCLKDIVIDER * CLKDIVIDER.
179  			 * HSPCLKDIVIDER =  2 ** hspclkdiv
180  			 * CLKDIVIDER = (1),		if clkdiv == 0 *OR*
181  			 *		(2 * clkdiv),	if clkdiv != 0
182  			 *
183  			 * Configure prescale_div value such that period
184  			 * register value is less than 65535.
185  			 */
186  
187  			*prescale_div = (1 << clkdiv) *
188  					(hspclkdiv ? (hspclkdiv * 2) : 1);
189  			if (*prescale_div > rqst_prescaler) {
190  				*tb_clk_div = (clkdiv << TBCTL_CLKDIV_SHIFT) |
191  					(hspclkdiv << TBCTL_HSPCLKDIV_SHIFT);
192  				return 0;
193  			}
194  		}
195  	}
196  	return 1;
197  }
198  
199  static void configure_polarity(struct ehrpwm_pwm_chip *pc, int chan)
200  {
201  	int aqctl_reg;
202  	unsigned short aqctl_val, aqctl_mask;
203  
204  	/*
205  	 * Configure PWM output to HIGH/LOW level on counter
206  	 * reaches compare register value and LOW/HIGH level
207  	 * on counter value reaches period register value and
208  	 * zero value on counter
209  	 */
210  	if (chan == 1) {
211  		aqctl_reg = AQCTLB;
212  		aqctl_mask = AQCTL_CBU_MASK;
213  
214  		if (pc->polarity[chan] == PWM_POLARITY_INVERSED)
215  			aqctl_val = AQCTL_CHANB_POLINVERSED;
216  		else
217  			aqctl_val = AQCTL_CHANB_POLNORMAL;
218  	} else {
219  		aqctl_reg = AQCTLA;
220  		aqctl_mask = AQCTL_CAU_MASK;
221  
222  		if (pc->polarity[chan] == PWM_POLARITY_INVERSED)
223  			aqctl_val = AQCTL_CHANA_POLINVERSED;
224  		else
225  			aqctl_val = AQCTL_CHANA_POLNORMAL;
226  	}
227  
228  	aqctl_mask |= AQCTL_PRD_MASK | AQCTL_ZRO_MASK;
229  	ehrpwm_modify(pc->mmio_base, aqctl_reg, aqctl_mask, aqctl_val);
230  }
231  
232  /*
233   * period_ns = 10^9 * (ps_divval * period_cycles) / PWM_CLK_RATE
234   * duty_ns   = 10^9 * (ps_divval * duty_cycles) / PWM_CLK_RATE
235   */
236  static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
237  		int duty_ns, int period_ns)
238  {
239  	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
240  	unsigned long long c;
241  	unsigned long period_cycles, duty_cycles;
242  	unsigned short ps_divval, tb_divval;
243  	int i, cmp_reg;
244  
245  	if (period_ns > NSEC_PER_SEC)
246  		return -ERANGE;
247  
248  	c = pc->clk_rate;
249  	c = c * period_ns;
250  	do_div(c, NSEC_PER_SEC);
251  	period_cycles = (unsigned long)c;
252  
253  	if (period_cycles < 1) {
254  		period_cycles = 1;
255  		duty_cycles = 1;
256  	} else {
257  		c = pc->clk_rate;
258  		c = c * duty_ns;
259  		do_div(c, NSEC_PER_SEC);
260  		duty_cycles = (unsigned long)c;
261  	}
262  
263  	/*
264  	 * Period values should be same for multiple PWM channels as IP uses
265  	 * same period register for multiple channels.
266  	 */
267  	for (i = 0; i < NUM_PWM_CHANNEL; i++) {
268  		if (pc->period_cycles[i] &&
269  				(pc->period_cycles[i] != period_cycles)) {
270  			/*
271  			 * Allow channel to reconfigure period if no other
272  			 * channels being configured.
273  			 */
274  			if (i == pwm->hwpwm)
275  				continue;
276  
277  			dev_err(chip->dev, "Period value conflicts with channel %d\n",
278  					i);
279  			return -EINVAL;
280  		}
281  	}
282  
283  	pc->period_cycles[pwm->hwpwm] = period_cycles;
284  
285  	/* Configure clock prescaler to support Low frequency PWM wave */
286  	if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval,
287  				&tb_divval)) {
288  		dev_err(chip->dev, "Unsupported values\n");
289  		return -EINVAL;
290  	}
291  
292  	pm_runtime_get_sync(chip->dev);
293  
294  	/* Update clock prescaler values */
295  	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CLKDIV_MASK, tb_divval);
296  
297  	/* Update period & duty cycle with presacler division */
298  	period_cycles = period_cycles / ps_divval;
299  	duty_cycles = duty_cycles / ps_divval;
300  
301  	/* Configure shadow loading on Period register */
302  	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_PRDLD_MASK, TBCTL_PRDLD_SHDW);
303  
304  	ehrpwm_write(pc->mmio_base, TBPRD, period_cycles);
305  
306  	/* Configure ehrpwm counter for up-count mode */
307  	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CTRMODE_MASK,
308  			TBCTL_CTRMODE_UP);
309  
310  	if (pwm->hwpwm == 1)
311  		/* Channel 1 configured with compare B register */
312  		cmp_reg = CMPB;
313  	else
314  		/* Channel 0 configured with compare A register */
315  		cmp_reg = CMPA;
316  
317  	ehrpwm_write(pc->mmio_base, cmp_reg, duty_cycles);
318  
319  	pm_runtime_put_sync(chip->dev);
320  	return 0;
321  }
322  
323  static int ehrpwm_pwm_set_polarity(struct pwm_chip *chip,
324  		struct pwm_device *pwm,	enum pwm_polarity polarity)
325  {
326  	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
327  
328  	/* Configuration of polarity in hardware delayed, do at enable */
329  	pc->polarity[pwm->hwpwm] = polarity;
330  	return 0;
331  }
332  
333  static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
334  {
335  	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
336  	unsigned short aqcsfrc_val, aqcsfrc_mask;
337  	int ret;
338  
339  	/* Leave clock enabled on enabling PWM */
340  	pm_runtime_get_sync(chip->dev);
341  
342  	/* Disabling Action Qualifier on PWM output */
343  	if (pwm->hwpwm) {
344  		aqcsfrc_val = AQCSFRC_CSFB_FRCDIS;
345  		aqcsfrc_mask = AQCSFRC_CSFB_MASK;
346  	} else {
347  		aqcsfrc_val = AQCSFRC_CSFA_FRCDIS;
348  		aqcsfrc_mask = AQCSFRC_CSFA_MASK;
349  	}
350  
351  	/* Changes to shadow mode */
352  	ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK,
353  			AQSFRC_RLDCSF_ZRO);
354  
355  	ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
356  
357  	/* Channels polarity can be configured from action qualifier module */
358  	configure_polarity(pc, pwm->hwpwm);
359  
360  	/* Enable TBCLK before enabling PWM device */
361  	ret = clk_enable(pc->tbclk);
362  	if (ret) {
363  		dev_err(chip->dev, "Failed to enable TBCLK for %s\n",
364  			dev_name(pc->chip.dev));
365  		return ret;
366  	}
367  
368  	/* Enable time counter for free_run */
369  	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
370  	return 0;
371  }
372  
373  static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
374  {
375  	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
376  	unsigned short aqcsfrc_val, aqcsfrc_mask;
377  
378  	/* Action Qualifier puts PWM output low forcefully */
379  	if (pwm->hwpwm) {
380  		aqcsfrc_val = AQCSFRC_CSFB_FRCLOW;
381  		aqcsfrc_mask = AQCSFRC_CSFB_MASK;
382  	} else {
383  		aqcsfrc_val = AQCSFRC_CSFA_FRCLOW;
384  		aqcsfrc_mask = AQCSFRC_CSFA_MASK;
385  	}
386  
387  	/*
388  	 * Changes to immediate action on Action Qualifier. This puts
389  	 * Action Qualifier control on PWM output from next TBCLK
390  	 */
391  	ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK,
392  			AQSFRC_RLDCSF_IMDT);
393  
394  	ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
395  
396  	/* Disabling TBCLK on PWM disable */
397  	clk_disable(pc->tbclk);
398  
399  	/* Stop Time base counter */
400  	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT);
401  
402  	/* Disable clock on PWM disable */
403  	pm_runtime_put_sync(chip->dev);
404  }
405  
406  static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
407  {
408  	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
409  
410  	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
411  		dev_warn(chip->dev, "Removing PWM device without disabling\n");
412  		pm_runtime_put_sync(chip->dev);
413  	}
414  
415  	/* set period value to zero on free */
416  	pc->period_cycles[pwm->hwpwm] = 0;
417  }
418  
419  static const struct pwm_ops ehrpwm_pwm_ops = {
420  	.free		= ehrpwm_pwm_free,
421  	.config		= ehrpwm_pwm_config,
422  	.set_polarity	= ehrpwm_pwm_set_polarity,
423  	.enable		= ehrpwm_pwm_enable,
424  	.disable	= ehrpwm_pwm_disable,
425  	.owner		= THIS_MODULE,
426  };
427  
428  static const struct of_device_id ehrpwm_of_match[] = {
429  	{ .compatible	= "ti,am33xx-ehrpwm" },
430  	{},
431  };
432  MODULE_DEVICE_TABLE(of, ehrpwm_of_match);
433  
434  static int ehrpwm_pwm_probe(struct platform_device *pdev)
435  {
436  	int ret;
437  	struct resource *r;
438  	struct clk *clk;
439  	struct ehrpwm_pwm_chip *pc;
440  	u16 status;
441  
442  	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
443  	if (!pc)
444  		return -ENOMEM;
445  
446  	clk = devm_clk_get(&pdev->dev, "fck");
447  	if (IS_ERR(clk)) {
448  		dev_err(&pdev->dev, "failed to get clock\n");
449  		return PTR_ERR(clk);
450  	}
451  
452  	pc->clk_rate = clk_get_rate(clk);
453  	if (!pc->clk_rate) {
454  		dev_err(&pdev->dev, "failed to get clock rate\n");
455  		return -EINVAL;
456  	}
457  
458  	pc->chip.dev = &pdev->dev;
459  	pc->chip.ops = &ehrpwm_pwm_ops;
460  	pc->chip.of_xlate = of_pwm_xlate_with_flags;
461  	pc->chip.of_pwm_n_cells = 3;
462  	pc->chip.base = -1;
463  	pc->chip.npwm = NUM_PWM_CHANNEL;
464  
465  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
466  	pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
467  	if (IS_ERR(pc->mmio_base))
468  		return PTR_ERR(pc->mmio_base);
469  
470  	/* Acquire tbclk for Time Base EHRPWM submodule */
471  	pc->tbclk = devm_clk_get(&pdev->dev, "tbclk");
472  	if (IS_ERR(pc->tbclk)) {
473  		dev_err(&pdev->dev, "Failed to get tbclk\n");
474  		return PTR_ERR(pc->tbclk);
475  	}
476  
477  	ret = clk_prepare(pc->tbclk);
478  	if (ret < 0) {
479  		dev_err(&pdev->dev, "clk_prepare() failed: %d\n", ret);
480  		return ret;
481  	}
482  
483  	ret = pwmchip_add(&pc->chip);
484  	if (ret < 0) {
485  		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
486  		return ret;
487  	}
488  
489  	pm_runtime_enable(&pdev->dev);
490  	pm_runtime_get_sync(&pdev->dev);
491  
492  	status = pwmss_submodule_state_change(pdev->dev.parent,
493  			PWMSS_EPWMCLK_EN);
494  	if (!(status & PWMSS_EPWMCLK_EN_ACK)) {
495  		dev_err(&pdev->dev, "PWMSS config space clock enable failed\n");
496  		ret = -EINVAL;
497  		goto pwmss_clk_failure;
498  	}
499  
500  	pm_runtime_put_sync(&pdev->dev);
501  
502  	platform_set_drvdata(pdev, pc);
503  	return 0;
504  
505  pwmss_clk_failure:
506  	pm_runtime_put_sync(&pdev->dev);
507  	pm_runtime_disable(&pdev->dev);
508  	pwmchip_remove(&pc->chip);
509  	clk_unprepare(pc->tbclk);
510  	return ret;
511  }
512  
513  static int ehrpwm_pwm_remove(struct platform_device *pdev)
514  {
515  	struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
516  
517  	clk_unprepare(pc->tbclk);
518  
519  	pm_runtime_get_sync(&pdev->dev);
520  	/*
521  	 * Due to hardware misbehaviour, acknowledge of the stop_req
522  	 * is missing. Hence checking of the status bit skipped.
523  	 */
524  	pwmss_submodule_state_change(pdev->dev.parent, PWMSS_EPWMCLK_STOP_REQ);
525  	pm_runtime_put_sync(&pdev->dev);
526  
527  	pm_runtime_put_sync(&pdev->dev);
528  	pm_runtime_disable(&pdev->dev);
529  	return pwmchip_remove(&pc->chip);
530  }
531  
532  #ifdef CONFIG_PM_SLEEP
533  static void ehrpwm_pwm_save_context(struct ehrpwm_pwm_chip *pc)
534  {
535  	pm_runtime_get_sync(pc->chip.dev);
536  	pc->ctx.tbctl = ehrpwm_read(pc->mmio_base, TBCTL);
537  	pc->ctx.tbprd = ehrpwm_read(pc->mmio_base, TBPRD);
538  	pc->ctx.cmpa = ehrpwm_read(pc->mmio_base, CMPA);
539  	pc->ctx.cmpb = ehrpwm_read(pc->mmio_base, CMPB);
540  	pc->ctx.aqctla = ehrpwm_read(pc->mmio_base, AQCTLA);
541  	pc->ctx.aqctlb = ehrpwm_read(pc->mmio_base, AQCTLB);
542  	pc->ctx.aqsfrc = ehrpwm_read(pc->mmio_base, AQSFRC);
543  	pc->ctx.aqcsfrc = ehrpwm_read(pc->mmio_base, AQCSFRC);
544  	pm_runtime_put_sync(pc->chip.dev);
545  }
546  
547  static void ehrpwm_pwm_restore_context(struct ehrpwm_pwm_chip *pc)
548  {
549  	ehrpwm_write(pc->mmio_base, TBPRD, pc->ctx.tbprd);
550  	ehrpwm_write(pc->mmio_base, CMPA, pc->ctx.cmpa);
551  	ehrpwm_write(pc->mmio_base, CMPB, pc->ctx.cmpb);
552  	ehrpwm_write(pc->mmio_base, AQCTLA, pc->ctx.aqctla);
553  	ehrpwm_write(pc->mmio_base, AQCTLB, pc->ctx.aqctlb);
554  	ehrpwm_write(pc->mmio_base, AQSFRC, pc->ctx.aqsfrc);
555  	ehrpwm_write(pc->mmio_base, AQCSFRC, pc->ctx.aqcsfrc);
556  	ehrpwm_write(pc->mmio_base, TBCTL, pc->ctx.tbctl);
557  }
558  
559  static int ehrpwm_pwm_suspend(struct device *dev)
560  {
561  	struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev);
562  	int i;
563  
564  	ehrpwm_pwm_save_context(pc);
565  	for (i = 0; i < pc->chip.npwm; i++) {
566  		struct pwm_device *pwm = &pc->chip.pwms[i];
567  
568  		if (!test_bit(PWMF_ENABLED, &pwm->flags))
569  			continue;
570  
571  		/* Disable explicitly if PWM is running */
572  		pm_runtime_put_sync(dev);
573  	}
574  	return 0;
575  }
576  
577  static int ehrpwm_pwm_resume(struct device *dev)
578  {
579  	struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev);
580  	int i;
581  
582  	for (i = 0; i < pc->chip.npwm; i++) {
583  		struct pwm_device *pwm = &pc->chip.pwms[i];
584  
585  		if (!test_bit(PWMF_ENABLED, &pwm->flags))
586  			continue;
587  
588  		/* Enable explicitly if PWM was running */
589  		pm_runtime_get_sync(dev);
590  	}
591  	ehrpwm_pwm_restore_context(pc);
592  	return 0;
593  }
594  #endif
595  
596  static SIMPLE_DEV_PM_OPS(ehrpwm_pwm_pm_ops, ehrpwm_pwm_suspend,
597  		ehrpwm_pwm_resume);
598  
599  static struct platform_driver ehrpwm_pwm_driver = {
600  	.driver = {
601  		.name	= "ehrpwm",
602  		.of_match_table = ehrpwm_of_match,
603  		.pm	= &ehrpwm_pwm_pm_ops,
604  	},
605  	.probe = ehrpwm_pwm_probe,
606  	.remove = ehrpwm_pwm_remove,
607  };
608  
609  module_platform_driver(ehrpwm_pwm_driver);
610  
611  MODULE_DESCRIPTION("EHRPWM PWM driver");
612  MODULE_AUTHOR("Texas Instruments");
613  MODULE_LICENSE("GPL");
614