diff mbox

[U-Boot] sunxi: display: Use PWM to drive backlight where applicable

Message ID 1471613410-9840-1-git-send-email-hdegoede@redhat.com
State Superseded
Delegated to: Hans de Goede
Headers show

Commit Message

Hans de Goede Aug. 19, 2016, 1:30 p.m. UTC
When the backlight's pwm input is connected to a pwm output of the SoC,
actually use pwm to drive the backlight.

The mean reason for doing this is to fix the backlight turning off
for aprox. 1 second while the kernel is booting. This is caused by
the kernel actually using pwm to drive the backlight, so that it
can dim the backlight. First the pwm driver loads and switches the
pinmux for the pin driving the backlight's pwm input to the pwm
controller. Then about 1s later the actual backlight driver loads
and tells the pwm driver to actually update the pwm settings, which
have a power-on-reset value of "off".

An additional advantage is that this allows us to initatiate the
backlight at 80%, which is the kernel default, avoiding a brightness
change while the kernel loads.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/include/asm/arch-sunxi/cpu_sun4i.h |  1 +
 arch/arm/include/asm/arch-sunxi/gpio.h      |  1 +
 arch/arm/include/asm/arch-sunxi/pwm.h       | 27 +++++++++++++++++++++++++++
 drivers/video/sunxi_display.c               | 12 +++++++++++-
 4 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/include/asm/arch-sunxi/pwm.h

Comments

Peter Korsgaard Aug. 22, 2016, 2:01 p.m. UTC | #1
>>>>> "Hans" == Hans de Goede <hdegoede@redhat.com> writes:

 > When the backlight's pwm input is connected to a pwm output of the SoC,
 > actually use pwm to drive the backlight.

 > The mean reason for doing this is to fix the backlight turning off
 > for aprox. 1 second while the kernel is booting. This is caused by
 > the kernel actually using pwm to drive the backlight, so that it
 > can dim the backlight. First the pwm driver loads and switches the
 > pinmux for the pin driving the backlight's pwm input to the pwm
 > controller. Then about 1s later the actual backlight driver loads
 > and tells the pwm driver to actually update the pwm settings, which
 > have a power-on-reset value of "off".

 > An additional advantage is that this allows us to initatiate the
 > backlight at 80%, which is the kernel default, avoiding a brightness
 > change while the kernel loads.

