diff options
author | Dave Airlie <airlied@redhat.com> | 2017-08-25 09:29:45 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-08-25 09:29:45 +1000 |
commit | cfcfb65ad15a1b43cf5cd434c57966fae03db96b (patch) | |
tree | 258c989daae3f81843f6c15468b8ba4d4abecffb /drivers/gpu/drm/msm/msm_gpu.c | |
parent | 7c0059dd832cc686bf0febefdcf8295cdd93007f (diff) | |
parent | d1f08d82176246c6d8a2f1dc26be3638ed4a6083 (diff) |
Merge tag 'drm-msm-next-2017-08-22' of git://people.freedesktop.org/~robclark/linux into drm-next
Updates for 4.14.. I have some further patches from Jordan to add
multiple priority levels and pre-emption, but those will probably be
for 4.15 to give me time for the mesa parts.
* tag 'drm-msm-next-2017-08-22' of git://people.freedesktop.org/~robclark/linux:
drm/msm/mdp5: mark runtime_pm functions as __maybe_unused
drm/msm: remove unused variable
drm/msm/mdp5: make helper function static
drm/msm: make msm_framebuffer_init() static
drm/msm: add helper to allocate stolen fb
drm/msm: don't track fbdev's gem object separately
drm/msm: add modeset module param
drm/msm/mdp5: add tracking for clk enable-count
drm/msm: remove unused define
drm/msm: Add a helper function for in-kernel buffer allocations
drm/msm: Attach the GPU MMU when it is created
drm/msm: Add A5XX hardware fault detection
drm/msm: Remove uneeded platform dev members
drm/msm/mdp5: Set up runtime PM for MDSS
drm/msm/mdp5: Write to SMP registers even if allocations don't change
drm/msm/mdp5: Don't use mode_set helper funcs for encoders and CRTCs
drm/msm/dsi: Implement RPM suspend/resume callbacks
drm/msm/dsi: Set up runtime PM for DSI
drm/msm/hdmi: Set up runtime PM for HDMI
drm/msm/mdp5: Use runtime PM get/put API instead of toggling clocks
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gpu.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.c | 85 |
1 files changed, 56 insertions, 29 deletions
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 9f3dbc236ab3..ffbff27600e0 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -562,11 +562,49 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu) return 0; } +static struct msm_gem_address_space * +msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev, + uint64_t va_start, uint64_t va_end) +{ + struct iommu_domain *iommu; + struct msm_gem_address_space *aspace; + int ret; + + /* + * Setup IOMMU.. eventually we will (I think) do this once per context + * and have separate page tables per context. For now, to keep things + * simple and to get something working, just use a single address space: + */ + iommu = iommu_domain_alloc(&platform_bus_type); + if (!iommu) + return NULL; + + iommu->geometry.aperture_start = va_start; + iommu->geometry.aperture_end = va_end; + + dev_info(gpu->dev->dev, "%s: using IOMMU\n", gpu->name); + + aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu"); + if (IS_ERR(aspace)) { + dev_err(gpu->dev->dev, "failed to init iommu: %ld\n", + PTR_ERR(aspace)); + iommu_domain_free(iommu); + return ERR_CAST(aspace); + } + + ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0); + if (ret) { + msm_gem_address_space_put(aspace); + return ERR_PTR(ret); + } + + return aspace; +} + int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, const char *name, struct msm_gpu_config *config) { - struct iommu_domain *iommu; int ret; if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs))) @@ -636,28 +674,19 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, if (IS_ERR(gpu->gpu_cx)) gpu->gpu_cx = NULL; - /* Setup IOMMU.. eventually we will (I think) do this once per context - * and have separate page tables per context. For now, to keep things - * simple and to get something working, just use a single address space: - */ - iommu = iommu_domain_alloc(&platform_bus_type); - if (iommu) { - iommu->geometry.aperture_start = config->va_start; - iommu->geometry.aperture_end = config->va_end; - - dev_info(drm->dev, "%s: using IOMMU\n", name); - gpu->aspace = msm_gem_address_space_create(&pdev->dev, - iommu, "gpu"); - if (IS_ERR(gpu->aspace)) { - ret = PTR_ERR(gpu->aspace); - dev_err(drm->dev, "failed to init iommu: %d\n", ret); - gpu->aspace = NULL; - iommu_domain_free(iommu); - goto fail; - } + gpu->pdev = pdev; + platform_set_drvdata(pdev, gpu); + + bs_init(gpu); - } else { + gpu->aspace = msm_gpu_create_address_space(gpu, pdev, + config->va_start, config->va_end); + + if (gpu->aspace == NULL) dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name); + else if (IS_ERR(gpu->aspace)) { + ret = PTR_ERR(gpu->aspace); + goto fail; } /* Create ringbuffer: */ @@ -669,14 +698,10 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } - gpu->pdev = pdev; - platform_set_drvdata(pdev, gpu); - - bs_init(gpu); - return 0; fail: + platform_set_drvdata(pdev, NULL); return ret; } @@ -693,7 +718,9 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) msm_gem_put_iova(gpu->rb->bo, gpu->aspace); msm_ringbuffer_destroy(gpu->rb); } - - if (gpu->fctx) - msm_fence_context_free(gpu->fctx); + if (gpu->aspace) { + gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu, + NULL, 0); + msm_gem_address_space_put(gpu->aspace); + } } |