diff options
| author | Dave Airlie <airlied@redhat.com> | 2019-04-12 13:39:22 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2019-04-12 13:39:32 +1000 | 
| commit | 788f07ebe040922c89e38f609b7890ba52a09db2 (patch) | |
| tree | 37b96117c5788c996f68467ca64b10ac3ce56a70 | |
| parent | ffb5d6fe140d2ef79c2a91861fc18a4a7a1f510a (diff) | |
| parent | 3f5f5d534bd40b666cf37bbeeb48bfe6c2efc1e0 (diff) | |
Merge tag 'drm-intel-fixes-2019-04-11' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
- Revert back to max link rate and lane count on eDP.
- DSI related fixes for all platforms including Ice Lake.
- GVT Fixes including one vGPU display plane size regression fix,
one for preventing use-after-free in ppgtt shadow free function,
and another warning fix for iomem access annotation.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190411235832.GA6476@intel.com
| -rw-r--r-- | drivers/gpu/drm/i915/gvt/dmabuf.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/gvt/gtt.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/gvt/kvmgt.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/icl_dsi.c | 48 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 69 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/vlv_dsi.c | 24 | 
9 files changed, 97 insertions, 110 deletions
| diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 5d887f7cc0d5..69a9a1b2ea4a 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -209,7 +209,7 @@ static int vgpu_get_plane_info(struct drm_device *dev,  	struct drm_i915_private *dev_priv = to_i915(dev);  	struct intel_vgpu_primary_plane_format p;  	struct intel_vgpu_cursor_plane_format c; -	int ret; +	int ret, tile_height = 1;  	if (plane_id == DRM_PLANE_TYPE_PRIMARY) {  		ret = intel_vgpu_decode_primary_plane(vgpu, &p); @@ -228,12 +228,15 @@ static int vgpu_get_plane_info(struct drm_device *dev,  			break;  		case PLANE_CTL_TILED_X:  			info->drm_format_mod = I915_FORMAT_MOD_X_TILED; +			tile_height = 8;  			break;  		case PLANE_CTL_TILED_Y:  			info->drm_format_mod = I915_FORMAT_MOD_Y_TILED; +			tile_height = 32;  			break;  		case PLANE_CTL_TILED_YF:  			info->drm_format_mod = I915_FORMAT_MOD_Yf_TILED; +			tile_height = 32;  			break;  		default:  			gvt_vgpu_err("invalid tiling mode: %x\n", p.tiled); @@ -264,8 +267,8 @@ static int vgpu_get_plane_info(struct drm_device *dev,  		return -EINVAL;  	} -	info->size = (info->stride * info->height + PAGE_SIZE - 1) -		      >> PAGE_SHIFT; +	info->size = (info->stride * roundup(info->height, tile_height) +		      + PAGE_SIZE - 1) >> PAGE_SHIFT;  	if (info->size == 0) {  		gvt_vgpu_err("fb size is zero\n");  		return -EINVAL; diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index cf133ef03873..9814773882ec 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -750,14 +750,20 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt)  static void ppgtt_free_all_spt(struct intel_vgpu *vgpu)  { -	struct intel_vgpu_ppgtt_spt *spt; +	struct intel_vgpu_ppgtt_spt *spt, *spn;  	struct radix_tree_iter iter; -	void **slot; +	LIST_HEAD(all_spt); +	void __rcu **slot; +	rcu_read_lock();  	radix_tree_for_each_slot(slot, &vgpu->gtt.spt_tree, &iter, 0) {  		spt = radix_tree_deref_slot(slot); -		ppgtt_free_spt(spt); +		list_move(&spt->post_shadow_list, &all_spt);  	} +	rcu_read_unlock(); + +	list_for_each_entry_safe(spt, spn, &all_spt, post_shadow_list) +		ppgtt_free_spt(spt);  }  static int ppgtt_handle_guest_write_page_table_bytes( diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index d5fcc447d22f..a68addf95c23 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -905,7 +905,7 @@ static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, u64 off)  static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off,  		void *buf, unsigned long count, bool is_write)  { -	void *aperture_va; +	void __iomem *aperture_va;  	if (!intel_vgpu_in_aperture(vgpu, off) ||  	    !intel_vgpu_in_aperture(vgpu, off + count)) { @@ -920,9 +920,9 @@ static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off,  		return -EIO;  	if (is_write) -		memcpy(aperture_va + offset_in_page(off), buf, count); +		memcpy_toio(aperture_va + offset_in_page(off), buf, count);  	else -		memcpy(buf, aperture_va + offset_in_page(off), count); +		memcpy_fromio(buf, aperture_va + offset_in_page(off), count);  	io_mapping_unmap(aperture_va); diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 73a7bee24a66..641e0778fa9c 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -323,6 +323,21 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder)  	}  } +static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv, +				     struct intel_dsi *intel_dsi) +{ +	enum port port; + +	for_each_dsi_port(port, intel_dsi->ports) { +		WARN_ON(intel_dsi->io_wakeref[port]); +		intel_dsi->io_wakeref[port] = +			intel_display_power_get(dev_priv, +						port == PORT_A ? +						POWER_DOMAIN_PORT_DDI_A_IO : +						POWER_DOMAIN_PORT_DDI_B_IO); +	} +} +  static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -336,13 +351,7 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)  		I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp);  	} -	for_each_dsi_port(port, intel_dsi->ports) { -		intel_dsi->io_wakeref[port] = -			intel_display_power_get(dev_priv, -						port == PORT_A ? -						POWER_DOMAIN_PORT_DDI_A_IO : -						POWER_DOMAIN_PORT_DDI_B_IO); -	} +	get_dsi_io_power_domains(dev_priv, intel_dsi);  }  static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) @@ -589,6 +598,12 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder,  		val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port);  	}  	I915_WRITE(DPCLKA_CFGCR0_ICL, val); + +	for_each_dsi_port(port, intel_dsi->ports) { +		val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port); +	} +	I915_WRITE(DPCLKA_CFGCR0_ICL, val); +  	POSTING_READ(DPCLKA_CFGCR0_ICL);  	mutex_unlock(&dev_priv->dpll_lock); @@ -1117,7 +1132,7 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder)  			DRM_ERROR("DDI port:%c buffer not idle\n",  				  port_name(port));  	} -	gen11_dsi_ungate_clocks(encoder); +	gen11_dsi_gate_clocks(encoder);  }  static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) @@ -1218,20 +1233,11 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,  	return 0;  } -static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, -				       struct intel_crtc_state *crtc_state) +static void gen11_dsi_get_power_domains(struct intel_encoder *encoder, +					struct intel_crtc_state *crtc_state)  { -	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); -	u64 domains = 0; -	enum port port; - -	for_each_dsi_port(port, intel_dsi->ports) -		if (port == PORT_A) -			domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO); -		else -			domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO); - -	return domains; +	get_dsi_io_power_domains(to_i915(encoder->base.dev), +				 enc_to_intel_dsi(&encoder->base));  }  static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 14d580cdefd3..ab4e60dfd6a3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2075,12 +2075,11 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port)  					      intel_aux_power_domain(dig_port);  } -static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, -				       struct intel_crtc_state *crtc_state) +static void intel_ddi_get_power_domains(struct intel_encoder *encoder, +					struct intel_crtc_state *crtc_state)  {  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);  	struct intel_digital_port *dig_port; -	u64 domains;  	/*  	 * TODO: Add support for MST encoders. Atm, the following should never @@ -2088,10 +2087,10 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder,  	 * hook.  	 */  	if (WARN_ON(intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) -		return 0; +		return;  	dig_port = enc_to_dig_port(&encoder->base); -	domains = BIT_ULL(dig_port->ddi_io_power_domain); +	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);  	/*  	 * AUX power is only needed for (e)DP mode, and for HDMI mode on TC @@ -2099,15 +2098,15 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder,  	 */  	if (intel_crtc_has_dp_encoder(crtc_state) ||  	    intel_port_is_tc(dev_priv, encoder->port)) -		domains |= BIT_ULL(intel_ddi_main_link_aux_domain(dig_port)); +		intel_display_power_get(dev_priv, +					intel_ddi_main_link_aux_domain(dig_port));  	/*  	 * VDSC power is needed when DSC is enabled  	 */  	if (crtc_state->dsc_params.compression_enable) -		domains |= BIT_ULL(intel_dsc_power_domain(crtc_state)); - -	return domains; +		intel_display_power_get(dev_priv, +					intel_dsc_power_domain(crtc_state));  }  void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state) @@ -2825,10 +2824,10 @@ void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)  				return;  		}  		/* -		 * DSI ports should have their DDI clock ungated when disabled -		 * and gated when enabled. +		 * For DSI we keep the ddi clocks gated +		 * except during enable/disable sequence.  		 */ -		ddi_clk_needed = !encoder->base.crtc; +		ddi_clk_needed = false;  	}  	val = I915_READ(DPCLKA_CFGCR0_ICL); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ccb616351bba..421aac80a838 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15986,8 +15986,6 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv)  	struct intel_encoder *encoder;  	for_each_intel_encoder(&dev_priv->drm, encoder) { -		u64 get_domains; -		enum intel_display_power_domain domain;  		struct intel_crtc_state *crtc_state;  		if (!encoder->get_power_domains) @@ -16001,9 +15999,7 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv)  			continue;  		crtc_state = to_intel_crtc_state(encoder->base.crtc->state); -		get_domains = encoder->get_power_domains(encoder, crtc_state); -		for_each_power_domain(domain, get_domains) -			intel_display_power_get(dev_priv, domain); +		encoder->get_power_domains(encoder, crtc_state);  	}  } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cf709835fb9a..8891f29a8c7f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1859,42 +1859,6 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,  	return -EINVAL;  } -/* Optimize link config in order: max bpp, min lanes, min clock */ -static int -intel_dp_compute_link_config_fast(struct intel_dp *intel_dp, -				  struct intel_crtc_state *pipe_config, -				  const struct link_config_limits *limits) -{ -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; -	int bpp, clock, lane_count; -	int mode_rate, link_clock, link_avail; - -	for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { -		mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, -						   bpp); - -		for (lane_count = limits->min_lane_count; -		     lane_count <= limits->max_lane_count; -		     lane_count <<= 1) { -			for (clock = limits->min_clock; clock <= limits->max_clock; clock++) { -				link_clock = intel_dp->common_rates[clock]; -				link_avail = intel_dp_max_data_rate(link_clock, -								    lane_count); - -				if (mode_rate <= link_avail) { -					pipe_config->lane_count = lane_count; -					pipe_config->pipe_bpp = bpp; -					pipe_config->port_clock = link_clock; - -					return 0; -				} -			} -		} -	} - -	return -EINVAL; -} -  static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc)  {  	int i, num_bpc; @@ -2031,15 +1995,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,  	limits.min_bpp = 6 * 3;  	limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); -	if (intel_dp_is_edp(intel_dp) && intel_dp->edp_dpcd[0] < DP_EDP_14) { +	if (intel_dp_is_edp(intel_dp)) {  		/*  		 * Use the maximum clock and number of lanes the eDP panel -		 * advertizes being capable of. The eDP 1.3 and earlier panels -		 * are generally designed to support only a single clock and -		 * lane configuration, and typically these values correspond to -		 * the native resolution of the panel. With eDP 1.4 rate select -		 * and DSC, this is decreasingly the case, and we need to be -		 * able to select less than maximum link config. +		 * advertizes being capable of. The panels are generally +		 * designed to support only a single clock and lane +		 * configuration, and typically these values correspond to the +		 * native resolution of the panel.  		 */  		limits.min_lane_count = limits.max_lane_count;  		limits.min_clock = limits.max_clock; @@ -2053,22 +2015,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,  		      intel_dp->common_rates[limits.max_clock],  		      limits.max_bpp, adjusted_mode->crtc_clock); -	if (intel_dp_is_edp(intel_dp)) -		/* -		 * Optimize for fast and narrow. eDP 1.3 section 3.3 and eDP 1.4 -		 * section A.1: "It is recommended that the minimum number of -		 * lanes be used, using the minimum link rate allowed for that -		 * lane configuration." -		 * -		 * Note that we use the max clock and lane count for eDP 1.3 and -		 * earlier, and fast vs. wide is irrelevant. -		 */ -		ret = intel_dp_compute_link_config_fast(intel_dp, pipe_config, -							&limits); -	else -		/* Optimize for slow and wide. */ -		ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, -							&limits); +	/* +	 * Optimize for slow and wide. This is the place to add alternative +	 * optimization policy. +	 */ +	ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits);  	/* enable compression if the mode doesn't fit available BW */  	DRM_DEBUG_KMS("Force DSC en = %d\n", intel_dp->force_dsc_en); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 15db41394b9e..d5660ac1b0d6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -270,10 +270,12 @@ struct intel_encoder {  	 * be set correctly before calling this function. */  	void (*get_config)(struct intel_encoder *,  			   struct intel_crtc_state *pipe_config); -	/* Returns a mask of power domains that need to be referenced as part -	 * of the hardware state readout code. */ -	u64 (*get_power_domains)(struct intel_encoder *encoder, -				 struct intel_crtc_state *crtc_state); +	/* +	 * Acquires the power domains needed for an active encoder during +	 * hardware state readout. +	 */ +	void (*get_power_domains)(struct intel_encoder *encoder, +				  struct intel_crtc_state *crtc_state);  	/*  	 * Called during system suspend after all pending requests for the  	 * encoder are flushed (for example for DP AUX transactions) and diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index 6403728fe778..31c93c3ccd00 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -256,6 +256,28 @@ static void band_gap_reset(struct drm_i915_private *dev_priv)  	mutex_unlock(&dev_priv->sb_lock);  } +static int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) +{ +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); +	u32 tmp; + +	tmp = I915_READ(PIPEMISC(crtc->pipe)); + +	switch (tmp & PIPEMISC_DITHER_BPC_MASK) { +	case PIPEMISC_DITHER_6_BPC: +		return 18; +	case PIPEMISC_DITHER_8_BPC: +		return 24; +	case PIPEMISC_DITHER_10_BPC: +		return 30; +	case PIPEMISC_DITHER_12_BPC: +		return 36; +	default: +		MISSING_CASE(tmp); +		return 0; +	} +} +  static int intel_dsi_compute_config(struct intel_encoder *encoder,  				    struct intel_crtc_state *pipe_config,  				    struct drm_connector_state *conn_state) @@ -1071,6 +1093,8 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,  	bpp = mipi_dsi_pixel_format_to_bpp(  			pixel_format_from_register_bits(fmt)); +	pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc); +  	/* Enable Frame time stamo based scanline reporting */  	adjusted_mode->private_flags |=  			I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; | 
