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

Commit 4c2f1dd9 authored by Rashi Bindra's avatar Rashi Bindra Committed by Nirmal Abraham
Browse files

fbdev: msm: Changes for mapping once during dsi on



SMMU buffer mapping/unmapping is done at DSI ON/OFF
instead of doing it during mdss_dsi_cmd_dma_tx to
avoid smmu page faults and NOC errors.

Change-Id: Ie8a80b3076f58eb5918630e603430c4871d6d24f
Signed-off-by: default avatarRashi Bindra <rbindra@codeaurora.org>
Signed-off-by: default avatarraghavendra ambadas <rambad@codeaurora.org>
parent d2a07f17
Loading
Loading
Loading
Loading
+30 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, 2021, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -35,6 +35,7 @@
#include "mdss_debug.h"
#include "mdss_debug.h"
#include "mdss_dsi_phy.h"
#include "mdss_dsi_phy.h"
#include "mdss_dba_utils.h"
#include "mdss_dba_utils.h"
#include "mdss_smmu.h"


#define XO_CLK_RATE	19200000
#define XO_CLK_RATE	19200000
#define CMDLINE_DSI_CTL_NUM_STRING_LEN 2
#define CMDLINE_DSI_CTL_NUM_STRING_LEN 2
@@ -1338,6 +1339,8 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state)
	int ret = 0;
	int ret = 0;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	struct mdss_panel_info *panel_info = NULL;
	struct mdss_panel_info *panel_info = NULL;
	struct platform_device *pdev;
	struct dsi_buf *tp;


	if (pdata == NULL) {
	if (pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);
		pr_err("%s: Invalid input data\n", __func__);
@@ -1349,6 +1352,16 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state)


	panel_info = &ctrl_pdata->panel_data.panel_info;
	panel_info = &ctrl_pdata->panel_data.panel_info;


	pdev = mdss_res->pdev;
	tp = &ctrl_pdata->tx_buf;
	mdss_smmu_dma_free_coherent(&pdev->dev, SZ_4K, tp->start, tp->dmap,
			ctrl_pdata->dma_addr, MDSS_IOMMU_DOMAIN_UNSECURE);
	tp->end = NULL;
	tp->size = 0;
	ctrl_pdata->dma_addr = 0;
	tp->start = NULL;
	tp->dmap = 0;

	pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n",
	pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n",
		__func__, ctrl_pdata, ctrl_pdata->ndx, power_state);
		__func__, ctrl_pdata, ctrl_pdata->ndx, power_state);


@@ -1517,6 +1530,8 @@ int mdss_dsi_on(struct mdss_panel_data *pdata)
	struct mipi_panel_info *mipi;
	struct mipi_panel_info *mipi;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	int cur_power_state;
	int cur_power_state;
	struct platform_device *pdev;
	struct dsi_buf *tp;


	if (pdata == NULL) {
	if (pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);
		pr_err("%s: Invalid input data\n", __func__);
@@ -1526,6 +1541,20 @@ int mdss_dsi_on(struct mdss_panel_data *pdata)
	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);
				panel_data);


	pdev = mdss_res->pdev;
	tp = &ctrl_pdata->tx_buf;
	if (!ctrl_pdata->mdss_util->iommu_attached())
		pr_err("%s : iommu not attached\n", __func__);

	ret = mdss_smmu_dma_alloc_coherent(&pdev->dev, SZ_4K, &tp->dmap,
		&ctrl_pdata->dma_addr, (void *)&tp->start, GFP_KERNEL,
			MDSS_IOMMU_DOMAIN_UNSECURE);
	if (IS_ERR_VALUE((unsigned long)ret))
		pr_err("%s : mdss_smmu_dma_alloc_coherent failed\n", __func__);

	tp->end = tp->start + SZ_4K;
	tp->size = SZ_4K;

	if (ctrl_pdata->debugfs_info)
	if (ctrl_pdata->debugfs_info)
		mdss_dsi_validate_debugfs_info(ctrl_pdata);
		mdss_dsi_validate_debugfs_info(ctrl_pdata);


+5 −34
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 2021, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -121,7 +121,6 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev,
	mutex_init(&ctrl->cmd_mutex);
	mutex_init(&ctrl->cmd_mutex);
	mutex_init(&ctrl->clk_lane_mutex);
	mutex_init(&ctrl->clk_lane_mutex);
	mutex_init(&ctrl->cmdlist_mutex);
	mutex_init(&ctrl->cmdlist_mutex);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->tx_buf, SZ_4K);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->rx_buf, SZ_4K);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->rx_buf, SZ_4K);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->status_buf, SZ_4K);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->status_buf, SZ_4K);
	ctrl->cmdlist_commit = mdss_dsi_cmdlist_commit;
	ctrl->cmdlist_commit = mdss_dsi_cmdlist_commit;
