static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
					struct dsi_buf *tp)
{
	int len;
	int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
	char *bp;
	unsigned long size, addr;

	bp = tp->data;

	len = ALIGN(tp->len, 4);
	size = ALIGN(tp->len, SZ_4K);


	if (is_mdss_iommu_attached()) {
		int ret = msm_iommu_map_contig_buffer(tp->dmap,
					mdss_get_iommu_domain(domain), 0,
					size, SZ_4K, 0, &(addr));
		if (IS_ERR_VALUE(ret)) {
			pr_err("unable to map dma memory to iommu(%d)\n", ret);
			return -ENOMEM;
		}
	} else {
		addr = tp->dmap;
	}

	INIT_COMPLETION(ctrl->dma_comp);

	if (ctrl->shared_pdata.broadcast_enable)
		if ((ctrl->ndx == DSI_CTRL_1)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x048, addr);
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x04c, len);
		}

	MIPI_OUTP((ctrl->ctrl_base) + 0x048, addr);
	MIPI_OUTP((ctrl->ctrl_base) + 0x04c, len);
	wmb();

	if (ctrl->shared_pdata.broadcast_enable)
		if ((ctrl->ndx == DSI_CTRL_1)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x090, 0x01);
		}

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

	if (!wait_for_completion_timeout(&ctrl->dma_comp,
				msecs_to_jiffies(DMA_TX_TIMEOUT))) {
		pr_err("%s: dma timeout error\n", __func__);
	}

	if (is_mdss_iommu_attached())
		msm_iommu_unmap_contig_buffer(addr,
			mdss_get_iommu_domain(domain), 0, size);

	return tp->len;
}
int mdss_mdp_put_img(struct mdss_mdp_img_data *data)
{
	struct ion_client *iclient = mdss_get_ionclient();
	if (data->flags & MDP_MEMORY_ID_TYPE_FB) {
		pr_debug("fb mem buf=0x%x\n", data->addr);
		fput_light(data->srcp_file, data->p_need);
		data->srcp_file = NULL;
	} else if (data->srcp_file) {
		pr_debug("pmem buf=0x%x\n", data->addr);
		data->srcp_file = NULL;
	} else if (!IS_ERR_OR_NULL(data->srcp_ihdl)) {
		pr_debug("ion hdl=%p buf=0x%x\n", data->srcp_ihdl, data->addr);

		if (is_mdss_iommu_attached()) {
			int domain;
			if (data->flags & MDP_SECURE_OVERLAY_SESSION)
				domain = MDSS_IOMMU_DOMAIN_SECURE;
			else
				domain = MDSS_IOMMU_DOMAIN_UNSECURE;
			ion_unmap_iommu(iclient, data->srcp_ihdl,
					mdss_get_iommu_domain(domain), 0);

			if (domain == MDSS_IOMMU_DOMAIN_SECURE) {
				msm_ion_unsecure_buffer(iclient,
					data->srcp_ihdl);
				mdss_mdp_secure_vote(0);
			}
		}

		ion_free(iclient, data->srcp_ihdl);
		data->srcp_ihdl = NULL;
	} else {
		return -ENOMEM;
	}

	return 0;
}
Example #3
0
int mdss_dsi_cmd_dma_tx(struct dsi_buf *tp,
			struct mdss_panel_data *pdata)
{
	int len;
	int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
	char *bp;
	unsigned long size, addr;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;

	if (pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);
		return -EINVAL;
	}

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);
	bp = tp->data;

	len = ALIGN(tp->len, 4);
	size = ALIGN(tp->len, SZ_4K);

	tp->dmap = dma_map_single(&dsi_dev, tp->data, size, DMA_TO_DEVICE);
	if (dma_mapping_error(&dsi_dev, tp->dmap)) {
		pr_err("%s: dmap mapp failed\n", __func__);
		return -ENOMEM;
	}

	if (is_mdss_iommu_attached()) {
		int ret = msm_iommu_map_contig_buffer(tp->dmap,
					mdss_get_iommu_domain(domain), 0,
					size, SZ_4K, 0, &(addr));
		if (IS_ERR_VALUE(ret)) {
			pr_err("unable to map dma memory to iommu(%d)\n", ret);
			return -ENOMEM;
		}
	} else {
		addr = tp->dmap;
	}

	INIT_COMPLETION(dsi_dma_comp);

	if (ctrl_pdata->shared_pdata.broadcast_enable)
		if ((pdata->panel_info.pdest == DISPLAY_2)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x048, addr);
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x04c, len);
		}

	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x048, addr);
	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x04c, len);
	wmb();

	if (ctrl_pdata->shared_pdata.broadcast_enable)
		if ((pdata->panel_info.pdest == DISPLAY_2)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x090, 0x01);
		}

	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x090, 0x01);	/* trigger */
	wmb();

	wait_for_completion(&dsi_dma_comp);

	if (is_mdss_iommu_attached())
		msm_iommu_unmap_contig_buffer(addr,
			mdss_get_iommu_domain(domain), 0, size);

	dma_unmap_single(&dsi_dev, tp->dmap, size, DMA_TO_DEVICE);
	tp->dmap = 0;
	return tp->len;
}
static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
					struct dsi_buf *tp)
{
	int len, ret = 0;
	int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
	char *bp;
	unsigned long size;
	dma_addr_t addr;
	struct mdss_dsi_ctrl_pdata *mctrl = NULL;
#ifdef DEBUG_CMD
	int i;
	bp = tp->data;

