diff mbox series

[v2,07/13] drm/i915: Store cpu_transcoder_mask in device info

Message ID 20200318170235.15176-1-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series None | expand

Commit Message

Ville Syrjala March 18, 2020, 5:02 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

We have a bunch of code that would like to know which
CPU transcoders are actually present in the hardware. Rather than
use various ad-hoc methods let's just include a full bitmask in
the device info, alongside pipe_mask.

v2: Rebase

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     |  6 ++--
 drivers/gpu/drm/i915/display/intel_display.c | 13 ++-------
 drivers/gpu/drm/i915/display/intel_display.h |  8 ++++--
 drivers/gpu/drm/i915/i915_drv.h              |  2 +-
 drivers/gpu/drm/i915/i915_pci.c              | 23 +++++++++++++++-
 drivers/gpu/drm/i915/intel_device_info.c     | 29 ++++++++++++--------
 drivers/gpu/drm/i915/intel_device_info.h     |  1 +
 7 files changed, 53 insertions(+), 29 deletions(-)

Comments

Souza, Jose April 2, 2020, 12:59 a.m. UTC | #1
On Wed, 2020-03-18 at 19:02 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> We have a bunch of code that would like to know which
> CPU transcoders are actually present in the hardware. Rather than
> use various ad-hoc methods let's just include a full bitmask in
> the device info, alongside pipe_mask.
> 
> v2: Rebase
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  6 ++--
>  drivers/gpu/drm/i915/display/intel_display.c | 13 ++-------
>  drivers/gpu/drm/i915/display/intel_display.h |  8 ++++--
>  drivers/gpu/drm/i915/i915_drv.h              |  2 +-
>  drivers/gpu/drm/i915/i915_pci.c              | 23 +++++++++++++++-
>  drivers/gpu/drm/i915/intel_device_info.c     | 29 ++++++++++++----
> ----
>  drivers/gpu/drm/i915/intel_device_info.h     |  1 +
>  7 files changed, 53 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 8bb6c583abb8..0fea2ec2cdd8 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1689,7 +1689,7 @@ bool intel_ddi_connector_get_hw_state(struct
> intel_connector *intel_connector)
>  		goto out;
>  	}
>  
> -	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
> +	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A)
>  		cpu_transcoder = TRANSCODER_EDP;
>  	else
>  		cpu_transcoder = (enum transcoder) pipe;
> @@ -1751,7 +1751,7 @@ static void intel_ddi_get_encoder_pipes(struct
> intel_encoder *encoder,
>  	if (!(tmp & DDI_BUF_CTL_ENABLE))
>  		goto out;
>  
> -	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A) {
> +	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A)
> {
>  		tmp = intel_de_read(dev_priv,
>  				    TRANS_DDI_FUNC_CTL(TRANSCODER_EDP))
> ;
>  
> @@ -4076,7 +4076,7 @@ static int intel_ddi_compute_config(struct
> intel_encoder *encoder,
>  	enum port port = encoder->port;
>  	int ret;
>  
> -	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
> +	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A)
>  		pipe_config->cpu_transcoder = TRANSCODER_EDP;
>  
>  	if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) {
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 4840988dc58d..292cac64f1ac 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -10855,7 +10855,7 @@ static bool hsw_get_transcoder_state(struct
> intel_crtc *crtc,
>  		panel_transcoder_mask |=
>  			BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1);
>  
> -	if (HAS_TRANSCODER_EDP(dev_priv))
> +	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP))
>  		panel_transcoder_mask |= BIT(TRANSCODER_EDP);
>  
>  	/*
> @@ -18712,15 +18712,6 @@ void
> intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
>  
>  #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
>  
> -static bool
> -has_transcoder(struct drm_i915_private *dev_priv, enum transcoder
> cpu_transcoder)
> -{
> -	if (cpu_transcoder == TRANSCODER_EDP)
> -		return HAS_TRANSCODER_EDP(dev_priv);
> -	else
> -		return INTEL_INFO(dev_priv)->pipe_mask &
> BIT(cpu_transcoder);
> -}
> -
>  struct intel_display_error_state {
>  
>  	u32 power_well_driver;
> @@ -18829,7 +18820,7 @@ intel_display_capture_error_state(struct
> drm_i915_private *dev_priv)
>  	for (i = 0; i < ARRAY_SIZE(error->transcoder); i++) {
>  		enum transcoder cpu_transcoder = transcoders[i];
>  
> -		if (!has_transcoder(dev_priv, cpu_transcoder))
> +		if (!HAS_TRANSCODER(dev_priv, cpu_transcoder))
>  			continue;
>  
>  		error->transcoder[i].available = true;
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h
> b/drivers/gpu/drm/i915/display/intel_display.h
> index adb1225a3480..cc7f287804d7 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -320,9 +320,13 @@ enum phy_fia {
>  	for_each_pipe(__dev_priv, __p) \
>  		for_each_if((__mask) & BIT(__p))
>  
> -#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
> +#define for_each_cpu_transcoder(__dev_priv, __t) \
>  	for ((__t) = 0; (__t) < I915_MAX_TRANSCODERS; (__t)++)	\
> -		for_each_if ((__mask) & (1 << (__t)))
> +		for_each_if (INTEL_INFO(__dev_priv)-
> >cpu_transcoder_mask & BIT(__t))
> +
> +#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
> +	for_each_cpu_transcoder(__dev_priv, __t) \
> +		for_each_if ((__mask) & BIT(__t))
>  
>  #define for_each_universal_plane(__dev_priv, __pipe, __p)		
> \
>  	for ((__p) = 0;							
> \
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index a7ea1d855359..ea9170fd169b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1602,7 +1602,7 @@ IS_SUBPLATFORM(const struct drm_i915_private
> *i915,
>  #define HAS_DDI(dev_priv)		 (INTEL_INFO(dev_priv)-
> >display.has_ddi)
>  #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)-
> >has_fpga_dbg)
>  #define HAS_PSR(dev_priv)		 (INTEL_INFO(dev_priv)-
> >display.has_psr)
> -#define HAS_TRANSCODER_EDP(dev_priv)	 (INTEL_INFO(dev_priv)-
> >trans_offsets[TRANSCODER_EDP] != 0)
> +#define HAS_TRANSCODER(dev_priv, trans)	 ((INTEL_INFO(dev_priv)
> ->cpu_transcoder_mask & BIT(trans)) != 0)
>  
>  #define HAS_RC6(dev_priv)		 (INTEL_INFO(dev_priv)-
> >has_rc6)
>  #define HAS_RC6p(dev_priv)		 (INTEL_INFO(dev_priv)-
> >has_rc6p)
> diff --git a/drivers/gpu/drm/i915/i915_pci.c
> b/drivers/gpu/drm/i915/i915_pci.c
> index 2c80a0194c80..66738f2c4f28 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -160,6 +160,7 @@
>  	GEN(2), \
>  	.is_mobile = 1, \
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
>  	.display.has_overlay = 1, \
>  	.display.cursor_needs_physical = 1, \
>  	.display.overlay_needs_physical = 1, \
> @@ -179,6 +180,7 @@
>  #define I845_FEATURES \
>  	GEN(2), \
>  	.pipe_mask = BIT(PIPE_A), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A), \
>  	.display.has_overlay = 1, \
>  	.display.overlay_needs_physical = 1, \
>  	.display.has_gmch = 1, \
> @@ -218,6 +220,7 @@ static const struct intel_device_info i865g_info
> = {
>  #define GEN3_FEATURES \
>  	GEN(3), \
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
>  	.display.has_gmch = 1, \
>  	.gpu_reset_clobbers_display = true, \
>  	.engine_mask = BIT(RCS0), \
> @@ -303,6 +306,7 @@ static const struct intel_device_info pnv_m_info
> = {
>  #define GEN4_FEATURES \
>  	GEN(4), \
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
>  	.display.has_hotplug = 1, \
>  	.display.has_gmch = 1, \
>  	.gpu_reset_clobbers_display = true, \
> @@ -354,6 +358,7 @@ static const struct intel_device_info gm45_info =
> {
>  #define GEN5_FEATURES \
>  	GEN(5), \
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
>  	.display.has_hotplug = 1, \
>  	.engine_mask = BIT(RCS0) | BIT(VCS0), \
>  	.has_snoop = true, \
> @@ -381,6 +386,7 @@ static const struct intel_device_info ilk_m_info
> = {
>  #define GEN6_FEATURES \
>  	GEN(6), \
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
>  	.display.has_hotplug = 1, \
>  	.display.has_fbc = 1, \
>  	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
> @@ -430,6 +436,7 @@ static const struct intel_device_info
> snb_m_gt2_info = {
>  #define GEN7_FEATURES  \
>  	GEN(7), \
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
> BIT(TRANSCODER_C), \
>  	.display.has_hotplug = 1, \
>  	.display.has_fbc = 1, \
>  	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
> @@ -482,6 +489,7 @@ static const struct intel_device_info ivb_q_info
> = {
>  	PLATFORM(INTEL_IVYBRIDGE),
>  	.gt = 2,
>  	.pipe_mask = 0, /* legal, last one wins */
> +	.cpu_transcoder_mask = 0,
>  	.has_l3_dpf = 1,
>  };
>  
> @@ -490,6 +498,7 @@ static const struct intel_device_info vlv_info =
> {
>  	GEN(7),
>  	.is_lp = 1,
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
>  	.has_runtime_pm = 1,
>  	.has_rc6 = 1,
>  	.has_rps = true,
> @@ -511,6 +520,8 @@ static const struct intel_device_info vlv_info =
> {
>  #define G75_FEATURES  \
>  	GEN7_FEATURES, \
>  	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
> \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
> \
> +		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP), \
>  	.display.has_ddi = 1, \
>  	.has_fpga_dbg = 1, \
>  	.display.has_psr = 1, \
> @@ -581,6 +592,7 @@ static const struct intel_device_info chv_info =
> {
>  	PLATFORM(INTEL_CHERRYVIEW),
>  	GEN(8),
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
> BIT(TRANSCODER_C),
>  	.display.has_hotplug = 1,
>  	.is_lp = 1,
>  	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
> @@ -656,6 +668,9 @@ static const struct intel_device_info
> skl_gt4_info = {
>  	.display.has_hotplug = 1, \
>  	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
> \
>  	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
> \
> +		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
> +		BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
>  	.has_64bit_reloc = 1, \
>  	.display.has_ddi = 1, \
>  	.has_fpga_dbg = 1, \
> @@ -759,6 +774,9 @@ static const struct intel_device_info cnl_info =
> {
>  #define GEN11_FEATURES \
>  	GEN10_FEATURES, \
>  	GEN11_DEFAULT_PAGE_SIZES, \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
> \
> +		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
> +		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \

Some CNL SKUs don't have DSI transcoders but not worthy fix it.

Looks good

Reviewed-by: José Roberto de Souza <jose.souza@intel.com>

>  	.pipe_offsets = { \
>  		[TRANSCODER_A] = PIPE_A_OFFSET, \
>  		[TRANSCODER_B] = PIPE_B_OFFSET, \
> @@ -799,6 +817,10 @@ static const struct intel_device_info ehl_info =
> {
>  #define GEN12_FEATURES \
>  	GEN11_FEATURES, \
>  	GEN(12), \
> +	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) |
> BIT(PIPE_D), \
> +	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
> \
> +		BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | \
> +		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
>  	.pipe_offsets = { \
>  		[TRANSCODER_A] = PIPE_A_OFFSET, \
>  		[TRANSCODER_B] = PIPE_B_OFFSET, \
> @@ -822,7 +844,6 @@ static const struct intel_device_info ehl_info =
> {
>  static const struct intel_device_info tgl_info = {
>  	GEN12_FEATURES,
>  	PLATFORM(INTEL_TIGERLAKE),
> -	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) |
> BIT(PIPE_D),
>  	.display.has_modular_fia = 1,
>  	.engine_mask =
>  		BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) |
> BIT(VCS2),
> diff --git a/drivers/gpu/drm/i915/intel_device_info.c
> b/drivers/gpu/drm/i915/intel_device_info.c
> index 9ff89e142ff1..db8496b4c38d 100644
> --- a/drivers/gpu/drm/i915/intel_device_info.c
> +++ b/drivers/gpu/drm/i915/intel_device_info.c
> @@ -980,25 +980,32 @@ void intel_device_info_runtime_init(struct
> drm_i915_private *dev_priv)
>  			drm_info(&dev_priv->drm,
>  				 "Display fused off, disabling\n");
>  			info->pipe_mask = 0;
> +			info->cpu_transcoder_mask = 0;
>  		} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
>  			drm_info(&dev_priv->drm, "PipeC fused off\n");
>  			info->pipe_mask &= ~BIT(PIPE_C);
> +			info->cpu_transcoder_mask &=
> ~BIT(TRANSCODER_C);
>  		}
>  	} else if (HAS_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 9) {
>  		u32 dfsm = I915_READ(SKL_DFSM);
> -		u8 enabled_mask = info->pipe_mask;
>  
> -		if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
> -			enabled_mask &= ~BIT(PIPE_A);
> -		if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
> -			enabled_mask &= ~BIT(PIPE_B);
> -		if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
> -			enabled_mask &= ~BIT(PIPE_C);
> +		if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
> +			info->pipe_mask &= ~BIT(PIPE_A);
> +			info->cpu_transcoder_mask &=
> ~BIT(TRANSCODER_A);
> +		}
> +		if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
> +			info->pipe_mask &= ~BIT(PIPE_B);
> +			info->cpu_transcoder_mask &=
> ~BIT(TRANSCODER_B);
> +		}
> +		if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
> +			info->pipe_mask &= ~BIT(PIPE_C);
> +			info->cpu_transcoder_mask &=
> ~BIT(TRANSCODER_C);
> +		}
>  		if (INTEL_GEN(dev_priv) >= 12 &&
> -		    (dfsm & TGL_DFSM_PIPE_D_DISABLE))
> -			enabled_mask &= ~BIT(PIPE_D);
> -
> -		info->pipe_mask = enabled_mask;
> +		    (dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
> +			info->pipe_mask &= ~BIT(PIPE_D);
> +			info->cpu_transcoder_mask &=
> ~BIT(TRANSCODER_D);
> +		}
>  
>  		if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
>  			info->display.has_hdcp = 0;
> diff --git a/drivers/gpu/drm/i915/intel_device_info.h
> b/drivers/gpu/drm/i915/intel_device_info.h
> index 1ecb9df2de91..cce6a72c5ebc 100644
> --- a/drivers/gpu/drm/i915/intel_device_info.h
> +++ b/drivers/gpu/drm/i915/intel_device_info.h
> @@ -168,6 +168,7 @@ struct intel_device_info {
>  	u32 display_mmio_offset;
>  
>  	u8 pipe_mask;
> +	u8 cpu_transcoder_mask;
>  
>  #define DEFINE_FLAG(name) u8 name:1
>  	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 8bb6c583abb8..0fea2ec2cdd8 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1689,7 +1689,7 @@  bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
 		goto out;
 	}
 
-	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A)
 		cpu_transcoder = TRANSCODER_EDP;
 	else
 		cpu_transcoder = (enum transcoder) pipe;
