linux-pwm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] pwm: meson: make full use of common clock framework
@ 2023-04-11 19:21 Heiner Kallweit
  2023-04-11 19:22 ` [PATCH v2 1/4] pwm: meson: switch to using struct clk_parent_data for mux parents Heiner Kallweit
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Heiner Kallweit @ 2023-04-11 19:21 UTC (permalink / raw)
  To: Jerome Brunet, Martin Blumenstingl, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding
  Cc: linux-arm-kernel, open list:ARM/Amlogic Meson..., linux-pwm

Newer versions of the PWM block use a core clock with external mux,
divider, and gate. These components either don't exist any longer in
the PWM block, or they are bypassed.
To minimize needed changes for supporting the new version, the internal
divider and gate should be handled by CCF too.

I didn't see a good way to split the patch, therefore it's somewhat
bigger. What it does:

- The internal mux is handled by CCF already. Register also internal
  divider and gate with CCF, so that we have one representation of the
  input clock: [mux] parent of [divider] parent of [gate]
  
- Now that CCF selects an appropriate mux parent, we don't need the
  DT-provided default parent any longer. Accordingly we can also omit
  setting the mux parent directly in the driver.
  
- Instead of manually handling the pre-div divider value, let CCF
  set the input clock. Targeted input clock frequency is
  0xffff * 1/period for best precision.
  
- For the "inverted pwm disabled" scenario target an input clock
  frequency of 1GHz. This ensures that the remaining low pulses
  have minimum length.

I don't have hw with the old PWM block, therefore I couldn't test this
patch. With the not yet included extension for the new PWM block
(channel->clock directly coming from get_clk(external_clk)) I didn't
notice any problem. My system uses PWM for the CPU voltage regulator
and for the SDIO 32kHz clock.

Note: The clock gate in the old PWM block is permanently disabled.
This seems to indicate that it's not used by the new PWM block.

Changes to RFT/RFC version:
- use parent_hws instead of parent_names for div/gate clock
- use devm_clk_hw_register where the struct clk * returned by
  devm_clk_register isn't needed

v2:
- add patch 1
- add patch 3
- switch to using clk_parent_data in all relevant places

Heiner Kallweit (4):
  pwm: meson: switch to using struct clk_parent_data for mux parents
  pwm: meson: don't use hdmi/video clock as mux parent
  pwm: meson: change clk/pwm gate from mask to bit
  pwm: meson: make full use of common clock framework

 drivers/pwm/pwm-meson.c | 194 +++++++++++++++++++++-------------------
 1 file changed, 101 insertions(+), 93 deletions(-)

-- 
2.40.0



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/4] pwm: meson: switch to using struct clk_parent_data for mux parents
  2023-04-11 19:21 [PATCH v2 0/4] pwm: meson: make full use of common clock framework Heiner Kallweit
@ 2023-04-11 19:22 ` Heiner Kallweit
  2023-04-11 19:44   ` Martin Blumenstingl
  2023-04-11 19:23 ` [PATCH v2 2/4] pwm: meson: don't use hdmi/video clock as mux parent Heiner Kallweit
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Heiner Kallweit @ 2023-04-11 19:22 UTC (permalink / raw)
  To: Jerome Brunet, Martin Blumenstingl, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding
  Cc: linux-arm-kernel, open list:ARM/Amlogic Meson..., linux-pwm

We'll use struct clk_parent_data for mux/div/gate initialization in the
follow-up patches. As a first step switch the mux from using
parent_names to clk_parent_data.

Suggested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/pwm/pwm-meson.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 4e5605c9d..52a2104f0 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -61,6 +61,7 @@
 #define MISC_A_EN		BIT(0)
 
 #define MESON_NUM_PWMS		2
