ARM: tegra: cardhu: add support for E1506 panel
Rakesh Iyer [Thu, 10 May 2012 20:24:53 +0000 (13:24 -0700)]
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>

arch/arm/mach-tegra/board-cardhu-panel.c
arch/arm/mach-tegra/board-cardhu-pinmux.c

index a621710..b85c542 100644 (file)
 #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
 
 #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
 
 #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;
index 05e2179..734047c 100644 (file)
@@ -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));
                        }