@@ -1751,7 +1751,7 @@  static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
 	if (!(tmp & DDI_BUF_CTL_ENABLE))
 		goto out;
 
-	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A) {
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) {
 		tmp = intel_de_read(dev_priv,
 				    TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
 
@@ -4076,7 +4076,7 @@  static int intel_ddi_compute_config(struct intel_encoder *encoder,
 	enum port port = encoder->port;
 	int ret;
 
-	if (HAS_TRANSCODER_EDP(dev_priv) && port == PORT_A)
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A)
 		pipe_config->cpu_transcoder = TRANSCODER_EDP;
 
 	if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) {
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 4840988dc58d..292cac64f1ac 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -10855,7 +10855,7 @@  static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
 		panel_transcoder_mask |=
 			BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1);
 
-	if (HAS_TRANSCODER_EDP(dev_priv))
+	if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP))
 		panel_transcoder_mask |= BIT(TRANSCODER_EDP);
 
 	/*
@@ -18712,15 +18712,6 @@  void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
 
 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
 
-static bool
-has_transcoder(struct drm_i915_private *dev_priv, enum transcoder cpu_transcoder)
-{
-	if (cpu_transcoder == TRANSCODER_EDP)
-		return HAS_TRANSCODER_EDP(dev_priv);
-	else
-		return INTEL_INFO(dev_priv)->pipe_mask & BIT(cpu_transcoder);
-}
-
 struct intel_display_error_state {
 
 	u32 power_well_driver;
@@ -18829,7 +18820,7 @@  intel_display_capture_error_state(struct drm_i915_private *dev_priv)
 	for (i = 0; i < ARRAY_SIZE(error->transcoder); i++) {
 		enum transcoder cpu_transcoder = transcoders[i];
 
-		if (!has_transcoder(dev_priv, cpu_transcoder))
+		if (!HAS_TRANSCODER(dev_priv, cpu_transcoder))
 			continue;
 
 		error->transcoder[i].available = true;
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index adb1225a3480..cc7f287804d7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -320,9 +320,13 @@  enum phy_fia {
 	for_each_pipe(__dev_priv, __p) \
 		for_each_if((__mask) & BIT(__p))
 
-#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
+#define for_each_cpu_transcoder(__dev_priv, __t) \
 	for ((__t) = 0; (__t) < I915_MAX_TRANSCODERS; (__t)++)	\
-		for_each_if ((__mask) & (1 << (__t)))
+		for_each_if (INTEL_INFO(__dev_priv)->cpu_transcoder_mask & BIT(__t))
+
+#define for_each_cpu_transcoder_masked(__dev_priv, __t, __mask) \
+	for_each_cpu_transcoder(__dev_priv, __t) \
+		for_each_if ((__mask) & BIT(__t))
 
 #define for_each_universal_plane(__dev_priv, __pipe, __p)		\
 	for ((__p) = 0;							\
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a7ea1d855359..ea9170fd169b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1602,7 +1602,7 @@  IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_DDI(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_ddi)
 #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->has_fpga_dbg)
 #define HAS_PSR(dev_priv)		 (INTEL_INFO(dev_priv)->display.has_psr)
-#define HAS_TRANSCODER_EDP(dev_priv)	 (INTEL_INFO(dev_priv)->trans_offsets[TRANSCODER_EDP] != 0)
+#define HAS_TRANSCODER(dev_priv, trans)	 ((INTEL_INFO(dev_priv)->cpu_transcoder_mask & BIT(trans)) != 0)
 
 #define HAS_RC6(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6)
 #define HAS_RC6p(dev_priv)		 (INTEL_INFO(dev_priv)->has_rc6p)
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 2c80a0194c80..66738f2c4f28 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -160,6 +160,7 @@ 
 	GEN(2), \
 	.is_mobile = 1, \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_overlay = 1, \
 	.display.cursor_needs_physical = 1, \
 	.display.overlay_needs_physical = 1, \
@@ -179,6 +180,7 @@ 
 #define I845_FEATURES \
 	GEN(2), \
 	.pipe_mask = BIT(PIPE_A), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A), \
 	.display.has_overlay = 1, \
 	.display.overlay_needs_physical = 1, \
 	.display.has_gmch = 1, \
@@ -218,6 +220,7 @@  static const struct intel_device_info i865g_info = {
 #define GEN3_FEATURES \
 	GEN(3), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_gmch = 1, \
 	.gpu_reset_clobbers_display = true, \
 	.engine_mask = BIT(RCS0), \
@@ -303,6 +306,7 @@  static const struct intel_device_info pnv_m_info = {
 #define GEN4_FEATURES \
 	GEN(4), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_hotplug = 1, \
 	.display.has_gmch = 1, \
 	.gpu_reset_clobbers_display = true, \
@@ -354,6 +358,7 @@  static const struct intel_device_info gm45_info = {
 #define GEN5_FEATURES \
 	GEN(5), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_hotplug = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0), \
 	.has_snoop = true, \
@@ -381,6 +386,7 @@  static const struct intel_device_info ilk_m_info = {
 #define GEN6_FEATURES \
 	GEN(6), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
 	.display.has_hotplug = 1, \
 	.display.has_fbc = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
@@ -430,6 +436,7 @@  static const struct intel_device_info snb_m_gt2_info = {
 #define GEN7_FEATURES  \
 	GEN(7), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C), \
 	.display.has_hotplug = 1, \
 	.display.has_fbc = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0), \
@@ -482,6 +489,7 @@  static const struct intel_device_info ivb_q_info = {
 	PLATFORM(INTEL_IVYBRIDGE),
 	.gt = 2,
 	.pipe_mask = 0, /* legal, last one wins */
