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