+#define MESON_MAX_MUX_PARENTS	4
 
 static struct meson_pwm_channel_data {
 	u8		reg_offset;
@@ -485,20 +486,27 @@ MODULE_DEVICE_TABLE(of, meson_pwm_matches);
 static int meson_pwm_init_channels(struct meson_pwm *meson)
 {
 	struct device *dev = meson->chip.dev;
-	struct clk_init_data init;
 	unsigned int i;
 	char name[255];
 	int err;
 
 	for (i = 0; i < meson->chip.npwm; i++) {
 		struct meson_pwm_channel *channel = &meson->channels[i];
+		struct clk_parent_data mux_parent_data[MESON_MAX_MUX_PARENTS] = {};
+		struct clk_init_data init = {};
+		int j;
 
 		snprintf(name, sizeof(name), "%s#mux%u", dev_name(dev), i);
 
+		for (j = 0; j < meson->data->num_parents; j++) {
+			mux_parent_data[j].index = -1;
+			mux_parent_data[j].name = meson->data->parent_names[j];
+		}
+
 		init.name = name;
 		init.ops = &clk_mux_ops;
 		init.flags = 0;
-		init.parent_names = meson->data->parent_names;
+		init.parent_data = mux_parent_data;
 		init.num_parents = meson->data->num_parents;
 
 		channel->mux.reg = meson->base + REG_MISC_AB;
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 2/4] pwm: meson: don't use hdmi/video clock as mux parent
  2023-04-11 19:21 [PATCH v2 0/4] pwm: meson: make full use of common clock framework Heiner Kallweit
  2023-04-11 19:22 ` [PATCH v2 1/4] pwm: meson: switch to using struct clk_parent_data for mux parents Heiner Kallweit
@ 2023-04-11 19:23 ` Heiner Kallweit
  2023-04-11 19:24 ` [PATCH v2 3/4] pwm: meson: change clk/pwm gate from mask to bit Heiner Kallweit
  2023-04-11 19:26 ` [PATCH v2 4/4] pwm: meson: make full use of common clock framework Heiner Kallweit
  3 siblings, 0 replies; 12+ messages in thread
From: Heiner Kallweit @ 2023-04-11 19:23 UTC (permalink / raw)
  To: Jerome Brunet, Martin Blumenstingl, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding
  Cc: linux-arm-kernel, open list:ARM/Amlogic Meson..., linux-pwm

meson_vclk may change the rate of the video clock. Therefore better
don't use it as pwm mux parent. After removing this clock from the
parent list pwm_gxbb_data and pwm_g12a_ee_data are the same as
pwm_meson8b_data. So we can remove them.

Reported-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/pwm/pwm-meson.c | 24 +++---------------------
 1 file changed, 3 insertions(+), 21 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 52a2104f0..931cf14ca 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -371,7 +371,7 @@ static const struct pwm_ops meson_pwm_ops = {
 };
 
 static const char * const pwm_meson8b_parent_names[] = {
-	"xtal", "vid_pll", "fclk_div4", "fclk_div3"
+	"xtal", NULL, "fclk_div4", "fclk_div3"
 };
 
 static const struct meson_pwm_data pwm_meson8b_data = {
@@ -379,15 +379,6 @@ static const struct meson_pwm_data pwm_meson8b_data = {
 	.num_parents = ARRAY_SIZE(pwm_meson8b_parent_names),
 };
 
-static const char * const pwm_gxbb_parent_names[] = {
-	"xtal", "hdmi_pll", "fclk_div4", "fclk_div3"
-};
-
-static const struct meson_pwm_data pwm_gxbb_data = {
-	.parent_names = pwm_gxbb_parent_names,
-	.num_parents = ARRAY_SIZE(pwm_gxbb_parent_names),
-};
-
 /*
  * Only the 2 first inputs of the GXBB AO PWMs are valid
  * The last 2 are grounded
@@ -437,15 +428,6 @@ static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
 	.num_parents = ARRAY_SIZE(pwm_g12a_ao_cd_parent_names),
 };
 
-static const char * const pwm_g12a_ee_parent_names[] = {
-	"xtal", "hdmi_pll", "fclk_div4", "fclk_div3"
-};
-
-static const struct meson_pwm_data pwm_g12a_ee_data = {
-	.parent_names = pwm_g12a_ee_parent_names,
-	.num_parents = ARRAY_SIZE(pwm_g12a_ee_parent_names),
-};
-
 static const struct of_device_id meson_pwm_matches[] = {
 	{
 		.compatible = "amlogic,meson8b-pwm",
@@ -453,7 +435,7 @@ static const struct of_device_id meson_pwm_matches[] = {
 	},
 	{
 		.compatible = "amlogic,meson-gxbb-pwm",
-		.data = &pwm_gxbb_data
+		.data = &pwm_meson8b_data
 	},
 	{
 		.compatible = "amlogic,meson-gxbb-ao-pwm",
@@ -469,7 +451,7 @@ static const struct of_device_id meson_pwm_matches[] = {
 	},
 	{
 		.compatible = "amlogic,meson-g12a-ee-pwm",
-		.data = &pwm_g12a_ee_data
+		.data = &pwm_meson8b_data
 	},
 	{
 		.compatible = "amlogic,meson-g12a-ao-pwm-ab",
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 3/4] pwm: meson: change clk/pwm gate from mask to bit
  2023-04-11 19:21 [PATCH v2 0/4] pwm: meson: make full use of common clock framework Heiner Kallweit
  2023-04-11 19:22 ` [PATCH v2 1/4] pwm: meson: switch to using struct clk_parent_data for mux parents Heiner Kallweit
  2023-04-11 19:23 ` [PATCH v2 2/4] pwm: meson: don't use hdmi/video clock as mux parent Heiner Kallweit
@ 2023-04-11 19:24 ` Heiner Kallweit
  2023-04-11 19:26 ` [PATCH v2 4/4] pwm: meson: make full use of common clock framework Heiner Kallweit
  3 siblings, 0 replies; 12+ messages in thread
From: Heiner Kallweit @ 2023-04-11 19:24 UTC (permalink / raw)
  To: Jerome Brunet, Martin Blumenstingl, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding
  Cc: linux-arm-kernel, open list:ARM/Amlogic Meson..., linux-pwm

Change single-bit values from mask to bit. This facilitates
CCF initialization for the clock gate in a follow-up patch.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/pwm/pwm-meson.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 931cf14ca..f7595f81c 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -49,16 +49,16 @@
 #define PWM_HIGH_MASK		GENMASK(31, 16)
 
 #define REG_MISC_AB		0x8
-#define MISC_B_CLK_EN		BIT(23)
-#define MISC_A_CLK_EN		BIT(15)
+#define MISC_B_CLK_EN		23
+#define MISC_A_CLK_EN		15
 #define MISC_CLK_DIV_MASK	0x7f
 #define MISC_B_CLK_DIV_SHIFT	16
 #define MISC_A_CLK_DIV_SHIFT	8
 #define MISC_B_CLK_SEL_SHIFT	6
 #define MISC_A_CLK_SEL_SHIFT	4
 #define MISC_CLK_SEL_MASK	0x3
-#define MISC_B_EN		BIT(1)
-#define MISC_A_EN		BIT(0)
+#define MISC_B_EN		1
+#define MISC_A_EN		0
 
 #define MESON_NUM_PWMS		2
 #define MESON_MAX_MUX_PARENTS	4
@@ -67,22 +67,22 @@ static struct meson_pwm_channel_data {
 	u8		reg_offset;
 	u8		clk_sel_shift;
 	u8		clk_div_shift;
-	u32		clk_en_mask;
-	u32		pwm_en_mask;
+	u8		clk_en_bit;
+	u8		pwm_en_bit;
 } meson_pwm_per_channel_data[MESON_NUM_PWMS] = {
 	{
 		.reg_offset	= REG_PWM_A,
 		.clk_sel_shift	= MISC_A_CLK_SEL_SHIFT,
 		.clk_div_shift	= MISC_A_CLK_DIV_SHIFT,
-		.clk_en_mask	= MISC_A_CLK_EN,
-		.pwm_en_mask	= MISC_A_EN,
+		.clk_en_bit	= MISC_A_CLK_EN,
+		.pwm_en_bit	= MISC_A_EN,
 	},
 	{
 		.reg_offset	= REG_PWM_B,
 		.clk_sel_shift	= MISC_B_CLK_SEL_SHIFT,
 		.clk_div_shift	= MISC_B_CLK_DIV_SHIFT,
-		.clk_en_mask	= MISC_B_CLK_EN,
-		.pwm_en_mask	= MISC_B_EN,
+		.clk_en_bit	= MISC_B_CLK_EN,
+		.pwm_en_bit	= MISC_B_EN,
 	}
 };
 
@@ -231,7 +231,7 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	value = readl(meson->base + REG_MISC_AB);
 	value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
 	value |= channel->pre_div << channel_data->clk_div_shift;
-	value |= channel_data->clk_en_mask;
+	value |= BIT(channel_data->clk_en_bit);
 	writel(value, meson->base + REG_MISC_AB);
 
 	value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
@@ -239,7 +239,7 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	writel(value, meson->base + channel_data->reg_offset);
 
 	value = readl(meson->base + REG_MISC_AB);
-	value |= channel_data->pwm_en_mask;
+	value |= BIT(channel_data->pwm_en_bit);
 	writel(value, meson->base + REG_MISC_AB);
 
 	spin_unlock_irqrestore(&meson->lock, flags);
@@ -253,7 +253,7 @@ static void meson_pwm_disable(struct meson_pwm *meson, struct pwm_device *pwm)
 	spin_lock_irqsave(&meson->lock, flags);
 
 	value = readl(meson->base + REG_MISC_AB);
-	value &= ~meson_pwm_per_channel_data[pwm->hwpwm].pwm_en_mask;
+	value &= ~BIT(meson_pwm_per_channel_data[pwm->hwpwm].pwm_en_bit);
 	writel(value, meson->base + REG_MISC_AB);
 
 	spin_unlock_irqrestore(&meson->lock, flags);
@@ -335,7 +335,7 @@ static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	value = readl(meson->base + REG_MISC_AB);
 
-	tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
+	tmp = BIT(channel_data->pwm_en_bit) | BIT(channel_data->clk_en_bit);
 	state->enabled = (value & tmp) == tmp;
 
 	tmp = value >> channel_data->clk_div_shift;
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 4/4] pwm: meson: make full use of common clock framework
  2023-04-11 19:21 [PATCH v2 0/4] pwm: meson: make full use of common clock framework Heiner Kallweit
                   ` (2 preceding siblings ...)
  2023-04-11 19:24 ` [PATCH v2 3/4] pwm: meson: change clk/pwm gate from mask to bit Heiner Kallweit
@ 2023-04-11 19:26 ` Heiner Kallweit
  2023-04-11 19:48   ` Martin Blumenstingl
  3 siblings, 1 reply; 12+ messages in thread
From: Heiner Kallweit @ 2023-04-11 19:26 UTC (permalink / raw)
  To: Jerome Brunet, Martin Blumenstingl, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding
  Cc: linux-arm-kernel, open list:ARM/Amlogic Meson..., linux-pwm

Newer versions of the PWM block use a core clock with external mux,
divider, and gate. These components either don't exist any longer in
the PWM block, or they are bypassed.
To minimize needed changes for supporting the new version, the internal
divider and gate should be handled by CCF too.

I didn't see a good way to split the patch, therefore it's somewhat
bigger. What it does:

- The internal mux is handled by CCF already. Register also internal
  divider and gate with CCF, so that we have one representation of the
  input clock: [mux] parent of [divider] parent of [gate]
  
- Now that CCF selects an appropriate mux parent, we don't need the
  DT-provided default parent any longer. Accordingly we can also omit
  setting the mux parent directly in the driver.
  
- Instead of manually handling the pre-div divider value, let CCF
  set the input clock. Targeted input clock frequency is
  0xffff * 1/period for best precision.
  
- For the "inverted pwm disabled" scenario target an input clock
  frequency of 1GHz. This ensures that the remaining low pulses
  have minimum length.

I don't have hw with the old PWM block, therefore I couldn't test this
patch. With the not yet included extension for the new PWM block
(channel->clock directly coming from get_clk(external_clk)) I didn't
notice any problem. My system uses PWM for the CPU voltage regulator
and for the SDIO 32kHz clock.

Note: The clock gate in the old PWM block is permanently disabled.
This seems to indicate that it's not used by the new PWM block.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
Changes to RFT/RFC version:
- use parent_hws instead of parent_names for div/gate clock
- use devm_clk_hw_register where the struct clk * returned by
  devm_clk_register isn't needed

v2:
- add patch 1
- add patch 3
- switch to using clk_parent_data in all relevant places
---
 drivers/pwm/pwm-meson.c | 134 +++++++++++++++++++++++-----------------
 1 file changed, 76 insertions(+), 58 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index f7595f81c..ec9c82e48 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -51,7 +51,7 @@
 #define REG_MISC_AB		0x8
 #define MISC_B_CLK_EN		23
 #define MISC_A_CLK_EN		15
-#define MISC_CLK_DIV_MASK	0x7f
+#define MISC_CLK_DIV_WIDTH	7
 #define MISC_B_CLK_DIV_SHIFT	16
 #define MISC_A_CLK_DIV_SHIFT	8
 #define MISC_B_CLK_SEL_SHIFT	6
@@ -87,12 +87,13 @@ static struct meson_pwm_channel_data {
 };
 
 struct meson_pwm_channel {
+	unsigned long rate;
 	unsigned int hi;
 	unsigned int lo;
-	u8 pre_div;
 
-	struct clk *clk_parent;
 	struct clk_mux mux;
+	struct clk_divider div;
+	struct clk_gate gate;
 	struct clk *clk;
 };
 
@@ -125,16 +126,6 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 	struct device *dev = chip->dev;
 	int err;
 
-	if (channel->clk_parent) {
-		err = clk_set_parent(channel->clk, channel->clk_parent);
-		if (err < 0) {
-			dev_err(dev, "failed to set parent %s for %s: %d\n",
-				__clk_get_name(channel->clk_parent),
-				__clk_get_name(channel->clk), err);
-			return err;
-		}
-	}
-
 	err = clk_prepare_enable(channel->clk);
 	if (err < 0) {
 		dev_err(dev, "failed to enable clock %s: %d\n",
@@ -157,8 +148,9 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 			  const struct pwm_state *state)
 {
 	struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm];
-	unsigned int duty, period, pre_div, cnt, duty_cnt;
+	unsigned int duty, period, cnt, duty_cnt;
 	unsigned long fin_freq;
+	u64 freq;
 
 	duty = state->duty_cycle;
 	period = state->period;
@@ -166,7 +158,11 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 	if (state->polarity == PWM_POLARITY_INVERSED)
 		duty = period - duty;
 
-	fin_freq = clk_get_rate(channel->clk);
+	freq = div64_u64(NSEC_PER_SEC * (u64)0xffff, period);
+	if (freq > ULONG_MAX)
+		freq = ULONG_MAX;
+
+	fin_freq = clk_round_rate(channel->clk, freq);
 	if (fin_freq == 0) {
 		dev_err(meson->chip.dev, "invalid source clock frequency\n");
 		return -EINVAL;
@@ -174,46 +170,35 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 
 	dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq);
 
-	pre_div = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * 0xffffLL);
-	if (pre_div > MISC_CLK_DIV_MASK) {
-		dev_err(meson->chip.dev, "unable to get period pre_div\n");
-		return -EINVAL;
-	}
-
-	cnt = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * (pre_div + 1));
+	cnt = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC);
 	if (cnt > 0xffff) {
 		dev_err(meson->chip.dev, "unable to get period cnt\n");
 		return -EINVAL;
 	}
 
-	dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period,
-		pre_div, cnt);
+	dev_dbg(meson->chip.dev, "period=%u cnt=%u\n", period, cnt);
 
 	if (duty == period) {
-		channel->pre_div = pre_div;
 		channel->hi = cnt;
 		channel->lo = 0;
 	} else if (duty == 0) {
-		channel->pre_div = pre_div;
 		channel->hi = 0;
 		channel->lo = cnt;
 	} else {
-		/* Then check is we can have the duty with the same pre_div */
-		duty_cnt = div64_u64(fin_freq * (u64)duty,
-				     NSEC_PER_SEC * (pre_div + 1));
+		duty_cnt = div64_u64(fin_freq * (u64)duty, NSEC_PER_SEC);
 		if (duty_cnt > 0xffff) {
 			dev_err(meson->chip.dev, "unable to get duty cycle\n");
 			return -EINVAL;
 		}
 
-		dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n",
-			duty, pre_div, duty_cnt);
+		dev_dbg(meson->chip.dev, "duty=%u duty_cnt=%u\n", duty, duty_cnt);
 
-		channel->pre_div = pre_div;
 		channel->hi = duty_cnt;
 		channel->lo = cnt - duty_cnt;
 	}
 
+	channel->rate = fin_freq;
+
 	return 0;
 }
 
