diff options
Diffstat (limited to 'drivers/gpu/drm/msm')
| -rw-r--r-- | drivers/gpu/drm/msm/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/Makefile | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 20 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dp/dp_aux.c | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_host.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_debugfs.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 49 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gpu_devfreq.c | 13 | 
12 files changed, 84 insertions, 40 deletions
| diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index ae11061727ff..39197b4beea7 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -4,8 +4,8 @@ config DRM_MSM  	tristate "MSM DRM"  	depends on DRM  	depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST +	depends on COMMON_CLK  	depends on IOMMU_SUPPORT -	depends on (OF && COMMON_CLK) || COMPILE_TEST  	depends on QCOM_OCMEM || QCOM_OCMEM=n  	depends on QCOM_LLCC || QCOM_LLCC=n  	depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 40577f8856d8..093454457545 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -23,8 +23,10 @@ msm-y := \  	hdmi/hdmi_i2c.o \  	hdmi/hdmi_phy.o \  	hdmi/hdmi_phy_8960.o \ +	hdmi/hdmi_phy_8996.o \  	hdmi/hdmi_phy_8x60.o \  	hdmi/hdmi_phy_8x74.o \ +	hdmi/hdmi_pll_8960.o \  	edp/edp.o \  	edp/edp_aux.o \  	edp/edp_bridge.o \ @@ -37,6 +39,7 @@ msm-y := \  	disp/mdp4/mdp4_dtv_encoder.o \  	disp/mdp4/mdp4_lcdc_encoder.o \  	disp/mdp4/mdp4_lvds_connector.o \ +	disp/mdp4/mdp4_lvds_pll.o \  	disp/mdp4/mdp4_irq.o \  	disp/mdp4/mdp4_kms.o \  	disp/mdp4/mdp4_plane.o \ @@ -116,9 +119,6 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \  	dp/dp_audio.o  msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o -msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o -msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o -msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_phy_8996.o  msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 267a880811d6..78aad5216a61 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1424,17 +1424,24 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)  {  	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;  	struct msm_gpu *gpu = &adreno_gpu->base; -	u32 gpu_scid, cntl1_regval = 0; +	u32 cntl1_regval = 0;  	if (IS_ERR(a6xx_gpu->llc_mmio))  		return;  	if (!llcc_slice_activate(a6xx_gpu->llc_slice)) { -		gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice); +		u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice);  		gpu_scid &= 0x1f;  		cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) |  			       (gpu_scid << 15) | (gpu_scid << 20); + +		/* On A660, the SCID programming for UCHE traffic is done in +		 * A6XX_GBIF_SCACHE_CNTL0[14:10] +		 */ +		if (adreno_is_a660_family(adreno_gpu)) +			gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | +				(1 << 8), (gpu_scid << 10) | (1 << 8));  	}  	/* @@ -1471,13 +1478,6 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)  	}  	gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval); - -	/* On A660, the SCID programming for UCHE traffic is done in -	 * A6XX_GBIF_SCACHE_CNTL0[14:10] -	 */ -	if (adreno_is_a660_family(adreno_gpu)) -		gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) | -			(1 << 8), (gpu_scid << 10) | (1 << 8));  }  static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu) @@ -1640,7 +1640,7 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)  	return (unsigned long)busy_time;  } -void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) +static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)  {  	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);  	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 7501849ed15d..6e90209cd543 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -777,12 +777,12 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu,  	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);  	a6xx_state->gmu_registers = state_kcalloc(a6xx_state, -		2, sizeof(*a6xx_state->gmu_registers)); +		3, sizeof(*a6xx_state->gmu_registers));  	if (!a6xx_state->gmu_registers)  		return; -	a6xx_state->nr_gmu_registers = 2; +	a6xx_state->nr_gmu_registers = 3;  	/* Get the CX GMU registers from AHB */  	_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0], diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c index eb40d8413bca..6d36f63c3338 100644 --- a/drivers/gpu/drm/msm/dp/dp_aux.c +++ b/drivers/gpu/drm/msm/dp/dp_aux.c @@ -33,6 +33,7 @@ struct dp_aux_private {  	bool read;  	bool no_send_addr;  	bool no_send_stop; +	bool initted;  	u32 offset;  	u32 segment; @@ -331,6 +332,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,  	}  	mutex_lock(&aux->mutex); +	if (!aux->initted) { +		ret = -EIO; +		goto exit; +	}  	dp_aux_update_offset_and_segment(aux, msg);  	dp_aux_transfer_helper(aux, msg, true); @@ -380,6 +385,8 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,  	}  	aux->cmd_busy = false; + +exit:  	mutex_unlock(&aux->mutex);  	return ret; @@ -431,8 +438,13 @@ void dp_aux_init(struct drm_dp_aux *dp_aux)  	aux = container_of(dp_aux, struct dp_aux_private, dp_aux); +	mutex_lock(&aux->mutex); +  	dp_catalog_aux_enable(aux->catalog, true);  	aux->retry_cnt = 0; +	aux->initted = true; + +	mutex_unlock(&aux->mutex);  }  void dp_aux_deinit(struct drm_dp_aux *dp_aux) @@ -441,7 +453,12 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux)  	aux = container_of(dp_aux, struct dp_aux_private, dp_aux); +	mutex_lock(&aux->mutex); + +	aux->initted = false;  	dp_catalog_aux_enable(aux->catalog, false); + +	mutex_unlock(&aux->mutex);  }  int dp_aux_register(struct drm_dp_aux *dp_aux) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index f69a125f9559..0afc3b756f92 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1658,6 +1658,8 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host,  	if (!prop) {  		DRM_DEV_DEBUG(dev,  			"failed to find data lane mapping, using default\n"); +		/* Set the number of date lanes to 4 by default. */ +		msm_host->num_data_lanes = 4;  		return 0;  	} diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 09d2d279c30a..dee13fedee3b 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -77,6 +77,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)  		goto free_priv;  	pm_runtime_get_sync(&gpu->pdev->dev); +	msm_gpu_hw_init(gpu);  	show_priv->state = gpu->funcs->gpu_state_get(gpu);  	pm_runtime_put_sync(&gpu->pdev->dev); diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 7936e8d498dd..892c04365239 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -967,29 +967,18 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,  	return ret;  } -static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, -		struct drm_file *file) +static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, +		      ktime_t timeout)  { -	struct msm_drm_private *priv = dev->dev_private; -	struct drm_msm_wait_fence *args = data; -	ktime_t timeout = to_ktime(args->timeout); -	struct msm_gpu_submitqueue *queue; -	struct msm_gpu *gpu = priv->gpu;  	struct dma_fence *fence;  	int ret; -	if (args->pad) { -		DRM_ERROR("invalid pad: %08x\n", args->pad); +	if (fence_id > queue->last_fence) { +		DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n", +				      fence_id, queue->last_fence);  		return -EINVAL;  	} -	if (!gpu) -		return 0; - -	queue = msm_submitqueue_get(file->driver_priv, args->queueid); -	if (!queue) -		return -ENOENT; -  	/*  	 * Map submitqueue scoped "seqno" (which is actually an idr key)  	 * back to underlying dma-fence @@ -1001,7 +990,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,  	ret = mutex_lock_interruptible(&queue->lock);  	if (ret)  		return ret; -	fence = idr_find(&queue->fence_idr, args->fence); +	fence = idr_find(&queue->fence_idr, fence_id);  	if (fence)  		fence = dma_fence_get_rcu(fence);  	mutex_unlock(&queue->lock); @@ -1017,6 +1006,32 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,  	}  	dma_fence_put(fence); + +	return ret; +} + +static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, +		struct drm_file *file) +{ +	struct msm_drm_private *priv = dev->dev_private; +	struct drm_msm_wait_fence *args = data; +	struct msm_gpu_submitqueue *queue; +	int ret; + +	if (args->pad) { +		DRM_ERROR("invalid pad: %08x\n", args->pad); +		return -EINVAL; +	} + +	if (!priv->gpu) +		return 0; + +	queue = msm_submitqueue_get(file->driver_priv, args->queueid); +	if (!queue) +		return -ENOENT; + +	ret = wait_fence(queue, args->fence, to_ktime(args->timeout)); +  	msm_submitqueue_put(queue);  	return ret; diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 104fdfc14027..512d55eecbaf 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1056,8 +1056,7 @@ static int msm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct  {  	struct msm_gem_object *msm_obj = to_msm_bo(obj); -	vma->vm_flags &= ~VM_PFNMAP; -	vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; +	vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;  	vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags));  	return 0; @@ -1121,7 +1120,7 @@ static int msm_gem_new_impl(struct drm_device *dev,  			break;  		fallthrough;  	default: -		DRM_DEV_ERROR(dev->dev, "invalid cache flag: %x\n", +		DRM_DEV_DEBUG(dev->dev, "invalid cache flag: %x\n",  				(flags & MSM_BO_CACHE_MASK));  		return -EINVAL;  	} diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 3cb029f10925..282628d6b72c 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -772,6 +772,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  		args->nr_cmds);  	if (IS_ERR(submit)) {  		ret = PTR_ERR(submit); +		submit = NULL;  		goto out_unlock;  	} @@ -904,6 +905,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  	drm_sched_entity_push_job(&submit->base);  	args->fence = submit->fence_id; +	queue->last_fence = submit->fence_id;  	msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);  	msm_process_post_deps(post_deps, args->nr_out_syncobjs, diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 59cdd00b69d0..48ea2de911f1 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -359,6 +359,8 @@ static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio,   * @ring_nr:   the ringbuffer used by this submitqueue, which is determined   *             by the submitqueue's priority   * @faults:    the number of GPU hangs associated with this submitqueue + * @last_fence: the sequence number of the last allocated fence (for error + *             checking)   * @ctx:       the per-drm_file context associated with the submitqueue (ie.   *             which set of pgtables do submits jobs associated with the   *             submitqueue use) @@ -374,6 +376,7 @@ struct msm_gpu_submitqueue {  	u32 flags;  	u32 ring_nr;  	int faults; +	uint32_t last_fence;  	struct msm_file_private *ctx;  	struct list_head node;  	struct idr fence_idr; diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 8b7473f69cb8..384e90c4b2a7 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -20,6 +20,10 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,  	struct msm_gpu *gpu = dev_to_gpu(dev);  	struct dev_pm_opp *opp; +	/* +	 * Note that devfreq_recommended_opp() can modify the freq +	 * to something that actually is in the opp table: +	 */  	opp = devfreq_recommended_opp(dev, freq, flags);  	/* @@ -28,6 +32,7 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,  	 */  	if (gpu->devfreq.idle_freq) {  		gpu->devfreq.idle_freq = *freq; +		dev_pm_opp_put(opp);  		return 0;  	} @@ -203,9 +208,6 @@ static void msm_devfreq_idle_work(struct kthread_work *work)  	struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq);  	unsigned long idle_freq, target_freq = 0; -	if (!df->devfreq) -		return; -  	/*  	 * Hold devfreq lock to synchronize with get_dev_status()/  	 * target() callbacks @@ -227,6 +229,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu)  {  	struct msm_gpu_devfreq *df = &gpu->devfreq; +	if (!df->devfreq) +		return; +  	msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), -			       HRTIMER_MODE_ABS); +			       HRTIMER_MODE_REL);  } | 
