summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorDilan Lee <dilee@nvidia.com>2011-07-27 18:21:55 +0800
committerSimon Glass <sjg@chromium.org>2011-08-29 10:59:17 -0700
commit5f939ba69cfb57681ed829b92de94f14cf354acc (patch)
tree4085de3a582c8ccaa0ca356b696c87a7844e178f /drivers/video
parentfd00e682c0ccd38ced77a91af4442d38d8cb2e09 (diff)
CHROMIUM: ARM: tegra2: Change panel power on sequence to meet timing
LCD panels require delays in the power-on sequence. This adds those with a facility for the ftd to specify them. This introduces significant boot delays - around 120ms at minimum. We will address these with further work. BUG=chrome-os-partner:4854 TEST=Probe these power signals on Aebl with a scope. Boot on Seaboard Change-Id: Ie12abd52b66db5966de985a102aaadaea7f3d970 Signed-off-by: Dilan Lee <dilee@nvidia.com> Reviewed-on: http://gerrit.chromium.org/gerrit/4194 Reviewed-by: Doug Anderson <dianders@chromium.org> Tested-by: Doug Anderson <dianders@chromium.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/tegra2.c71
1 files changed, 66 insertions, 5 deletions
diff --git a/drivers/video/tegra2.c b/drivers/video/tegra2.c
index 047c0670630..2600d8d91cd 100644
--- a/drivers/video/tegra2.c
+++ b/drivers/video/tegra2.c
@@ -24,6 +24,7 @@
#include <fdt_decode.h>
#include <asm/clocks.h>
#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <asm/arch/pwfm.h>
@@ -32,6 +33,8 @@
DECLARE_GLOBAL_DATA_PTR;
+unsigned long timer_last;
+
int lcd_line_length;
int lcd_color_fg;
int lcd_color_bg;
@@ -106,20 +109,57 @@ struct pingroup_config pinmux_cros_1[] = {
PINMUX(SLXD, SPDIF, NORMAL, NORMAL),
};
+/* Initialize the Tegra LCD pinmuxs */
+static void init_lcd_pinmux(struct fdt_lcd *config)
+{
+ /* TODO: put pinmux into the FDT */
+ pinmux_config_table(pinmux_cros_1, ARRAY_SIZE(pinmux_cros_1));
+
+ fdt_setup_gpio(&config->panel_vdd);
+ fdt_setup_gpio(&config->lvds_shutdown);
+ fdt_setup_gpio(&config->backlight_vdd);
+ fdt_setup_gpio(&config->backlight_en);
+
+ gpio_set_value(config->panel_vdd.gpio, 1);
+ udelay(config->panel_timings[0] * 1000);
+
+ gpio_set_value(config->lvds_shutdown.gpio, 1);
+ timer_last = timer_get_us();
+}
+
/* Initialize the Tegra LCD panel and controller */
void init_lcd(struct fdt_lcd *config)
{
clk_init();
-
- /* TODO: put pinmux into the FDT */
- pinmux_config_table(pinmux_cros_1, ARRAY_SIZE(pinmux_cros_1));
power_enable_partition(POWERP_3D);
- fdt_setup_gpios(config->gpios);
-
tegra2_display_register(config);
+}
+
+static void init_lcd_pwm(struct fdt_lcd *config)
+{
+ long pre_delay;
+
+ /*
+ * Compare the current timer valuse with the timer_last to
+ * figure out the pre_delay which is the passed time from
+ * the end of init_lcd_pinmux to now.
+ * If the required delay(timings[1]) is bigger than pre_delay,
+ * we have to do a delay (timings[1] - pre_delay) to make
+ * sure the required delay(timings[1]) has passed.
+ */
+ pre_delay = timer_get_us() - timer_last;
+
+ if ((long)(config->panel_timings[1] * 1000) > pre_delay)
+ udelay((long)(config->panel_timings[1] * 1000) - pre_delay);
+
+ gpio_set_value(config->backlight_vdd.gpio, 1);
+ udelay(config->panel_timings[2] * 1000);
/* Enable PWM at 15/16 high, divider 1 */
pwfm_setup(config->pwfm, 1, 0xdf, 1);
+ udelay(config->panel_timings[3] * 1000);
+
+ gpio_set_value(config->backlight_en.gpio, 1);
}
void lcd_cursor_size(ushort width, ushort height)
@@ -229,6 +269,16 @@ void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
void lcd_enable(void)
{
+ struct fdt_lcd config;
+
+ /* get panel details */
+ if (fdt_decode_lcd(gd->blob, &config)) {
+ printf("No LCD information in device tree\n");
+ return;
+ }
+
+ /* call board specific hw init for backlight PWM */
+ init_lcd_pwm(&config);
}
void lcd_early_init(const void *blob)
@@ -240,3 +290,14 @@ void lcd_early_init(const void *blob)
update_panel_size(&config);
}
+int lcd_pinmux_early_init(const void *blob)
+{
+ struct fdt_lcd config;
+
+ /* get panel details */
+ if (fdt_decode_lcd(gd->blob, &config))
+ return -1;
+
+ init_lcd_pinmux(&config);
+ return 0;
+}