@@ -223,16 +208,15 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	struct meson_pwm_channel_data *channel_data;
 	unsigned long flags;
 	u32 value;
+	int err;
 
 	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
 
-	spin_lock_irqsave(&meson->lock, flags);
+	err = clk_set_rate(channel->clk, channel->rate);
+	if (err)
+		dev_err(meson->chip.dev, "setting clock rate failed\n");
 
-	value = readl(meson->base + REG_MISC_AB);
-	value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
-	value |= channel->pre_div << channel_data->clk_div_shift;
-	value |= BIT(channel_data->clk_en_bit);
-	writel(value, meson->base + REG_MISC_AB);
+	spin_lock_irqsave(&meson->lock, flags);
 
 	value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
 		FIELD_PREP(PWM_LOW_MASK, channel->lo);
@@ -271,16 +255,16 @@ static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			/*
 			 * This IP block revision doesn't have an "always high"
 			 * setting which we can use for "inverted disabled".
-			 * Instead we achieve this using the same settings
-			 * that we use a pre_div of 0 (to get the shortest
-			 * possible duration for one "count") and
+			 * Instead we achieve this by setting an arbitrary,
+			 * very high frequency, resulting in the shortest
+			 * possible duration for one "count" and
 			 * "period == duty_cycle". This results in a signal
 			 * which is LOW for one "count", while being HIGH for
 			 * the rest of the (so the signal is HIGH for slightly
 			 * less than 100% of the period, but this is the best
 			 * we can achieve).
 			 */
