Merge tag 'pm-6.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[linux-block.git] / drivers / pwm / pwm-meson.c
CommitLineData
1cdb4413 1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
211ed630 2/*
4ae42ce7
MB
3 * PWM controller driver for Amlogic Meson SoCs.
4 *
5 * This PWM is only a set of Gates, Dividers and Counters:
6 * PWM output is achieved by calculating a clock that permits calculating
7 * two periods (low and high). The counter then has to be set to switch after
8 * N cycles for the first half period.
dd4d280a 9 * Partly the hardware has no "polarity" setting. This driver reverses the period
4ae42ce7
MB
10 * cycles (the low length is inverted with the high length) for
11 * PWM_POLARITY_INVERSED. This means that .get_state cannot read the polarity
12 * from the hardware.
13 * Setting the duty cycle will disable and re-enable the PWM output.
14 * Disabling the PWM stops the output immediately (without waiting for the
15 * current period to complete first).
16 *
17 * The public S912 (GXM) datasheet contains some documentation for this PWM
18 * controller starting on page 543:
19 * https://dl.khadas.com/Hardware/VIM2/Datasheet/S912_Datasheet_V0.220170314publicversion-Wesion.pdf
20 * An updated version of this IP block is found in S922X (G12B) SoCs. The
21 * datasheet contains the description for this IP block revision starting at
22 * page 1084:
23 * https://dn.odroid.com/S922X/ODROID-N2/Datasheet/S922X_Public_Datasheet_V0.2.pdf
24 *
211ed630
NA
25 * Copyright (c) 2016 BayLibre, SAS.
26 * Author: Neil Armstrong <narmstrong@baylibre.com>
27 * Copyright (C) 2014 Amlogic, Inc.
211ed630
NA
28 */
29
181164b6
MB
30#include <linux/bitfield.h>
31#include <linux/bits.h>
211ed630
NA
32#include <linux/clk.h>
33#include <linux/clk-provider.h>
34#include <linux/err.h>
35#include <linux/io.h>
36#include <linux/kernel.h>
fb2081e8 37#include <linux/math64.h>
211ed630
NA
38#include <linux/module.h>
39#include <linux/of.h>
211ed630
NA
40#include <linux/platform_device.h>
41#include <linux/pwm.h>
42#include <linux/slab.h>
43#include <linux/spinlock.h>
44
45#define REG_PWM_A 0x0
46#define REG_PWM_B 0x4
181164b6
MB
47#define PWM_LOW_MASK GENMASK(15, 0)
48#define PWM_HIGH_MASK GENMASK(31, 16)
211ed630
NA
49
50#define REG_MISC_AB 0x8
329db102
HK
51#define MISC_B_CLK_EN_SHIFT 23
52#define MISC_A_CLK_EN_SHIFT 15
53#define MISC_CLK_DIV_WIDTH 7
211ed630
NA
54#define MISC_B_CLK_DIV_SHIFT 16
55#define MISC_A_CLK_DIV_SHIFT 8
56#define MISC_B_CLK_SEL_SHIFT 6
57#define MISC_A_CLK_SEL_SHIFT 4
33cefd84 58#define MISC_CLK_SEL_MASK 0x3
dd4d280a
GS
59#define MISC_B_CONSTANT_EN BIT(29)
60#define MISC_A_CONSTANT_EN BIT(28)
61#define MISC_B_INVERT_EN BIT(27)
62#define MISC_A_INVERT_EN BIT(26)
211ed630
NA
63#define MISC_B_EN BIT(1)
64#define MISC_A_EN BIT(0)
65
a50a49a4 66#define MESON_NUM_PWMS 2
f2cea1dc 67#define MESON_NUM_MUX_PARENTS 4
a50a49a4 68
8bbf3164
MB
69static struct meson_pwm_channel_data {
70 u8 reg_offset;
71 u8 clk_sel_shift;
72 u8 clk_div_shift;
329db102 73 u8 clk_en_shift;
8bbf3164 74 u32 pwm_en_mask;
dd4d280a
GS
75 u32 const_en_mask;
76 u32 inv_en_mask;
8bbf3164
MB
77} meson_pwm_per_channel_data[MESON_NUM_PWMS] = {
78 {
79 .reg_offset = REG_PWM_A,
80 .clk_sel_shift = MISC_A_CLK_SEL_SHIFT,
81 .clk_div_shift = MISC_A_CLK_DIV_SHIFT,
329db102 82 .clk_en_shift = MISC_A_CLK_EN_SHIFT,
8bbf3164 83 .pwm_en_mask = MISC_A_EN,
dd4d280a
GS
84 .const_en_mask = MISC_A_CONSTANT_EN,
85 .inv_en_mask = MISC_A_INVERT_EN,
8bbf3164
MB
86 },
87 {
88 .reg_offset = REG_PWM_B,
89 .clk_sel_shift = MISC_B_CLK_SEL_SHIFT,
90 .clk_div_shift = MISC_B_CLK_DIV_SHIFT,
329db102 91 .clk_en_shift = MISC_B_CLK_EN_SHIFT,
8bbf3164 92 .pwm_en_mask = MISC_B_EN,
dd4d280a
GS
93 .const_en_mask = MISC_B_CONSTANT_EN,
94 .inv_en_mask = MISC_B_INVERT_EN,
8bbf3164 95 }
211ed630
NA
96};
97
98struct meson_pwm_channel {
329db102 99 unsigned long rate;
211ed630
NA
100 unsigned int hi;
101 unsigned int lo;
dd4d280a
GS
102 bool constant;
103 bool inverted;
211ed630 104
211ed630 105 struct clk_mux mux;
329db102
HK
106 struct clk_divider div;
107 struct clk_gate gate;
211ed630
NA
108 struct clk *clk;
109};
110
111struct meson_pwm_data {
f2cea1dc 112 const char *const parent_names[MESON_NUM_MUX_PARENTS];
1031c2b4 113 int (*channels_init)(struct pwm_chip *chip);
dd4d280a
GS
114 bool has_constant;
115 bool has_polarity;
211ed630
NA
116};
117
118struct meson_pwm {
211ed630 119 const struct meson_pwm_data *data;
a50a49a4 120 struct meson_pwm_channel channels[MESON_NUM_PWMS];
211ed630 121 void __iomem *base;
f173747f
MB
122 /*
123 * Protects register (write) access to the REG_MISC_AB register
124 * that is shared between the two PWMs.
125 */
211ed630
NA
126 spinlock_t lock;
127};
128
129static inline struct meson_pwm *to_meson_pwm(struct pwm_chip *chip)
130{
28ecf9bd 131 return pwmchip_get_drvdata(chip);
211ed630
NA
132}
133
134static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
135{
1064c6ba 136 struct meson_pwm *meson = to_meson_pwm(chip);
37349609 137 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
e369035a 138 struct device *dev = pwmchip_parent(chip);
211ed630
NA
139 int err;
140
211ed630
NA
141 err = clk_prepare_enable(channel->clk);
142 if (err < 0) {
143 dev_err(dev, "failed to enable clock %s: %d\n",
144 __clk_get_name(channel->clk), err);
145 return err;
146 }
147
5f97f18f 148 return 0;
211ed630
NA
149}
150
151static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
152{
5f97f18f
UKK
153 struct meson_pwm *meson = to_meson_pwm(chip);
154 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
211ed630 155
cb971fdb 156 clk_disable_unprepare(channel->clk);
211ed630
NA
157}
158
b647dcfd 159static int meson_pwm_calc(struct pwm_chip *chip, struct pwm_device *pwm,
71523d18 160 const struct pwm_state *state)
211ed630 161{
b647dcfd 162 struct meson_pwm *meson = to_meson_pwm(chip);
5f97f18f 163 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
329db102 164 unsigned int cnt, duty_cnt;
3e551115 165 long fin_freq;
329db102 166 u64 duty, period, freq;
211ed630 167
b79c3670
MB
168 duty = state->duty_cycle;
169 period = state->period;
170
8caa81eb
UKK
171 /*
172 * Note this is wrong. The result is an output wave that isn't really
173 * inverted and so is wrongly identified by .get_state as normal.
174 * Fixing this needs some care however as some machines might rely on
175 * this.
176 */
dd4d280a 177 if (state->polarity == PWM_POLARITY_INVERSED && !meson->data->has_polarity)
211ed630
NA
178 duty = period - duty;
179
329db102
HK
180 freq = div64_u64(NSEC_PER_SEC * 0xffffULL, period);
181 if (freq > ULONG_MAX)
182 freq = ULONG_MAX;
183
184 fin_freq = clk_round_rate(channel->clk, freq);
3e551115
GS
185 if (fin_freq <= 0) {
186 dev_err(pwmchip_parent(chip),
187 "invalid source clock frequency %llu\n", freq);
188 return fin_freq ? fin_freq : -EINVAL;
211ed630
NA
189 }
190
3e551115 191 dev_dbg(pwmchip_parent(chip), "fin_freq: %ld Hz\n", fin_freq);
211ed630 192
32c44e1f 193 cnt = mul_u64_u64_div_u64(fin_freq, period, NSEC_PER_SEC);
fb2081e8 194 if (cnt > 0xffff) {
e369035a 195 dev_err(pwmchip_parent(chip), "unable to get period cnt\n");
fb2081e8
MB
196 return -EINVAL;
197 }
198
e369035a 199 dev_dbg(pwmchip_parent(chip), "period=%llu cnt=%u\n", period, cnt);
211ed630
NA
200
201 if (duty == period) {
211ed630
NA
202 channel->hi = cnt;
203 channel->lo = 0;
dd4d280a 204 channel->constant = true;
211ed630 205 } else if (duty == 0) {
211ed630
NA
206 channel->hi = 0;
207 channel->lo = cnt;
dd4d280a 208 channel->constant = true;
211ed630 209 } else {
32c44e1f 210 duty_cnt = mul_u64_u64_div_u64(fin_freq, duty, NSEC_PER_SEC);
211ed630 211
e369035a 212 dev_dbg(pwmchip_parent(chip), "duty=%llu duty_cnt=%u\n", duty, duty_cnt);
211ed630 213
211ed630
NA
214 channel->hi = duty_cnt;
215 channel->lo = cnt - duty_cnt;
dd4d280a 216 channel->constant = false;
211ed630
NA
217 }
218
329db102
HK
219 channel->rate = fin_freq;
220
211ed630
NA
221 return 0;
222}
223
b647dcfd 224static void meson_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
211ed630 225{
b647dcfd 226 struct meson_pwm *meson = to_meson_pwm(chip);
5f97f18f 227 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
8bbf3164 228 struct meson_pwm_channel_data *channel_data;
f173747f 229 unsigned long flags;
8bbf3164 230 u32 value;
329db102 231 int err;
211ed630 232
8bbf3164 233 channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
211ed630 234
329db102
HK
235 err = clk_set_rate(channel->clk, channel->rate);
236 if (err)
e369035a 237 dev_err(pwmchip_parent(chip), "setting clock rate failed\n");
f173747f 238
329db102 239 spin_lock_irqsave(&meson->lock, flags);
211ed630 240
181164b6
MB
241 value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
242 FIELD_PREP(PWM_LOW_MASK, channel->lo);
8bbf3164 243 writel(value, meson->base + channel_data->reg_offset);
211ed630
NA
244
245 value = readl(meson->base + REG_MISC_AB);
8bbf3164 246 value |= channel_data->pwm_en_mask;
dd4d280a
GS
247
248 if (meson->data->has_constant) {
249 value &= ~channel_data->const_en_mask;
250 if (channel->constant)
251 value |= channel_data->const_en_mask;
252 }
253
254 if (meson->data->has_polarity) {
255 value &= ~channel_data->inv_en_mask;
256 if (channel->inverted)
257 value |= channel_data->inv_en_mask;
258 }
259
211ed630 260 writel(value, meson->base + REG_MISC_AB);
f173747f
MB
261
262 spin_unlock_irqrestore(&meson->lock, flags);
211ed630
NA
263}
264
b647dcfd 265static void meson_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
211ed630 266{
b647dcfd 267 struct meson_pwm *meson = to_meson_pwm(chip);
dd4d280a
GS
268 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
269 struct meson_pwm_channel_data *channel_data;
f173747f 270 unsigned long flags;
8bbf3164 271 u32 value;
211ed630 272
dd4d280a
GS
273 channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
274
f173747f
MB
275 spin_lock_irqsave(&meson->lock, flags);
276
211ed630 277 value = readl(meson->base + REG_MISC_AB);
dd4d280a
GS
278 value &= ~channel_data->pwm_en_mask;
279
280 if (meson->data->has_polarity) {
281 value &= ~channel_data->inv_en_mask;
282 if (channel->inverted)
283 value |= channel_data->inv_en_mask;
284 }
285
211ed630 286 writel(value, meson->base + REG_MISC_AB);
f173747f
MB
287
288 spin_unlock_irqrestore(&meson->lock, flags);
211ed630
NA
289}
290
291static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
71523d18 292 const struct pwm_state *state)
211ed630 293{
211ed630 294 struct meson_pwm *meson = to_meson_pwm(chip);
5f97f18f 295 struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
211ed630
NA
296 int err = 0;
297
dd4d280a
GS
298 channel->inverted = (state->polarity == PWM_POLARITY_INVERSED);
299
211ed630 300 if (!state->enabled) {
dd4d280a 301 if (channel->inverted && !meson->data->has_polarity) {
7341c785 302 /*
dd4d280a 303 * Some of IP block revisions don't have an "always high"
7341c785 304 * setting which we can use for "inverted disabled".
329db102
HK
305 * Instead we achieve this by setting mux parent with
306 * highest rate and minimum divider value, resulting
307 * in the shortest possible duration for one "count"
308 * and "period == duty_cycle". This results in a signal
7341c785
MB
309 * which is LOW for one "count", while being HIGH for
310 * the rest of the (so the signal is HIGH for slightly
311 * less than 100% of the period, but this is the best
312 * we can achieve).
313 */
329db102 314 channel->rate = ULONG_MAX;
7341c785
MB
315 channel->hi = ~0;
316 channel->lo = 0;
dd4d280a 317 channel->constant = true;
7341c785 318
b647dcfd 319 meson_pwm_enable(chip, pwm);
7341c785 320 } else {
b647dcfd 321 meson_pwm_disable(chip, pwm);
7341c785 322 }
d6885b3e 323 } else {
b647dcfd 324 err = meson_pwm_calc(chip, pwm, state);
211ed630 325 if (err < 0)
f173747f 326 return err;
211ed630 327
b647dcfd 328 meson_pwm_enable(chip, pwm);
211ed630
NA
329 }
330
f173747f 331 return 0;
211ed630
NA
332}
333
08d8c9f5 334static u64 meson_pwm_cnt_to_ns(unsigned long fin_freq, u32 cnt)
c375bcba 335{
08d8c9f5 336 return fin_freq ? div64_ul(NSEC_PER_SEC * (u64)cnt, fin_freq) : 0;
c375bcba
MB
337}
338
6c452cff
UKK
339static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
340 struct pwm_state *state)
211ed630
NA
341{
342 struct meson_pwm *meson = to_meson_pwm(chip);
c375bcba 343 struct meson_pwm_channel_data *channel_data;
08d8c9f5 344 unsigned long fin_freq;
8c22e890 345 unsigned int hi, lo;
329db102 346 u32 value;
211ed630 347
c375bcba 348 channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
08d8c9f5 349 fin_freq = clk_get_rate(meson->channels[pwm->hwpwm].clk);
211ed630
NA
350
351 value = readl(meson->base + REG_MISC_AB);
329db102 352 state->enabled = value & channel_data->pwm_en_mask;
c375bcba 353
dd4d280a
GS
354 if (meson->data->has_polarity && (value & channel_data->inv_en_mask))
355 state->polarity = PWM_POLARITY_INVERSED;
356 else
357 state->polarity = PWM_POLARITY_NORMAL;
358
c375bcba 359 value = readl(meson->base + channel_data->reg_offset);
8c22e890
GS
360 lo = FIELD_GET(PWM_LOW_MASK, value);
361 hi = FIELD_GET(PWM_HIGH_MASK, value);
c375bcba 362
08d8c9f5
GS
363 state->period = meson_pwm_cnt_to_ns(fin_freq, lo + hi);
364 state->duty_cycle = meson_pwm_cnt_to_ns(fin_freq, hi);
6c452cff
UKK
365
366 return 0;
211ed630
NA
367}
368
369static const struct pwm_ops meson_pwm_ops = {
370 .request = meson_pwm_request,
371 .free = meson_pwm_free,
372 .apply = meson_pwm_apply,
373 .get_state = meson_pwm_get_state,
211ed630
NA
374};
375
1031c2b4
JB
376static int meson_pwm_init_clocks_meson8b(struct pwm_chip *chip,
377 struct clk_parent_data *mux_parent_data)
211ed630 378{
b647dcfd 379 struct meson_pwm *meson = to_meson_pwm(chip);
e369035a 380 struct device *dev = pwmchip_parent(chip);
211ed630
NA
381 unsigned int i;
382 char name[255];
383 int err;
384
1031c2b4 385 for (i = 0; i < MESON_NUM_PWMS; i++) {
a50a49a4 386 struct meson_pwm_channel *channel = &meson->channels[i];
329db102 387 struct clk_parent_data div_parent = {}, gate_parent = {};
ed733003 388 struct clk_init_data init = {};
211ed630 389
b96e9eb6 390 snprintf(name, sizeof(name), "%s#mux%u", dev_name(dev), i);
211ed630
NA
391
392 init.name = name;
393 init.ops = &clk_mux_ops;
90b6c5c7 394 init.flags = 0;
ed733003 395 init.parent_data = mux_parent_data;
f2cea1dc 396 init.num_parents = MESON_NUM_MUX_PARENTS;
211ed630
NA
397
398 channel->mux.reg = meson->base + REG_MISC_AB;
8bbf3164
MB
399 channel->mux.shift =
400 meson_pwm_per_channel_data[i].clk_sel_shift;
33cefd84 401 channel->mux.mask = MISC_CLK_SEL_MASK;
211ed630
NA
402 channel->mux.flags = 0;
403 channel->mux.lock = &meson->lock;
404 channel->mux.table = NULL;
405 channel->mux.hw.init = &init;
406
329db102 407 err = devm_clk_hw_register(dev, &channel->mux.hw);
b41ccc3b
UKK
408 if (err)
409 return dev_err_probe(dev, err,
410 "failed to register %s\n", name);
329db102
HK
411
412 snprintf(name, sizeof(name), "%s#div%u", dev_name(dev), i);
413
414 init.name = name;
415 init.ops = &clk_divider_ops;
416 init.flags = CLK_SET_RATE_PARENT;
417 div_parent.index = -1;
418 div_parent.hw = &channel->mux.hw;
419 init.parent_data = &div_parent;
420 init.num_parents = 1;
421
422 channel->div.reg = meson->base + REG_MISC_AB;
423 channel->div.shift = meson_pwm_per_channel_data[i].clk_div_shift;
424 channel->div.width = MISC_CLK_DIV_WIDTH;
425 channel->div.hw.init = &init;
426 channel->div.flags = 0;
427 channel->div.lock = &meson->lock;
428
429 err = devm_clk_hw_register(dev, &channel->div.hw);
b41ccc3b
UKK
430 if (err)
431 return dev_err_probe(dev, err,
432 "failed to register %s\n", name);
211ed630 433
329db102 434 snprintf(name, sizeof(name), "%s#gate%u", dev_name(dev), i);
211ed630 435
329db102
HK
436 init.name = name;
437 init.ops = &clk_gate_ops;
438 init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
439 gate_parent.index = -1;
440 gate_parent.hw = &channel->div.hw;
441 init.parent_data = &gate_parent;
442 init.num_parents = 1;
443
444 channel->gate.reg = meson->base + REG_MISC_AB;
445 channel->gate.bit_idx = meson_pwm_per_channel_data[i].clk_en_shift;
446 channel->gate.hw.init = &init;
447 channel->gate.flags = 0;
448 channel->gate.lock = &meson->lock;
449
450 err = devm_clk_hw_register(dev, &channel->gate.hw);
b41ccc3b
UKK
451 if (err)
452 return dev_err_probe(dev, err, "failed to register %s\n", name);
329db102
HK
453
454 channel->clk = devm_clk_hw_get_clk(dev, &channel->gate.hw, NULL);
b41ccc3b
UKK
455 if (IS_ERR(channel->clk))
456 return dev_err_probe(dev, PTR_ERR(channel->clk),
457 "failed to register %s\n", name);
211ed630
NA
458 }
459
460 return 0;
461}
462
1031c2b4
JB
463static int meson_pwm_init_channels_meson8b_legacy(struct pwm_chip *chip)
464{
465 struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
466 struct meson_pwm *meson = to_meson_pwm(chip);
467 int i;
468
469 dev_warn_once(pwmchip_parent(chip),
470 "using obsolete compatible, please consider updating dt\n");
471
472 for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) {
473 mux_parent_data[i].index = -1;
474 mux_parent_data[i].name = meson->data->parent_names[i];
475 }
476
477 return meson_pwm_init_clocks_meson8b(chip, mux_parent_data);
478}
479
480static int meson_pwm_init_channels_meson8b_v2(struct pwm_chip *chip)
481{
482 struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
483 int i;
484
485 /*
486 * NOTE: Instead of relying on the hard coded names in the driver
487 * as the legacy version, this relies on DT to provide the list of
488 * clocks.
489 * For once, using input numbers actually makes more sense than names.
490 * Also DT requires clock-names to be explicitly ordered, so there is
491 * no point bothering with clock names in this case.
492 */
493 for (i = 0; i < MESON_NUM_MUX_PARENTS; i++)
494 mux_parent_data[i].index = i;
495
496 return meson_pwm_init_clocks_meson8b(chip, mux_parent_data);
497}
498
2ed3284f
JZ
499static void meson_pwm_s4_put_clk(void *data)
500{
501 struct clk *clk = data;
502
503 clk_put(clk);
504}
505
506static int meson_pwm_init_channels_s4(struct pwm_chip *chip)
507{
508 struct device *dev = pwmchip_parent(chip);
509 struct device_node *np = dev->of_node;
510 struct meson_pwm *meson = to_meson_pwm(chip);
511 int i, ret;
512
513 for (i = 0; i < MESON_NUM_PWMS; i++) {
514 meson->channels[i].clk = of_clk_get(np, i);
515 if (IS_ERR(meson->channels[i].clk))
516 return dev_err_probe(dev,
517 PTR_ERR(meson->channels[i].clk),
518 "Failed to get clk\n");
519
520 ret = devm_add_action_or_reset(dev, meson_pwm_s4_put_clk,
521 meson->channels[i].clk);
522 if (ret)
523 return dev_err_probe(dev, ret,
524 "Failed to add clk_put action\n");
525 }
526
527 return 0;
528}
529
1031c2b4
JB
530static const struct meson_pwm_data pwm_meson8b_data = {
531 .parent_names = { "xtal", NULL, "fclk_div4", "fclk_div3" },
532 .channels_init = meson_pwm_init_channels_meson8b_legacy,
533};
534
535/*
536 * Only the 2 first inputs of the GXBB AO PWMs are valid
537 * The last 2 are grounded
538 */
539static const struct meson_pwm_data pwm_gxbb_ao_data = {
540 .parent_names = { "xtal", "clk81", NULL, NULL },
541 .channels_init = meson_pwm_init_channels_meson8b_legacy,
542};
543
544static const struct meson_pwm_data pwm_axg_ee_data = {
545 .parent_names = { "xtal", "fclk_div5", "fclk_div4", "fclk_div3" },
546 .channels_init = meson_pwm_init_channels_meson8b_legacy,
5dca8a93
GS
547 .has_constant = true,
548 .has_polarity = true,
1031c2b4
JB
549};
550
551static const struct meson_pwm_data pwm_axg_ao_data = {
552 .parent_names = { "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" },
553 .channels_init = meson_pwm_init_channels_meson8b_legacy,
5dca8a93
GS
554 .has_constant = true,
555 .has_polarity = true,
1031c2b4
JB
556};
557
3a44aacf
GS
558static const struct meson_pwm_data pwm_g12a_ee_data = {
559 .parent_names = { "xtal", NULL, "fclk_div4", "fclk_div3" },
560 .channels_init = meson_pwm_init_channels_meson8b_legacy,
5dca8a93
GS
561 .has_constant = true,
562 .has_polarity = true,
3a44aacf
GS
563};
564
1031c2b4
JB
565static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
566 .parent_names = { "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" },
567 .channels_init = meson_pwm_init_channels_meson8b_legacy,
5dca8a93
GS
568 .has_constant = true,
569 .has_polarity = true,
1031c2b4
JB
570};
571
572static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
573 .parent_names = { "xtal", "g12a_ao_clk81", NULL, NULL },
574 .channels_init = meson_pwm_init_channels_meson8b_legacy,
5dca8a93
GS
575 .has_constant = true,
576 .has_polarity = true,
1031c2b4
JB
577};
578
579static const struct meson_pwm_data pwm_meson8_v2_data = {
580 .channels_init = meson_pwm_init_channels_meson8b_v2,
581};
582
3a44aacf
GS
583static const struct meson_pwm_data pwm_meson_axg_v2_data = {
584 .channels_init = meson_pwm_init_channels_meson8b_v2,
5dca8a93
GS
585 .has_constant = true,
586 .has_polarity = true,
3a44aacf
GS
587};
588
2ed3284f
JZ
589static const struct meson_pwm_data pwm_s4_data = {
590 .channels_init = meson_pwm_init_channels_s4,
5dca8a93
GS
591 .has_constant = true,
592 .has_polarity = true,
2ed3284f
JZ
593};
594
1031c2b4
JB
595static const struct of_device_id meson_pwm_matches[] = {
596 {
597 .compatible = "amlogic,meson8-pwm-v2",
598 .data = &pwm_meson8_v2_data
599 },
3a44aacf
GS
600 {
601 .compatible = "amlogic,meson-axg-pwm-v2",
602 .data = &pwm_meson_axg_v2_data
603 },
604 {
605 .compatible = "amlogic,meson-g12-pwm-v2",
606 .data = &pwm_meson_axg_v2_data
607 },
1031c2b4
JB
608 /* The following compatibles are obsolete */
609 {
610 .compatible = "amlogic,meson8b-pwm",
611 .data = &pwm_meson8b_data
612 },
613 {
614 .compatible = "amlogic,meson-gxbb-pwm",
615 .data = &pwm_meson8b_data
616 },
617 {
618 .compatible = "amlogic,meson-gxbb-ao-pwm",
619 .data = &pwm_gxbb_ao_data
620 },
621 {
622 .compatible = "amlogic,meson-axg-ee-pwm",
623 .data = &pwm_axg_ee_data
624 },
625 {
626 .compatible = "amlogic,meson-axg-ao-pwm",
627 .data = &pwm_axg_ao_data
628 },
629 {
630 .compatible = "amlogic,meson-g12a-ee-pwm",
3a44aacf 631 .data = &pwm_g12a_ee_data
1031c2b4
JB
632 },
633 {
634 .compatible = "amlogic,meson-g12a-ao-pwm-ab",
635 .data = &pwm_g12a_ao_ab_data
636 },
637 {
638 .compatible = "amlogic,meson-g12a-ao-pwm-cd",
639 .data = &pwm_g12a_ao_cd_data
640 },
2ed3284f
JZ
641 {
642 .compatible = "amlogic,meson-s4-pwm",
643 .data = &pwm_s4_data
644 },
1031c2b4
JB
645 {},
646};
647MODULE_DEVICE_TABLE(of, meson_pwm_matches);
648
211ed630
NA
649static int meson_pwm_probe(struct platform_device *pdev)
650{
28ecf9bd 651 struct pwm_chip *chip;
211ed630 652 struct meson_pwm *meson;
211ed630
NA
653 int err;
654
28ecf9bd
UKK
655 chip = devm_pwmchip_alloc(&pdev->dev, MESON_NUM_PWMS, sizeof(*meson));
656 if (IS_ERR(chip))
657 return PTR_ERR(chip);
658 meson = to_meson_pwm(chip);
211ed630 659
17076b10 660 meson->base = devm_platform_ioremap_resource(pdev, 0);
211ed630
NA
661 if (IS_ERR(meson->base))
662 return PTR_ERR(meson->base);
663
c6999956 664 spin_lock_init(&meson->lock);
28ecf9bd 665 chip->ops = &meson_pwm_ops;
211ed630
NA
666
667 meson->data = of_device_get_match_data(&pdev->dev);
211ed630 668
1031c2b4 669 err = meson->data->channels_init(chip);
211ed630
NA
670 if (err < 0)
671 return err;
672
28ecf9bd 673 err = devm_pwmchip_add(&pdev->dev, chip);
b41ccc3b
UKK
674 if (err < 0)
675 return dev_err_probe(&pdev->dev, err,
676 "failed to register PWM chip\n");
211ed630 677
211ed630
NA
678 return 0;
679}
680
211ed630
NA
681static struct platform_driver meson_pwm_driver = {
682 .driver = {
683 .name = "meson-pwm",
684 .of_match_table = meson_pwm_matches,
685 },
686 .probe = meson_pwm_probe,
211ed630
NA
687};
688module_platform_driver(meson_pwm_driver);
689
211ed630
NA
690MODULE_DESCRIPTION("Amlogic Meson PWM Generator driver");
691MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
692MODULE_LICENSE("Dual BSD/GPL");