+	.cpu_transcoder_mask = 0,
 	.has_l3_dpf = 1,
 };
 
@@ -490,6 +498,7 @@  static const struct intel_device_info vlv_info = {
 	GEN(7),
 	.is_lp = 1,
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
 	.has_runtime_pm = 1,
 	.has_rc6 = 1,
 	.has_rps = true,
@@ -511,6 +520,8 @@  static const struct intel_device_info vlv_info = {
 #define G75_FEATURES  \
 	GEN7_FEATURES, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP), \
 	.display.has_ddi = 1, \
 	.has_fpga_dbg = 1, \
 	.display.has_psr = 1, \
@@ -581,6 +592,7 @@  static const struct intel_device_info chv_info = {
 	PLATFORM(INTEL_CHERRYVIEW),
 	GEN(8),
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
 	.display.has_hotplug = 1,
 	.is_lp = 1,
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0),
@@ -656,6 +668,9 @@  static const struct intel_device_info skl_gt4_info = {
 	.display.has_hotplug = 1, \
 	.engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
 	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
+		BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
 	.has_64bit_reloc = 1, \
 	.display.has_ddi = 1, \
 	.has_fpga_dbg = 1, \
@@ -759,6 +774,9 @@  static const struct intel_device_info cnl_info = {
 #define GEN11_FEATURES \
 	GEN10_FEATURES, \
 	GEN11_DEFAULT_PAGE_SIZES, \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP) | \
+		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
 	.pipe_offsets = { \
 		[TRANSCODER_A] = PIPE_A_OFFSET, \
 		[TRANSCODER_B] = PIPE_B_OFFSET, \
@@ -799,6 +817,10 @@  static const struct intel_device_info ehl_info = {
 #define GEN12_FEATURES \
 	GEN11_FEATURES, \
 	GEN(12), \
+	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
+	.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
+		BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | \
+		BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
 	.pipe_offsets = { \
 		[TRANSCODER_A] = PIPE_A_OFFSET, \
 		[TRANSCODER_B] = PIPE_B_OFFSET, \
@@ -822,7 +844,6 @@  static const struct intel_device_info ehl_info = {
 static const struct intel_device_info tgl_info = {
 	GEN12_FEATURES,
 	PLATFORM(INTEL_TIGERLAKE),
-	.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
 	.display.has_modular_fia = 1,
 	.engine_mask =
 		BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 9ff89e142ff1..db8496b4c38d 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -980,25 +980,32 @@  void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
 			drm_info(&dev_priv->drm,
 				 "Display fused off, disabling\n");
 			info->pipe_mask = 0;
+			info->cpu_transcoder_mask = 0;
 		} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
 			drm_info(&dev_priv->drm, "PipeC fused off\n");
 			info->pipe_mask &= ~BIT(PIPE_C);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
 		}
 	} else if (HAS_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 9) {
 		u32 dfsm = I915_READ(SKL_DFSM);
-		u8 enabled_mask = info->pipe_mask;
 
-		if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
-			enabled_mask &= ~BIT(PIPE_A);
-		if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
-			enabled_mask &= ~BIT(PIPE_B);
-		if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
-			enabled_mask &= ~BIT(PIPE_C);
+		if (dfsm & SKL_DFSM_PIPE_A_DISABLE) {
+			info->pipe_mask &= ~BIT(PIPE_A);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_A);
+		}
+		if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
+			info->pipe_mask &= ~BIT(PIPE_B);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);
+		}
+		if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
+			info->pipe_mask &= ~BIT(PIPE_C);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
+		}
 		if (INTEL_GEN(dev_priv) >= 12 &&
-		    (dfsm & TGL_DFSM_PIPE_D_DISABLE))
-			enabled_mask &= ~BIT(PIPE_D);
-
-		info->pipe_mask = enabled_mask;
+		    (dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
+			info->pipe_mask &= ~BIT(PIPE_D);
+			info->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
+		}
 
 		if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
 			info->display.has_hdcp = 0;
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index 1ecb9df2de91..cce6a72c5ebc 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -168,6 +168,7 @@  struct intel_device_info {
 	u32 display_mmio_offset;
 
 	u8 pipe_mask;
+	u8 cpu_transcoder_mask;
 
 #define DEFINE_FLAG(name) u8 name:1
 	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);