-			channel->pre_div = 0;
+			channel->rate = 1000000000;
 			channel->hi = ~0;
 			channel->lo = 0;
 
@@ -305,7 +289,6 @@ static unsigned int meson_pwm_cnt_to_ns(struct pwm_chip *chip,
 	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct meson_pwm_channel *channel;
 	unsigned long fin_freq;
-	u32 fin_ns;
 
 	/* to_meson_pwm() can only be used after .get_state() is called */
 	channel = &meson->channels[pwm->hwpwm];
@@ -314,9 +297,7 @@ static unsigned int meson_pwm_cnt_to_ns(struct pwm_chip *chip,
 	if (fin_freq == 0)
 		return 0;
 
-	fin_ns = div_u64(NSEC_PER_SEC, fin_freq);
-
-	return cnt * fin_ns * (channel->pre_div + 1);
+	return div_u64(NSEC_PER_SEC * (u64)cnt, fin_freq);
 }
 
 static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -335,11 +316,8 @@ static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	value = readl(meson->base + REG_MISC_AB);
 
-	tmp = BIT(channel_data->pwm_en_bit) | BIT(channel_data->clk_en_bit);
-	state->enabled = (value & tmp) == tmp;
-
-	tmp = value >> channel_data->clk_div_shift;
-	channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
+	tmp = BIT(channel_data->pwm_en_bit);
+	state->enabled = __clk_is_enabled(channel->clk) && (value & tmp) == tmp;
 
 	value = readl(meson->base + channel_data->reg_offset);
 
@@ -475,6 +453,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)
 	for (i = 0; i < meson->chip.npwm; i++) {
 		struct meson_pwm_channel *channel = &meson->channels[i];
 		struct clk_parent_data mux_parent_data[MESON_MAX_MUX_PARENTS] = {};
+		struct clk_parent_data div_parent = {}, gate_parent = {};
 		struct clk_init_data init = {};
 		int j;
 
@@ -500,18 +479,57 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)
 		channel->mux.table = NULL;
 		channel->mux.hw.init = &init;
 