	pr_info("%s: ", __func__);
	for (i = 0; i < tp->len; i++)
		printk("%x ", *bp++);

	pr_info("\n");
#endif
	bp = tp->data;

	len = ALIGN(tp->len, 4);
	size = ALIGN(tp->len, SZ_4K);
	

	if (is_mdss_iommu_attached()) {
		ret = msm_iommu_map_contig_buffer(tp->dmap,
					mdss_get_iommu_domain(domain), 0,
					size, SZ_4K, 0, &(addr));
		if (IS_ERR_VALUE(ret)) {
			pr_err("unable to map dma memory to iommu(%d)\n", ret);
			return -ENOMEM;
		}
	} else {
		addr = tp->dmap;
	}

	INIT_COMPLETION(ctrl->dma_comp);

	/* Ensure that for slave controller, master is also configured */
	if (mdss_dsi_is_slave_ctrl(ctrl)) {
		mctrl = mdss_dsi_get_master_ctrl();
		if (mctrl) {
			MIPI_OUTP(mctrl->ctrl_base + 0x048, addr);
			MIPI_OUTP(mctrl->ctrl_base + 0x04c, len);
		} else {
			pr_warn("%s: Unable to get master control\n",
				__func__);
		}
	}

	MIPI_OUTP((ctrl->ctrl_base) + 0x048, addr);
	MIPI_OUTP((ctrl->ctrl_base) + 0x04c, len);
	wmb();

	/* Trigger on master controller as well */
	if (mctrl)
		MIPI_OUTP(mctrl->ctrl_base + 0x090, 0x01);

	MIPI_OUTP((ctrl->ctrl_base) + 0x090, 0x01);
	wmb();

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

	if (is_mdss_iommu_attached())
		msm_iommu_unmap_contig_buffer(addr,
			mdss_get_iommu_domain(domain), 0, size);

	return ret;
}
Example #5
0
static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
                               struct dsi_buf *tp)
{
    int len, ret = 0;
    int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
    char *bp;
    struct mdss_dsi_ctrl_pdata *mctrl = NULL;

    bp = tp->data;

    len = ALIGN(tp->len, 4);
    ctrl->dma_size = ALIGN(tp->len, SZ_4K);


    if (is_mdss_iommu_attached()) {
        int ret = msm_iommu_map_contig_buffer(tp->dmap,
                                              mdss_get_iommu_domain(domain), 0,
                                              ctrl->dma_size, SZ_4K, 0, &(ctrl->dma_addr));
        if (IS_ERR_VALUE(ret)) {
            pr_err("unable to map dma memory to iommu(%d)\n", ret);
            return -ENOMEM;
        }
    } else {
        ctrl->dma_addr = tp->dmap;
    }

    INIT_COMPLETION(ctrl->dma_comp);

    if (mdss_dsi_sync_wait_trigger(ctrl)) {
        /* broadcast same cmd to other panel */
        mctrl = mdss_dsi_get_other_ctrl(ctrl);
        if (mctrl && mctrl->dma_addr == 0) {
            MIPI_OUTP(mctrl->ctrl_base + 0x048, ctrl->dma_addr);
            MIPI_OUTP(mctrl->ctrl_base + 0x04c, len);
            MIPI_OUTP(mctrl->ctrl_base + 0x090, 0x01); /* trigger */
        }
    }

    /* send cmd to its panel */
    MIPI_OUTP((ctrl->ctrl_base) + 0x048, ctrl->dma_addr);
    MIPI_OUTP((ctrl->ctrl_base) + 0x04c, len);
    wmb();

    MIPI_OUTP((ctrl->ctrl_base) + 0x090, 0x01);
    wmb();

    if (ctrl->do_unicast) {
        /* let cmd_trigger to kickoff later */
        pr_debug("%s: SKIP, ndx=%d do_unicast=%d\n", __func__,
                 ctrl->ndx, ctrl->do_unicast);
        ret = tp->len;
        goto end;
    }

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

