diff options
author | Rakesh Iyer <riyer@nvidia.com> | 2012-05-10 13:24:53 -0700 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2012-06-06 06:35:04 -0700 |
commit | f1319c75b57101ac97b2c32d8ccb0212cbeb7c71 (patch) | |
tree | 129384e8fafbd8106d232c9091d8214ce7b99bfe /arch/arm/mach-tegra | |
parent | f61bdbde09605793cfa05f7c59545c62b5e08aa6 (diff) |
ARM: tegra: cardhu: add support for E1506 panel
Add support for 720p DSI panel on the E1506.
Bug 978305.
Change-Id: If76d2754eebc9e612c2ce006fa73ead7ebb1a109
Signed-off-by: Rakesh Iyer <riyer@nvidia.com>
Reviewed-on: http://git-master/r/104894
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Kevin Huang (Eng-SW) <kevinh@nvidia.com>
Reviewed-by: Jon Mayo <jmayo@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu-panel.c | 194 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu-pinmux.c | 22 |
2 files changed, 201 insertions, 15 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-panel.c b/arch/arm/mach-tegra/board-cardhu-panel.c index a62171060b84..b85c542e96f8 100644 --- a/arch/arm/mach-tegra/board-cardhu-panel.c +++ b/arch/arm/mach-tegra/board-cardhu-panel.c @@ -43,8 +43,16 @@ #include "gpio-names.h" /* Select panel to be used. */ -#define DSI_PANEL_219 1 +#define DSI_PANEL_219 0 #define DSI_PANEL_218 0 +#define DSI_PANEL_1506 1 + +#if DSI_PANEL_1506 +#define DC_CTRL_MODE TEGRA_DC_OUT_ONE_SHOT_MODE +#else +#define DC_CTRL_MODE 0 +#endif + #define AVDD_LCD PMU_TCA6416_GPIO_PORT17 #define DSI_PANEL_RESET 1 @@ -60,6 +68,13 @@ #define pm313_BPP TEGRA_GPIO_PN6 /* 0:24bpp, 1:18bpp */ #define pm313_lvds_shutdown TEGRA_GPIO_PH1 +/* E1506 display board pins */ +#define e1506_pm269_lcd_te TEGRA_GPIO_PJ1 +#define e1506_pm269_dsi_vddio TEGRA_GPIO_PH1 +#define e1506_pm269_dsia_bl_pwm TEGRA_GPIO_PH0 +#define e1506_pm269_panel_enb TEGRA_GPIO_PW1 +#define e1506_pm269_bl_enb TEGRA_GPIO_PH2 + /* E1247 reworked for pm269 pins */ #define e1247_pm269_lvds_shutdown TEGRA_GPIO_PN6 @@ -71,10 +86,10 @@ #define cardhu_bl_pwm TEGRA_GPIO_PH0 #define cardhu_hdmi_hpd TEGRA_GPIO_PN7 -#if defined(DSI_PANEL_219) || defined(DSI_PANEL_218) +#if defined(DSI_PANEL_219) || defined(DSI_PANEL_218) || defined(DSI_PANEL_1506) #define cardhu_dsia_bl_enb TEGRA_GPIO_PW1 #define cardhu_dsib_bl_enb TEGRA_GPIO_PW0 -#define cardhu_dsi_218_panel_reset TEGRA_GPIO_PD2 +#define cardhu_dsi_panel_reset TEGRA_GPIO_PD2 #define cardhu_dsi_219_panel_reset TEGRA_GPIO_PW0 #endif @@ -132,14 +147,14 @@ static tegra_dc_bl_output cardhu_bl_output_measured = { 248, 249, 250, 251, 252, 253, 254, 255 }; -static p_tegra_dc_bl_output bl_output; +static p_tegra_dc_bl_output bl_output = cardhu_bl_output_measured; + +static bool kernel_1st_panel_init = true; static int cardhu_backlight_init(struct device *dev) { int ret; - bl_output = cardhu_bl_output_measured; - if (WARN_ON(ARRAY_SIZE(cardhu_bl_output_measured) != 256)) pr_err("bl_output array does not have 256 elements\n"); @@ -240,6 +255,9 @@ static int cardhu_backlight_notify(struct device *unused, int brightness) #elif DSI_PANEL_219 /* DSIa */ gpio_set_value(cardhu_dsia_bl_enb, !!brightness); +#elif DSI_PANEL_1506 + /* DSIa */ + gpio_set_value(e1506_pm269_bl_enb, !!brightness); #endif /* SD brightness is a percentage, 8-bit value. */ @@ -742,14 +760,17 @@ static int cardhu_dsi_panel_enable(void) return PTR_ERR(cardhu_dsi_reg); } } + regulator_enable(cardhu_dsi_reg); +#if !DSI_PANEL_1506 ret = gpio_request(AVDD_LCD, "avdd_lcd"); if (ret < 0) gpio_free(AVDD_LCD); ret = gpio_direction_output(AVDD_LCD, 1); if (ret < 0) gpio_free(AVDD_LCD); +#endif #if DSI_PANEL_219 @@ -779,22 +800,58 @@ static int cardhu_dsi_panel_enable(void) mdelay(15); #endif +#if DSI_PANEL_1506 + ret = gpio_request(e1506_pm269_dsi_vddio, "e1506_pm269_dsi_vddio"); + if (ret < 0) + return ret; + ret = gpio_direction_output(e1506_pm269_dsi_vddio, 0); + if (ret < 0) { + gpio_free(e1506_pm269_dsi_vddio); + return ret; + } + + ret = gpio_request(e1506_pm269_panel_enb, "e1506_pm269_panel_enb"); + if (ret < 0) + return ret; + ret = gpio_direction_output(e1506_pm269_panel_enb, 0); + if (ret < 0) { + gpio_free(e1506_pm269_panel_enb); + return ret; + } + + ret = gpio_request(e1506_pm269_bl_enb, "e1506_pm269_bl_enb"); + if (ret < 0) + return ret; + ret = gpio_direction_output(e1506_pm269_bl_enb, 0); + if (ret < 0) { + gpio_free(e1506_pm269_bl_enb); + return ret; + } + + gpio_set_value(e1506_pm269_dsi_vddio, 1); + mdelay(10); + gpio_set_value(e1506_pm269_panel_enb, 1); + mdelay(10); + gpio_set_value(e1506_pm269_bl_enb, 1); + mdelay(15); +#endif + #if DSI_PANEL_RESET #if DSI_PANEL_218 - ret = gpio_request(cardhu_dsi_218_panel_reset, "dsi_panel_reset"); + ret = gpio_request(cardhu_dsi_panel_reset, "dsi_panel_reset"); if (ret < 0) { return ret; } - ret = gpio_direction_output(cardhu_dsi_218_panel_reset, 0); + ret = gpio_direction_output(cardhu_dsi_panel_reset, 0); if (ret < 0) { - gpio_free(cardhu_dsi_218_panel_reset); + gpio_free(cardhu_dsi_panel_reset); return ret; } - gpio_set_value(cardhu_dsi_218_panel_reset, 1); - gpio_set_value(cardhu_dsi_218_panel_reset, 0); + gpio_set_value(cardhu_dsi_panel_reset, 1); + gpio_set_value(cardhu_dsi_panel_reset, 0); mdelay(2); - gpio_set_value(cardhu_dsi_218_panel_reset, 1); + gpio_set_value(cardhu_dsi_panel_reset, 1); mdelay(2); #endif @@ -816,6 +873,24 @@ static int cardhu_dsi_panel_enable(void) gpio_set_value(cardhu_dsi_219_panel_reset, 1); mdelay(15); #endif + +#if DSI_PANEL_1506 + ret = gpio_request(cardhu_dsi_panel_reset, "dsi_panel_reset"); + if (ret < 0) + return ret; + ret = gpio_direction_output(cardhu_dsi_panel_reset, 0); + if (ret < 0) { + gpio_free(cardhu_dsi_panel_reset); + return ret; + } + + gpio_set_value(cardhu_dsi_panel_reset, 1); + mdelay(1); + gpio_set_value(cardhu_dsi_panel_reset, 0); + mdelay(1); + gpio_set_value(cardhu_dsi_panel_reset, 1); + mdelay(20); +#endif #endif return 0; @@ -826,7 +901,6 @@ static int cardhu_dsi_panel_disable(void) int err; err = 0; - printk(KERN_INFO "DSI panel disable\n"); #if DSI_PANEL_219 gpio_free(cardhu_dsi_219_panel_reset); @@ -839,6 +913,19 @@ static int cardhu_dsi_panel_disable(void) gpio_free(cardhu_dsi_218_panel_reset); #endif +#if DSI_PANEL_1506 + tegra_gpio_disable(e1506_pm269_bl_enb); + gpio_free(e1506_pm269_bl_enb); + tegra_gpio_disable(e1506_pm269_panel_enb); + gpio_free(e1506_pm269_panel_enb); + tegra_gpio_disable(e1506_pm269_dsi_vddio); + gpio_free(e1506_pm269_dsi_vddio); + if (kernel_1st_panel_init != true) { + tegra_gpio_disable(cardhu_dsi_panel_reset); + gpio_free(cardhu_dsi_panel_reset); + } else + kernel_1st_panel_init = false; +#endif return err; } @@ -865,16 +952,48 @@ static int cardhu_dsi_panel_postsuspend(void) return err; } +u8 password_array[] = {0xb9, 0xff, 0x83, 0x92}; + static struct tegra_dsi_cmd dsi_init_cmd[] = { DSI_CMD_SHORT(0x05, 0x11, 0x00), DSI_DLY_MS(150), +#if DSI_PANEL_1506 + DSI_CMD_LONG(0x39, password_array), + DSI_DLY_MS(10), + DSI_CMD_SHORT(0x15, 0xd4, 0x0c), + DSI_DLY_MS(10), + DSI_CMD_SHORT(0x15, 0xba, 0x11), + DSI_DLY_MS(10), +#endif +#if (DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE) + DSI_CMD_SHORT(0x15, 0x35, 0x00), +#endif DSI_CMD_SHORT(0x05, 0x29, 0x00), DSI_DLY_MS(20), }; -static struct tegra_dsi_cmd dsi_suspend_cmd[] = { +static struct tegra_dsi_cmd dsi_early_suspend_cmd[] = { DSI_CMD_SHORT(0x05, 0x28, 0x00), DSI_DLY_MS(20), +#if (DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE) + DSI_CMD_SHORT(0x05, 0x34, 0x00), +#endif +}; + +static struct tegra_dsi_cmd dsi_late_resume_cmd[] = { +#if (DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE) + DSI_CMD_SHORT(0x15, 0x35, 0x00), +#endif + DSI_CMD_SHORT(0x05, 0x29, 0x00), + DSI_DLY_MS(20), +}; + +static struct tegra_dsi_cmd dsi_suspend_cmd[] = { + DSI_CMD_SHORT(0x05, 0x28, 0x00), + DSI_DLY_MS(120), +#if (DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE) + DSI_CMD_SHORT(0x05, 0x34, 0x00), +#endif DSI_CMD_SHORT(0x05, 0x10, 0x00), DSI_DLY_MS(5), }; @@ -882,7 +1001,19 @@ static struct tegra_dsi_cmd dsi_suspend_cmd[] = { struct tegra_dsi_out cardhu_dsi = { .n_data_lanes = 2, .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P, + +#if (DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE) + /* + * The one-shot frame time must be shorter than the time between TE. + * Increasing refresh_rate will result in a decrease in the frame time + * for one-shot. rated_refresh_rate is only an approximation of the + * TE rate, and is only used to report refresh rate to upper layers. + */ + .refresh_rate = 66, + .rated_refresh_rate = 60, +#else .refresh_rate = 60, +#endif .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0, .panel_has_frame_buffer = true, @@ -897,6 +1028,12 @@ struct tegra_dsi_out cardhu_dsi = { .n_init_cmd = ARRAY_SIZE(dsi_init_cmd), .dsi_init_cmd = dsi_init_cmd, + .n_early_suspend_cmd = ARRAY_SIZE(dsi_early_suspend_cmd), + .dsi_early_suspend_cmd = dsi_early_suspend_cmd, + + .n_late_resume_cmd = ARRAY_SIZE(dsi_late_resume_cmd), + .dsi_late_resume_cmd = dsi_late_resume_cmd, + .n_suspend_cmd = ARRAY_SIZE(dsi_suspend_cmd), .dsi_suspend_cmd = dsi_suspend_cmd, @@ -937,6 +1074,21 @@ static struct tegra_dc_mode cardhu_dsi_modes[] = { }, #endif +#if DSI_PANEL_1506 + { + .pclk = 61417000, + .h_ref_to_sync = 2, + .v_ref_to_sync = 2, + .h_sync_width = 4, + .v_sync_width = 4, + .h_back_porch = 100, + .v_back_porch = 14, + .h_active = 720, + .v_active = 1280, + .h_front_porch = 4, + .v_front_porch = 4, + }, +#endif }; @@ -954,6 +1106,13 @@ static struct tegra_fb_data cardhu_dsi_fb_data = { .yres = 480, .bits_per_pixel = 32, #endif + +#if DSI_PANEL_1506 + .win = 0, + .xres = 720, + .yres = 1280, + .bits_per_pixel = 32, +#endif .flags = TEGRA_FB_FLIP_ON_PROBE, }; #endif @@ -977,6 +1136,7 @@ static struct tegra_dc_out cardhu_disp1_out = { .enable = cardhu_panel_enable, .disable = cardhu_panel_disable, #else + .flags = DC_CTRL_MODE, .type = TEGRA_DC_OUT_DSI, .modes = cardhu_dsi_modes, @@ -1233,6 +1393,12 @@ int __init cardhu_panel_init(void) gpio_request(cardhu_hdmi_hpd, "hdmi_hpd"); gpio_direction_input(cardhu_hdmi_hpd); +#if !(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE) + tegra_gpio_enable(e1506_pm269_lcd_te); + gpio_request(e1506_pm269_lcd_te, "lcd_te"); + gpio_direction_input(e1506_pm269_lcd_te); +#endif + #ifdef CONFIG_HAS_EARLYSUSPEND cardhu_panel_early_suspender.suspend = cardhu_panel_early_suspend; cardhu_panel_early_suspender.resume = cardhu_panel_late_resume; diff --git a/arch/arm/mach-tegra/board-cardhu-pinmux.c b/arch/arm/mach-tegra/board-cardhu-pinmux.c index 05e2179682b1..734047c2731f 100644 --- a/arch/arm/mach-tegra/board-cardhu-pinmux.c +++ b/arch/arm/mach-tegra/board-cardhu-pinmux.c @@ -495,6 +495,11 @@ static __initdata struct tegra_pingroup_config cardhu_pinmux_e1198[] = { DEFAULT_PINMUX(SPI2_CS2_N, SPI2, PULL_UP, NORMAL, INPUT), }; +static __initdata struct tegra_pingroup_config cardhu_pinmux_pm269_e1506[] = { + DEFAULT_PINMUX(LCD_M1, DISPLAYA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(LCD_DC1, DISPLAYA, NORMAL, NORMAL, OUTPUT), +}; + static __initdata struct tegra_pingroup_config unused_pins_lowpower[] = { DEFAULT_PINMUX(GMI_WAIT, NAND, PULL_UP, TRISTATE, OUTPUT), DEFAULT_PINMUX(GMI_ADV_N, NAND, NORMAL, TRISTATE, OUTPUT), @@ -619,6 +624,7 @@ static void __init cardhu_gpio_init_configure(void) int __init cardhu_pinmux_init(void) { struct board_info board_info; + struct board_info display_board_info; cardhu_gpio_init_configure(); @@ -627,6 +633,7 @@ int __init cardhu_pinmux_init(void) ARRAY_SIZE(cardhu_drive_pinmux)); tegra_get_board_info(&board_info); + tegra_get_display_board_info(&display_board_info); switch (board_info.board_id) { case BOARD_E1198: tegra_pinmux_config_table(cardhu_pinmux_e1198, @@ -663,6 +670,12 @@ int __init cardhu_pinmux_init(void) tegra_pinmux_config_table(cardhu_pinmux_e118x, ARRAY_SIZE(cardhu_pinmux_e118x)); } + + if (display_board_info.board_id == BOARD_DISPLAY_E1506) { + tegra_pinmux_config_table(cardhu_pinmux_pm269_e1506, + ARRAY_SIZE(cardhu_pinmux_pm269_e1506)); + } + tegra_pinmux_config_table(unused_pins_lowpower, ARRAY_SIZE(unused_pins_lowpower)); tegra_pinmux_config_table(gmi_pins_269, @@ -722,6 +735,10 @@ struct gpio_init_pin_info vddio_gmi_pins_pm269_wo_pm313[] = { PIN_GPIO_LPM("GMI_AD9", TEGRA_GPIO_PH1, 0, 0), }; +struct gpio_init_pin_info vddio_gmi_pins_pm269_e1506[] = { + PIN_GPIO_LPM("GMI_CS2", TEGRA_GPIO_PK3, 1, 0), +}; + static void set_unused_pin_gpio(struct gpio_init_pin_info *lpm_pin_info, int list_count) { @@ -781,7 +798,10 @@ int __init cardhu_pins_state_init(void) set_unused_pin_gpio(&vddio_gmi_pins_pm269[0], ARRAY_SIZE(vddio_gmi_pins_pm269)); - if (display_board_info.board_id != BOARD_DISPLAY_PM313) { + if (display_board_info.board_id == BOARD_DISPLAY_E1506) { + set_unused_pin_gpio(&vddio_gmi_pins_pm269_e1506[0], + ARRAY_SIZE(vddio_gmi_pins_pm269_e1506)); + } else if (display_board_info.board_id != BOARD_DISPLAY_PM313) { set_unused_pin_gpio(&vddio_gmi_pins_pm269_wo_pm313[0], ARRAY_SIZE(vddio_gmi_pins_pm269_wo_pm313)); } |