public inbox for linux-fbdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] backlight: pwm_bl: configure pwm only once per backlight toggle
@ 2019-10-17  8:10 Uwe Kleine-König
  2019-10-17  9:48 ` Michal Vokáč
                   ` (3 more replies)
  0 siblings, 4 replies; 31+ messages in thread
From: Uwe Kleine-König @ 2019-10-17  8:10 UTC (permalink / raw)
  To: Adam Ford, Enric Balletbo i Serra, Daniel Thompson, Lee Jones,
	Jingoo Han
  Cc: linux-pwm, linux-fbdev, Thierry Reding, kernel, dri-devel

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.

Best regards
Uwe

 drivers/video/backlight/pwm_bl.c | 34 +++++++++++---------------------
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 746eebc411df..ddebd62b3978 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -42,10 +42,8 @@ struct pwm_bl_data {
 
 static void pwm_backlight_power_on(struct pwm_bl_data *pb)
 {
-	struct pwm_state state;
 	int err;
 
-	pwm_get_state(pb->pwm, &state);
 	if (pb->enabled)
 		return;
 
@@ -53,9 +51,6 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb)
 	if (err < 0)
 		dev_err(pb->dev, "failed to enable power supply\n");
 
-	state.enabled = true;
-	pwm_apply_state(pb->pwm, &state);
-
 	if (pb->post_pwm_on_delay)
 		msleep(pb->post_pwm_on_delay);
 
@@ -67,40 +62,27 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb)
 
 static void pwm_backlight_power_off(struct pwm_bl_data *pb)
 {
-	struct pwm_state state;
-
-	pwm_get_state(pb->pwm, &state);
-	if (!pb->enabled)
-		return;
-
 	if (pb->enable_gpio)
 		gpiod_set_value_cansleep(pb->enable_gpio, 0);
 
 	if (pb->pwm_off_delay)
 		msleep(pb->pwm_off_delay);
 
-	state.enabled = false;
-	state.duty_cycle = 0;
-	pwm_apply_state(pb->pwm, &state);
-
 	regulator_disable(pb->power_supply);
 	pb->enabled = false;
 }
 
-static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
+static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness, struct pwm_state *state)
 {
 	unsigned int lth = pb->lth_brightness;
-	struct pwm_state state;
 	u64 duty_cycle;
 
-	pwm_get_state(pb->pwm, &state);
-
 	if (pb->levels)
 		duty_cycle = pb->levels[brightness];
 	else
 		duty_cycle = brightness;
 
-	duty_cycle *= state.period - lth;
+	duty_cycle *= state->period - lth;
 	do_div(duty_cycle, pb->scale);
 
 	return duty_cycle + lth;
@@ -122,12 +104,20 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
 
 	if (brightness > 0) {
 		pwm_get_state(pb->pwm, &state);
-		state.duty_cycle = compute_duty_cycle(pb, brightness);
+		state.duty_cycle = compute_duty_cycle(pb, brightness, &state);
+		state.enabled = true;
 		pwm_apply_state(pb->pwm, &state);
+
 		pwm_backlight_power_on(pb);
-	} else
+	} else {
 		pwm_backlight_power_off(pb);
 
+		pwm_get_state(pb->pwm, &state);
+		state.enabled = false;
+		state.duty_cycle = 0;
+		pwm_apply_state(pb->pwm, &state);
+	}
+
 	if (pb->notify_after)
 		pb->notify_after(pb->dev, brightness);
 
-- 
2.23.0

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

end of thread, other threads:[~2019-10-23 15:05 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-10-17  8:10 [PATCH] backlight: pwm_bl: configure pwm only once per backlight toggle Uwe Kleine-König
2019-10-17  9:48 ` Michal Vokáč
2019-10-17 10:11   ` Uwe Kleine-König
2019-10-17 11:11     ` Thierry Reding
2019-10-17 12:09       ` Uwe Kleine-König
2019-10-17 12:59         ` Thierry Reding
2019-10-17 13:58           ` Michal Vokáč
2019-10-17 15:14             ` Thierry Reding
2019-10-17 17:07               ` Adam Ford
2019-10-17 17:13                 ` Thierry Reding
2019-10-17 17:44                   ` Adam Ford
2019-10-18  9:36                     ` Michal Vokáč
2019-10-23 14:16                       ` Adam Ford
2019-10-23 14:23                         ` Fabio Estevam
2019-10-23 15:05                           ` 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 13:30       ` Adam Ford
2019-10-17 13:59         ` Adam Ford
2019-10-17 10:59   ` Michal Vokáč
2019-10-17 20:19     ` Uwe Kleine-König
2019-10-17 11:47 ` Daniel Thompson
2019-10-17 12:19   ` Uwe Kleine-König
2019-10-17 12:34     ` Adam Ford
2019-10-17 12:40       ` Adam Ford
2019-10-17 13:05         ` Thierry Reding
2019-10-17 13:09           ` Adam Ford
2019-10-17 13:18     ` Daniel Thompson
2019-10-17 18:28       ` Uwe Kleine-König
2019-10-17 12:53 ` Adam Ford
2019-10-17 14:51 ` Adam Ford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox