diff options
Diffstat (limited to 'drivers/video/exynos_mipi_dsi_common.c')
-rw-r--r-- | drivers/video/exynos_mipi_dsi_common.c | 122 |
1 files changed, 121 insertions, 1 deletions
diff --git a/drivers/video/exynos_mipi_dsi_common.c b/drivers/video/exynos_mipi_dsi_common.c index 6e5d9840c..6531470f0 100644 --- a/drivers/video/exynos_mipi_dsi_common.c +++ b/drivers/video/exynos_mipi_dsi_common.c @@ -27,6 +27,9 @@ #include <asm/arch/mipi_dsim.h> #include "exynos_mipi_dsi_lowlevel.h" +#include "exynos_mipi_dsi_common.h" + +#define DSIM_RX_FIFO_MAX_DEPTH 64 #define MHZ (1000 * 1000) #define FIN_HZ (24 * MHZ) @@ -248,6 +251,123 @@ int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id, return 0; } +static void exynos_mipi_dsi_rx_err_handler(struct mipi_dsim_device *dsim, + unsigned int rx_fifo) +{ + /* Parse error report bit*/ + if (rx_fifo & (1 << 8)) + printf("SoT error!\n"); + if (rx_fifo & (1 << 9)) + printf("SoT sync error!\n"); + if (rx_fifo & (1 << 10)) + printf("EoT error!\n"); + if (rx_fifo & (1 << 11)) + printf("Escape mode entry command error!\n"); + if (rx_fifo & (1 << 12)) + printf("Low-power transmit sync error!\n"); + if (rx_fifo & (1 << 13)) + printf("HS receive timeout error!\n"); + if (rx_fifo & (1 << 14)) + printf("False control error!\n"); + /* Bit 15 is reserved*/ + if (rx_fifo & (1 << 16)) + printf("ECC error, single-bit(detected and corrected)!\n"); + if (rx_fifo & (1 << 17)) + printf("ECC error, multi-bit(detected, not corrected)!\n"); + if (rx_fifo & (1 << 18)) + printf("Checksum error(long packet only)!\n"); + if (rx_fifo & (1 << 19)) + printf("DSI data type not recognized!\n"); + if (rx_fifo & (1 << 20)) + printf("DSI VC ID invalid!\n"); + if (rx_fifo & (1 << 21)) + printf("Invalid transmission length!\n"); + /* Bit 22 is reserved */ + if (rx_fifo & (1 << 23)) + printf("DSI protocol violation!\n"); +} + +int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id, + unsigned int addr, unsigned int count, char *buf) +{ + struct exynos_mipi_dsim *mipi_dsim = + (struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim(); + unsigned int timeout = TRY_GET_FIFO_TIMEOUT; + unsigned int rx_fifo, rx_size = 0; + int i, j, ret = 0; + u32 rx_fifo_depth = DSIM_RX_FIFO_MAX_DEPTH; + + /* Init RX FIFO before read and clear DSIM_INTSRC */ + exynos_mipi_dsi_init_fifo_pointer(dsim, DSIM_INIT_RX); + exynos_mipi_dsi_clear_interrupt(dsim,INTSRC_RX_DATA_DONE); + + /* Set the maximum packet size returned */ + exynos_mipi_dsi_wr_data(dsim, + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, count, 0); + + /* Read request */ + exynos_mipi_dsi_wr_data(dsim, data_id, addr, 0); + + mdelay(200); + + do { + rx_fifo = readl(&mipi_dsim->rxfifo); + + /* Parse the RX packet data types */ + switch (rx_fifo & 0xff) { + case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: + exynos_mipi_dsi_rx_err_handler(dsim, rx_fifo); + if (ret < 0) { + goto exit; + } + break; + case MIPI_DSI_RX_END_OF_TRANSMISSION: + printf("EoTp was received from LCD module.\n"); + break; + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE: + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE: + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE: + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE: + printf("Short Packet was received from LCD module.\n"); + for (i = 0; i <= count; i++) + buf[i] = (rx_fifo >> (8 + i * 8)) & 0xff; + break; + case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE: + case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE: + printf("Long Packet was received from LCD module.\n"); + rx_size = (rx_fifo & 0x00ffff00) >> 8; + printf("rx fifo : %8x, response : %x, rx_size : %d\n", + rx_fifo, rx_fifo & 0xff, rx_size); + /* Read data from RX packet payload */ + for (i = 0; i < rx_size >> 2; i++) { + rx_fifo = readl(&mipi_dsim->rxfifo); + for (j = 0; j < 4; j++) + buf[(i*4)+j] = (u8)(rx_fifo >> (j * 8)) & 0xff; + } + if (rx_size % 4) { + rx_fifo = readl(&mipi_dsim->rxfifo); + for (j = 0; j < rx_size % 4; j++) + buf[4 * i + j] = + (u8)(rx_fifo >> (j * 8)) & 0xff; + } + break; + default: + printf("Packet format is invaild.\n"); + ret = -EBUSY; + break; + } + } while (!exynos_mipi_dsi_rx_fifo_is_empty(dsim) && --rx_fifo_depth); + + ret = rx_size; + if (!rx_fifo_depth) { + printf("Check DPHY values about HS clk.\n"); + ret = -EBUSY; + } + +exit: + return ret; +} + int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim, unsigned int enable) { int sw_timeout; @@ -255,7 +375,7 @@ int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim, unsigned int enable) if (enable) { sw_timeout = 1000; - exynos_mipi_dsi_clear_interrupt(dsim); + exynos_mipi_dsi_clear_interrupt(dsim, INTSRC_PLL_STABLE); exynos_mipi_dsi_enable_pll(dsim, 1); while (1) { sw_timeout--; |