-		channel->clk = devm_clk_register(dev, &channel->mux.hw);
-		if (IS_ERR(channel->clk)) {
-			err = PTR_ERR(channel->clk);
+		err = devm_clk_hw_register(dev, &channel->mux.hw);
+		if (err) {
 			dev_err(dev, "failed to register %s: %d\n", name, err);
 			return err;
 		}
 
-		snprintf(name, sizeof(name), "clkin%u", i);
+		snprintf(name, sizeof(name), "%s#div%u", dev_name(dev), i);
+
+		init.name = name;
+		init.ops = &clk_divider_ops;
+		init.flags = CLK_SET_RATE_PARENT;
+		div_parent.index = -1;
+		div_parent.hw = &channel->mux.hw;
+		init.parent_data = &div_parent;
+		init.num_parents = 1;
+
+		channel->div.reg = meson->base + REG_MISC_AB;
+		channel->div.shift = meson_pwm_per_channel_data[i].clk_div_shift;
+		channel->div.width = MISC_CLK_DIV_WIDTH;
+		channel->div.hw.init = &init;
+		channel->div.flags = 0;
+		channel->div.lock = &meson->lock;
+
+		err = devm_clk_hw_register(dev, &channel->div.hw);
+		if (err) {
+			dev_err(dev, "failed to register %s: %d\n", name, err);
+			return err;
+		}
 
-		channel->clk_parent = devm_clk_get_optional(dev, name);
-		if (IS_ERR(channel->clk_parent))
-			return PTR_ERR(channel->clk_parent);
+		snprintf(name, sizeof(name), "%s#gate%u", dev_name(dev), i);
+
+		init.name = name;
+		init.ops = &clk_gate_ops;
+		init.flags = CLK_SET_RATE_PARENT;
+		gate_parent.index = -1;
+		gate_parent.hw = &channel->div.hw;
+		init.parent_data = &gate_parent;
+		init.num_parents = 1;
+
+		channel->gate.reg = meson->base + REG_MISC_AB;
+		channel->gate.bit_idx = meson_pwm_per_channel_data[i].clk_en_bit;
+		channel->gate.hw.init = &init;
+		channel->gate.flags = 0;
+		channel->gate.lock = &meson->lock;
+
+		channel->clk = devm_clk_register(dev, &channel->gate.hw);
+		if (IS_ERR(channel->clk)) {
+			err = PTR_ERR(channel->clk);
+			dev_err(dev, "failed to register %s: %d\n", name, err);
+			return err;
+		}
 	}
 
 	return 0;
-- 
2.40.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/4] pwm: meson: switch to using struct clk_parent_data for mux parents
  2023-04-11 19:22 ` [PATCH v2 1/4] pwm: meson: switch to using struct clk_parent_data for mux parents Heiner Kallweit
@ 2023-04-11 19:44   ` Martin Blumenstingl
  0 siblings, 0 replies; 12+ messages in thread
From: Martin Blumenstingl @ 2023-04-11 19:44 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Jerome Brunet, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding, linux-arm-kernel,
	open list:ARM/Amlogic Meson...,
	linux-pwm

Hello Heiner,

On Tue, Apr 11, 2023 at 9:26 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
>
> We'll use struct clk_parent_data for mux/div/gate initialization in the
> follow-up patches. As a first step switch the mux from using
> parent_names to clk_parent_data.
great, thanks!

[...]
> +               for (j = 0; j < meson->data->num_parents; j++) {
> +                       mux_parent_data[j].index = -1;
> +                       mux_parent_data[j].name = meson->data->parent_names[j];
> +               }
I think this can be moved outside the npwm loop because the clock
inputs are for the whole IP block, not per PWM channel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/4] pwm: meson: make full use of common clock framework
  2023-04-11 19:26 ` [PATCH v2 4/4] pwm: meson: make full use of common clock framework Heiner Kallweit
@ 2023-04-11 19:48   ` Martin Blumenstingl
  2023-04-11 21:00     ` Heiner Kallweit
  2023-04-13  9:13     ` Thierry Reding
  0 siblings, 2 replies; 12+ messages in thread
