Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58cf64ac authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: add support for DMA TPG for sending panel commands"

parents f73033b6 447b6e45
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -417,10 +417,10 @@ int dsi_panel_device_register(struct device_node *pan_node,
				struct mdss_dsi_ctrl_pdata *ctrl_pdata);

int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
		struct dsi_cmd_desc *cmds, int cnt);
		struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg);

int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,
			struct dsi_cmd_desc *cmds, int rlen);
			struct dsi_cmd_desc *cmds, int rlen, int use_dma_tpg);

void mdss_dsi_host_init(struct mdss_panel_data *pdata);
void mdss_dsi_op_mode_config(int mode,
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ struct dsi_cmd_desc {
#define CMD_REQ_COMMIT  0x0002
#define CMD_CLK_CTRL    0x0004
#define CMD_REQ_UNICAST 0x0008
#define CMD_REQ_DMA_TPG 0x0040
#define CMD_REQ_NO_MAX_PKT_SIZE 0x0008
#define CMD_REQ_LP_MODE 0x0010
#define CMD_REQ_HS_MODE 0x0020
+152 −34
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@
#include "mdss_debug.h"

#define VSYNC_PERIOD 17
#define DMA_TX_TIMEOUT 200
#define DMA_TPG_FIFO_LEN 64

struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX];

@@ -1207,8 +1209,107 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
static int mdss_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,
			struct dsi_buf *rp, int rlen);

static int mdss_dsi_cmd_dma_tpg_tx(struct mdss_dsi_ctrl_pdata *ctrl,
					struct dsi_buf *tp)
{
	int len, i, ret = 0, data = 0;
	u32 *bp, ctrl_rev;
	struct mdss_dsi_ctrl_pdata *mctrl = NULL;

	if (tp->len > DMA_TPG_FIFO_LEN) {
		pr_debug("command length more than FIFO length\n");
		return -EINVAL;
	}

	ctrl_rev = MIPI_INP(ctrl->ctrl_base);

	if (ctrl_rev < MDSS_DSI_HW_REV_103) {
		pr_err("CMD DMA TPG not supported for this DSI version\n");
		return -EINVAL;
	}

	bp = (u32 *)tp->data;
	len = ALIGN(tp->len, 4);

	INIT_COMPLETION(ctrl->dma_comp);

	if (mdss_dsi_sync_wait_trigger(ctrl))
		mctrl = mdss_dsi_get_other_ctrl(ctrl);

	data = BIT(16) | BIT(17);	/* select CMD_DMA_PATTERN_SEL to 3 */
	data |= BIT(2);			/* select CMD_DMA_FIFO_MODE to 1 */
	data |= BIT(1);			/* enable CMD_DMA_TPG */

	MIPI_OUTP(ctrl->ctrl_base + 0x15c, data);
	if (mctrl)
		MIPI_OUTP(mctrl->ctrl_base + 0x15c, data);

	/*
	 * The DMA command parameters need to be programmed to the DMA_INIT_VAL
	 * register in the proper order. The 'len' value will be a multiple
	 * of 4, the padding bytes to make sure of this will be taken care of in
	 * mdss_dsi_cmd_dma_add API.
	 */
	for (i = 0; i < len; i += 4) {
		MIPI_OUTP(ctrl->ctrl_base + 0x17c, *bp);
		if (mctrl)
			MIPI_OUTP(mctrl->ctrl_base + 0x17c, *bp);
		wmb(); /* make sure write happens before writing next command */
		bp++;
	}

	/*
	 * The number of writes to the DMA_INIT_VAL register should be an even
	 * number of dwords (32 bits). In case 'len' is not a multiple of 8,
	 * we need to do make an extra write to the register with 0x00 to
	 * satisfy this condition.
	 */
	if ((len % 8) != 0) {
		MIPI_OUTP(ctrl->ctrl_base + 0x17c, 0x00);
		if (mctrl)
			MIPI_OUTP(mctrl->ctrl_base + 0x17c, 0x00);
	}

