summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMing Wong <miwong@nvidia.com>2011-10-14 12:29:20 -0700
committerLokesh Pathak <lpathak@nvidia.com>2011-11-10 07:06:19 -0800
commitdb68e9e93efa9de467b5c741dcf979dd113606d2 (patch)
treea30254fe083320efeb42f4f2a5a0e5b60708ddc7
parentea572ebf71bbced17f2df2313f03e032949fac68 (diff)
video: tegra: dsi: Add support for DCS short write (1 parameter)
Add MIPI DCS short write (1 parameter) support. The cmds sent with this new function will be sent every frame by hardware Signed-off-by: Ming Wong <miwong@nvidia.com> Bug 884157 (cherry picked from commit 855cac72bf030213db6fa1e42ce4e5891b16681c) Change-Id: I5c4e8696195d01f4f9dfb8cf66b5b3744f78c41e Reviewed-on: http://git-master/r/62300 Reviewed-by: Lokesh Pathak <lpathak@nvidia.com> Tested-by: Lokesh Pathak <lpathak@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h2
-rw-r--r--drivers/video/tegra/dc/dsi.c89
-rw-r--r--drivers/video/tegra/dc/dsi.h1
-rw-r--r--drivers/video/tegra/dc/dsi_regs.h4
4 files changed, 96 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index f42383429906..2ea1410f1d14 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -525,6 +525,8 @@ struct tegra_dc_pwm_params {
void tegra_dc_config_pwm(struct tegra_dc *dc, struct tegra_dc_pwm_params *cfg);
+int tegra_dsi_send_panel_short_cmd(struct tegra_dc *dc, u8 *pdata, u8 data_len);
+
int tegra_dc_update_csc(struct tegra_dc *dc, int win_index);
/*
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 3b0a70795ecd..91388d7c54e2 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -249,6 +249,10 @@ const u32 init_reg[] = {
DSI_INIT_SEQ_DATA_1,
DSI_INIT_SEQ_DATA_2,
DSI_INIT_SEQ_DATA_3,
+ DSI_INIT_SEQ_DATA_4,
+ DSI_INIT_SEQ_DATA_5,
+ DSI_INIT_SEQ_DATA_6,
+ DSI_INIT_SEQ_DATA_7,
DSI_DCS_CMDS,
DSI_PKT_SEQ_0_LO,
DSI_PKT_SEQ_1_LO,
@@ -1406,6 +1410,91 @@ static int tegra_dsi_send_panel_cmd(struct tegra_dc *dc,
return err;
}
+static u8 get8BitECC(u32 header)
+{
+ char ecc_parity[24] = { 0x07, 0x0b, 0x0d, 0x0e, 0x13, 0x15, 0x16, 0x19,
+ 0x1a, 0x1c, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c,
+ 0x31, 0x32, 0x34, 0x38, 0x1f, 0x2f, 0x37, 0x3b};
+ u8 ecc_byte;
+ int i;
+
+ ecc_byte = 0;
+ for (i = 0; i < 24; i++)
+ ecc_byte ^= ((header >> i) & 1) ? ecc_parity[i] : 0x00;
+
+ return ecc_byte;
+}
+
+/* This function is written to send DCS short write (1 parameter) only
+ * This means the cmd will contain only 1 byte of index and 1 byte of value
+ * The data type ID is fixed at 0x15 and the ECC is calculated
+ * based on the data in pdata
+ * The command will be sent by hardware every frame
+ * pdata should contain both the index + value for each cmd
+ * data_len will be the total number of bytes in pdata
+ */
+
+int tegra_dsi_send_panel_short_cmd(struct tegra_dc *dc,
+ u8 *pdata,
+ u8 data_len)
+{
+ u8 ecc8Bits = 0, data_len_orig = 0;
+ u32 val = 0, packetHeader = 0;
+ int err = 0, count = 0;
+ struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
+
+ data_len_orig = data_len;
+ if (pdata != NULL) {
+ while (data_len) {
+ if (data_len >= 2) {
+ packetHeader = (CMD_SHORTW |
+ (((u16 *) pdata)[0]) << 8 | 0x00 << 24);
+ ecc8Bits = get8BitECC(packetHeader);
+ val = (packetHeader | (ecc8Bits << 24));
+ data_len -= 2;
+ pdata += 2;
+ count++;
+ }
+ switch (count) {
+ case 1:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_0);
+ break;
+ case 2:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_1);
+ break;
+ case 3:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_2);
+ break;
+ case 4:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_3);
+ break;
+ case 5:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_4);
+ break;
+ case 6:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_5);
+ break;
+ case 7:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_6);
+ break;
+ case 8:
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_7);
+ break;
+ default:
+ err = 1;
+ break;
+ }
+ }
+ }
+
+ val = DSI_INIT_SEQ_CONTROL_DSI_FRAME_INIT_BYTE_COUNT(data_len_orig*2) |
+ DSI_INIT_SEQ_CONTROL_DSI_SEND_INIT_SEQUENCE(1);
+ tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_CONTROL);
+
+ return err;
+}
+EXPORT_SYMBOL(tegra_dsi_send_panel_short_cmd);
+
static int tegra_dsi_bta(struct tegra_dc_dsi_data *dsi)
{
u32 val;
diff --git a/drivers/video/tegra/dc/dsi.h b/drivers/video/tegra/dc/dsi.h
index 6ccf544dd842..dad8fe4359eb 100644
--- a/drivers/video/tegra/dc/dsi.h
+++ b/drivers/video/tegra/dc/dsi.h
@@ -185,6 +185,7 @@ enum {
CMD_EOT = 0x08,
CMD_NULL = 0x09,
+ CMD_SHORTW = 0x15,
CMD_BLNK = 0x19,
CMD_LONGW = 0x39,
diff --git a/drivers/video/tegra/dc/dsi_regs.h b/drivers/video/tegra/dc/dsi_regs.h
index 9fde76768afc..203ac32bd92d 100644
--- a/drivers/video/tegra/dc/dsi_regs.h
+++ b/drivers/video/tegra/dc/dsi_regs.h
@@ -128,6 +128,10 @@ enum {
#define DSI_INIT_SEQ_DATA_1 0x1c
#define DSI_INIT_SEQ_DATA_2 0x1d
#define DSI_INIT_SEQ_DATA_3 0x1e
+#define DSI_INIT_SEQ_DATA_4 0x1f
+#define DSI_INIT_SEQ_DATA_5 0x20
+#define DSI_INIT_SEQ_DATA_6 0x21
+#define DSI_INIT_SEQ_DATA_7 0x22
#define DSI_PKT_SEQ_0_LO 0x23
#define DSI_PKT_SEQ_0_LO_SEQ_0_FORCE_LP(x) (((x) & 0x1) << 30)