]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: dsi: Add support for DCS short write (1 parameter)
authorMing Wong <miwong@nvidia.com>
Fri, 14 Oct 2011 19:29:20 +0000 (12:29 -0700)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 08:21:31 +0000 (01:21 -0700)
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

arch/arm/mach-tegra/include/mach/dc.h
drivers/video/tegra/dc/dsi.c
drivers/video/tegra/dc/dsi.h
drivers/video/tegra/dc/dsi_regs.h

index fa141e57b735b014c5c8526f12be1fcc2713e3a4..fa409f4c2e45ea65cd8ae8ad4620525cd32f36ba 100644 (file)
@@ -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);
index 2d64c48de8e0a8a267a7385bcf241f621dbd7738..dfe6b93be2259736ad4a3c94a22d20c661a6b0b4 100644 (file)
@@ -248,6 +248,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,
@@ -1411,6 +1415,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;
index 6ccf544dd842cd38eb887467a2ccc94af43b7d29..95636c0e01eb093dc06679adc6a2dd5054265c59 100644 (file)
@@ -185,6 +185,7 @@ enum {
 
        CMD_EOT         = 0x08,
        CMD_NULL        = 0x09,
+       CMD_SHORTW      = 0x15,
        CMD_BLNK        = 0x19,
        CMD_LONGW       = 0x39,
 
index 9fde76768afc919ecb89561062aa201ea8ffe8e5..203ac32bd92d018cdf3854c0075b8b91852d8d5d 100644 (file)
@@ -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)