summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/board-cardhu-panel.c194
-rw-r--r--arch/arm/mach-tegra/board-cardhu-pinmux.c22
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));
}