From: Martin Blumenstingl @ 2023-04-11 19:48 UTC (permalink / raw)
  To: Heiner Kallweit
  Cc: Jerome Brunet, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding, linux-arm-kernel,
	open list:ARM/Amlogic Meson...,
	linux-pwm

On Tue, Apr 11, 2023 at 9:26 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
[...]
> +               init.name = name;
> +               init.ops = &clk_gate_ops;
> +               init.flags = CLK_SET_RATE_PARENT;
As much as I don't want it: I think we need CLK_IGNORE_UNUSED here as well :-(
On GXBB, GXL and GXM SoCs the board design typically uses PWM
regulators (like the boards using 32-bit SoCs as well as newer boards
using G12A or later SoCs).
This means: if we enable that PWM controller and one of the channels
is firmware managed and the other isn't then we can end up disabling
the clock - taking away VCCK (which supplies the CPU) or VDDEE (which
supplies GPU and various other components).
I'd be happy if there are other suggestions around this though.


Best regards,
Martin

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/4] pwm: meson: make full use of common clock framework
  2023-04-11 19:48   ` Martin Blumenstingl
@ 2023-04-11 21:00     ` Heiner Kallweit
  2023-04-13  9:13     ` Thierry Reding
  1 sibling, 0 replies; 12+ messages in thread
From: Heiner Kallweit @ 2023-04-11 21:00 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: Jerome Brunet, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, thierry.reding, linux-arm-kernel,
	open list:ARM/Amlogic Meson...,
	linux-pwm

On 11.04.2023 21:48, Martin Blumenstingl wrote:
> On Tue, Apr 11, 2023 at 9:26 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
> [...]
>> +               init.name = name;
>> +               init.ops = &clk_gate_ops;
>> +               init.flags = CLK_SET_RATE_PARENT;
> As much as I don't want it: I think we need CLK_IGNORE_UNUSED here as well :-(
> On GXBB, GXL and GXM SoCs the board design typically uses PWM
> regulators (like the boards using 32-bit SoCs as well as newer boards
> using G12A or later SoCs).
> This means: if we enable that PWM controller and one of the channels
> is firmware managed and the other isn't then we can end up disabling
> the clock - taking away VCCK (which supplies the CPU) or VDDEE (which
> supplies GPU and various other components).

I see your point, good to know. Eventually it may be an option to
mark such firmware-managed pwm channels in DT.
I'll wait for potential additional feedback until tomorrow, then I'll
submit a version incl. the two small changes to address your remarks.

> I'd be happy if there are other suggestions around this though.
> 
> 
> Best regards,
> Martin


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/4] pwm: meson: make full use of common clock framework
  2023-04-11 19:48   ` Martin Blumenstingl
  2023-04-11 21:00     ` Heiner Kallweit
@ 2023-04-13  9:13     ` Thierry Reding
  2023-04-14 18:33       ` Martin Blumenstingl
  1 sibling, 1 reply; 12+ messages in thread
From: Thierry Reding @ 2023-04-13  9:13 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: Heiner Kallweit, Jerome Brunet, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, linux-arm-kernel,
	open list:ARM/Amlogic Meson...,
	linux-pwm

[-- Attachment #1: Type: text/plain, Size: 1266 bytes --]

On Tue, Apr 11, 2023 at 09:48:46PM +0200, Martin Blumenstingl wrote:
> On Tue, Apr 11, 2023 at 9:26 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
> [...]
> > +               init.name = name;
> > +               init.ops = &clk_gate_ops;
> > +               init.flags = CLK_SET_RATE_PARENT;
> As much as I don't want it: I think we need CLK_IGNORE_UNUSED here as well :-(
> On GXBB, GXL and GXM SoCs the board design typically uses PWM
> regulators (like the boards using 32-bit SoCs as well as newer boards
> using G12A or later SoCs).
> This means: if we enable that PWM controller and one of the channels
> is firmware managed and the other isn't then we can end up disabling
> the clock - taking away VCCK (which supplies the CPU) or VDDEE (which
> supplies GPU and various other components).
> I'd be happy if there are other suggestions around this though.

What exactly does "firmware managed" mean? Typically we describe all
supplies in DT to avoid these kinds of workarounds. If VCCK and/or VDDEE
are PWM-controlled regulators that should never be turned off, can they
not simply be added to device tree and marked as "always-on"? That would
propagate to the PWM and make sure the corresponding clock remains
enabled.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/4] pwm: meson: make full use of common clock framework
  2023-04-13  9:13     ` Thierry Reding
@ 2023-04-14 18:33       ` Martin Blumenstingl
  2023-04-17  9:27         ` Thierry Reding
  0 siblings, 1 reply; 12+ messages in thread
From: Martin Blumenstingl @ 2023-04-14 18:33 UTC (permalink / raw)
  To: Thierry Reding, Heiner Kallweit
  Cc: Jerome Brunet, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, linux-arm-kernel,
	open list:ARM/Amlogic Meson...,
	linux-pwm

Hello Thierry and Heiner,

