From: Jerome Brunet <jbrunet@baylibre.com> To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Neil Armstrong" <neil.armstrong@linaro.org>, "Rob Herring" <robh+dt@kernel.org>, "Krzysztof Kozlowski" <krzysztof.kozlowski+dt@linaro.org>, "Conor Dooley" <conor+dt@kernel.org> Cc: Jerome Brunet <jbrunet@baylibre.com>, Kevin Hilman <khilman@baylibre.com>, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-amlogic@lists.infradead.org, linux-pwm@vger.kernel.org, JunYi Zhao <junyi.zhao@amlogic.com> Subject: [PATCH v5 5/5] pwm: meson: add generic compatible for meson8 to sm1 Date: Wed, 21 Feb 2024 16:11:51 +0100 [thread overview] Message-ID: <20240221151154.26452-6-jbrunet@baylibre.com> (raw) In-Reply-To: <20240221151154.26452-1-jbrunet@baylibre.com> 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 <jbrunet@baylibre.com> --- drivers/pwm/pwm-meson.c | 195 +++++++++++++++++++++++++--------------- 1 file changed, 121 insertions(+), 74 deletions(-) diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index fe61335d87d0..90fc7b349723 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -101,6 +101,7 @@ struct meson_pwm_channel { struct meson_pwm_data { const char *const parent_names[MESON_NUM_MUX_PARENTS]; + int (*channels_init)(struct pwm_chip *chip); }; struct meson_pwm { @@ -341,86 +342,16 @@ static const struct pwm_ops meson_pwm_ops = { .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 pdata = {}; struct meson8b_pwm_clocks *clks; @@ -502,6 +433,122 @@ static int meson_pwm_init_channels(struct pwm_chip *chip) 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; @@ -522,7 +569,7 @@ static int meson_pwm_probe(struct platform_device *pdev) 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; -- 2.43.0 _______________________________________________ linux-amlogic mailing list linux-amlogic@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-amlogic
WARNING: multiple messages have this Message-ID (diff)
From: Jerome Brunet <jbrunet@baylibre.com> To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Neil Armstrong" <neil.armstrong@linaro.org>, "Rob Herring" <robh+dt@kernel.org>, "Krzysztof Kozlowski" <krzysztof.kozlowski+dt@linaro.org>, "Conor Dooley" <conor+dt@kernel.org> Cc: Jerome Brunet <jbrunet@baylibre.com>, Kevin Hilman <khilman@baylibre.com>, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-amlogic@lists.infradead.org, linux-pwm@vger.kernel.org, JunYi Zhao <junyi.zhao@amlogic.com> Subject: [PATCH v5 5/5] pwm: meson: add generic compatible for meson8 to sm1 Date: Wed, 21 Feb 2024 16:11:51 +0100 [thread overview] Message-ID: <20240221151154.26452-6-jbrunet@baylibre.com> (raw) In-Reply-To: <20240221151154.26452-1-jbrunet@baylibre.com> 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 <jbrunet@baylibre.com> --- drivers/pwm/pwm-meson.c | 195 +++++++++++++++++++++++++--------------- 1 file changed, 121 insertions(+), 74 deletions(-) diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index fe61335d87d0..90fc7b349723 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -101,6 +101,7 @@ struct meson_pwm_channel { struct meson_pwm_data { const char *const parent_names[MESON_NUM_MUX_PARENTS]; + int (*channels_init)(struct pwm_chip *chip); }; struct meson_pwm { @@ -341,86 +342,16 @@ static const struct pwm_ops meson_pwm_ops = { .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 pdata = {}; struct meson8b_pwm_clocks *clks; @@ -502,6 +433,122 @@ static int meson_pwm_init_channels(struct pwm_chip *chip) 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; @@ -522,7 +569,7 @@ static int meson_pwm_probe(struct platform_device *pdev) 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; -- 2.43.0
next prev parent reply other threads:[~2024-02-21 15:12 UTC|newest] Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-02-21 15:11 [PATCH v5 0/5] pwm: meson: dt-bindings fixup Jerome Brunet 2024-02-21 15:11 ` Jerome Brunet 2024-02-21 15:11 ` [PATCH v5 1/5] dt-bindings: pwm: amlogic: fix s4 bindings Jerome Brunet 2024-02-21 15:11 ` Jerome Brunet 2024-02-21 15:11 ` [PATCH v5 2/5] dt-bindings: pwm: amlogic: Add a new binding for meson8 pwm types Jerome Brunet 2024-02-21 15:11 ` Jerome Brunet 2024-02-23 14:19 ` Rob Herring 2024-02-23 14:19 ` Rob Herring 2024-02-21 15:11 ` [PATCH v5 3/5] pwm: meson: generalize 4 inputs clock on meson8 pwm type Jerome Brunet 2024-02-21 15:11 ` Jerome Brunet 2024-02-21 15:11 ` [PATCH v5 4/5] pwm: meson: don't carry internal clock elements around Jerome Brunet 2024-02-21 15:11 ` Jerome Brunet 2024-04-12 11:27 ` Uwe Kleine-König 2024-04-12 11:27 ` Uwe Kleine-König 2024-02-21 15:11 ` Jerome Brunet [this message] 2024-02-21 15:11 ` [PATCH v5 5/5] pwm: meson: add generic compatible for meson8 to sm1 Jerome Brunet 2024-04-12 12:08 ` Uwe Kleine-König 2024-04-12 12:08 ` Uwe Kleine-König 2024-04-18 11:57 ` Jerome Brunet 2024-04-18 11:57 ` Jerome Brunet 2024-04-18 16:08 ` Uwe Kleine-König 2024-04-18 16:08 ` Uwe Kleine-König 2024-04-23 8:08 ` Neil Armstrong 2024-04-23 8:08 ` Neil Armstrong 2024-03-02 10:04 ` [PATCH v5 0/5] pwm: meson: dt-bindings fixup Uwe Kleine-König 2024-03-02 10:04 ` Uwe Kleine-König 2024-03-02 15:50 ` Jerome Brunet 2024-03-02 15:50 ` Jerome Brunet 2024-04-12 8:04 ` Jerome Brunet 2024-04-12 8:04 ` Jerome Brunet 2024-04-12 8:29 ` George Stark 2024-04-12 8:29 ` George Stark
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240221151154.26452-6-jbrunet@baylibre.com \ --to=jbrunet@baylibre.com \ --cc=conor+dt@kernel.org \ --cc=devicetree@vger.kernel.org \ --cc=junyi.zhao@amlogic.com \ --cc=khilman@baylibre.com \ --cc=krzysztof.kozlowski+dt@linaro.org \ --cc=linux-amlogic@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pwm@vger.kernel.org \ --cc=neil.armstrong@linaro.org \ --cc=robh+dt@kernel.org \ --cc=u.kleine-koenig@pengutronix.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.