• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Imagination Technologies Pulse Width Modulator driver
4   *
5   * Copyright (c) 2014-2015, Imagination Technologies
6   *
7   * Based on drivers/pwm/pwm-tegra.c, Copyright (c) 2010, NVIDIA Corporation
8   */
9  
10  #include <linux/clk.h>
11  #include <linux/err.h>
12  #include <linux/io.h>
13  #include <linux/mfd/syscon.h>
14  #include <linux/module.h>
15  #include <linux/of.h>
16  #include <linux/of_device.h>
17  #include <linux/platform_device.h>
18  #include <linux/pm_runtime.h>
19  #include <linux/pwm.h>
20  #include <linux/regmap.h>
21  #include <linux/slab.h>
22  
23  /* PWM registers */
24  #define PWM_CTRL_CFG				0x0000
25  #define PWM_CTRL_CFG_NO_SUB_DIV			0
26  #define PWM_CTRL_CFG_SUB_DIV0			1
27  #define PWM_CTRL_CFG_SUB_DIV1			2
28  #define PWM_CTRL_CFG_SUB_DIV0_DIV1		3
29  #define PWM_CTRL_CFG_DIV_SHIFT(ch)		((ch) * 2 + 4)
30  #define PWM_CTRL_CFG_DIV_MASK			0x3
31  
32  #define PWM_CH_CFG(ch)				(0x4 + (ch) * 4)
33  #define PWM_CH_CFG_TMBASE_SHIFT			0
34  #define PWM_CH_CFG_DUTY_SHIFT			16
35  
36  #define PERIP_PWM_PDM_CONTROL			0x0140
37  #define PERIP_PWM_PDM_CONTROL_CH_MASK		0x1
38  #define PERIP_PWM_PDM_CONTROL_CH_SHIFT(ch)	((ch) * 4)
39  
40  #define IMG_PWM_PM_TIMEOUT			1000 /* ms */
41  
42  /*
43   * PWM period is specified with a timebase register,
44   * in number of step periods. The PWM duty cycle is also
45   * specified in step periods, in the [0, $timebase] range.
46   * In other words, the timebase imposes the duty cycle
47   * resolution. Therefore, let's constraint the timebase to
48   * a minimum value to allow a sane range of duty cycle values.
49   * Imposing a minimum timebase, will impose a maximum PWM frequency.
50   *
51   * The value chosen is completely arbitrary.
52   */
53  #define MIN_TMBASE_STEPS			16
54  
55  #define IMG_PWM_NPWM				4
56  
57  struct img_pwm_soc_data {
58  	u32 max_timebase;
59  };
60  
61  struct img_pwm_chip {
62  	struct device	*dev;
63  	struct pwm_chip	chip;
64  	struct clk	*pwm_clk;
65  	struct clk	*sys_clk;
66  	void __iomem	*base;
67  	struct regmap	*periph_regs;
68  	int		max_period_ns;
69  	int		min_period_ns;
70  	const struct img_pwm_soc_data   *data;
71  	u32		suspend_ctrl_cfg;
72  	u32		suspend_ch_cfg[IMG_PWM_NPWM];
73  };
74  
to_img_pwm_chip(struct pwm_chip * chip)75  static inline struct img_pwm_chip *to_img_pwm_chip(struct pwm_chip *chip)
76  {
77  	return container_of(chip, struct img_pwm_chip, chip);
78  }
79  
img_pwm_writel(struct img_pwm_chip * chip,u32 reg,u32 val)80  static inline void img_pwm_writel(struct img_pwm_chip *chip,
81  				  u32 reg, u32 val)
82  {
83  	writel(val, chip->base + reg);
84  }
85  
img_pwm_readl(struct img_pwm_chip * chip,u32 reg)86  static inline u32 img_pwm_readl(struct img_pwm_chip *chip,
87  					 u32 reg)
88  {
89  	return readl(chip->base + reg);
90  }
91  
img_pwm_config(struct pwm_chip * chip,struct pwm_device * pwm,int duty_ns,int period_ns)92  static int img_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
93  			  int duty_ns, int period_ns)
94  {
95  	u32 val, div, duty, timebase;
96  	unsigned long mul, output_clk_hz, input_clk_hz;
97  	struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip);
98  	unsigned int max_timebase = pwm_chip->data->max_timebase;
99  	int ret;
100  
101  	if (period_ns < pwm_chip->min_period_ns ||
102  	    period_ns > pwm_chip->max_period_ns) {
103  		dev_err(chip->dev, "configured period not in range\n");
104  		return -ERANGE;
105  	}
106  
107  	input_clk_hz = clk_get_rate(pwm_chip->pwm_clk);
108  	output_clk_hz = DIV_ROUND_UP(NSEC_PER_SEC, period_ns);
109  
110  	mul = DIV_ROUND_UP(input_clk_hz, output_clk_hz);
111  	if (mul <= max_timebase) {
112  		div = PWM_CTRL_CFG_NO_SUB_DIV;
113  		timebase = DIV_ROUND_UP(mul, 1);
114  	} else if (mul <= max_timebase * 8) {
115  		div = PWM_CTRL_CFG_SUB_DIV0;
116  		timebase = DIV_ROUND_UP(mul, 8);
117  	} else if (mul <= max_timebase * 64) {
118  		div = PWM_CTRL_CFG_SUB_DIV1;
119  		timebase = DIV_ROUND_UP(mul, 64);
120  	} else if (mul <= max_timebase * 512) {
121  		div = PWM_CTRL_CFG_SUB_DIV0_DIV1;
122  		timebase = DIV_ROUND_UP(mul, 512);
123  	} else {
124  		dev_err(chip->dev,
125  			"failed to configure timebase steps/divider value\n");
126  		return -EINVAL;
127  	}
128  
129  	duty = DIV_ROUND_UP(timebase * duty_ns, period_ns);
130  
131  	ret = pm_runtime_get_sync(chip->dev);
132  	if (ret < 0) {
133  		pm_runtime_put_autosuspend(chip->dev);
134  		return ret;
135  	}
136  
137  	val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
138  	val &= ~(PWM_CTRL_CFG_DIV_MASK << PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm));
139  	val |= (div & PWM_CTRL_CFG_DIV_MASK) <<
140  		PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm);
141  	img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
142  
143  	val = (duty << PWM_CH_CFG_DUTY_SHIFT) |
144  	      (timebase << PWM_CH_CFG_TMBASE_SHIFT);
145  	img_pwm_writel(pwm_chip, PWM_CH_CFG(pwm->hwpwm), val);
146  
147  	pm_runtime_mark_last_busy(chip->dev);
148  	pm_runtime_put_autosuspend(chip->dev);
149  
150  	return 0;
151  }
152  
img_pwm_enable(struct pwm_chip * chip,struct pwm_device * pwm)153  static int img_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
154  {
155  	u32 val;
156  	struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip);
157  	int ret;
158  
159  	ret = pm_runtime_resume_and_get(chip->dev);
160  	if (ret < 0)
161  		return ret;
162  
163  	val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
164  	val |= BIT(pwm->hwpwm);
165  	img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
166  
167  	regmap_update_bits(pwm_chip->periph_regs, PERIP_PWM_PDM_CONTROL,
168  			   PERIP_PWM_PDM_CONTROL_CH_MASK <<
169  			   PERIP_PWM_PDM_CONTROL_CH_SHIFT(pwm->hwpwm), 0);
170  
171  	return 0;
172  }
173  
img_pwm_disable(struct pwm_chip * chip,struct pwm_device * pwm)174  static void img_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
175  {
176  	u32 val;
177  	struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip);
178  
179  	val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
180  	val &= ~BIT(pwm->hwpwm);
181  	img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val);
182  
183  	pm_runtime_mark_last_busy(chip->dev);
184  	pm_runtime_put_autosuspend(chip->dev);
185  }
186  
187  static const struct pwm_ops img_pwm_ops = {
188  	.config = img_pwm_config,
189  	.enable = img_pwm_enable,
190  	.disable = img_pwm_disable,
191  	.owner = THIS_MODULE,
192  };
193  
194  static const struct img_pwm_soc_data pistachio_pwm = {
195  	.max_timebase = 255,
196  };
197  
198  static const struct of_device_id img_pwm_of_match[] = {
199  	{
200  		.compatible = "img,pistachio-pwm",
201  		.data = &pistachio_pwm,
202  	},
203  	{ }
204  };
205  MODULE_DEVICE_TABLE(of, img_pwm_of_match);
206  
img_pwm_runtime_suspend(struct device * dev)207  static int img_pwm_runtime_suspend(struct device *dev)
208  {
209  	struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev);
210  
211  	clk_disable_unprepare(pwm_chip->pwm_clk);
212  	clk_disable_unprepare(pwm_chip->sys_clk);
213  
214  	return 0;
215  }
216  
img_pwm_runtime_resume(struct device * dev)217  static int img_pwm_runtime_resume(struct device *dev)
218  {
219  	struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev);
220  	int ret;
221  
222  	ret = clk_prepare_enable(pwm_chip->sys_clk);
223  	if (ret < 0) {
224  		dev_err(dev, "could not prepare or enable sys clock\n");
225  		return ret;
226  	}
227  
228  	ret = clk_prepare_enable(pwm_chip->pwm_clk);
229  	if (ret < 0) {
230  		dev_err(dev, "could not prepare or enable pwm clock\n");
231  		clk_disable_unprepare(pwm_chip->sys_clk);
232  		return ret;
233  	}
234  
235  	return 0;
236  }
237  
img_pwm_probe(struct platform_device * pdev)238  static int img_pwm_probe(struct platform_device *pdev)
239  {
240  	int ret;
241  	u64 val;
242  	unsigned long clk_rate;
243  	struct resource *res;
244  	struct img_pwm_chip *pwm;
245  	const struct of_device_id *of_dev_id;
246  
247  	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
248  	if (!pwm)
249  		return -ENOMEM;
250  
251  	pwm->dev = &pdev->dev;
252  
253  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
254  	pwm->base = devm_ioremap_resource(&pdev->dev, res);
255  	if (IS_ERR(pwm->base))
256  		return PTR_ERR(pwm->base);
257  
258  	of_dev_id = of_match_device(img_pwm_of_match, &pdev->dev);
259  	if (!of_dev_id)
260  		return -ENODEV;
261  	pwm->data = of_dev_id->data;
262  
263  	pwm->periph_regs = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
264  							   "img,cr-periph");
265  	if (IS_ERR(pwm->periph_regs))
266  		return PTR_ERR(pwm->periph_regs);
267  
268  	pwm->sys_clk = devm_clk_get(&pdev->dev, "sys");
269  	if (IS_ERR(pwm->sys_clk)) {
270  		dev_err(&pdev->dev, "failed to get system clock\n");
271  		return PTR_ERR(pwm->sys_clk);
272  	}
273  
274  	pwm->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
275  	if (IS_ERR(pwm->pwm_clk)) {
276  		dev_err(&pdev->dev, "failed to get pwm clock\n");
277  		return PTR_ERR(pwm->pwm_clk);
278  	}
279  
280  	platform_set_drvdata(pdev, pwm);
281  
282  	pm_runtime_set_autosuspend_delay(&pdev->dev, IMG_PWM_PM_TIMEOUT);
283  	pm_runtime_use_autosuspend(&pdev->dev);
284  	pm_runtime_enable(&pdev->dev);
285  	if (!pm_runtime_enabled(&pdev->dev)) {
286  		ret = img_pwm_runtime_resume(&pdev->dev);
287  		if (ret)
288  			goto err_pm_disable;
289  	}
290  
291  	clk_rate = clk_get_rate(pwm->pwm_clk);
292  	if (!clk_rate) {
293  		dev_err(&pdev->dev, "pwm clock has no frequency\n");
294  		ret = -EINVAL;
295  		goto err_suspend;
296  	}
297  
298  	/* The maximum input clock divider is 512 */
299  	val = (u64)NSEC_PER_SEC * 512 * pwm->data->max_timebase;
300  	do_div(val, clk_rate);
301  	pwm->max_period_ns = val;
302  
303  	val = (u64)NSEC_PER_SEC * MIN_TMBASE_STEPS;
304  	do_div(val, clk_rate);
305  	pwm->min_period_ns = val;
306  
307  	pwm->chip.dev = &pdev->dev;
308  	pwm->chip.ops = &img_pwm_ops;
309  	pwm->chip.base = -1;
310  	pwm->chip.npwm = IMG_PWM_NPWM;
311  
312  	ret = pwmchip_add(&pwm->chip);
313  	if (ret < 0) {
314  		dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret);
315  		goto err_suspend;
316  	}
317  
318  	return 0;
319  
320  err_suspend:
321  	if (!pm_runtime_enabled(&pdev->dev))
322  		img_pwm_runtime_suspend(&pdev->dev);
323  err_pm_disable:
324  	pm_runtime_disable(&pdev->dev);
325  	pm_runtime_dont_use_autosuspend(&pdev->dev);
326  	return ret;
327  }
328  
img_pwm_remove(struct platform_device * pdev)329  static int img_pwm_remove(struct platform_device *pdev)
330  {
331  	struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev);
332  
333  	pm_runtime_disable(&pdev->dev);
334  	if (!pm_runtime_status_suspended(&pdev->dev))
335  		img_pwm_runtime_suspend(&pdev->dev);
336  
337  	return pwmchip_remove(&pwm_chip->chip);
338  }
339  
340  #ifdef CONFIG_PM_SLEEP
img_pwm_suspend(struct device * dev)341  static int img_pwm_suspend(struct device *dev)
342  {
343  	struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev);
344  	int i, ret;
345  
346  	if (pm_runtime_status_suspended(dev)) {
347  		ret = img_pwm_runtime_resume(dev);
348  		if (ret)
349  			return ret;
350  	}
351  
352  	for (i = 0; i < pwm_chip->chip.npwm; i++)
353  		pwm_chip->suspend_ch_cfg[i] = img_pwm_readl(pwm_chip,
354  							    PWM_CH_CFG(i));
355  
356  	pwm_chip->suspend_ctrl_cfg = img_pwm_readl(pwm_chip, PWM_CTRL_CFG);
357  
358  	img_pwm_runtime_suspend(dev);
359  
360  	return 0;
361  }
362  
img_pwm_resume(struct device * dev)363  static int img_pwm_resume(struct device *dev)
364  {
365  	struct img_pwm_chip *pwm_chip = dev_get_drvdata(dev);
366  	int ret;
367  	int i;
368  
369  	ret = img_pwm_runtime_resume(dev);
370  	if (ret)
371  		return ret;
372  
373  	for (i = 0; i < pwm_chip->chip.npwm; i++)
374  		img_pwm_writel(pwm_chip, PWM_CH_CFG(i),
375  			       pwm_chip->suspend_ch_cfg[i]);
376  
377  	img_pwm_writel(pwm_chip, PWM_CTRL_CFG, pwm_chip->suspend_ctrl_cfg);
378  
379  	for (i = 0; i < pwm_chip->chip.npwm; i++)
380  		if (pwm_chip->suspend_ctrl_cfg & BIT(i))
381  			regmap_update_bits(pwm_chip->periph_regs,
382  					   PERIP_PWM_PDM_CONTROL,
383  					   PERIP_PWM_PDM_CONTROL_CH_MASK <<
384  					   PERIP_PWM_PDM_CONTROL_CH_SHIFT(i),
385  					   0);
386  
387  	if (pm_runtime_status_suspended(dev))
388  		img_pwm_runtime_suspend(dev);
389  
390  	return 0;
391  }
392  #endif /* CONFIG_PM */
393  
394  static const struct dev_pm_ops img_pwm_pm_ops = {
395  	SET_RUNTIME_PM_OPS(img_pwm_runtime_suspend,
396  			   img_pwm_runtime_resume,
397  			   NULL)
398  	SET_SYSTEM_SLEEP_PM_OPS(img_pwm_suspend, img_pwm_resume)
399  };
400  
401  static struct platform_driver img_pwm_driver = {
402  	.driver = {
403  		.name = "img-pwm",
404  		.pm = &img_pwm_pm_ops,
405  		.of_match_table = img_pwm_of_match,
406  	},
407  	.probe = img_pwm_probe,
408  	.remove = img_pwm_remove,
409  };
410  module_platform_driver(img_pwm_driver);
411  
412  MODULE_AUTHOR("Sai Masarapu <Sai.Masarapu@imgtec.com>");
413  MODULE_DESCRIPTION("Imagination Technologies PWM DAC driver");
414  MODULE_LICENSE("GPL v2");
415