    if (mctrl && mctrl->dma_addr) {
        if (is_mdss_iommu_attached()) {
            msm_iommu_unmap_contig_buffer(mctrl->dma_addr,
                                          mdss_get_iommu_domain(domain), 0, mctrl->dma_size);
        }
        mctrl->dma_addr = 0;
        mctrl->dma_size = 0;
    }

    if (is_mdss_iommu_attached()) {
        msm_iommu_unmap_contig_buffer(ctrl->dma_addr,
                                      mdss_get_iommu_domain(domain), 0, ctrl->dma_size);
    }

    ctrl->dma_addr = 0;
    ctrl->dma_size = 0;
end:
    return ret;
}
static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
					struct dsi_buf *tp)
{
	int len, ret = 0;
	int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
	char *bp;
	unsigned long size, addr;

#ifdef DEBUG_CMD
	int i;
	bp = tp->data;

	pr_info("%s: ", __func__);
	for (i = 0; i < tp->len; i++)
		printk("%x ", *bp++);

	pr_info("\n");
#endif
	bp = tp->data;

	len = ALIGN(tp->len, 4);
	size = ALIGN(tp->len, SZ_4K);

	tp->dmap = dma_map_single(&dsi_dev, tp->data, size, DMA_TO_DEVICE);
	if (dma_mapping_error(&dsi_dev, tp->dmap)) {
		pr_err("%s: dmap mapp failed\n", __func__);
		return -ENOMEM;
	}

	if (is_mdss_iommu_attached()) {
		int ret = msm_iommu_map_contig_buffer(tp->dmap,
					mdss_get_iommu_domain(domain), 0,
					size, SZ_4K, 0, &(addr));
		if (IS_ERR_VALUE(ret)) {
			pr_err("unable to map dma memory to iommu(%d)\n", ret);
			return -ENOMEM;
		}
	} else {
		addr = tp->dmap;
	}

	INIT_COMPLETION(ctrl->dma_comp);

	if (ctrl->shared_pdata.broadcast_enable)
		if ((ctrl->ndx == DSI_CTRL_1)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x048, addr);
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x04c, len);
		}

	MIPI_OUTP((ctrl->ctrl_base) + 0x048, addr);
	MIPI_OUTP((ctrl->ctrl_base) + 0x04c, len);
	wmb();

	if (ctrl->shared_pdata.broadcast_enable)
		if ((ctrl->ndx == DSI_CTRL_1)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x090, 0x01);
		}

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

	ret = wait_for_completion_timeout(&ctrl->dma_comp,
				msecs_to_jiffies(DMA_TX_TIMEOUT));
	if (ret == 0) {
#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
		dumpreg();
		mdp5_dump_regs();
		mdss_dsi_dump_power_clk(&ctrl->panel_data, 0);
		mdss_mdp_dump_power_clk();
		mdss_mdp_debug_bus();
		xlog_dump();
#endif
		pr_err("dma tx timeout!!\n");
		ret = -ETIMEDOUT;
	} else
		ret = tp->len;

	if (is_mdss_iommu_attached())
		msm_iommu_unmap_contig_buffer(addr,
			mdss_get_iommu_domain(domain), 0, size);

	return ret;
}
/*
 * 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;
	u32 dsi_ctrl, data;
	int video_mode;
	u32 left_dsi_ctrl = 0;
	bool left_ctrl_restore = false;

	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)) {
			left_dsi_ctrl = MIPI_INP(left_ctrl_pdata->ctrl_base
								+ 0x0004);
			video_mode = left_dsi_ctrl & 0x02; /* VIDEO_MODE_EN */
			if (video_mode) {
				data = left_dsi_ctrl | 0x04; /* CMD_MODE_EN */
				MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
						data);
				left_ctrl_restore = true;
			}
		}
	}

	/* 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);
	}
/*fix qcom bug*/
#ifdef CONFIG_HUAWEI_KERNEL
	if (rlen <= 2) {
#else		
	if (rlen == 0) {
#endif	
		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)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 (left_ctrl_restore)
		MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x0004,
					left_dsi_ctrl); /*restore */
	if (video_mode)
		MIPI_OUTP((ctrl->ctrl_base) + 0x0004,
					dsi_ctrl); /* restore */

	return rp->len;
}

#define DMA_TX_TIMEOUT 200
static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
					struct dsi_buf *tp)
{
	int len, ret = 0;
	int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
	char *bp;
	unsigned long size, addr;
#ifdef CONFIG_HUAWEI_LCD
    bool iommu_attached = false;
#endif
	bp = tp->data;

	len = ALIGN(tp->len, 4);
	size = ALIGN(tp->len, SZ_4K);


