diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 812 | 
1 files changed, 328 insertions, 484 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ab5ac5ee1825..d031d74abd27 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -71,20 +71,6 @@ static void skl_init_clock_gating(struct drm_device *dev)  	gen9_init_clock_gating(dev); -	if (INTEL_REVID(dev) <= SKL_REVID_B0) { -		/* -		 * WaDisableSDEUnitClockGating:skl -		 * WaSetGAPSunitClckGateDisable:skl -		 */ -		I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | -			   GEN8_GAPSUNIT_CLOCK_GATE_DISABLE | -			   GEN8_SDEUNIT_CLOCK_GATE_DISABLE); - -		/* WaDisableVFUnitClockGating:skl */ -		I915_WRITE(GEN6_UCGCTL2, I915_READ(GEN6_UCGCTL2) | -			   GEN6_VFUNIT_CLOCK_GATE_DISABLE); -	} -  	if (INTEL_REVID(dev) <= SKL_REVID_D0) {  		/* WaDisableHDCInvalidation:skl */  		I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | @@ -127,13 +113,10 @@ static void bxt_init_clock_gating(struct drm_device *dev)  	I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |  		   GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); -	if (INTEL_REVID(dev) == BXT_REVID_A0) { -		/* -		 * Hardware specification requires this bit to be -		 * set to 1 for A0 -		 */ +	/* WaStoreMultiplePTEenable:bxt */ +	/* This is a requirement according to Hardware specification */ +	if (INTEL_REVID(dev) == BXT_REVID_A0)  		I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); -	}  	/* WaSetClckGatingDisableMedia:bxt */  	if (INTEL_REVID(dev) == BXT_REVID_A0) { @@ -703,12 +686,9 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)  	crtc = single_enabled_crtc(dev);  	if (crtc) { -		const struct drm_display_mode *adjusted_mode; +		const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;  		int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; -		int clock; - -		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; -		clock = adjusted_mode->crtc_clock; +		int clock = adjusted_mode->crtc_clock;  		/* Display SR */  		wm = intel_calculate_wm(clock, &pineview_display_wm, @@ -1502,8 +1482,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)  	if (crtc) {  		/* self-refresh has much higher latency */  		static const int sr_latency_ns = 12000; -		const struct drm_display_mode *adjusted_mode = -			&to_intel_crtc(crtc)->config->base.adjusted_mode; +		const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;  		int clock = adjusted_mode->crtc_clock;  		int htotal = adjusted_mode->crtc_htotal;  		int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; @@ -1650,8 +1629,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)  	if (HAS_FW_BLC(dev) && enabled) {  		/* self-refresh has much higher latency */  		static const int sr_latency_ns = 6000; -		const struct drm_display_mode *adjusted_mode = -			&to_intel_crtc(enabled)->config->base.adjusted_mode; +		const struct drm_display_mode *adjusted_mode = &to_intel_crtc(enabled)->config->base.adjusted_mode;  		int clock = adjusted_mode->crtc_clock;  		int htotal = adjusted_mode->crtc_htotal;  		int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w; @@ -1787,23 +1765,6 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,  	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;  } -struct skl_pipe_wm_parameters { -	bool active; -	uint32_t pipe_htotal; -	uint32_t pixel_rate; /* in KHz */ -	struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; -	struct intel_plane_wm_parameters cursor; -}; - -struct ilk_pipe_wm_parameters { -	bool active; -	uint32_t pipe_htotal; -	uint32_t pixel_rate; -	struct intel_plane_wm_parameters pri; -	struct intel_plane_wm_parameters spr; -	struct intel_plane_wm_parameters cur; -}; -  struct ilk_wm_maximums {  	uint16_t pri;  	uint16_t spr; @@ -1822,26 +1783,26 @@ struct intel_wm_config {   * For both WM_PIPE and WM_LP.   * mem_value must be in 0.1us units.   */ -static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params, +static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate, +				   const struct intel_plane_state *pstate,  				   uint32_t mem_value,  				   bool is_lp)  { +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;  	uint32_t method1, method2; -	if (!params->active || !params->pri.enabled) +	if (!cstate->base.active || !pstate->visible)  		return 0; -	method1 = ilk_wm_method1(params->pixel_rate, -				 params->pri.bytes_per_pixel, -				 mem_value); +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);  	if (!is_lp)  		return method1; -	method2 = ilk_wm_method2(params->pixel_rate, -				 params->pipe_htotal, -				 params->pri.horiz_pixels, -				 params->pri.bytes_per_pixel, +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), +				 cstate->base.adjusted_mode.crtc_htotal, +				 drm_rect_width(&pstate->dst), +				 bpp,  				 mem_value);  	return min(method1, method2); @@ -1851,21 +1812,21 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,   * For both WM_PIPE and WM_LP.   * mem_value must be in 0.1us units.   */ -static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params, +static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate, +				   const struct intel_plane_state *pstate,  				   uint32_t mem_value)  { +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;  	uint32_t method1, method2; -	if (!params->active || !params->spr.enabled) +	if (!cstate->base.active || !pstate->visible)  		return 0; -	method1 = ilk_wm_method1(params->pixel_rate, -				 params->spr.bytes_per_pixel, -				 mem_value); -	method2 = ilk_wm_method2(params->pixel_rate, -				 params->pipe_htotal, -				 params->spr.horiz_pixels, -				 params->spr.bytes_per_pixel, +	method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value); +	method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), +				 cstate->base.adjusted_mode.crtc_htotal, +				 drm_rect_width(&pstate->dst), +				 bpp,  				 mem_value);  	return min(method1, method2);  } @@ -1874,29 +1835,33 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,   * For both WM_PIPE and WM_LP.   * mem_value must be in 0.1us units.   */ -static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params, +static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate, +				   const struct intel_plane_state *pstate,  				   uint32_t mem_value)  { -	if (!params->active || !params->cur.enabled) +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; + +	if (!cstate->base.active || !pstate->visible)  		return 0; -	return ilk_wm_method2(params->pixel_rate, -			      params->pipe_htotal, -			      params->cur.horiz_pixels, -			      params->cur.bytes_per_pixel, +	return ilk_wm_method2(ilk_pipe_pixel_rate(cstate), +			      cstate->base.adjusted_mode.crtc_htotal, +			      drm_rect_width(&pstate->dst), +			      bpp,  			      mem_value);  }  /* Only for WM_LP. */ -static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params, +static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate, +				   const struct intel_plane_state *pstate,  				   uint32_t pri_val)  { -	if (!params->active || !params->pri.enabled) +	int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; + +	if (!cstate->base.active || !pstate->visible)  		return 0; -	return ilk_wm_fbc(pri_val, -			  params->pri.horiz_pixels, -			  params->pri.bytes_per_pixel); +	return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);  }  static unsigned int ilk_display_fifo_size(const struct drm_device *dev) @@ -2061,10 +2026,12 @@ static bool ilk_validate_wm_level(int level,  }  static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, +				 const struct intel_crtc *intel_crtc,  				 int level, -				 const struct ilk_pipe_wm_parameters *p, +				 struct intel_crtc_state *cstate,  				 struct intel_wm_level *result)  { +	struct intel_plane *intel_plane;  	uint16_t pri_latency = dev_priv->wm.pri_latency[level];  	uint16_t spr_latency = dev_priv->wm.spr_latency[level];  	uint16_t cur_latency = dev_priv->wm.cur_latency[level]; @@ -2076,10 +2043,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,  		cur_latency *= 5;  	} -	result->pri_val = ilk_compute_pri_wm(p, pri_latency, level); -	result->spr_val = ilk_compute_spr_wm(p, spr_latency); -	result->cur_val = ilk_compute_cur_wm(p, cur_latency); -	result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val); +	for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) { +		struct intel_plane_state *pstate = +			to_intel_plane_state(intel_plane->base.state); + +		switch (intel_plane->base.type) { +		case DRM_PLANE_TYPE_PRIMARY: +			result->pri_val = ilk_compute_pri_wm(cstate, pstate, +							     pri_latency, +							     level); +			result->fbc_val = ilk_compute_fbc_wm(cstate, pstate, +							     result->pri_val); +			break; +		case DRM_PLANE_TYPE_OVERLAY: +			result->spr_val = ilk_compute_spr_wm(cstate, pstate, +							     spr_latency); +			break; +		case DRM_PLANE_TYPE_CURSOR: +			result->cur_val = ilk_compute_cur_wm(cstate, pstate, +							     cur_latency); +			break; +		} +	} +  	result->enable = true;  } @@ -2088,7 +2074,7 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode; +	const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;  	u32 linetime, ips_linetime;  	if (!intel_crtc->active) @@ -2097,9 +2083,9 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)  	/* The WM are computed with base on how long it takes to fill a single  	 * row at the given clock rate, multiplied by 8.  	 * */ -	linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8, -				     mode->crtc_clock); -	ips_linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8, +	linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, +				     adjusted_mode->crtc_clock); +	ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,  					 dev_priv->cdclk_freq);  	return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) | @@ -2338,48 +2324,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)  	intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);  } -static void ilk_compute_wm_parameters(struct drm_crtc *crtc, -				      struct ilk_pipe_wm_parameters *p) -{ -	struct drm_device *dev = crtc->dev; -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	enum pipe pipe = intel_crtc->pipe; -	struct drm_plane *plane; - -	if (!intel_crtc->active) -		return; - -	p->active = true; -	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; -	p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config); - -	if (crtc->primary->state->fb) -		p->pri.bytes_per_pixel = -			crtc->primary->state->fb->bits_per_pixel / 8; -	else -		p->pri.bytes_per_pixel = 4; - -	p->cur.bytes_per_pixel = 4; -	/* -	 * TODO: for now, assume primary and cursor planes are always enabled. -	 * Setting them to false makes the screen flicker. -	 */ -	p->pri.enabled = true; -	p->cur.enabled = true; - -	p->pri.horiz_pixels = intel_crtc->config->pipe_src_w; -	p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w; - -	drm_for_each_legacy_plane(plane, dev) { -		struct intel_plane *intel_plane = to_intel_plane(plane); - -		if (intel_plane->pipe == pipe) { -			p->spr = intel_plane->wm; -			break; -		} -	} -} -  static void ilk_compute_wm_config(struct drm_device *dev,  				  struct intel_wm_config *config)  { @@ -2399,34 +2343,47 @@ static void ilk_compute_wm_config(struct drm_device *dev,  }  /* Compute new watermarks for the pipe */ -static bool intel_compute_pipe_wm(struct drm_crtc *crtc, -				  const struct ilk_pipe_wm_parameters *params, +static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,  				  struct intel_pipe_wm *pipe_wm)  { +	struct drm_crtc *crtc = cstate->base.crtc;  	struct drm_device *dev = crtc->dev;  	const struct drm_i915_private *dev_priv = dev->dev_private; +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +	struct intel_plane *intel_plane; +	struct intel_plane_state *sprstate = NULL;  	int level, max_level = ilk_wm_max_level(dev);  	/* LP0 watermark maximums depend on this pipe alone */  	struct intel_wm_config config = {  		.num_pipes_active = 1, -		.sprites_enabled = params->spr.enabled, -		.sprites_scaled = params->spr.scaled,  	};  	struct ilk_wm_maximums max; -	pipe_wm->pipe_enabled = params->active; -	pipe_wm->sprites_enabled = params->spr.enabled; -	pipe_wm->sprites_scaled = params->spr.scaled; +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { +		if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) { +			sprstate = to_intel_plane_state(intel_plane->base.state); +			break; +		} +	} + +	config.sprites_enabled = sprstate->visible; +	config.sprites_scaled = sprstate->visible && +		(drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || +		drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); + +	pipe_wm->pipe_enabled = cstate->base.active; +	pipe_wm->sprites_enabled = sprstate->visible; +	pipe_wm->sprites_scaled = config.sprites_scaled;  	/* ILK/SNB: LP2+ watermarks only w/o sprites */ -	if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled) +	if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)  		max_level = 1;  	/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ -	if (params->spr.scaled) +	if (config.sprites_scaled)  		max_level = 0; -	ilk_compute_wm_level(dev_priv, 0, params, &pipe_wm->wm[0]); +	ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))  		pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc); @@ -2443,7 +2400,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,  	for (level = 1; level <= max_level; level++) {  		struct intel_wm_level wm = {}; -		ilk_compute_wm_level(dev_priv, level, params, &wm); +		ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);  		/*  		 * Disable any watermark level that exceeds the @@ -2848,18 +2805,40 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)  #define SKL_DDB_SIZE		896	/* in blocks */  #define BXT_DDB_SIZE		512 +/* + * Return the index of a plane in the SKL DDB and wm result arrays.  Primary + * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and + * other universal planes are in indices 1..n.  Note that this may leave unused + * indices between the top "sprite" plane and the cursor. + */ +static int +skl_wm_plane_id(const struct intel_plane *plane) +{ +	switch (plane->base.type) { +	case DRM_PLANE_TYPE_PRIMARY: +		return 0; +	case DRM_PLANE_TYPE_CURSOR: +		return PLANE_CURSOR; +	case DRM_PLANE_TYPE_OVERLAY: +		return plane->plane + 1; +	default: +		MISSING_CASE(plane->base.type); +		return plane->plane; +	} +} +  static void  skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, -				   struct drm_crtc *for_crtc, +				   const struct intel_crtc_state *cstate,  				   const struct intel_wm_config *config, -				   const struct skl_pipe_wm_parameters *params,  				   struct skl_ddb_entry *alloc /* out */)  { +	struct drm_crtc *for_crtc = cstate->base.crtc;  	struct drm_crtc *crtc;  	unsigned int pipe_size, ddb_size;  	int nth_active_pipe; -	if (!params->active) { +	if (!cstate->base.active) {  		alloc->start = 0;  		alloc->end = 0;  		return; @@ -2919,24 +2898,35 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,  		}  		val = I915_READ(CUR_BUF_CFG(pipe)); -		skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val); +		skl_ddb_entry_init_from_hw(&ddb->plane[pipe][PLANE_CURSOR], +					   val);  	}  }  static unsigned int -skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y) +skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, +			     const struct drm_plane_state *pstate, +			     int y)  { +	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); +	struct drm_framebuffer *fb = pstate->fb;  	/* for planar format */ -	if (p->y_bytes_per_pixel) { +	if (fb->pixel_format == DRM_FORMAT_NV12) {  		if (y)  /* y-plane data rate */ -			return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel; +			return intel_crtc->config->pipe_src_w * +				intel_crtc->config->pipe_src_h * +				drm_format_plane_cpp(fb->pixel_format, 0);  		else    /* uv-plane data rate */ -			return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel; +			return (intel_crtc->config->pipe_src_w/2) * +				(intel_crtc->config->pipe_src_h/2) * +				drm_format_plane_cpp(fb->pixel_format, 1);  	}  	/* for packed formats */ -	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel; +	return intel_crtc->config->pipe_src_w * +		intel_crtc->config->pipe_src_h * +		drm_format_plane_cpp(fb->pixel_format, 0);  }  /* @@ -2945,72 +2935,81 @@ skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)   *   3 * 4096 * 8192  * 4 < 2^32   */  static unsigned int -skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc, -				 const struct skl_pipe_wm_parameters *params) +skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)  { +	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); +	struct drm_device *dev = intel_crtc->base.dev; +	const struct intel_plane *intel_plane;  	unsigned int total_data_rate = 0; -	int plane; -	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { -		const struct intel_plane_wm_parameters *p; +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { +		const struct drm_plane_state *pstate = intel_plane->base.state; -		p = ¶ms->plane[plane]; -		if (!p->enabled) +		if (pstate->fb == NULL)  			continue; -		total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */ -		if (p->y_bytes_per_pixel) { -			total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */ -		} +		/* packed/uv */ +		total_data_rate += skl_plane_relative_data_rate(cstate, +								pstate, +								0); + +		if (pstate->fb->pixel_format == DRM_FORMAT_NV12) +			/* y-plane */ +			total_data_rate += skl_plane_relative_data_rate(cstate, +									pstate, +									1);  	}  	return total_data_rate;  }  static void -skl_allocate_pipe_ddb(struct drm_crtc *crtc, +skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,  		      const struct intel_wm_config *config, -		      const struct skl_pipe_wm_parameters *params,  		      struct skl_ddb_allocation *ddb /* out */)  { +	struct drm_crtc *crtc = cstate->base.crtc;  	struct drm_device *dev = crtc->dev; -	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +	struct intel_plane *intel_plane;  	enum pipe pipe = intel_crtc->pipe;  	struct skl_ddb_entry *alloc = &ddb->pipe[pipe];  	uint16_t alloc_size, start, cursor_blocks;  	uint16_t minimum[I915_MAX_PLANES];  	uint16_t y_minimum[I915_MAX_PLANES];  	unsigned int total_data_rate; -	int plane; -	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc); +	skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);  	alloc_size = skl_ddb_entry_size(alloc);  	if (alloc_size == 0) {  		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); -		memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe])); +		memset(&ddb->plane[pipe][PLANE_CURSOR], 0, +		       sizeof(ddb->plane[pipe][PLANE_CURSOR]));  		return;  	}  	cursor_blocks = skl_cursor_allocation(config); -	ddb->cursor[pipe].start = alloc->end - cursor_blocks; -	ddb->cursor[pipe].end = alloc->end; +	ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks; +	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;  	alloc_size -= cursor_blocks;  	alloc->end -= cursor_blocks;  	/* 1. Allocate the mininum required blocks for each active plane */ -	for_each_plane(dev_priv, pipe, plane) { -		const struct intel_plane_wm_parameters *p; +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { +		struct drm_plane *plane = &intel_plane->base; +		struct drm_framebuffer *fb = plane->fb; +		int id = skl_wm_plane_id(intel_plane); -		p = ¶ms->plane[plane]; -		if (!p->enabled) +		if (fb == NULL) +			continue; +		if (plane->type == DRM_PLANE_TYPE_CURSOR)  			continue; -		minimum[plane] = 8; -		alloc_size -= minimum[plane]; -		y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0; -		alloc_size -= y_minimum[plane]; +		minimum[id] = 8; +		alloc_size -= minimum[id]; +		y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0; +		alloc_size -= y_minimum[id];  	}  	/* @@ -3019,45 +3018,50 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,  	 *  	 * FIXME: we may not allocate every single block here.  	 */ -	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); +	total_data_rate = skl_get_total_relative_data_rate(cstate);  	start = alloc->start; -	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { -		const struct intel_plane_wm_parameters *p; +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { +		struct drm_plane *plane = &intel_plane->base; +		struct drm_plane_state *pstate = intel_plane->base.state;  		unsigned int data_rate, y_data_rate;  		uint16_t plane_blocks, y_plane_blocks = 0; +		int id = skl_wm_plane_id(intel_plane); -		p = ¶ms->plane[plane]; -		if (!p->enabled) +		if (pstate->fb == NULL) +			continue; +		if (plane->type == DRM_PLANE_TYPE_CURSOR)  			continue; -		data_rate = skl_plane_relative_data_rate(p, 0); +		data_rate = skl_plane_relative_data_rate(cstate, pstate, 0);  		/*  		 * allocation for (packed formats) or (uv-plane part of planar format):  		 * promote the expression to 64 bits to avoid overflowing, the  		 * result is < available as data_rate / total_data_rate < 1  		 */ -		plane_blocks = minimum[plane]; +		plane_blocks = minimum[id];  		plane_blocks += div_u64((uint64_t)alloc_size * data_rate,  					total_data_rate); -		ddb->plane[pipe][plane].start = start; -		ddb->plane[pipe][plane].end = start + plane_blocks; +		ddb->plane[pipe][id].start = start; +		ddb->plane[pipe][id].end = start + plane_blocks;  		start += plane_blocks;  		/*  		 * allocation for y_plane part of planar format:  		 */ -		if (p->y_bytes_per_pixel) { -			y_data_rate = skl_plane_relative_data_rate(p, 1); -			y_plane_blocks = y_minimum[plane]; +		if (pstate->fb->pixel_format == DRM_FORMAT_NV12) { +			y_data_rate = skl_plane_relative_data_rate(cstate, +								   pstate, +								   1); +			y_plane_blocks = y_minimum[id];  			y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,  						total_data_rate); -			ddb->y_plane[pipe][plane].start = start; -			ddb->y_plane[pipe][plane].end = start + y_plane_blocks; +			ddb->y_plane[pipe][id].start = start; +			ddb->y_plane[pipe][id].end = start + y_plane_blocks;  			start += y_plane_blocks;  		} @@ -3133,8 +3137,8 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,  		   sizeof(new_ddb->plane[pipe])))  		return true; -	if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe], -		    sizeof(new_ddb->cursor[pipe]))) +	if (memcmp(&new_ddb->plane[pipe][PLANE_CURSOR], &cur_ddb->plane[pipe][PLANE_CURSOR], +		    sizeof(new_ddb->plane[pipe][PLANE_CURSOR])))  		return true;  	return false; @@ -3144,87 +3148,21 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,  					     struct intel_wm_config *config)  {  	struct drm_crtc *crtc; -	struct drm_plane *plane;  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)  		config->num_pipes_active += to_intel_crtc(crtc)->active; - -	/* FIXME: I don't think we need those two global parameters on SKL */ -	list_for_each_entry(plane, &dev->mode_config.plane_list, head) { -		struct intel_plane *intel_plane = to_intel_plane(plane); - -		config->sprites_enabled |= intel_plane->wm.enabled; -		config->sprites_scaled |= intel_plane->wm.scaled; -	} -} - -static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, -					   struct skl_pipe_wm_parameters *p) -{ -	struct drm_device *dev = crtc->dev; -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	enum pipe pipe = intel_crtc->pipe; -	struct drm_plane *plane; -	struct drm_framebuffer *fb; -	int i = 1; /* Index for sprite planes start */ - -	p->active = intel_crtc->active; -	if (p->active) { -		p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; -		p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config); - -		fb = crtc->primary->state->fb; -		/* For planar: Bpp is for uv plane, y_Bpp is for y plane */ -		if (fb) { -			p->plane[0].enabled = true; -			p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? -				drm_format_plane_cpp(fb->pixel_format, 1) : -				drm_format_plane_cpp(fb->pixel_format, 0); -			p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? -				drm_format_plane_cpp(fb->pixel_format, 0) : 0; -			p->plane[0].tiling = fb->modifier[0]; -		} else { -			p->plane[0].enabled = false; -			p->plane[0].bytes_per_pixel = 0; -			p->plane[0].y_bytes_per_pixel = 0; -			p->plane[0].tiling = DRM_FORMAT_MOD_NONE; -		} -		p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w; -		p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h; -		p->plane[0].rotation = crtc->primary->state->rotation; - -		fb = crtc->cursor->state->fb; -		p->cursor.y_bytes_per_pixel = 0; -		if (fb) { -			p->cursor.enabled = true; -			p->cursor.bytes_per_pixel = fb->bits_per_pixel / 8; -			p->cursor.horiz_pixels = crtc->cursor->state->crtc_w; -			p->cursor.vert_pixels = crtc->cursor->state->crtc_h; -		} else { -			p->cursor.enabled = false; -			p->cursor.bytes_per_pixel = 0; -			p->cursor.horiz_pixels = 64; -			p->cursor.vert_pixels = 64; -		} -	} - -	list_for_each_entry(plane, &dev->mode_config.plane_list, head) { -		struct intel_plane *intel_plane = to_intel_plane(plane); - -		if (intel_plane->pipe == pipe && -			plane->type == DRM_PLANE_TYPE_OVERLAY) -			p->plane[i++] = intel_plane->wm; -	}  }  static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, -				 struct skl_pipe_wm_parameters *p, -				 struct intel_plane_wm_parameters *p_params, +				 struct intel_crtc_state *cstate, +				 struct intel_plane *intel_plane,  				 uint16_t ddb_allocation,  				 int level,  				 uint16_t *out_blocks, /* out */  				 uint8_t *out_lines /* out */)  { +	struct drm_plane *plane = &intel_plane->base; +	struct drm_framebuffer *fb = plane->state->fb;  	uint32_t latency = dev_priv->wm.skl_latency[level];  	uint32_t method1, method2;  	uint32_t plane_bytes_per_line, plane_blocks_per_line; @@ -3232,31 +3170,35 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,  	uint32_t selected_result;  	uint8_t bytes_per_pixel; -	if (latency == 0 || !p->active || !p_params->enabled) +	if (latency == 0 || !cstate->base.active || !fb)  		return false; -	bytes_per_pixel = p_params->y_bytes_per_pixel ? -		p_params->y_bytes_per_pixel : -		p_params->bytes_per_pixel; -	method1 = skl_wm_method1(p->pixel_rate, +	bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ? +		drm_format_plane_cpp(DRM_FORMAT_NV12, 0) : +		drm_format_plane_cpp(DRM_FORMAT_NV12, 1); +	method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),  				 bytes_per_pixel,  				 latency); -	method2 = skl_wm_method2(p->pixel_rate, -				 p->pipe_htotal, -				 p_params->horiz_pixels, +	method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), +				 cstate->base.adjusted_mode.crtc_htotal, +				 cstate->pipe_src_w,  				 bytes_per_pixel, -				 p_params->tiling, +				 fb->modifier[0],  				 latency); -	plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel; +	plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel;  	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); -	if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || -	    p_params->tiling == I915_FORMAT_MOD_Yf_TILED) { +	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || +	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {  		uint32_t min_scanlines = 4;  		uint32_t y_tile_minimum; -		if (intel_rotation_90_or_270(p_params->rotation)) { -			switch (p_params->bytes_per_pixel) { +		if (intel_rotation_90_or_270(plane->state->rotation)) { +			int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ? +				drm_format_plane_cpp(fb->pixel_format, 1) : +				drm_format_plane_cpp(fb->pixel_format, 0); + +			switch (bpp) {  			case 1:  				min_scanlines = 16;  				break; @@ -3280,8 +3222,8 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,  	res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);  	if (level >= 1 && level <= 7) { -		if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || -		    p_params->tiling == I915_FORMAT_MOD_Yf_TILED) +		if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || +		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)  			res_lines += 4;  		else  			res_blocks++; @@ -3298,83 +3240,80 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,  static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,  				 struct skl_ddb_allocation *ddb, -				 struct skl_pipe_wm_parameters *p, -				 enum pipe pipe, +				 struct intel_crtc_state *cstate,  				 int level, -				 int num_planes,  				 struct skl_wm_level *result)  { +	struct drm_device *dev = dev_priv->dev; +	struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); +	struct intel_plane *intel_plane;  	uint16_t ddb_blocks; -	int i; +	enum pipe pipe = intel_crtc->pipe; + +	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { +		int i = skl_wm_plane_id(intel_plane); -	for (i = 0; i < num_planes; i++) {  		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);  		result->plane_en[i] = skl_compute_plane_wm(dev_priv, -						p, &p->plane[i], +						cstate, +						intel_plane,  						ddb_blocks,  						level,  						&result->plane_res_b[i],  						&result->plane_res_l[i]);  	} - -	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]); -	result->cursor_en = skl_compute_plane_wm(dev_priv, p, &p->cursor, -						 ddb_blocks, level, -						 &result->cursor_res_b, -						 &result->cursor_res_l);  }  static uint32_t -skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) +skl_compute_linetime_wm(struct intel_crtc_state *cstate)  { -	if (!to_intel_crtc(crtc)->active) +	if (!cstate->base.active)  		return 0; -	if (WARN_ON(p->pixel_rate == 0)) +	if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))  		return 0; -	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate); +	return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000, +			    skl_pipe_pixel_rate(cstate));  } -static void skl_compute_transition_wm(struct drm_crtc *crtc, -				      struct skl_pipe_wm_parameters *params, +static void skl_compute_transition_wm(struct intel_crtc_state *cstate,  				      struct skl_wm_level *trans_wm /* out */)  { +	struct drm_crtc *crtc = cstate->base.crtc;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	int i; +	struct intel_plane *intel_plane; -	if (!params->active) +	if (!cstate->base.active)  		return;  	/* Until we know more, just disable transition WMs */ -	for (i = 0; i < intel_num_planes(intel_crtc); i++) +	for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) { +		int i = skl_wm_plane_id(intel_plane); +  		trans_wm->plane_en[i] = false; -	trans_wm->cursor_en = false; +	}  } -static void skl_compute_pipe_wm(struct drm_crtc *crtc, +static void skl_compute_pipe_wm(struct intel_crtc_state *cstate,  				struct skl_ddb_allocation *ddb, -				struct skl_pipe_wm_parameters *params,  				struct skl_pipe_wm *pipe_wm)  { -	struct drm_device *dev = crtc->dev; +	struct drm_device *dev = cstate->base.crtc->dev;  	const struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);  	int level, max_level = ilk_wm_max_level(dev);  	for (level = 0; level <= max_level; level++) { -		skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe, -				     level, intel_num_planes(intel_crtc), -				     &pipe_wm->wm[level]); +		skl_compute_wm_level(dev_priv, ddb, cstate, +				     level, &pipe_wm->wm[level]);  	} -	pipe_wm->linetime = skl_compute_linetime_wm(crtc, params); +	pipe_wm->linetime = skl_compute_linetime_wm(cstate); -	skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm); +	skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);  }  static void skl_compute_wm_results(struct drm_device *dev, -				   struct skl_pipe_wm_parameters *p,  				   struct skl_pipe_wm *p_wm,  				   struct skl_wm_values *r,  				   struct intel_crtc *intel_crtc) @@ -3399,13 +3338,13 @@ static void skl_compute_wm_results(struct drm_device *dev,  		temp = 0; -		temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT; -		temp |= p_wm->wm[level].cursor_res_b; +		temp |= p_wm->wm[level].plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; +		temp |= p_wm->wm[level].plane_res_b[PLANE_CURSOR]; -		if (p_wm->wm[level].cursor_en) +		if (p_wm->wm[level].plane_en[PLANE_CURSOR])  			temp |= PLANE_WM_EN; -		r->cursor[pipe][level] = temp; +		r->plane[pipe][PLANE_CURSOR][level] = temp;  	} @@ -3421,12 +3360,12 @@ static void skl_compute_wm_results(struct drm_device *dev,  	}  	temp = 0; -	temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT; -	temp |= p_wm->trans_wm.cursor_res_b; -	if (p_wm->trans_wm.cursor_en) +	temp |= p_wm->trans_wm.plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; +	temp |= p_wm->trans_wm.plane_res_b[PLANE_CURSOR]; +	if (p_wm->trans_wm.plane_en[PLANE_CURSOR])  		temp |= PLANE_WM_EN; -	r->cursor_trans[pipe] = temp; +	r->plane_trans[pipe][PLANE_CURSOR] = temp;  	r->wm_linetime[pipe] = p_wm->linetime;  } @@ -3460,12 +3399,13 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,  				I915_WRITE(PLANE_WM(pipe, i, level),  					   new->plane[pipe][i][level]);  			I915_WRITE(CUR_WM(pipe, level), -				   new->cursor[pipe][level]); +				   new->plane[pipe][PLANE_CURSOR][level]);  		}  		for (i = 0; i < intel_num_planes(crtc); i++)  			I915_WRITE(PLANE_WM_TRANS(pipe, i),  				   new->plane_trans[pipe][i]); -		I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]); +		I915_WRITE(CUR_WM_TRANS(pipe), +			   new->plane_trans[pipe][PLANE_CURSOR]);  		for (i = 0; i < intel_num_planes(crtc); i++) {  			skl_ddb_entry_write(dev_priv, @@ -3477,7 +3417,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,  		}  		skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe), -				    &new->ddb.cursor[pipe]); +				    &new->ddb.plane[pipe][PLANE_CURSOR]);  	}  } @@ -3617,16 +3557,15 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,  }  static bool skl_update_pipe_wm(struct drm_crtc *crtc, -			       struct skl_pipe_wm_parameters *params,  			       struct intel_wm_config *config,  			       struct skl_ddb_allocation *ddb, /* out */  			       struct skl_pipe_wm *pipe_wm /* out */)  {  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); -	skl_compute_wm_pipe_parameters(crtc, params); -	skl_allocate_pipe_ddb(crtc, config, params, ddb); -	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm); +	skl_allocate_pipe_ddb(cstate, config, ddb); +	skl_compute_pipe_wm(cstate, ddb, pipe_wm);  	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))  		return false; @@ -3659,7 +3598,6 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,  	 */  	list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,  				base.head) { -		struct skl_pipe_wm_parameters params = {};  		struct skl_pipe_wm pipe_wm = {};  		bool wm_changed; @@ -3669,8 +3607,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,  		if (!intel_crtc->active)  			continue; -		wm_changed = skl_update_pipe_wm(&intel_crtc->base, -						¶ms, config, +		wm_changed = skl_update_pipe_wm(&intel_crtc->base, config,  						&r->ddb, &pipe_wm);  		/* @@ -3680,7 +3617,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,  		 */  		WARN_ON(!wm_changed); -		skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc); +		skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);  		r->dirty[intel_crtc->pipe] = true;  	}  } @@ -3690,10 +3627,9 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)  	watermarks->wm_linetime[pipe] = 0;  	memset(watermarks->plane[pipe], 0,  	       sizeof(uint32_t) * 8 * I915_MAX_PLANES); -	memset(watermarks->cursor[pipe], 0, sizeof(uint32_t) * 8);  	memset(watermarks->plane_trans[pipe],  	       0, sizeof(uint32_t) * I915_MAX_PLANES); -	watermarks->cursor_trans[pipe] = 0; +	watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;  	/* Clear ddb entries for pipe */  	memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry)); @@ -3701,7 +3637,8 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)  	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);  	memset(&watermarks->ddb.y_plane[pipe], 0,  	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES); -	memset(&watermarks->ddb.cursor[pipe], 0, sizeof(struct skl_ddb_entry)); +	memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0, +	       sizeof(struct skl_ddb_entry));  } @@ -3710,7 +3647,6 @@ static void skl_update_wm(struct drm_crtc *crtc)  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);  	struct drm_device *dev = crtc->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct skl_pipe_wm_parameters params = {};  	struct skl_wm_values *results = &dev_priv->wm.skl_results;  	struct skl_pipe_wm pipe_wm = {};  	struct intel_wm_config config = {}; @@ -3723,11 +3659,10 @@ static void skl_update_wm(struct drm_crtc *crtc)  	skl_compute_wm_global_parameters(dev, &config); -	if (!skl_update_pipe_wm(crtc, ¶ms, &config, -				&results->ddb, &pipe_wm)) +	if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))  		return; -	skl_compute_wm_results(dev, ¶ms, &pipe_wm, results, intel_crtc); +	skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);  	results->dirty[intel_crtc->pipe] = true;  	skl_update_other_pipe_wm(dev, crtc, &config, results); @@ -3738,55 +3673,34 @@ static void skl_update_wm(struct drm_crtc *crtc)  	dev_priv->wm.skl_hw = *results;  } -static void -skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, -		     uint32_t sprite_width, uint32_t sprite_height, -		     int pixel_size, bool enabled, bool scaled) -{ -	struct intel_plane *intel_plane = to_intel_plane(plane); -	struct drm_framebuffer *fb = plane->state->fb; - -	intel_plane->wm.enabled = enabled; -	intel_plane->wm.scaled = scaled; -	intel_plane->wm.horiz_pixels = sprite_width; -	intel_plane->wm.vert_pixels = sprite_height; -	intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE; - -	/* For planar: Bpp is for UV plane, y_Bpp is for Y plane */ -	intel_plane->wm.bytes_per_pixel = -		(fb && fb->pixel_format == DRM_FORMAT_NV12) ? -		drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size; -	intel_plane->wm.y_bytes_per_pixel = -		(fb && fb->pixel_format == DRM_FORMAT_NV12) ? -		drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0; - -	/* -	 * Framebuffer can be NULL on plane disable, but it does not -	 * matter for watermarks if we assume no tiling in that case. -	 */ -	if (fb) -		intel_plane->wm.tiling = fb->modifier[0]; -	intel_plane->wm.rotation = plane->state->rotation; - -	skl_update_wm(crtc); -} -  static void ilk_update_wm(struct drm_crtc *crtc)  {  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);  	struct drm_device *dev = crtc->dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct ilk_wm_maximums max; -	struct ilk_pipe_wm_parameters params = {};  	struct ilk_wm_values results = {};  	enum intel_ddb_partitioning partitioning;  	struct intel_pipe_wm pipe_wm = {};  	struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;  	struct intel_wm_config config = {}; -	ilk_compute_wm_parameters(crtc, ¶ms); +	WARN_ON(cstate->base.active != intel_crtc->active); + +	/* +	 * IVB workaround: must disable low power watermarks for at least +	 * one frame before enabling scaling.  LP watermarks can be re-enabled +	 * when scaling is disabled. +	 * +	 * WaCxSRDisabledForSpriteScaling:ivb +	 */ +	if (cstate->disable_lp_wm) { +		ilk_disable_lp_wm(dev); +		intel_wait_for_vblank(dev, intel_crtc->pipe); +	} -	intel_compute_pipe_wm(crtc, ¶ms, &pipe_wm); +	intel_compute_pipe_wm(cstate, &pipe_wm);  	if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))  		return; @@ -3817,34 +3731,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)  	ilk_write_wm_values(dev_priv, &results);  } -static void -ilk_update_sprite_wm(struct drm_plane *plane, -		     struct drm_crtc *crtc, -		     uint32_t sprite_width, uint32_t sprite_height, -		     int pixel_size, bool enabled, bool scaled) -{ -	struct drm_device *dev = plane->dev; -	struct intel_plane *intel_plane = to_intel_plane(plane); - -	intel_plane->wm.enabled = enabled; -	intel_plane->wm.scaled = scaled; -	intel_plane->wm.horiz_pixels = sprite_width; -	intel_plane->wm.vert_pixels = sprite_width; -	intel_plane->wm.bytes_per_pixel = pixel_size; - -	/* -	 * IVB workaround: must disable low power watermarks for at least -	 * one frame before enabling scaling.  LP watermarks can be re-enabled -	 * when scaling is disabled. -	 * -	 * WaCxSRDisabledForSpriteScaling:ivb -	 */ -	if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev)) -		intel_wait_for_vblank(dev, intel_plane->pipe); - -	ilk_update_wm(crtc); -} -  static void skl_pipe_wm_active_state(uint32_t val,  				     struct skl_pipe_wm *active,  				     bool is_transwm, @@ -3863,10 +3749,10 @@ static void skl_pipe_wm_active_state(uint32_t val,  					(val >> PLANE_WM_LINES_SHIFT) &  						PLANE_WM_LINES_MASK;  		} else { -			active->wm[level].cursor_en = is_enabled; -			active->wm[level].cursor_res_b = +			active->wm[level].plane_en[PLANE_CURSOR] = is_enabled; +			active->wm[level].plane_res_b[PLANE_CURSOR] =  					val & PLANE_WM_BLOCKS_MASK; -			active->wm[level].cursor_res_l = +			active->wm[level].plane_res_l[PLANE_CURSOR] =  					(val >> PLANE_WM_LINES_SHIFT) &  						PLANE_WM_LINES_MASK;  		} @@ -3879,10 +3765,10 @@ static void skl_pipe_wm_active_state(uint32_t val,  					(val >> PLANE_WM_LINES_SHIFT) &  						PLANE_WM_LINES_MASK;  		} else { -			active->trans_wm.cursor_en = is_enabled; -			active->trans_wm.cursor_res_b = +			active->trans_wm.plane_en[PLANE_CURSOR] = is_enabled; +			active->trans_wm.plane_res_b[PLANE_CURSOR] =  					val & PLANE_WM_BLOCKS_MASK; -			active->trans_wm.cursor_res_l = +			active->trans_wm.plane_res_l[PLANE_CURSOR] =  					(val >> PLANE_WM_LINES_SHIFT) &  						PLANE_WM_LINES_MASK;  		} @@ -3908,12 +3794,12 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)  		for (i = 0; i < intel_num_planes(intel_crtc); i++)  			hw->plane[pipe][i][level] =  					I915_READ(PLANE_WM(pipe, i, level)); -		hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level)); +		hw->plane[pipe][PLANE_CURSOR][level] = I915_READ(CUR_WM(pipe, level));  	}  	for (i = 0; i < intel_num_planes(intel_crtc); i++)  		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i)); -	hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe)); +	hw->plane_trans[pipe][PLANE_CURSOR] = I915_READ(CUR_WM_TRANS(pipe));  	if (!intel_crtc->active)  		return; @@ -3928,7 +3814,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)  			skl_pipe_wm_active_state(temp, active, false,  						false, i, level);  		} -		temp = hw->cursor[pipe][level]; +		temp = hw->plane[pipe][PLANE_CURSOR][level];  		skl_pipe_wm_active_state(temp, active, false, true, i, level);  	} @@ -3937,7 +3823,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)  		skl_pipe_wm_active_state(temp, active, true, false, i, 0);  	} -	temp = hw->cursor_trans[pipe]; +	temp = hw->plane_trans[pipe][PLANE_CURSOR];  	skl_pipe_wm_active_state(temp, active, true, true, i, 0);  } @@ -4222,21 +4108,6 @@ void intel_update_watermarks(struct drm_crtc *crtc)  		dev_priv->display.update_wm(crtc);  } -void intel_update_sprite_watermarks(struct drm_plane *plane, -				    struct drm_crtc *crtc, -				    uint32_t sprite_width, -				    uint32_t sprite_height, -				    int pixel_size, -				    bool enabled, bool scaled) -{ -	struct drm_i915_private *dev_priv = plane->dev->dev_private; - -	if (dev_priv->display.update_sprite_wm) -		dev_priv->display.update_sprite_wm(plane, crtc, -						   sprite_width, sprite_height, -						   pixel_size, enabled, scaled); -} -  /**   * Lock protecting IPS related data structures   */ @@ -4886,7 +4757,6 @@ static void gen9_enable_rc6(struct drm_device *dev)  		I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA);  	I915_WRITE(GEN6_RC_SLEEP, 0); -	I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */  	/* 2c: Program Coarse Power Gating Policies. */  	I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 25); @@ -4897,16 +4767,19 @@ static void gen9_enable_rc6(struct drm_device *dev)  		rc6_mask = GEN6_RC_CTL_RC6_ENABLE;  	DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?  			"on" : "off"); - +	/* WaRsUseTimeoutMode */  	if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) || -	    (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) +	    (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) { +		I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */  		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |  			   GEN7_RC_CTL_TO_MODE |  			   rc6_mask); -	else +	} else { +		I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */  		I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |  			   GEN6_RC_CTL_EI_MODE(1) |  			   rc6_mask); +	}  	/*  	 * 3b: Enable Coarse Power Gating only when RC6 is enabled. @@ -5215,32 +5088,27 @@ static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)  	struct drm_device *dev = dev_priv->dev;  	u32 val, rp0; -	if (dev->pdev->revision >= 0x20) { -		val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); +	val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); -		switch (INTEL_INFO(dev)->eu_total) { -		case 8: -				/* (2 * 4) config */ -				rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT); -				break; -		case 12: -				/* (2 * 6) config */ -				rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT); -				break; -		case 16: -				/* (2 * 8) config */ -		default: -				/* Setting (2 * 8) Min RP0 for any other combination */ -				rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT); -				break; -		} -		rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK); -	} else { -		/* For pre-production hardware */ -		val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG); -		rp0 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & -		       PUNIT_GPU_STATUS_MAX_FREQ_MASK; +	switch (INTEL_INFO(dev)->eu_total) { +	case 8: +		/* (2 * 4) config */ +		rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT); +		break; +	case 12: +		/* (2 * 6) config */ +		rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT); +		break; +	case 16: +		/* (2 * 8) config */ +	default: +		/* Setting (2 * 8) Min RP0 for any other combination */ +		rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT); +		break;  	} + +	rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK); +  	return rp0;  } @@ -5256,18 +5124,11 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv)  static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv)  { -	struct drm_device *dev = dev_priv->dev;  	u32 val, rp1; -	if (dev->pdev->revision >= 0x20) { -		val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); -		rp1 = (val & FB_GFX_FREQ_FUSE_MASK); -	} else { -		/* For pre-production hardware */ -		val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); -		rp1 = ((val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & -		       PUNIT_GPU_STATUS_MAX_FREQ_MASK); -	} +	val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); +	rp1 = (val & FB_GFX_FREQ_FUSE_MASK); +  	return rp1;  } @@ -5482,25 +5343,10 @@ static void cherryview_init_gt_powersave(struct drm_device *dev)  	mutex_unlock(&dev_priv->sb_lock);  	switch ((val >> 2) & 0x7) { -	case 0: -	case 1: -		dev_priv->rps.cz_freq = 200; -		dev_priv->mem_freq = 1600; -		break; -	case 2: -		dev_priv->rps.cz_freq = 267; -		dev_priv->mem_freq = 1600; -		break;  	case 3: -		dev_priv->rps.cz_freq = 333;  		dev_priv->mem_freq = 2000;  		break; -	case 4: -		dev_priv->rps.cz_freq = 320; -		dev_priv->mem_freq = 1600; -		break; -	case 5: -		dev_priv->rps.cz_freq = 400; +	default:  		dev_priv->mem_freq = 1600;  		break;  	} @@ -6677,8 +6523,8 @@ static void lpt_init_clock_gating(struct drm_device *dev)  			   PCH_LP_PARTITION_LEVEL_DISABLE);  	/* WADPOClockGatingDisable:hsw */ -	I915_WRITE(_TRANSA_CHICKEN1, -		   I915_READ(_TRANSA_CHICKEN1) | +	I915_WRITE(TRANS_CHICKEN1(PIPE_A), +		   I915_READ(TRANS_CHICKEN1(PIPE_A)) |  		   TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);  } @@ -7176,7 +7022,6 @@ void intel_init_pm(struct drm_device *dev)  			dev_priv->display.init_clock_gating =  				skl_init_clock_gating;  		dev_priv->display.update_wm = skl_update_wm; -		dev_priv->display.update_sprite_wm = skl_update_sprite_wm;  	} else if (HAS_PCH_SPLIT(dev)) {  		ilk_setup_wm_latency(dev); @@ -7185,7 +7030,6 @@ void intel_init_pm(struct drm_device *dev)  		    (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&  		     dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {  			dev_priv->display.update_wm = ilk_update_wm; -			dev_priv->display.update_sprite_wm = ilk_update_sprite_wm;  		} else {  			DRM_DEBUG_KMS("Failed to read display plane latency. "  				      "Disable CxSR\n"); @@ -7327,7 +7171,7 @@ static int vlv_gpu_freq_div(unsigned int czclk_freq)  static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)  { -	int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); +	int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);  	div = vlv_gpu_freq_div(czclk_freq);  	if (div < 0) @@ -7338,7 +7182,7 @@ static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)  static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)  { -	int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4); +	int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);  	mul = vlv_gpu_freq_div(czclk_freq);  	if (mul < 0) @@ -7349,7 +7193,7 @@ static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)  static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)  { -	int div, czclk_freq = dev_priv->rps.cz_freq; +	int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);  	div = vlv_gpu_freq_div(czclk_freq) / 2;  	if (div < 0) @@ -7360,7 +7204,7 @@ static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)  static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)  { -	int mul, czclk_freq = dev_priv->rps.cz_freq; +	int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);  	mul = vlv_gpu_freq_div(czclk_freq) / 2;  	if (mul < 0)  |