diff options
author | Dilan Lee <dilee@nvidia.com> | 2011-07-27 18:21:55 +0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2011-08-29 10:59:17 -0700 |
commit | 5f939ba69cfb57681ed829b92de94f14cf354acc (patch) | |
tree | 4085de3a582c8ccaa0ca356b696c87a7844e178f /drivers/video | |
parent | fd00e682c0ccd38ced77a91af4442d38d8cb2e09 (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.c | 71 |
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; +} |