Exemplo n.º 1
0
/*
 * 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;
}
Exemplo n.º 3
0
/*
 * 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;
}
Exemplo n.º 4
0
/*
 * 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;
}
Exemplo n.º 6
0
/*
 * 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;
}