diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_fbc.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_fbc.c | 59 | 
1 files changed, 49 insertions, 10 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 4820d21cc942..f17a1afb4929 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -608,6 +608,7 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)  static void ivb_fbc_activate(struct intel_fbc *fbc)  {  	struct drm_i915_private *i915 = fbc->i915; +	u32 dpfc_ctl;  	if (DISPLAY_VER(i915) >= 10)  		glk_fbc_program_cfb_stride(fbc); @@ -617,8 +618,13 @@ static void ivb_fbc_activate(struct intel_fbc *fbc)  	if (intel_gt_support_legacy_fencing(to_gt(i915)))  		snb_fbc_program_fence(fbc); +	/* wa_14019417088 Alternative WA*/ +	dpfc_ctl = ivb_dpfc_ctl(fbc); +	if (DISPLAY_VER(i915) >= 20) +		intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); +  	intel_de_write(i915, ILK_DPFC_CONTROL(fbc->id), -		       DPFC_CTL_EN | ivb_dpfc_ctl(fbc)); +		       DPFC_CTL_EN | dpfc_ctl);  }  static bool ivb_fbc_is_compressing(struct intel_fbc *fbc) @@ -1022,10 +1028,13 @@ static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *  	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);  	unsigned int effective_w, effective_h, max_w, max_h; -	if (DISPLAY_VER(i915) >= 10) { +	if (DISPLAY_VER(i915) >= 11) { +		max_w = 8192; +		max_h = 4096; +	} else if (DISPLAY_VER(i915) >= 10) {  		max_w = 5120;  		max_h = 4096; -	} else if (DISPLAY_VER(i915) >= 8 || IS_HASWELL(i915)) { +	} else if (DISPLAY_VER(i915) >= 7) {  		max_w = 4096;  		max_h = 4096;  	} else if (IS_G4X(i915) || DISPLAY_VER(i915) >= 5) { @@ -1044,6 +1053,31 @@ static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *  	return effective_w <= max_w && effective_h <= max_h;  } +static bool intel_fbc_plane_size_valid(const struct intel_plane_state *plane_state) +{ +	struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); +	unsigned int w, h, max_w, max_h; + +	if (DISPLAY_VER(i915) >= 10) { +		max_w = 5120; +		max_h = 4096; +	} else if (DISPLAY_VER(i915) >= 8 || IS_HASWELL(i915)) { +		max_w = 4096; +		max_h = 4096; +	} else if (IS_G4X(i915) || DISPLAY_VER(i915) >= 5) { +		max_w = 4096; +		max_h = 2048; +	} else { +		max_w = 2048; +		max_h = 1536; +	} + +	w = drm_rect_width(&plane_state->uapi.src) >> 16; +	h = drm_rect_height(&plane_state->uapi.src) >> 16; + +	return w <= max_w && h <= max_h; +} +  static bool i8xx_fbc_tiling_valid(const struct intel_plane_state *plane_state)  {  	const struct drm_framebuffer *fb = plane_state->hw.fb; @@ -1174,7 +1208,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,  		return 0;  	} -	if (!i915->params.enable_fbc) { +	if (!i915->display.params.enable_fbc) {  		plane_state->no_fbc_reason = "disabled per module param or by default";  		return 0;  	} @@ -1201,7 +1235,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,  	 * Recommendation is to keep this combination disabled  	 * Bspec: 50422 HSD: 14010260002  	 */ -	if (DISPLAY_VER(i915) >= 12 && crtc_state->has_psr2) { +	if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_psr2) {  		plane_state->no_fbc_reason = "PSR2 enabled";  		return 0;  	} @@ -1241,11 +1275,16 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,  		return 0;  	} -	if (!intel_fbc_hw_tracking_covers_screen(plane_state)) { +	if (!intel_fbc_plane_size_valid(plane_state)) {  		plane_state->no_fbc_reason = "plane size too big";  		return 0;  	} +	if (!intel_fbc_hw_tracking_covers_screen(plane_state)) { +		plane_state->no_fbc_reason = "surface size too big"; +		return 0; +	} +  	/*  	 * Work around a problem on GEN9+ HW, where enabling FBC on a plane  	 * having a Y offset that isn't divisible by 4 causes FIFO underrun @@ -1751,8 +1790,8 @@ void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915)   */  static int intel_sanitize_fbc_option(struct drm_i915_private *i915)  { -	if (i915->params.enable_fbc >= 0) -		return !!i915->params.enable_fbc; +	if (i915->display.params.enable_fbc >= 0) +		return !!i915->display.params.enable_fbc;  	if (!HAS_FBC(i915))  		return 0; @@ -1824,9 +1863,9 @@ void intel_fbc_init(struct drm_i915_private *i915)  	if (need_fbc_vtd_wa(i915))  		DISPLAY_RUNTIME_INFO(i915)->fbc_mask = 0; -	i915->params.enable_fbc = intel_sanitize_fbc_option(i915); +	i915->display.params.enable_fbc = intel_sanitize_fbc_option(i915);  	drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n", -		    i915->params.enable_fbc); +		    i915->display.params.enable_fbc);  	for_each_fbc_id(i915, fbc_id)  		i915->display.fbc[fbc_id] = intel_fbc_create(i915, fbc_id); | 
