All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding@gmail.com>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: linux-pwm@vger.kernel.org,
	"Daniel Thompson" <daniel.thompson@linaro.org>,
	"Michal Vokáč" <michal.vokac@ysoft.com>,
	"Lee Jones" <lee.jones@linaro.org>,
	linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org,
	kernel@pengutronix.de, "Jingoo Han" <jingoohan1@gmail.com>,
	"Enric Balletbo i Serra" <enric.balletbo@collabora.com>,
	"Adam Ford" <aford173@gmail.com>
Subject: Re: [PATCH] backlight: pwm_bl: configure pwm only once per backlight toggle
Date: Thu, 17 Oct 2019 11:11:31 +0000	[thread overview]
Message-ID: <20191017111131.GB3122066@ulmo> (raw)
In-Reply-To: <20191017101116.3d5okxmto5coecad@pengutronix.de>

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

On Thu, Oct 17, 2019 at 12:11:16PM +0200, Uwe Kleine-König wrote:
> On Thu, Oct 17, 2019 at 11:48:08AM +0200, Michal Vokáč wrote:
> > On 17. 10. 19 10:10, Uwe Kleine-König wrote:
> > > A previous change in the pwm core (namely 01ccf903edd6 ("pwm: Let
> > > pwm_get_state() return the last implemented state")) changed the
> > > semantic of pwm_get_state() and disclosed an (as it seems) common
> > > problem in lowlevel PWM drivers. By not relying on the period and duty
> > > cycle being retrievable from a disabled PWM this type of problem is
> > > worked around.
> > > 
> > > Apart from this issue only calling the pwm_get_state/pwm_apply_state
> > > combo once is also more effective.
> > > 
> > > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > > ---
> > > Hello,
> > > 
> > > There are now two reports about 01ccf903edd6 breaking a backlight. As
> > > far as I understand the problem this is a combination of the backend pwm
> > > driver yielding surprising results and the pwm-bl driver doing things
> > > more complicated than necessary.
> > > 
> > > So I guess this patch works around these problems. Still it would be
> > > interesting to find out the details in the imx driver that triggers the
> > > problem. So Adam, can you please instrument the pwm-imx27 driver to
> > > print *state at the beginning of pwm_imx27_apply() and the end of
> > > pwm_imx27_get_state() and provide the results?
> > > 
> > > Note I only compile tested this change.
> > 
> > Hi Uwe,
> > I was just about to respond to the "pwm_bl on i.MX6Q broken on 5.4-RC1+"
> > thread that I have a similar problem when you submitted this patch.
> > 
> > So here are my few cents:
> > 
> > My setup is as follows:
> >  - imx6dl-yapp4-draco with i.MX6Solo
> >  - backlight is controlled with inverted PWM signal
> >  - max brightness level = 32, default brightness level set to 32 in DT.
> > 
> > 1. Almost correct backlight behavior before 01ccf903edd6 ("pwm: Let
> >    pwm_get_state() return the last implemented state):
> > 
> >  - System boots to userspace and backlight is enabled all the time from
> >    power up.
> > 
> >    $ dmesg | grep state
> >    [    1.763381] get state end: -1811360608, enabled: 0
> 
> What is -1811360608? When I wrote "print *state" above, I thought about
> something like:
> 
> 	pr_info("%s: period: %u, duty: %u, polarity: %d, enabled: %d",
> 		__func__, state->period, state->duty_cycle, state->polarity, state->enabled);
> 
> A quick look into drivers/pwm/pwm-imx27.c shows that this is another
> driver that yields duty_cycle = 0 when the hardware is off.

It seems to me like the best recourse to fix this for now would be to
patch up the drivers that return 0 when the hardware is off by caching
the currently configured duty cycle.

How about the patch below?

Thierry

--- >8 ---
From 15a52a7f1b910804fabd74a5882befd3f9d6bb37 Mon Sep 17 00:00:00 2001
From: Thierry Reding <thierry.reding@gmail.com>
Date: Thu, 17 Oct 2019 12:56:00 +0200
Subject: [PATCH] pwm: imx27: Cache duty cycle register value

The hardware register containing the duty cycle value cannot be accessed
when the PWM is disabled. This causes the ->get_state() callback to read
back a duty cycle value of 0, which can confuse consumer drivers.

Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
---
 drivers/pwm/pwm-imx27.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index ae11d8577f18..4113d5cd4c62 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -85,6 +85,13 @@ struct pwm_imx27_chip {
 	struct clk	*clk_per;
 	void __iomem	*mmio_base;
 	struct pwm_chip	chip;
+
+	/*
+	 * The driver cannot read the current duty cycle from the hardware if
+	 * the hardware is disabled. Cache the last programmed duty cycle
+	 * value to return in that case.
+	 */
+	unsigned int duty_cycle;
 };
 
 #define to_pwm_imx27_chip(chip)	container_of(chip, struct pwm_imx27_chip, chip)
@@ -155,14 +162,17 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
 	tmp = NSEC_PER_SEC * (u64)(period + 2);
 	state->period = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
 
-	/* PWMSAR can be read only if PWM is enabled */
-	if (state->enabled) {
+	/*
+	 * PWMSAR can be read only if PWM is enabled. If the PWM is disabled,
+	 * use the cached value.
+	 */
+	if (state->enabled)
 		val = readl(imx->mmio_base + MX3_PWMSAR);
-		tmp = NSEC_PER_SEC * (u64)(val);
-		state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
-	} else {
-		state->duty_cycle = 0;
-	}
+	else
+		val = imx->duty_cycle;
+
+	tmp = NSEC_PER_SEC * (u64)(val);
+	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
 
 	if (!state->enabled)
 		pwm_imx27_clk_disable_unprepare(chip);
@@ -261,6 +271,13 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 		writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
 		writel(period_cycles, imx->mmio_base + MX3_PWMPR);
 
+		/*
+		 * Store the duty cycle for future reference in cases where
+		 * the MX3_PWMSAR register can't be read (i.e. when the PWM
+		 * is disabled).
+		 */
+		imx->duty_cycle = duty_cycles;
+
 		cr = MX3_PWMCR_PRESCALER_SET(prescale) |
 		     MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN |
 		     FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) |
-- 
2.23.0


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

WARNING: multiple messages have this Message-ID (diff)
From: Thierry Reding <thierry.reding@gmail.com>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: linux-pwm@vger.kernel.org,
	"Daniel Thompson" <daniel.thompson@linaro.org>,
	"Michal Vokáč" <michal.vokac@ysoft.com>,
	"Lee Jones" <lee.jones@linaro.org>,
	linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org,
	kernel@pengutronix.de, "Jingoo Han" <jingoohan1@gmail.com>,
	"Enric Balletbo i Serra" <enric.balletbo@collabora.com>,
	"Adam Ford" <aford173@gmail.com>
Subject: Re: [PATCH] backlight: pwm_bl: configure pwm only once per backlight toggle
Date: Thu, 17 Oct 2019 13:11:31 +0200	[thread overview]
Message-ID: <20191017111131.GB3122066@ulmo> (raw)
In-Reply-To: <20191017101116.3d5okxmto5coecad@pengutronix.de>


[-- Attachment #1.1: Type: text/plain, Size: 5504 bytes --]

On Thu, Oct 17, 2019 at 12:11:16PM +0200, Uwe Kleine-König wrote:
> On Thu, Oct 17, 2019 at 11:48:08AM +0200, Michal Vokáč wrote:
> > On 17. 10. 19 10:10, Uwe Kleine-König wrote:
> > > A previous change in the pwm core (namely 01ccf903edd6 ("pwm: Let
> > > pwm_get_state() return the last implemented state")) changed the
> > > semantic of pwm_get_state() and disclosed an (as it seems) common
> > > problem in lowlevel PWM drivers. By not relying on the period and duty
> > > cycle being retrievable from a disabled PWM this type of problem is
> > > worked around.
> > > 
> > > Apart from this issue only calling the pwm_get_state/pwm_apply_state
> > > combo once is also more effective.
> > > 
> > > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > > ---
> > > Hello,
> > > 
> > > There are now two reports about 01ccf903edd6 breaking a backlight. As
> > > far as I understand the problem this is a combination of the backend pwm
> > > driver yielding surprising results and the pwm-bl driver doing things
> > > more complicated than necessary.
> > > 
> > > So I guess this patch works around these problems. Still it would be
> > > interesting to find out the details in the imx driver that triggers the
> > > problem. So Adam, can you please instrument the pwm-imx27 driver to
> > > print *state at the beginning of pwm_imx27_apply() and the end of
> > > pwm_imx27_get_state() and provide the results?
> > > 
> > > Note I only compile tested this change.
> > 
> > Hi Uwe,
> > I was just about to respond to the "pwm_bl on i.MX6Q broken on 5.4-RC1+"
> > thread that I have a similar problem when you submitted this patch.
> > 
> > So here are my few cents:
> > 
> > My setup is as follows:
> >  - imx6dl-yapp4-draco with i.MX6Solo
> >  - backlight is controlled with inverted PWM signal
> >  - max brightness level = 32, default brightness level set to 32 in DT.
> > 
> > 1. Almost correct backlight behavior before 01ccf903edd6 ("pwm: Let
> >    pwm_get_state() return the last implemented state):
> > 
> >  - System boots to userspace and backlight is enabled all the time from
> >    power up.
> > 
> >    $ dmesg | grep state
> >    [    1.763381] get state end: -1811360608, enabled: 0
> 
> What is -1811360608? When I wrote "print *state" above, I thought about
> something like:
> 
> 	pr_info("%s: period: %u, duty: %u, polarity: %d, enabled: %d",
> 		__func__, state->period, state->duty_cycle, state->polarity, state->enabled);
> 
> A quick look into drivers/pwm/pwm-imx27.c shows that this is another
> driver that yields duty_cycle = 0 when the hardware is off.

It seems to me like the best recourse to fix this for now would be to
patch up the drivers that return 0 when the hardware is off by caching
the currently configured duty cycle.

How about the patch below?

Thierry

--- >8 ---
From 15a52a7f1b910804fabd74a5882befd3f9d6bb37 Mon Sep 17 00:00:00 2001
From: Thierry Reding <thierry.reding@gmail.com>
Date: Thu, 17 Oct 2019 12:56:00 +0200
Subject: [PATCH] pwm: imx27: Cache duty cycle register value

The hardware register containing the duty cycle value cannot be accessed
when the PWM is disabled. This causes the ->get_state() callback to read
back a duty cycle value of 0, which can confuse consumer drivers.

Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
---
 drivers/pwm/pwm-imx27.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
index ae11d8577f18..4113d5cd4c62 100644
--- a/drivers/pwm/pwm-imx27.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -85,6 +85,13 @@ struct pwm_imx27_chip {
 	struct clk	*clk_per;
 	void __iomem	*mmio_base;
 	struct pwm_chip	chip;
+
+	/*
+	 * The driver cannot read the current duty cycle from the hardware if
+	 * the hardware is disabled. Cache the last programmed duty cycle
+	 * value to return in that case.
+	 */
+	unsigned int duty_cycle;
 };
 
 #define to_pwm_imx27_chip(chip)	container_of(chip, struct pwm_imx27_chip, chip)
@@ -155,14 +162,17 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
 	tmp = NSEC_PER_SEC * (u64)(period + 2);
 	state->period = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
 
-	/* PWMSAR can be read only if PWM is enabled */
-	if (state->enabled) {
+	/*
+	 * PWMSAR can be read only if PWM is enabled. If the PWM is disabled,
+	 * use the cached value.
+	 */
+	if (state->enabled)
 		val = readl(imx->mmio_base + MX3_PWMSAR);
-		tmp = NSEC_PER_SEC * (u64)(val);
-		state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
-	} else {
-		state->duty_cycle = 0;
-	}
+	else
+		val = imx->duty_cycle;
+
+	tmp = NSEC_PER_SEC * (u64)(val);
+	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
 
 	if (!state->enabled)
 		pwm_imx27_clk_disable_unprepare(chip);
@@ -261,6 +271,13 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 		writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
 		writel(period_cycles, imx->mmio_base + MX3_PWMPR);
 
+		/*
+		 * Store the duty cycle for future reference in cases where
+		 * the MX3_PWMSAR register can't be read (i.e. when the PWM
+		 * is disabled).
+		 */
+		imx->duty_cycle = duty_cycles;
+
 		cr = MX3_PWMCR_PRESCALER_SET(prescale) |
 		     MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN |
 		     FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) |
-- 
2.23.0


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

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2019-10-17 11:11 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-17  8:10 [PATCH] backlight: pwm_bl: configure pwm only once per backlight toggle Uwe Kleine-König
2019-10-17  8:10 ` Uwe Kleine-König
2019-10-17  9:48 ` Michal Vokáč
2019-10-17  9:48   ` Michal Vokáč
2019-10-17 10:11   ` Uwe Kleine-König
2019-10-17 10:11     ` Uwe Kleine-König
2019-10-17 11:11     ` Thierry Reding [this message]
2019-10-17 11:11       ` Thierry Reding
2019-10-17 12:09       ` Uwe Kleine-König
2019-10-17 12:09         ` Uwe Kleine-König
2019-10-17 12:59         ` Thierry Reding
2019-10-17 12:59           ` Thierry Reding
2019-10-17 13:58           ` Michal Vokáč
2019-10-17 13:58             ` Michal Vokáč
2019-10-17 15:14             ` Thierry Reding
2019-10-17 15:14               ` Thierry Reding
2019-10-17 17:07               ` Adam Ford
2019-10-17 17:07                 ` Adam Ford
2019-10-17 17:13                 ` Thierry Reding
2019-10-17 17:13                   ` Thierry Reding
2019-10-17 17:44                   ` Adam Ford
2019-10-17 17:44                     ` Adam Ford
2019-10-18  9:36                     ` Michal Vokáč
2019-10-18  9:36                       ` Michal Vokáč
2019-10-23 14:16                       ` Adam Ford
2019-10-23 14:16                         ` Adam Ford
2019-10-23 14:23                         ` Fabio Estevam
2019-10-23 14:23                           ` Fabio Estevam
2019-10-23 15:05                           ` Uwe Kleine-König
2019-10-23 15:05                             ` Uwe Kleine-König
2019-10-17 20:25               ` Uwe Kleine-König
2019-10-17 20:25                 ` Uwe Kleine-König
2019-10-17 19:44           ` Uwe Kleine-König
2019-10-17 19:44             ` Uwe Kleine-König
2019-10-17 13:30       ` Adam Ford
2019-10-17 13:30         ` Adam Ford
2019-10-17 13:59         ` Adam Ford
2019-10-17 13:59           ` Adam Ford
2019-10-17 10:59   ` Michal Vokáč
2019-10-17 10:59     ` Michal Vokáč
2019-10-17 20:19     ` Uwe Kleine-König
2019-10-17 20:19       ` Uwe Kleine-König
2019-10-17 11:47 ` Daniel Thompson
2019-10-17 11:47   ` Daniel Thompson
2019-10-17 12:19   ` Uwe Kleine-König
2019-10-17 12:19     ` Uwe Kleine-König
2019-10-17 12:34     ` Adam Ford
2019-10-17 12:34       ` Adam Ford
2019-10-17 12:40       ` Adam Ford
2019-10-17 12:40         ` Adam Ford
2019-10-17 13:05         ` Thierry Reding
2019-10-17 13:05           ` Thierry Reding
2019-10-17 13:09           ` Adam Ford
2019-10-17 13:09             ` Adam Ford
2019-10-17 13:18     ` Daniel Thompson
2019-10-17 13:18       ` Daniel Thompson
2019-10-17 18:28       ` Uwe Kleine-König
2019-10-17 18:28         ` Uwe Kleine-König
2019-10-17 12:53 ` Adam Ford
2019-10-17 12:53   ` Adam Ford
2019-10-17 14:51 ` Adam Ford
2019-10-17 14:51   ` Adam Ford

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=20191017111131.GB3122066@ulmo \
    --to=thierry.reding@gmail.com \
    --cc=aford173@gmail.com \
    --cc=daniel.thompson@linaro.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=enric.balletbo@collabora.com \
    --cc=jingoohan1@gmail.com \
    --cc=kernel@pengutronix.de \
    --cc=lee.jones@linaro.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=michal.vokac@ysoft.com \
    --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: link
Be 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.