int mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl, struct dcs_cmd_req *req) { struct dsi_buf *rp; int len = 0, ret = -EINVAL; if (req->rbuf) { rp = &ctrl->rx_buf; len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen); memcpy(req->rbuf, rp->data, rp->len); /* * For dual DSI cases, early return of master ctrl * is valid. Hence, for those cases the return value * is zero even though we don't send any commands. */ if (mdss_dsi_is_master_ctrl(ctrl) || (len != 0)) ret = 0; } else { pr_err("%s: No rx buffer provided\n", __func__); } if (req->cb) req->cb(len); return ret; }
/* * 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) { int ret = 0; bool ctrl_restore = false, mctrl_restore = false; struct mdss_dsi_ctrl_pdata *mctrl = NULL; /* * In broadcast mode, the configuration for master controller * would be done when the slave controller is configured */ if (mdss_dsi_is_master_ctrl(ctrl)) { pr_debug("%s: Broadcast mode enabled. skipping config for ctrl%d\n", __func__, ctrl->ndx); return 0; } /* * Turn on cmd mode in order to transmit the commands. * For video mode, do not send cmds more than one pixel line, * since it only transmit it during BLLP. * Ensure that for slave controller, master is also configured */ if (mdss_dsi_is_slave_ctrl(ctrl)) { mctrl = mdss_dsi_get_master_ctrl(); if (!mctrl) pr_warn("%s: Unable to get master control\n", __func__); else mctrl_restore = __mdss_dsi_cmd_mode_config(mctrl, 1); } ctrl_restore = __mdss_dsi_cmd_mode_config(ctrl, 1); ret = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt); if (IS_ERR_VALUE(ret)) { pr_err("%s: failed to call\n", __func__); cnt = -EINVAL; } if (mctrl_restore) __mdss_dsi_cmd_mode_config(mctrl, 0); if (ctrl_restore) __mdss_dsi_cmd_mode_config(ctrl, 0); return cnt; }
/* * 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) { int ret = 0; bool ctrl_restore = false, mctrl_restore = false; struct mdss_dsi_ctrl_pdata *mctrl = NULL; /* * In broadcast mode, the configuration for master controller * would be done when the slave controller is configured */ if (mdss_dsi_is_master_ctrl(ctrl)) { pr_debug("%s: Broadcast mode enabled. skipping config for ctrl%d\n", __func__, ctrl->ndx); return 0; } /* * Turn on cmd mode in order to transmit the commands. * For video mode, do not send cmds more than one pixel line, * since it only transmit it during BLLP. * Ensure that for slave controller, master is also configured */ if (mdss_dsi_is_slave_ctrl(ctrl)) { mctrl = mdss_dsi_get_master_ctrl(); if (!mctrl) pr_warn("%s: Unable to get master control\n", __func__); #ifdef CONFIG_MACH_LGE else{ mdelay(5); mctrl_restore = __mdss_dsi_cmd_mode_config(mctrl, 1); } #else else mctrl_restore = __mdss_dsi_cmd_mode_config(mctrl, 1); #endif }
void mdss_dsi_op_mode_config(int mode, struct mdss_panel_data *pdata) { u32 dsi_ctrl, intr_ctrl; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_dsi_ctrl_pdata *mctrl = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return; } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); /* * In broadcast mode, the configuration for master controller * would be done when the slave controller is configured */ if (mdss_dsi_is_master_ctrl(ctrl_pdata)) { pr_debug("%s: Broadcast mode enabled. skipping config for ctrl%d\n", __func__, ctrl_pdata->ndx); return; } dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004); /*If Video enabled, Keep Video and Cmd mode ON */ if (dsi_ctrl & 0x02) dsi_ctrl &= ~0x05; else dsi_ctrl &= ~0x07; if (mode == DSI_VIDEO_MODE) { dsi_ctrl |= 0x03; intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_BTA_DONE_MASK; } else { /* command mode */ dsi_ctrl |= 0x05; if (pdata->panel_info.type == MIPI_VIDEO_PANEL) dsi_ctrl |= 0x02; intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK | DSI_INTR_CMD_MDP_DONE_MASK | DSI_INTR_BTA_DONE_MASK; } /* Ensure that for slave controller, master is also configured */ if (mdss_dsi_is_slave_ctrl(ctrl_pdata)) { mctrl = mdss_dsi_get_master_ctrl(); if (mctrl) { pr_debug("%s: configuring ctrl%d\n", __func__, mctrl->ndx); MIPI_OUTP(mctrl->ctrl_base + 0x0110, intr_ctrl); MIPI_OUTP(mctrl->ctrl_base + 0x0004, dsi_ctrl); } else { pr_warn("%s: Unable to get master control\n", __func__); } } pr_debug("%s: configuring ctrl%d\n", __func__, ctrl_pdata->ndx); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0110, intr_ctrl); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl); wmb(); }
/* * mdss_dsi_cmds_rx() - dcs read from panel * @ctrl: dsi controller * @cmds: read command descriptor * @len: number of bytes to read back * * controller have 4 registers can hold 16 bytes of rxed data * dcs packet: 4 bytes header + payload + 2 bytes crc * 2 padding bytes add to payload to have payload length is mutipled by 4 * 1st read: 4 bytes header + 8 bytes payload + 2 padding + 2 crc * 2nd read: 12 bytes payload + 2 padding + 2 crc * 3rd read: 12 bytes payload + 2 padding + 2 crc * */ int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_cmd_desc *cmds, int rlen) { int data_byte, rx_byte, dlen, end; int short_response, diff, pkt_size, ret = 0; struct dsi_buf *tp, *rp; char cmd; bool ctrl_restore = false, mctrl_restore = false; struct mdss_dsi_ctrl_pdata *mctrl = NULL; /* * In broadcast mode, the configuration for master controller * would be done when the slave controller is configured */ if (mdss_dsi_is_master_ctrl(ctrl)) { pr_debug("%s: Broadcast mode enabled. skipping config for ctrl%d\n", __func__, ctrl->ndx); return 0; } /* * Turn on cmd mode in order to transmit the commands. * For video mode, do not send cmds more than one pixel line, * since it only transmit it during BLLP. * Ensure that for slave controller, master is also configured */ if (mdss_dsi_is_slave_ctrl(ctrl)) { mctrl = mdss_dsi_get_master_ctrl(); if (!mctrl) pr_warn("%s: Unable to get master control\n", __func__); else mctrl_restore = __mdss_dsi_cmd_mode_config(mctrl, 1); } ctrl_restore = __mdss_dsi_cmd_mode_config(ctrl, 1); if (rlen <= 2) { short_response = 1; rx_byte = 4; } else { short_response = 0; data_byte = 8; /* first read */ /* * add extra 2 padding bytes 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. */ pkt_size = data_byte + 2; rx_byte = data_byte + 8; /* 4 header + 2 crc + 2 padding*/ } tp = &ctrl->tx_buf; rp = &ctrl->rx_buf; end = 0; mdss_dsi_buf_init(rp); while (!end) { pr_debug("%s: rlen=%d pkt_size=%d rx_byte=%d\n", __func__, rlen, pkt_size, rx_byte); if (!short_response) { max_pktsize[0] = pkt_size; mdss_dsi_buf_init(tp); ret = mdss_dsi_cmd_dma_add(tp, &pkt_size_cmd); if (!ret) { pr_err("%s: failed to add max_pkt_size\n", __func__); rp->len = 0; goto end; } mdss_dsi_wait4video_eng_busy(ctrl); mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); ret = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(ret)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to tx max_pkt_size\n", __func__); rp->len = 0; goto end; } pr_debug("%s: max_pkt_size=%d sent\n", __func__, pkt_size); } mdss_dsi_buf_init(tp); ret = mdss_dsi_cmd_dma_add(tp, cmds); if (!ret) { pr_err("%s: failed to add cmd = 0x%x\n", __func__, cmds->payload[0]); rp->len = 0; goto end; } mdss_dsi_wait4video_eng_busy(ctrl); /* video mode only */ mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM); /* transmit read comamnd to client */ ret = mdss_dsi_cmd_dma_tx(ctrl, tp); if (IS_ERR_VALUE(ret)) { mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM); pr_err("%s: failed to tx cmd = 0x%x\n", __func__, cmds->payload[0]); rp->len = 0; goto end; } /* * once cmd_dma_done interrupt received, * return data from client is ready and stored * at RDBK_DATA register already * since rx fifo is 16 bytes, dcs header is kept at first loop, * after that dcs header lost during shift into registers */ dlen = mdss_dsi_cmd_dma_rx(ctrl, rp, rx_byte); if (short_response) break; if (rlen <= data_byte) { diff = data_byte - rlen; end = 1; } else { diff = 0; rlen -= data_byte; } dlen -= 2; /* 2 padding bytes */ dlen -= 2; /* 2 crc */ dlen -= diff; rp->data += dlen; /* next start position */ rp->len += dlen; data_byte = 12; /* NOT first read */ pkt_size += data_byte; pr_debug("%s: rp data=%x len=%d dlen=%d diff=%d\n", __func__, (int) (unsigned long) rp->data, rp->len, dlen, diff); } rp->data = rp->start; /* move back to start position */ cmd = rp->data[0]; switch (cmd) { case DTYPE_ACK_ERR_RESP: pr_debug("%s: rx ACK_ERR_PACLAGE\n", __func__); rp->len = 0; case DTYPE_GEN_READ1_RESP: case DTYPE_DCS_READ1_RESP: mdss_dsi_short_read1_resp(rp); break; case DTYPE_GEN_READ2_RESP: case DTYPE_DCS_READ2_RESP: mdss_dsi_short_read2_resp(rp); break; case DTYPE_GEN_LREAD_RESP: case DTYPE_DCS_LREAD_RESP: mdss_dsi_long_read_resp(rp); break; default: pr_warning("%s:Invalid response cmd\n", __func__); rp->len = 0; } end: if (mctrl_restore) __mdss_dsi_cmd_mode_config(mctrl, 0); if (ctrl_restore) __mdss_dsi_cmd_mode_config(ctrl, 0); return rp->len; }