	if (is_mdss_iommu_attached()) {
		int ret = msm_iommu_map_contig_buffer(tp->dmap,
					mdss_get_iommu_domain(domain), 0,
					size, SZ_4K, 0, &(addr));
		if (IS_ERR_VALUE(ret)) {
			pr_err("unable to map dma memory to iommu(%d)\n", ret);
			return -ENOMEM;
		}
    #ifdef CONFIG_HUAWEI_LCD
        iommu_attached = true;
    #endif
	} else {
		addr = tp->dmap;
    #ifdef CONFIG_HUAWEI_LCD
        iommu_attached = false;
    #endif
	}

	INIT_COMPLETION(ctrl->dma_comp);

	if (ctrl->shared_pdata.broadcast_enable)
		if ((ctrl->ndx == DSI_CTRL_1)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x048, addr);
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x04c, len);
		}

	MIPI_OUTP((ctrl->ctrl_base) + 0x048, addr);
	MIPI_OUTP((ctrl->ctrl_base) + 0x04c, len);
	wmb();

	if (ctrl->shared_pdata.broadcast_enable)
		if ((ctrl->ndx == DSI_CTRL_1)
		  && (left_ctrl_pdata != NULL)) {
			MIPI_OUTP(left_ctrl_pdata->ctrl_base + 0x090, 0x01);
		}

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

	ret = wait_for_completion_timeout(&ctrl->dma_comp,
				msecs_to_jiffies(DMA_TX_TIMEOUT));
	if (ret == 0)
		ret = -ETIMEDOUT;
	else
		ret = tp->len;
#ifdef CONFIG_HUAWEI_LCD
    //unmap it when it have been maped at front
    if (is_mdss_iommu_attached() && iommu_attached)
#else
    if (is_mdss_iommu_attached())
#endif
		msm_iommu_unmap_contig_buffer(addr,
			mdss_get_iommu_domain(domain), 0, size);

	return ret;
}
int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data)
{
	struct file *file;
	int ret = -EINVAL;
	int fb_num;
	unsigned long *start, *len;
	struct ion_client *iclient = mdss_get_ionclient();

	start = (unsigned long *) &data->addr;
	len = (unsigned long *) &data->len;
	data->flags |= img->flags;
	data->p_need = 0;

	if (img->flags & MDP_BLIT_SRC_GEM) {
		data->srcp_file = NULL;
		ret = kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
					start, len);
	} else if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
		file = fget_light(img->memory_id, &data->p_need);
		if (file == NULL) {
			pr_err("invalid framebuffer file (%d)\n",
					img->memory_id);
			return -EINVAL;
		}
		data->srcp_file = file;

		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
			ret = mdss_fb_get_phys_info(start, len, fb_num);
			if (ret)
				pr_err("mdss_fb_get_phys_info() failed\n");
		} else {
			pr_err("invalid FB_MAJOR\n");
			ret = -1;
		}
	} else if (iclient) {
		data->srcp_ihdl = ion_import_dma_buf(iclient, img->memory_id);
		if (IS_ERR_OR_NULL(data->srcp_ihdl)) {
			pr_err("error on ion_import_fd\n");
			ret = PTR_ERR(data->srcp_ihdl);
			data->srcp_ihdl = NULL;
			return ret;
		}

		if (is_mdss_iommu_attached()) {
			int domain;
			if (data->flags & MDP_SECURE_OVERLAY_SESSION) {
				domain = MDSS_IOMMU_DOMAIN_SECURE;

				mdss_mdp_secure_vote(1);
				ret = msm_ion_secure_buffer(iclient,
					data->srcp_ihdl, 0x2, 0);
				if (IS_ERR_VALUE(ret)) {
					ion_free(iclient, data->srcp_ihdl);
					pr_err("failed to secure handle (%d)\n",
						ret);
					return ret;
				}
			} else {
				domain = MDSS_IOMMU_DOMAIN_UNSECURE;
			}

			ret = ion_map_iommu(iclient, data->srcp_ihdl,
					    mdss_get_iommu_domain(domain),
					    0, SZ_4K, 0, start, len, 0, 0);
		} else {
			ret = ion_phys(iclient, data->srcp_ihdl, start,
				       (size_t *) len);
		}

		if (IS_ERR_VALUE(ret)) {
			ion_free(iclient, data->srcp_ihdl);
			pr_err("failed to map ion handle (%d)\n", ret);
			return ret;
		}
	}

	if (!*start) {
		pr_err("start address is zero!\n");
		return -ENOMEM;
	}

	if (!ret && (img->offset < data->len)) {
		data->addr += img->offset;
		data->len -= img->offset;

		pr_debug("mem=%d ihdl=%p buf=0x%x len=0x%x\n", img->memory_id,
			 data->srcp_ihdl, data->addr, data->len);
	} else {
		return -EINVAL;
	}

	return ret;
}