summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 2d64c48de..dfe6b93be 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -248,6 +248,10 @@ const u32 init_reg[] = {
248 DSI_INIT_SEQ_DATA_1, 248 DSI_INIT_SEQ_DATA_1,
249 DSI_INIT_SEQ_DATA_2, 249 DSI_INIT_SEQ_DATA_2,
250 DSI_INIT_SEQ_DATA_3, 250 DSI_INIT_SEQ_DATA_3,
251 DSI_INIT_SEQ_DATA_4,
252 DSI_INIT_SEQ_DATA_5,
253 DSI_INIT_SEQ_DATA_6,
254 DSI_INIT_SEQ_DATA_7,
251 DSI_DCS_CMDS, 255 DSI_DCS_CMDS,
252 DSI_PKT_SEQ_0_LO, 256 DSI_PKT_SEQ_0_LO,
253 DSI_PKT_SEQ_1_LO, 257 DSI_PKT_SEQ_1_LO,
@@ -1411,6 +1415,90 @@ static int tegra_dsi_send_panel_cmd(struct tegra_dc *dc,
1411 return err; 1415 return err;
1412} 1416}
1413 1417
1418static u8 get_8bit_ecc(u32 header)
1419{
1420 char ecc_parity[24] = {
1421 0x07, 0x0b, 0x0d, 0x0e, 0x13, 0x15, 0x16, 0x19,
1422 0x1a, 0x1c, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c,
1423 0x31, 0x32, 0x34, 0x38, 0x1f, 0x2f, 0x37, 0x3b
1424 };
1425 u8 ecc_byte;
1426 int i;
1427
1428 ecc_byte = 0;
1429 for (i = 0; i < 24; i++)
1430 ecc_byte ^= ((header >> i) & 1) ? ecc_parity[i] : 0x00;
1431
1432 return ecc_byte;
1433}
1434
1435/* This function is written to send DCS short write (1 parameter) only.
1436 * This means the cmd will contain only 1 byte of index and 1 byte of value.
1437 * The data type ID is fixed at 0x15 and the ECC is calculated based on the
1438 * data in pdata.
1439 * The command will be sent by hardware every frame.
1440 * pdata should contain both the index + value for each cmd.
1441 * data_len will be the total number of bytes in pdata.
1442 */
1443int tegra_dsi_send_panel_short_cmd(struct tegra_dc *dc, u8 *pdata, u8 data_len)
1444{
1445 u8 ecc8bits = 0, data_len_orig = 0;
1446 u32 val = 0, pkthdr = 0;
1447 int err = 0, count = 0;
1448 struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
1449
1450 data_len_orig = data_len;
1451 if (pdata != NULL) {
1452 while (data_len) {
1453 if (data_len >= 2) {
1454 pkthdr = (CMD_SHORTW |
1455 (((u16 *)pdata)[0]) << 8 | 0x00 << 24);
1456 ecc8bits = get_8bit_ecc(pkthdr);
1457 val = (pkthdr | (ecc8bits << 24));
1458 data_len -= 2;
1459 pdata += 2;
1460 count++;
1461 }
1462 switch (count) {
1463 case 1:
1464 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_0);
1465 break;
1466 case 2:
1467 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_1);
1468 break;
1469 case 3:
1470 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_2);
1471 break;
1472 case 4:
1473 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_3);
1474 break;
1475 case 5:
1476 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_4);
1477 break;
1478 case 6:
1479 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_5);
1480 break;
1481 case 7:
1482 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_6);
1483 break;
1484 case 8:
1485 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_DATA_7);
1486 break;
1487 default:
1488 err = 1;
1489 break;
1490 }
1491 }
1492 }
1493
1494 val = DSI_INIT_SEQ_CONTROL_DSI_FRAME_INIT_BYTE_COUNT(data_len_orig * 2)
1495 | DSI_INIT_SEQ_CONTROL_DSI_SEND_INIT_SEQUENCE(1);
1496 tegra_dsi_writel(dsi, val, DSI_INIT_SEQ_CONTROL);
1497
1498 return err;
1499}
1500EXPORT_SYMBOL(tegra_dsi_send_panel_short_cmd);
1501
1414static int tegra_dsi_bta(struct tegra_dc_dsi_data *dsi) 1502static int tegra_dsi_bta(struct tegra_dc_dsi_data *dsi)
1415{ 1503{
1416 u32 val; 1504 u32 val;