	if (mctrl) {
		MIPI_OUTP(mctrl->ctrl_base + 0x04c, len);
		MIPI_OUTP(mctrl->ctrl_base + 0x090, 0x01); /* trigger */
	}
	MIPI_OUTP(ctrl->ctrl_base + 0x04c, len);
	wmb(); /* make sure DMA length is programmed */

	MIPI_OUTP(ctrl->ctrl_base + 0x090, 0x01); /* trigger */
	wmb(); /* make sure DMA trigger happens */

	ret = wait_for_completion_timeout(&ctrl->dma_comp,
				msecs_to_jiffies(DMA_TX_TIMEOUT));
	if (ret == 0)
		ret = -ETIMEDOUT;
	else
		ret = tp->len;

	/* Reset the DMA TPG FIFO */
	MIPI_OUTP(ctrl->ctrl_base + 0x1ec, 0x1);
	wmb(); /* make sure FIFO reset happens */
	MIPI_OUTP(ctrl->ctrl_base + 0x1ec, 0x0);
	wmb(); /* make sure FIFO reset happens */
	/* Disable CMD_DMA_TPG */
	MIPI_OUTP(ctrl->ctrl_base + 0x15c, 0x0);

	if (mctrl) {
		/* Reset the DMA TPG FIFO */
		MIPI_OUTP(mctrl->ctrl_base + 0x1ec, 0x1);
		wmb(); /* make sure FIFO reset happens */
		MIPI_OUTP(mctrl->ctrl_base + 0x1ec, 0x0);
		wmb(); /* make sure FIFO reset happens */
		/* Disable CMD_DMA_TPG */
		MIPI_OUTP(mctrl->ctrl_base + 0x15c, 0x0);
	}

	return ret;
}

static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl,
			struct dsi_cmd_desc *cmds, int cnt)
			struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg)
{
	struct dsi_buf *tp;
	struct dsi_cmd_desc *cm;
@@ -1235,6 +1336,9 @@ static int mdss_dsi_cmds2buf_tx(struct mdss_dsi_ctrl_pdata *ctrl,
			wait = mdss_dsi_wait4video_eng_busy(ctrl);

			mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
			if (use_dma_tpg)
				len = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp);
			else
				len = mdss_dsi_cmd_dma_tx(ctrl, tp);
			if (IS_ERR_VALUE(len)) {
				mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM);
@@ -1293,7 +1397,7 @@ static inline bool __mdss_dsi_cmd_mode_config(
 * thread context only
 */
int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
		struct dsi_cmd_desc *cmds, int cnt)
		struct dsi_cmd_desc *cmds, int cnt, int use_dma_tpg)
{
	int len = 0;
	struct mdss_dsi_ctrl_pdata *mctrl = NULL;
@@ -1328,7 +1432,7 @@ int mdss_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
do_send:
	ctrl->cmd_cfg_restore = __mdss_dsi_cmd_mode_config(ctrl, 1);

	len = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt);
	len = mdss_dsi_cmds2buf_tx(ctrl, cmds, cnt, use_dma_tpg);
	if (!len)
		pr_err("%s: failed to call\n", __func__);

@@ -1369,7 +1473,7 @@ static struct dsi_cmd_desc pkt_size_cmd = {
 *
 */
int mdss_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,
			struct dsi_cmd_desc *cmds, int rlen)
			struct dsi_cmd_desc *cmds, int rlen, int use_dma_tpg)
{
	int data_byte, rx_byte, dlen, end;
	int short_response, diff, pkt_size, ret = 0;
@@ -1451,6 +1555,9 @@ do_send:
		mdss_dsi_wait4video_eng_busy(ctrl);

		mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
		if (use_dma_tpg)
			ret = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp);
		else
			ret = mdss_dsi_cmd_dma_tx(ctrl, tp);
		if (IS_ERR_VALUE(ret)) {
			mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM);
