diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/gpu/drm/msm/msm_drv.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/gpu/drm/msm/msm_drv.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 111 | 
1 files changed, 63 insertions, 48 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index aca48c868c14..463ca4164f5f 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -8,10 +8,12 @@  #include <linux/dma-mapping.h>  #include <linux/fault-inject.h>  #include <linux/kthread.h> +#include <linux/of_address.h>  #include <linux/sched/mm.h>  #include <linux/uaccess.h>  #include <uapi/linux/sched/types.h> +#include <drm/drm_aperture.h>  #include <drm/drm_bridge.h>  #include <drm/drm_drv.h>  #include <drm/drm_file.h> @@ -46,15 +48,17 @@   * - 1.8.0 - Add MSM_BO_CACHED_COHERENT for supported GPUs (a6xx)   * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN   * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT + * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST)   */  #define MSM_VERSION_MAJOR	1  #define MSM_VERSION_MINOR	10  #define MSM_VERSION_PATCHLEVEL	0 +static void msm_deinit_vram(struct drm_device *ddev); +  static const struct drm_mode_config_funcs mode_config_funcs = {  	.fb_create = msm_framebuffer_create, -	.output_poll_changed = drm_fb_helper_output_poll_changed, -	.atomic_check = drm_atomic_helper_check, +	.atomic_check = msm_atomic_check,  	.atomic_commit = drm_atomic_helper_commit,  }; @@ -62,12 +66,6 @@ static const struct drm_mode_config_helper_funcs mode_config_helper_funcs = {  	.atomic_commit_tail = msm_atomic_commit_tail,  }; -#ifdef CONFIG_DRM_FBDEV_EMULATION -static bool fbdev = true; -MODULE_PARM_DESC(fbdev, "Enable fbdev compat layer"); -module_param(fbdev, bool, 0600); -#endif -  static char *vram = "16m";  MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU)");  module_param(vram, charp, 0); @@ -150,9 +148,6 @@ static void msm_irq_uninstall(struct drm_device *dev)  	struct msm_drm_private *priv = dev->dev_private;  	struct msm_kms *kms = priv->kms; -	if (!priv->kms) -		return; -  	kms->funcs->irq_uninstall(kms);  	if (kms->irq_requested)  		free_irq(kms->irq, dev); @@ -240,12 +235,8 @@ static int msm_drm_uninit(struct device *dev)  	msm_perf_debugfs_cleanup(priv);  	msm_rd_debugfs_cleanup(priv); -#ifdef CONFIG_DRM_FBDEV_EMULATION -	if (fbdev && priv->fbdev) -		msm_fbdev_free(ddev); -#endif - -	msm_disp_snapshot_destroy(ddev); +	if (kms) +		msm_disp_snapshot_destroy(ddev);  	drm_mode_config_cleanup(ddev); @@ -253,30 +244,27 @@ static int msm_drm_uninit(struct device *dev)  		drm_bridge_remove(priv->bridges[i]);  	priv->num_bridges = 0; -	pm_runtime_get_sync(dev); -	msm_irq_uninstall(ddev); -	pm_runtime_put_sync(dev); +	if (kms) { +		pm_runtime_get_sync(dev); +		msm_irq_uninstall(ddev); +		pm_runtime_put_sync(dev); +	}  	if (kms && kms->funcs)  		kms->funcs->destroy(kms); -	if (priv->vram.paddr) { -		unsigned long attrs = DMA_ATTR_NO_KERNEL_MAPPING; -		drm_mm_takedown(&priv->vram.mm); -		dma_free_attrs(dev, priv->vram.size, NULL, -			       priv->vram.paddr, attrs); -	} +	msm_deinit_vram(ddev);  	component_unbind_all(dev, ddev);  	ddev->dev_private = NULL; +	drm_dev_put(ddev); +  	destroy_workqueue(priv->wq);  	return 0;  } -#include <linux/of_address.h> -  struct msm_gem_address_space *msm_kms_init_aspace(struct drm_device *dev)  {  	struct msm_gem_address_space *aspace; @@ -401,6 +389,19 @@ static int msm_init_vram(struct drm_device *dev)  	return ret;  } +static void msm_deinit_vram(struct drm_device *ddev) +{ +	struct msm_drm_private *priv = ddev->dev_private; +	unsigned long attrs = DMA_ATTR_NO_KERNEL_MAPPING; + +	if (!priv->vram.paddr) +		return; + +	drm_mm_takedown(&priv->vram.mm); +	dma_free_attrs(ddev->dev, priv->vram.size, NULL, priv->vram.paddr, +			attrs); +} +  static int msm_drm_init(struct device *dev, const struct drm_driver *drv)  {  	struct msm_drm_private *priv = dev_get_drvdata(dev); @@ -420,8 +421,10 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)  	priv->dev = ddev;  	priv->wq = alloc_ordered_workqueue("msm", 0); -	if (!priv->wq) -		return -ENOMEM; +	if (!priv->wq) { +		ret = -ENOMEM; +		goto err_put_dev; +	}  	INIT_LIST_HEAD(&priv->objects);  	mutex_init(&priv->obj_lock); @@ -444,14 +447,19 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)  	ret = msm_init_vram(ddev);  	if (ret) -		goto err_drm_dev_put; +		goto err_cleanup_mode_config; + +	dma_set_max_seg_size(dev, UINT_MAX);  	/* Bind all our sub-components: */  	ret = component_bind_all(dev, ddev);  	if (ret) -		goto err_drm_dev_put; +		goto err_deinit_vram; -	dma_set_max_seg_size(dev, UINT_MAX); +	/* the fw fb could be anywhere in memory */ +	ret = drm_aperture_remove_framebuffers(false, drv); +	if (ret) +		goto err_msm_uninit;  	msm_gem_shrinker_init(ddev); @@ -529,23 +537,30 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)  	}  	drm_mode_config_reset(ddev); -#ifdef CONFIG_DRM_FBDEV_EMULATION -	if (kms && fbdev) -		priv->fbdev = msm_fbdev_init(ddev); -#endif -  	ret = msm_debugfs_late_init(ddev);  	if (ret)  		goto err_msm_uninit;  	drm_kms_helper_poll_init(ddev); +	if (kms) +		msm_fbdev_setup(ddev); +  	return 0;  err_msm_uninit:  	msm_drm_uninit(dev); -err_drm_dev_put: + +	return ret; + +err_deinit_vram: +	msm_deinit_vram(ddev); +err_cleanup_mode_config: +	drm_mode_config_cleanup(ddev); +	destroy_workqueue(priv->wq); +err_put_dev:  	drm_dev_put(ddev); +  	return ret;  } @@ -899,7 +914,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,  }  static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, -		      ktime_t timeout) +		      ktime_t timeout, uint32_t flags)  {  	struct dma_fence *fence;  	int ret; @@ -918,17 +933,18 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,  	 * retired, so if the fence is not found it means there is nothing  	 * to wait for  	 */ -	ret = mutex_lock_interruptible(&queue->idr_lock); -	if (ret) -		return ret; +	spin_lock(&queue->idr_lock);  	fence = idr_find(&queue->fence_idr, fence_id);  	if (fence)  		fence = dma_fence_get_rcu(fence); -	mutex_unlock(&queue->idr_lock); +	spin_unlock(&queue->idr_lock);  	if (!fence)  		return 0; +	if (flags & MSM_WAIT_FENCE_BOOST) +		dma_fence_set_deadline(fence, ktime_get()); +  	ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout));  	if (ret == 0) {  		ret = -ETIMEDOUT; @@ -949,8 +965,8 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,  	struct msm_gpu_submitqueue *queue;  	int ret; -	if (args->pad) { -		DRM_ERROR("invalid pad: %08x\n", args->pad); +	if (args->flags & ~MSM_WAIT_FENCE_FLAGS) { +		DRM_ERROR("invalid flags: %08x\n", args->flags);  		return -EINVAL;  	} @@ -961,7 +977,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,  	if (!queue)  		return -ENOENT; -	ret = wait_fence(queue, args->fence, to_ktime(args->timeout)); +	ret = wait_fence(queue, args->fence, to_ktime(args->timeout), args->flags);  	msm_submitqueue_put(queue); @@ -1068,7 +1084,6 @@ static const struct drm_driver msm_driver = {  				DRIVER_SYNCOBJ,  	.open               = msm_open,  	.postclose           = msm_postclose, -	.lastclose          = drm_fb_helper_lastclose,  	.dumb_create        = msm_gem_dumb_create,  	.dumb_map_offset    = msm_gem_dumb_map_offset,  	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,  |