On Thu, Apr 13, 2023 at 11:13 AM Thierry Reding
<thierry.reding@gmail.com> wrote:
>
> On Tue, Apr 11, 2023 at 09:48:46PM +0200, Martin Blumenstingl wrote:
> > On Tue, Apr 11, 2023 at 9:26 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
> > [...]
> > > +               init.name = name;
> > > +               init.ops = &clk_gate_ops;
> > > +               init.flags = CLK_SET_RATE_PARENT;
> > As much as I don't want it: I think we need CLK_IGNORE_UNUSED here as well :-(
> > On GXBB, GXL and GXM SoCs the board design typically uses PWM
> > regulators (like the boards using 32-bit SoCs as well as newer boards
> > using G12A or later SoCs).
> > This means: if we enable that PWM controller and one of the channels
> > is firmware managed and the other isn't then we can end up disabling
> > the clock - taking away VCCK (which supplies the CPU) or VDDEE (which
> > supplies GPU and various other components).
> > I'd be happy if there are other suggestions around this though.
>
> What exactly does "firmware managed" mean? Typically we describe all
> supplies in DT to avoid these kinds of workarounds. If VCCK and/or VDDEE
> are PWM-controlled regulators that should never be turned off, can they
> not simply be added to device tree and marked as "always-on"? That would
> propagate to the PWM and make sure the corresponding clock remains
> enabled.
Most Amlogic boards use PWM-controlled regulators. There's three SoC
generations I know of that are "special" when it comes to managing
these regulators (and CPU clocks) though.
Let's start with the simple ones: Meson8/8b/8m2, G12A, G12B, SM1 (and
I assume newer generations as well): here the PWM regulators are
managed by Linux.
Then there's the special cases: GXBB, GXL and GXM which run a SCPI
firmware for managing the CPU clocks, regulators and suspend.

SCPI firmware is running in the "secure world", while Linux is running
in the "normal world".
I don't know if there's boards with secure boot that lock Linux out
from the PWM and CPU clock registers.
This means: so far we've left any PWM controller settings that relate
to the regulators up to the SCPI firmware, not messing with any of the
registers from Linux.

My concern is for example with the Khadas VIM2, see it's schematics [0] page 4:
- PWM_C is used to manage the VDDEE regulator (I suspect that there's
a typo though and it should be called VDDEE_PWM_C, but the schematics
state that the signal is called "VDDEE_PWM_D")
- PWM_D can routed to the GPIO headers
Now if a user enables &pwm_cd (the PWM controller responsible for
channel PWM_C and PWM_D) to use PWM_D on the pin header we don't want
to turn off PWM_C by accident.
Turning PWM_C off by accident can happen if we register the clock gate
and don't have a consumer for it. CCF (common clock framework) can
then just turn off that clock because it's unused. This would lock up
the board because VDDEE is used for critical functionality on the SoC.

Two extra questions from Heiner:
> I check regarding Thierry's comment and found the vddcpu
> pwm-regulators described in the DT's. Is your concern that
> not for all boards the vddcpu pwm-regulator is described in
> the DT?
Correct, boards that have the pwm-regulators described in their .dts
(typically the boards using a Meson8/8b/8m2, G12A, G12B or SM1 SoC)
are not a problem.
Only the ones that don't describe the pwm-regulators in their .dts are
an issue as these are managed by the SCPI firmware.

> AFAICS pwm channels are independent. How can switching
> off the clock for one channel affect the other channel?
It's not about one channel affecting the other. My thought is that
CCF's "disabled unused clocks" feature will turn off the clock if it's
not used. Since SCPI firmware uses it, Linux doesn't know that CCF may
disable the clock unless CLK_IGNORE_UNUSED is set.

I hope this makes sense. If you have any additional questions then
feel free to ask.


Best regards,
Martin


