/* * mdss_dsi_cmds_tx: * thread context only */ int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_cmd_desc *cmds, int cnt) { struct dsi_buf *tp; struct dsi_cmd_desc *cm; struct dsi_ctrl_hdr *dchdr; u32 dsi_ctrl, data; int i, video_mode; #ifdef CONFIG_OLED_SUPPORT #ifdef LGE_HRTIMER_OLED_PATCH #else struct timeval tv_start, tv_end; long tv_diff; int delay_count; #endif #endif if (ctrl->shared_pdata.broadcast_enable) { if (ctrl->ndx == DSI_CTRL_0) { pr_debug("%s: Broadcast mode. 1st ctrl\n", __func__); return 0; } } if (ctrl->shared_pdata.broadcast_enable) { if ((ctrl->ndx == DSI_CTRL_1) && (left_ctrl_pdata != NULL)) { dsi_ctrl = MIPI_INP(left_ctrl_pdata->ctrl_base + 0x0004); video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */ if (video_mode) { data = dsi_ctrl | 0x04; /* CMD_MODE_EN */ MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004, data); } } } /* 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((ctrl->ctrl_base) + 0x0004); video_mode = dsi_ctrl & 0x02; /* VIDEO_MODE_EN */ if (video_mode) { data = dsi_ctrl | 0x04; /* CMD_MODE_EN */ MIPI_OUTP((ctrl->ctrl_base) + 0x0004, data); } tp = &ctrl->tx_buf; cm = cmds; for (i = 0; i < cnt; i++) { mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); mdss_dsi_buf_init(tp); mdss_dsi_cmd_dma_add(tp, cm); mdss_dsi_cmd_dma_tx(ctrl, tp); dchdr = &cm->dchdr; #ifdef CONFIG_OLED_SUPPORT #ifdef LGE_HRTIMER_OLED_PATCH if(dchdr->wait) { printk("[Zee][OLED] mipi_dsi_tx(0x%X) start (target delay=%dms)\n", cm->payload[0], (int)dchdr->wait); if(dchdr->wait > 5) oled_hrtimer_delay(dchdr->wait); else mdelay(dchdr->wait); printk("[Zee][OLED] mipi_dsi_tx(0x%X) finish (target delay=%dms)\n", cm->payload[0], (int)dchdr->wait); } #else if(dchdr->wait) { delay_count = 0; do_gettimeofday(&tv_start); do { mdelay(1); do_gettimeofday(&tv_end); tv_diff = ((tv_end.tv_sec - tv_start.tv_sec) * 1000000) // sec + (tv_end.tv_usec - tv_start.tv_usec); // usec delay_count++; } while(dchdr->wait * 1000 > tv_diff); pr_info("%s: 0x%X needs %d(ms) delay and real delay is %ld(us), delay_count(%d).\n", __func__, cm->payload[0], (int)dchdr->wait, tv_diff, delay_count); } #endif #else if (dchdr->wait) usleep(dchdr->wait * 1000); #endif cm++; } if (video_mode) MIPI_OUTP((ctrl->ctrl_base) + 0x0004, dsi_ctrl); /* restore */ return cnt; }
static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_cmd_desc *cmds, int cnt) { struct dsi_buf *tp; struct dsi_cmd_desc *cm; struct dsi_ctrl_hdr *dchdr; int len, wait, tot = 0; #ifdef CONFIG_OLED_SUPPORT #ifdef LGE_HRTIMER_OLED_PATCH #else struct timeval tv_start, tv_end; long tv_diff; int delay_count; #endif #endif tp = &ctrl->tx_buf; mdss_dsi_buf_init(tp); cm = cmds; len = 0; while (cnt--) { dchdr = &cm->dchdr; mdss_dsi_buf_reserve(tp, len); len = mdss_dsi_cmd_dma_add(tp, cm); if (!len) { pr_err("%s: failed to add cmd = 0x%x\n", __func__, cm->payload[0]); return -EINVAL; } tot += len; if (dchdr->last) { tp->data = tp->start; /* begin of buf */ wait = mdss_dsi_wait4video_eng_busy(ctrl); mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); len = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(len)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to call cmd_dma_tx for cmd = 0x%x\n", __func__, cmds->payload[0]); return -EINVAL; } #ifdef CONFIG_OLED_SUPPORT #ifdef LGE_HRTIMER_OLED_PATCH if (!wait || dchdr->wait/* > VSYNC_PERIOD*/) { pr_info("[Zee][OLED] mipi_dsi_tx(0x%X) start (target delay=%dms)\n", cm->payload[0], (int)dchdr->wait); if (dchdr->wait > 5) oled_hrtimer_delay(dchdr->wait); else mdelay(dchdr->wait); pr_info("[Zee][OLED] mipi_dsi_tx(0x%X) finish (target delay=%dms)\n", cm->payload[0], (int)dchdr->wait); } #else if (!wait || dchdr->wait/* > VSYNC_PERIOD*/) { delay_count = 0; do_gettimeofday(&tv_start); do { mdelay(1); do_gettimeofday(&tv_end); tv_diff = ((tv_end.tv_sec - tv_start.tv_sec) * 1000000) /* sec */ + (tv_end.tv_usec - tv_start.tv_usec); /* usec */ delay_count++; } while (dchdr->wait * 1000 > tv_diff); pr_info("%s: 0x%X needs %d(ms) delay and real delay is %ld(us), delay_count(%d).\n", __func__, cm->payload[0], (int)dchdr->wait, tv_diff, delay_count); } #endif #else if (!wait || dchdr->wait > VSYNC_PERIOD) usleep(dchdr->wait * 1000); #endif mdss_dsi_buf_init(tp); len = 0; } cm++; } return tot; }