diff options
| author | Ujwal Patel <ujwalp@codeaurora.org> | 2013-08-02 17:35:52 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:19:56 -0700 |
| commit | 5d546aa4e1fad084e3fe0e8f2aa2839a6acc4753 (patch) | |
| tree | 00801238765774bf8fb960c617fd8e2e9a84c241 | |
| parent | 6f10be25d60e115537aee4b739e23b32cc0ea7f5 (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.c | 17 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.h | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_io_util.c | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_video.c | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 20 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_wb.c | 13 |
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; } |
