Ejemplo n.º 1
0
/*
 * 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;
    struct mdss_dsi_ctrl_pdata *mctrl = NULL;

    /*
     * 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.
     */

    if (mdss_dsi_sync_wait_enable(ctrl)) {
        if (mdss_dsi_sync_wait_trigger(ctrl)) {
            mctrl = mdss_dsi_get_other_ctrl(ctrl);
            if (!mctrl) {
                pr_warn("%s: sync_wait, NULL at other control\n",
                        __func__);
                goto do_send;
            }

            mctrl->cmd_cfg_restore =
                __mdss_dsi_cmd_mode_config(mctrl, 1);
        } else if (!ctrl->do_unicast) {
            /* broadcast cmds, let cmd_trigger do it */
            return 0;

        }
    }

    pr_debug("%s: ctrl=%d do_unicast=%d\n", __func__,
             ctrl->ndx, ctrl->do_unicast);

do_send:
    ctrl->cmd_cfg_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 (!ctrl->do_unicast) {
        if (mctrl && mctrl->cmd_cfg_restore) {
            __mdss_dsi_cmd_mode_config(mctrl, 0);
            mctrl->cmd_cfg_restore = false;
        }

        if (ctrl->cmd_cfg_restore) {
            __mdss_dsi_cmd_mode_config(ctrl, 0);
            ctrl->cmd_cfg_restore = false;
        }
    }

    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__);
		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
	}
		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
	}

	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_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;
}