From 88037da79978863dd344635ffaf002d944ef1d00 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Tue, 26 May 2020 14:52:46 -0700 Subject: [PATCH] disp: msm: fix vram allocation when IOMMU is not present Allocate DSI/LUTDMA buffers from VRAM when IOMMU is not available. Add checks in msm_gem to avoid few operations when aspace is not available due to no IOMMU. Parse the VRAM size from device tree, when available. Change-Id: Iedf5749b71c2e772ac5434048520a34705c54b45 Signed-off-by: Veera Sundaram Sankaran --- msm/dsi/dsi_display.c | 26 ++++++++++++++++---------- msm/msm_drv.c | 22 ++++++++++++++++------ msm/msm_gem.c | 22 ++++++++++++---------- msm/sde/sde_color_processing.c | 8 +++++++- msm/sde/sde_hw_reg_dma_v1.c | 27 ++++++++++++++++----------- 5 files changed, 67 insertions(+), 38 deletions(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 2396b63f..8d70d882 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -495,17 +495,23 @@ static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) display->aspace = msm_gem_smmu_address_space_get( display->drm_dev, MSM_SMMU_DOMAIN_UNSECURE); - if (!display->aspace) { - DSI_ERR("failed to get aspace\n"); - rc = -EINVAL; - goto free_gem; - } - /* register to aspace */ - rc = msm_gem_address_space_register_cb(display->aspace, - dsi_display_aspace_cb_locked, (void *)display); - if (rc) { - DSI_ERR("failed to register callback %d\n", rc); + + if (PTR_ERR(display->aspace) == -ENODEV) { + display->aspace = NULL; + DSI_DEBUG("IOMMU not present, relying on VRAM\n"); + } else if (IS_ERR_OR_NULL(display->aspace)) { + rc = PTR_ERR(display->aspace); + display->aspace = NULL; + DSI_ERR("failed to get aspace %d\n", rc); goto free_gem; + } else if (display->aspace) { + /* register to aspace */ + rc = msm_gem_address_space_register_cb(display->aspace, + dsi_display_aspace_cb_locked, (void *)display); + if (rc) { + DSI_ERR("failed to register callback %d\n", rc); + goto free_gem; + } } rc = msm_gem_get_iova(display->tx_cmd_buf, display->aspace, diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 3382a4f1..e79f8900 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -522,8 +522,13 @@ static int msm_init_vram(struct drm_device *dev) * mach-msm: */ } else if (!iommu_present(&platform_bus_type)) { - DRM_INFO("using %s VRAM carveout\n", vram); - size = memparse(vram, NULL); + u32 vram_size; + + ret = of_property_read_u32(dev->dev->of_node, + "qcom,vram-size", &vram_size); + size = (ret < 0) ? memparse(vram, NULL) : vram_size; + DRM_INFO("using 0x%x VRAM carveout\n", size); + ret = 0; } if (size) { @@ -1894,21 +1899,26 @@ msm_gem_smmu_address_space_get(struct drm_device *dev, struct msm_drm_private *priv = NULL; struct msm_kms *kms; const struct msm_kms_funcs *funcs; + struct msm_gem_address_space *aspace; + + if (!iommu_present(&platform_bus_type)) + return ERR_PTR(-ENODEV); if ((!dev) || (!dev->dev_private)) - return NULL; + return ERR_PTR(-EINVAL); priv = dev->dev_private; kms = priv->kms; if (!kms) - return NULL; + return ERR_PTR(-EINVAL); funcs = kms->funcs; if ((!funcs) || (!funcs->get_address_space)) - return NULL; + return ERR_PTR(-EINVAL); - return funcs->get_address_space(priv->kms, domain); + aspace = funcs->get_address_space(priv->kms, domain); + return aspace ? aspace : ERR_PTR(-EINVAL); } int msm_get_mixer_count(struct msm_drm_private *priv, diff --git a/msm/msm_gem.c b/msm/msm_gem.c index fbc8bc61..4be1b8c3 100644 --- a/msm/msm_gem.c +++ b/msm/msm_gem.c @@ -109,22 +109,23 @@ static struct page **get_pages(struct drm_gem_object *obj) return ptr; } - /* For non-cached buffers, ensure the new pages are clean - * because display controller, GPU, etc. are not coherent: + if (msm_obj->vram_node) { + goto end; + /* + * For non-cached buffers, ensure the new pages are clean + * because display controller, GPU, etc. are not coherent */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) { + } else if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) { aspace_dev = msm_gem_get_aspace_device(msm_obj->aspace); if (aspace_dev) dma_map_sg(aspace_dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, - DMA_BIDIRECTIONAL); + msm_obj->sgt->nents, DMA_BIDIRECTIONAL); else - dev_err(dev->dev, - "failed to get aspace_device\n"); - + DRM_ERROR("failed to get aspace_device\n"); } } +end: return msm_obj->pages; } @@ -191,6 +192,8 @@ void msm_gem_sync(struct drm_gem_object *obj) msm_obj = to_msm_bo(obj); + if (msm_obj->vram_node) + return; /* * dma_sync_sg_for_device synchronises a single contiguous or * scatter/gather mapping for the CPU and device. @@ -200,8 +203,7 @@ void msm_gem_sync(struct drm_gem_object *obj) dma_sync_sg_for_device(aspace_dev, msm_obj->sgt->sgl, msm_obj->sgt->nents, DMA_BIDIRECTIONAL); else - dev_err(obj->dev->dev, - "failed to get aspace_device\n"); + DRM_ERROR("failed to get aspace_device\n"); } diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index c2209d1a..cbd4be9d 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -3474,7 +3474,13 @@ static void _sde_cp_crtc_set_ltm_buffer(struct sde_crtc *sde_crtc, void *cfg) sde_crtc->ltm_buffers[i]->aspace = msm_gem_smmu_address_space_get(crtc->dev, MSM_SMMU_DOMAIN_UNSECURE); - if (!sde_crtc->ltm_buffers[i]->aspace) { + + if (PTR_ERR(sde_crtc->ltm_buffers[i]->aspace) == -ENODEV) { + sde_crtc->ltm_buffers[i]->aspace = NULL; + DRM_DEBUG("IOMMU not present, relying on VRAM\n"); + } else if (IS_ERR_OR_NULL(sde_crtc->ltm_buffers[i]->aspace)) { + ret = PTR_ERR(sde_crtc->ltm_buffers[i]->aspace); + sde_crtc->ltm_buffers[i]->aspace = NULL; DRM_ERROR("failed to get aspace\n"); goto exit; } diff --git a/msm/sde/sde_hw_reg_dma_v1.c b/msm/sde/sde_hw_reg_dma_v1.c index 4fbcf742..d900c48a 100644 --- a/msm/sde/sde_hw_reg_dma_v1.c +++ b/msm/sde/sde_hw_reg_dma_v1.c @@ -1015,19 +1015,24 @@ static struct sde_reg_dma_buffer *alloc_reg_dma_buf_v1(u32 size) aspace = msm_gem_smmu_address_space_get(reg_dma->drm_dev, MSM_SMMU_DOMAIN_UNSECURE); - if (!aspace) { - DRM_ERROR("failed to get aspace\n"); - rc = -EINVAL; - goto free_gem; - } - /* register to aspace */ - rc = msm_gem_address_space_register_cb(aspace, - sde_reg_dma_aspace_cb_locked, - (void *)dma_buf); - if (rc) { - DRM_ERROR("failed to register callback %d", rc); + if (PTR_ERR(aspace) == -ENODEV) { + aspace = NULL; + DRM_DEBUG("IOMMU not present, relying on VRAM\n"); + } else if (IS_ERR_OR_NULL(aspace)) { + rc = PTR_ERR(aspace); + aspace = NULL; + DRM_ERROR("failed to get aspace %d", rc); goto free_gem; + } else if (aspace) { + /* register to aspace */ + rc = msm_gem_address_space_register_cb(aspace, + sde_reg_dma_aspace_cb_locked, + (void *)dma_buf); + if (rc) { + DRM_ERROR("failed to register callback %d", rc); + goto free_gem; + } } dma_buf->aspace = aspace;