@@ -1484,6 +1591,9 @@ do_send:
		mdss_dsi_wait4video_eng_busy(ctrl);	/* video mode only */
		mdss_dsi_enable_irq(ctrl, DSI_CMD_TERM);
		/* transmit read comamnd to client */
		if (use_dma_tpg)
			ret = mdss_dsi_cmd_dma_tpg_tx(ctrl, tp);
		else
			ret = mdss_dsi_cmd_dma_tx(ctrl, tp);
		if (IS_ERR_VALUE(ret)) {
			mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM);
@@ -1585,8 +1695,6 @@ end:
	return rp->read_cnt;
}

#define DMA_TX_TIMEOUT 200

static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
					struct dsi_buf *tp)
{
@@ -1911,7 +2019,8 @@ int mdss_dsi_cmdlist_tx(struct mdss_dsi_ctrl_pdata *ctrl,
			ctrl->do_unicast = true;
	}

	len = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt);
	len = mdss_dsi_cmds_tx(ctrl, req->cmds, req->cmds_cnt,
				(req->flags & CMD_REQ_DMA_TPG));

	if (req->cb)
		req->cb(len);
@@ -1927,7 +2036,8 @@ int mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl,

	if (req->rbuf) {
		rp = &ctrl->rx_buf;
		len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen);
		len = mdss_dsi_cmds_rx(ctrl, req->cmds, req->rlen,
				(req->flags & CMD_REQ_DMA_TPG));
		memcpy(req->rbuf, rp->data, rp->len);
		ctrl->rx_len = len;
	} else {
@@ -1947,6 +2057,7 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
	struct mdss_rect *roi = NULL;
	int ret = -EINVAL;
	int rc = 0;
	u32 ctrl_rev;

	if (mdss_get_sd_client_cnt())
		return -EPERM;
@@ -1966,6 +2077,12 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
	/* make sure dsi_cmd_mdp is idle */
	mdss_dsi_cmd_mdp_busy(ctrl);

	ctrl_rev = MIPI_INP(ctrl->ctrl_base);

	/* For DSI versions less than 1.3.0, CMD DMA TPG is not supported */
	if (ctrl_rev < MDSS_DSI_HW_REV_103)
		req->flags &= ~CMD_REQ_DMA_TPG;

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

@@ -1995,19 +2112,16 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)

	MDSS_XLOG(ctrl->ndx, req->flags, req->cmds_cnt, from_mdp, current->pid);

	/*
	 * mdss interrupt is generated in mdp core clock domain
	 * mdp clock need to be enabled to receive dsi interrupt
	 * also, axi bus bandwidth need since dsi controller will
	 * fetch dcs commands from axi bus
	 */

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);

	if (!(req->flags & CMD_REQ_DMA_TPG)) {
		if (ctrl->mdss_util->bus_bandwidth_ctrl)
			ctrl->mdss_util->bus_bandwidth_ctrl(1);

		if (ctrl->mdss_util->bus_scale_set_quota)
		ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, SZ_1M, SZ_1M);

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
			ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT,
								SZ_1M, SZ_1M);

		if (ctrl->mdss_util->iommu_ctrl) {
			rc = ctrl->mdss_util->iommu_ctrl(1);
@@ -2017,6 +2131,7 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
				return rc;
			}
		}
	}

	mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);

@@ -2031,14 +2146,17 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
	if (req->flags & CMD_REQ_HS_MODE)
		mdss_dsi_set_tx_power_mode(1, &ctrl->panel_data);

	if (!(req->flags & CMD_REQ_DMA_TPG)) {
		if (ctrl->mdss_util->iommu_ctrl)
			ctrl->mdss_util->iommu_ctrl(0);

	mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
		if (ctrl->mdss_util->bus_scale_set_quota)
			ctrl->mdss_util->bus_scale_set_quota(MDSS_DSI_RT, 0, 0);
		if (ctrl->mdss_util->bus_bandwidth_ctrl)
			ctrl->mdss_util->bus_bandwidth_ctrl(0);
	}

	mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
need_lock:

	MDSS_XLOG(ctrl->ndx, from_mdp, ctrl->mdp_busy, current->pid,