summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUjwal Patel <ujwalp@codeaurora.org>2013-08-02 17:35:52 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:19:56 -0700
commit5d546aa4e1fad084e3fe0e8f2aa2839a6acc4753 (patch)
tree00801238765774bf8fb960c617fd8e2e9a84c241
parent6f10be25d60e115537aee4b739e23b32cc0ea7f5 (diff)
msm: mdss: Add support for LPAE systems
In LPAE systems physical memory addressing is different than CPU addressing scheme. This change enables MDSS driver for LPAE systems where driver is directly dealing with physical addresses. Signed-off-by: Ujwal Patel <ujwalp@codeaurora.org> Change-Id: Icd332b771e803cf17b67211b1e35666e5a274a4e
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c17
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_io_util.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c7
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c20
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_wb.c13
6 files changed, 49 insertions, 13 deletions
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 1766d9567ff5..b09a42076b12 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -805,9 +805,10 @@ static struct fb_ops mdss_fb_ops = {
static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom)
{
void *virt = NULL;
- unsigned long phys = 0;
+ phys_addr_t phys = 0;
size_t size = 0;
struct platform_device *pdev = mfd->pdev;
+ int rc = 0;
if (!pdev || !pdev->dev.of_node) {
pr_err("Invalid device node\n");
@@ -836,11 +837,19 @@ static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom)
}
phys = memory_pool_node_paddr(virt);
+ if (MDSS_LPAE_CHECK(phys)) {
+ pr_warn("fb mem phys %pa > 4GB is not supported.\n", &phys);
+ free_contiguous_memory(virt);
+ return -ERANGE;
+ }
- msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0,
+ rc = msm_iommu_map_contig_buffer(phys, dom, 0, size, SZ_4K, 0,
&mfd->iova);
- pr_info("allocating %u bytes at %p (%lx phys) for fb %d\n",
- size, virt, phys, mfd->index);
+ if (rc)
+ pr_warn("Cannot map fb_mem %pa to IOMMU. rc=%d\n", &phys, rc);
+
+ pr_info("allocating 0x%x bytes at %p (%pa phys) for fb %d\n",
+ size, virt, &phys, mfd->index);
mfd->fbi->screen_base = virt;
mfd->fbi->fix.smem_start = phys;
diff --git a/drivers/video/fbdev/msm/mdss_fb.h b/drivers/video/fbdev/msm/mdss_fb.h
index ab7b360ce2f4..6019179e4216 100644
--- a/drivers/video/fbdev/msm/mdss_fb.h
+++ b/drivers/video/fbdev/msm/mdss_fb.h
@@ -21,6 +21,9 @@
#include "mdss_panel.h"
+#define MDSS_LPAE_CHECK(phys) \
+ ((sizeof(phys) > sizeof(unsigned long)) ? ((phys >> 32) & 0xFF) : (0))
+
#define MSM_FB_DEFAULT_PAGE_SIZE 2
#define MFD_KEY 0x11161126
#define MSM_FB_MAX_DEV_LIST 32
diff --git a/drivers/video/fbdev/msm/mdss_io_util.c b/drivers/video/fbdev/msm/mdss_io_util.c
index e8191c3c85d4..05b300e43a52 100644
--- a/drivers/video/fbdev/msm/mdss_io_util.c
+++ b/drivers/video/fbdev/msm/mdss_io_util.c
@@ -102,7 +102,7 @@ int msm_dss_ioremap_byname(struct platform_device *pdev,
return -ENODEV;
}
- io_data->len = resource_size(res);
+ io_data->len = (u32)resource_size(res);
io_data->base = ioremap(res->start, io_data->len);
if (!io_data->base) {
DEV_ERR("%pS->%s: '%s' ioremap failed\n",
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index 3f3e51ca64d3..a4f6238842e9 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -531,6 +531,13 @@ int mdss_mdp_video_copy_splash_screen(struct mdss_panel_data *pdata)
virt = ion_map_kernel(iclient, ihdl);
ion_phys(iclient, ihdl, &phys, &size);
+ if (MDSS_LPAE_CHECK(phys)) {
+ pr_err("Phys mem %pa >4Gb cannot be used w/o IOMMU\n", &phys);
+ pdata->panel_info.splash_ihdl = NULL;
+ ion_free(iclient, ihdl);
+ return -ERANGE;
+ }
+
pr_debug("%s %d Allocating %u bytes at 0x%lx (%pa phys)\n",
__func__, __LINE__, size,
(unsigned long int)virt, &phys);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 32fea953ff3a..4510b1689201 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1464,7 +1464,7 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
(dma_addr_t) mfd->cursor_buf_phys);
pr_err("unable to map cursor buffer to iommu(%d)\n",
ret);
- return -ENOMEM;
+ return ret;
}
}
@@ -1487,16 +1487,26 @@ static int mdss_mdp_hw_cursor_update(struct msm_fb_data_type *mfd,
(img->dy << 16) | img->dx);
if (cursor->set & FB_CUR_SETIMAGE) {
- int calpha_en, transp_en, alpha, size, cursor_addr;
+ int calpha_en, transp_en, alpha, size;
+ u32 cursor_addr;
ret = copy_from_user(mfd->cursor_buf, img->data,
img->width * img->height * 4);
- if (ret)
+ if (ret) {
+ pr_err("copy_from_user error. rc=%d\n", ret);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
return ret;
+ }
- if (is_mdss_iommu_attached())
+ if (is_mdss_iommu_attached()) {
cursor_addr = mfd->cursor_buf_iova;
- else
+ } else {
+ if (MDSS_LPAE_CHECK(mfd->cursor_buf_phys)) {
+ pr_err("can't access phy mem >4GB w/o iommu\n");
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+ return -ERANGE;
+ }
cursor_addr = mfd->cursor_buf_phys;
+ }
if (img->bg_color == 0xffffffff)
transp_en = 0;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_wb.c b/drivers/video/fbdev/msm/mdss_mdp_wb.c
index 062562c04345..1cc1f5b24856 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_wb.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_wb.c
@@ -102,16 +102,23 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd)
rc = ion_map_iommu(iclient, ihdl,
mdss_get_iommu_domain(domain),
0, SZ_4K, 0,
- (unsigned long *) &img->addr,
+ &img->addr,
(unsigned long *) &img->len,
0, 0);
} else {
+ if (MDSS_LPAE_CHECK(mdss_wb_mem)) {
+ pr_err("Can't use phys mem %pa>4Gb w/o IOMMU\n",
+ &mdss_wb_mem);
+ ion_free(iclient, ihdl);
+ return NULL;
+ }
+
img->addr = mdss_wb_mem;
img->len = img_size;
}
- pr_debug("ihdl=%p virt=%p phys=0x%lx iova=0x%x size=%u\n",
- ihdl, videomemory, mdss_wb_mem, img->addr, img_size);
+ pr_debug("ihdl=%p virt=%p phys=0x%pa iova=0x%pa size=%u\n",
+ ihdl, videomemory, &mdss_wb_mem, &img->addr, img_size);
}
return &mdss_wb_buffer;
}