summaryrefslogtreecommitdiff
path: root/drivers/video/exynos_mipi_dsi_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/exynos_mipi_dsi_common.c')
-rw-r--r--drivers/video/exynos_mipi_dsi_common.c122
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--;