hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/pwm/pwm-jz4740.c
....@@ -1,34 +1,32 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
34 * JZ4740 platform PWM support
45 *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms of the GNU General Public License as published by the
7
- * Free Software Foundation; either version 2 of the License, or (at your
8
- * option) any later version.
9
- *
10
- * You should have received a copy of the GNU General Public License along
11
- * with this program; if not, write to the Free Software Foundation, Inc.,
12
- * 675 Mass Ave, Cambridge, MA 02139, USA.
13
- *
6
+ * Limitations:
7
+ * - The .apply callback doesn't complete the currently running period before
8
+ * reconfiguring the hardware.
149 */
1510
1611 #include <linux/clk.h>
1712 #include <linux/err.h>
1813 #include <linux/gpio.h>
1914 #include <linux/kernel.h>
15
+#include <linux/mfd/ingenic-tcu.h>
16
+#include <linux/mfd/syscon.h>
2017 #include <linux/module.h>
2118 #include <linux/of_device.h>
2219 #include <linux/platform_device.h>
2320 #include <linux/pwm.h>
21
+#include <linux/regmap.h>
2422
25
-#include <asm/mach-jz4740/timer.h>
26
-
27
-#define NUM_PWM 8
23
+struct soc_info {
24
+ unsigned int num_pwms;
25
+};
2826
2927 struct jz4740_pwm_chip {
3028 struct pwm_chip chip;
31
- struct clk *clk;
29
+ struct regmap *map;
3230 };
3331
3432 static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
....@@ -36,144 +34,216 @@
3634 return container_of(chip, struct jz4740_pwm_chip, chip);
3735 }
3836
37
+static bool jz4740_pwm_can_use_chn(struct jz4740_pwm_chip *jz,
38
+ unsigned int channel)
39
+{
40
+ /* Enable all TCU channels for PWM use by default except channels 0/1 */
41
+ u32 pwm_channels_mask = GENMASK(jz->chip.npwm - 1, 2);
42
+
43
+ device_property_read_u32(jz->chip.dev->parent,
44
+ "ingenic,pwm-channels-mask",
45
+ &pwm_channels_mask);
46
+
47
+ return !!(pwm_channels_mask & BIT(channel));
48
+}
49
+
3950 static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
4051 {
41
- /*
42
- * Timers 0 and 1 are used for system tasks, so they are unavailable
43
- * for use as PWMs.
44
- */
45
- if (pwm->hwpwm < 2)
52
+ struct jz4740_pwm_chip *jz = to_jz4740(chip);
53
+ struct clk *clk;
54
+ char name[16];
55
+ int err;
56
+
57
+ if (!jz4740_pwm_can_use_chn(jz, pwm->hwpwm))
4658 return -EBUSY;
4759
48
- jz4740_timer_start(pwm->hwpwm);
60
+ snprintf(name, sizeof(name), "timer%u", pwm->hwpwm);
61
+
62
+ clk = clk_get(chip->dev, name);
63
+ if (IS_ERR(clk))
64
+ return dev_err_probe(chip->dev, PTR_ERR(clk),
65
+ "Failed to get clock\n");
66
+
67
+ err = clk_prepare_enable(clk);
68
+ if (err < 0) {
69
+ clk_put(clk);
70
+ return err;
71
+ }
72
+
73
+ pwm_set_chip_data(pwm, clk);
4974
5075 return 0;
5176 }
5277
5378 static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
5479 {
55
- jz4740_timer_set_ctrl(pwm->hwpwm, 0);
80
+ struct clk *clk = pwm_get_chip_data(pwm);
5681
57
- jz4740_timer_stop(pwm->hwpwm);
82
+ clk_disable_unprepare(clk);
83
+ clk_put(clk);
5884 }
5985
6086 static int jz4740_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
6187 {
62
- uint32_t ctrl = jz4740_timer_get_ctrl(pwm->pwm);
88
+ struct jz4740_pwm_chip *jz = to_jz4740(chip);
6389
64
- ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
65
- jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
66
- jz4740_timer_enable(pwm->hwpwm);
90
+ /* Enable PWM output */
91
+ regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
92
+ TCU_TCSR_PWM_EN, TCU_TCSR_PWM_EN);
93
+
94
+ /* Start counter */
95
+ regmap_write(jz->map, TCU_REG_TESR, BIT(pwm->hwpwm));
6796
6897 return 0;
6998 }
7099
71100 static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
72101 {
73
- uint32_t ctrl = jz4740_timer_get_ctrl(pwm->hwpwm);
102
+ struct jz4740_pwm_chip *jz = to_jz4740(chip);
74103
75
- /* Disable PWM output.
104
+ /*
105
+ * Set duty > period. This trick allows the TCU channels in TCU2 mode to
106
+ * properly return to their init level.
107
+ */
108
+ regmap_write(jz->map, TCU_REG_TDHRc(pwm->hwpwm), 0xffff);
109
+ regmap_write(jz->map, TCU_REG_TDFRc(pwm->hwpwm), 0x0);
110
+
111
+ /*
112
+ * Disable PWM output.
76113 * In TCU2 mode (channel 1/2 on JZ4750+), this must be done before the
77114 * counter is stopped, while in TCU1 mode the order does not matter.
78115 */
79
- ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
80
- jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
116
+ regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
117
+ TCU_TCSR_PWM_EN, 0);
81118
82119 /* Stop counter */
83
- jz4740_timer_disable(pwm->hwpwm);
120
+ regmap_write(jz->map, TCU_REG_TECR, BIT(pwm->hwpwm));
84121 }
85122
86
-static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
87
- int duty_ns, int period_ns)
123
+static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
124
+ const struct pwm_state *state)
88125 {
89126 struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
90
- unsigned long long tmp;
127
+ unsigned long long tmp = 0xffffull * NSEC_PER_SEC;
128
+ struct clk *clk = pwm_get_chip_data(pwm);
91129 unsigned long period, duty;
92
- unsigned int prescaler = 0;
93
- uint16_t ctrl;
94
- bool is_enabled;
130
+ long rate;
131
+ int err;
95132
96
- tmp = (unsigned long long)clk_get_rate(jz4740->clk) * period_ns;
97
- do_div(tmp, 1000000000);
98
- period = tmp;
133
+ /*
134
+ * Limit the clock to a maximum rate that still gives us a period value
135
+ * which fits in 16 bits.
136
+ */
137
+ do_div(tmp, state->period);
99138
100
- while (period > 0xffff && prescaler < 6) {
101
- period >>= 2;
102
- ++prescaler;
139
+ /*
140
+ * /!\ IMPORTANT NOTE:
141
+ * -------------------
142
+ * This code relies on the fact that clk_round_rate() will always round
143
+ * down, which is not a valid assumption given by the clk API, but only
144
+ * happens to be true with the clk drivers used for Ingenic SoCs.
145
+ *
146
+ * Right now, there is no alternative as the clk API does not have a
147
+ * round-down function (and won't have one for a while), but if it ever
148
+ * comes to light, a round-down function should be used instead.
149
+ */
150
+ rate = clk_round_rate(clk, tmp);
151
+ if (rate < 0) {
152
+ dev_err(chip->dev, "Unable to round rate: %ld", rate);
153
+ return rate;
103154 }
104155
105
- if (prescaler == 6)
106
- return -EINVAL;
156
+ /* Calculate period value */
157
+ tmp = (unsigned long long)rate * state->period;
158
+ do_div(tmp, NSEC_PER_SEC);
159
+ period = tmp;
107160
108
- tmp = (unsigned long long)period * duty_ns;
109
- do_div(tmp, period_ns);
110
- duty = period - tmp;
161
+ /* Calculate duty value */
162
+ tmp = (unsigned long long)rate * state->duty_cycle;
163
+ do_div(tmp, NSEC_PER_SEC);
164
+ duty = tmp;
111165
112166 if (duty >= period)
113167 duty = period - 1;
114168
115
- is_enabled = jz4740_timer_is_enabled(pwm->hwpwm);
116
- if (is_enabled)
117
- jz4740_pwm_disable(chip, pwm);
169
+ jz4740_pwm_disable(chip, pwm);
118170
119
- jz4740_timer_set_count(pwm->hwpwm, 0);
120
- jz4740_timer_set_duty(pwm->hwpwm, duty);
121
- jz4740_timer_set_period(pwm->hwpwm, period);
122
-
123
- ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
124
- JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
125
-
126
- jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
127
-
128
- if (is_enabled)
129
- jz4740_pwm_enable(chip, pwm);
130
-
131
- return 0;
132
-}
133
-
134
-static int jz4740_pwm_set_polarity(struct pwm_chip *chip,
135
- struct pwm_device *pwm, enum pwm_polarity polarity)
136
-{
137
- uint32_t ctrl = jz4740_timer_get_ctrl(pwm->pwm);
138
-
139
- switch (polarity) {
140
- case PWM_POLARITY_NORMAL:
141
- ctrl &= ~JZ_TIMER_CTRL_PWM_ACTIVE_LOW;
142
- break;
143
- case PWM_POLARITY_INVERSED:
144
- ctrl |= JZ_TIMER_CTRL_PWM_ACTIVE_LOW;
145
- break;
171
+ err = clk_set_rate(clk, rate);
172
+ if (err) {
173
+ dev_err(chip->dev, "Unable to set rate: %d", err);
174
+ return err;
146175 }
147176
148
- jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
177
+ /* Reset counter to 0 */
178
+ regmap_write(jz4740->map, TCU_REG_TCNTc(pwm->hwpwm), 0);
179
+
180
+ /* Set duty */
181
+ regmap_write(jz4740->map, TCU_REG_TDHRc(pwm->hwpwm), duty);
182
+
183
+ /* Set period */
184
+ regmap_write(jz4740->map, TCU_REG_TDFRc(pwm->hwpwm), period);
185
+
186
+ /* Set abrupt shutdown */
187
+ regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
188
+ TCU_TCSR_PWM_SD, TCU_TCSR_PWM_SD);
189
+
190
+ /*
191
+ * Set polarity.
192
+ *
193
+ * The PWM starts in inactive state until the internal timer reaches the
194
+ * duty value, then becomes active until the timer reaches the period
195
+ * value. In theory, we should then use (period - duty) as the real duty
196
+ * value, as a high duty value would otherwise result in the PWM pin
197
+ * being inactive most of the time.
198
+ *
199
+ * Here, we don't do that, and instead invert the polarity of the PWM
200
+ * when it is active. This trick makes the PWM start with its active
201
+ * state instead of its inactive state.
202
+ */
203
+ if ((state->polarity == PWM_POLARITY_NORMAL) ^ state->enabled)
204
+ regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
205
+ TCU_TCSR_PWM_INITL_HIGH, 0);
206
+ else
207
+ regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
208
+ TCU_TCSR_PWM_INITL_HIGH,
209
+ TCU_TCSR_PWM_INITL_HIGH);
210
+
211
+ if (state->enabled)
212
+ jz4740_pwm_enable(chip, pwm);
213
+
149214 return 0;
150215 }
151216
152217 static const struct pwm_ops jz4740_pwm_ops = {
153218 .request = jz4740_pwm_request,
154219 .free = jz4740_pwm_free,
155
- .config = jz4740_pwm_config,
156
- .set_polarity = jz4740_pwm_set_polarity,
157
- .enable = jz4740_pwm_enable,
158
- .disable = jz4740_pwm_disable,
220
+ .apply = jz4740_pwm_apply,
159221 .owner = THIS_MODULE,
160222 };
161223
162224 static int jz4740_pwm_probe(struct platform_device *pdev)
163225 {
226
+ struct device *dev = &pdev->dev;
164227 struct jz4740_pwm_chip *jz4740;
228
+ const struct soc_info *info;
165229
166
- jz4740 = devm_kzalloc(&pdev->dev, sizeof(*jz4740), GFP_KERNEL);
230
+ info = device_get_match_data(dev);
231
+ if (!info)
232
+ return -EINVAL;
233
+
234
+ jz4740 = devm_kzalloc(dev, sizeof(*jz4740), GFP_KERNEL);
167235 if (!jz4740)
168236 return -ENOMEM;
169237
170
- jz4740->clk = devm_clk_get(&pdev->dev, "ext");
171
- if (IS_ERR(jz4740->clk))
172
- return PTR_ERR(jz4740->clk);
238
+ jz4740->map = device_node_to_regmap(dev->parent->of_node);
239
+ if (IS_ERR(jz4740->map)) {
240
+ dev_err(dev, "regmap not found: %ld\n", PTR_ERR(jz4740->map));
241
+ return PTR_ERR(jz4740->map);
242
+ }
173243
174
- jz4740->chip.dev = &pdev->dev;
244
+ jz4740->chip.dev = dev;
175245 jz4740->chip.ops = &jz4740_pwm_ops;
176
- jz4740->chip.npwm = NUM_PWM;
246
+ jz4740->chip.npwm = info->num_pwms;
177247 jz4740->chip.base = -1;
178248 jz4740->chip.of_xlate = of_pwm_xlate_with_flags;
179249 jz4740->chip.of_pwm_n_cells = 3;
....@@ -190,11 +260,18 @@
190260 return pwmchip_remove(&jz4740->chip);
191261 }
192262
263
+static const struct soc_info __maybe_unused jz4740_soc_info = {
264
+ .num_pwms = 8,
265
+};
266
+
267
+static const struct soc_info __maybe_unused jz4725b_soc_info = {
268
+ .num_pwms = 6,
269
+};
270
+
193271 #ifdef CONFIG_OF
194272 static const struct of_device_id jz4740_pwm_dt_ids[] = {
195
- { .compatible = "ingenic,jz4740-pwm", },
196
- { .compatible = "ingenic,jz4770-pwm", },
197
- { .compatible = "ingenic,jz4780-pwm", },
273
+ { .compatible = "ingenic,jz4740-pwm", .data = &jz4740_soc_info },
274
+ { .compatible = "ingenic,jz4725b-pwm", .data = &jz4725b_soc_info },
198275 {},
199276 };
200277 MODULE_DEVICE_TABLE(of, jz4740_pwm_dt_ids);