Skip to content

Commit 1031c2b

Browse files
jbrun3tUwe Kleine-König
authored andcommitted
pwm: meson: Add generic compatible for meson8 to sm1
Introduce a new compatible support in the Amlogic PWM driver. The PWM HW is actually the same for all SoCs supported so far. A specific compatible is needed only because the clock sources of the PWMs are hard-coded in the driver. It is better to have the clock source described in DT but this changes the bindings so a new compatible must be introduced. When all supported platform have migrated to the new compatible, support for the legacy ones may be removed from the driver. The addition of this new compatible makes the old ones obsolete, as described in the DT documentation. Adding a callback to setup the clock will also make it easier to add support for the new PWM HW found in a1, s4, c3 and t7 SoC families. Signed-off-by: Jerome Brunet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Uwe Kleine-König <[email protected]>
1 parent 141a850 commit 1031c2b

File tree

1 file changed

+121
-74
lines changed

1 file changed

+121
-74
lines changed

drivers/pwm/pwm-meson.c

Lines changed: 121 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ struct meson_pwm_channel {
9898

9999
struct meson_pwm_data {
100100
const char *const parent_names[MESON_NUM_MUX_PARENTS];
101+
int (*channels_init)(struct pwm_chip *chip);
101102
};
102103

103104
struct meson_pwm {
@@ -338,86 +339,16 @@ static const struct pwm_ops meson_pwm_ops = {
338339
.get_state = meson_pwm_get_state,
339340
};
340341

341-
static const struct meson_pwm_data pwm_meson8b_data = {
342-
.parent_names = { "xtal", NULL, "fclk_div4", "fclk_div3" },
343-
};
344-
345-
/*
346-
* Only the 2 first inputs of the GXBB AO PWMs are valid
347-
* The last 2 are grounded
348-
*/
349-
static const struct meson_pwm_data pwm_gxbb_ao_data = {
350-
.parent_names = { "xtal", "clk81", NULL, NULL },
351-
};
352-
353-
static const struct meson_pwm_data pwm_axg_ee_data = {
354-
.parent_names = { "xtal", "fclk_div5", "fclk_div4", "fclk_div3" },
355-
};
356-
357-
static const struct meson_pwm_data pwm_axg_ao_data = {
358-
.parent_names = { "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" },
359-
};
360-
361-
static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
362-
.parent_names = { "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" },
363-
};
364-
365-
static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
366-
.parent_names = { "xtal", "g12a_ao_clk81", NULL, NULL },
367-
};
368-
369-
static const struct of_device_id meson_pwm_matches[] = {
370-
{
371-
.compatible = "amlogic,meson8b-pwm",
372-
.data = &pwm_meson8b_data
373-
},
374-
{
375-
.compatible = "amlogic,meson-gxbb-pwm",
376-
.data = &pwm_meson8b_data
377-
},
378-
{
379-
.compatible = "amlogic,meson-gxbb-ao-pwm",
380-
.data = &pwm_gxbb_ao_data
381-
},
382-
{
383-
.compatible = "amlogic,meson-axg-ee-pwm",
384-
.data = &pwm_axg_ee_data
385-
},
386-
{
387-
.compatible = "amlogic,meson-axg-ao-pwm",
388-
.data = &pwm_axg_ao_data
389-
},
390-
{
391-
.compatible = "amlogic,meson-g12a-ee-pwm",
392-
.data = &pwm_meson8b_data
393-
},
394-
{
395-
.compatible = "amlogic,meson-g12a-ao-pwm-ab",
396-
.data = &pwm_g12a_ao_ab_data
397-
},
398-
{
399-
.compatible = "amlogic,meson-g12a-ao-pwm-cd",
400-
.data = &pwm_g12a_ao_cd_data
401-
},
402-
{},
403-
};
404-
MODULE_DEVICE_TABLE(of, meson_pwm_matches);
405-
406-
static int meson_pwm_init_channels(struct pwm_chip *chip)
342+
static int meson_pwm_init_clocks_meson8b(struct pwm_chip *chip,
343+
struct clk_parent_data *mux_parent_data)
407344
{
408345
struct meson_pwm *meson = to_meson_pwm(chip);
409-
struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
410346
struct device *dev = pwmchip_parent(chip);
411347
unsigned int i;
412348
char name[255];
413349
int err;
414350

415-
for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) {
416-
mux_parent_data[i].index = -1;
417-
mux_parent_data[i].name = meson->data->parent_names[i];
418-
}
419-
420-
for (i = 0; i < chip->npwm; i++) {
351+
for (i = 0; i < MESON_NUM_PWMS; i++) {
421352
struct meson_pwm_channel *channel = &meson->channels[i];
422353
struct clk_parent_data div_parent = {}, gate_parent = {};
423354
struct clk_init_data init = {};
@@ -495,6 +426,122 @@ static int meson_pwm_init_channels(struct pwm_chip *chip)
495426
return 0;
496427
}
497428

429+
static int meson_pwm_init_channels_meson8b_legacy(struct pwm_chip *chip)
430+
{
431+
struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
432+
struct meson_pwm *meson = to_meson_pwm(chip);
433+
int i;
434+
435+
dev_warn_once(pwmchip_parent(chip),
436+
"using obsolete compatible, please consider updating dt\n");
437+
438+
for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) {
439+
mux_parent_data[i].index = -1;
440+
mux_parent_data[i].name = meson->data->parent_names[i];
441+
}
442+
443+
return meson_pwm_init_clocks_meson8b(chip, mux_parent_data);
444+
}
445+
446+
static int meson_pwm_init_channels_meson8b_v2(struct pwm_chip *chip)
447+
{
448+
struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
449+
int i;
450+
451+
/*
452+
* NOTE: Instead of relying on the hard coded names in the driver
453+
* as the legacy version, this relies on DT to provide the list of
454+
* clocks.
455+
* For once, using input numbers actually makes more sense than names.
456+
* Also DT requires clock-names to be explicitly ordered, so there is
457+
* no point bothering with clock names in this case.
458+
*/
459+
for (i = 0; i < MESON_NUM_MUX_PARENTS; i++)
460+
mux_parent_data[i].index = i;
461+
462+
return meson_pwm_init_clocks_meson8b(chip, mux_parent_data);
463+
}
464+
465+
static const struct meson_pwm_data pwm_meson8b_data = {
466+
.parent_names = { "xtal", NULL, "fclk_div4", "fclk_div3" },
467+
.channels_init = meson_pwm_init_channels_meson8b_legacy,
468+
};
469+
470+
/*
471+
* Only the 2 first inputs of the GXBB AO PWMs are valid
472+
* The last 2 are grounded
473+
*/
474+
static const struct meson_pwm_data pwm_gxbb_ao_data = {
475+
.parent_names = { "xtal", "clk81", NULL, NULL },
476+
.channels_init = meson_pwm_init_channels_meson8b_legacy,
477+
};
478+
479+
static const struct meson_pwm_data pwm_axg_ee_data = {
480+
.parent_names = { "xtal", "fclk_div5", "fclk_div4", "fclk_div3" },
481+
.channels_init = meson_pwm_init_channels_meson8b_legacy,
482+
};
483+
484+
static const struct meson_pwm_data pwm_axg_ao_data = {
485+
.parent_names = { "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" },
486+
.channels_init = meson_pwm_init_channels_meson8b_legacy,
487+
};
488+
489+
static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
490+
.parent_names = { "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" },
491+
.channels_init = meson_pwm_init_channels_meson8b_legacy,
492+
};
493+
494+
static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
495+
.parent_names = { "xtal", "g12a_ao_clk81", NULL, NULL },
496+
.channels_init = meson_pwm_init_channels_meson8b_legacy,
497+
};
498+
499+
static const struct meson_pwm_data pwm_meson8_v2_data = {
500+
.channels_init = meson_pwm_init_channels_meson8b_v2,
501+
};
502+
503+
static const struct of_device_id meson_pwm_matches[] = {
504+
{
505+
.compatible = "amlogic,meson8-pwm-v2",
506+
.data = &pwm_meson8_v2_data
507+
},
508+
/* The following compatibles are obsolete */
509+
{
510+
.compatible = "amlogic,meson8b-pwm",
511+
.data = &pwm_meson8b_data
512+
},
513+
{
514+
.compatible = "amlogic,meson-gxbb-pwm",
515+
.data = &pwm_meson8b_data
516+
},
517+
{
518+
.compatible = "amlogic,meson-gxbb-ao-pwm",
519+
.data = &pwm_gxbb_ao_data
520+
},
521+
{
522+
.compatible = "amlogic,meson-axg-ee-pwm",
523+
.data = &pwm_axg_ee_data
524+
},
525+
{
526+
.compatible = "amlogic,meson-axg-ao-pwm",
527+
.data = &pwm_axg_ao_data
528+
},
529+
{
530+
.compatible = "amlogic,meson-g12a-ee-pwm",
531+
.data = &pwm_meson8b_data
532+
},
533+
{
534+
.compatible = "amlogic,meson-g12a-ao-pwm-ab",
535+
.data = &pwm_g12a_ao_ab_data
536+
},
537+
{
538+
.compatible = "amlogic,meson-g12a-ao-pwm-cd",
539+
.data = &pwm_g12a_ao_cd_data
540+
},
541+
{},
542+
};
543+
MODULE_DEVICE_TABLE(of, meson_pwm_matches);
544+
498545
static int meson_pwm_probe(struct platform_device *pdev)
499546
{
500547
struct pwm_chip *chip;
@@ -515,7 +562,7 @@ static int meson_pwm_probe(struct platform_device *pdev)
515562

516563
meson->data = of_device_get_match_data(&pdev->dev);
517564

518-
err = meson_pwm_init_channels(chip);
565+
err = meson->data->channels_init(chip);
519566
if (err < 0)
520567
return err;
521568

0 commit comments

Comments
 (0)