diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_gem.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_plane.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/gvt/cmd_parser.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_render_state.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dsi_vbt.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lspcon.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/imx/ipuv3-plane.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_drv.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/ipu-v3/Kconfig | 1 | 
20 files changed, 96 insertions, 41 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index a6899180b265..c586f44312f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -244,6 +244,12 @@ struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,  		struct dma_fence *f = e->fence;  		struct amd_sched_fence *s_fence = to_amd_sched_fence(f); +		if (dma_fence_is_signaled(f)) { +			hash_del(&e->node); +			dma_fence_put(f); +			kmem_cache_free(amdgpu_sync_slab, e); +			continue; +		}  		if (ring && s_fence) {  			/* For fences from the same ring it is sufficient  			 * when they are scheduled. @@ -256,13 +262,6 @@ struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,  			}  		} -		if (dma_fence_is_signaled(f)) { -			hash_del(&e->node); -			dma_fence_put(f); -			kmem_cache_free(amdgpu_sync_slab, e); -			continue; -		} -  		return f;  	} diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index c0f336d23f9c..aed25c4183bb 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1655,6 +1655,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)  	if (config->funcs->atomic_check)  		ret = config->funcs->atomic_check(state->dev, state); +	if (ret) +		return ret; +  	if (!state->allow_modeset) {  		for_each_new_crtc_in_state(state, crtc, crtc_state, i) {  			if (drm_atomic_crtc_needs_modeset(crtc_state)) { @@ -1665,7 +1668,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state)  		}  	} -	return ret; +	return 0;  }  EXPORT_SYMBOL(drm_atomic_check_only); @@ -2167,10 +2170,10 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,  	struct drm_atomic_state *state;  	struct drm_modeset_acquire_ctx ctx;  	struct drm_plane *plane; -	struct drm_out_fence_state *fence_state = NULL; +	struct drm_out_fence_state *fence_state;  	unsigned plane_mask;  	int ret = 0; -	unsigned int i, j, num_fences = 0; +	unsigned int i, j, num_fences;  	/* disallow for drivers not supporting atomic: */  	if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) @@ -2211,6 +2214,8 @@ retry:  	plane_mask = 0;  	copied_objs = 0;  	copied_props = 0; +	fence_state = NULL; +	num_fences = 0;  	for (i = 0; i < arg->count_objs; i++) {  		uint32_t obj_id, count_props; diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 8dc11064253d..cdaac37907b1 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -255,13 +255,13 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)  	struct drm_gem_object *obj = ptr;  	struct drm_device *dev = obj->dev; +	if (dev->driver->gem_close_object) +		dev->driver->gem_close_object(obj, file_priv); +  	if (drm_core_check_feature(dev, DRIVER_PRIME))  		drm_gem_remove_prime_handles(obj, file_priv);  	drm_vma_node_revoke(&obj->vma_node, file_priv); -	if (dev->driver->gem_close_object) -		dev->driver->gem_close_object(obj, file_priv); -  	drm_gem_object_handle_put_unlocked(obj);  	return 0; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 5dc8c4350602..e40c12fabbde 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -601,6 +601,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,  		crtc = drm_crtc_find(dev, plane_req->crtc_id);  		if (!crtc) { +			drm_framebuffer_put(fb);  			DRM_DEBUG_KMS("Unknown crtc ID %d\n",  				      plane_req->crtc_id);  			return -ENOENT; diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 713848c36349..e556a46cd4c2 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -2714,7 +2714,7 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)  unmap_src:  	i915_gem_object_unpin_map(obj);  put_obj: -	i915_gem_object_put(wa_ctx->indirect_ctx.obj); +	i915_gem_object_put(obj);  	return ret;  } diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 00d8967c8512..d1bd53b73738 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4580,7 +4580,7 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,  		sseu->slice_mask |= BIT(s); -		if (IS_GEN9_BC(dev_priv)) +		if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))  			sseu->subslice_mask =  				INTEL_INFO(dev_priv)->sseu.subslice_mask; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 39ed58a21fc1..e1e971ee2ed5 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -688,19 +688,19 @@ static inline bool skip_rcs_switch(struct i915_hw_ppgtt *ppgtt,  }  static bool -needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, -		  struct intel_engine_cs *engine, -		  struct i915_gem_context *to) +needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *engine)  { +	struct i915_gem_context *from = engine->legacy_active_context; +  	if (!ppgtt)  		return false;  	/* Always load the ppgtt on first use */ -	if (!engine->legacy_active_context) +	if (!from)  		return true;  	/* Same context without new entries, skip */ -	if (engine->legacy_active_context == to && +	if ((!from->ppgtt || from->ppgtt == ppgtt) &&  	    !(intel_engine_flag(engine) & ppgtt->pd_dirty_rings))  		return false; @@ -744,7 +744,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)  	if (skip_rcs_switch(ppgtt, engine, to))  		return 0; -	if (needs_pd_load_pre(ppgtt, engine, to)) { +	if (needs_pd_load_pre(ppgtt, engine)) {  		/* Older GENs and non render rings still want the load first,  		 * "PP_DCLV followed by PP_DIR_BASE register through Load  		 * Register Immediate commands in Ring Buffer before submitting @@ -841,7 +841,7 @@ int i915_switch_context(struct drm_i915_gem_request *req)  		struct i915_hw_ppgtt *ppgtt =  			to->ppgtt ?: req->i915->mm.aliasing_ppgtt; -		if (needs_pd_load_pre(ppgtt, engine, to)) { +		if (needs_pd_load_pre(ppgtt, engine)) {  			int ret;  			trace_switch_mm(engine, to); @@ -852,6 +852,7 @@ int i915_switch_context(struct drm_i915_gem_request *req)  			ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);  		} +		engine->legacy_active_context = to;  		return 0;  	} diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index 7032c542a9b1..4dd4c2159a92 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -242,6 +242,10 @@ int i915_gem_render_state_emit(struct drm_i915_gem_request *req)  			goto err_unpin;  	} +	ret = req->engine->emit_flush(req, EMIT_INVALIDATE); +	if (ret) +		goto err_unpin; +  	ret = req->engine->emit_bb_start(req,  					 so->batch_offset, so->batch_size,  					 I915_DISPATCH_SECURE); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 639d45c1dd2e..7ea7fd1e8856 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1120,8 +1120,8 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,  	bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;  	uint8_t aux_channel, ddc_pin;  	/* Each DDI port can have more than one value on the "DVO Port" field, -	 * so look for all the possible values for each port and abort if more -	 * than one is found. */ +	 * so look for all the possible values for each port. +	 */  	int dvo_ports[][3] = {  		{DVO_PORT_HDMIA, DVO_PORT_DPA, -1},  		{DVO_PORT_HDMIB, DVO_PORT_DPB, -1}, @@ -1130,7 +1130,10 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,  		{DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE},  	}; -	/* Find the child device to use, abort if more than one found. */ +	/* +	 * Find the first child device to reference the port, report if more +	 * than one found. +	 */  	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {  		it = dev_priv->vbt.child_dev + i; @@ -1140,11 +1143,11 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,  			if (it->common.dvo_port == dvo_ports[port][j]) {  				if (child) { -					DRM_DEBUG_KMS("More than one child device for port %c in VBT.\n", +					DRM_DEBUG_KMS("More than one child device for port %c in VBT, using the first.\n",  						      port_name(port)); -					return; +				} else { +					child = it;  				} -				child = it;  			}  		}  	} diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9edeaaef77ad..d3b3252a8742 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1762,7 +1762,7 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv,  	if (dev_priv->vbt.edp.low_vswing) {  		if (voltage == VOLTAGE_INFO_0_85V) {  			*n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_85V); -			return cnl_ddi_translations_dp_0_85V; +			return cnl_ddi_translations_edp_0_85V;  		} else if (voltage == VOLTAGE_INFO_0_95V) {  			*n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_95V);  			return cnl_ddi_translations_edp_0_95V; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9471c88d449e..cc484b56eeaa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3485,6 +3485,13 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)  	    !gpu_reset_clobbers_display(dev_priv))  		return; +	/* We have a modeset vs reset deadlock, defensively unbreak it. +	 * +	 * FIXME: We can do a _lot_ better, this is just a first iteration. +	 */ +	i915_gem_set_wedged(dev_priv); +	DRM_DEBUG_DRIVER("Wedging GPU to avoid deadlocks with pending modeset updates\n"); +  	/*  	 * Need mode_config.mutex so that we don't  	 * trample ongoing ->detect() and whatnot. diff --git a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c index 6e09ceb71500..150a156f3b1e 100644 --- a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c @@ -46,7 +46,7 @@ static u32 dcs_get_backlight(struct intel_connector *connector)  	struct intel_encoder *encoder = connector->encoder;  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);  	struct mipi_dsi_device *dsi_device; -	u8 data; +	u8 data = 0;  	enum port port;  	/* FIXME: Need to take care of 16 bit brightness level */ diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c index 7158c7ce9c09..91c07b0c8db9 100644 --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c @@ -306,7 +306,7 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv,  	if (!gpio_desc) {  		gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev, -						 "panel", gpio_index, +						 NULL, gpio_index,  						 value ? GPIOD_OUT_LOW :  						 GPIOD_OUT_HIGH); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7404cf2aac28..2afa4daa88e8 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1221,6 +1221,14 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)  	return ret;  } +static u8 gtiir[] = { +	[RCS] = 0, +	[BCS] = 0, +	[VCS] = 1, +	[VCS2] = 1, +	[VECS] = 3, +}; +  static int gen8_init_common_ring(struct intel_engine_cs *engine)  {  	struct drm_i915_private *dev_priv = engine->i915; @@ -1245,9 +1253,22 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)  	DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name); -	/* After a GPU reset, we may have requests to replay */ +	GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir)); + +	/* +	 * Clear any pending interrupt state. +	 * +	 * We do it twice out of paranoia that some of the IIR are double +	 * buffered, and if we only reset it once there may still be +	 * an interrupt pending. +	 */ +	I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]), +		   GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift); +	I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]), +		   GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);  	clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); +	/* After a GPU reset, we may have requests to replay */  	submit = false;  	for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) {  		if (!port_isset(&port[n])) diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 52b3a1fd4059..57ef5833c427 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -63,7 +63,6 @@ enum {  };  /* Logical Rings */ -void intel_logical_ring_stop(struct intel_engine_cs *engine);  void intel_logical_ring_cleanup(struct intel_engine_cs *engine);  int logical_render_ring_init(struct intel_engine_cs *engine);  int logical_xcs_ring_init(struct intel_engine_cs *engine); diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 5abef482eacf..beb9baaf2f2e 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -210,8 +210,8 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port)  	struct drm_device *dev = intel_dig_port->base.base.dev;  	struct drm_i915_private *dev_priv = to_i915(dev); -	if (!IS_GEN9(dev_priv)) { -		DRM_ERROR("LSPCON is supported on GEN9 only\n"); +	if (!HAS_LSPCON(dev_priv)) { +		DRM_ERROR("LSPCON is not supported on this platform\n");  		return false;  	} diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 6276bb834b4f..d3845989a29d 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -545,15 +545,13 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,  		return;  	} +	ics = ipu_drm_fourcc_to_colorspace(fb->format->format);  	switch (ipu_plane->dp_flow) {  	case IPU_DP_FLOW_SYNC_BG: -		ipu_dp_setup_channel(ipu_plane->dp, -					IPUV3_COLORSPACE_RGB, -					IPUV3_COLORSPACE_RGB); +		ipu_dp_setup_channel(ipu_plane->dp, ics, IPUV3_COLORSPACE_RGB);  		ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);  		break;  	case IPU_DP_FLOW_SYNC_FG: -		ics = ipu_drm_fourcc_to_colorspace(state->fb->format->format);  		ipu_dp_setup_channel(ipu_plane->dp, ics,  					IPUV3_COLORSPACE_UNKNOWN);  		/* Enable local alpha on partial plane */ diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index c6b1b7f3a2a3..c16bc0a7115b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -275,11 +275,15 @@ static void rockchip_drm_fb_resume(struct drm_device *drm)  static int rockchip_drm_sys_suspend(struct device *dev)  {  	struct drm_device *drm = dev_get_drvdata(dev); -	struct rockchip_drm_private *priv = drm->dev_private; +	struct rockchip_drm_private *priv; + +	if (!drm) +		return 0;  	drm_kms_helper_poll_disable(drm);  	rockchip_drm_fb_suspend(drm); +	priv = drm->dev_private;  	priv->state = drm_atomic_helper_suspend(drm);  	if (IS_ERR(priv->state)) {  		rockchip_drm_fb_resume(drm); @@ -293,8 +297,12 @@ static int rockchip_drm_sys_suspend(struct device *dev)  static int rockchip_drm_sys_resume(struct device *dev)  {  	struct drm_device *drm = dev_get_drvdata(dev); -	struct rockchip_drm_private *priv = drm->dev_private; +	struct rockchip_drm_private *priv; + +	if (!drm) +		return 0; +	priv = drm->dev_private;  	drm_atomic_helper_resume(drm, priv->state);  	rockchip_drm_fb_resume(drm);  	drm_kms_helper_poll_enable(drm); diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index abc7d8fe06b4..a45a627283a1 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -25,12 +25,20 @@  #include "sun4i_framebuffer.h"  #include "sun4i_tcon.h" +static void sun4i_drv_lastclose(struct drm_device *dev) +{ +	struct sun4i_drv *drv = dev->dev_private; + +	drm_fbdev_cma_restore_mode(drv->fbdev); +} +  DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops);  static struct drm_driver sun4i_drv_driver = {  	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,  	/* Generic Operations */ +	.lastclose		= sun4i_drv_lastclose,  	.fops			= &sun4i_drv_fops,  	.name			= "sun4i-drm",  	.desc			= "Allwinner sun4i Display Engine", diff --git a/drivers/gpu/ipu-v3/Kconfig b/drivers/gpu/ipu-v3/Kconfig index 08766c6e7856..87a20b3dcf7a 100644 --- a/drivers/gpu/ipu-v3/Kconfig +++ b/drivers/gpu/ipu-v3/Kconfig @@ -1,6 +1,7 @@  config IMX_IPUV3_CORE  	tristate "IPUv3 core support"  	depends on SOC_IMX5 || SOC_IMX6Q || ARCH_MULTIPLATFORM +	depends on DRM || !DRM # if DRM=m, this can't be 'y'  	select GENERIC_IRQ_CHIP  	help  	  Choose this if you have a i.MX5/6 system and want to use the Image |