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 <veeras@codeaurora.org>
This commit is contained in:
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user