struct meson_pwm_data {
        const char *const parent_names[MESON_NUM_MUX_PARENTS];
+       int (*channels_init)(struct pwm_chip *chip);
 };
 
 struct meson_pwm {
        .get_state = meson_pwm_get_state,
 };
 
-static const struct meson_pwm_data pwm_meson8b_data = {
-       .parent_names = { "xtal", NULL, "fclk_div4", "fclk_div3" },
-};
-
-/*
- * Only the 2 first inputs of the GXBB AO PWMs are valid
- * The last 2 are grounded
- */
-static const struct meson_pwm_data pwm_gxbb_ao_data = {
-       .parent_names = { "xtal", "clk81", NULL, NULL },
-};
-
-static const struct meson_pwm_data pwm_axg_ee_data = {
-       .parent_names = { "xtal", "fclk_div5", "fclk_div4", "fclk_div3" },
-};
-
-static const struct meson_pwm_data pwm_axg_ao_data = {
-       .parent_names = { "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" },
-};
-
-static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
-       .parent_names = { "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" },
-};
-
-static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
-       .parent_names = { "xtal", "g12a_ao_clk81", NULL, NULL },
-};
-
-static const struct of_device_id meson_pwm_matches[] = {
-       {
-               .compatible = "amlogic,meson8b-pwm",
-               .data = &pwm_meson8b_data
-       },
-       {
-               .compatible = "amlogic,meson-gxbb-pwm",
-               .data = &pwm_meson8b_data
-       },
-       {
-               .compatible = "amlogic,meson-gxbb-ao-pwm",
-               .data = &pwm_gxbb_ao_data
-       },
-       {
-               .compatible = "amlogic,meson-axg-ee-pwm",
-               .data = &pwm_axg_ee_data
-       },
-       {
-               .compatible = "amlogic,meson-axg-ao-pwm",
-               .data = &pwm_axg_ao_data
-       },
-       {
-               .compatible = "amlogic,meson-g12a-ee-pwm",
-               .data = &pwm_meson8b_data
-       },
-       {
-               .compatible = "amlogic,meson-g12a-ao-pwm-ab",
-               .data = &pwm_g12a_ao_ab_data
-       },
-       {
-               .compatible = "amlogic,meson-g12a-ao-pwm-cd",
-               .data = &pwm_g12a_ao_cd_data
-       },
-       {},
-};
-MODULE_DEVICE_TABLE(of, meson_pwm_matches);
-
-static int meson_pwm_init_channels(struct pwm_chip *chip)
+static int meson_pwm_init_clocks_meson8b(struct pwm_chip *chip,
+                                        struct clk_parent_data *mux_parent_data)
 {
        struct meson_pwm *meson = to_meson_pwm(chip);
-       struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
        struct device *dev = pwmchip_parent(chip);
        unsigned int i;
        char name[255];
        int err;
 
-       for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) {
-               mux_parent_data[i].index = -1;
-               mux_parent_data[i].name = meson->data->parent_names[i];
-       }
-
-       for (i = 0; i < chip->npwm; i++) {
+       for (i = 0; i < MESON_NUM_PWMS; i++) {
                struct meson_pwm_channel *channel = &meson->channels[i];
                struct clk_parent_data div_parent = {}, gate_parent = {};
                struct clk_init_data init = {};
        return 0;
 }
 
+static int meson_pwm_init_channels_meson8b_legacy(struct pwm_chip *chip)
+{
+       struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
+       struct meson_pwm *meson = to_meson_pwm(chip);
+       int i;
+
+       dev_warn_once(pwmchip_parent(chip),
+                     "using obsolete compatible, please consider updating dt\n");
+
+       for (i = 0; i < MESON_NUM_MUX_PARENTS; i++) {
+               mux_parent_data[i].index = -1;
+               mux_parent_data[i].name = meson->data->parent_names[i];
+       }
+
+       return meson_pwm_init_clocks_meson8b(chip, mux_parent_data);
+}
+
+static int meson_pwm_init_channels_meson8b_v2(struct pwm_chip *chip)
+{
+       struct clk_parent_data mux_parent_data[MESON_NUM_MUX_PARENTS] = {};
+       int i;
+
+       /*
+        * NOTE: Instead of relying on the hard coded names in the driver
+        * as the legacy version, this relies on DT to provide the list of
+        * clocks.
+        * For once, using input numbers actually makes more sense than names.
+        * Also DT requires clock-names to be explicitly ordered, so there is
+        * no point bothering with clock names in this case.
+        */
+       for (i = 0; i < MESON_NUM_MUX_PARENTS; i++)
+               mux_parent_data[i].index = i;
+
+       return meson_pwm_init_clocks_meson8b(chip, mux_parent_data);
+}
+
+static const struct meson_pwm_data pwm_meson8b_data = {
+       .parent_names = { "xtal", NULL, "fclk_div4", "fclk_div3" },
+       .channels_init = meson_pwm_init_channels_meson8b_legacy,
+};
+
+/*
+ * Only the 2 first inputs of the GXBB AO PWMs are valid
+ * The last 2 are grounded
+ */
+static const struct meson_pwm_data pwm_gxbb_ao_data = {
+       .parent_names = { "xtal", "clk81", NULL, NULL },
+       .channels_init = meson_pwm_init_channels_meson8b_legacy,
+};
+
+static const struct meson_pwm_data pwm_axg_ee_data = {
+       .parent_names = { "xtal", "fclk_div5", "fclk_div4", "fclk_div3" },
+       .channels_init = meson_pwm_init_channels_meson8b_legacy,
+};
+
+static const struct meson_pwm_data pwm_axg_ao_data = {
+       .parent_names = { "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" },
+       .channels_init = meson_pwm_init_channels_meson8b_legacy,
+};
+
+static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
+       .parent_names = { "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" },
+       .channels_init = meson_pwm_init_channels_meson8b_legacy,
+};
+
+static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
+       .parent_names = { "xtal", "g12a_ao_clk81", NULL, NULL },
+       .channels_init = meson_pwm_init_channels_meson8b_legacy,
+};
+
+static const struct meson_pwm_data pwm_meson8_v2_data = {
+       .channels_init = meson_pwm_init_channels_meson8b_v2,
+};
+
+static const struct of_device_id meson_pwm_matches[] = {
+       {
+               .compatible = "amlogic,meson8-pwm-v2",
+               .data = &pwm_meson8_v2_data
+       },
+       /* The following compatibles are obsolete */
+       {
+               .compatible = "amlogic,meson8b-pwm",
+               .data = &pwm_meson8b_data
+       },
+       {
+               .compatible = "amlogic,meson-gxbb-pwm",
+               .data = &pwm_meson8b_data
+       },
+       {
+               .compatible = "amlogic,meson-gxbb-ao-pwm",
+               .data = &pwm_gxbb_ao_data
+       },
+       {
+               .compatible = "amlogic,meson-axg-ee-pwm",
+               .data = &pwm_axg_ee_data
+       },
+       {
+               .compatible = "amlogic,meson-axg-ao-pwm",
+               .data = &pwm_axg_ao_data
+       },
+       {
+               .compatible = "amlogic,meson-g12a-ee-pwm",
+               .data = &pwm_meson8b_data
+       },
+       {
+               .compatible = "amlogic,meson-g12a-ao-pwm-ab",
+               .data = &pwm_g12a_ao_ab_data
+       },
+       {
+               .compatible = "amlogic,meson-g12a-ao-pwm-cd",
+               .data = &pwm_g12a_ao_cd_data
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, meson_pwm_matches);
+
 static int meson_pwm_probe(struct platform_device *pdev)
 {
        struct pwm_chip *chip;
 
        meson->data = of_device_get_match_data(&pdev->dev);
 
-       err = meson_pwm_init_channels(chip);
+       err = meson->data->channels_init(chip);
        if (err < 0)
                return err;