xref: /kernel/linux/linux-5.10/drivers/pwm/pwm-img.c (revision 8c2ecf20)
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
57struct img_pwm_soc_data {
58	u32 max_timebase;
59};
60
61struct 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
75static 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
80static inline void img_pwm_writel(struct img_pwm_chip *chip,
81				  u32 reg, u32 val)
82{
83	writel(val, chip->base + reg);
84}
85
86static inline u32 img_pwm_readl(struct img_pwm_chip *chip,
87					 u32 reg)
88{
89	return readl(chip->base + reg);
90}
91
92static 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
153static 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
174static 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
187static 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
194static const struct img_pwm_soc_data pistachio_pwm = {
195	.max_timebase = 255,
196};
197
198static const struct of_device_id img_pwm_of_match[] = {
199	{
200		.compatible = "img,pistachio-pwm",
201		.data = &pistachio_pwm,
202	},
203	{ }
204};
205MODULE_DEVICE_TABLE(of, img_pwm_of_match);
206
207static 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
217static 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
238static 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
320err_suspend:
321	if (!pm_runtime_enabled(&pdev->dev))
322		img_pwm_runtime_suspend(&pdev->dev);
323err_pm_disable:
324	pm_runtime_disable(&pdev->dev);
325	pm_runtime_dont_use_autosuspend(&pdev->dev);
326	return ret;
327}
328
329static 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
341static 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
363static 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
394static 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
401static 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};
410module_platform_driver(img_pwm_driver);
411
412MODULE_AUTHOR("Sai Masarapu <Sai.Masarapu@imgtec.com>");
413MODULE_DESCRIPTION("Imagination Technologies PWM DAC driver");
414MODULE_LICENSE("GPL v2");
415