Nice!

 > Signed-off-by: Hans de Goede <hdegoede@redhat.com>
 > ---
 >  arch/arm/include/asm/arch-sunxi/cpu_sun4i.h |  1 +
 >  arch/arm/include/asm/arch-sunxi/gpio.h      |  1 +
 >  arch/arm/include/asm/arch-sunxi/pwm.h       | 27 +++++++++++++++++++++++++++
 >  drivers/video/sunxi_display.c               | 12 +++++++++++-
 >  4 files changed, 40 insertions(+), 1 deletion(-)
 >  create mode 100644 arch/arm/include/asm/arch-sunxi/pwm.h

 > diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
 > index cd009d7..a5f396e 100644
 > --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
 > +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
 > @@ -76,6 +76,7 @@
 >  #define SUNXI_INTC_BASE			0x01c20400
 >  #define SUNXI_PIO_BASE			0x01c20800
 >  #define SUNXI_TIMER_BASE		0x01c20c00
 > +#define SUNXI_PWM_BASE			0x01c20e00
 >  #define SUNXI_SPDIF_BASE		0x01c21000
 >  #define SUNXI_AC97_BASE			0x01c21400
 >  #define SUNXI_IR0_BASE			0x01c21800
 > diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
 > index bff7d14..ef426ae 100644
 > --- a/arch/arm/include/asm/arch-sunxi/gpio.h
 > +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
 > @@ -150,6 +150,7 @@ enum sunxi_gpio_number {
 >  #define SUN6I_GPA_SDC3		4
 >  #define SUN8I_H3_GPA_UART0	2
 
 > +#define SUN4I_GPB_PWM		2

Using this define for the ! SUN4I / SUN5I case is a bit icky (even if
they today happen to be the same numerical value). Perhaps introduce a
SUNXI_PWM_MODE indirection like you do for SUNXI_PWM_PIN0 would be
nicer.


>  #define SUN4I_GPB_TWI0		2
 >  #define SUN4I_GPB_TWI1		2
 >  #define SUN5I_GPB_TWI1		2
 > diff --git a/arch/arm/include/asm/arch-sunxi/pwm.h b/arch/arm/include/asm/arch-sunxi/pwm.h
 > new file mode 100644
 > index 0000000..ec997a6
 > --- /dev/null
 > +++ b/arch/arm/include/asm/arch-sunxi/pwm.h
 > @@ -0,0 +1,27 @@
 > +/*
 > + * (C) Copyright 2016 Hans de Goede <hdegoede@redhat.com>
 > + *
 > + * SPDX-License-Identifier:	GPL-2.0+
 > + */
 > +
 > +#ifndef _SUNXI_PWM_H
 > +#define _SUNXI_PWM_H
 > +
 > +#define SUNXI_PWM_CTRL_REG		(SUNXI_PWM_BASE + 0)
 > +#define SUNXI_PWM_CH0_PERIOD		(SUNXI_PWM_BASE + 4)
 > +
 > +#define SUNXI_PWM_CTRL_PRESCALE0(x)	((x) & 0xf)
 > +#define SUNXI_PWM_CTRL_ENABLE0		(0x5 << 4)
 > +#define SUNXI_PWM_CTRL_POLARITY0(x)	((x) << 5)
 > +
 > +#define SUNXI_PWM_PERIOD_80PCT		0x04af03c0
 > +
 > +#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN5I
 > +#define SUNXI_PWM_PIN0			SUNXI_GPB(2)
 > +#endif
 > +

This should afaik work for sun6i as well if you add:

#if defined CONFIG_MACH_SUN6I
#define SUNXI_PWM_PIN0  SUNXI_GPH(13)
#endif

E.G. the Yones Toptech BS1078v2 uses this.

I'll try to find some time to test it.
Hans de Goede Aug. 26, 2016, 2:01 p.m. UTC | #2
Hi,

On 22-08-16 16:01, Peter Korsgaard wrote:
>>>>>> "Hans" == Hans de Goede <hdegoede@redhat.com> writes:
>
>  > When the backlight's pwm input is connected to a pwm output of the SoC,
>  > actually use pwm to drive the backlight.
>
>  > The mean reason for doing this is to fix the backlight turning off
>  > for aprox. 1 second while the kernel is booting. This is caused by
>  > the kernel actually using pwm to drive the backlight, so that it
>  > can dim the backlight. First the pwm driver loads and switches the
>  > pinmux for the pin driving the backlight's pwm input to the pwm
>  > controller. Then about 1s later the actual backlight driver loads
>  > and tells the pwm driver to actually update the pwm settings, which
>  > have a power-on-reset value of "off".
>
>  > An additional advantage is that this allows us to initatiate the
>  > backlight at 80%, which is the kernel default, avoiding a brightness
>  > change while the kernel loads.
>
> Nice!
>
>  > Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>  > ---
>  >  arch/arm/include/asm/arch-sunxi/cpu_sun4i.h |  1 +
>  >  arch/arm/include/asm/arch-sunxi/gpio.h      |  1 +
>  >  arch/arm/include/asm/arch-sunxi/pwm.h       | 27 +++++++++++++++++++++++++++
>  >  drivers/video/sunxi_display.c               | 12 +++++++++++-
>  >  4 files changed, 40 insertions(+), 1 deletion(-)
>  >  create mode 100644 arch/arm/include/asm/arch-sunxi/pwm.h
>
>  > diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
>  > index cd009d7..a5f396e 100644
>  > --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
>  > +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
>  > @@ -76,6 +76,7 @@
>  >  #define SUNXI_INTC_BASE			0x01c20400
>  >  #define SUNXI_PIO_BASE			0x01c20800
>  >  #define SUNXI_TIMER_BASE		0x01c20c00
>  > +#define SUNXI_PWM_BASE			0x01c20e00
>  >  #define SUNXI_SPDIF_BASE		0x01c21000
>  >  #define SUNXI_AC97_BASE			0x01c21400
>  >  #define SUNXI_IR0_BASE			0x01c21800
>  > diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
>  > index bff7d14..ef426ae 100644
>  > --- a/arch/arm/include/asm/arch-sunxi/gpio.h
>  > +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
>  > @@ -150,6 +150,7 @@ enum sunxi_gpio_number {
>  >  #define SUN6I_GPA_SDC3		4
>  >  #define SUN8I_H3_GPA_UART0	2
>
>  > +#define SUN4I_GPB_PWM		2
>
> Using this define for the ! SUN4I / SUN5I case is a bit icky (even if
> they today happen to be the same numerical value). Perhaps introduce a
> SUNXI_PWM_MODE indirection like you do for SUNXI_PWM_PIN0 would be
> nicer.

Ack, fixed for v2.

>
>
>>  #define SUN4I_GPB_TWI0		2
>  >  #define SUN4I_GPB_TWI1		2
>  >  #define SUN5I_GPB_TWI1		2
>  > diff --git a/arch/arm/include/asm/arch-sunxi/pwm.h b/arch/arm/include/asm/arch-sunxi/pwm.h
>  > new file mode 100644
>  > index 0000000..ec997a6
>  > --- /dev/null
>  > +++ b/arch/arm/include/asm/arch-sunxi/pwm.h
>  > @@ -0,0 +1,27 @@
>  > +/*
>  > + * (C) Copyright 2016 Hans de Goede <hdegoede@redhat.com>
>  > + *
>  > + * SPDX-License-Identifier:	GPL-2.0+
>  > + */
>  > +
>  > +#ifndef _SUNXI_PWM_H
>  > +#define _SUNXI_PWM_H
>  > +
>  > +#define SUNXI_PWM_CTRL_REG		(SUNXI_PWM_BASE + 0)
>  > +#define SUNXI_PWM_CH0_PERIOD		(SUNXI_PWM_BASE + 4)
>  > +
>  > +#define SUNXI_PWM_CTRL_PRESCALE0(x)	((x) & 0xf)
>  > +#define SUNXI_PWM_CTRL_ENABLE0		(0x5 << 4)
>  > +#define SUNXI_PWM_CTRL_POLARITY0(x)	((x) << 5)
>  > +
>  > +#define SUNXI_PWM_PERIOD_80PCT		0x04af03c0
>  > +
>  > +#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN5I
>  > +#define SUNXI_PWM_PIN0			SUNXI_GPB(2)
>  > +#endif
>  > +
>
> This should afaik work for sun6i as well if you add:
>
> #if defined CONFIG_MACH_SUN6I
> #define SUNXI_PWM_PIN0  SUNXI_GPH(13)
> #endif

I did not do this because the kernel does not yet
have the backlight(s) described in dts. But that really
is not a good reason to do this, so I've implemented this
and tested it on one of my own A31s tablets, this is also
included in v2.

Regards,

Hans
diff mbox

Patch

diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index cd009d7..a5f396e 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -76,6 +76,7 @@ 
 #define SUNXI_INTC_BASE			0x01c20400
 #define SUNXI_PIO_BASE			0x01c20800
 #define SUNXI_TIMER_BASE		0x01c20c00
+#define SUNXI_PWM_BASE			0x01c20e00
 #define SUNXI_SPDIF_BASE		0x01c21000
 #define SUNXI_AC97_BASE			0x01c21400
 #define SUNXI_IR0_BASE			0x01c21800
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index bff7d14..ef426ae 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -150,6 +150,7 @@  enum sunxi_gpio_number {
 #define SUN6I_GPA_SDC3		4
 #define SUN8I_H3_GPA_UART0	2
 
+#define SUN4I_GPB_PWM		2
 #define SUN4I_GPB_TWI0		2
 #define SUN4I_GPB_TWI1		2
 #define SUN5I_GPB_TWI1		2
diff --git a/arch/arm/include/asm/arch-sunxi/pwm.h b/arch/arm/include/asm/arch-sunxi/pwm.h
new file mode 100644
index 0000000..ec997a6
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/pwm.h
@@ -0,0 +1,27 @@ 
+/*
+ * (C) Copyright 2016 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SUNXI_PWM_H
+#define _SUNXI_PWM_H
+
+#define SUNXI_PWM_CTRL_REG		(SUNXI_PWM_BASE + 0)
+#define SUNXI_PWM_CH0_PERIOD		(SUNXI_PWM_BASE + 4)
+
+#define SUNXI_PWM_CTRL_PRESCALE0(x)	((x) & 0xf)
+#define SUNXI_PWM_CTRL_ENABLE0		(0x5 << 4)
+#define SUNXI_PWM_CTRL_POLARITY0(x)	((x) << 5)
+
+#define SUNXI_PWM_PERIOD_80PCT		0x04af03c0
+
+#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN5I
+#define SUNXI_PWM_PIN0			SUNXI_GPB(2)
+#endif
+
+#if defined CONFIG_MACH_SUN8I_A23 || defined CONFIG_MACH_SUN8I_A33
+#define SUNXI_PWM_PIN0			SUNXI_GPH(0)
+#endif
+
+#endif
diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index 56f6c8e..a152cf2 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -12,6 +12,7 @@ 
 #include <asm/arch/clock.h>
 #include <asm/arch/display.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/pwm.h>
 #include <asm/global_data.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
@@ -34,7 +35,6 @@ 
 #define PWM_ON 1
 #define PWM_OFF 0
 #endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 enum sunxi_monitor {
@@ -743,6 +743,16 @@  static void sunxi_lcdc_backlight_enable(void)
 		gpio_direction_output(pin, 1);
 
 	pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM);
+#ifdef SUNXI_PWM_PIN0
+	if (pin == SUNXI_PWM_PIN0) {
+		writel(SUNXI_PWM_CTRL_POLARITY0(PWM_ON) |
+		       SUNXI_PWM_CTRL_ENABLE0 |
+		       SUNXI_PWM_CTRL_PRESCALE0(0xf), SUNXI_PWM_CTRL_REG);
+		writel(SUNXI_PWM_PERIOD_80PCT, SUNXI_PWM_CH0_PERIOD);
+		sunxi_gpio_set_cfgpin(pin, SUN4I_GPB_PWM);
+		return;
+	}
+#endif
 	if (pin >= 0)
 		gpio_direction_output(pin, PWM_ON);
 }