@@ -2145,7 +2144,6 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
					struct dsi_buf *tp)
					struct dsi_buf *tp)
{
{
	int len, ret = 0;
	int len, ret = 0;
	int domain = MDSS_IOMMU_DOMAIN_UNSECURE;
	char *bp;
	char *bp;
	struct mdss_dsi_ctrl_pdata *mctrl = NULL;
	struct mdss_dsi_ctrl_pdata *mctrl = NULL;
	int ignored = 0;	/* overflow ignored */
	int ignored = 0;	/* overflow ignored */
@@ -2155,20 +2153,6 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
	len = ALIGN(tp->len, 4);
	len = ALIGN(tp->len, 4);
	ctrl->dma_size = ALIGN(tp->len, SZ_4K);
	ctrl->dma_size = ALIGN(tp->len, SZ_4K);


	ctrl->mdss_util->iommu_lock();
	if (ctrl->mdss_util->iommu_attached()) {
		ret = mdss_smmu_dsi_map_buffer(tp->dmap, domain, ctrl->dma_size,
			&(ctrl->dma_addr), tp->start, DMA_TO_DEVICE);
		if (IS_ERR_VALUE((unsigned long)ret)) {
			pr_err("unable to map dma memory to iommu(%d)\n", ret);
			ctrl->mdss_util->iommu_unlock();
			return -ENOMEM;
		}
		ctrl->dmap_iommu_map = true;
	} else {
		ctrl->dma_addr = tp->dmap;
	}

	reinit_completion(&ctrl->dma_comp);
	reinit_completion(&ctrl->dma_comp);


	if (ctrl->panel_mode == DSI_VIDEO_MODE)
	if (ctrl->panel_mode == DSI_VIDEO_MODE)
@@ -2177,7 +2161,7 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
	if (mdss_dsi_sync_wait_trigger(ctrl)) {
	if (mdss_dsi_sync_wait_trigger(ctrl)) {
		/* broadcast same cmd to other panel */
		/* broadcast same cmd to other panel */
		mctrl = mdss_dsi_get_other_ctrl(ctrl);
		mctrl = mdss_dsi_get_other_ctrl(ctrl);
		if (mctrl && mctrl->dma_addr == 0) {
		if (mctrl) {
			if (ignored) {
			if (ignored) {
				/* mask out overflow isr */
				/* mask out overflow isr */
				mdss_dsi_set_reg(mctrl, 0x10c,
				mdss_dsi_set_reg(mctrl, 0x10c,
@@ -2229,6 +2213,7 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
			pr_warn("%s: dma tx done but irq not triggered\n",
			pr_warn("%s: dma tx done but irq not triggered\n",
				__func__);
				__func__);
		} else {
		} else {
			MDSS_XLOG(0x909, status);
			ret = -ETIMEDOUT;
			ret = -ETIMEDOUT;
		}
		}
	}
	}
@@ -2245,19 +2230,6 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
			if (!(data & BIT(5)))
			if (!(data & BIT(5)))
				mdss_dsi_set_reg(mctrl, 0x10c, 0x0f0000, 0);
				mdss_dsi_set_reg(mctrl, 0x10c, 0x0f0000, 0);
		}
		}
		if (mctrl->dmap_iommu_map) {
			mdss_smmu_dsi_unmap_buffer(mctrl->dma_addr, domain,
				mctrl->dma_size, DMA_TO_DEVICE);
			mctrl->dmap_iommu_map = false;
		}
		mctrl->dma_addr = 0;
		mctrl->dma_size = 0;
	}

	if (ctrl->dmap_iommu_map) {
		mdss_smmu_dsi_unmap_buffer(ctrl->dma_addr, domain,
			ctrl->dma_size, DMA_TO_DEVICE);
		ctrl->dmap_iommu_map = false;
	}
	}


	if (ignored) {
	if (ignored) {
@@ -2268,10 +2240,9 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
		if (!(data & BIT(5)))
		if (!(data & BIT(5)))
			mdss_dsi_set_reg(ctrl, 0x10c, 0x0f0000, 0);
			mdss_dsi_set_reg(ctrl, 0x10c, 0x0f0000, 0);
	}
	}
	ctrl->dma_addr = 0;
	MDSS_XLOG(ret);
	ctrl->dma_size = 0;

end:
end:
	ctrl->mdss_util->iommu_unlock();
	return ret;
	return ret;
}
}


+6 −7
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 2021, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -1499,6 +1499,11 @@ static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
	MDSS_XLOG(ctl->num, ctl->underrun_cnt);
	MDSS_XLOG(ctl->num, ctl->underrun_cnt);


	if (!ctx->timegen_en) {
	if (!ctx->timegen_en) {
		rc = mdss_iommu_ctrl(1);
		if (IS_ERR_VALUE((unsigned long)rc)) {
			pr_err("IOMMU attach failed\n");
			return rc;
		}
		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL,
		rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_LINK_READY, NULL,
			CTL_INTF_EVENT_FLAG_DEFAULT);
			CTL_INTF_EVENT_FLAG_DEFAULT);
		if (rc) {
		if (rc) {
@@ -1521,12 +1526,6 @@ static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
					usecs_to_jiffies(VSYNC_TIMEOUT_US));
					usecs_to_jiffies(VSYNC_TIMEOUT_US));
		}
		}


		rc = mdss_iommu_ctrl(1);
		if (IS_ERR_VALUE((unsigned long)rc)) {
			pr_err("IOMMU attach failed\n");
			return rc;
		}

		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);


		mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
		mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,