[0] https://dl.khadas.com/products/vim2/schematic/vim2_sch_v12.pdf

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/4] pwm: meson: make full use of common clock framework
  2023-04-14 18:33       ` Martin Blumenstingl
@ 2023-04-17  9:27         ` Thierry Reding
  2023-04-23 17:34           ` Martin Blumenstingl
  0 siblings, 1 reply; 12+ messages in thread
From: Thierry Reding @ 2023-04-17  9:27 UTC (permalink / raw)
  To: Martin Blumenstingl
  Cc: Heiner Kallweit, Jerome Brunet, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, linux-arm-kernel,
	open list:ARM/Amlogic Meson...,
	linux-pwm

[-- Attachment #1: Type: text/plain, Size: 5151 bytes --]

On Fri, Apr 14, 2023 at 08:33:28PM +0200, Martin Blumenstingl wrote:
> Hello Thierry and Heiner,
> 
> On Thu, Apr 13, 2023 at 11:13 AM Thierry Reding
> <thierry.reding@gmail.com> wrote:
> >
> > On Tue, Apr 11, 2023 at 09:48:46PM +0200, Martin Blumenstingl wrote:
> > > On Tue, Apr 11, 2023 at 9:26 PM Heiner Kallweit <hkallweit1@gmail.com> wrote:
> > > [...]
> > > > +               init.name = name;
> > > > +               init.ops = &clk_gate_ops;
> > > > +               init.flags = CLK_SET_RATE_PARENT;
> > > As much as I don't want it: I think we need CLK_IGNORE_UNUSED here as well :-(
> > > On GXBB, GXL and GXM SoCs the board design typically uses PWM
> > > regulators (like the boards using 32-bit SoCs as well as newer boards
> > > using G12A or later SoCs).
> > > This means: if we enable that PWM controller and one of the channels
> > > is firmware managed and the other isn't then we can end up disabling
> > > the clock - taking away VCCK (which supplies the CPU) or VDDEE (which
> > > supplies GPU and various other components).
> > > I'd be happy if there are other suggestions around this though.
> >
> > What exactly does "firmware managed" mean? Typically we describe all
> > supplies in DT to avoid these kinds of workarounds. If VCCK and/or VDDEE
> > are PWM-controlled regulators that should never be turned off, can they
> > not simply be added to device tree and marked as "always-on"? That would
> > propagate to the PWM and make sure the corresponding clock remains
> > enabled.
> Most Amlogic boards use PWM-controlled regulators. There's three SoC
> generations I know of that are "special" when it comes to managing
> these regulators (and CPU clocks) though.
> Let's start with the simple ones: Meson8/8b/8m2, G12A, G12B, SM1 (and
> I assume newer generations as well): here the PWM regulators are
> managed by Linux.
> Then there's the special cases: GXBB, GXL and GXM which run a SCPI
> firmware for managing the CPU clocks, regulators and suspend.
> 
> SCPI firmware is running in the "secure world", while Linux is running
> in the "normal world".
> I don't know if there's boards with secure boot that lock Linux out
> from the PWM and CPU clock registers.
> This means: so far we've left any PWM controller settings that relate
> to the regulators up to the SCPI firmware, not messing with any of the
> registers from Linux.
> 
> My concern is for example with the Khadas VIM2, see it's schematics [0] page 4:
> - PWM_C is used to manage the VDDEE regulator (I suspect that there's
> a typo though and it should be called VDDEE_PWM_C, but the schematics
> state that the signal is called "VDDEE_PWM_D")
> - PWM_D can routed to the GPIO headers
> Now if a user enables &pwm_cd (the PWM controller responsible for
> channel PWM_C and PWM_D) to use PWM_D on the pin header we don't want
> to turn off PWM_C by accident.
> Turning PWM_C off by accident can happen if we register the clock gate
> and don't have a consumer for it. CCF (common clock framework) can
> then just turn off that clock because it's unused. This would lock up
> the board because VDDEE is used for critical functionality on the SoC.
> 
> Two extra questions from Heiner:
> > I check regarding Thierry's comment and found the vddcpu
> > pwm-regulators described in the DT's. Is your concern that
> > not for all boards the vddcpu pwm-regulator is described in
> > the DT?
> Correct, boards that have the pwm-regulators described in their .dts
> (typically the boards using a Meson8/8b/8m2, G12A, G12B or SM1 SoC)
> are not a problem.
> Only the ones that don't describe the pwm-regulators in their .dts are
> an issue as these are managed by the SCPI firmware.
> 
> > AFAICS pwm channels are independent. How can switching
> > off the clock for one channel affect the other channel?
> It's not about one channel affecting the other. My thought is that
> CCF's "disabled unused clocks" feature will turn off the clock if it's
> not used. Since SCPI firmware uses it, Linux doesn't know that CCF may
> disable the clock unless CLK_IGNORE_UNUSED is set.
> 
> I hope this makes sense. If you have any additional questions then
> feel free to ask.

It seems to me like really your only option is to completely hide that
clock from Linux. Even if you use CLK_IGNORE_UNUSED, you could still run
into a situation where the clock gets turned off.

Actually the same is true of the PWM channel. Once the PWM channel is
registered somebody could try and use the sysfs interface to control it.
So even if nothing in the DT makes use of the "reserved" PWM channel,
people could still try to use it, which means that even if the clock
were to remain always on, somebody could modify the period and
destabilize the CPU.

I think reserving specific PWM channels is the only way to safely make
this work. People could still abuse this by patching the DT, but once
you can do that, you can probably do a whole bunch of other things as
well, so if there's no hardware mechanism to prevent access to the PWM
channel, that's about as good as it'll get.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/4] pwm: meson: make full use of common clock framework
  2023-04-17  9:27         ` Thierry Reding
@ 2023-04-23 17:34           ` Martin Blumenstingl
  0 siblings, 0 replies; 12+ messages in thread
From: Martin Blumenstingl @ 2023-04-23 17:34 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Heiner Kallweit, Jerome Brunet, Neil Armstrong, Kevin Hilman,
	Uwe Kleine-König, linux-arm-kernel,
	open list:ARM/Amlogic Meson...,
	linux-pwm

On Mon, Apr 17, 2023 at 11:27 AM Thierry Reding
<thierry.reding@gmail.com> wrote:
[...]
> It seems to me like really your only option is to completely hide that
> clock from Linux. Even if you use CLK_IGNORE_UNUSED, you could still run
> into a situation where the clock gets turned off.
>
> Actually the same is true of the PWM channel. Once the PWM channel is
> registered somebody could try and use the sysfs interface to control it.
> So even if nothing in the DT makes use of the "reserved" PWM channel,
> people could still try to use it, which means that even if the clock
> were to remain always on, somebody could modify the period and
> destabilize the CPU.
>
> I think reserving specific PWM channels is the only way to safely make
> this work. People could still abuse this by patching the DT, but once
> you can do that, you can probably do a whole bunch of other things as
> well, so if there's no hardware mechanism to prevent access to the PWM
> channel, that's about as good as it'll get.
I agree with you. It should be done in a separate patch(set), not as
part of this CCF conversion as the issue which you mention is already
present even without Heiner's changes.


Best regards,
Martin

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-04-23 17:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-11 19:21 [PATCH v2 0/4] pwm: meson: make full use of common clock framework Heiner Kallweit
2023-04-11 19:22 ` [PATCH v2 1/4] pwm: meson: switch to using struct clk_parent_data for mux parents Heiner Kallweit
2023-04-11 19:44   ` Martin Blumenstingl
2023-04-11 19:23 ` [PATCH v2 2/4] pwm: meson: don't use hdmi/video clock as mux parent Heiner Kallweit
2023-04-11 19:24 ` [PATCH v2 3/4] pwm: meson: change clk/pwm gate from mask to bit Heiner Kallweit
2023-04-11 19:26 ` [PATCH v2 4/4] pwm: meson: make full use of common clock framework Heiner Kallweit
2023-04-11 19:48   ` Martin Blumenstingl
2023-04-11 21:00     ` Heiner Kallweit
2023-04-13  9:13     ` Thierry Reding
2023-04-14 18:33       ` Martin Blumenstingl
2023-04-17  9:27         ` Thierry Reding
2023-04-23 17:34           ` Martin Blumenstingl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).