/* * mipi_dsi_cmds_tx: * ov_mutex need to be acquired before call this function. */ int mipi_dsi_cmds_tx(struct msm_fb_data_type *mfd, struct dsi_buf *tp, struct dsi_cmd_desc *cmds, int cnt) { struct dsi_cmd_desc *cm; uint32 dsi_ctrl, ctrl; int i, video_mode; int length_tx; int ret; /* turn on cmd mode * for video mode, do not send cmds more than * one pixel line, since it only transmit it * during BLLP. */ dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000); video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */ if (video_mode) { ctrl = dsi_ctrl | 0x04; /* CMD_MODE_EN */ MIPI_OUTP(MIPI_DSI_BASE + 0x0000, ctrl); } else { /* cmd mode */ /* * during boot up, cmd mode is configured * even it is video mode panel. */ /* make sure mdp dma is not txing pixel data */ if (mfd->panel_info.type == MIPI_CMD_PANEL) mdp4_dsi_cmd_dma_busy_wait(mfd); } mipi_dsi_enable_irq(); cm = cmds; mipi_dsi_buf_init(tp); for (i = 0; i < cnt; i++) { mipi_dsi_buf_init(tp); mipi_dsi_cmd_dma_add(tp, cm); length_tx = mipi_dsi_cmd_dma_tx(tp); if( length_tx < 0 ) // if failed { pr_err(" mipi_dsi_cmd_dma_tx FAILED, %d/%d(%x %x %x %x)\n", i, cnt, cm->payload[0], cm->payload[1], cm->payload[2], cm->payload[3]); break; } if (cm->wait) msleep(cm->wait); cm++; } ret = i; mipi_dsi_disable_irq(); if (video_mode) MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl); /* restore */ return ret; }
/* * Novatek panel will reply with MAX_RETURN_PACKET_SIZE bytes of data * plus DCS header, ECC and CRC for DCS long read response * currently, we set MAX_RETURN_PAKET_SIZE to 4 to align with 32 bits * register * currently, only MAX_RETURN_PACKET_SIZE (4) bytes per read */ int mipi_dsi_cmds_rx(struct dsi_buf *tp, struct dsi_buf *rp, struct dsi_cmd_desc *cmds, int len) { int cnt, res; if (len <= 2) cnt = 4; /* short read */ else cnt = MIPI_DSI_MRPS + 6; /* long read, 4 bytes header + 2 bytes crc */ if (cnt > MIPI_DSI_REG_LEN) { PR_DISP_INFO("%s: len=%d too long\n", __func__, len); return -ERANGE; } res = cnt & 0x03; cnt += res; /* 4 byte align */ mipi_dsi_buf_init(tp); mipi_dsi_cmd_dma_add(tp, cmds); dsi_mutex_lock(); dsi_busy_check(); mipi_dsi_enable_irq(); /* transmit read comamnd to client */ mipi_dsi_cmd_dma_tx(tp); /* * once cmd_dma_done interrupt received, * return data from client is ready and stored * at RDBK_DATA register already */ mipi_dsi_buf_reserve(rp, res); mipi_dsi_cmd_dma_rx(rp, cnt); mipi_dsi_disable_irq(); dsi_mutex_unlock(); /* strip off dcs read header & crc */ rp->data += (4 + res); rp->len -= (6 + res); return len; }
/* * mipi_dsi_cmds_tx: * ov_mutex need to be acquired before call this function. */ int mipi_dsi_cmds_tx(struct msm_fb_data_type *mfd, struct dsi_buf *tp, struct dsi_cmd_desc *cmds, int cnt) { struct dsi_cmd_desc *cm; uint32 dsi_ctrl, ctrl; int i, video_mode; /* turn on cmd mode * for video mode, do not send cmds more than * one pixel line, since it only transmit it * during BLLP. */ dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000); video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */ if (video_mode) { ctrl = dsi_ctrl | 0x04; /* CMD_MODE_EN */ MIPI_OUTP(MIPI_DSI_BASE + 0x0000, ctrl); } else { /* cmd mode */ /* * during boot up, cmd mode is configured * even it is video mode panel. */ /* make sure mdp dma is not txing pixel data */ #ifndef CONFIG_FB_MSM_MIPI_DSI_MAGNA if (mfd->panel_info.type == MIPI_CMD_PANEL) mdp4_dsi_cmd_dma_busy_wait(mfd); #endif } cm = cmds; mipi_dsi_buf_init(tp); for (i = 0; i < cnt; i++) { mipi_dsi_buf_init(tp); mipi_dsi_cmd_dma_add(tp, cm); mipi_dsi_cmd_dma_tx(tp); if (cm->wait) msleep(cm->wait); cm++; } if (video_mode) MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl); /* restore */ return cnt; }
/* * Novatek panel will reply with MAX_RETURN_PACKET_SIZE bytes of data * plus DCS header, ECC and CRC for DCS long read response * currently, we set MAX_RETURN_PAKET_SIZE to 4 to align with 32 bits * register * currently, only MAX_RETURN_PACKET_SIZE (4) bytes per read * * ov_mutex need to be acquired before call this function. */ int mipi_dsi_cmds_rx(struct msm_fb_data_type *mfd, struct dsi_buf *tp, struct dsi_buf *rp, struct dsi_cmd_desc *cmds, int len) { int cnt, res; if (len <= 2) cnt = 4; /* short read */ else cnt = MIPI_DSI_MRPS + 6; /* 4 bytes header + 2 bytes crc */ if (cnt > MIPI_DSI_REG_LEN) { pr_debug("%s: len=%d too long\n", __func__, len); return -ERANGE; } res = cnt & 0x03; cnt += res; /* 4 byte align */ mipi_dsi_buf_init(tp); mipi_dsi_cmd_dma_add(tp, cmds); /* make sure mdp dma is not txing pixel data */ if (mfd->panel_info.type == MIPI_CMD_PANEL) mdp4_dsi_cmd_dma_busy_wait(mfd); /* transmit read comamnd to client */ mipi_dsi_cmd_dma_tx(tp); /* * once cmd_dma_done interrupt received, * return data from client is ready and stored * at RDBK_DATA register already */ mipi_dsi_buf_reserve(rp, res); mipi_dsi_cmd_dma_rx(rp, cnt); /* strip off dcs read header & crc */ rp->data += (4 + res); rp->len -= (6 + res); return len; }
int mipi_dsi_cmds_tx(struct dsi_buf *tp, struct dsi_cmd_desc *cmds, int cnt) { struct dsi_cmd_desc *cm; uint32 dsi_ctrl, ctrl; int i, video_mode; dsi_mutex_lock(); dsi_busy_check(); /* turn on cmd mode * for video mode, do not send cmds more than * one pixel line, since it only transmit it * during BLLP. */ dsi_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0000); video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */ if (video_mode) { ctrl = dsi_ctrl | 0x04; /* CMD_MODE_EN */ MIPI_OUTP(MIPI_DSI_BASE + 0x0000, ctrl); } mipi_dsi_enable_irq(); cm = cmds; mipi_dsi_buf_init(tp); for (i = 0; i < cnt; i++) { mipi_dsi_buf_init(tp); mipi_dsi_cmd_dma_add(tp, cm); mipi_dsi_cmd_dma_tx(tp); if (cm->wait) hr_msleep(cm->wait); cm++; } mipi_dsi_disable_irq(); if (video_mode) MIPI_OUTP(MIPI_DSI_BASE + 0x0000, dsi_ctrl); /* restore */ dsi_mutex_unlock(); return cnt; }
/* * DSI panel reply with MAX_RETURN_PACKET_SIZE bytes of data * plus DCS header, ECC and CRC for DCS long read response * mipi_dsi_controller only have 4x32 bits register ( 16 bytes) to * hold data per transaction. * MIPI_DSI_LEN equal to 8 * len should be either 4 or 8 * any return data more than MIPI_DSI_LEN need to be break down * to multiple transactions. * * ov_mutex need to be acquired before call this function. */ int mipi_dsi_cmds_rx(struct msm_fb_data_type *mfd, struct dsi_buf *tp, struct dsi_buf *rp, struct dsi_cmd_desc *cmds, int len) { int cnt, res; static int pkt_size; if (len <= 2) cnt = 4; /* short read */ else { if (len > MIPI_DSI_LEN) len = MIPI_DSI_LEN; /* 8 bytes at most */ res = len & 0x03; len += (4 - res); /* 4 bytes align */ /* * add extra 2 bytes to len to have overall * packet size is multipe by 4. This also make * sure 4 bytes dcs headerlocates within a * 32 bits register after shift in. * after all, len should be either 6 or 10. */ len += 2; cnt = len + 6; /* 4 bytes header + 2 bytes crc */ } if (mfd->panel_info.type == MIPI_CMD_PANEL) { /* make sure mdp dma is not txing pixel data */ mdp4_dsi_cmd_dma_busy_wait(mfd); } mipi_dsi_enable_irq(); if (pkt_size != len) { /* set new max pkt size */ pkt_size = len; max_pktsize[0] = pkt_size; mipi_dsi_buf_init(tp); mipi_dsi_cmd_dma_add(tp, pkt_size_cmd); mipi_dsi_cmd_dma_tx(tp); } mipi_dsi_buf_init(tp); mipi_dsi_cmd_dma_add(tp, cmds); /* transmit read comamnd to client */ mipi_dsi_cmd_dma_tx(tp); /* * once cmd_dma_done interrupt received, * return data from client is ready and stored * at RDBK_DATA register already */ mipi_dsi_cmd_dma_rx(rp, cnt); mipi_dsi_disable_irq(); /* strip off dcs header & crc */ if (cnt > 4) { /* long response */ rp->data += 4; /* skip dcs header */ rp->len -= 6; /* deduct 4 bytes header + 2 bytes crc */ rp->len -= 2; /* extra 2 bytes added */ } else { rp->data += 1; /* skip dcs short header */ rp->len -= 2; /* deduct 1 byte header + 1 byte ecc */ } return rp->len; }