diff options
| author | Jordan Crouse <jcrouse@codeaurora.org> | 2017-02-13 10:14:16 -0700 |
|---|---|---|
| committer | Jordan Crouse <jcrouse@codeaurora.org> | 2017-02-22 09:52:08 -0700 |
| commit | 1314edd5c5a4c42e5159285de31814ec6ff8beba (patch) | |
| tree | 3505d984fe37c573c6cba2b21b444e10b9e2c683 /drivers/gpu | |
| parent | 3aea14ccac22a874ae7666cec1b11a9ab4a82f02 (diff) | |
drm/msm: get an iova from the address space instead of an id
In the future we won't have a fixed set of addresses spaces.
Instead of going through the effort of assigning a ID for each
address space just use the address space itself as a token for
getting / putting an iova.
This forces a few changes in the gem object however: instead
of using a simple index into a list of domains, we need to
maintain a list of them. Luckily the list will be pretty small;
even with dynamic address spaces we wouldn't ever see more than
two or three.
Change-Id: Ic0dedbad4495f02a21135217f3605b93f8b8dfea
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
26 files changed, 220 insertions, 190 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 478a41181083..392622953df9 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -64,7 +64,7 @@ int adreno_hw_init(struct msm_gpu *gpu) DBG("%s", gpu->name); - ret = msm_gem_get_iova(gpu->rb->bo, gpu->id, &gpu->rb_iova); + ret = msm_gem_get_iova(gpu->rb->bo, gpu->aspace, &gpu->rb_iova); if (ret) { gpu->rb_iova = 0; dev_err(gpu->dev->dev, "could not map ringbuffer: %d\n", ret); @@ -417,7 +417,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, return -ENOMEM; } - ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->id, + ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->aspace, &adreno_gpu->memptrs_iova); if (ret) { dev_err(drm->dev, "could not map memptrs: %d\n", ret); @@ -433,7 +433,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu) if (gpu->memptrs_bo) { if (gpu->memptrs_iova) - msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id); + msm_gem_put_iova(gpu->memptrs_bo, gpu->base.aspace); drm_gem_object_unreference_unlocked(gpu->memptrs_bo); } release_firmware(gpu->pm4); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 6ac9aa165768..dff43329c020 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -133,7 +133,7 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) container_of(work, struct mdp4_crtc, unref_cursor_work); struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base); - msm_gem_put_iova(val, mdp4_kms->id); + msm_gem_put_iova(val, mdp4_kms->aspace); drm_gem_object_unreference_unlocked(val); } @@ -392,7 +392,8 @@ static void update_cursor(struct drm_crtc *crtc) if (next_bo) { /* take a obj ref + iova ref when we start scanning out: */ drm_gem_object_reference(next_bo); - msm_gem_get_iova_locked(next_bo, mdp4_kms->id, &iova); + msm_gem_get_iova_locked(next_bo, mdp4_kms->aspace, + &iova); /* enable cursor: */ mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma), @@ -449,7 +450,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, } if (cursor_bo) { - ret = msm_gem_get_iova(cursor_bo, mdp4_kms->id, &iova); + ret = msm_gem_get_iova(cursor_bo, mdp4_kms->aspace, &iova); if (ret) goto fail; } else { diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 6d8e174236ea..da9d58eccc3a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -197,7 +197,7 @@ static void mdp4_destroy(struct msm_kms *kms) struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); if (mdp4_kms->blank_cursor_iova) - msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id); + msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->aspace); if (mdp4_kms->blank_cursor_bo) drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo); @@ -541,13 +541,6 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) aspace = NULL; } - mdp4_kms->id = msm_register_address_space(dev, aspace); - if (mdp4_kms->id < 0) { - ret = mdp4_kms->id; - dev_err(dev->dev, "failed to register mdp4 iommu: %d\n", ret); - goto fail; - } - ret = modeset_init(mdp4_kms); if (ret) { dev_err(dev->dev, "modeset_init failed: %d\n", ret); @@ -564,7 +557,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) goto fail; } - ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id, + ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->aspace, &mdp4_kms->blank_cursor_iova); if (ret) { dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 923a028db452..aa060e71ec91 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -33,8 +33,6 @@ struct mdp4_kms { int rev; /* mapper-id used to request GEM buffer mapped for scanout: */ - int id; - void __iomem *mmio; struct regulator *dsi_pll_vdda; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 30d57e74c42f..bc1ece2a5b7e 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -109,7 +109,7 @@ static int mdp4_plane_prepare_fb(struct drm_plane *plane, return 0; DBG("%s: prepare: FB[%u]", mdp4_plane->name, fb->base.id); - return msm_framebuffer_prepare(fb, mdp4_kms->id); + return msm_framebuffer_prepare(fb, mdp4_kms->aspace); } static void mdp4_plane_cleanup_fb(struct drm_plane *plane, @@ -123,7 +123,7 @@ static void mdp4_plane_cleanup_fb(struct drm_plane *plane, return; DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id); - msm_framebuffer_cleanup(fb, mdp4_kms->id); + msm_framebuffer_cleanup(fb, mdp4_kms->aspace); } @@ -172,13 +172,13 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane, MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 0)); + msm_framebuffer_iova(fb, mdp4_kms->aspace, 0)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP1_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 1)); + msm_framebuffer_iova(fb, mdp4_kms->aspace, 1)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP2_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 2)); + msm_framebuffer_iova(fb, mdp4_kms->aspace, 2)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe), - msm_framebuffer_iova(fb, mdp4_kms->id, 3)); + msm_framebuffer_iova(fb, mdp4_kms->aspace, 3)); plane->fb = fb; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 7f9f4ac88029..56c1f6c4ab96 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -171,7 +171,7 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) container_of(work, struct mdp5_crtc, unref_cursor_work); struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base); - msm_gem_put_iova(val, mdp5_kms->id); + msm_gem_put_iova(val, mdp5_kms->aspace); drm_gem_object_unreference_unlocked(val); } @@ -536,7 +536,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, if (!cursor_bo) return -ENOENT; - ret = msm_gem_get_iova(cursor_bo, mdp5_kms->id, &cursor_addr); + ret = msm_gem_get_iova(cursor_bo, mdp5_kms->aspace, &cursor_addr); if (ret) return -EINVAL; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index cc5a73505537..ede681e12a68 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -627,13 +627,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) aspace = NULL; } - mdp5_kms->id = msm_register_address_space(dev, aspace); - if (mdp5_kms->id < 0) { - ret = mdp5_kms->id; - dev_err(dev->dev, "failed to register mdp5 iommu: %d\n", ret); - goto fail; - } - ret = modeset_init(mdp5_kms); if (ret) { dev_err(dev->dev, "modeset_init failed: %d\n", ret); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 6cb43ad0c1d7..c1aa86d21416 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -36,7 +36,6 @@ struct mdp5_kms { /* mapper-id used to request GEM buffer mapped for scanout: */ - int id; struct msm_gem_address_space *aspace; struct mdp5_smp *smp; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 81cd49045ffc..873ab11d34d2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -260,7 +260,7 @@ static int mdp5_plane_prepare_fb(struct drm_plane *plane, return 0; DBG("%s: prepare: FB[%u]", mdp5_plane->name, fb->base.id); - return msm_framebuffer_prepare(fb, mdp5_kms->id); + return msm_framebuffer_prepare(fb, mdp5_kms->aspace); } static void mdp5_plane_cleanup_fb(struct drm_plane *plane, @@ -274,7 +274,7 @@ static void mdp5_plane_cleanup_fb(struct drm_plane *plane, return; DBG("%s: cleanup: FB[%u]", mdp5_plane->name, fb->base.id); - msm_framebuffer_cleanup(fb, mdp5_kms->id); + msm_framebuffer_cleanup(fb, mdp5_kms->aspace); } static int mdp5_plane_atomic_check(struct drm_plane *plane, @@ -400,13 +400,13 @@ static void set_scanout_locked(struct drm_plane *plane, MDP5_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 0)); + msm_framebuffer_iova(fb, mdp5_kms->aspace, 0)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 1)); + msm_framebuffer_iova(fb, mdp5_kms->aspace, 1)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 2)); + msm_framebuffer_iova(fb, mdp5_kms->aspace, 2)); mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe), - msm_framebuffer_iova(fb, mdp5_kms->id, 3)); + msm_framebuffer_iova(fb, mdp5_kms->aspace, 3)); plane->fb = fb; } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 4b67edf5a77b..6d3cf1accdb9 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -38,20 +38,6 @@ static const struct drm_mode_config_funcs mode_config_funcs = { .atomic_commit = msm_atomic_commit, }; -int msm_register_address_space(struct drm_device *dev, - struct msm_gem_address_space *aspace) -{ - struct msm_drm_private *priv = dev->dev_private; - int idx = priv->num_aspaces++; - - if (WARN_ON(idx >= ARRAY_SIZE(priv->aspace))) - return -EINVAL; - - priv->aspace[idx] = aspace; - - return idx; -} - #ifdef CONFIG_DRM_MSM_REGISTER_LOGGING static bool reglog = false; MODULE_PARM_DESC(reglog, "Enable register read/write logging"); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 4ed5953d07f9..f59bd5fd4d37 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -374,8 +374,6 @@ int msm_queue_fence_cb(struct drm_device *dev, struct msm_fence_cb *cb, uint32_t fence); void msm_update_fence(struct drm_device *dev, uint32_t fence); -int msm_register_address_space(struct drm_device *dev, - struct msm_gem_address_space *aspace); void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, struct sg_table *sgt, void *priv); @@ -402,13 +400,16 @@ int msm_gem_mmap_obj(struct drm_gem_object *obj, int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma); int msm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); -int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, - uint32_t *iova); -int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova); -uint32_t msm_gem_iova(struct drm_gem_object *obj, int id); +int msm_gem_get_iova_locked(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint32_t *iova); +int msm_gem_get_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint32_t *iova); +uint32_t msm_gem_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace); struct page **msm_gem_get_pages(struct drm_gem_object *obj); void msm_gem_put_pages(struct drm_gem_object *obj); -void msm_gem_put_iova(struct drm_gem_object *obj, int id); +void msm_gem_put_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace); int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, @@ -439,9 +440,12 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, struct drm_gem_object *msm_gem_import(struct drm_device *dev, uint32_t size, struct sg_table *sgt); -int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id); -void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id); -uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane); +int msm_framebuffer_prepare(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace); +void msm_framebuffer_cleanup(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace); +uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace, int plane); struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane); const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb); struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index dca4de382581..28395ea13235 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -92,14 +92,15 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m) * should be fine, since only the scanout (mdpN) side of things needs * this, the gpu doesn't care about fb's. */ -int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id) +int msm_framebuffer_prepare(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); int ret, i, n = drm_format_num_planes(fb->pixel_format); uint32_t iova; for (i = 0; i < n; i++) { - ret = msm_gem_get_iova(msm_fb->planes[i], id, &iova); + ret = msm_gem_get_iova(msm_fb->planes[i], aspace, &iova); DBG("FB[%u]: iova[%d]: %08x (%d)", fb->base.id, i, iova, ret); if (ret) return ret; @@ -108,21 +109,23 @@ int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id) return 0; } -void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id) +void msm_framebuffer_cleanup(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); int i, n = drm_format_num_planes(fb->pixel_format); for (i = 0; i < n; i++) - msm_gem_put_iova(msm_fb->planes[i], id); + msm_gem_put_iova(msm_fb->planes[i], aspace); } -uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane) +uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, + struct msm_gem_address_space *aspace, int plane) { struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); if (!msm_fb->planes[plane]) return 0; - return msm_gem_iova(msm_fb->planes[plane], id) + fb->offsets[plane]; + return msm_gem_iova(msm_fb->planes[plane], aspace) + fb->offsets[plane]; } struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 5aa08cf4d6d8..ca24cc433afc 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -273,20 +273,61 @@ uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj) return offset; } +static void obj_remove_domain(struct msm_gem_vma *domain) +{ + if (domain) { + list_del(&domain->list); + kfree(domain); + } +} + static void put_iova(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct msm_drm_private *priv = obj->dev->dev_private; struct msm_gem_object *msm_obj = to_msm_bo(obj); - int id; + struct msm_gem_vma *domain, *tmp; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) { - msm_gem_unmap_vma(priv->aspace[id], &msm_obj->domain[id], - msm_obj->sgt, get_dmabuf_ptr(obj)); + list_for_each_entry_safe(domain, tmp, &msm_obj->domains, list) { + if (iommu_present(&platform_bus_type)) { + msm_gem_unmap_vma(domain->aspace, domain, + msm_obj->sgt, get_dmabuf_ptr(obj)); + } + + obj_remove_domain(domain); + } +} + +static struct msm_gem_vma *obj_add_domain(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *domain = kzalloc(sizeof(*domain), GFP_KERNEL); + + if (!domain) + return ERR_PTR(-ENOMEM); + + domain->aspace = aspace; + + list_add_tail(&domain->list, &msm_obj->domains); + + return domain; +} + +static struct msm_gem_vma *obj_get_domain(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *domain; + + list_for_each_entry(domain, &msm_obj->domains, list) { + if (domain->aspace == aspace) + return domain; } + + return NULL; } /* should be called under struct_mutex.. although it can be called @@ -296,49 +337,64 @@ put_iova(struct drm_gem_object *obj) * That means when I do eventually need to add support for unpinning * the refcnt counter needs to be atomic_t. */ -int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id, - uint32_t *iova) +int msm_gem_get_iova_locked(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint32_t *iova) { struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct page **pages; + struct msm_gem_vma *domain; int ret = 0; - if (!msm_obj->domain[id].iova) { - struct msm_drm_private *priv = obj->dev->dev_private; - struct page **pages = get_pages(obj); + if (!iommu_present(&platform_bus_type)) { + pages = get_pages(obj); if (IS_ERR(pages)) return PTR_ERR(pages); - if (iommu_present(&platform_bus_type)) { - ret = msm_gem_map_vma(priv->aspace[id], - &msm_obj->domain[id], msm_obj->sgt, - get_dmabuf_ptr(obj)); - } else - msm_obj->domain[id].iova = physaddr(obj); + *iova = physaddr(obj); + return 0; + } + + domain = obj_get_domain(obj, aspace); + + if (!domain) { + domain = obj_add_domain(obj, aspace); + if (IS_ERR(domain)) + return PTR_ERR(domain); + + pages = get_pages(obj); + if (IS_ERR(pages)) { + obj_remove_domain(domain); + return PTR_ERR(pages); + } + + ret = msm_gem_map_vma(aspace, domain, msm_obj->sgt, + get_dmabuf_ptr(obj)); } if (!ret) - *iova = msm_obj->domain[id].iova; + *iova = domain->iova; + else + obj_remove_domain(domain); return ret; } /* get iova, taking a reference. Should have a matching put */ -int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova) +int msm_gem_get_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint32_t *iova) { - struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *domain; int ret; - /* this is safe right now because we don't unmap until the - * bo is deleted: - */ - if (msm_obj->domain[id].iova) { - *iova = msm_obj->domain[id].iova; + domain = obj_get_domain(obj, aspace); + if (domain) { + *iova = domain->iova; return 0; } mutex_lock(&obj->dev->struct_mutex); - ret = msm_gem_get_iova_locked(obj, id, iova); + ret = msm_gem_get_iova_locked(obj, aspace, iova); mutex_unlock(&obj->dev->struct_mutex); return ret; } @@ -346,14 +402,18 @@ int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova) /* get iova without taking a reference, used in places where you have * already done a 'msm_gem_get_iova()'. */ -uint32_t msm_gem_iova(struct drm_gem_object *obj, int id) +uint32_t msm_gem_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) { - struct msm_gem_object *msm_obj = to_msm_bo(obj); - WARN_ON(!msm_obj->domain[id].iova); - return msm_obj->domain[id].iova; + struct msm_gem_vma *domain = obj_get_domain(obj, aspace); + + WARN_ON(!domain); + + return domain ? domain->iova : 0; } -void msm_gem_put_iova(struct drm_gem_object *obj, int id) +void msm_gem_put_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) { // XXX TODO .. // NOTE: probably don't need a _locked() version.. we wouldn't @@ -487,9 +547,8 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) { struct drm_device *dev = obj->dev; struct msm_gem_object *msm_obj = to_msm_bo(obj); - struct msm_drm_private *priv = obj->dev->dev_private; + struct msm_gem_vma *domain; uint64_t off = drm_vma_node_start(&obj->vma_node); - int id; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p\t", @@ -498,8 +557,9 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) obj->name, obj->refcount.refcount.counter, off, msm_obj->vaddr); - for (id = 0; id < priv->num_aspaces; id++) - seq_printf(m, " %08llx", msm_obj->domain[id].iova); + /* FIXME: we need to print the address space here too */ + list_for_each_entry(domain, &msm_obj->domains, list) + seq_printf(m, " %08llx", domain->iova); seq_puts(m, "\n"); } @@ -618,8 +678,12 @@ static int msm_gem_new_impl(struct drm_device *dev, if (!msm_obj) return -ENOMEM; - if (use_vram) - msm_obj->vram_node = &msm_obj->domain[0].node; + if (use_vram) { + struct msm_gem_vma *domain = obj_add_domain(&msm_obj->base, 0); + + if (!IS_ERR(domain)) + msm_obj->vram_node = &domain->node; + } msm_obj->flags = flags; @@ -627,6 +691,8 @@ static int msm_gem_new_impl(struct drm_device *dev, reservation_object_init(msm_obj->resv); INIT_LIST_HEAD(&msm_obj->submit_entry); + INIT_LIST_HEAD(&msm_obj->domains); + list_add_tail(&msm_obj->mm_list, &priv->inactive_list); *obj = &msm_obj->base; diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 86c297c6de32..937e80c12554 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -43,7 +43,9 @@ struct msm_gem_address_space { struct msm_gem_vma { /* Node used by the GPU address space, but not the SDE address space */ struct drm_mm_node node; + struct msm_gem_address_space *aspace; uint64_t iova; + struct list_head list; }; struct msm_gem_object { @@ -74,7 +76,7 @@ struct msm_gem_object { struct sg_table *sgt; void *vaddr; - struct msm_gem_vma domain[NUM_DOMAINS]; + struct list_head domains; /* normally (resv == &_resv) except for imported bo's */ struct reservation_object *resv; diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 1847f83b1e33..f277f075d704 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -141,7 +141,7 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i) struct msm_gem_object *msm_obj = submit->bos[i].obj; if (submit->bos[i].flags & BO_PINNED) - msm_gem_put_iova(&msm_obj->base, submit->gpu->id); + msm_gem_put_iova(&msm_obj->base, submit->gpu->aspace); if (submit->bos[i].flags & BO_LOCKED) ww_mutex_unlock(&msm_obj->resv->lock); @@ -180,7 +180,7 @@ retry: /* if locking succeeded, pin bo: */ ret = msm_gem_get_iova_locked(&msm_obj->base, - submit->gpu->id, &iova); + submit->gpu->aspace, &iova); /* this would break the logic in the fail path.. there is no * reason for this to happen, but just to be on the safe side diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 1dc82145d3d0..9881461d7d24 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -474,7 +474,7 @@ static void retire_worker(struct work_struct *work) (obj->write_fence <= fence)) { /* move to inactive: */ msm_gem_move_to_inactive(&obj->base); - msm_gem_put_iova(&obj->base, gpu->id); + msm_gem_put_iova(&obj->base, gpu->aspace); drm_gem_object_unreference(&obj->base); } else { break; @@ -533,7 +533,7 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, /* ring takes a reference to the bo and iova: */ drm_gem_object_reference(&msm_obj->base); msm_gem_get_iova_locked(&msm_obj->base, - submit->gpu->id, &iova); + submit->gpu->aspace, &iova); } if (submit->bos[i].flags & MSM_SUBMIT_BO_READ) @@ -667,8 +667,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, } else { dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name); } - gpu->id = msm_register_address_space(drm, gpu->aspace); - /* Create ringbuffer: */ mutex_lock(&drm->struct_mutex); @@ -707,7 +705,7 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) if (gpu->rb) { if (gpu->rb_iova) - msm_gem_put_iova(gpu->rb->bo, gpu->id); + msm_gem_put_iova(gpu->rb->bo, gpu->aspace); msm_ringbuffer_destroy(gpu->rb); } } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 401f74075485..206814f33ca9 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -97,7 +97,6 @@ struct msm_gpu { int irq; struct msm_gem_address_space *aspace; - int id; /* Power Control: */ struct regulator *gpu_reg, *gpu_cx; diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index ac9997c238cd..6e27ac09c7a4 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * 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 @@ -88,8 +88,7 @@ static void _sde_connector_destroy_fb(struct sde_connector *c_conn, return; } - msm_framebuffer_cleanup(c_state->out_fb, - c_state->mmu_id); + msm_framebuffer_cleanup(c_state->out_fb, c_state->aspace); drm_framebuffer_unreference(c_state->out_fb); c_state->out_fb = NULL; @@ -193,7 +192,7 @@ sde_connector_atomic_duplicate_state(struct drm_connector *connector) if (c_state->out_fb) { drm_framebuffer_reference(c_state->out_fb); rc = msm_framebuffer_prepare(c_state->out_fb, - c_state->mmu_id); + c_state->aspace); if (rc) SDE_ERROR("failed to prepare fb, %d\n", rc); } @@ -241,14 +240,14 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector, rc = -EFAULT; } else { if (c_state->out_fb->flags & DRM_MODE_FB_SECURE) - c_state->mmu_id = - c_conn->mmu_id[SDE_IOMMU_DOMAIN_SECURE]; + c_state->aspace = + c_conn->aspace[SDE_IOMMU_DOMAIN_SECURE]; else - c_state->mmu_id = - c_conn->mmu_id[SDE_IOMMU_DOMAIN_UNSECURE]; + c_state->aspace = + c_conn->aspace[SDE_IOMMU_DOMAIN_UNSECURE]; rc = msm_framebuffer_prepare(c_state->out_fb, - c_state->mmu_id); + c_state->aspace); if (rc) SDE_ERROR("prep fb failed, %d\n", rc); } @@ -492,18 +491,17 @@ struct drm_connector *sde_connector_init(struct drm_device *dev, c_conn->panel = panel; c_conn->display = display; - /* cache mmu_id's for later */ sde_kms = to_sde_kms(priv->kms); if (sde_kms->vbif[VBIF_NRT]) { - c_conn->mmu_id[SDE_IOMMU_DOMAIN_UNSECURE] = - sde_kms->mmu_id[MSM_SMMU_DOMAIN_NRT_UNSECURE]; - c_conn->mmu_id[SDE_IOMMU_DOMAIN_SECURE] = - sde_kms->mmu_id[MSM_SMMU_DOMAIN_NRT_SECURE]; + c_conn->aspace[SDE_IOMMU_DOMAIN_UNSECURE] = + sde_kms->aspace[MSM_SMMU_DOMAIN_NRT_UNSECURE]; + c_conn->aspace[SDE_IOMMU_DOMAIN_SECURE] = + sde_kms->aspace[MSM_SMMU_DOMAIN_NRT_SECURE]; } else { - c_conn->mmu_id[SDE_IOMMU_DOMAIN_UNSECURE] = - sde_kms->mmu_id[MSM_SMMU_DOMAIN_UNSECURE]; - c_conn->mmu_id[SDE_IOMMU_DOMAIN_SECURE] = - sde_kms->mmu_id[MSM_SMMU_DOMAIN_SECURE]; + c_conn->aspace[SDE_IOMMU_DOMAIN_UNSECURE] = + sde_kms->aspace[MSM_SMMU_DOMAIN_UNSECURE]; + c_conn->aspace[SDE_IOMMU_DOMAIN_SECURE] = + sde_kms->aspace[MSM_SMMU_DOMAIN_SECURE]; } if (ops) diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h index 9580282291db..7d86528c81bc 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.h +++ b/drivers/gpu/drm/msm/sde/sde_connector.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * 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 @@ -140,7 +140,7 @@ struct sde_connector { struct drm_panel *panel; void *display; - int mmu_id[SDE_IOMMU_DOMAIN_MAX]; + struct msm_gem_address_space *aspace[SDE_IOMMU_DOMAIN_MAX]; char name[SDE_CONNECTOR_NAME_SIZE]; @@ -195,13 +195,13 @@ struct sde_connector { * struct sde_connector_state - private connector status structure * @base: Base drm connector structure * @out_fb: Pointer to output frame buffer, if applicable - * @mmu_id: MMU ID for accessing frame buffer objects, if applicable + * @aspace: Address space for accessing frame buffer objects, if applicable * @property_values: Local cache of current connector property values */ struct sde_connector_state { struct drm_connector_state base; struct drm_framebuffer *out_fb; - int mmu_id; + struct msm_gem_address_space *aspace; uint64_t property_values[CONNECTOR_PROP_COUNT]; }; diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h index ed4b7be34281..2205dd98a927 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h @@ -264,7 +264,7 @@ struct sde_encoder_phys_cmd { * @wb_fmt: Writeback pixel format * @frame_count: Counter of completed writeback operations * @kickoff_count: Counter of issued writeback operations - * @mmu_id: mmu identifier for non-secure/secure domain + * @aspace: address space identifier for non-secure/secure domain * @wb_dev: Pointer to writeback device * @start_time: Start time of writeback latest request * @end_time: End time of writeback latest request @@ -285,7 +285,7 @@ struct sde_encoder_phys_wb { const struct sde_format *wb_fmt; u32 frame_count; u32 kickoff_count; - int mmu_id[SDE_IOMMU_DOMAIN_MAX]; + struct msm_gem_address_space *aspace[SDE_IOMMU_DOMAIN_MAX]; struct sde_wb_device *wb_dev; ktime_t start_time; ktime_t end_time; diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c index 9943e3906df0..9368c4974126 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c @@ -180,7 +180,8 @@ static void sde_encoder_phys_wb_setup_fb(struct sde_encoder_phys *phys_enc, struct sde_hw_wb *hw_wb; struct sde_hw_wb_cfg *wb_cfg; const struct msm_format *format; - int ret, mmu_id; + int ret; + struct msm_gem_address_space *aspace; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); @@ -193,9 +194,9 @@ static void sde_encoder_phys_wb_setup_fb(struct sde_encoder_phys *phys_enc, wb_cfg->intf_mode = phys_enc->intf_mode; wb_cfg->is_secure = (fb->flags & DRM_MODE_FB_SECURE) ? true : false; - mmu_id = (wb_cfg->is_secure) ? - wb_enc->mmu_id[SDE_IOMMU_DOMAIN_SECURE] : - wb_enc->mmu_id[SDE_IOMMU_DOMAIN_UNSECURE]; + aspace = (wb_cfg->is_secure) ? + wb_enc->aspace[SDE_IOMMU_DOMAIN_SECURE] : + wb_enc->aspace[SDE_IOMMU_DOMAIN_UNSECURE]; SDE_DEBUG("[fb_secure:%d]\n", wb_cfg->is_secure); @@ -217,7 +218,7 @@ static void sde_encoder_phys_wb_setup_fb(struct sde_encoder_phys *phys_enc, wb_cfg->roi = *wb_roi; if (hw_wb->caps->features & BIT(SDE_WB_XY_ROI_OFFSET)) { - ret = sde_format_populate_layout(mmu_id, fb, &wb_cfg->dest); + ret = sde_format_populate_layout(aspace, fb, &wb_cfg->dest); if (ret) { SDE_DEBUG("failed to populate layout %d\n", ret); return; @@ -226,7 +227,7 @@ static void sde_encoder_phys_wb_setup_fb(struct sde_encoder_phys *phys_enc, wb_cfg->dest.height = fb->height; wb_cfg->dest.num_planes = wb_cfg->dest.format->num_planes; } else { - ret = sde_format_populate_layout_with_roi(mmu_id, fb, wb_roi, + ret = sde_format_populate_layout_with_roi(aspace, fb, wb_roi, &wb_cfg->dest); if (ret) { /* this error should be detected during atomic_check */ @@ -1017,15 +1018,15 @@ struct sde_encoder_phys *sde_encoder_phys_wb_init( phys_enc = &wb_enc->base; if (p->sde_kms->vbif[VBIF_NRT]) { - wb_enc->mmu_id[SDE_IOMMU_DOMAIN_UNSECURE] = - p->sde_kms->mmu_id[MSM_SMMU_DOMAIN_NRT_UNSECURE]; - wb_enc->mmu_id[SDE_IOMMU_DOMAIN_SECURE] = - p->sde_kms->mmu_id[MSM_SMMU_DOMAIN_NRT_SECURE]; + wb_enc->aspace[SDE_IOMMU_DOMAIN_UNSECURE] = + p->sde_kms->aspace[MSM_SMMU_DOMAIN_NRT_UNSECURE]; + wb_enc->aspace[SDE_IOMMU_DOMAIN_SECURE] = + p->sde_kms->aspace[MSM_SMMU_DOMAIN_NRT_SECURE]; } else { - wb_enc->mmu_id[SDE_IOMMU_DOMAIN_UNSECURE] = - p->sde_kms->mmu_id[MSM_SMMU_DOMAIN_UNSECURE]; - wb_enc->mmu_id[SDE_IOMMU_DOMAIN_SECURE] = - p->sde_kms->mmu_id[MSM_SMMU_DOMAIN_SECURE]; + wb_enc->aspace[SDE_IOMMU_DOMAIN_UNSECURE] = + p->sde_kms->aspace[MSM_SMMU_DOMAIN_UNSECURE]; + wb_enc->aspace[SDE_IOMMU_DOMAIN_SECURE] = + p->sde_kms->aspace[MSM_SMMU_DOMAIN_SECURE]; } hw_mdp = sde_rm_get_mdp(&p->sde_kms->rm); diff --git a/drivers/gpu/drm/msm/sde/sde_formats.c b/drivers/gpu/drm/msm/sde/sde_formats.c index 41180f5dec12..42bbbdcab2c9 100644 --- a/drivers/gpu/drm/msm/sde/sde_formats.c +++ b/drivers/gpu/drm/msm/sde/sde_formats.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * 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 @@ -630,7 +630,7 @@ static int _sde_format_get_plane_sizes( } static int _sde_format_populate_addrs_ubwc( - int mmu_id, + struct msm_gem_address_space *aspace, struct drm_framebuffer *fb, struct sde_hw_fmt_layout *layout) { @@ -641,7 +641,7 @@ static int _sde_format_populate_addrs_ubwc( return -EINVAL; } - base_addr = msm_framebuffer_iova(fb, mmu_id, 0); + base_addr = msm_framebuffer_iova(fb, aspace, 0); if (!base_addr) { DRM_ERROR("failed to retrieve base addr\n"); return -EFAULT; @@ -711,7 +711,7 @@ static int _sde_format_populate_addrs_ubwc( } static int _sde_format_populate_addrs_linear( - int mmu_id, + struct msm_gem_address_space *aspace, struct drm_framebuffer *fb, struct sde_hw_fmt_layout *layout) { @@ -728,7 +728,7 @@ static int _sde_format_populate_addrs_linear( /* Populate addresses for simple formats here */ for (i = 0; i < layout->num_planes; ++i) { - layout->plane_addr[i] = msm_framebuffer_iova(fb, mmu_id, i); + layout->plane_addr[i] = msm_framebuffer_iova(fb, aspace, i); if (!layout->plane_addr[i]) { DRM_ERROR("failed to retrieve base addr\n"); return -EFAULT; @@ -739,7 +739,7 @@ static int _sde_format_populate_addrs_linear( } int sde_format_populate_layout( - int mmu_id, + struct msm_gem_address_space *aspace, struct drm_framebuffer *fb, struct sde_hw_fmt_layout *layout) { @@ -770,9 +770,9 @@ int sde_format_populate_layout( /* Populate the addresses given the fb */ if (SDE_FORMAT_IS_UBWC(layout->format)) - ret = _sde_format_populate_addrs_ubwc(mmu_id, fb, layout); + ret = _sde_format_populate_addrs_ubwc(aspace, fb, layout); else - ret = _sde_format_populate_addrs_linear(mmu_id, fb, layout); + ret = _sde_format_populate_addrs_linear(aspace, fb, layout); /* check if anything changed */ if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr))) @@ -814,14 +814,14 @@ static void _sde_format_calc_offset_linear(struct sde_hw_fmt_layout *source, } int sde_format_populate_layout_with_roi( - int mmu_id, + struct msm_gem_address_space *aspace, struct drm_framebuffer *fb, struct sde_rect *roi, struct sde_hw_fmt_layout *layout) { int ret; - ret = sde_format_populate_layout(mmu_id, fb, layout); + ret = sde_format_populate_layout(aspace, fb, layout); if (ret || !roi) return ret; diff --git a/drivers/gpu/drm/msm/sde/sde_formats.h b/drivers/gpu/drm/msm/sde/sde_formats.h index 5dcdfbb653ed..0de081d619b7 100644 --- a/drivers/gpu/drm/msm/sde/sde_formats.h +++ b/drivers/gpu/drm/msm/sde/sde_formats.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * 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 @@ -14,6 +14,7 @@ #define _SDE_FORMATS_H #include <drm/drm_fourcc.h> +#include "msm_gem.h" #include "sde_hw_mdss.h" /** @@ -76,7 +77,7 @@ int sde_format_check_modified_format( /** * sde_format_populate_layout - populate the given format layout based on * mmu, fb, and format found in the fb - * @mmu_id: mmu id handle + * @aspace: address space pointer * @fb: framebuffer pointer * @fmtl: format layout structure to populate * @@ -84,14 +85,14 @@ int sde_format_check_modified_format( * are the same as before or 0 if new addresses were populated */ int sde_format_populate_layout( - int mmu_id, + struct msm_gem_address_space *aspace, struct drm_framebuffer *fb, struct sde_hw_fmt_layout *fmtl); /** * sde_format_populate_layout_with_roi - populate the given format layout * based on mmu, fb, roi, and format found in the fb - * @mmu_id: mmu id handle + * @aspace: mmu id handle * @fb: framebuffer pointer * @roi: region of interest (optional) * @fmtl: format layout structure to populate @@ -99,7 +100,7 @@ int sde_format_populate_layout( * Return: error code on failure, 0 on success */ int sde_format_populate_layout_with_roi( - int mmu_id, + struct msm_gem_address_space *aspace, struct drm_framebuffer *fb, struct sde_rect *roi, struct sde_hw_fmt_layout *fmtl); diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index e40e33f11fd9..e906b66dcd95 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -940,17 +940,17 @@ static int _sde_kms_mmu_destroy(struct sde_kms *sde_kms) struct msm_mmu *mmu; int i; - for (i = ARRAY_SIZE(sde_kms->mmu_id) - 1; i >= 0; i--) { - mmu = sde_kms->aspace[i]->mmu; - - if (!mmu) + for (i = ARRAY_SIZE(sde_kms->aspace) - 1; i >= 0; i--) { + if (!sde_kms->aspace[i]) continue; + mmu = sde_kms->aspace[i]->mmu; + mmu->funcs->detach(mmu, (const char **)iommu_ports, ARRAY_SIZE(iommu_ports)); msm_gem_address_space_destroy(sde_kms->aspace[i]); - sde_kms->mmu_id[i] = 0; + sde_kms->aspace[i] = NULL; } return 0; @@ -991,17 +991,6 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms) goto fail; } - sde_kms->mmu_id[i] = msm_register_address_space(sde_kms->dev, - aspace); - if (sde_kms->mmu_id[i] < 0) { - ret = sde_kms->mmu_id[i]; - SDE_ERROR("failed to register sde iommu %d: %d\n", - i, ret); - mmu->funcs->detach(mmu, (const char **)iommu_ports, - ARRAY_SIZE(iommu_ports)); - msm_gem_address_space_destroy(aspace); - goto fail; - } } return 0; diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index 8663c632699b..cd3722fa7df8 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -123,7 +123,6 @@ struct sde_kms { struct sde_mdss_cfg *catalog; struct msm_gem_address_space *aspace[MSM_SMMU_DOMAIN_MAX]; - int mmu_id[MSM_SMMU_DOMAIN_MAX]; struct sde_power_client *core_client; /* directory entry for debugfs */ diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index b3de45302dea..114acfd7a173 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -86,7 +86,7 @@ enum sde_plane_qos { struct sde_plane { struct drm_plane base; - int mmu_id; + struct msm_gem_address_space *aspace; struct mutex lock; @@ -580,7 +580,7 @@ static inline void _sde_plane_set_scanout(struct drm_plane *plane, return; } - ret = sde_format_populate_layout(psde->mmu_id, fb, &pipe_cfg->layout); + ret = sde_format_populate_layout(psde->aspace, fb, &pipe_cfg->layout); if (ret == -EAGAIN) SDE_DEBUG_PLANE(psde, "not updating same src addrs\n"); else if (ret) @@ -1285,7 +1285,7 @@ static int sde_plane_prepare_fb(struct drm_plane *plane, return 0; SDE_DEBUG_PLANE(psde, "FB[%u]\n", fb->base.id); - return msm_framebuffer_prepare(fb, psde->mmu_id); + return msm_framebuffer_prepare(fb, psde->aspace); } static void sde_plane_cleanup_fb(struct drm_plane *plane, @@ -1294,11 +1294,11 @@ static void sde_plane_cleanup_fb(struct drm_plane *plane, struct drm_framebuffer *fb = old_state ? old_state->fb : NULL; struct sde_plane *psde = plane ? to_sde_plane(plane) : NULL; - if (!fb) + if (!fb || !psde) return; SDE_DEBUG_PLANE(psde, "FB[%u]\n", fb->base.id); - msm_framebuffer_cleanup(fb, psde->mmu_id); + msm_framebuffer_cleanup(fb, psde->aspace); } static void _sde_plane_atomic_check_mode_changed(struct sde_plane *psde, @@ -2384,7 +2384,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, /* cache local stuff for later */ plane = &psde->base; psde->pipe = pipe; - psde->mmu_id = kms->mmu_id[MSM_SMMU_DOMAIN_UNSECURE]; + psde->aspace = kms->aspace[MSM_SMMU_DOMAIN_UNSECURE]; /* initialize underlying h/w driver */ psde->pipe_hw = sde_hw_sspp_init(pipe, kms->mmio, kms->catalog); |
