• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * drivers/pwm/pwm-tegra.c
4  *
5  * Tegra pulse-width-modulation controller driver
6  *
7  * Copyright (c) 2010, NVIDIA Corporation.
8  * Based on arch/arm/plat-mxc/pwm.c by Sascha Hauer <s.hauer@pengutronix.de>
9  */
10 
11 #include <linux/clk.h>
12 #include <linux/err.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_device.h>
17 #include <linux/pwm.h>
18 #include <linux/platform_device.h>
19 #include <linux/pinctrl/consumer.h>
20 #include <linux/slab.h>
21 #include <linux/reset.h>
22 
23 #define PWM_ENABLE	(1 << 31)
24 #define PWM_DUTY_WIDTH	8
25 #define PWM_DUTY_SHIFT	16
26 #define PWM_SCALE_WIDTH	13
27 #define PWM_SCALE_SHIFT	0
28 
29 struct tegra_pwm_soc {
30 	unsigned int num_channels;
31 
32 	/* Maximum IP frequency for given SoCs */
33 	unsigned long max_frequency;
34 };
35 
36 struct tegra_pwm_chip {
37 	struct pwm_chip chip;
38 	struct device *dev;
39 
40 	struct clk *clk;
41 	struct reset_control*rst;
42 
43 	unsigned long clk_rate;
44 
45 	void __iomem *regs;
46 
47 	const struct tegra_pwm_soc *soc;
48 };
49 
to_tegra_pwm_chip(struct pwm_chip * chip)50 static inline struct tegra_pwm_chip *to_tegra_pwm_chip(struct pwm_chip *chip)
51 {
52 	return container_of(chip, struct tegra_pwm_chip, chip);
53 }
54 
pwm_readl(struct tegra_pwm_chip * chip,unsigned int num)55 static inline u32 pwm_readl(struct tegra_pwm_chip *chip, unsigned int num)
56 {
57 	return readl(chip->regs + (num << 4));
58 }
59 
pwm_writel(struct tegra_pwm_chip * chip,unsigned int num,unsigned long val)60 static inline void pwm_writel(struct tegra_pwm_chip *chip, unsigned int num,
61 			     unsigned long val)
62 {
63 	writel(val, chip->regs + (num << 4));
64 }
65 
tegra_pwm_config(struct pwm_chip * chip,struct pwm_device * pwm,int duty_ns,int period_ns)66 static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
67 			    int duty_ns, int period_ns)
68 {
69 	struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
70 	unsigned long long c = duty_ns, hz;
71 	unsigned long rate;
72 	u32 val = 0;
73 	int err;
74 
75 	/*
76 	 * Convert from duty_ns / period_ns to a fixed number of duty ticks
77 	 * per (1 << PWM_DUTY_WIDTH) cycles and make sure to round to the
78 	 * nearest integer during division.
79 	 */
80 	c *= (1 << PWM_DUTY_WIDTH);
81 	c = DIV_ROUND_CLOSEST_ULL(c, period_ns);
82 
83 	val = (u32)c << PWM_DUTY_SHIFT;
84 
85 	/*
86 	 * Compute the prescaler value for which (1 << PWM_DUTY_WIDTH)
87 	 * cycles at the PWM clock rate will take period_ns nanoseconds.
88 	 */
89 	rate = pc->clk_rate >> PWM_DUTY_WIDTH;
90 
91 	/* Consider precision in PWM_SCALE_WIDTH rate calculation */
92 	hz = DIV_ROUND_CLOSEST_ULL(100ULL * NSEC_PER_SEC, period_ns);
93 	rate = DIV_ROUND_CLOSEST_ULL(100ULL * rate, hz);
94 
95 	/*
96 	 * Since the actual PWM divider is the register's frequency divider
97 	 * field minus 1, we need to decrement to get the correct value to
98 	 * write to the register.
99 	 */
100 	if (rate > 0)
101 		rate--;
102 
103 	/*
104 	 * Make sure that the rate will fit in the register's frequency
105 	 * divider field.
106 	 */
107 	if (rate >> PWM_SCALE_WIDTH)
108 		return -EINVAL;
109 
110 	val |= rate << PWM_SCALE_SHIFT;
111 
112 	/*
113 	 * If the PWM channel is disabled, make sure to turn on the clock
114 	 * before writing the register. Otherwise, keep it enabled.
115 	 */
116 	if (!pwm_is_enabled(pwm)) {
117 		err = clk_prepare_enable(pc->clk);
118 		if (err < 0)
119 			return err;
120 	} else
121 		val |= PWM_ENABLE;
122 
123 	pwm_writel(pc, pwm->hwpwm, val);
124 
125 	/*
126 	 * If the PWM is not enabled, turn the clock off again to save power.
127 	 */
128 	if (!pwm_is_enabled(pwm))
129 		clk_disable_unprepare(pc->clk);
130 
131 	return 0;
132 }
133 
tegra_pwm_enable(struct pwm_chip * chip,struct pwm_device * pwm)134 static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
135 {
136 	struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
137 	int rc = 0;
138 	u32 val;
139 
140 	rc = clk_prepare_enable(pc->clk);
141 	if (rc < 0)
142 		return rc;
143 
144 	val = pwm_readl(pc, pwm->hwpwm);
145 	val |= PWM_ENABLE;
146 	pwm_writel(pc, pwm->hwpwm, val);
147 
148 	return 0;
149 }
150 
tegra_pwm_disable(struct pwm_chip * chip,struct pwm_device * pwm)151 static void tegra_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
152 {
153 	struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
154 	u32 val;
155 
156 	val = pwm_readl(pc, pwm->hwpwm);
157 	val &= ~PWM_ENABLE;
158 	pwm_writel(pc, pwm->hwpwm, val);
159 
160 	clk_disable_unprepare(pc->clk);
161 }
162 
163 static const struct pwm_ops tegra_pwm_ops = {
164 	.config = tegra_pwm_config,
165 	.enable = tegra_pwm_enable,
166 	.disable = tegra_pwm_disable,
167 	.owner = THIS_MODULE,
168 };
169 
tegra_pwm_probe(struct platform_device * pdev)170 static int tegra_pwm_probe(struct platform_device *pdev)
171 {
172 	struct tegra_pwm_chip *pwm;
173 	struct resource *r;
174 	int ret;
175 
176 	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
177 	if (!pwm)
178 		return -ENOMEM;
179 
180 	pwm->soc = of_device_get_match_data(&pdev->dev);
181 	pwm->dev = &pdev->dev;
182 
183 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
184 	pwm->regs = devm_ioremap_resource(&pdev->dev, r);
185 	if (IS_ERR(pwm->regs))
186 		return PTR_ERR(pwm->regs);
187 
188 	platform_set_drvdata(pdev, pwm);
189 
190 	pwm->clk = devm_clk_get(&pdev->dev, NULL);
191 	if (IS_ERR(pwm->clk))
192 		return PTR_ERR(pwm->clk);
193 
194 	/* Set maximum frequency of the IP */
195 	ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
196 	if (ret < 0) {
197 		dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
198 		return ret;
199 	}
200 
201 	/*
202 	 * The requested and configured frequency may differ due to
203 	 * clock register resolutions. Get the configured frequency
204 	 * so that PWM period can be calculated more accurately.
205 	 */
206 	pwm->clk_rate = clk_get_rate(pwm->clk);
207 
208 	pwm->rst = devm_reset_control_get_exclusive(&pdev->dev, "pwm");
209 	if (IS_ERR(pwm->rst)) {
210 		ret = PTR_ERR(pwm->rst);
211 		dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
212 		return ret;
213 	}
214 
215 	reset_control_deassert(pwm->rst);
216 
217 	pwm->chip.dev = &pdev->dev;
218 	pwm->chip.ops = &tegra_pwm_ops;
219 	pwm->chip.base = -1;
220 	pwm->chip.npwm = pwm->soc->num_channels;
221 
222 	ret = pwmchip_add(&pwm->chip);
223 	if (ret < 0) {
224 		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
225 		reset_control_assert(pwm->rst);
226 		return ret;
227 	}
228 
229 	return 0;
230 }
231 
tegra_pwm_remove(struct platform_device * pdev)232 static int tegra_pwm_remove(struct platform_device *pdev)
233 {
234 	struct tegra_pwm_chip *pc = platform_get_drvdata(pdev);
235 	unsigned int i;
236 	int err;
237 
238 	if (WARN_ON(!pc))
239 		return -ENODEV;
240 
241 	err = clk_prepare_enable(pc->clk);
242 	if (err < 0)
243 		return err;
244 
245 	for (i = 0; i < pc->chip.npwm; i++) {
246 		struct pwm_device *pwm = &pc->chip.pwms[i];
247 
248 		if (!pwm_is_enabled(pwm))
249 			if (clk_prepare_enable(pc->clk) < 0)
250 				continue;
251 
252 		pwm_writel(pc, i, 0);
253 
254 		clk_disable_unprepare(pc->clk);
255 	}
256 
257 	reset_control_assert(pc->rst);
258 	clk_disable_unprepare(pc->clk);
259 
260 	return pwmchip_remove(&pc->chip);
261 }
262 
263 #ifdef CONFIG_PM_SLEEP
tegra_pwm_suspend(struct device * dev)264 static int tegra_pwm_suspend(struct device *dev)
265 {
266 	return pinctrl_pm_select_sleep_state(dev);
267 }
268 
tegra_pwm_resume(struct device * dev)269 static int tegra_pwm_resume(struct device *dev)
270 {
271 	return pinctrl_pm_select_default_state(dev);
272 }
273 #endif
274 
275 static const struct tegra_pwm_soc tegra20_pwm_soc = {
276 	.num_channels = 4,
277 	.max_frequency = 48000000UL,
278 };
279 
280 static const struct tegra_pwm_soc tegra186_pwm_soc = {
281 	.num_channels = 1,
282 	.max_frequency = 102000000UL,
283 };
284 
285 static const struct of_device_id tegra_pwm_of_match[] = {
286 	{ .compatible = "nvidia,tegra20-pwm", .data = &tegra20_pwm_soc },
287 	{ .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc },
288 	{ }
289 };
290 MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
291 
292 static const struct dev_pm_ops tegra_pwm_pm_ops = {
293 	SET_SYSTEM_SLEEP_PM_OPS(tegra_pwm_suspend, tegra_pwm_resume)
294 };
295 
296 static struct platform_driver tegra_pwm_driver = {
297 	.driver = {
298 		.name = "tegra-pwm",
299 		.of_match_table = tegra_pwm_of_match,
300 		.pm = &tegra_pwm_pm_ops,
301 	},
302 	.probe = tegra_pwm_probe,
303 	.remove = tegra_pwm_remove,
304 };
305 
306 module_platform_driver(tegra_pwm_driver);
307 
308 MODULE_LICENSE("GPL");
309 MODULE_AUTHOR("NVIDIA Corporation");
310 MODULE_ALIAS("platform:tegra-pwm");
311