summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMing Wong <miwong@nvidia.com>2011-10-14 12:29:20 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:49:59 -0800
commitccb1676b1dc92c170dbb7633496be7ae97206d0a (patch)
treea625c8a5ce71a6ac1ab3b110cd6f96a9366b1944
parentc3510d18d039e966bf8f115cc317b525abb615bf (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 Bug 884157 Reviewed-on: http://git-master/r/58180 Reviewed-by: Jon Mayo <jmayo@nvidia.com> (cherry picked from commit df4679db62b164e33e82fe56a18787cfca431d82) Signed-off-by: Jon Mayo <jmayo@nvidia.com> [jmayo@nvidia.com: cleaned up formatting] Change-Id: Ia2b54c070c91bbb4ba59741c0c5c23dae8f71ce8 Reviewed-on: http://git-master/r/63413 Reviewed-by: Lokesh Pathak <lpathak@nvidia.com> Tested-by: Lokesh Pathak <lpathak@nvidia.com> Rebase-Id: R965eb64babd304bd66f2c057721a9dd1eedb17ca
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h2
-rw-r--r--drivers/video/tegra/dc/dsi.c88
-rw-r--r--drivers/video/tegra/dc/dsi.h1
-rw-r--r--drivers/video/tegra/dc/dsi_regs.h4
4 files changed, 95 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index fa141e57b735..fa409f4c2e45 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -536,6 +536,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);
int tegra_dc_update_lut(struct tegra_dc *dc, int win_index, int fboveride);
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 01bf1c79f736..356c6d93c54c 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -247,6 +247,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,
@@ -1410,6 +1414,90 @@ static int tegra_dsi_send_panel_cmd(struct tegra_dc *dc,
return err;
}
+static u8 get_8bit_ecc(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, pkthdr = 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) {
+ pkthdr = (CMD_SHORTW |
+ (((u16 *)pdata)[0]) << 8 | 0x00 << 24);
+ ecc8bits = get_8bit_ecc(pkthdr);
+ val = (pkthdr | (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..95636c0e01eb 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)