diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_display.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 1985 | 
1 files changed, 389 insertions, 1596 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ec403e46a328..bf7ce684dd8e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -32,6 +32,7 @@  #include <linux/module.h>  #include <linux/dma-resv.h>  #include <linux/slab.h> +#include <linux/vga_switcheroo.h>  #include <drm/drm_atomic.h>  #include <drm/drm_atomic_helper.h> @@ -41,6 +42,7 @@  #include <drm/drm_edid.h>  #include <drm/drm_fourcc.h>  #include <drm/drm_plane_helper.h> +#include <drm/drm_privacy_screen_consumer.h>  #include <drm/drm_probe_helper.h>  #include <drm/drm_rect.h> @@ -70,11 +72,10 @@  #include "gt/gen8_ppgtt.h" -#include "pxp/intel_pxp.h" -  #include "g4x_dp.h"  #include "g4x_hdmi.h"  #include "i915_drv.h" +#include "icl_dsi.h"  #include "intel_acpi.h"  #include "intel_atomic.h"  #include "intel_atomic_plane.h" @@ -96,6 +97,8 @@  #include "intel_hotplug.h"  #include "intel_overlay.h"  #include "intel_panel.h" +#include "intel_pch_display.h" +#include "intel_pch_refclk.h"  #include "intel_pcode.h"  #include "intel_pipe_crc.h"  #include "intel_plane_initial.h" @@ -103,19 +106,15 @@  #include "intel_pps.h"  #include "intel_psr.h"  #include "intel_quirks.h" -#include "intel_sbi.h"  #include "intel_sprite.h"  #include "intel_tc.h"  #include "intel_vga.h"  #include "i9xx_plane.h"  #include "skl_scaler.h"  #include "skl_universal_plane.h" +#include "vlv_dsi_pll.h"  #include "vlv_sideband.h" - -static void i9xx_crtc_clock_get(struct intel_crtc *crtc, -				struct intel_crtc_state *pipe_config); -static void ilk_pch_clock_get(struct intel_crtc *crtc, -			      struct intel_crtc_state *pipe_config); +#include "vlv_dsi.h"  static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state);  static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state); @@ -341,6 +340,14 @@ is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)  		is_trans_port_sync_slave(crtc_state);  } +static struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state) +{ +	if (crtc_state->bigjoiner_slave) +		return crtc_state->bigjoiner_linked_crtc; +	else +		return to_intel_crtc(crtc_state->uapi.crtc); +} +  static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,  				    enum pipe pipe)  { @@ -454,80 +461,6 @@ static void assert_planes_disabled(struct intel_crtc *crtc)  		assert_plane_disabled(plane);  } -void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, -				    enum pipe pipe) -{ -	u32 val; -	bool enabled; - -	val = intel_de_read(dev_priv, PCH_TRANSCONF(pipe)); -	enabled = !!(val & TRANS_ENABLE); -	I915_STATE_WARN(enabled, -	     "transcoder assertion failed, should be off on pipe %c but is still active\n", -	     pipe_name(pipe)); -} - -static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, -				   enum pipe pipe, enum port port, -				   i915_reg_t dp_reg) -{ -	enum pipe port_pipe; -	bool state; - -	state = g4x_dp_port_enabled(dev_priv, dp_reg, port, &port_pipe); - -	I915_STATE_WARN(state && port_pipe == pipe, -			"PCH DP %c enabled on transcoder %c, should be disabled\n", -			port_name(port), pipe_name(pipe)); - -	I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B, -			"IBX PCH DP %c still using transcoder B\n", -			port_name(port)); -} - -static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, -				     enum pipe pipe, enum port port, -				     i915_reg_t hdmi_reg) -{ -	enum pipe port_pipe; -	bool state; - -	state = intel_sdvo_port_enabled(dev_priv, hdmi_reg, &port_pipe); - -	I915_STATE_WARN(state && port_pipe == pipe, -			"PCH HDMI %c enabled on transcoder %c, should be disabled\n", -			port_name(port), pipe_name(pipe)); - -	I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B, -			"IBX PCH HDMI %c still using transcoder B\n", -			port_name(port)); -} - -static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, -				      enum pipe pipe) -{ -	enum pipe port_pipe; - -	assert_pch_dp_disabled(dev_priv, pipe, PORT_B, PCH_DP_B); -	assert_pch_dp_disabled(dev_priv, pipe, PORT_C, PCH_DP_C); -	assert_pch_dp_disabled(dev_priv, pipe, PORT_D, PCH_DP_D); - -	I915_STATE_WARN(intel_crt_port_enabled(dev_priv, PCH_ADPA, &port_pipe) && -			port_pipe == pipe, -			"PCH VGA enabled on transcoder %c, should be disabled\n", -			pipe_name(pipe)); - -	I915_STATE_WARN(intel_lvds_port_enabled(dev_priv, PCH_LVDS, &port_pipe) && -			port_pipe == pipe, -			"PCH LVDS enabled on transcoder %c, should be disabled\n", -			pipe_name(pipe)); - -	/* PCH SDVOB multiplex with HDMIB */ -	assert_pch_hdmi_disabled(dev_priv, pipe, PORT_B, PCH_HDMIB); -	assert_pch_hdmi_disabled(dev_priv, pipe, PORT_C, PCH_HDMIC); -	assert_pch_hdmi_disabled(dev_priv, pipe, PORT_D, PCH_HDMID); -} -  void vlv_wait_port_ready(struct drm_i915_private *dev_priv,  			 struct intel_digital_port *dig_port,  			 unsigned int expected_mask) @@ -562,154 +495,6 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,  			 expected_mask);  } -static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) -{ -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); -	enum pipe pipe = crtc->pipe; -	i915_reg_t reg; -	u32 val, pipeconf_val; - -	/* Make sure PCH DPLL is enabled */ -	assert_shared_dpll_enabled(dev_priv, crtc_state->shared_dpll); - -	/* FDI must be feeding us bits for PCH ports */ -	assert_fdi_tx_enabled(dev_priv, pipe); -	assert_fdi_rx_enabled(dev_priv, pipe); - -	if (HAS_PCH_CPT(dev_priv)) { -		reg = TRANS_CHICKEN2(pipe); -		val = intel_de_read(dev_priv, reg); -		/* -		 * Workaround: Set the timing override bit -		 * before enabling the pch transcoder. -		 */ -		val |= TRANS_CHICKEN2_TIMING_OVERRIDE; -		/* Configure frame start delay to match the CPU */ -		val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK; -		val |= TRANS_CHICKEN2_FRAME_START_DELAY(dev_priv->framestart_delay - 1); -		intel_de_write(dev_priv, reg, val); -	} - -	reg = PCH_TRANSCONF(pipe); -	val = intel_de_read(dev_priv, reg); -	pipeconf_val = intel_de_read(dev_priv, PIPECONF(pipe)); - -	if (HAS_PCH_IBX(dev_priv)) { -		/* Configure frame start delay to match the CPU */ -		val &= ~TRANS_FRAME_START_DELAY_MASK; -		val |= TRANS_FRAME_START_DELAY(dev_priv->framestart_delay - 1); - -		/* -		 * Make the BPC in transcoder be consistent with -		 * that in pipeconf reg. For HDMI we must use 8bpc -		 * here for both 8bpc and 12bpc. -		 */ -		val &= ~PIPECONF_BPC_MASK; -		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) -			val |= PIPECONF_8BPC; -		else -			val |= pipeconf_val & PIPECONF_BPC_MASK; -	} - -	val &= ~TRANS_INTERLACE_MASK; -	if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) { -		if (HAS_PCH_IBX(dev_priv) && -		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) -			val |= TRANS_LEGACY_INTERLACED_ILK; -		else -			val |= TRANS_INTERLACED; -	} else { -		val |= TRANS_PROGRESSIVE; -	} - -	intel_de_write(dev_priv, reg, val | TRANS_ENABLE); -	if (intel_de_wait_for_set(dev_priv, reg, TRANS_STATE_ENABLE, 100)) -		drm_err(&dev_priv->drm, "failed to enable transcoder %c\n", -			pipe_name(pipe)); -} - -static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, -				      enum transcoder cpu_transcoder) -{ -	u32 val, pipeconf_val; - -	/* FDI must be feeding us bits for PCH ports */ -	assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder); -	assert_fdi_rx_enabled(dev_priv, PIPE_A); - -	val = intel_de_read(dev_priv, TRANS_CHICKEN2(PIPE_A)); -	/* Workaround: set timing override bit. */ -	val |= TRANS_CHICKEN2_TIMING_OVERRIDE; -	/* Configure frame start delay to match the CPU */ -	val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK; -	val |= TRANS_CHICKEN2_FRAME_START_DELAY(dev_priv->framestart_delay - 1); -	intel_de_write(dev_priv, TRANS_CHICKEN2(PIPE_A), val); - -	val = TRANS_ENABLE; -	pipeconf_val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder)); - -	if ((pipeconf_val & PIPECONF_INTERLACE_MASK_HSW) == -	    PIPECONF_INTERLACED_ILK) -		val |= TRANS_INTERLACED; -	else -		val |= TRANS_PROGRESSIVE; - -	intel_de_write(dev_priv, LPT_TRANSCONF, val); -	if (intel_de_wait_for_set(dev_priv, LPT_TRANSCONF, -				  TRANS_STATE_ENABLE, 100)) -		drm_err(&dev_priv->drm, "Failed to enable PCH transcoder\n"); -} - -static void ilk_disable_pch_transcoder(struct drm_i915_private *dev_priv, -				       enum pipe pipe) -{ -	i915_reg_t reg; -	u32 val; - -	/* FDI relies on the transcoder */ -	assert_fdi_tx_disabled(dev_priv, pipe); -	assert_fdi_rx_disabled(dev_priv, pipe); - -	/* Ports must be off as well */ -	assert_pch_ports_disabled(dev_priv, pipe); - -	reg = PCH_TRANSCONF(pipe); -	val = intel_de_read(dev_priv, reg); -	val &= ~TRANS_ENABLE; -	intel_de_write(dev_priv, reg, val); -	/* wait for PCH transcoder off, transcoder state */ -	if (intel_de_wait_for_clear(dev_priv, reg, TRANS_STATE_ENABLE, 50)) -		drm_err(&dev_priv->drm, "failed to disable transcoder %c\n", -			pipe_name(pipe)); - -	if (HAS_PCH_CPT(dev_priv)) { -		/* Workaround: Clear the timing override chicken bit again. */ -		reg = TRANS_CHICKEN2(pipe); -		val = intel_de_read(dev_priv, reg); -		val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE; -		intel_de_write(dev_priv, reg, val); -	} -} - -void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) -{ -	u32 val; - -	val = intel_de_read(dev_priv, LPT_TRANSCONF); -	val &= ~TRANS_ENABLE; -	intel_de_write(dev_priv, LPT_TRANSCONF, val); -	/* wait for PCH transcoder off, transcoder state */ -	if (intel_de_wait_for_clear(dev_priv, LPT_TRANSCONF, -				    TRANS_STATE_ENABLE, 50)) -		drm_err(&dev_priv->drm, "Failed to disable PCH transcoder\n"); - -	/* Workaround: clear timing override bit. */ -	val = intel_de_read(dev_priv, TRANS_CHICKEN2(PIPE_A)); -	val &= ~TRANS_CHICKEN2_TIMING_OVERRIDE; -	intel_de_write(dev_priv, TRANS_CHICKEN2(PIPE_A), val); -} -  enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)  {  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -823,14 +608,6 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)  		intel_wait_for_pipe_off(old_crtc_state);  } -bool -intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info, -				    u64 modifier) -{ -	return info->is_yuv && -	       info->num_planes == (is_ccs_modifier(modifier) ? 4 : 2); -} -  unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info)  {  	unsigned int size = 0; @@ -850,7 +627,11 @@ unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info  	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {  		unsigned int plane_size; -		plane_size = rem_info->plane[i].dst_stride * rem_info->plane[i].height; +		if (rem_info->plane[i].linear) +			plane_size = rem_info->plane[i].size; +		else +			plane_size = rem_info->plane[i].dst_stride * rem_info->plane[i].height; +  		if (plane_size == 0)  			continue; @@ -869,7 +650,7 @@ bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);  	return DISPLAY_VER(dev_priv) < 4 || -		(plane->has_fbc && +		(plane->fbc &&  		 plane_state->view.gtt.type == I915_GGTT_VIEW_NORMAL);  } @@ -885,7 +666,7 @@ u32 intel_fb_xy_to_linear(int x, int y,  {  	const struct drm_framebuffer *fb = state->hw.fb;  	unsigned int cpp = fb->format->cpp[color_plane]; -	unsigned int pitch = state->view.color_plane[color_plane].stride; +	unsigned int pitch = state->view.color_plane[color_plane].mapping_stride;  	return y * pitch + x * cpp;  } @@ -904,136 +685,6 @@ void intel_add_fb_offsets(int *x, int *y,  	*y += state->view.color_plane[color_plane].y;  } -/* - * From the Sky Lake PRM: - * "The Color Control Surface (CCS) contains the compression status of - *  the cache-line pairs. The compression state of the cache-line pair - *  is specified by 2 bits in the CCS. Each CCS cache-line represents - *  an area on the main surface of 16 x16 sets of 128 byte Y-tiled - *  cache-line-pairs. CCS is always Y tiled." - * - * Since cache line pairs refers to horizontally adjacent cache lines, - * each cache line in the CCS corresponds to an area of 32x16 cache - * lines on the main surface. Since each pixel is 4 bytes, this gives - * us a ratio of one byte in the CCS for each 8x16 pixels in the - * main surface. - */ -static const struct drm_format_info skl_ccs_formats[] = { -	{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, -	  .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, -	{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, -	  .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, }, -	{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, -	  .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, }, -	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, -	  .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, }, -}; - -/* - * Gen-12 compression uses 4 bits of CCS data for each cache line pair in the - * main surface. And each 64B CCS cache line represents an area of 4x1 Y-tiles - * in the main surface. With 4 byte pixels and each Y-tile having dimensions of - * 32x32 pixels, the ratio turns out to 1B in the CCS for every 2x32 pixels in - * the main surface. - */ -static const struct drm_format_info gen12_ccs_formats[] = { -	{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, -	  .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 1, .vsub = 1, }, -	{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, -	  .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 1, .vsub = 1, }, -	{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, -	  .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 1, .vsub = 1, .has_alpha = true }, -	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, -	  .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 1, .vsub = 1, .has_alpha = true }, -	{ .format = DRM_FORMAT_YUYV, .num_planes = 2, -	  .char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 2, .vsub = 1, .is_yuv = true }, -	{ .format = DRM_FORMAT_YVYU, .num_planes = 2, -	  .char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 2, .vsub = 1, .is_yuv = true }, -	{ .format = DRM_FORMAT_UYVY, .num_planes = 2, -	  .char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 2, .vsub = 1, .is_yuv = true }, -	{ .format = DRM_FORMAT_VYUY, .num_planes = 2, -	  .char_per_block = { 2, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 2, .vsub = 1, .is_yuv = true }, -	{ .format = DRM_FORMAT_XYUV8888, .num_planes = 2, -	  .char_per_block = { 4, 1 }, .block_w = { 1, 2 }, .block_h = { 1, 1 }, -	  .hsub = 1, .vsub = 1, .is_yuv = true }, -	{ .format = DRM_FORMAT_NV12, .num_planes = 4, -	  .char_per_block = { 1, 2, 1, 1 }, .block_w = { 1, 1, 4, 4 }, .block_h = { 1, 1, 1, 1 }, -	  .hsub = 2, .vsub = 2, .is_yuv = true }, -	{ .format = DRM_FORMAT_P010, .num_planes = 4, -	  .char_per_block = { 2, 4, 1, 1 }, .block_w = { 1, 1, 2, 2 }, .block_h = { 1, 1, 1, 1 }, -	  .hsub = 2, .vsub = 2, .is_yuv = true }, -	{ .format = DRM_FORMAT_P012, .num_planes = 4, -	  .char_per_block = { 2, 4, 1, 1 }, .block_w = { 1, 1, 2, 2 }, .block_h = { 1, 1, 1, 1 }, -	  .hsub = 2, .vsub = 2, .is_yuv = true }, -	{ .format = DRM_FORMAT_P016, .num_planes = 4, -	  .char_per_block = { 2, 4, 1, 1 }, .block_w = { 1, 1, 2, 2 }, .block_h = { 1, 1, 1, 1 }, -	  .hsub = 2, .vsub = 2, .is_yuv = true }, -}; - -/* - * Same as gen12_ccs_formats[] above, but with additional surface used - * to pass Clear Color information in plane 2 with 64 bits of data. - */ -static const struct drm_format_info gen12_ccs_cc_formats[] = { -	{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3, -	  .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, -	  .hsub = 1, .vsub = 1, }, -	{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3, -	  .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, -	  .hsub = 1, .vsub = 1, }, -	{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3, -	  .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, -	  .hsub = 1, .vsub = 1, .has_alpha = true }, -	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3, -	  .char_per_block = { 4, 1, 0 }, .block_w = { 1, 2, 2 }, .block_h = { 1, 1, 1 }, -	  .hsub = 1, .vsub = 1, .has_alpha = true }, -}; - -static const struct drm_format_info * -lookup_format_info(const struct drm_format_info formats[], -		   int num_formats, u32 format) -{ -	int i; - -	for (i = 0; i < num_formats; i++) { -		if (formats[i].format == format) -			return &formats[i]; -	} - -	return NULL; -} - -static const struct drm_format_info * -intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd) -{ -	switch (cmd->modifier[0]) { -	case I915_FORMAT_MOD_Y_TILED_CCS: -	case I915_FORMAT_MOD_Yf_TILED_CCS: -		return lookup_format_info(skl_ccs_formats, -					  ARRAY_SIZE(skl_ccs_formats), -					  cmd->pixel_format); -	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: -	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: -		return lookup_format_info(gen12_ccs_formats, -					  ARRAY_SIZE(gen12_ccs_formats), -					  cmd->pixel_format); -	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: -		return lookup_format_info(gen12_ccs_cc_formats, -					  ARRAY_SIZE(gen12_ccs_cc_formats), -					  cmd->pixel_format); -	default: -		return NULL; -	} -} -  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,  			      u32 pixel_format, u64 modifier)  { @@ -1048,7 +699,7 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,  	 * the highest stride limits of them all,  	 * if in case pipe A is disabled, use the first pipe from pipe_mask.  	 */ -	crtc = intel_get_first_crtc(dev_priv); +	crtc = intel_first_crtc(dev_priv);  	if (!crtc)  		return 0; @@ -1126,7 +777,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc,  	 */  	if (HAS_GMCH(dev_priv) &&  	    intel_set_memory_cxsr(dev_priv, false)) -		intel_wait_for_vblank(dev_priv, crtc->pipe); +		intel_crtc_wait_for_next_vblank(crtc);  	/*  	 * Gen2 reports pipe underruns whenever all planes are disabled. @@ -1135,8 +786,8 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc,  	if (DISPLAY_VER(dev_priv) == 2 && !crtc_state->active_planes)  		intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); -	intel_disable_plane(plane, crtc_state); -	intel_wait_for_vblank(dev_priv, crtc->pipe); +	intel_plane_disable_arm(plane, crtc_state); +	intel_crtc_wait_for_next_vblank(crtc);  }  unsigned int @@ -1192,7 +843,7 @@ __intel_display_resume(struct drm_device *dev,  static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)  {  	return (INTEL_INFO(dev_priv)->gpu_reset_clobbers_display && -		intel_has_gpu_reset(&dev_priv->gt)); +		intel_has_gpu_reset(to_gt(dev_priv)));  }  void intel_display_prepare_reset(struct drm_i915_private *dev_priv) @@ -1211,14 +862,14 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)  		return;  	/* We have a modeset vs reset deadlock, defensively unbreak it. */ -	set_bit(I915_RESET_MODESET, &dev_priv->gt.reset.flags); +	set_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags);  	smp_mb__after_atomic(); -	wake_up_bit(&dev_priv->gt.reset.flags, I915_RESET_MODESET); +	wake_up_bit(&to_gt(dev_priv)->reset.flags, I915_RESET_MODESET);  	if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) {  		drm_dbg_kms(&dev_priv->drm,  			    "Modeset potentially stuck, unbreaking through wedging\n"); -		intel_gt_set_wedged(&dev_priv->gt); +		intel_gt_set_wedged(to_gt(dev_priv));  	}  	/* @@ -1269,7 +920,7 @@ void intel_display_finish_reset(struct drm_i915_private *dev_priv)  		return;  	/* reset doesn't touch the display */ -	if (!test_bit(I915_RESET_MODESET, &dev_priv->gt.reset.flags)) +	if (!test_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags))  		return;  	state = fetch_and_zero(&dev_priv->modeset_restore_state); @@ -1307,27 +958,7 @@ unlock:  	drm_modeset_acquire_fini(ctx);  	mutex_unlock(&dev->mode_config.mutex); -	clear_bit_unlock(I915_RESET_MODESET, &dev_priv->gt.reset.flags); -} - -static bool underrun_recovery_supported(const struct intel_crtc_state *crtc_state) -{ -	if (crtc_state->pch_pfit.enabled && -	    (crtc_state->pipe_src_w > drm_rect_width(&crtc_state->pch_pfit.dst) || -	     crtc_state->pipe_src_h > drm_rect_height(&crtc_state->pch_pfit.dst) || -	     crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)) -		return false; - -	if (crtc_state->dsc.compression_enable) -		return false; - -	if (crtc_state->has_psr2) -		return false; - -	if (crtc_state->splitter.enable) -		return false; - -	return true; +	clear_bit_unlock(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags);  }  static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state) @@ -1353,19 +984,18 @@ static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state)  	 */  	tmp |= PIXEL_ROUNDING_TRUNC_FB_PASSTHRU; -	if (IS_DG2(dev_priv)) { -		/* -		 * Underrun recovery must always be disabled on DG2.  However -		 * the chicken bit meaning is inverted compared to other -		 * platforms. -		 */ +	/* +	 * Underrun recovery must always be disabled on display 13+. +	 * DG2 chicken bit meaning is inverted compared to other platforms. +	 */ +	if (IS_DG2(dev_priv))  		tmp &= ~UNDERRUN_RECOVERY_ENABLE_DG2; -	} else if (DISPLAY_VER(dev_priv) >= 13) { -		if (underrun_recovery_supported(crtc_state)) -			tmp &= ~UNDERRUN_RECOVERY_DISABLE_ADLP; -		else -			tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP; -	} +	else if (DISPLAY_VER(dev_priv) >= 13) +		tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP; + +	/* Wa_14010547955:dg2 */ +	if (IS_DG2_DISPLAY_STEP(dev_priv, STEP_B0, STEP_FOREVER)) +		tmp |= DG2_RENDER_CCSTAG_4_3_EN;  	intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp);  } @@ -1387,7 +1017,7 @@ bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)  		if (cleanup_done)  			continue; -		drm_crtc_wait_one_vblank(crtc); +		intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc));  		return true;  	} @@ -1395,158 +1025,6 @@ bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)  	return false;  } -void lpt_disable_iclkip(struct drm_i915_private *dev_priv) -{ -	u32 temp; - -	intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_GATE); - -	mutex_lock(&dev_priv->sb_lock); - -	temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK); -	temp |= SBI_SSCCTL_DISABLE; -	intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK); - -	mutex_unlock(&dev_priv->sb_lock); -} - -/* Program iCLKIP clock to the desired frequency */ -static void lpt_program_iclkip(const struct intel_crtc_state *crtc_state) -{ -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); -	int clock = crtc_state->hw.adjusted_mode.crtc_clock; -	u32 divsel, phaseinc, auxdiv, phasedir = 0; -	u32 temp; - -	lpt_disable_iclkip(dev_priv); - -	/* The iCLK virtual clock root frequency is in MHz, -	 * but the adjusted_mode->crtc_clock in in KHz. To get the -	 * divisors, it is necessary to divide one by another, so we -	 * convert the virtual clock precision to KHz here for higher -	 * precision. -	 */ -	for (auxdiv = 0; auxdiv < 2; auxdiv++) { -		u32 iclk_virtual_root_freq = 172800 * 1000; -		u32 iclk_pi_range = 64; -		u32 desired_divisor; - -		desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq, -						    clock << auxdiv); -		divsel = (desired_divisor / iclk_pi_range) - 2; -		phaseinc = desired_divisor % iclk_pi_range; - -		/* -		 * Near 20MHz is a corner case which is -		 * out of range for the 7-bit divisor -		 */ -		if (divsel <= 0x7f) -			break; -	} - -	/* This should not happen with any sane values */ -	drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIVSEL(divsel) & -		    ~SBI_SSCDIVINTPHASE_DIVSEL_MASK); -	drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIR(phasedir) & -		    ~SBI_SSCDIVINTPHASE_INCVAL_MASK); - -	drm_dbg_kms(&dev_priv->drm, -		    "iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n", -		    clock, auxdiv, divsel, phasedir, phaseinc); - -	mutex_lock(&dev_priv->sb_lock); - -	/* Program SSCDIVINTPHASE6 */ -	temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK); -	temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK; -	temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel); -	temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK; -	temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc); -	temp |= SBI_SSCDIVINTPHASE_DIR(phasedir); -	temp |= SBI_SSCDIVINTPHASE_PROPAGATE; -	intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK); - -	/* Program SSCAUXDIV */ -	temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK); -	temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1); -	temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv); -	intel_sbi_write(dev_priv, SBI_SSCAUXDIV6, temp, SBI_ICLK); - -	/* Enable modulator and associated divider */ -	temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK); -	temp &= ~SBI_SSCCTL_DISABLE; -	intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK); - -	mutex_unlock(&dev_priv->sb_lock); - -	/* Wait for initialization time */ -	udelay(24); - -	intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_UNGATE); -} - -int lpt_get_iclkip(struct drm_i915_private *dev_priv) -{ -	u32 divsel, phaseinc, auxdiv; -	u32 iclk_virtual_root_freq = 172800 * 1000; -	u32 iclk_pi_range = 64; -	u32 desired_divisor; -	u32 temp; - -	if ((intel_de_read(dev_priv, PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0) -		return 0; - -	mutex_lock(&dev_priv->sb_lock); - -	temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK); -	if (temp & SBI_SSCCTL_DISABLE) { -		mutex_unlock(&dev_priv->sb_lock); -		return 0; -	} - -	temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK); -	divsel = (temp & SBI_SSCDIVINTPHASE_DIVSEL_MASK) >> -		SBI_SSCDIVINTPHASE_DIVSEL_SHIFT; -	phaseinc = (temp & SBI_SSCDIVINTPHASE_INCVAL_MASK) >> -		SBI_SSCDIVINTPHASE_INCVAL_SHIFT; - -	temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK); -	auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >> -		SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT; - -	mutex_unlock(&dev_priv->sb_lock); - -	desired_divisor = (divsel + 2) * iclk_pi_range + phaseinc; - -	return DIV_ROUND_CLOSEST(iclk_virtual_root_freq, -				 desired_divisor << auxdiv); -} - -static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state, -					   enum pipe pch_transcoder) -{ -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); -	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - -	intel_de_write(dev_priv, PCH_TRANS_HTOTAL(pch_transcoder), -		       intel_de_read(dev_priv, HTOTAL(cpu_transcoder))); -	intel_de_write(dev_priv, PCH_TRANS_HBLANK(pch_transcoder), -		       intel_de_read(dev_priv, HBLANK(cpu_transcoder))); -	intel_de_write(dev_priv, PCH_TRANS_HSYNC(pch_transcoder), -		       intel_de_read(dev_priv, HSYNC(cpu_transcoder))); - -	intel_de_write(dev_priv, PCH_TRANS_VTOTAL(pch_transcoder), -		       intel_de_read(dev_priv, VTOTAL(cpu_transcoder))); -	intel_de_write(dev_priv, PCH_TRANS_VBLANK(pch_transcoder), -		       intel_de_read(dev_priv, VBLANK(cpu_transcoder))); -	intel_de_write(dev_priv, PCH_TRANS_VSYNC(pch_transcoder), -		       intel_de_read(dev_priv, VSYNC(cpu_transcoder))); -	intel_de_write(dev_priv, PCH_TRANS_VSYNCSHIFT(pch_transcoder), -		       intel_de_read(dev_priv, VSYNCSHIFT(cpu_transcoder))); -} -  /*   * Finds the encoder associated with the given CRTC. This can only be   * used when we know that the CRTC isn't feeding multiple encoders! @@ -1555,15 +1033,17 @@ struct intel_encoder *  intel_get_crtc_new_encoder(const struct intel_atomic_state *state,  			   const struct intel_crtc_state *crtc_state)  { -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);  	const struct drm_connector_state *connector_state;  	const struct drm_connector *connector;  	struct intel_encoder *encoder = NULL; +	struct intel_crtc *master_crtc;  	int num_encoders = 0;  	int i; +	master_crtc = intel_master_crtc(crtc_state); +  	for_each_new_connector_in_state(&state->base, connector, connector_state, i) { -		if (connector_state->crtc != &crtc->base) +		if (connector_state->crtc != &master_crtc->base)  			continue;  		encoder = to_intel_encoder(connector_state->best_encoder); @@ -1572,111 +1052,11 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,  	drm_WARN(encoder->base.dev, num_encoders != 1,  		 "%d encoders for pipe %c\n", -		 num_encoders, pipe_name(crtc->pipe)); +		 num_encoders, pipe_name(master_crtc->pipe));  	return encoder;  } -/* - * Enable PCH resources required for PCH ports: - *   - PCH PLLs - *   - FDI training & RX/TX - *   - update transcoder timings - *   - DP transcoding bits - *   - transcoder - */ -static void ilk_pch_enable(const struct intel_atomic_state *state, -			   const struct intel_crtc_state *crtc_state) -{ -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -	struct drm_device *dev = crtc->base.dev; -	struct drm_i915_private *dev_priv = to_i915(dev); -	enum pipe pipe = crtc->pipe; -	u32 temp; - -	assert_pch_transcoder_disabled(dev_priv, pipe); - -	/* For PCH output, training FDI link */ -	intel_fdi_link_train(crtc, crtc_state); - -	/* We need to program the right clock selection before writing the pixel -	 * mutliplier into the DPLL. */ -	if (HAS_PCH_CPT(dev_priv)) { -		u32 sel; - -		temp = intel_de_read(dev_priv, PCH_DPLL_SEL); -		temp |= TRANS_DPLL_ENABLE(pipe); -		sel = TRANS_DPLLB_SEL(pipe); -		if (crtc_state->shared_dpll == -		    intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B)) -			temp |= sel; -		else -			temp &= ~sel; -		intel_de_write(dev_priv, PCH_DPLL_SEL, temp); -	} - -	/* XXX: pch pll's can be enabled any time before we enable the PCH -	 * transcoder, and we actually should do this to not upset any PCH -	 * transcoder that already use the clock when we share it. -	 * -	 * Note that enable_shared_dpll tries to do the right thing, but -	 * get_shared_dpll unconditionally resets the pll - we need that to have -	 * the right LVDS enable sequence. */ -	intel_enable_shared_dpll(crtc_state); - -	/* set transcoder timing, panel must allow it */ -	assert_pps_unlocked(dev_priv, pipe); -	ilk_pch_transcoder_set_timings(crtc_state, pipe); - -	intel_fdi_normal_train(crtc); - -	/* For PCH DP, enable TRANS_DP_CTL */ -	if (HAS_PCH_CPT(dev_priv) && -	    intel_crtc_has_dp_encoder(crtc_state)) { -		const struct drm_display_mode *adjusted_mode = -			&crtc_state->hw.adjusted_mode; -		u32 bpc = (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5; -		i915_reg_t reg = TRANS_DP_CTL(pipe); -		enum port port; - -		temp = intel_de_read(dev_priv, reg); -		temp &= ~(TRANS_DP_PORT_SEL_MASK | -			  TRANS_DP_SYNC_MASK | -			  TRANS_DP_BPC_MASK); -		temp |= TRANS_DP_OUTPUT_ENABLE; -		temp |= bpc << 9; /* same format but at 11:9 */ - -		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) -			temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; -		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) -			temp |= TRANS_DP_VSYNC_ACTIVE_HIGH; - -		port = intel_get_crtc_new_encoder(state, crtc_state)->port; -		drm_WARN_ON(dev, port < PORT_B || port > PORT_D); -		temp |= TRANS_DP_PORT_SEL(port); - -		intel_de_write(dev_priv, reg, temp); -	} - -	ilk_enable_pch_transcoder(crtc_state); -} - -void lpt_pch_enable(const struct intel_crtc_state *crtc_state) -{ -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); -	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - -	assert_pch_transcoder_disabled(dev_priv, PIPE_A); - -	lpt_program_iclkip(crtc_state); - -	/* Set transcoder timing. */ -	ilk_pch_transcoder_set_timings(crtc_state, PIPE_A); - -	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder); -} -  static void cpt_verify_modeset(struct drm_i915_private *dev_priv,  			       enum pipe pipe)  { @@ -1784,7 +1164,7 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)  	}  	/* We need to wait for a vblank before we can disable the plane. */ -	intel_wait_for_vblank(dev_priv, crtc->pipe); +	intel_crtc_wait_for_next_vblank(crtc);  }  static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc) @@ -1919,7 +1299,7 @@ static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state)  {  	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); -	return crtc_state->uapi.async_flip && intel_vtd_active() && +	return crtc_state->uapi.async_flip && intel_vtd_active(i915) &&  		(DISPLAY_VER(i915) == 9 || IS_BROADWELL(i915) || IS_HASWELL(i915));  } @@ -2015,7 +1395,6 @@ static void intel_crtc_disable_flip_done(struct intel_atomic_state *state,  static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,  					     struct intel_crtc *crtc)  { -	struct drm_i915_private *i915 = to_i915(state->base.dev);  	const struct intel_crtc_state *old_crtc_state =  		intel_atomic_get_old_crtc_state(state, crtc);  	const struct intel_crtc_state *new_crtc_state = @@ -2041,7 +1420,7 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,  	}  	if (need_vbl_wait) -		intel_wait_for_vblank(i915, crtc->pipe); +		intel_crtc_wait_for_next_vblank(crtc);  }  static void intel_pre_plane_update(struct intel_atomic_state *state, @@ -2054,11 +1433,13 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,  		intel_atomic_get_new_crtc_state(state, crtc);  	enum pipe pipe = crtc->pipe; +	intel_psr_pre_plane_update(state, crtc); +  	if (hsw_pre_update_disable_ips(old_crtc_state, new_crtc_state))  		hsw_disable_ips(old_crtc_state);  	if (intel_fbc_pre_update(state, crtc)) -		intel_wait_for_vblank(dev_priv, pipe); +		intel_crtc_wait_for_next_vblank(crtc);  	if (!needs_async_flip_vtd_wa(old_crtc_state) &&  	    needs_async_flip_vtd_wa(new_crtc_state)) @@ -2090,7 +1471,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,  	 */  	if (HAS_GMCH(dev_priv) && old_crtc_state->hw.active &&  	    new_crtc_state->disable_cxsr && intel_set_memory_cxsr(dev_priv, false)) -		intel_wait_for_vblank(dev_priv, pipe); +		intel_crtc_wait_for_next_vblank(crtc);  	/*  	 * IVB workaround: must disable low power watermarks for at least @@ -2101,7 +1482,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,  	 */  	if (old_crtc_state->hw.active &&  	    new_crtc_state->disable_lp_wm && ilk_disable_lp_wm(dev_priv)) -		intel_wait_for_vblank(dev_priv, pipe); +		intel_crtc_wait_for_next_vblank(crtc);  	/*  	 * If we're doing a modeset we don't need to do any @@ -2165,7 +1546,7 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state,  		    !(update_mask & BIT(plane->id)))  			continue; -		intel_disable_plane(plane, new_crtc_state); +		intel_plane_disable_arm(plane, new_crtc_state);  		if (old_plane_state->uapi.visible)  			fb_bits |= plane->frontbuffer_bit; @@ -2199,10 +1580,30 @@ intel_connector_primary_encoder(struct intel_connector *connector)  static void intel_encoders_update_prepare(struct intel_atomic_state *state)  { +	struct drm_i915_private *i915 = to_i915(state->base.dev); +	struct intel_crtc_state *new_crtc_state, *old_crtc_state; +	struct intel_crtc *crtc;  	struct drm_connector_state *new_conn_state;  	struct drm_connector *connector;  	int i; +	/* +	 * Make sure the DPLL state is up-to-date for fastset TypeC ports after non-blocking commits. +	 * TODO: Update the DPLL state for all cases in the encoder->update_prepare() hook. +	 */ +	if (i915->dpll.mgr) { +		for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { +			if (intel_crtc_needs_modeset(new_crtc_state)) +				continue; + +			new_crtc_state->shared_dpll = old_crtc_state->shared_dpll; +			new_crtc_state->dpll_hw_state = old_crtc_state->dpll_hw_state; +		} +	} + +	if (!state->modeset) +		return; +  	for_each_new_connector_in_state(&state->base, connector, new_conn_state,  					i) {  		struct intel_connector *intel_connector; @@ -2229,6 +1630,9 @@ static void intel_encoders_update_complete(struct intel_atomic_state *state)  	struct drm_connector *connector;  	int i; +	if (!state->modeset) +		return; +  	for_each_new_connector_in_state(&state->base, connector, new_conn_state,  					i) {  		struct intel_connector *intel_connector; @@ -2316,28 +1720,6 @@ static void intel_encoders_enable(struct intel_atomic_state *state,  	}  } -static void intel_encoders_pre_disable(struct intel_atomic_state *state, -				       struct intel_crtc *crtc) -{ -	const struct intel_crtc_state *old_crtc_state = -		intel_atomic_get_old_crtc_state(state, crtc); -	const struct drm_connector_state *old_conn_state; -	struct drm_connector *conn; -	int i; - -	for_each_old_connector_in_state(&state->base, conn, old_conn_state, i) { -		struct intel_encoder *encoder = -			to_intel_encoder(old_conn_state->best_encoder); - -		if (old_conn_state->crtc != &crtc->base) -			continue; - -		if (encoder->pre_disable) -			encoder->pre_disable(state, encoder, old_crtc_state, -					     old_conn_state); -	} -} -  static void intel_encoders_disable(struct intel_atomic_state *state,  				   struct intel_crtc *crtc)  { @@ -2432,7 +1814,7 @@ static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_stat  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);  	struct intel_plane *plane = to_intel_plane(crtc->base.primary); -	plane->disable_plane(plane, crtc_state); +	plane->disable_arm(plane, crtc_state);  }  static void ilk_crtc_enable(struct intel_atomic_state *state, @@ -2500,7 +1882,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,  	intel_enable_transcoder(new_crtc_state);  	if (new_crtc_state->has_pch_encoder) -		ilk_pch_enable(state, new_crtc_state); +		ilk_pch_enable(state, crtc);  	intel_crtc_vblank_on(new_crtc_state); @@ -2516,8 +1898,8 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,  	 * in case there are more corner cases we don't know about.  	 */  	if (new_crtc_state->has_pch_encoder) { -		intel_wait_for_vblank(dev_priv, pipe); -		intel_wait_for_vblank(dev_priv, pipe); +		intel_crtc_wait_for_next_vblank(crtc); +		intel_crtc_wait_for_next_vblank(crtc);  	}  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);  	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); @@ -2592,42 +1974,39 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)  static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,  					 const struct intel_crtc_state *crtc_state)  { -	struct intel_crtc *master = to_intel_crtc(crtc_state->uapi.crtc); -	struct drm_i915_private *dev_priv = to_i915(master->base.dev); +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);  	struct intel_crtc_state *master_crtc_state; +	struct intel_crtc *master_crtc;  	struct drm_connector_state *conn_state;  	struct drm_connector *conn;  	struct intel_encoder *encoder = NULL;  	int i; -	if (crtc_state->bigjoiner_slave) -		master = crtc_state->bigjoiner_linked_crtc; - -	master_crtc_state = intel_atomic_get_new_crtc_state(state, master); +	master_crtc = intel_master_crtc(crtc_state); +	master_crtc_state = intel_atomic_get_new_crtc_state(state, master_crtc);  	for_each_new_connector_in_state(&state->base, conn, conn_state, i) { -		if (conn_state->crtc != &master->base) +		if (conn_state->crtc != &master_crtc->base)  			continue;  		encoder = to_intel_encoder(conn_state->best_encoder);  		break;  	} -	if (!crtc_state->bigjoiner_slave) { -		/* need to enable VDSC, which we skipped in pre-enable */ -		intel_dsc_enable(encoder, crtc_state); -	} else { -		/* -		 * Enable sequence steps 1-7 on bigjoiner master -		 */ -		intel_encoders_pre_pll_enable(state, master); -		if (master_crtc_state->shared_dpll) -			intel_enable_shared_dpll(master_crtc_state); -		intel_encoders_pre_enable(state, master); +	/* +	 * Enable sequence steps 1-7 on bigjoiner master +	 */ +	if (crtc_state->bigjoiner_slave) +		intel_encoders_pre_pll_enable(state, master_crtc); -		/* and DSC on slave */ -		intel_dsc_enable(NULL, crtc_state); -	} +	if (crtc_state->shared_dpll) +		intel_enable_shared_dpll(crtc_state); + +	if (crtc_state->bigjoiner_slave) +		intel_encoders_pre_enable(state, master_crtc); + +	/* need to enable VDSC, which we skipped in pre-enable */ +	intel_dsc_enable(crtc_state);  	if (DISPLAY_VER(dev_priv) >= 13)  		intel_uncompressed_joiner_enable(crtc_state); @@ -2720,7 +2099,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,  	intel_encoders_enable(state, crtc);  	if (psl_clkgate_wa) { -		intel_wait_for_vblank(dev_priv, pipe); +		intel_crtc_wait_for_next_vblank(crtc);  		glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);  	} @@ -2728,8 +2107,12 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,  	 * to change the workaround. */  	hsw_workaround_pipe = new_crtc_state->hsw_workaround_pipe;  	if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) { -		intel_wait_for_vblank(dev_priv, hsw_workaround_pipe); -		intel_wait_for_vblank(dev_priv, hsw_workaround_pipe); +		struct intel_crtc *wa_crtc; + +		wa_crtc = intel_crtc_for_pipe(dev_priv, hsw_workaround_pipe); + +		intel_crtc_wait_for_next_vblank(wa_crtc); +		intel_crtc_wait_for_next_vblank(wa_crtc);  	}  } @@ -2774,33 +2157,12 @@ static void ilk_crtc_disable(struct intel_atomic_state *state,  	ilk_pfit_disable(old_crtc_state);  	if (old_crtc_state->has_pch_encoder) -		ilk_fdi_disable(crtc); +		ilk_pch_disable(state, crtc);  	intel_encoders_post_disable(state, crtc); -	if (old_crtc_state->has_pch_encoder) { -		ilk_disable_pch_transcoder(dev_priv, pipe); - -		if (HAS_PCH_CPT(dev_priv)) { -			i915_reg_t reg; -			u32 temp; - -			/* disable TRANS_DP_CTL */ -			reg = TRANS_DP_CTL(pipe); -			temp = intel_de_read(dev_priv, reg); -			temp &= ~(TRANS_DP_OUTPUT_ENABLE | -				  TRANS_DP_PORT_SEL_MASK); -			temp |= TRANS_DP_PORT_SEL_NONE; -			intel_de_write(dev_priv, reg, temp); - -			/* disable DPLL_SEL */ -			temp = intel_de_read(dev_priv, PCH_DPLL_SEL); -			temp &= ~(TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe)); -			intel_de_write(dev_priv, PCH_DPLL_SEL, temp); -		} - -		ilk_fdi_pll_disable(crtc); -	} +	if (old_crtc_state->has_pch_encoder) +		ilk_pch_post_disable(state, crtc);  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);  	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); @@ -2809,12 +2171,17 @@ static void ilk_crtc_disable(struct intel_atomic_state *state,  static void hsw_crtc_disable(struct intel_atomic_state *state,  			     struct intel_crtc *crtc)  { +	const struct intel_crtc_state *old_crtc_state = +		intel_atomic_get_old_crtc_state(state, crtc); +  	/*  	 * FIXME collapse everything to one hook.  	 * Need care with mst->ddi interactions.  	 */ -	intel_encoders_disable(state, crtc); -	intel_encoders_post_disable(state, crtc); +	if (!old_crtc_state->bigjoiner_slave) { +		intel_encoders_disable(state, crtc); +		intel_encoders_post_disable(state, crtc); +	}  }  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) @@ -3171,7 +2538,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,  	/* prevents spurious underruns */  	if (DISPLAY_VER(dev_priv) == 2) -		intel_wait_for_vblank(dev_priv, pipe); +		intel_crtc_wait_for_next_vblank(crtc);  }  static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state) @@ -3202,7 +2569,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state,  	 * wait for planes to fully turn off before disabling the pipe.  	 */  	if (DISPLAY_VER(dev_priv) == 2) -		intel_wait_for_vblank(dev_priv, pipe); +		intel_crtc_wait_for_next_vblank(crtc);  	intel_encoders_disable(state, crtc); @@ -4306,414 +3673,6 @@ out:  	return ret;  } -static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) -{ -	struct intel_encoder *encoder; -	int i; -	u32 val, final; -	bool has_lvds = false; -	bool has_cpu_edp = false; -	bool has_panel = false; -	bool has_ck505 = false; -	bool can_ssc = false; -	bool using_ssc_source = false; - -	/* We need to take the global config into account */ -	for_each_intel_encoder(&dev_priv->drm, encoder) { -		switch (encoder->type) { -		case INTEL_OUTPUT_LVDS: -			has_panel = true; -			has_lvds = true; -			break; -		case INTEL_OUTPUT_EDP: -			has_panel = true; -			if (encoder->port == PORT_A) -				has_cpu_edp = true; -			break; -		default: -			break; -		} -	} - -	if (HAS_PCH_IBX(dev_priv)) { -		has_ck505 = dev_priv->vbt.display_clock_mode; -		can_ssc = has_ck505; -	} else { -		has_ck505 = false; -		can_ssc = true; -	} - -	/* Check if any DPLLs are using the SSC source */ -	for (i = 0; i < dev_priv->dpll.num_shared_dpll; i++) { -		u32 temp = intel_de_read(dev_priv, PCH_DPLL(i)); - -		if (!(temp & DPLL_VCO_ENABLE)) -			continue; - -		if ((temp & PLL_REF_INPUT_MASK) == -		    PLLB_REF_INPUT_SPREADSPECTRUMIN) { -			using_ssc_source = true; -			break; -		} -	} - -	drm_dbg_kms(&dev_priv->drm, -		    "has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n", -		    has_panel, has_lvds, has_ck505, using_ssc_source); - -	/* Ironlake: try to setup display ref clock before DPLL -	 * enabling. This is only under driver's control after -	 * PCH B stepping, previous chipset stepping should be -	 * ignoring this setting. -	 */ -	val = intel_de_read(dev_priv, PCH_DREF_CONTROL); - -	/* As we must carefully and slowly disable/enable each source in turn, -	 * compute the final state we want first and check if we need to -	 * make any changes at all. -	 */ -	final = val; -	final &= ~DREF_NONSPREAD_SOURCE_MASK; -	if (has_ck505) -		final |= DREF_NONSPREAD_CK505_ENABLE; -	else -		final |= DREF_NONSPREAD_SOURCE_ENABLE; - -	final &= ~DREF_SSC_SOURCE_MASK; -	final &= ~DREF_CPU_SOURCE_OUTPUT_MASK; -	final &= ~DREF_SSC1_ENABLE; - -	if (has_panel) { -		final |= DREF_SSC_SOURCE_ENABLE; - -		if (intel_panel_use_ssc(dev_priv) && can_ssc) -			final |= DREF_SSC1_ENABLE; - -		if (has_cpu_edp) { -			if (intel_panel_use_ssc(dev_priv) && can_ssc) -				final |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; -			else -				final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; -		} else -			final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; -	} else if (using_ssc_source) { -		final |= DREF_SSC_SOURCE_ENABLE; -		final |= DREF_SSC1_ENABLE; -	} - -	if (final == val) -		return; - -	/* Always enable nonspread source */ -	val &= ~DREF_NONSPREAD_SOURCE_MASK; - -	if (has_ck505) -		val |= DREF_NONSPREAD_CK505_ENABLE; -	else -		val |= DREF_NONSPREAD_SOURCE_ENABLE; - -	if (has_panel) { -		val &= ~DREF_SSC_SOURCE_MASK; -		val |= DREF_SSC_SOURCE_ENABLE; - -		/* SSC must be turned on before enabling the CPU output  */ -		if (intel_panel_use_ssc(dev_priv) && can_ssc) { -			drm_dbg_kms(&dev_priv->drm, "Using SSC on panel\n"); -			val |= DREF_SSC1_ENABLE; -		} else -			val &= ~DREF_SSC1_ENABLE; - -		/* Get SSC going before enabling the outputs */ -		intel_de_write(dev_priv, PCH_DREF_CONTROL, val); -		intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); -		udelay(200); - -		val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; - -		/* Enable CPU source on CPU attached eDP */ -		if (has_cpu_edp) { -			if (intel_panel_use_ssc(dev_priv) && can_ssc) { -				drm_dbg_kms(&dev_priv->drm, -					    "Using SSC on eDP\n"); -				val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; -			} else -				val |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; -		} else -			val |= DREF_CPU_SOURCE_OUTPUT_DISABLE; - -		intel_de_write(dev_priv, PCH_DREF_CONTROL, val); -		intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); -		udelay(200); -	} else { -		drm_dbg_kms(&dev_priv->drm, "Disabling CPU source output\n"); - -		val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; - -		/* Turn off CPU output */ -		val |= DREF_CPU_SOURCE_OUTPUT_DISABLE; - -		intel_de_write(dev_priv, PCH_DREF_CONTROL, val); -		intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); -		udelay(200); - -		if (!using_ssc_source) { -			drm_dbg_kms(&dev_priv->drm, "Disabling SSC source\n"); - -			/* Turn off the SSC source */ -			val &= ~DREF_SSC_SOURCE_MASK; -			val |= DREF_SSC_SOURCE_DISABLE; - -			/* Turn off SSC1 */ -			val &= ~DREF_SSC1_ENABLE; - -			intel_de_write(dev_priv, PCH_DREF_CONTROL, val); -			intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); -			udelay(200); -		} -	} - -	BUG_ON(val != final); -} - -/* Implements 3 different sequences from BSpec chapter "Display iCLK - * Programming" based on the parameters passed: - * - Sequence to enable CLKOUT_DP - * - Sequence to enable CLKOUT_DP without spread - * - Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O - */ -static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv, -				 bool with_spread, bool with_fdi) -{ -	u32 reg, tmp; - -	if (drm_WARN(&dev_priv->drm, with_fdi && !with_spread, -		     "FDI requires downspread\n")) -		with_spread = true; -	if (drm_WARN(&dev_priv->drm, HAS_PCH_LPT_LP(dev_priv) && -		     with_fdi, "LP PCH doesn't have FDI\n")) -		with_fdi = false; - -	mutex_lock(&dev_priv->sb_lock); - -	tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); -	tmp &= ~SBI_SSCCTL_DISABLE; -	tmp |= SBI_SSCCTL_PATHALT; -	intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); - -	udelay(24); - -	if (with_spread) { -		tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); -		tmp &= ~SBI_SSCCTL_PATHALT; -		intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); - -		if (with_fdi) -			lpt_fdi_program_mphy(dev_priv); -	} - -	reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0; -	tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); -	tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE; -	intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); - -	mutex_unlock(&dev_priv->sb_lock); -} - -/* Sequence to disable CLKOUT_DP */ -void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv) -{ -	u32 reg, tmp; - -	mutex_lock(&dev_priv->sb_lock); - -	reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0; -	tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); -	tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE; -	intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); - -	tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); -	if (!(tmp & SBI_SSCCTL_DISABLE)) { -		if (!(tmp & SBI_SSCCTL_PATHALT)) { -			tmp |= SBI_SSCCTL_PATHALT; -			intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); -			udelay(32); -		} -		tmp |= SBI_SSCCTL_DISABLE; -		intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); -	} - -	mutex_unlock(&dev_priv->sb_lock); -} - -#define BEND_IDX(steps) ((50 + (steps)) / 5) - -static const u16 sscdivintphase[] = { -	[BEND_IDX( 50)] = 0x3B23, -	[BEND_IDX( 45)] = 0x3B23, -	[BEND_IDX( 40)] = 0x3C23, -	[BEND_IDX( 35)] = 0x3C23, -	[BEND_IDX( 30)] = 0x3D23, -	[BEND_IDX( 25)] = 0x3D23, -	[BEND_IDX( 20)] = 0x3E23, -	[BEND_IDX( 15)] = 0x3E23, -	[BEND_IDX( 10)] = 0x3F23, -	[BEND_IDX(  5)] = 0x3F23, -	[BEND_IDX(  0)] = 0x0025, -	[BEND_IDX( -5)] = 0x0025, -	[BEND_IDX(-10)] = 0x0125, -	[BEND_IDX(-15)] = 0x0125, -	[BEND_IDX(-20)] = 0x0225, -	[BEND_IDX(-25)] = 0x0225, -	[BEND_IDX(-30)] = 0x0325, -	[BEND_IDX(-35)] = 0x0325, -	[BEND_IDX(-40)] = 0x0425, -	[BEND_IDX(-45)] = 0x0425, -	[BEND_IDX(-50)] = 0x0525, -}; - -/* - * Bend CLKOUT_DP - * steps -50 to 50 inclusive, in steps of 5 - * < 0 slow down the clock, > 0 speed up the clock, 0 == no bend (135MHz) - * change in clock period = -(steps / 10) * 5.787 ps - */ -static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps) -{ -	u32 tmp; -	int idx = BEND_IDX(steps); - -	if (drm_WARN_ON(&dev_priv->drm, steps % 5 != 0)) -		return; - -	if (drm_WARN_ON(&dev_priv->drm, idx >= ARRAY_SIZE(sscdivintphase))) -		return; - -	mutex_lock(&dev_priv->sb_lock); - -	if (steps % 10 != 0) -		tmp = 0xAAAAAAAB; -	else -		tmp = 0x00000000; -	intel_sbi_write(dev_priv, SBI_SSCDITHPHASE, tmp, SBI_ICLK); - -	tmp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE, SBI_ICLK); -	tmp &= 0xffff0000; -	tmp |= sscdivintphase[idx]; -	intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK); - -	mutex_unlock(&dev_priv->sb_lock); -} - -#undef BEND_IDX - -static bool spll_uses_pch_ssc(struct drm_i915_private *dev_priv) -{ -	u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP); -	u32 ctl = intel_de_read(dev_priv, SPLL_CTL); - -	if ((ctl & SPLL_PLL_ENABLE) == 0) -		return false; - -	if ((ctl & SPLL_REF_MASK) == SPLL_REF_MUXED_SSC && -	    (fuse_strap & HSW_CPU_SSC_ENABLE) == 0) -		return true; - -	if (IS_BROADWELL(dev_priv) && -	    (ctl & SPLL_REF_MASK) == SPLL_REF_PCH_SSC_BDW) -		return true; - -	return false; -} - -static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv, -			       enum intel_dpll_id id) -{ -	u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP); -	u32 ctl = intel_de_read(dev_priv, WRPLL_CTL(id)); - -	if ((ctl & WRPLL_PLL_ENABLE) == 0) -		return false; - -	if ((ctl & WRPLL_REF_MASK) == WRPLL_REF_PCH_SSC) -		return true; - -	if ((IS_BROADWELL(dev_priv) || IS_HSW_ULT(dev_priv)) && -	    (ctl & WRPLL_REF_MASK) == WRPLL_REF_MUXED_SSC_BDW && -	    (fuse_strap & HSW_CPU_SSC_ENABLE) == 0) -		return true; - -	return false; -} - -static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv) -{ -	struct intel_encoder *encoder; -	bool has_fdi = false; - -	for_each_intel_encoder(&dev_priv->drm, encoder) { -		switch (encoder->type) { -		case INTEL_OUTPUT_ANALOG: -			has_fdi = true; -			break; -		default: -			break; -		} -	} - -	/* -	 * The BIOS may have decided to use the PCH SSC -	 * reference so we must not disable it until the -	 * relevant PLLs have stopped relying on it. We'll -	 * just leave the PCH SSC reference enabled in case -	 * any active PLL is using it. It will get disabled -	 * after runtime suspend if we don't have FDI. -	 * -	 * TODO: Move the whole reference clock handling -	 * to the modeset sequence proper so that we can -	 * actually enable/disable/reconfigure these things -	 * safely. To do that we need to introduce a real -	 * clock hierarchy. That would also allow us to do -	 * clock bending finally. -	 */ -	dev_priv->pch_ssc_use = 0; - -	if (spll_uses_pch_ssc(dev_priv)) { -		drm_dbg_kms(&dev_priv->drm, "SPLL using PCH SSC\n"); -		dev_priv->pch_ssc_use |= BIT(DPLL_ID_SPLL); -	} - -	if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL1)) { -		drm_dbg_kms(&dev_priv->drm, "WRPLL1 using PCH SSC\n"); -		dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL1); -	} - -	if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL2)) { -		drm_dbg_kms(&dev_priv->drm, "WRPLL2 using PCH SSC\n"); -		dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL2); -	} - -	if (dev_priv->pch_ssc_use) -		return; - -	if (has_fdi) { -		lpt_bend_clkout_dp(dev_priv, 0); -		lpt_enable_clkout_dp(dev_priv, true, true); -	} else { -		lpt_disable_clkout_dp(dev_priv); -	} -} - -/* - * Initialize reference clocks when the driver loads - */ -void intel_init_pch_refclk(struct drm_i915_private *dev_priv) -{ -	if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) -		ilk_init_pch_refclk(dev_priv); -	else if (HAS_PCH_LPT(dev_priv)) -		lpt_init_pch_refclk(dev_priv); -} -  static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state)  {  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -4978,8 +3937,8 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,  					     &pipe_config->dp_m2_n2);  } -static void ilk_get_fdi_m_n_config(struct intel_crtc *crtc, -				   struct intel_crtc_state *pipe_config) +void ilk_get_fdi_m_n_config(struct intel_crtc *crtc, +			    struct intel_crtc_state *pipe_config)  {  	intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,  				     &pipe_config->fdi_m_n, NULL); @@ -5116,50 +4075,9 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,  	i9xx_get_pipe_color_config(pipe_config);  	intel_color_get_config(pipe_config); -	if (intel_de_read(dev_priv, PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { -		struct intel_shared_dpll *pll; -		enum intel_dpll_id pll_id; -		bool pll_active; - -		pipe_config->has_pch_encoder = true; - -		tmp = intel_de_read(dev_priv, FDI_RX_CTL(crtc->pipe)); -		pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> -					  FDI_DP_PORT_WIDTH_SHIFT) + 1; - -		ilk_get_fdi_m_n_config(crtc, pipe_config); - -		if (HAS_PCH_IBX(dev_priv)) { -			/* -			 * The pipe->pch transcoder and pch transcoder->pll -			 * mapping is fixed. -			 */ -			pll_id = (enum intel_dpll_id) crtc->pipe; -		} else { -			tmp = intel_de_read(dev_priv, PCH_DPLL_SEL); -			if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) -				pll_id = DPLL_ID_PCH_PLL_B; -			else -				pll_id= DPLL_ID_PCH_PLL_A; -		} - -		pipe_config->shared_dpll = -			intel_get_shared_dpll_by_id(dev_priv, pll_id); -		pll = pipe_config->shared_dpll; - -		pll_active = intel_dpll_get_hw_state(dev_priv, pll, -						     &pipe_config->dpll_hw_state); -		drm_WARN_ON(dev, !pll_active); - -		tmp = pipe_config->dpll_hw_state.dpll; -		pipe_config->pixel_multiplier = -			((tmp & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK) -			 >> PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT) + 1; +	pipe_config->pixel_multiplier = 1; -		ilk_pch_clock_get(crtc, pipe_config); -	} else { -		pipe_config->pixel_multiplier = 1; -	} +	ilk_pch_get_config(pipe_config);  	intel_get_transcoder_timings(crtc, pipe_config);  	intel_get_pipe_src_size(crtc, pipe_config); @@ -5174,6 +4092,16 @@ out:  	return ret;  } +static u8 bigjoiner_pipes(struct drm_i915_private *i915) +{ +	if (DISPLAY_VER(i915) >= 12) +		return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D); +	else if (DISPLAY_VER(i915) >= 11) +		return BIT(PIPE_B) | BIT(PIPE_C); +	else +		return 0; +} +  static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,  					   enum transcoder cpu_transcoder)  { @@ -5189,6 +4117,54 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,  	return tmp & TRANS_DDI_FUNC_ENABLE;  } +static u8 enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv) +{ +	u8 master_pipes = 0, slave_pipes = 0; +	struct intel_crtc *crtc; + +	for_each_intel_crtc(&dev_priv->drm, crtc) { +		enum intel_display_power_domain power_domain; +		enum pipe pipe = crtc->pipe; +		intel_wakeref_t wakeref; + +		if ((bigjoiner_pipes(dev_priv) & BIT(pipe)) == 0) +			continue; + +		power_domain = intel_dsc_power_domain(crtc, (enum transcoder) pipe); +		with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) { +			u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe)); + +			if (!(tmp & BIG_JOINER_ENABLE)) +				continue; + +			if (tmp & MASTER_BIG_JOINER_ENABLE) +				master_pipes |= BIT(pipe); +			else +				slave_pipes |= BIT(pipe); +		} + +		if (DISPLAY_VER(dev_priv) < 13) +			continue; + +		power_domain = POWER_DOMAIN_PIPE(pipe); +		with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) { +			u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe)); + +			if (tmp & UNCOMPRESSED_JOINER_MASTER) +				master_pipes |= BIT(pipe); +			if (tmp & UNCOMPRESSED_JOINER_SLAVE) +				slave_pipes |= BIT(pipe); +		} +	} + +	/* Bigjoiner pipes should always be consecutive master and slave */ +	drm_WARN(&dev_priv->drm, slave_pipes != master_pipes << 1, +		 "Bigjoiner misconfigured (master pipes 0x%x, slave pipes 0x%x)\n", +		 master_pipes, slave_pipes); + +	return slave_pipes; +} +  static u8 hsw_panel_transcoders(struct drm_i915_private *i915)  {  	u8 panel_transcoder_mask = BIT(TRANSCODER_EDP); @@ -5250,10 +4226,18 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)  			enabled_transcoders |= BIT(cpu_transcoder);  	} +	/* single pipe or bigjoiner master */  	cpu_transcoder = (enum transcoder) crtc->pipe;  	if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))  		enabled_transcoders |= BIT(cpu_transcoder); +	/* bigjoiner slave -> consider the master pipe's transcoder as well */ +	if (enabled_bigjoiner_pipes(dev_priv) & BIT(crtc->pipe)) { +		cpu_transcoder = (enum transcoder) crtc->pipe - 1; +		if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder)) +			enabled_transcoders |= BIT(cpu_transcoder); +	} +  	return enabled_transcoders;  } @@ -5374,45 +4358,6 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,  	return transcoder_is_dsi(pipe_config->cpu_transcoder);  } -static void hsw_get_ddi_port_state(struct intel_crtc *crtc, -				   struct intel_crtc_state *pipe_config) -{ -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); -	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; -	enum port port; -	u32 tmp; - -	if (transcoder_is_dsi(cpu_transcoder)) { -		port = (cpu_transcoder == TRANSCODER_DSI_A) ? -						PORT_A : PORT_B; -	} else { -		tmp = intel_de_read(dev_priv, -				    TRANS_DDI_FUNC_CTL(cpu_transcoder)); -		if (!(tmp & TRANS_DDI_FUNC_ENABLE)) -			return; -		if (DISPLAY_VER(dev_priv) >= 12) -			port = TGL_TRANS_DDI_FUNC_CTL_VAL_TO_PORT(tmp); -		else -			port = TRANS_DDI_FUNC_CTL_VAL_TO_PORT(tmp); -	} - -	/* -	 * Haswell has only FDI/PCH transcoder A. It is which is connected to -	 * DDI E. So just check whether this pipe is wired to DDI E and whether -	 * the PCH transcoder is on. -	 */ -	if (DISPLAY_VER(dev_priv) < 9 && -	    (port == PORT_E) && intel_de_read(dev_priv, LPT_TRANSCONF) & TRANS_ENABLE) { -		pipe_config->has_pch_encoder = true; - -		tmp = intel_de_read(dev_priv, FDI_RX_CTL(PIPE_A)); -		pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> -					  FDI_DP_PORT_WIDTH_SHIFT) + 1; - -		ilk_get_fdi_m_n_config(crtc, pipe_config); -	} -} -  static bool hsw_get_pipe_config(struct intel_crtc *crtc,  				struct intel_crtc_state *pipe_config)  { @@ -5439,21 +4384,12 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,  	if (DISPLAY_VER(dev_priv) >= 13 && !pipe_config->dsc.compression_enable)  		intel_uncompressed_joiner_get_config(pipe_config); -	if (!active) { -		/* bigjoiner slave doesn't enable transcoder */ -		if (!pipe_config->bigjoiner_slave) -			goto out; - -		active = true; -		pipe_config->pixel_multiplier = 1; +	if (!active) +		goto out; -		/* we cannot read out most state, so don't bother.. */ -		pipe_config->quirks |= PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE; -	} else if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || -	    DISPLAY_VER(dev_priv) >= 11) { -		hsw_get_ddi_port_state(crtc, pipe_config); +	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) || +	    DISPLAY_VER(dev_priv) >= 11)  		intel_get_transcoder_timings(crtc, pipe_config); -	}  	if (HAS_VRR(dev_priv) && !transcoder_is_dsi(pipe_config->cpu_transcoder))  		intel_vrr_get_config(crtc, pipe_config); @@ -5521,10 +4457,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,  		}  	} -	if (pipe_config->bigjoiner_slave) { -		/* Cannot be read out as a slave, set to 0. */ -		pipe_config->pixel_multiplier = 0; -	} else if (pipe_config->cpu_transcoder != TRANSCODER_EDP && +	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {  		pipe_config->pixel_multiplier =  			intel_de_read(dev_priv, @@ -5721,7 +4654,8 @@ found:  	drm_atomic_state_put(state);  	/* let the connector get through one full cycle before testing */ -	intel_wait_for_vblank(dev_priv, crtc->pipe); +	intel_crtc_wait_for_next_vblank(crtc); +  	return true;  fail: @@ -5782,8 +4716,8 @@ static int i9xx_pll_refclk(struct drm_device *dev,  }  /* Returns the clock of the currently programmed mode of the given pipe. */ -static void i9xx_crtc_clock_get(struct intel_crtc *crtc, -				struct intel_crtc_state *pipe_config) +void i9xx_crtc_clock_get(struct intel_crtc *crtc, +			 struct intel_crtc_state *pipe_config)  {  	struct drm_device *dev = crtc->base.dev;  	struct drm_i915_private *dev_priv = to_i915(dev); @@ -5893,24 +4827,6 @@ int intel_dotclock_calculate(int link_freq,  	return div_u64(mul_u32_u32(m_n->link_m, link_freq), m_n->link_n);  } -static void ilk_pch_clock_get(struct intel_crtc *crtc, -			      struct intel_crtc_state *pipe_config) -{ -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - -	/* read out port_clock from the DPLL */ -	i9xx_crtc_clock_get(crtc, pipe_config); - -	/* -	 * In case there is an active pipe without active ports, -	 * we may need some idea for the dotclock anyway. -	 * Calculate one based on the FDI configuration. -	 */ -	pipe_config->hw.adjusted_mode.crtc_clock = -		intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config), -					 &pipe_config->fdi_m_n); -} -  /* Returns the currently programmed mode of the given encoder. */  struct drm_display_mode *  intel_encoder_current_mode(struct intel_encoder *encoder) @@ -5924,7 +4840,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)  	if (!encoder->get_hw_state(encoder, &pipe))  		return NULL; -	crtc = intel_get_crtc_for_pipe(dev_priv, pipe); +	crtc = intel_crtc_for_pipe(dev_priv, pipe);  	mode = kzalloc(sizeof(*mode), GFP_KERNEL);  	if (!mode) @@ -6245,6 +5161,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)  		linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE;  		linked_state->color_ctl = plane_state->color_ctl;  		linked_state->view = plane_state->view; +		linked_state->decrypt = plane_state->decrypt;  		intel_plane_copy_hw_state(linked_state, plane_state);  		linked_state->uapi.src = plane_state->uapi.src; @@ -6252,13 +5169,13 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)  		if (icl_is_hdr_plane(dev_priv, plane->id)) {  			if (linked->id == PLANE_SPRITE5) -				plane_state->cus_ctl |= PLANE_CUS_PLANE_7; +				plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL;  			else if (linked->id == PLANE_SPRITE4) -				plane_state->cus_ctl |= PLANE_CUS_PLANE_6; +				plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL;  			else if (linked->id == PLANE_SPRITE3) -				plane_state->cus_ctl |= PLANE_CUS_PLANE_5_RKL; +				plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL;  			else if (linked->id == PLANE_SPRITE2) -				plane_state->cus_ctl |= PLANE_CUS_PLANE_4_RKL; +				plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL;  			else  				MISSING_CASE(linked->id);  		} @@ -6371,8 +5288,6 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,  		crtc_state->update_wm_post = true;  	if (mode_changed && crtc_state->hw.enable && -	    dev_priv->dpll_funcs && -	    !crtc_state->bigjoiner_slave &&  	    !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) {  		ret = dev_priv->dpll_funcs->crtc_compute_clock(crtc_state);  		if (ret) @@ -6928,18 +5843,15 @@ static void  intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,  					   struct intel_crtc_state *crtc_state)  { -	const struct intel_crtc_state *from_crtc_state = crtc_state; - -	if (crtc_state->bigjoiner_slave) { -		from_crtc_state = intel_atomic_get_new_crtc_state(state, -								  crtc_state->bigjoiner_linked_crtc); +	const struct intel_crtc_state *master_crtc_state; +	struct intel_crtc *master_crtc; -		/* No need to copy state if the master state is unchanged */ -		if (!from_crtc_state) -			return; -	} +	master_crtc = intel_master_crtc(crtc_state); +	master_crtc_state = intel_atomic_get_new_crtc_state(state, master_crtc); -	intel_crtc_copy_color_blobs(crtc_state, from_crtc_state); +	/* No need to copy state if the master state is unchanged */ +	if (master_crtc_state) +		intel_crtc_copy_color_blobs(crtc_state, master_crtc_state);  }  static void @@ -6982,7 +5894,6 @@ copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,  			  const struct intel_crtc_state *from_crtc_state)  {  	struct intel_crtc_state *saved_state; -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);  	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);  	if (!saved_state) @@ -7012,8 +5923,8 @@ copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,  	crtc_state->nv12_planes = crtc_state->c8_planes = crtc_state->update_planes = 0;  	crtc_state->bigjoiner_linked_crtc = to_intel_crtc(from_crtc_state->uapi.crtc);  	crtc_state->bigjoiner_slave = true; -	crtc_state->cpu_transcoder = (enum transcoder)crtc->pipe; -	crtc_state->has_audio = false; +	crtc_state->cpu_transcoder = from_crtc_state->cpu_transcoder; +	crtc_state->has_audio = from_crtc_state->has_audio;  	return 0;  } @@ -7609,51 +6520,48 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,  	PIPE_CONF_CHECK_X(output_types); -	/* FIXME do the readout properly and get rid of this quirk */ -	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) { -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hblank_start); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hblank_end); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hsync_start); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hsync_end); - -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vdisplay); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vtotal); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vblank_start); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vblank_end); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vsync_start); -		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vsync_end); - -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end); - -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start); -		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end); - -		PIPE_CONF_CHECK_I(pixel_multiplier); - +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hblank_start); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hblank_end); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hsync_start); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hsync_end); + +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vdisplay); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vtotal); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vblank_start); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vblank_end); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vsync_start); +	PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vsync_end); + +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end); + +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start); +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end); + +	PIPE_CONF_CHECK_I(pixel_multiplier); + +	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, +			      DRM_MODE_FLAG_INTERLACE); + +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {  		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, -				      DRM_MODE_FLAG_INTERLACE); - -		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) { -			PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, -					      DRM_MODE_FLAG_PHSYNC); -			PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, -					      DRM_MODE_FLAG_NHSYNC); -			PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, -					      DRM_MODE_FLAG_PVSYNC); -			PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, -					      DRM_MODE_FLAG_NVSYNC); -		} +				      DRM_MODE_FLAG_PHSYNC); +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, +				      DRM_MODE_FLAG_NHSYNC); +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, +				      DRM_MODE_FLAG_PVSYNC); +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags, +				      DRM_MODE_FLAG_NVSYNC);  	}  	PIPE_CONF_CHECK_I(output_format); @@ -7665,9 +6573,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);  	PIPE_CONF_CHECK_BOOL(has_infoframe); -	/* FIXME do the readout properly and get rid of this quirk */ -	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) -		PIPE_CONF_CHECK_BOOL(fec_enable); +	PIPE_CONF_CHECK_BOOL(fec_enable);  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio); @@ -7696,9 +6602,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,  		}  		PIPE_CONF_CHECK_I(scaler_state.scaler_id); -		/* FIXME do the readout properly and get rid of this quirk */ -		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) -			PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate); +		PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);  		PIPE_CONF_CHECK_X(gamma_mode);  		if (IS_CHERRYVIEW(dev_priv)) @@ -7725,11 +6629,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,  	PIPE_CONF_CHECK_BOOL(double_wide); -	if (dev_priv->dpll.mgr) +	if (dev_priv->dpll.mgr) {  		PIPE_CONF_CHECK_P(shared_dpll); -	/* FIXME do the readout properly and get rid of this quirk */ -	if (dev_priv->dpll.mgr && !PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {  		PIPE_CONF_CHECK_X(dpll_hw_state.dpll);  		PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);  		PIPE_CONF_CHECK_X(dpll_hw_state.fp0); @@ -7763,19 +6665,17 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,  		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);  	} -	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) { -		PIPE_CONF_CHECK_X(dsi_pll.ctrl); -		PIPE_CONF_CHECK_X(dsi_pll.div); +	PIPE_CONF_CHECK_X(dsi_pll.ctrl); +	PIPE_CONF_CHECK_X(dsi_pll.div); -		if (IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) >= 5) -			PIPE_CONF_CHECK_I(pipe_bpp); +	if (IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) >= 5) +		PIPE_CONF_CHECK_I(pipe_bpp); -		PIPE_CONF_CHECK_CLOCK_FUZZY(hw.pipe_mode.crtc_clock); -		PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock); -		PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock); +	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.pipe_mode.crtc_clock); +	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock); +	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock); -		PIPE_CONF_CHECK_I(min_voltage_level); -	} +	PIPE_CONF_CHECK_I(min_voltage_level);  	if (current_config->has_psr || pipe_config->has_psr)  		PIPE_CONF_CHECK_X_WITH_MASK(infoframes.enable, @@ -8049,7 +6949,7 @@ verify_crtc_state(struct intel_crtc *crtc,  	struct intel_encoder *encoder;  	struct intel_crtc_state *pipe_config = old_crtc_state;  	struct drm_atomic_state *state = old_crtc_state->uapi.state; -	struct intel_crtc *master = crtc; +	struct intel_crtc *master_crtc;  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);  	intel_crtc_free_hw_state(old_crtc_state); @@ -8077,10 +6977,9 @@ verify_crtc_state(struct intel_crtc *crtc,  			"(expected %i, found %i)\n",  			new_crtc_state->hw.active, crtc->active); -	if (new_crtc_state->bigjoiner_slave) -		master = new_crtc_state->bigjoiner_linked_crtc; +	master_crtc = intel_master_crtc(new_crtc_state); -	for_each_encoder_on_crtc(dev, &master->base, encoder) { +	for_each_encoder_on_crtc(dev, &master_crtc->base, encoder) {  		enum pipe pipe;  		bool active; @@ -8090,7 +6989,7 @@ verify_crtc_state(struct intel_crtc *crtc,  				encoder->base.base.id, active,  				new_crtc_state->hw.active); -		I915_STATE_WARN(active && master->pipe != pipe, +		I915_STATE_WARN(active && master_crtc->pipe != pipe,  				"Encoder connected to wrong pipe %c\n",  				pipe_name(pipe)); @@ -8101,10 +7000,6 @@ verify_crtc_state(struct intel_crtc *crtc,  	if (!new_crtc_state->hw.active)  		return; -	if (new_crtc_state->bigjoiner_slave) -		/* No PLLs set for slave */ -		pipe_config->shared_dpll = NULL; -  	intel_pipe_config_sanity_check(dev_priv, pipe_config);  	if (!intel_pipe_config_compare(new_crtc_state, @@ -8223,9 +7118,6 @@ verify_mpllb_state(struct intel_atomic_state *state,  	if (!new_crtc_state->hw.active)  		return; -	if (new_crtc_state->bigjoiner_slave) -		return; -  	encoder = intel_get_crtc_new_encoder(state, new_crtc_state);  	intel_mpllb_readout_hw_state(encoder, &mpllb_hw_state); @@ -8607,28 +7499,13 @@ static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)  	return 0;  } -static bool bo_has_valid_encryption(struct drm_i915_gem_object *obj) -{ -	struct drm_i915_private *i915 = to_i915(obj->base.dev); - -	return intel_pxp_key_check(&i915->gt.pxp, obj, false) == 0; -} - -static bool pxp_is_borked(struct drm_i915_gem_object *obj) -{ -	return i915_gem_object_is_protected(obj) && !bo_has_valid_encryption(obj); -} -  static int intel_atomic_check_planes(struct intel_atomic_state *state)  {  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;  	struct intel_plane_state *plane_state;  	struct intel_plane *plane; -	struct intel_plane_state *new_plane_state; -	struct intel_plane_state *old_plane_state;  	struct intel_crtc *crtc; -	const struct drm_framebuffer *fb;  	int i, ret;  	ret = icl_add_linked_planes(state); @@ -8676,72 +7553,6 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)  			return ret;  	} -	for_each_new_intel_plane_in_state(state, plane, plane_state, i) { -		new_plane_state = intel_atomic_get_new_plane_state(state, plane); -		old_plane_state = intel_atomic_get_old_plane_state(state, plane); -		fb = new_plane_state->hw.fb; -		if (fb) { -			new_plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb)); -			new_plane_state->force_black = pxp_is_borked(intel_fb_obj(fb)); -		} else { -			new_plane_state->decrypt = old_plane_state->decrypt; -			new_plane_state->force_black = old_plane_state->force_black; -		} -	} - -	return 0; -} - -static int intel_atomic_check_cdclk(struct intel_atomic_state *state, -				    bool *need_cdclk_calc) -{ -	struct drm_i915_private *dev_priv = to_i915(state->base.dev); -	const struct intel_cdclk_state *old_cdclk_state; -	const struct intel_cdclk_state *new_cdclk_state; -	struct intel_plane_state *plane_state; -	struct intel_bw_state *new_bw_state; -	struct intel_plane *plane; -	int min_cdclk = 0; -	enum pipe pipe; -	int ret; -	int i; -	/* -	 * active_planes bitmask has been updated, and potentially -	 * affected planes are part of the state. We can now -	 * compute the minimum cdclk for each plane. -	 */ -	for_each_new_intel_plane_in_state(state, plane, plane_state, i) { -		ret = intel_plane_calc_min_cdclk(state, plane, need_cdclk_calc); -		if (ret) -			return ret; -	} - -	old_cdclk_state = intel_atomic_get_old_cdclk_state(state); -	new_cdclk_state = intel_atomic_get_new_cdclk_state(state); - -	if (new_cdclk_state && -	    old_cdclk_state->force_min_cdclk != new_cdclk_state->force_min_cdclk) -		*need_cdclk_calc = true; - -	ret = intel_cdclk_bw_calc_min_cdclk(state); -	if (ret) -		return ret; - -	new_bw_state = intel_atomic_get_new_bw_state(state); - -	if (!new_cdclk_state || !new_bw_state) -		return 0; - -	for_each_pipe(dev_priv, pipe) { -		min_cdclk = max(new_cdclk_state->min_cdclk[pipe], min_cdclk); - -		/* -		 * Currently do this change only if we need to increase -		 */ -		if (new_bw_state->min_cdclk > min_cdclk) -			*need_cdclk_calc = true; -	} -  	return 0;  } @@ -8790,13 +7601,13 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,  					struct intel_crtc_state *new_crtc_state)  {  	struct intel_crtc_state *slave_crtc_state, *master_crtc_state; -	struct intel_crtc *slave, *master; +	struct intel_crtc *slave_crtc, *master_crtc;  	/* slave being enabled, is master is still claiming this crtc? */  	if (old_crtc_state->bigjoiner_slave) { -		slave = crtc; -		master = old_crtc_state->bigjoiner_linked_crtc; -		master_crtc_state = intel_atomic_get_new_crtc_state(state, master); +		slave_crtc = crtc; +		master_crtc = old_crtc_state->bigjoiner_linked_crtc; +		master_crtc_state = intel_atomic_get_new_crtc_state(state, master_crtc);  		if (!master_crtc_state || !intel_crtc_needs_modeset(master_crtc_state))  			goto claimed;  	} @@ -8804,17 +7615,17 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,  	if (!new_crtc_state->bigjoiner)  		return 0; -	slave = intel_dsc_get_bigjoiner_secondary(crtc); -	if (!slave) { +	slave_crtc = intel_dsc_get_bigjoiner_secondary(crtc); +	if (!slave_crtc) {  		DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires "  			      "CRTC + 1 to be used, doesn't exist\n",  			      crtc->base.base.id, crtc->base.name);  		return -EINVAL;  	} -	new_crtc_state->bigjoiner_linked_crtc = slave; -	slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave); -	master = crtc; +	new_crtc_state->bigjoiner_linked_crtc = slave_crtc; +	slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave_crtc); +	master_crtc = crtc;  	if (IS_ERR(slave_crtc_state))  		return PTR_ERR(slave_crtc_state); @@ -8823,15 +7634,15 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,  		goto claimed;  	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n", -		      slave->base.base.id, slave->base.name); +		      slave_crtc->base.base.id, slave_crtc->base.name);  	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);  claimed:  	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "  		      "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n", -		      slave->base.base.id, slave->base.name, -		      master->base.base.id, master->base.name); +		      slave_crtc->base.base.id, slave_crtc->base.name, +		      master_crtc->base.base.id, master_crtc->base.name);  	return -EINVAL;  } @@ -8865,35 +7676,37 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state,   * correspond to the last vblank and have no relation to the actual time when   * the flip done event was sent.   */ -static int intel_atomic_check_async(struct intel_atomic_state *state) +static int intel_atomic_check_async(struct intel_atomic_state *state, struct intel_crtc *crtc)  {  	struct drm_i915_private *i915 = to_i915(state->base.dev);  	const struct intel_crtc_state *old_crtc_state, *new_crtc_state;  	const struct intel_plane_state *new_plane_state, *old_plane_state; -	struct intel_crtc *crtc;  	struct intel_plane *plane;  	int i; -	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, -					    new_crtc_state, i) { -		if (intel_crtc_needs_modeset(new_crtc_state)) { -			drm_dbg_kms(&i915->drm, "Modeset Required. Async flip not supported\n"); -			return -EINVAL; -		} +	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); +	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); -		if (!new_crtc_state->hw.active) { -			drm_dbg_kms(&i915->drm, "CRTC inactive\n"); -			return -EINVAL; -		} -		if (old_crtc_state->active_planes != new_crtc_state->active_planes) { -			drm_dbg_kms(&i915->drm, -				    "Active planes cannot be changed during async flip\n"); -			return -EINVAL; -		} +	if (intel_crtc_needs_modeset(new_crtc_state)) { +		drm_dbg_kms(&i915->drm, "Modeset Required. Async flip not supported\n"); +		return -EINVAL; +	} + +	if (!new_crtc_state->hw.active) { +		drm_dbg_kms(&i915->drm, "CRTC inactive\n"); +		return -EINVAL; +	} +	if (old_crtc_state->active_planes != new_crtc_state->active_planes) { +		drm_dbg_kms(&i915->drm, +			    "Active planes cannot be changed during async flip\n"); +		return -EINVAL;  	}  	for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,  					     new_plane_state, i) { +		if (plane->pipe != crtc->pipe) +			continue; +  		/*  		 * TODO: Async flip is only supported through the page flip IOCTL  		 * as of now. So support currently added for primary plane only. @@ -8920,8 +7733,14 @@ static int intel_atomic_check_async(struct intel_atomic_state *state)  			return -EINVAL;  		} -		if (old_plane_state->view.color_plane[0].stride != -		    new_plane_state->view.color_plane[0].stride) { +		if (new_plane_state->hw.fb->format->num_planes > 1) { +			drm_dbg_kms(&i915->drm, +				    "Planar formats not supported with async flips\n"); +			return -EINVAL; +		} + +		if (old_plane_state->view.color_plane[0].mapping_stride != +		    new_plane_state->view.color_plane[0].mapping_stride) {  			drm_dbg_kms(&i915->drm, "Stride cannot be changed in async flip\n");  			return -EINVAL;  		} @@ -9177,7 +7996,6 @@ static int intel_atomic_check(struct drm_device *dev,  	if (ret)  		goto fail; -	intel_fbc_choose_crtc(dev_priv, state);  	ret = intel_compute_global_watermarks(state);  	if (ret)  		goto fail; @@ -9186,7 +8004,7 @@ static int intel_atomic_check(struct drm_device *dev,  	if (ret)  		goto fail; -	ret = intel_atomic_check_cdclk(state, &any_ms); +	ret = intel_cdclk_atomic_check(state, &any_ms);  	if (ret)  		goto fail; @@ -9209,10 +8027,14 @@ static int intel_atomic_check(struct drm_device *dev,  	if (ret)  		goto fail; +	ret = intel_fbc_atomic_check(state); +	if (ret) +		goto fail; +  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,  					    new_crtc_state, i) {  		if (new_crtc_state->uapi.async_flip) { -			ret = intel_atomic_check_async(state); +			ret = intel_atomic_check_async(state, crtc);  			if (ret)  				goto fail;  		} @@ -9417,15 +8239,17 @@ static void intel_update_crtc(struct intel_atomic_state *state,  	intel_fbc_update(state, crtc); +	intel_update_planes_on_crtc(state, crtc); +  	/* Perform vblank evasion around commit operation */  	intel_pipe_update_start(new_crtc_state);  	commit_pipe_pre_planes(state, crtc);  	if (DISPLAY_VER(dev_priv) >= 9) -		skl_update_planes_on_crtc(state, crtc); +		skl_arm_planes_on_crtc(state, crtc);  	else -		i9xx_update_planes_on_crtc(state, crtc); +		i9xx_arm_planes_on_crtc(state, crtc);  	commit_pipe_post_planes(state, crtc); @@ -9449,23 +8273,6 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,  {  	struct drm_i915_private *dev_priv = to_i915(state->base.dev); -	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave); - -	intel_encoders_pre_disable(state, crtc); - -	intel_crtc_disable_planes(state, crtc); - -	/* -	 * We still need special handling for disabling bigjoiner master -	 * and slaves since for slave we do not have encoder or plls -	 * so we dont need to disable those. -	 */ -	if (old_crtc_state->bigjoiner) { -		intel_crtc_disable_planes(state, -					  old_crtc_state->bigjoiner_linked_crtc); -		old_crtc_state->bigjoiner_linked_crtc->active = false; -	} -  	/*  	 * We need to disable pipe CRC before disabling the pipe,  	 * or we race against vblank off. @@ -9490,10 +8297,22 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)  	u32 handled = 0;  	int i; +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, +					    new_crtc_state, i) { +		if (!intel_crtc_needs_modeset(new_crtc_state)) +			continue; + +		if (!old_crtc_state->hw.active) +			continue; + +		intel_pre_plane_update(state, crtc); +		intel_crtc_disable_planes(state, crtc); +	} +  	/* Only disable port sync and MST slaves */  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,  					    new_crtc_state, i) { -		if (!intel_crtc_needs_modeset(new_crtc_state) || old_crtc_state->bigjoiner) +		if (!intel_crtc_needs_modeset(new_crtc_state))  			continue;  		if (!old_crtc_state->hw.active) @@ -9505,10 +8324,10 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)  		 * Slave vblanks are masked till Master Vblanks.  		 */  		if (!is_trans_port_sync_slave(old_crtc_state) && -		    !intel_dp_mst_is_slave_trans(old_crtc_state)) +		    !intel_dp_mst_is_slave_trans(old_crtc_state) && +		    !old_crtc_state->bigjoiner_slave)  			continue; -		intel_pre_plane_update(state, crtc);  		intel_old_crtc_state_disables(state, old_crtc_state,  					      new_crtc_state, crtc);  		handled |= BIT(crtc->pipe); @@ -9518,21 +8337,14 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,  					    new_crtc_state, i) {  		if (!intel_crtc_needs_modeset(new_crtc_state) || -		    (handled & BIT(crtc->pipe)) || -		    old_crtc_state->bigjoiner_slave) +		    (handled & BIT(crtc->pipe)))  			continue; -		intel_pre_plane_update(state, crtc); -		if (old_crtc_state->bigjoiner) { -			struct intel_crtc *slave = -				old_crtc_state->bigjoiner_linked_crtc; - -			intel_pre_plane_update(state, slave); -		} +		if (!old_crtc_state->hw.active) +			continue; -		if (old_crtc_state->hw.active) -			intel_old_crtc_state_disables(state, old_crtc_state, -						      new_crtc_state, crtc); +		intel_old_crtc_state_disables(state, old_crtc_state, +					      new_crtc_state, crtc);  	}  } @@ -9610,7 +8422,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)  			if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,  						 &old_crtc_state->wm.skl.ddb) &&  			    (update_pipes | modeset_pipes)) -				intel_wait_for_vblank(dev_priv, pipe); +				intel_crtc_wait_for_next_vblank(crtc);  		}  	} @@ -9701,19 +8513,19 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat  	for (;;) {  		prepare_to_wait(&intel_state->commit_ready.wait,  				&wait_fence, TASK_UNINTERRUPTIBLE); -		prepare_to_wait(bit_waitqueue(&dev_priv->gt.reset.flags, +		prepare_to_wait(bit_waitqueue(&to_gt(dev_priv)->reset.flags,  					      I915_RESET_MODESET),  				&wait_reset, TASK_UNINTERRUPTIBLE);  		if (i915_sw_fence_done(&intel_state->commit_ready) || -		    test_bit(I915_RESET_MODESET, &dev_priv->gt.reset.flags)) +		    test_bit(I915_RESET_MODESET, &to_gt(dev_priv)->reset.flags))  			break;  		schedule();  	}  	finish_wait(&intel_state->commit_ready.wait, &wait_fence); -	finish_wait(bit_waitqueue(&dev_priv->gt.reset.flags, +	finish_wait(bit_waitqueue(&to_gt(dev_priv)->reset.flags,  				  I915_RESET_MODESET),  		    &wait_reset);  } @@ -9752,10 +8564,14 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s  	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {  		struct drm_framebuffer *fb = plane_state->hw.fb; +		int cc_plane;  		int ret; -		if (!fb || -		    fb->modifier != I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC) +		if (!fb) +			continue; + +		cc_plane = intel_fb_rc_ccs_cc_plane(fb); +		if (cc_plane < 0)  			continue;  		/* @@ -9772,7 +8588,7 @@ static void intel_atomic_prepare_plane_clear_colors(struct intel_atomic_state *s  		 * GPU write on it.  		 */  		ret = i915_gem_object_read_from_page(intel_fb_obj(fb), -						     fb->offsets[2] + 16, +						     fb->offsets[cc_plane] + 16,  						     &plane_state->ccval,  						     sizeof(plane_state->ccval));  		/* The above could only fail if the FB obj has an unexpected backing store type. */ @@ -9840,11 +8656,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)  		}  	} -	if (state->modeset) -		intel_encoders_update_prepare(state); +	intel_encoders_update_prepare(state);  	intel_dbuf_pre_plane_update(state); -	intel_psr_pre_plane_update(state);  	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {  		if (new_crtc_state->uapi.async_flip) @@ -9854,11 +8668,12 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */  	dev_priv->display->commit_modeset_enables(state); -	if (state->modeset) { -		intel_encoders_update_complete(state); +	intel_encoders_update_complete(state); +	if (state->modeset)  		intel_set_cdclk_post_plane_update(state); -	} + +	intel_wait_for_vblank_workers(state);  	/* FIXME: We should call drm_atomic_helper_commit_hw_done() here  	 * already, but still need the state for the delayed optimization. To @@ -9874,13 +8689,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)  	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {  		if (new_crtc_state->uapi.async_flip)  			intel_crtc_disable_flip_done(state, crtc); - -		if (new_crtc_state->hw.active && -		    !intel_crtc_needs_modeset(new_crtc_state) && -		    !new_crtc_state->preload_luts && -		    (new_crtc_state->uapi.color_mgmt_changed || -		     new_crtc_state->update_pipe)) -			intel_color_load_luts(new_crtc_state);  	}  	/* @@ -9967,7 +8775,7 @@ static void intel_atomic_commit_work(struct work_struct *work)  	intel_atomic_commit_tail(state);  } -static int __i915_sw_fence_call +static int  intel_atomic_commit_ready(struct i915_sw_fence *fence,  			  enum i915_sw_fence_notify notify)  { @@ -10114,8 +8922,8 @@ static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)  	struct intel_plane *plane;  	for_each_intel_plane(&dev_priv->drm, plane) { -		struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, -								  plane->pipe); +		struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, +							      plane->pipe);  		plane->base.possible_crtcs = drm_crtc_mask(&crtc->base);  	} @@ -10580,7 +9388,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,  static const struct drm_mode_config_funcs intel_mode_funcs = {  	.fb_create = intel_user_framebuffer_create, -	.get_format_info = intel_get_format_info, +	.get_format_info = intel_fb_get_format_info,  	.output_poll_changed = intel_fbdev_output_poll_changed,  	.mode_valid = intel_mode_valid,  	.atomic_check = intel_atomic_check, @@ -10640,7 +9448,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)  		return;  	intel_init_cdclk_hooks(dev_priv); -	intel_init_audio_hooks(dev_priv); +	intel_audio_hooks_init(dev_priv);  	intel_dpll_init_clock_hook(dev_priv); @@ -11108,7 +9916,7 @@ int intel_modeset_init(struct drm_i915_private *i915)  void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)  { -	struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); +	struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);  	/* 640x480@60Hz, ~25175 kHz */  	struct dpll clock = {  		.m1 = 18, @@ -11181,7 +9989,7 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)  void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)  { -	struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); +	struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);  	drm_dbg_kms(&dev_priv->drm, "disabling pipe %c due to force quirk\n",  		    pipe_name(pipe)); @@ -11233,7 +10041,7 @@ intel_sanitize_plane_mapping(struct drm_i915_private *dev_priv)  			    "[PLANE:%d:%s] attached to the wrong pipe, disabling plane\n",  			    plane->base.base.id, plane->base.name); -		plane_crtc = intel_get_crtc_for_pipe(dev_priv, pipe); +		plane_crtc = intel_crtc_for_pipe(dev_priv, pipe);  		intel_plane_disable_noatomic(plane_crtc, plane);  	}  } @@ -11486,7 +10294,7 @@ static void readout_plane_state(struct drm_i915_private *dev_priv)  		visible = plane->get_hw_state(plane, &pipe); -		crtc = intel_get_crtc_for_pipe(dev_priv, pipe); +		crtc = intel_crtc_for_pipe(dev_priv, pipe);  		crtc_state = to_intel_crtc_state(crtc->base.state);  		intel_set_plane_visible(crtc_state, plane_state, visible); @@ -11553,7 +10361,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)  		pipe = 0;  		if (encoder->get_hw_state(encoder, &pipe)) { -			crtc = intel_get_crtc_for_pipe(dev_priv, pipe); +			crtc = intel_crtc_for_pipe(dev_priv, pipe);  			crtc_state = to_intel_crtc_state(crtc->base.state);  			encoder->base.crtc = &crtc->base; @@ -11628,9 +10436,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)  		struct intel_plane *plane;  		int min_cdclk = 0; -		if (crtc_state->bigjoiner_slave) -			continue; -  		if (crtc_state->hw.active) {  			/*  			 * The initial mode needs to be set in order to keep @@ -11690,39 +10495,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)  		intel_bw_crtc_update(bw_state, crtc_state);  		intel_pipe_config_sanity_check(dev_priv, crtc_state); - -		/* discard our incomplete slave state, copy it from master */ -		if (crtc_state->bigjoiner && crtc_state->hw.active) { -			struct intel_crtc *slave = crtc_state->bigjoiner_linked_crtc; -			struct intel_crtc_state *slave_crtc_state = -				to_intel_crtc_state(slave->base.state); - -			copy_bigjoiner_crtc_state(slave_crtc_state, crtc_state); -			slave->base.mode = crtc->base.mode; - -			cdclk_state->min_cdclk[slave->pipe] = min_cdclk; -			cdclk_state->min_voltage_level[slave->pipe] = -				crtc_state->min_voltage_level; - -			for_each_intel_plane_on_crtc(&dev_priv->drm, slave, plane) { -				const struct intel_plane_state *plane_state = -					to_intel_plane_state(plane->base.state); - -				/* -				 * FIXME don't have the fb yet, so can't -				 * use intel_plane_data_rate() :( -				 */ -				if (plane_state->uapi.visible) -					crtc_state->data_rate[plane->id] = -						4 * crtc_state->pixel_rate; -				else -					crtc_state->data_rate[plane->id] = 0; -			} - -			intel_bw_crtc_update(bw_state, slave_crtc_state); -			drm_calc_timestamping_constants(&slave->base, -							&slave_crtc_state->hw.adjusted_mode); -		}  	}  } @@ -12027,7 +10799,7 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)  	destroy_workqueue(i915->flip_wq);  	destroy_workqueue(i915->modeset_wq); -	intel_fbc_cleanup_cfb(i915); +	intel_fbc_cleanup(i915);  }  /* part #3: call after gem init */ @@ -12042,6 +10814,27 @@ void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915)  	intel_bios_driver_remove(i915);  } +bool intel_modeset_probe_defer(struct pci_dev *pdev) +{ +	struct drm_privacy_screen *privacy_screen; + +	/* +	 * apple-gmux is needed on dual GPU MacBook Pro +	 * to probe the panel if we're the inactive GPU. +	 */ +	if (vga_switcheroo_client_probe_defer(pdev)) +		return true; + +	/* If the LCD panel has a privacy-screen, wait for it */ +	privacy_screen = drm_privacy_screen_get(&pdev->dev, NULL); +	if (IS_ERR(privacy_screen) && PTR_ERR(privacy_screen) == -EPROBE_DEFER) +		return true; + +	drm_privacy_screen_put(privacy_screen); + +	return false; +} +  void intel_display_driver_register(struct drm_i915_private *i915)  {  	if (!HAS_DISPLAY(i915)) |