sunxi: display: Use PWM to drive backlight where applicable
authorHans de Goede <hdegoede@redhat.com>
Fri, 19 Aug 2016 13:25:41 +0000 (15:25 +0200)
committerHans de Goede <hdegoede@redhat.com>
Fri, 26 Aug 2016 14:58:37 +0000 (16:58 +0200)
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>
Reviewed by: Peter Korsgaard <peter@korsgaard.com>

arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
arch/arm/include/asm/arch-sunxi/gpio.h
arch/arm/include/asm/arch-sunxi/pwm.h [new file with mode: 0644]
drivers/video/sunxi_display.c

index cd009d7ccc2332075943956bf1387c42be5bb704..5f938309150ed0b77e935f3a2c71f3e15fe2e2da 100644 (file)
 #define SUNXI_INTC_BASE                        0x01c20400
 #define SUNXI_PIO_BASE                 0x01c20800
 #define SUNXI_TIMER_BASE               0x01c20c00
+#ifndef CONFIG_SUNXI_GEN_SUN6I
+#define SUNXI_PWM_BASE                 0x01c20e00
+#endif
 #define SUNXI_SPDIF_BASE               0x01c21000
+#ifdef CONFIG_SUNXI_GEN_SUN6I
+#define SUNXI_PWM_BASE                 0x01c21400
+#else
 #define SUNXI_AC97_BASE                        0x01c21400
+#endif
 #define SUNXI_IR0_BASE                 0x01c21800
 #define SUNXI_IR1_BASE                 0x01c21c00
 
index bff7d1453f12d71624ffdd08f25ee66b36fda398..85a4ec3b0e8f4397ea9d225606579a0668ae60ce 100644 (file)
@@ -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
@@ -186,6 +187,8 @@ enum sunxi_gpio_number {
 #define SUN6I_GPG_TWI3         2
 #define SUN5I_GPG_UART1                4
 
+#define SUN6I_GPH_PWM          2
+#define SUN8I_GPH_PWM          2
 #define SUN4I_GPH_SDC1         5
 #define SUN6I_GPH_TWI0         2
 #define SUN8I_GPH_TWI0         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 (file)
index 0000000..5884b5d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * (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)
+#define SUNXI_PWM_MUX                  SUN4I_GPB_PWM
+#endif
+
+#if defined CONFIG_MACH_SUN6I
+#define SUNXI_PWM_PIN0                 SUNXI_GPH(13)
+#define SUNXI_PWM_MUX                  SUN6I_GPH_PWM
+#endif
+
+#if defined CONFIG_MACH_SUN8I_A23 || defined CONFIG_MACH_SUN8I_A33
+#define SUNXI_PWM_PIN0                 SUNXI_GPH(0)
+#define SUNXI_PWM_MUX                  SUN8I_GPH_PWM
+#endif
+
+#endif
index 56f6c8e3497377653a076852875750e112813bb0..50b16a9129f8e10aa19bc9507ce2ed33d2e41444 100644 (file)
@@ -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>
@@ -743,6 +744,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, SUNXI_PWM_MUX);
+               return;
+       }
+#endif
        if (pin >= 0)
                gpio_direction_output(pin, PWM_ON);
 }