summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMing Wong <miwong@nvidia.com>2011-10-14 12:29:20 -0700
committerSimone Willett <swillett@nvidia.com>2011-10-25 16:34:14 -0700
commitdf4679db62b164e33e82fe56a18787cfca431d82 (patch)
tree7042dcf0ee49b277b50965a19ec6e0dd5545da5c
parent2af190f7b5842c2bc53694d2d94cd79c4ec50afe (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 Change-Id: I4110f5698d7156c481ef70c5a343ef4920a78677 Reviewed-on: http://git-master/r/58180 Tested-by: Ming Wong <miwong@nvidia.com> Reviewed-by: Venkata (Muni) Anda <vanda@nvidia.com> Reviewed-by: Kevin Huang (Eng-SW) <kevinh@nvidia.com> Reviewed-by: Jon Mayo <jmayo@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h2
-rw-r--r--drivers/video/tegra/dc/dsi.c85
-rw-r--r--drivers/video/tegra/dc/dsi.h1
-rw-r--r--drivers/video/tegra/dc/dsi_regs.h4
4 files changed, 92 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 f5772b7259c5..787607919433 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,
@@ -1410,6 +1414,87 @@ 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..7ab191c985bd 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)