All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/26] drm/i915: Pimp DP DFP handling
@ 2020-02-03 15:13 ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Attempt to deal with DP downstream facing ports (DFP) more
thoroughly. This involves reading more of the port caps
and dealing with various clock/bpc limitations.

Also we try to hook up the DP dual mode dongles into the
mix (unfortunately I've not yet seen a DP++ DFP that would
pass the dual mode adapter register i2c accesses through).

And we try to enable YCbCr 444->420 conversion for HDMI DFPs
which could allow some 4k displays to actually use 4k on
pre-icl hardware (which doesn't have native 420 output),
assuming we don't run into some other hardware limits.

It's a bit on the large side but since it looks like other
people are poking around the same area I figured I'd post
the entire thing.

Entire series available here:
git://github.com/vsyrjala/linux.git dp_downstream_ports_5

Ville Syrjälä (26):
  drm/i915: Nuke pre-production GLK HDMI w/a 1139
  drm/i915: Limit display Wa_1405510057 to gen11
  drm/i915: Drop WaDDIIOTimeout:glk
  drm/i915: Add glk to intel_detect_preproduction_hw()
  drm/dp: Include the AUX CH name in the debug messages
  drm/i915/lspcon: Do not send infoframes to non-HDMI sinks
  drm/dp: Define protocol converter DPCD registers
  drm/dp: Define more downstream facing port caps
  drm/i915: Reworkd DFP max bpc handling
  drm/dp: Add helpers to identify downstream facing port types
  drm/dp: Pimp drm_dp_downstream_max_bpc()
  drm/dp: Redo drm_dp_downstream_max_clock() as
    drm_dp_downstream_max_dotclock()
  drm/i915: Reworkd DP DFP clock handling
  drm/i915: Dump downstream facing port caps
  drm/dp: Add drm_dp_downstream_{min,max}_tmds_clock()
  drm/i915: Deal with TMDS DFP clock limits
  drm/i915: Configure DP 1.3+ protocol converted HDMI mode
  drm/dp: Add drm_dp_downstream_mode()
  drm/i915: Handle downstream facing ports w/o EDID
  drm/i915: Extract intel_hdmi_has_audio()
  drm/i915: DP->HDMI TMDS clock limits vs. deep color
  drm/dp: Add helpers for DFP YCbCr 4:2:0 handling
  drm/i915: Do YCbCr 444->420 conversion via DP protocol converters
  drm/i915: Decouple DP++ from the HDMI code
  drm/i915: Try to probe DP++ dongles on DP++ downstream facing ports
  drm/i915: Try to frob the TMDS buffer enable knob on DP++ dongles on
    DP DFPs

 drivers/gpu/drm/drm_dp_helper.c               | 409 +++++++++++++++---
 drivers/gpu/drm/drm_edid.c                    |  21 +
 drivers/gpu/drm/i915/display/intel_ddi.c      |  23 +-
 .../drm/i915/display/intel_display_types.h    |  22 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 367 ++++++++++++++--
 drivers/gpu/drm/i915/display/intel_dp.h       |   1 +
 drivers/gpu/drm/i915/display/intel_hdmi.c     | 181 ++++----
 drivers/gpu/drm/i915/display/intel_hdmi.h     |  11 +-
 drivers/gpu/drm/i915/i915_debugfs.c           |   4 +-
 drivers/gpu/drm/i915/i915_drv.c               |   1 +
 drivers/gpu/drm/i915/i915_drv.h               |   2 +
 drivers/gpu/drm/i915/intel_pm.c               |  10 -
 include/drm/drm_dp_helper.h                   |  63 ++-
 include/drm/drm_edid.h                        |   4 +
 14 files changed, 904 insertions(+), 215 deletions(-)

-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 00/26] drm/i915: Pimp DP DFP handling
@ 2020-02-03 15:13 ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Attempt to deal with DP downstream facing ports (DFP) more
thoroughly. This involves reading more of the port caps
and dealing with various clock/bpc limitations.

Also we try to hook up the DP dual mode dongles into the
mix (unfortunately I've not yet seen a DP++ DFP that would
pass the dual mode adapter register i2c accesses through).

And we try to enable YCbCr 444->420 conversion for HDMI DFPs
which could allow some 4k displays to actually use 4k on
pre-icl hardware (which doesn't have native 420 output),
assuming we don't run into some other hardware limits.

It's a bit on the large side but since it looks like other
people are poking around the same area I figured I'd post
the entire thing.

Entire series available here:
git://github.com/vsyrjala/linux.git dp_downstream_ports_5

Ville Syrjälä (26):
  drm/i915: Nuke pre-production GLK HDMI w/a 1139
  drm/i915: Limit display Wa_1405510057 to gen11
  drm/i915: Drop WaDDIIOTimeout:glk
  drm/i915: Add glk to intel_detect_preproduction_hw()
  drm/dp: Include the AUX CH name in the debug messages
  drm/i915/lspcon: Do not send infoframes to non-HDMI sinks
  drm/dp: Define protocol converter DPCD registers
  drm/dp: Define more downstream facing port caps
  drm/i915: Reworkd DFP max bpc handling
  drm/dp: Add helpers to identify downstream facing port types
  drm/dp: Pimp drm_dp_downstream_max_bpc()
  drm/dp: Redo drm_dp_downstream_max_clock() as
    drm_dp_downstream_max_dotclock()
  drm/i915: Reworkd DP DFP clock handling
  drm/i915: Dump downstream facing port caps
  drm/dp: Add drm_dp_downstream_{min,max}_tmds_clock()
  drm/i915: Deal with TMDS DFP clock limits
  drm/i915: Configure DP 1.3+ protocol converted HDMI mode
  drm/dp: Add drm_dp_downstream_mode()
  drm/i915: Handle downstream facing ports w/o EDID
  drm/i915: Extract intel_hdmi_has_audio()
  drm/i915: DP->HDMI TMDS clock limits vs. deep color
  drm/dp: Add helpers for DFP YCbCr 4:2:0 handling
  drm/i915: Do YCbCr 444->420 conversion via DP protocol converters
  drm/i915: Decouple DP++ from the HDMI code
  drm/i915: Try to probe DP++ dongles on DP++ downstream facing ports
  drm/i915: Try to frob the TMDS buffer enable knob on DP++ dongles on
    DP DFPs

 drivers/gpu/drm/drm_dp_helper.c               | 409 +++++++++++++++---
 drivers/gpu/drm/drm_edid.c                    |  21 +
 drivers/gpu/drm/i915/display/intel_ddi.c      |  23 +-
 .../drm/i915/display/intel_display_types.h    |  22 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 367 ++++++++++++++--
 drivers/gpu/drm/i915/display/intel_dp.h       |   1 +
 drivers/gpu/drm/i915/display/intel_hdmi.c     | 181 ++++----
 drivers/gpu/drm/i915/display/intel_hdmi.h     |  11 +-
 drivers/gpu/drm/i915/i915_debugfs.c           |   4 +-
 drivers/gpu/drm/i915/i915_drv.c               |   1 +
 drivers/gpu/drm/i915/i915_drv.h               |   2 +
 drivers/gpu/drm/i915/intel_pm.c               |  10 -
 include/drm/drm_dp_helper.h                   |  63 ++-
 include/drm/drm_edid.h                        |   4 +
 14 files changed, 904 insertions(+), 215 deletions(-)

-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH 01/26] drm/i915: Nuke pre-production GLK HDMI w/a 1139
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

w/a #1139 is only needed for pre-production GLK. Nuke it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ab13cf834cc4..9e409a819ff5 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2274,11 +2274,6 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		}
 	}
 
-	/* Display WA #1139: glk */
-	if (bpc == 12 && IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1) &&
-	    adjusted_mode->htotal > 5460)
-		return false;
-
 	/* Display Wa_1405510057:icl */
 	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
 	    bpc == 10 && INTEL_GEN(dev_priv) >= 11 &&
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 01/26] drm/i915: Nuke pre-production GLK HDMI w/a 1139
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

w/a #1139 is only needed for pre-production GLK. Nuke it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ab13cf834cc4..9e409a819ff5 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2274,11 +2274,6 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		}
 	}
 
-	/* Display WA #1139: glk */
-	if (bpc == 12 && IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1) &&
-	    adjusted_mode->htotal > 5460)
-		return false;
-
 	/* Display Wa_1405510057:icl */
 	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
 	    bpc == 10 && INTEL_GEN(dev_priv) >= 11 &&
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 02/26] drm/i915: Limit display Wa_1405510057 to gen11
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

TGL+ supposedly do not need Wa_1405510057 so limit it to
gen11 only.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 9e409a819ff5..5991a99c43a8 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2274,9 +2274,9 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		}
 	}
 
-	/* Display Wa_1405510057:icl */
+	/* Display Wa_1405510057:icl,ehl */
 	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
-	    bpc == 10 && INTEL_GEN(dev_priv) >= 11 &&
+	    bpc == 10 && IS_GEN(dev_priv, 11) &&
 	    (adjusted_mode->crtc_hblank_end -
 	     adjusted_mode->crtc_hblank_start) % 8 == 2)
 		return false;
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 02/26] drm/i915: Limit display Wa_1405510057 to gen11
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

TGL+ supposedly do not need Wa_1405510057 so limit it to
gen11 only.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 9e409a819ff5..5991a99c43a8 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2274,9 +2274,9 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		}
 	}
 
-	/* Display Wa_1405510057:icl */
+	/* Display Wa_1405510057:icl,ehl */
 	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
-	    bpc == 10 && INTEL_GEN(dev_priv) >= 11 &&
+	    bpc == 10 && IS_GEN(dev_priv, 11) &&
 	    (adjusted_mode->crtc_hblank_end -
 	     adjusted_mode->crtc_hblank_start) % 8 == 2)
 		return false;
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 03/26] drm/i915: Drop WaDDIIOTimeout:glk
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

WaDDIIOTimeout is only for A1 (pre-prod) glk steppings. Nuke it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a2d2407af2ed..cf373eb6c694 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -128,16 +128,6 @@ static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
 	 */
 	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
 		   PWM1_GATING_DIS | PWM2_GATING_DIS);
-
-	/* WaDDIIOTimeout:glk */
-	if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
-		u32 val = I915_READ(CHICKEN_MISC_2);
-		val &= ~(GLK_CL0_PWR_DOWN |
-			 GLK_CL1_PWR_DOWN |
-			 GLK_CL2_PWR_DOWN);
-		I915_WRITE(CHICKEN_MISC_2, val);
-	}
-
 }
 
 static void pnv_get_mem_freq(struct drm_i915_private *dev_priv)
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 03/26] drm/i915: Drop WaDDIIOTimeout:glk
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

WaDDIIOTimeout is only for A1 (pre-prod) glk steppings. Nuke it.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a2d2407af2ed..cf373eb6c694 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -128,16 +128,6 @@ static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
 	 */
 	I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
 		   PWM1_GATING_DIS | PWM2_GATING_DIS);
-
-	/* WaDDIIOTimeout:glk */
-	if (IS_GLK_REVID(dev_priv, 0, GLK_REVID_A1)) {
-		u32 val = I915_READ(CHICKEN_MISC_2);
-		val &= ~(GLK_CL0_PWR_DOWN |
-			 GLK_CL1_PWR_DOWN |
-			 GLK_CL2_PWR_DOWN);
-		I915_WRITE(CHICKEN_MISC_2, val);
-	}
-
 }
 
 static void pnv_get_mem_freq(struct drm_i915_private *dev_priv)
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 04/26] drm/i915: Add glk to intel_detect_preproduction_hw()
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Detect GLK pre-production steppings. Not 100% of A2 being pre-prod
since the spec is a bit of a mess but feels more or less correct.

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 1 +
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 4661c5f1f297..73d259d99554 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -438,6 +438,7 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv)
 	pre |= IS_SKL_REVID(dev_priv, 0, SKL_REVID_F0);
 	pre |= IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST);
 	pre |= IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0);
+	pre |= IS_GLK_REVID(dev_priv, 0, GLK_REVID_A2);
 
 	if (pre) {
 		DRM_ERROR("This is a pre-production stepping. "
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a71ff233cc55..9df900f9307f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1562,6 +1562,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define GLK_REVID_A0		0x0
 #define GLK_REVID_A1		0x1
+#define GLK_REVID_A2		0x2
+#define GLK_REVID_B0		0x3
 
 #define IS_GLK_REVID(dev_priv, since, until) \
 	(IS_GEMINILAKE(dev_priv) && IS_REVID(dev_priv, since, until))
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 04/26] drm/i915: Add glk to intel_detect_preproduction_hw()
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Detect GLK pre-production steppings. Not 100% of A2 being pre-prod
since the spec is a bit of a mess but feels more or less correct.

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 1 +
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 4661c5f1f297..73d259d99554 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -438,6 +438,7 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv)
 	pre |= IS_SKL_REVID(dev_priv, 0, SKL_REVID_F0);
 	pre |= IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST);
 	pre |= IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0);
+	pre |= IS_GLK_REVID(dev_priv, 0, GLK_REVID_A2);
 
 	if (pre) {
 		DRM_ERROR("This is a pre-production stepping. "
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a71ff233cc55..9df900f9307f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1562,6 +1562,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define GLK_REVID_A0		0x0
 #define GLK_REVID_A1		0x1
+#define GLK_REVID_A2		0x2
+#define GLK_REVID_B0		0x3
 
 #define IS_GLK_REVID(dev_priv, since, until) \
 	(IS_GEMINILAKE(dev_priv) && IS_REVID(dev_priv, since, until))
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 05/26] drm/dp: Include the AUX CH name in the debug messages
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

To make it easier to figure out what caused a particular debug
message let's print out aux->name.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 44 +++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 5a103e9b3c86..f8cedbc3da5d 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -257,7 +257,8 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
 			err = ret;
 	}
 
-	DRM_DEBUG_KMS("Too many retries, giving up. First error: %d\n", err);
+	DRM_DEBUG_KMS("%s: Too many retries, giving up. First error: %d\n",
+		      aux->name, err);
 	ret = err;
 
 unlock:
@@ -678,10 +679,11 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			 * Avoid spamming the kernel log with timeout errors.
 			 */
 			if (ret == -ETIMEDOUT)
-				DRM_DEBUG_KMS_RATELIMITED("transaction timed out\n");
+				DRM_DEBUG_KMS_RATELIMITED("%s: transaction timed out\n",
+							  aux->name);
 			else
-				DRM_DEBUG_KMS("transaction failed: %d\n", ret);
-
+				DRM_DEBUG_KMS("%s: transaction failed: %d\n",
+					      aux->name, ret);
 			return ret;
 		}
 
@@ -695,11 +697,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			break;
 
 		case DP_AUX_NATIVE_REPLY_NACK:
-			DRM_DEBUG_KMS("native nack (result=%d, size=%zu)\n", ret, msg->size);
+			DRM_DEBUG_KMS("%s: native nack (result=%d, size=%zu)\n",
+				      aux->name, ret, msg->size);
 			return -EREMOTEIO;
 
 		case DP_AUX_NATIVE_REPLY_DEFER:
-			DRM_DEBUG_KMS("native defer\n");
+			DRM_DEBUG_KMS("%s: native defer\n", aux->name);
 			/*
 			 * We could check for I2C bit rate capabilities and if
 			 * available adjust this interval. We could also be
@@ -713,7 +716,8 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			continue;
 
 		default:
-			DRM_ERROR("invalid native reply %#04x\n", msg->reply);
+			DRM_ERROR("%s: invalid native reply %#04x\n",
+				  aux->name, msg->reply);
 			return -EREMOTEIO;
 		}
 
@@ -728,13 +732,13 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			return ret;
 
 		case DP_AUX_I2C_REPLY_NACK:
-			DRM_DEBUG_KMS("I2C nack (result=%d, size=%zu)\n",
-				      ret, msg->size);
+			DRM_DEBUG_KMS("%s: I2C nack (result=%d, size=%zu)\n",
+				      aux->name, ret, msg->size);
 			aux->i2c_nack_count++;
 			return -EREMOTEIO;
 
 		case DP_AUX_I2C_REPLY_DEFER:
-			DRM_DEBUG_KMS("I2C defer\n");
+			DRM_DEBUG_KMS("%s: I2C defer\n", aux->name);
 			/* DP Compliance Test 4.2.2.5 Requirement:
 			 * Must have at least 7 retries for I2C defers on the
 			 * transaction to pass this test
@@ -748,12 +752,13 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			continue;
 
 		default:
-			DRM_ERROR("invalid I2C reply %#04x\n", msg->reply);
+			DRM_ERROR("%s: invalid I2C reply %#04x\n",
+				  aux->name, msg->reply);
 			return -EREMOTEIO;
 		}
 	}
 
-	DRM_DEBUG_KMS("too many retries, giving up\n");
+	DRM_DEBUG_KMS("%s: Too many retries, giving up\n", aux->name);
 	return -EREMOTEIO;
 }
 
@@ -782,8 +787,8 @@ static int drm_dp_i2c_drain_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *o
 			return err == 0 ? -EPROTO : err;
 
 		if (err < msg.size && err < ret) {
-			DRM_DEBUG_KMS("Partial I2C reply: requested %zu bytes got %d bytes\n",
-				      msg.size, err);
+			DRM_DEBUG_KMS("%s: Partial I2C reply: requested %zu bytes got %d bytes\n",
+				      aux->name, msg.size, err);
 			ret = err;
 		}
 
@@ -962,11 +967,12 @@ static void drm_dp_aux_crc_work(struct work_struct *work)
 		}
 
 		if (ret == -EAGAIN) {
-			DRM_DEBUG_KMS("Get CRC failed after retrying: %d\n",
-				      ret);
+			DRM_DEBUG_KMS("%s: Get CRC failed after retrying: %d\n",
+				      aux->name, ret);
 			continue;
 		} else if (ret) {
-			DRM_DEBUG_KMS("Failed to get a CRC: %d\n", ret);
+			DRM_DEBUG_KMS("%s: Failed to get a CRC: %d\n",
+				      aux->name, ret);
 			continue;
 		}
 
@@ -1247,8 +1253,8 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
 
 	dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id));
 
-	DRM_DEBUG_KMS("DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d quirks 0x%04x\n",
-		      is_branch ? "branch" : "sink",
+	DRM_DEBUG_KMS("%s: DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d quirks 0x%04x\n",
+		      aux->name, is_branch ? "branch" : "sink",
 		      (int)sizeof(ident->oui), ident->oui,
 		      dev_id_len, ident->device_id,
 		      ident->hw_rev >> 4, ident->hw_rev & 0xf,
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 05/26] drm/dp: Include the AUX CH name in the debug messages
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

To make it easier to figure out what caused a particular debug
message let's print out aux->name.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 44 +++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 5a103e9b3c86..f8cedbc3da5d 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -257,7 +257,8 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
 			err = ret;
 	}
 
-	DRM_DEBUG_KMS("Too many retries, giving up. First error: %d\n", err);
+	DRM_DEBUG_KMS("%s: Too many retries, giving up. First error: %d\n",
+		      aux->name, err);
 	ret = err;
 
 unlock:
@@ -678,10 +679,11 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			 * Avoid spamming the kernel log with timeout errors.
 			 */
 			if (ret == -ETIMEDOUT)
-				DRM_DEBUG_KMS_RATELIMITED("transaction timed out\n");
+				DRM_DEBUG_KMS_RATELIMITED("%s: transaction timed out\n",
+							  aux->name);
 			else
-				DRM_DEBUG_KMS("transaction failed: %d\n", ret);
-
+				DRM_DEBUG_KMS("%s: transaction failed: %d\n",
+					      aux->name, ret);
 			return ret;
 		}
 
@@ -695,11 +697,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			break;
 
 		case DP_AUX_NATIVE_REPLY_NACK:
-			DRM_DEBUG_KMS("native nack (result=%d, size=%zu)\n", ret, msg->size);
+			DRM_DEBUG_KMS("%s: native nack (result=%d, size=%zu)\n",
+				      aux->name, ret, msg->size);
 			return -EREMOTEIO;
 
 		case DP_AUX_NATIVE_REPLY_DEFER:
-			DRM_DEBUG_KMS("native defer\n");
+			DRM_DEBUG_KMS("%s: native defer\n", aux->name);
 			/*
 			 * We could check for I2C bit rate capabilities and if
 			 * available adjust this interval. We could also be
@@ -713,7 +716,8 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			continue;
 
 		default:
-			DRM_ERROR("invalid native reply %#04x\n", msg->reply);
+			DRM_ERROR("%s: invalid native reply %#04x\n",
+				  aux->name, msg->reply);
 			return -EREMOTEIO;
 		}
 
@@ -728,13 +732,13 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			return ret;
 
 		case DP_AUX_I2C_REPLY_NACK:
-			DRM_DEBUG_KMS("I2C nack (result=%d, size=%zu)\n",
-				      ret, msg->size);
+			DRM_DEBUG_KMS("%s: I2C nack (result=%d, size=%zu)\n",
+				      aux->name, ret, msg->size);
 			aux->i2c_nack_count++;
 			return -EREMOTEIO;
 
 		case DP_AUX_I2C_REPLY_DEFER:
-			DRM_DEBUG_KMS("I2C defer\n");
+			DRM_DEBUG_KMS("%s: I2C defer\n", aux->name);
 			/* DP Compliance Test 4.2.2.5 Requirement:
 			 * Must have at least 7 retries for I2C defers on the
 			 * transaction to pass this test
@@ -748,12 +752,13 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			continue;
 
 		default:
-			DRM_ERROR("invalid I2C reply %#04x\n", msg->reply);
+			DRM_ERROR("%s: invalid I2C reply %#04x\n",
+				  aux->name, msg->reply);
 			return -EREMOTEIO;
 		}
 	}
 
-	DRM_DEBUG_KMS("too many retries, giving up\n");
+	DRM_DEBUG_KMS("%s: Too many retries, giving up\n", aux->name);
 	return -EREMOTEIO;
 }
 
@@ -782,8 +787,8 @@ static int drm_dp_i2c_drain_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *o
 			return err == 0 ? -EPROTO : err;
 
 		if (err < msg.size && err < ret) {
-			DRM_DEBUG_KMS("Partial I2C reply: requested %zu bytes got %d bytes\n",
-				      msg.size, err);
+			DRM_DEBUG_KMS("%s: Partial I2C reply: requested %zu bytes got %d bytes\n",
+				      aux->name, msg.size, err);
 			ret = err;
 		}
 
@@ -962,11 +967,12 @@ static void drm_dp_aux_crc_work(struct work_struct *work)
 		}
 
 		if (ret == -EAGAIN) {
-			DRM_DEBUG_KMS("Get CRC failed after retrying: %d\n",
-				      ret);
+			DRM_DEBUG_KMS("%s: Get CRC failed after retrying: %d\n",
+				      aux->name, ret);
 			continue;
 		} else if (ret) {
-			DRM_DEBUG_KMS("Failed to get a CRC: %d\n", ret);
+			DRM_DEBUG_KMS("%s: Failed to get a CRC: %d\n",
+				      aux->name, ret);
 			continue;
 		}
 
@@ -1247,8 +1253,8 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
 
 	dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id));
 
-	DRM_DEBUG_KMS("DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d quirks 0x%04x\n",
-		      is_branch ? "branch" : "sink",
+	DRM_DEBUG_KMS("%s: DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d quirks 0x%04x\n",
+		      aux->name, is_branch ? "branch" : "sink",
 		      (int)sizeof(ident->oui), ident->oui,
 		      dev_id_len, ident->device_id,
 		      ident->hw_rev >> 4, ident->hw_rev & 0xf,
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 06/26] drm/i915/lspcon: Do not send infoframes to non-HDMI sinks
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Non-HDMI sinks shouldn't be sent infoframes. Check for that when
using LSPCON.

FIXME: How do we turn off infoframes once enabled? Do we even
       have to?

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c           | 10 ++++------
 drivers/gpu/drm/i915/display/intel_display_types.h |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c            |  7 ++++++-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index aa066fb9eb00..818bee4918fa 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3658,18 +3658,16 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder,
 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
 		intel_ddi_pre_enable_hdmi(encoder, crtc_state, conn_state);
 	} else {
-		struct intel_lspcon *lspcon =
-				enc_to_intel_lspcon(encoder);
+		struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
 		intel_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
-		if (lspcon->active) {
-			struct intel_digital_port *dig_port =
-					enc_to_dig_port(encoder);
 
+		/* FIXME precompute everything properly */
+		/* FIXME how do we turn infoframes off again? */
+		if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
 			dig_port->set_infoframes(encoder,
 						 crtc_state->has_infoframe,
 						 crtc_state, conn_state);
-		}
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 7c6133a9c51b..5774240c0996 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1207,6 +1207,7 @@ struct intel_dp {
 	u8 sink_count;
 	bool link_mst;
 	bool link_trained;
+	bool has_hdmi_sink;
 	bool has_audio;
 	bool reset_link_params;
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f4dede6253f8..1786e6e8ffe3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5664,7 +5664,11 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 	edid = intel_dp_get_edid(intel_dp);
 	intel_connector->detect_edid = edid;
 
-	intel_dp->has_audio = drm_detect_monitor_audio(edid);
+	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
+		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
+		intel_dp->has_audio = drm_detect_monitor_audio(edid);
+	}
+
 	drm_dp_cec_set_edid(&intel_dp->aux, edid);
 }
 
@@ -5677,6 +5681,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	kfree(intel_connector->detect_edid);
 	intel_connector->detect_edid = NULL;
 
+	intel_dp->has_hdmi_sink = false;
 	intel_dp->has_audio = false;
 }
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 06/26] drm/i915/lspcon: Do not send infoframes to non-HDMI sinks
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Non-HDMI sinks shouldn't be sent infoframes. Check for that when
using LSPCON.

FIXME: How do we turn off infoframes once enabled? Do we even
       have to?

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c           | 10 ++++------
 drivers/gpu/drm/i915/display/intel_display_types.h |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c            |  7 ++++++-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index aa066fb9eb00..818bee4918fa 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3658,18 +3658,16 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder,
 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
 		intel_ddi_pre_enable_hdmi(encoder, crtc_state, conn_state);
 	} else {
-		struct intel_lspcon *lspcon =
-				enc_to_intel_lspcon(encoder);
+		struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
 		intel_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
-		if (lspcon->active) {
-			struct intel_digital_port *dig_port =
-					enc_to_dig_port(encoder);
 
+		/* FIXME precompute everything properly */
+		/* FIXME how do we turn infoframes off again? */
+		if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
 			dig_port->set_infoframes(encoder,
 						 crtc_state->has_infoframe,
 						 crtc_state, conn_state);
-		}
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 7c6133a9c51b..5774240c0996 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1207,6 +1207,7 @@ struct intel_dp {
 	u8 sink_count;
 	bool link_mst;
 	bool link_trained;
+	bool has_hdmi_sink;
 	bool has_audio;
 	bool reset_link_params;
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index f4dede6253f8..1786e6e8ffe3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5664,7 +5664,11 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 	edid = intel_dp_get_edid(intel_dp);
 	intel_connector->detect_edid = edid;
 
-	intel_dp->has_audio = drm_detect_monitor_audio(edid);
+	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
+		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
+		intel_dp->has_audio = drm_detect_monitor_audio(edid);
+	}
+
 	drm_dp_cec_set_edid(&intel_dp->aux, edid);
 }
 
@@ -5677,6 +5681,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	kfree(intel_connector->detect_edid);
 	intel_connector->detect_edid = NULL;
 
+	intel_dp->has_hdmi_sink = false;
 	intel_dp->has_audio = false;
 }
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 07/26] drm/dp: Define protocol converter DPCD registers
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

DP 1.3 and 1.4 introduced some new registers for DP->HDMI protocol
converters. Define those.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 include/drm/drm_dp_helper.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 262faf9e5e94..faf05cda5043 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -974,6 +974,16 @@
 #define DP_CEC_TX_MESSAGE_BUFFER               0x3020
 #define DP_CEC_MESSAGE_BUFFER_LENGTH             0x10
 
+#define DP_PROTOCOL_CONVERTER_CONTROL_0		0x3050 /* DP 1.3 */
+# define DP_HDMI_DVI_OUTPUT_CONFIG		(1 << 0) /* DP 1.3 */
+#define DP_PROTOCOL_CONVERTER_CONTROL_1		0x3051 /* DP 1.3 */
+# define DP_CONVERSION_TO_YCBCR420_ENABLE	(1 << 0) /* DP 1.3 */
+# define DP_HDMI_EDID_PROCESSING_DISABLE	(1 << 1) /* DP 1.4 */
+# define DP_HDMI_AUTONOMOUS_SCRAMBLING_DISABLE	(1 << 2) /* DP 1.4 */
+# define DP_HDMI_FORCE_SCRAMBLING		(1 << 3) /* DP 1.4 */
+#define DP_PROTOCOL_CONVERTER_CONTROL_2		0x3052 /* DP 1.3 */
+# define DP_CONVERSION_TO_YCBCR422_ENABLE	(1 << 0) /* DP 1.3 */
+
 #define DP_AUX_HDCP_BKSV		0x68000
 #define DP_AUX_HDCP_RI_PRIME		0x68005
 #define DP_AUX_HDCP_AKSV		0x68007
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 07/26] drm/dp: Define protocol converter DPCD registers
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

DP 1.3 and 1.4 introduced some new registers for DP->HDMI protocol
converters. Define those.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 include/drm/drm_dp_helper.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 262faf9e5e94..faf05cda5043 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -974,6 +974,16 @@
 #define DP_CEC_TX_MESSAGE_BUFFER               0x3020
 #define DP_CEC_MESSAGE_BUFFER_LENGTH             0x10
 
+#define DP_PROTOCOL_CONVERTER_CONTROL_0		0x3050 /* DP 1.3 */
+# define DP_HDMI_DVI_OUTPUT_CONFIG		(1 << 0) /* DP 1.3 */
+#define DP_PROTOCOL_CONVERTER_CONTROL_1		0x3051 /* DP 1.3 */
+# define DP_CONVERSION_TO_YCBCR420_ENABLE	(1 << 0) /* DP 1.3 */
+# define DP_HDMI_EDID_PROCESSING_DISABLE	(1 << 1) /* DP 1.4 */
+# define DP_HDMI_AUTONOMOUS_SCRAMBLING_DISABLE	(1 << 2) /* DP 1.4 */
+# define DP_HDMI_FORCE_SCRAMBLING		(1 << 3) /* DP 1.4 */
+#define DP_PROTOCOL_CONVERTER_CONTROL_2		0x3052 /* DP 1.3 */
+# define DP_CONVERSION_TO_YCBCR422_ENABLE	(1 << 0) /* DP 1.3 */
+
 #define DP_AUX_HDCP_BKSV		0x68000
 #define DP_AUX_HDCP_RI_PRIME		0x68005
 #define DP_AUX_HDCP_AKSV		0x68007
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 08/26] drm/dp: Define more downstream facing port caps
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Our definitions for the DPCD DFP capabilities are lacking.
Add the missing bits.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 include/drm/drm_dp_helper.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index faf05cda5043..2ffa47f875fa 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -385,12 +385,18 @@
 # define DP_DS_PORT_TYPE_WIRELESS           6
 # define DP_DS_PORT_HPD			    (1 << 3)
 /* offset 1 for VGA is maximum megapixels per second / 8 */
-/* offset 2 */
+/* offset 1 for DVI/HDMI is maximum TMDS clock in Mbps / 2.5 */
+/* offset 2 for VGA/DVI/HDMI */
 # define DP_DS_MAX_BPC_MASK	            (3 << 0)
 # define DP_DS_8BPC		            0
 # define DP_DS_10BPC		            1
 # define DP_DS_12BPC		            2
 # define DP_DS_16BPC		            3
+/* offset 3 for DVI */
+# define DP_DS_DVI_DUAL_LINK		    (1 << 1)
+# define DP_DS_DVI_HIGH_COLOR_DEPTH	    (1 << 2)
+/* offset 3 for HDMI */
+# define DP_DS_HDMI_FRAME_SEQ_TO_FRAME_PACK (1 << 0)
 
 #define DP_MAX_DOWNSTREAM_PORTS		    0x10
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 08/26] drm/dp: Define more downstream facing port caps
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Our definitions for the DPCD DFP capabilities are lacking.
Add the missing bits.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 include/drm/drm_dp_helper.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index faf05cda5043..2ffa47f875fa 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -385,12 +385,18 @@
 # define DP_DS_PORT_TYPE_WIRELESS           6
 # define DP_DS_PORT_HPD			    (1 << 3)
 /* offset 1 for VGA is maximum megapixels per second / 8 */
-/* offset 2 */
+/* offset 1 for DVI/HDMI is maximum TMDS clock in Mbps / 2.5 */
+/* offset 2 for VGA/DVI/HDMI */
 # define DP_DS_MAX_BPC_MASK	            (3 << 0)
 # define DP_DS_8BPC		            0
 # define DP_DS_10BPC		            1
 # define DP_DS_12BPC		            2
 # define DP_DS_16BPC		            3
+/* offset 3 for DVI */
+# define DP_DS_DVI_DUAL_LINK		    (1 << 1)
+# define DP_DS_DVI_HIGH_COLOR_DEPTH	    (1 << 2)
+/* offset 3 for HDMI */
+# define DP_DS_HDMI_FRAME_SEQ_TO_FRAME_PACK (1 << 0)
 
 #define DP_MAX_DOWNSTREAM_PORTS		    0x10
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 09/26] drm/i915: Reworkd DFP max bpc handling
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Stash the downstream facing port max bpc away during
intel_dp_set_edid(). We'll soon need the EDID in there so
we can't figure this out so easily during .compute_config() anymore.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  5 +++++
 drivers/gpu/drm/i915/display/intel_dp.c       | 21 +++++++++++++------
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5774240c0996..dba0bb245a43 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1304,6 +1304,11 @@ struct intel_dp {
 
 	/* Display stream compression testing */
 	bool force_dsc_en;
+
+	/* Downstream facing port caps */
+	struct {
+		u8 max_bpc;
+	} dfp;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 1786e6e8ffe3..5fab7ab97815 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1914,13 +1914,12 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	int bpp, bpc;
+	int bpp;
 
 	bpp = pipe_config->pipe_bpp;
-	bpc = drm_dp_downstream_max_bpc(intel_dp->dpcd, intel_dp->downstream_ports);
 
-	if (bpc > 0)
-		bpp = min(bpp, 3*bpc);
+	if (intel_dp->dfp.max_bpc)
+		bpp = min(bpp, 3 * intel_dp->dfp.max_bpc);
 
 	if (intel_dp_is_edp(intel_dp)) {
 		/* Get bpp from vbt only for panels that dont have bpp in edid */
@@ -5657,12 +5656,20 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
 static void
 intel_dp_set_edid(struct intel_dp *intel_dp)
 {
-	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct intel_connector *connector = intel_dp->attached_connector;
 	struct edid *edid;
 
 	intel_dp_unset_edid(intel_dp);
 	edid = intel_dp_get_edid(intel_dp);
-	intel_connector->detect_edid = edid;
+	connector->detect_edid = edid;
+
+	intel_dp->dfp.max_bpc =
+		drm_dp_downstream_max_bpc(intel_dp->dpcd,
+					  intel_dp->downstream_ports);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d\n",
+		      connector->base.base.id, connector->base.name,
+		      intel_dp->dfp.max_bpc);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5683,6 +5690,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 
 	intel_dp->has_hdmi_sink = false;
 	intel_dp->has_audio = false;
+
+	intel_dp->dfp.max_bpc = 0;
 }
 
 static int
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 09/26] drm/i915: Reworkd DFP max bpc handling
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Stash the downstream facing port max bpc away during
intel_dp_set_edid(). We'll soon need the EDID in there so
we can't figure this out so easily during .compute_config() anymore.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  5 +++++
 drivers/gpu/drm/i915/display/intel_dp.c       | 21 +++++++++++++------
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5774240c0996..dba0bb245a43 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1304,6 +1304,11 @@ struct intel_dp {
 
 	/* Display stream compression testing */
 	bool force_dsc_en;
+
+	/* Downstream facing port caps */
+	struct {
+		u8 max_bpc;
+	} dfp;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 1786e6e8ffe3..5fab7ab97815 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1914,13 +1914,12 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	int bpp, bpc;
+	int bpp;
 
 	bpp = pipe_config->pipe_bpp;
-	bpc = drm_dp_downstream_max_bpc(intel_dp->dpcd, intel_dp->downstream_ports);
 
-	if (bpc > 0)
-		bpp = min(bpp, 3*bpc);
+	if (intel_dp->dfp.max_bpc)
+		bpp = min(bpp, 3 * intel_dp->dfp.max_bpc);
 
 	if (intel_dp_is_edp(intel_dp)) {
 		/* Get bpp from vbt only for panels that dont have bpp in edid */
@@ -5657,12 +5656,20 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
 static void
 intel_dp_set_edid(struct intel_dp *intel_dp)
 {
-	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct intel_connector *connector = intel_dp->attached_connector;
 	struct edid *edid;
 
 	intel_dp_unset_edid(intel_dp);
 	edid = intel_dp_get_edid(intel_dp);
-	intel_connector->detect_edid = edid;
+	connector->detect_edid = edid;
+
+	intel_dp->dfp.max_bpc =
+		drm_dp_downstream_max_bpc(intel_dp->dpcd,
+					  intel_dp->downstream_ports);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d\n",
+		      connector->base.base.id, connector->base.name,
+		      intel_dp->dfp.max_bpc);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5683,6 +5690,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 
 	intel_dp->has_hdmi_sink = false;
 	intel_dp->has_audio = false;
+
+	intel_dp->dfp.max_bpc = 0;
 }
 
 static int
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 10/26] drm/dp: Add helpers to identify downstream facing port types
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add a few helpers to let us better identify which kind of DFP
we're dealing with.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 60 +++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |  5 +++
 2 files changed, 65 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index f8cedbc3da5d..bdb7ae3ce32e 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -362,6 +362,66 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 
+static bool is_edid_digital_input_dp(const struct edid *edid)
+{
+	return edid && edid->revision >= 4 &&
+		edid->input & DRM_EDID_INPUT_DIGITAL &&
+		(edid->input & DRM_EDID_DIGITAL_TYPE_MASK) == DRM_EDID_DIGITAL_TYPE_DP;
+}
+
+/**
+ * drm_dp_downstream_is_type() - is the downstream facing port of certain type?
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ *
+ * Caveat: Only works with DPCD 1.1+ port caps.
+ *
+ * Returns whether the downstream facing port matches the type.
+ */
+bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4], u8 type)
+{
+	return drm_dp_is_branch(dpcd) &&
+		dpcd[DP_DPCD_REV] >= 0x11 &&
+		(port_cap[0] & DP_DS_PORT_TYPE_MASK) == type;
+}
+EXPORT_SYMBOL(drm_dp_downstream_is_type);
+
+/**
+ * drm_dp_downstream_is_tmds() - is the downstream facing port TMDS?
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ * @edid: EDID
+ *
+ * Returns whether the downstream facing port is TMDS (HDMI/DVI).
+ */
+bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4],
+			       const struct edid *edid)
+{
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_TMDS:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP_DUALMODE:
+		if (is_edid_digital_input_dp(edid))
+			return false;
+		/* fall through */
+	case DP_DS_PORT_TYPE_DVI:
+	case DP_DS_PORT_TYPE_HDMI:
+		return true;
+	default:
+		return false;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_is_tmds);
+
 /**
  * drm_dp_downstream_max_clock() - extract branch device max
  *                                 pixel rate for legacy VGA
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 2ffa47f875fa..958db298adc7 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1475,6 +1475,11 @@ static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux,
 int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 				 u8 status[DP_LINK_STATUS_SIZE]);
 
+bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4], u8 type);
+bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4],
+			       const struct edid *edid);
 int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 				const u8 port_cap[4]);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 10/26] drm/dp: Add helpers to identify downstream facing port types
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add a few helpers to let us better identify which kind of DFP
we're dealing with.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 60 +++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |  5 +++
 2 files changed, 65 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index f8cedbc3da5d..bdb7ae3ce32e 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -362,6 +362,66 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 
+static bool is_edid_digital_input_dp(const struct edid *edid)
+{
+	return edid && edid->revision >= 4 &&
+		edid->input & DRM_EDID_INPUT_DIGITAL &&
+		(edid->input & DRM_EDID_DIGITAL_TYPE_MASK) == DRM_EDID_DIGITAL_TYPE_DP;
+}
+
+/**
+ * drm_dp_downstream_is_type() - is the downstream facing port of certain type?
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ *
+ * Caveat: Only works with DPCD 1.1+ port caps.
+ *
+ * Returns whether the downstream facing port matches the type.
+ */
+bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4], u8 type)
+{
+	return drm_dp_is_branch(dpcd) &&
+		dpcd[DP_DPCD_REV] >= 0x11 &&
+		(port_cap[0] & DP_DS_PORT_TYPE_MASK) == type;
+}
+EXPORT_SYMBOL(drm_dp_downstream_is_type);
+
+/**
+ * drm_dp_downstream_is_tmds() - is the downstream facing port TMDS?
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ * @edid: EDID
+ *
+ * Returns whether the downstream facing port is TMDS (HDMI/DVI).
+ */
+bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4],
+			       const struct edid *edid)
+{
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_TMDS:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP_DUALMODE:
+		if (is_edid_digital_input_dp(edid))
+			return false;
+		/* fall through */
+	case DP_DS_PORT_TYPE_DVI:
+	case DP_DS_PORT_TYPE_HDMI:
+		return true;
+	default:
+		return false;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_is_tmds);
+
 /**
  * drm_dp_downstream_max_clock() - extract branch device max
  *                                 pixel rate for legacy VGA
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 2ffa47f875fa..958db298adc7 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1475,6 +1475,11 @@ static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux,
 int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 				 u8 status[DP_LINK_STATUS_SIZE]);
 
+bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4], u8 type);
+bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			       const u8 port_cap[4],
+			       const struct edid *edid);
 int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 				const u8 port_cap[4]);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 11/26] drm/dp: Pimp drm_dp_downstream_max_bpc()
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Deal with more cases in drm_dp_downstream_max_bpc():
- DPCD 1.0 -> assume 8bpc for non-DP
- DPCD 1.1+ DP (or DP++ with DP sink) -> allow anything
- DPCD 1.1+ TMDS -> check the caps, assume 8bpc if the value is crap
- anything else -> assume 8bpc

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c         | 65 ++++++++++++++++---------
 drivers/gpu/drm/i915/display/intel_dp.c |  2 +-
 drivers/gpu/drm/i915/i915_debugfs.c     |  4 +-
 include/drm/drm_dp_helper.h             | 10 ++--
 4 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index bdb7ae3ce32e..7164b9d274e1 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -456,32 +456,44 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 EXPORT_SYMBOL(drm_dp_downstream_max_clock);
 
 /**
- * drm_dp_downstream_max_bpc() - extract branch device max
- *                               bits per component
- * @dpcd: DisplayPort configuration data
- * @port_cap: port capabilities
- *
- * Returns max bpc on success or 0 if max bpc not defined
- */
+  * drm_dp_downstream_max_bpc() - extract downstream facing port max
+  *                               bits per component
+  * @dpcd: DisplayPort configuration data
+  * @port_cap: downstream facing port capabilities
+  * @edid: EDID
+  *
+  * Returns max bpc on success or 0 if max bpc not defined
+  */
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			      const u8 port_cap[4])
+			      const u8 port_cap[4],
+			      const struct edid *edid)
 {
-	int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
-	bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
-		DP_DETAILED_CAP_INFO_AVAILABLE;
-	int bpc;
-
-	if (!detailed_cap_info)
+	if (!drm_dp_is_branch(dpcd))
 		return 0;
 
-	switch (type) {
-	case DP_DS_PORT_TYPE_VGA:
-	case DP_DS_PORT_TYPE_DVI:
-	case DP_DS_PORT_TYPE_HDMI:
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_DP:
+			return 0;
+		default:
+			return 8;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP:
+		return 0;
 	case DP_DS_PORT_TYPE_DP_DUALMODE:
-		bpc = port_cap[2] & DP_DS_MAX_BPC_MASK;
+		if (is_edid_digital_input_dp(edid))
+			return 0;
+		/* fall through */
+	case DP_DS_PORT_TYPE_HDMI:
+	case DP_DS_PORT_TYPE_DVI:
+	case DP_DS_PORT_TYPE_VGA:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 8;
 
-		switch (bpc) {
+		switch (port_cap[2] & DP_DS_MAX_BPC_MASK) {
 		case DP_DS_8BPC:
 			return 8;
 		case DP_DS_10BPC:
@@ -490,10 +502,12 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			return 12;
 		case DP_DS_16BPC:
 			return 16;
+		default:
+			return 8;
 		}
-		/* fall through */
+		break;
 	default:
-		return 0;
+		return 8;
 	}
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
@@ -516,12 +530,15 @@ EXPORT_SYMBOL(drm_dp_downstream_id);
  * @m: pointer for debugfs file
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
+ * @edid: EDID
  * @aux: DisplayPort AUX channel
  *
  */
 void drm_dp_downstream_debug(struct seq_file *m,
 			     const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			     const u8 port_cap[4], struct drm_dp_aux *aux)
+			     const u8 port_cap[4],
+			     const struct edid *edid,
+			     struct drm_dp_aux *aux)
 {
 	bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
 				 DP_DETAILED_CAP_INFO_AVAILABLE;
@@ -588,7 +605,7 @@ void drm_dp_downstream_debug(struct seq_file *m,
 				seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
 		}
 
-		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap);
+		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, edid);
 
 		if (bpc > 0)
 			seq_printf(m, "\t\tMax bpc: %d\n", bpc);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5fab7ab97815..706750f9379e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5665,7 +5665,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 
 	intel_dp->dfp.max_bpc =
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
-					  intel_dp->downstream_ports);
+					  intel_dp->downstream_ports, edid);
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d\n",
 		      connector->base.base.id, connector->base.name,
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index e75e8212f03b..cfef38932f65 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2393,6 +2393,7 @@ static void intel_dp_info(struct seq_file *m,
 {
 	struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
 	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
+	const struct drm_property_blob *edid = intel_connector->base.edid_blob_ptr;
 
 	seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
 	seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio));
@@ -2400,7 +2401,8 @@ static void intel_dp_info(struct seq_file *m,
 		intel_panel_info(m, &intel_connector->panel);
 
 	drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
-				&intel_dp->aux);
+				edid ? edid->data : NULL, &intel_dp->aux);
+
 	if (intel_connector->hdcp.shim) {
 		seq_puts(m, "\tHDCP version: ");
 		intel_hdcp_info(m, intel_connector);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 958db298adc7..62637acaefee 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1483,10 +1483,14 @@ bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 				const u8 port_cap[4]);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			      const u8 port_cap[4]);
+			      const u8 port_cap[4],
+			      const struct edid *edid);
 int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]);
-void drm_dp_downstream_debug(struct seq_file *m, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			     const u8 port_cap[4], struct drm_dp_aux *aux);
+void drm_dp_downstream_debug(struct seq_file *m,
+			     const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			     const u8 port_cap[4],
+			     const struct edid *edid,
+			     struct drm_dp_aux *aux);
 
 void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
 void drm_dp_aux_init(struct drm_dp_aux *aux);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 11/26] drm/dp: Pimp drm_dp_downstream_max_bpc()
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Deal with more cases in drm_dp_downstream_max_bpc():
- DPCD 1.0 -> assume 8bpc for non-DP
- DPCD 1.1+ DP (or DP++ with DP sink) -> allow anything
- DPCD 1.1+ TMDS -> check the caps, assume 8bpc if the value is crap
- anything else -> assume 8bpc

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c         | 65 ++++++++++++++++---------
 drivers/gpu/drm/i915/display/intel_dp.c |  2 +-
 drivers/gpu/drm/i915/i915_debugfs.c     |  4 +-
 include/drm/drm_dp_helper.h             | 10 ++--
 4 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index bdb7ae3ce32e..7164b9d274e1 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -456,32 +456,44 @@ int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 EXPORT_SYMBOL(drm_dp_downstream_max_clock);
 
 /**
- * drm_dp_downstream_max_bpc() - extract branch device max
- *                               bits per component
- * @dpcd: DisplayPort configuration data
- * @port_cap: port capabilities
- *
- * Returns max bpc on success or 0 if max bpc not defined
- */
+  * drm_dp_downstream_max_bpc() - extract downstream facing port max
+  *                               bits per component
+  * @dpcd: DisplayPort configuration data
+  * @port_cap: downstream facing port capabilities
+  * @edid: EDID
+  *
+  * Returns max bpc on success or 0 if max bpc not defined
+  */
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			      const u8 port_cap[4])
+			      const u8 port_cap[4],
+			      const struct edid *edid)
 {
-	int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
-	bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
-		DP_DETAILED_CAP_INFO_AVAILABLE;
-	int bpc;
-
-	if (!detailed_cap_info)
+	if (!drm_dp_is_branch(dpcd))
 		return 0;
 
-	switch (type) {
-	case DP_DS_PORT_TYPE_VGA:
-	case DP_DS_PORT_TYPE_DVI:
-	case DP_DS_PORT_TYPE_HDMI:
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_DP:
+			return 0;
+		default:
+			return 8;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP:
+		return 0;
 	case DP_DS_PORT_TYPE_DP_DUALMODE:
-		bpc = port_cap[2] & DP_DS_MAX_BPC_MASK;
+		if (is_edid_digital_input_dp(edid))
+			return 0;
+		/* fall through */
+	case DP_DS_PORT_TYPE_HDMI:
+	case DP_DS_PORT_TYPE_DVI:
+	case DP_DS_PORT_TYPE_VGA:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 8;
 
-		switch (bpc) {
+		switch (port_cap[2] & DP_DS_MAX_BPC_MASK) {
 		case DP_DS_8BPC:
 			return 8;
 		case DP_DS_10BPC:
@@ -490,10 +502,12 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			return 12;
 		case DP_DS_16BPC:
 			return 16;
+		default:
+			return 8;
 		}
-		/* fall through */
+		break;
 	default:
-		return 0;
+		return 8;
 	}
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
@@ -516,12 +530,15 @@ EXPORT_SYMBOL(drm_dp_downstream_id);
  * @m: pointer for debugfs file
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
+ * @edid: EDID
  * @aux: DisplayPort AUX channel
  *
  */
 void drm_dp_downstream_debug(struct seq_file *m,
 			     const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			     const u8 port_cap[4], struct drm_dp_aux *aux)
+			     const u8 port_cap[4],
+			     const struct edid *edid,
+			     struct drm_dp_aux *aux)
 {
 	bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
 				 DP_DETAILED_CAP_INFO_AVAILABLE;
@@ -588,7 +605,7 @@ void drm_dp_downstream_debug(struct seq_file *m,
 				seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
 		}
 
-		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap);
+		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, edid);
 
 		if (bpc > 0)
 			seq_printf(m, "\t\tMax bpc: %d\n", bpc);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5fab7ab97815..706750f9379e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5665,7 +5665,7 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 
 	intel_dp->dfp.max_bpc =
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
-					  intel_dp->downstream_ports);
+					  intel_dp->downstream_ports, edid);
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d\n",
 		      connector->base.base.id, connector->base.name,
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index e75e8212f03b..cfef38932f65 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2393,6 +2393,7 @@ static void intel_dp_info(struct seq_file *m,
 {
 	struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
 	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
+	const struct drm_property_blob *edid = intel_connector->base.edid_blob_ptr;
 
 	seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
 	seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio));
@@ -2400,7 +2401,8 @@ static void intel_dp_info(struct seq_file *m,
 		intel_panel_info(m, &intel_connector->panel);
 
 	drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
-				&intel_dp->aux);
+				edid ? edid->data : NULL, &intel_dp->aux);
+
 	if (intel_connector->hdcp.shim) {
 		seq_puts(m, "\tHDCP version: ");
 		intel_hdcp_info(m, intel_connector);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 958db298adc7..62637acaefee 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1483,10 +1483,14 @@ bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 				const u8 port_cap[4]);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			      const u8 port_cap[4]);
+			      const u8 port_cap[4],
+			      const struct edid *edid);
 int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]);
-void drm_dp_downstream_debug(struct seq_file *m, const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-			     const u8 port_cap[4], struct drm_dp_aux *aux);
+void drm_dp_downstream_debug(struct seq_file *m,
+			     const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+			     const u8 port_cap[4],
+			     const struct edid *edid,
+			     struct drm_dp_aux *aux);
 
 void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
 void drm_dp_aux_init(struct drm_dp_aux *aux);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 12/26] drm/dp: Redo drm_dp_downstream_max_clock() as drm_dp_downstream_max_dotclock()
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

We want to differentiate between the DFP dotclock and TMDS clock
limits. Let's convert the current thing to just give us the
dotclock limit.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c         | 42 ++++++++++---------------
 drivers/gpu/drm/i915/display/intel_dp.c |  4 +--
 include/drm/drm_dp_helper.h             |  4 +--
 3 files changed, 20 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 7164b9d274e1..0ae6849744c2 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -423,37 +423,32 @@ bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 EXPORT_SYMBOL(drm_dp_downstream_is_tmds);
 
 /**
- * drm_dp_downstream_max_clock() - extract branch device max
- *                                 pixel rate for legacy VGA
- *                                 converter or max TMDS clock
- *                                 rate for others
+ * drm_dp_downstream_max_dotclock() - extract downstream facing port max dot clock
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
  *
- * Returns max clock in kHz on success or 0 if max clock not defined
+ * Returns downstream facing port max dot clock in kHz on success,
+ * or 0 if max clock not defined
  */
-int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-				const u8 port_cap[4])
+int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				   const u8 port_cap[4])
 {
-	int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
-	bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
-		DP_DETAILED_CAP_INFO_AVAILABLE;
+	if (!drm_dp_is_branch(dpcd))
+		return 0;
 
-	if (!detailed_cap_info)
+	if (dpcd[DP_DPCD_REV] < 0x11)
 		return 0;
 
-	switch (type) {
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
 	case DP_DS_PORT_TYPE_VGA:
-		return port_cap[1] * 8 * 1000;
-	case DP_DS_PORT_TYPE_DVI:
-	case DP_DS_PORT_TYPE_HDMI:
-	case DP_DS_PORT_TYPE_DP_DUALMODE:
-		return port_cap[1] * 2500;
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 0;
+		return port_cap[1] * 8000;
 	default:
 		return 0;
 	}
 }
-EXPORT_SYMBOL(drm_dp_downstream_max_clock);
+EXPORT_SYMBOL(drm_dp_downstream_max_dotclock);
 
 /**
   * drm_dp_downstream_max_bpc() - extract downstream facing port max
@@ -596,14 +591,9 @@ void drm_dp_downstream_debug(struct seq_file *m,
 		seq_printf(m, "\t\tSW: %d.%d\n", rev[0], rev[1]);
 
 	if (detailed_cap_info) {
-		clk = drm_dp_downstream_max_clock(dpcd, port_cap);
-
-		if (clk > 0) {
-			if (type == DP_DS_PORT_TYPE_VGA)
-				seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
-			else
-				seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
-		}
+		clk = drm_dp_downstream_max_dotclock(dpcd, port_cap);
+		if (clk > 0)
+			seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
 
 		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, edid);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 706750f9379e..22c5995e31a7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -252,8 +252,8 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
 	if (type != DP_DS_PORT_TYPE_VGA)
 		return max_dotclk;
 
-	ds_max_dotclk = drm_dp_downstream_max_clock(intel_dp->dpcd,
-						    intel_dp->downstream_ports);
+	ds_max_dotclk = drm_dp_downstream_max_dotclock(intel_dp->dpcd,
+						       intel_dp->downstream_ports);
 
 	if (ds_max_dotclk != 0)
 		max_dotclk = min(max_dotclk, ds_max_dotclk);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 62637acaefee..39c1faf7dede 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1480,8 +1480,8 @@ bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			       const u8 port_cap[4],
 			       const struct edid *edid);
-int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-				const u8 port_cap[4]);
+int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				   const u8 port_cap[4]);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 12/26] drm/dp: Redo drm_dp_downstream_max_clock() as drm_dp_downstream_max_dotclock()
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

We want to differentiate between the DFP dotclock and TMDS clock
limits. Let's convert the current thing to just give us the
dotclock limit.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c         | 42 ++++++++++---------------
 drivers/gpu/drm/i915/display/intel_dp.c |  4 +--
 include/drm/drm_dp_helper.h             |  4 +--
 3 files changed, 20 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 7164b9d274e1..0ae6849744c2 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -423,37 +423,32 @@ bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 EXPORT_SYMBOL(drm_dp_downstream_is_tmds);
 
 /**
- * drm_dp_downstream_max_clock() - extract branch device max
- *                                 pixel rate for legacy VGA
- *                                 converter or max TMDS clock
- *                                 rate for others
+ * drm_dp_downstream_max_dotclock() - extract downstream facing port max dot clock
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
  *
- * Returns max clock in kHz on success or 0 if max clock not defined
+ * Returns downstream facing port max dot clock in kHz on success,
+ * or 0 if max clock not defined
  */
-int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-				const u8 port_cap[4])
+int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				   const u8 port_cap[4])
 {
-	int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
-	bool detailed_cap_info = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
-		DP_DETAILED_CAP_INFO_AVAILABLE;
+	if (!drm_dp_is_branch(dpcd))
+		return 0;
 
-	if (!detailed_cap_info)
+	if (dpcd[DP_DPCD_REV] < 0x11)
 		return 0;
 
-	switch (type) {
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
 	case DP_DS_PORT_TYPE_VGA:
-		return port_cap[1] * 8 * 1000;
-	case DP_DS_PORT_TYPE_DVI:
-	case DP_DS_PORT_TYPE_HDMI:
-	case DP_DS_PORT_TYPE_DP_DUALMODE:
-		return port_cap[1] * 2500;
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 0;
+		return port_cap[1] * 8000;
 	default:
 		return 0;
 	}
 }
-EXPORT_SYMBOL(drm_dp_downstream_max_clock);
+EXPORT_SYMBOL(drm_dp_downstream_max_dotclock);
 
 /**
   * drm_dp_downstream_max_bpc() - extract downstream facing port max
@@ -596,14 +591,9 @@ void drm_dp_downstream_debug(struct seq_file *m,
 		seq_printf(m, "\t\tSW: %d.%d\n", rev[0], rev[1]);
 
 	if (detailed_cap_info) {
-		clk = drm_dp_downstream_max_clock(dpcd, port_cap);
-
-		if (clk > 0) {
-			if (type == DP_DS_PORT_TYPE_VGA)
-				seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
-			else
-				seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
-		}
+		clk = drm_dp_downstream_max_dotclock(dpcd, port_cap);
+		if (clk > 0)
+			seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
 
 		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, edid);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 706750f9379e..22c5995e31a7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -252,8 +252,8 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
 	if (type != DP_DS_PORT_TYPE_VGA)
 		return max_dotclk;
 
-	ds_max_dotclk = drm_dp_downstream_max_clock(intel_dp->dpcd,
-						    intel_dp->downstream_ports);
+	ds_max_dotclk = drm_dp_downstream_max_dotclock(intel_dp->dpcd,
+						       intel_dp->downstream_ports);
 
 	if (ds_max_dotclk != 0)
 		max_dotclk = min(max_dotclk, ds_max_dotclk);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 62637acaefee..39c1faf7dede 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1480,8 +1480,8 @@ bool drm_dp_downstream_is_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			       const u8 port_cap[4],
 			       const struct edid *edid);
-int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
-				const u8 port_cap[4]);
+int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				   const u8 port_cap[4]);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 13/26] drm/i915: Reworkd DP DFP clock handling
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Move the downstream facing port dotclock check into a new function
(intel_dp_mode_valid_downstream()) so that we have a nice future
place where we can collect other related checks.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 55 +++++++++----------
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index dba0bb245a43..f978b33ea757 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1307,6 +1307,7 @@ struct intel_dp {
 
 	/* Downstream facing port caps */
 	struct {
+		int max_dotclock;
 		u8 max_bpc;
 	} dfp;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 22c5995e31a7..bbe5c72b5bb3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -238,29 +238,6 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return max_link_clock * max_lanes;
 }
 
-static int
-intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct intel_encoder *encoder = &intel_dig_port->base;
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	int max_dotclk = dev_priv->max_dotclk_freq;
-	int ds_max_dotclk;
-
-	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
-
-	if (type != DP_DS_PORT_TYPE_VGA)
-		return max_dotclk;
-
-	ds_max_dotclk = drm_dp_downstream_max_dotclock(intel_dp->dpcd,
-						       intel_dp->downstream_ports);
-
-	if (ds_max_dotclk != 0)
-		max_dotclk = min(max_dotclk, ds_max_dotclk);
-
-	return max_dotclk;
-}
-
 static int cnl_max_source_rate(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -606,6 +583,19 @@ static bool intel_dp_hdisplay_bad(struct drm_i915_private *dev_priv,
 	return hdisplay == 4096 && !HAS_DDI(dev_priv);
 }
 
+static enum drm_mode_status
+intel_dp_mode_valid_downstream(struct intel_connector *connector,
+			       int target_clock)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(connector);
+
+	if (intel_dp->dfp.max_dotclock &&
+	    target_clock > intel_dp->dfp.max_dotclock)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -616,15 +606,14 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	int target_clock = mode->clock;
 	int max_rate, mode_rate, max_lanes, max_link_clock;
-	int max_dotclk;
+	int max_dotclk = dev_priv->max_dotclk_freq;
 	u16 dsc_max_output_bpp = 0;
 	u8 dsc_slice_count = 0;
+	enum drm_mode_status status;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
 
-	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
-
 	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
 		if (mode->hdisplay > fixed_mode->hdisplay)
 			return MODE_PANEL;
@@ -680,6 +669,10 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return MODE_H_ILLEGAL;
 
+	status = intel_dp_mode_valid_downstream(intel_connector, target_clock);
+	if (status != MODE_OK)
+		return status;
+
 	return intel_mode_valid_max_plane_size(dev_priv, mode);
 }
 
@@ -5667,9 +5660,14 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
 					  intel_dp->downstream_ports, edid);
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d\n",
+	intel_dp->dfp.max_dotclock =
+		drm_dp_downstream_max_dotclock(intel_dp->dpcd,
+					       intel_dp->downstream_ports);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d\n",
 		      connector->base.base.id, connector->base.name,
-		      intel_dp->dfp.max_bpc);
+		      intel_dp->dfp.max_bpc,
+		      intel_dp->dfp.max_dotclock);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5692,6 +5690,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	intel_dp->has_audio = false;
 
 	intel_dp->dfp.max_bpc = 0;
+	intel_dp->dfp.max_dotclock = 0;
 }
 
 static int
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 13/26] drm/i915: Reworkd DP DFP clock handling
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Move the downstream facing port dotclock check into a new function
(intel_dp_mode_valid_downstream()) so that we have a nice future
place where we can collect other related checks.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 55 +++++++++----------
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index dba0bb245a43..f978b33ea757 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1307,6 +1307,7 @@ struct intel_dp {
 
 	/* Downstream facing port caps */
 	struct {
+		int max_dotclock;
 		u8 max_bpc;
 	} dfp;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 22c5995e31a7..bbe5c72b5bb3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -238,29 +238,6 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return max_link_clock * max_lanes;
 }
 
-static int
-intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	struct intel_encoder *encoder = &intel_dig_port->base;
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	int max_dotclk = dev_priv->max_dotclk_freq;
-	int ds_max_dotclk;
-
-	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
-
-	if (type != DP_DS_PORT_TYPE_VGA)
-		return max_dotclk;
-
-	ds_max_dotclk = drm_dp_downstream_max_dotclock(intel_dp->dpcd,
-						       intel_dp->downstream_ports);
-
-	if (ds_max_dotclk != 0)
-		max_dotclk = min(max_dotclk, ds_max_dotclk);
-
-	return max_dotclk;
-}
-
 static int cnl_max_source_rate(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -606,6 +583,19 @@ static bool intel_dp_hdisplay_bad(struct drm_i915_private *dev_priv,
 	return hdisplay == 4096 && !HAS_DDI(dev_priv);
 }
 
+static enum drm_mode_status
+intel_dp_mode_valid_downstream(struct intel_connector *connector,
+			       int target_clock)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(connector);
+
+	if (intel_dp->dfp.max_dotclock &&
+	    target_clock > intel_dp->dfp.max_dotclock)
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -616,15 +606,14 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	int target_clock = mode->clock;
 	int max_rate, mode_rate, max_lanes, max_link_clock;
-	int max_dotclk;
+	int max_dotclk = dev_priv->max_dotclk_freq;
 	u16 dsc_max_output_bpp = 0;
 	u8 dsc_slice_count = 0;
+	enum drm_mode_status status;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
 
-	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
-
 	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
 		if (mode->hdisplay > fixed_mode->hdisplay)
 			return MODE_PANEL;
@@ -680,6 +669,10 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return MODE_H_ILLEGAL;
 
+	status = intel_dp_mode_valid_downstream(intel_connector, target_clock);
+	if (status != MODE_OK)
+		return status;
+
 	return intel_mode_valid_max_plane_size(dev_priv, mode);
 }
 
@@ -5667,9 +5660,14 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
 					  intel_dp->downstream_ports, edid);
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d\n",
+	intel_dp->dfp.max_dotclock =
+		drm_dp_downstream_max_dotclock(intel_dp->dpcd,
+					       intel_dp->downstream_ports);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d\n",
 		      connector->base.base.id, connector->base.name,
-		      intel_dp->dfp.max_bpc);
+		      intel_dp->dfp.max_bpc,
+		      intel_dp->dfp.max_dotclock);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5692,6 +5690,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	intel_dp->has_audio = false;
 
 	intel_dp->dfp.max_bpc = 0;
+	intel_dp->dfp.max_dotclock = 0;
 }
 
 static int
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 14/26] drm/i915: Dump downstream facing port caps
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

It helps when the logs have a dump of the DFP capabilities.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index bbe5c72b5bb3..a0b611e8b370 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4528,6 +4528,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
 			     DP_MAX_DOWNSTREAM_PORTS) < 0)
 		return false; /* downstream port status fetch failed */
 
+	DRM_DEBUG_KMS("DPCD DFP: %*ph\n", (int)sizeof(intel_dp->downstream_ports),
+		      intel_dp->downstream_ports);
+
 	return true;
 }
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 14/26] drm/i915: Dump downstream facing port caps
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

It helps when the logs have a dump of the DFP capabilities.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index bbe5c72b5bb3..a0b611e8b370 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4528,6 +4528,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
 			     DP_MAX_DOWNSTREAM_PORTS) < 0)
 		return false; /* downstream port status fetch failed */
 
+	DRM_DEBUG_KMS("DPCD DFP: %*ph\n", (int)sizeof(intel_dp->downstream_ports),
+		      intel_dp->downstream_ports);
+
 	return true;
 }
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 15/26] drm/dp: Add drm_dp_downstream_{min,max}_tmds_clock()
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add helpers to get the TMDS clock limits for HDMI/DVI downstream
facing ports.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 116 ++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |   6 ++
 2 files changed, 122 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 0ae6849744c2..31ca550467ed 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -450,6 +450,114 @@ int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_dotclock);
 
+/**
+ * drm_dp_downstream_max_tmds_clock() - extract downstream facing port max TMDS clock
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ * @edid: EDID
+ *
+ * Returns HDMI/DVI downstream facing port max TMDS clock in kHz on success,
+ * or 0 if max TMDS clock not defined
+ */
+int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid)
+{
+	if (!drm_dp_is_branch(dpcd))
+		return 0;
+
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_TMDS:
+			return 165000;
+		default:
+			return 0;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP_DUALMODE:
+		if (is_edid_digital_input_dp(edid))
+			return 0;
+		/*
+		 * It's left up to the driver to check the
+		 * DP dual mode adapter's max TMDS clock.
+		 *
+		 * Unfortunatley it looks like branch devices
+		 * may not fordward that the DP dual mode i2c
+		 * access so we just usually get i2c nak :(
+		 */
+		/* fall through */
+	case DP_DS_PORT_TYPE_HDMI:
+		 /*
+		  * We should perhaps assume 165 MHz when detailed cap
+		  * info is not available. But looks like many typical
+		  * branch devices fall into that category and so we'd
+		  * probably end up with users complaining that they can't
+		  * get high resolution modes with their favorite dongle.
+		  *
+		  * So let's limit to 300 MHz instead since DPCD 1.4
+		  * HDMI 2.0 DFPs are required to have the detailed cap
+		  * info. So it's more likely we're dealing with a HDMI 1.4
+		  * compatible* device here.
+		  */
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 300000;
+		return port_cap[1] * 2500;
+	case DP_DS_PORT_TYPE_DVI:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 165000;
+		/* FIXME what to do about DVI dual link? */
+		return port_cap[1] * 2500;
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_max_tmds_clock);
+
+/**
+ * drm_dp_downstream_min_tmds_clock() - extract downstream facing port min TMDS clock
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ * @edid: EDID
+ *
+ * Returns HDMI/DVI downstream facing port min TMDS clock in kHz on success,
+ * or 0 if max TMDS clock not defined
+ */
+int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid)
+{
+	if (!drm_dp_is_branch(dpcd))
+		return 0;
+
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_TMDS:
+			return 25000;
+		default:
+			return 0;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP_DUALMODE:
+		if (is_edid_digital_input_dp(edid))
+			return 0;
+		/* fall through */
+	case DP_DS_PORT_TYPE_DVI:
+	case DP_DS_PORT_TYPE_HDMI:
+		/*
+		 * Unclear whether the protocol converter could
+		 * utilize pixel replication. Assume it won't.
+		 */
+		return 25000;
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_min_tmds_clock);
+
 /**
   * drm_dp_downstream_max_bpc() - extract downstream facing port max
   *                               bits per component
@@ -595,6 +703,14 @@ void drm_dp_downstream_debug(struct seq_file *m,
 		if (clk > 0)
 			seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
 
+		clk = drm_dp_downstream_max_tmds_clock(dpcd, port_cap, edid);
+		if (clk > 0)
+			seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
+
+		clk = drm_dp_downstream_min_tmds_clock(dpcd, port_cap, edid);
+		if (clk > 0)
+			seq_printf(m, "\t\tMin TMDS clock: %d kHz\n", clk);
+
 		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, edid);
 
 		if (bpc > 0)
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 39c1faf7dede..89683a3a9af1 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1482,6 +1482,12 @@ bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			       const struct edid *edid);
 int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 				   const u8 port_cap[4]);
+int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid);
+int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 15/26] drm/dp: Add drm_dp_downstream_{min, max}_tmds_clock()
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add helpers to get the TMDS clock limits for HDMI/DVI downstream
facing ports.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 116 ++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |   6 ++
 2 files changed, 122 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 0ae6849744c2..31ca550467ed 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -450,6 +450,114 @@ int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_dotclock);
 
+/**
+ * drm_dp_downstream_max_tmds_clock() - extract downstream facing port max TMDS clock
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ * @edid: EDID
+ *
+ * Returns HDMI/DVI downstream facing port max TMDS clock in kHz on success,
+ * or 0 if max TMDS clock not defined
+ */
+int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid)
+{
+	if (!drm_dp_is_branch(dpcd))
+		return 0;
+
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_TMDS:
+			return 165000;
+		default:
+			return 0;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP_DUALMODE:
+		if (is_edid_digital_input_dp(edid))
+			return 0;
+		/*
+		 * It's left up to the driver to check the
+		 * DP dual mode adapter's max TMDS clock.
+		 *
+		 * Unfortunatley it looks like branch devices
+		 * may not fordward that the DP dual mode i2c
+		 * access so we just usually get i2c nak :(
+		 */
+		/* fall through */
+	case DP_DS_PORT_TYPE_HDMI:
+		 /*
+		  * We should perhaps assume 165 MHz when detailed cap
+		  * info is not available. But looks like many typical
+		  * branch devices fall into that category and so we'd
+		  * probably end up with users complaining that they can't
+		  * get high resolution modes with their favorite dongle.
+		  *
+		  * So let's limit to 300 MHz instead since DPCD 1.4
+		  * HDMI 2.0 DFPs are required to have the detailed cap
+		  * info. So it's more likely we're dealing with a HDMI 1.4
+		  * compatible* device here.
+		  */
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 300000;
+		return port_cap[1] * 2500;
+	case DP_DS_PORT_TYPE_DVI:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return 165000;
+		/* FIXME what to do about DVI dual link? */
+		return port_cap[1] * 2500;
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_max_tmds_clock);
+
+/**
+ * drm_dp_downstream_min_tmds_clock() - extract downstream facing port min TMDS clock
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ * @edid: EDID
+ *
+ * Returns HDMI/DVI downstream facing port min TMDS clock in kHz on success,
+ * or 0 if max TMDS clock not defined
+ */
+int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid)
+{
+	if (!drm_dp_is_branch(dpcd))
+		return 0;
+
+	if (dpcd[DP_DPCD_REV] < 0x11) {
+		switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) {
+		case DP_DWN_STRM_PORT_TYPE_TMDS:
+			return 25000;
+		default:
+			return 0;
+		}
+	}
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP_DUALMODE:
+		if (is_edid_digital_input_dp(edid))
+			return 0;
+		/* fall through */
+	case DP_DS_PORT_TYPE_DVI:
+	case DP_DS_PORT_TYPE_HDMI:
+		/*
+		 * Unclear whether the protocol converter could
+		 * utilize pixel replication. Assume it won't.
+		 */
+		return 25000;
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_min_tmds_clock);
+
 /**
   * drm_dp_downstream_max_bpc() - extract downstream facing port max
   *                               bits per component
@@ -595,6 +703,14 @@ void drm_dp_downstream_debug(struct seq_file *m,
 		if (clk > 0)
 			seq_printf(m, "\t\tMax dot clock: %d kHz\n", clk);
 
+		clk = drm_dp_downstream_max_tmds_clock(dpcd, port_cap, edid);
+		if (clk > 0)
+			seq_printf(m, "\t\tMax TMDS clock: %d kHz\n", clk);
+
+		clk = drm_dp_downstream_min_tmds_clock(dpcd, port_cap, edid);
+		if (clk > 0)
+			seq_printf(m, "\t\tMin TMDS clock: %d kHz\n", clk);
+
 		bpc = drm_dp_downstream_max_bpc(dpcd, port_cap, edid);
 
 		if (bpc > 0)
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 39c1faf7dede..89683a3a9af1 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1482,6 +1482,12 @@ bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			       const struct edid *edid);
 int drm_dp_downstream_max_dotclock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 				   const u8 port_cap[4]);
+int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid);
+int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				     const u8 port_cap[4],
+				     const struct edid *edid);
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 16/26] drm/i915: Deal with TMDS DFP clock limits
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Use the new helpers to extract the TMDS clock limits from
the downstream facing port and check them in .mode_valid().

TODO: we should check these in .compute_config() too to eg.
determine if we can do deep color on the HDMI side or not

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 35 +++++++++++++++++--
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index f978b33ea757..117fc17dae44 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1307,6 +1307,7 @@ struct intel_dp {
 
 	/* Downstream facing port caps */
 	struct {
+		int min_tmds_clock, max_tmds_clock;
 		int max_dotclock;
 		u8 max_bpc;
 	} dfp;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index a0b611e8b370..c0a638df97c5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -585,14 +585,29 @@ static bool intel_dp_hdisplay_bad(struct drm_i915_private *dev_priv,
 
 static enum drm_mode_status
 intel_dp_mode_valid_downstream(struct intel_connector *connector,
+			       const struct drm_display_mode *mode,
 			       int target_clock)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	const struct drm_display_info *info = &connector->base.display_info;
+	int tmds_clock;
 
 	if (intel_dp->dfp.max_dotclock &&
 	    target_clock > intel_dp->dfp.max_dotclock)
 		return MODE_CLOCK_HIGH;
 
+	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
+	tmds_clock = target_clock;
+	if (drm_mode_is_420_only(info, mode))
+		tmds_clock /= 2;
+
+	if (intel_dp->dfp.min_tmds_clock &&
+	    tmds_clock < intel_dp->dfp.min_tmds_clock)
+		return MODE_CLOCK_LOW;
+	if (intel_dp->dfp.max_tmds_clock &&
+	    tmds_clock > intel_dp->dfp.max_tmds_clock)
+		return MODE_CLOCK_HIGH;
+
 	return MODE_OK;
 }
 
@@ -669,7 +684,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return MODE_H_ILLEGAL;
 
-	status = intel_dp_mode_valid_downstream(intel_connector, target_clock);
+	status = intel_dp_mode_valid_downstream(intel_connector,
+						mode, target_clock);
 	if (status != MODE_OK)
 		return status;
 
@@ -5667,10 +5683,21 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 		drm_dp_downstream_max_dotclock(intel_dp->dpcd,
 					       intel_dp->downstream_ports);
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d\n",
+	intel_dp->dfp.min_tmds_clock =
+		drm_dp_downstream_min_tmds_clock(intel_dp->dpcd,
+						 intel_dp->downstream_ports,
+						 edid);
+	intel_dp->dfp.max_tmds_clock =
+		drm_dp_downstream_max_tmds_clock(intel_dp->dpcd,
+						 intel_dp->downstream_ports,
+						 edid);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d\n",
 		      connector->base.base.id, connector->base.name,
 		      intel_dp->dfp.max_bpc,
-		      intel_dp->dfp.max_dotclock);
+		      intel_dp->dfp.max_dotclock,
+		      intel_dp->dfp.min_tmds_clock,
+		      intel_dp->dfp.max_tmds_clock);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5694,6 +5721,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 
 	intel_dp->dfp.max_bpc = 0;
 	intel_dp->dfp.max_dotclock = 0;
+	intel_dp->dfp.min_tmds_clock = 0;
+	intel_dp->dfp.max_tmds_clock = 0;
 }
 
 static int
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 16/26] drm/i915: Deal with TMDS DFP clock limits
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Use the new helpers to extract the TMDS clock limits from
the downstream facing port and check them in .mode_valid().

TODO: we should check these in .compute_config() too to eg.
determine if we can do deep color on the HDMI side or not

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 35 +++++++++++++++++--
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index f978b33ea757..117fc17dae44 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1307,6 +1307,7 @@ struct intel_dp {
 
 	/* Downstream facing port caps */
 	struct {
+		int min_tmds_clock, max_tmds_clock;
 		int max_dotclock;
 		u8 max_bpc;
 	} dfp;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index a0b611e8b370..c0a638df97c5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -585,14 +585,29 @@ static bool intel_dp_hdisplay_bad(struct drm_i915_private *dev_priv,
 
 static enum drm_mode_status
 intel_dp_mode_valid_downstream(struct intel_connector *connector,
+			       const struct drm_display_mode *mode,
 			       int target_clock)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	const struct drm_display_info *info = &connector->base.display_info;
+	int tmds_clock;
 
 	if (intel_dp->dfp.max_dotclock &&
 	    target_clock > intel_dp->dfp.max_dotclock)
 		return MODE_CLOCK_HIGH;
 
+	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
+	tmds_clock = target_clock;
+	if (drm_mode_is_420_only(info, mode))
+		tmds_clock /= 2;
+
+	if (intel_dp->dfp.min_tmds_clock &&
+	    tmds_clock < intel_dp->dfp.min_tmds_clock)
+		return MODE_CLOCK_LOW;
+	if (intel_dp->dfp.max_tmds_clock &&
+	    tmds_clock > intel_dp->dfp.max_tmds_clock)
+		return MODE_CLOCK_HIGH;
+
 	return MODE_OK;
 }
 
@@ -669,7 +684,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return MODE_H_ILLEGAL;
 
-	status = intel_dp_mode_valid_downstream(intel_connector, target_clock);
+	status = intel_dp_mode_valid_downstream(intel_connector,
+						mode, target_clock);
 	if (status != MODE_OK)
 		return status;
 
@@ -5667,10 +5683,21 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 		drm_dp_downstream_max_dotclock(intel_dp->dpcd,
 					       intel_dp->downstream_ports);
 
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d\n",
+	intel_dp->dfp.min_tmds_clock =
+		drm_dp_downstream_min_tmds_clock(intel_dp->dpcd,
+						 intel_dp->downstream_ports,
+						 edid);
+	intel_dp->dfp.max_tmds_clock =
+		drm_dp_downstream_max_tmds_clock(intel_dp->dpcd,
+						 intel_dp->downstream_ports,
+						 edid);
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d\n",
 		      connector->base.base.id, connector->base.name,
 		      intel_dp->dfp.max_bpc,
-		      intel_dp->dfp.max_dotclock);
+		      intel_dp->dfp.max_dotclock,
+		      intel_dp->dfp.min_tmds_clock,
+		      intel_dp->dfp.max_tmds_clock);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5694,6 +5721,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 
 	intel_dp->dfp.max_bpc = 0;
 	intel_dp->dfp.max_dotclock = 0;
+	intel_dp->dfp.min_tmds_clock = 0;
+	intel_dp->dfp.max_tmds_clock = 0;
 }
 
 static int
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 17/26] drm/i915: Configure DP 1.3+ protocol converted HDMI mode
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

DP 1.3 adds some extra control knobs for DP->HDMI protocol conversion.
Let's use that to configure the "HDMI mode" (ie. infoframes vs. not)
based on the capabilities of the sink.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c  | 22 ++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.h  |  1 +
 3 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 818bee4918fa..3d1393ff6435 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3551,6 +3551,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	intel_ddi_init_dp_buf_reg(encoder);
 	if (!is_mst)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	intel_dp_configure_protocol_converter(intel_dp);
 	intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
 					      true);
 	intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index c0a638df97c5..d075450a0472 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3575,6 +3575,27 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
+{
+	u8 tmp;
+
+	if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
+		return;
+
+	if (!drm_dp_is_branch(intel_dp->dpcd))
+		return;
+
+	tmp = intel_dp->has_hdmi_sink ?
+		DP_HDMI_DVI_OUTPUT_CONFIG : 0;
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux,
+			       DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) <= 0)
+		DRM_DEBUG_KMS("Failed to set protocol converter HDMI mode to %s\n",
+			      enableddisabled(intel_dp->has_hdmi_sink));
+
+	/* TODO: configure YCbCr 4:2:2/4:2:0 conversion */
+}
+
 static void intel_enable_dp(struct intel_encoder *encoder,
 			    const struct intel_crtc_state *pipe_config,
 			    const struct drm_connector_state *conn_state)
@@ -3611,6 +3632,7 @@ static void intel_enable_dp(struct intel_encoder *encoder,
 	}
 
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	intel_dp_configure_protocol_converter(intel_dp);
 	intel_dp_start_link_train(intel_dp);
 	intel_dp_stop_link_train(intel_dp);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 3da166054788..953197d46444 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -51,6 +51,7 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 int intel_dp_retrain_link(struct intel_encoder *encoder,
 			  struct drm_modeset_acquire_ctx *ctx);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp);
 void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
 					   const struct intel_crtc_state *crtc_state,
 					   bool enable);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 17/26] drm/i915: Configure DP 1.3+ protocol converted HDMI mode
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

DP 1.3 adds some extra control knobs for DP->HDMI protocol conversion.
Let's use that to configure the "HDMI mode" (ie. infoframes vs. not)
based on the capabilities of the sink.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c  | 22 ++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.h  |  1 +
 3 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 818bee4918fa..3d1393ff6435 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3551,6 +3551,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	intel_ddi_init_dp_buf_reg(encoder);
 	if (!is_mst)
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	intel_dp_configure_protocol_converter(intel_dp);
 	intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
 					      true);
 	intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index c0a638df97c5..d075450a0472 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3575,6 +3575,27 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
 	intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
+{
+	u8 tmp;
+
+	if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
+		return;
+
+	if (!drm_dp_is_branch(intel_dp->dpcd))
+		return;
+
+	tmp = intel_dp->has_hdmi_sink ?
+		DP_HDMI_DVI_OUTPUT_CONFIG : 0;
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux,
+			       DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) <= 0)
+		DRM_DEBUG_KMS("Failed to set protocol converter HDMI mode to %s\n",
+			      enableddisabled(intel_dp->has_hdmi_sink));
+
+	/* TODO: configure YCbCr 4:2:2/4:2:0 conversion */
+}
+
 static void intel_enable_dp(struct intel_encoder *encoder,
 			    const struct intel_crtc_state *pipe_config,
 			    const struct drm_connector_state *conn_state)
@@ -3611,6 +3632,7 @@ static void intel_enable_dp(struct intel_encoder *encoder,
 	}
 
 	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	intel_dp_configure_protocol_converter(intel_dp);
 	intel_dp_start_link_train(intel_dp);
 	intel_dp_stop_link_train(intel_dp);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 3da166054788..953197d46444 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -51,6 +51,7 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 int intel_dp_retrain_link(struct intel_encoder *encoder,
 			  struct drm_modeset_acquire_ctx *ctx);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp);
 void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
 					   const struct intel_crtc_state *crtc_state,
 					   bool enable);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 18/26] drm/dp: Add drm_dp_downstream_mode()
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The downstream facing port caps in the DPCD can give us a hint
as to what kind of display mode the sink can use if it doesn't
have an EDID. Use that information to pick a suitable mode.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 54 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_edid.c      | 21 +++++++++++++
 include/drm/drm_dp_helper.h     | 12 ++++++++
 include/drm/drm_edid.h          |  4 +++
 4 files changed, 91 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 31ca550467ed..507282dc79ac 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -615,6 +615,60 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
 
+/**
+ * drm_dp_downstream_mode() - return a mode for downstream facing port
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ *
+ * Provides a suitable mode for downstream facing ports without EDID.
+ *
+ * Returns a new drm_display_mode on success or NULL on failure
+ */
+struct drm_display_mode *
+drm_dp_downstream_mode(struct drm_device *dev,
+		       const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+		       const u8 port_cap[4])
+
+{
+	u8 vic;
+
+	if (!drm_dp_is_branch(dpcd))
+		return NULL;
+
+	if (dpcd[DP_DPCD_REV] < 0x11)
+		return NULL;
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_NON_EDID:
+		switch (port_cap[0] & DP_DS_NON_EDID_MASK) {
+		case DP_DS_NON_EDID_720x480i_60:
+			vic = 6;
+			break;
+		case DP_DS_NON_EDID_720x480i_50:
+			vic = 21;
+			break;
+		case DP_DS_NON_EDID_1920x1080i_60:
+			vic = 5;
+			break;
+		case DP_DS_NON_EDID_1920x1080i_50:
+			vic = 20;
+			break;
+		case DP_DS_NON_EDID_1280x720_60:
+			vic = 4;
+			break;
+		case DP_DS_NON_EDID_1280x720_50:
+			vic = 19;
+			break;
+		default:
+			return NULL;
+		}
+		return drm_display_mode_from_cea_vic(dev, vic);
+	default:
+		return NULL;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_mode);
+
 /**
  * drm_dp_downstream_id() - identify branch device
  * @aux: DisplayPort AUX channel
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 99769d6c9f84..4894a00b0711 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3633,6 +3633,27 @@ drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
 	bitmap_set(hdmi->y420_cmdb_modes, vic, 1);
 }
 
+struct drm_display_mode *
+drm_display_mode_from_cea_vic(struct drm_device *dev,
+			      u8 video_code)
+{
+	const struct drm_display_mode *cea_mode;
+	struct drm_display_mode *newmode;
+
+	cea_mode = cea_mode_for_vic(video_code);
+	if (!cea_mode)
+		return NULL;
+
+	newmode = drm_mode_duplicate(dev, cea_mode);
+	if (!newmode)
+		return NULL;
+
+	newmode->vrefresh = 0;
+
+	return newmode;
+}
+EXPORT_SYMBOL(drm_display_mode_from_cea_vic);
+
 static int
 do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
 {
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 89683a3a9af1..be4a5ffe4252 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -27,6 +27,8 @@
 #include <linux/i2c.h>
 #include <linux/types.h>
 
+struct drm_device;
+
 /*
  * Unless otherwise noted, all values are from the DP 1.1a spec.  Note that
  * DP and DPCD versions are independent.  Differences from 1.0 are not noted,
@@ -384,6 +386,13 @@
 # define DP_DS_PORT_TYPE_DP_DUALMODE        5
 # define DP_DS_PORT_TYPE_WIRELESS           6
 # define DP_DS_PORT_HPD			    (1 << 3)
+# define DP_DS_NON_EDID_MASK		    (0xf << 4)
+# define DP_DS_NON_EDID_720x480i_60	    (1 << 4)
+# define DP_DS_NON_EDID_720x480i_50	    (2 << 4)
+# define DP_DS_NON_EDID_1920x1080i_60	    (3 << 4)
+# define DP_DS_NON_EDID_1920x1080i_50	    (4 << 4)
+# define DP_DS_NON_EDID_1280x720_60	    (5 << 4)
+# define DP_DS_NON_EDID_1280x720_50	    (7 << 4)
 /* offset 1 for VGA is maximum megapixels per second / 8 */
 /* offset 1 for DVI/HDMI is maximum TMDS clock in Mbps / 2.5 */
 /* offset 2 for VGA/DVI/HDMI */
@@ -1491,6 +1500,9 @@ int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
+struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev,
+						const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+						const u8 port_cap[4]);
 int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]);
 void drm_dp_downstream_debug(struct seq_file *m,
 			     const u8 dpcd[DP_RECEIVER_CAP_SIZE],
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index f0b03d401c27..cb1be3f5840a 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -503,4 +503,8 @@ void drm_edid_get_monitor_name(struct edid *edid, char *name,
 struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
 					   int hsize, int vsize, int fresh,
 					   bool rb);
+struct drm_display_mode *
+drm_display_mode_from_cea_vic(struct drm_device *dev,
+			      u8 video_code);
+
 #endif /* __DRM_EDID_H__ */
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 18/26] drm/dp: Add drm_dp_downstream_mode()
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The downstream facing port caps in the DPCD can give us a hint
as to what kind of display mode the sink can use if it doesn't
have an EDID. Use that information to pick a suitable mode.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 54 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_edid.c      | 21 +++++++++++++
 include/drm/drm_dp_helper.h     | 12 ++++++++
 include/drm/drm_edid.h          |  4 +++
 4 files changed, 91 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 31ca550467ed..507282dc79ac 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -615,6 +615,60 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
 
+/**
+ * drm_dp_downstream_mode() - return a mode for downstream facing port
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ *
+ * Provides a suitable mode for downstream facing ports without EDID.
+ *
+ * Returns a new drm_display_mode on success or NULL on failure
+ */
+struct drm_display_mode *
+drm_dp_downstream_mode(struct drm_device *dev,
+		       const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+		       const u8 port_cap[4])
+
+{
+	u8 vic;
+
+	if (!drm_dp_is_branch(dpcd))
+		return NULL;
+
+	if (dpcd[DP_DPCD_REV] < 0x11)
+		return NULL;
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_NON_EDID:
+		switch (port_cap[0] & DP_DS_NON_EDID_MASK) {
+		case DP_DS_NON_EDID_720x480i_60:
+			vic = 6;
+			break;
+		case DP_DS_NON_EDID_720x480i_50:
+			vic = 21;
+			break;
+		case DP_DS_NON_EDID_1920x1080i_60:
+			vic = 5;
+			break;
+		case DP_DS_NON_EDID_1920x1080i_50:
+			vic = 20;
+			break;
+		case DP_DS_NON_EDID_1280x720_60:
+			vic = 4;
+			break;
+		case DP_DS_NON_EDID_1280x720_50:
+			vic = 19;
+			break;
+		default:
+			return NULL;
+		}
+		return drm_display_mode_from_cea_vic(dev, vic);
+	default:
+		return NULL;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_mode);
+
 /**
  * drm_dp_downstream_id() - identify branch device
  * @aux: DisplayPort AUX channel
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 99769d6c9f84..4894a00b0711 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3633,6 +3633,27 @@ drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
 	bitmap_set(hdmi->y420_cmdb_modes, vic, 1);
 }
 
+struct drm_display_mode *
+drm_display_mode_from_cea_vic(struct drm_device *dev,
+			      u8 video_code)
+{
+	const struct drm_display_mode *cea_mode;
+	struct drm_display_mode *newmode;
+
+	cea_mode = cea_mode_for_vic(video_code);
+	if (!cea_mode)
+		return NULL;
+
+	newmode = drm_mode_duplicate(dev, cea_mode);
+	if (!newmode)
+		return NULL;
+
+	newmode->vrefresh = 0;
+
+	return newmode;
+}
+EXPORT_SYMBOL(drm_display_mode_from_cea_vic);
+
 static int
 do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
 {
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 89683a3a9af1..be4a5ffe4252 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -27,6 +27,8 @@
 #include <linux/i2c.h>
 #include <linux/types.h>
 
+struct drm_device;
+
 /*
  * Unless otherwise noted, all values are from the DP 1.1a spec.  Note that
  * DP and DPCD versions are independent.  Differences from 1.0 are not noted,
@@ -384,6 +386,13 @@
 # define DP_DS_PORT_TYPE_DP_DUALMODE        5
 # define DP_DS_PORT_TYPE_WIRELESS           6
 # define DP_DS_PORT_HPD			    (1 << 3)
+# define DP_DS_NON_EDID_MASK		    (0xf << 4)
+# define DP_DS_NON_EDID_720x480i_60	    (1 << 4)
+# define DP_DS_NON_EDID_720x480i_50	    (2 << 4)
+# define DP_DS_NON_EDID_1920x1080i_60	    (3 << 4)
+# define DP_DS_NON_EDID_1920x1080i_50	    (4 << 4)
+# define DP_DS_NON_EDID_1280x720_60	    (5 << 4)
+# define DP_DS_NON_EDID_1280x720_50	    (7 << 4)
 /* offset 1 for VGA is maximum megapixels per second / 8 */
 /* offset 1 for DVI/HDMI is maximum TMDS clock in Mbps / 2.5 */
 /* offset 2 for VGA/DVI/HDMI */
@@ -1491,6 +1500,9 @@ int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
+struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev,
+						const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+						const u8 port_cap[4]);
 int drm_dp_downstream_id(struct drm_dp_aux *aux, char id[6]);
 void drm_dp_downstream_debug(struct seq_file *m,
 			     const u8 dpcd[DP_RECEIVER_CAP_SIZE],
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index f0b03d401c27..cb1be3f5840a 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -503,4 +503,8 @@ void drm_edid_get_monitor_name(struct edid *edid, char *name,
 struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
 					   int hsize, int vsize, int fresh,
 					   bool rb);
+struct drm_display_mode *
+drm_display_mode_from_cea_vic(struct drm_device *dev,
+			      u8 video_code);
+
 #endif /* __DRM_EDID_H__ */
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 19/26] drm/i915: Handle downstream facing ports w/o EDID
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Use drm_dp_downstream_mode() to get a suitable mode for downstream
facing ports which don't have an EDID.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d075450a0472..65202615c8f1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5893,7 +5893,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 	}
 
 	/* if eDP has no EDID, fall back to fixed mode */
-	if (intel_dp_is_edp(intel_attached_dp(to_intel_connector(connector))) &&
+	if (intel_dp_is_edp(intel_attached_dp(intel_connector)) &&
 	    intel_connector->panel.fixed_mode) {
 		struct drm_display_mode *mode;
 
@@ -5905,6 +5905,19 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 		}
 	}
 
+	if (!edid) {
+		struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
+		struct drm_display_mode *mode;
+
+		mode = drm_dp_downstream_mode(connector->dev,
+					      intel_dp->dpcd,
+					      intel_dp->downstream_ports);
+		if (mode) {
+			drm_mode_probed_add(connector, mode);
+			return 1;
+		}
+	}
+
 	return 0;
 }
 
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 19/26] drm/i915: Handle downstream facing ports w/o EDID
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Use drm_dp_downstream_mode() to get a suitable mode for downstream
facing ports which don't have an EDID.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d075450a0472..65202615c8f1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5893,7 +5893,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 	}
 
 	/* if eDP has no EDID, fall back to fixed mode */
-	if (intel_dp_is_edp(intel_attached_dp(to_intel_connector(connector))) &&
+	if (intel_dp_is_edp(intel_attached_dp(intel_connector)) &&
 	    intel_connector->panel.fixed_mode) {
 		struct drm_display_mode *mode;
 
@@ -5905,6 +5905,19 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 		}
 	}
 
+	if (!edid) {
+		struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
+		struct drm_display_mode *mode;
+
+		mode = drm_dp_downstream_mode(connector->dev,
+					      intel_dp->dpcd,
+					      intel_dp->downstream_ports);
+		if (mode) {
+			drm_mode_probed_add(connector, mode);
+			return 1;
+		}
+	}
+
 	return 0;
 }
 
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 20/26] drm/i915: Extract intel_hdmi_has_audio()
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Pull the "do we want to enable audio?" computation into a small helper
to make intel_hdmi_compute_config() less messy. Will make it easier to
add more checks for this later (eg. we should actually be checking
at the hblank is long enough for audio transmission).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 28 +++++++++++++++--------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 5991a99c43a8..31fec0050f8d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2405,6 +2405,23 @@ static bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_s
 	}
 }
 
+static bool intel_hdmi_has_audio(struct intel_encoder *encoder,
+				 const struct intel_crtc_state *crtc_state,
+				 const struct drm_connector_state *conn_state)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	const struct intel_digital_connector_state *intel_conn_state =
+		to_intel_digital_connector_state(conn_state);
+
+	if (!crtc_state->has_hdmi_sink)
+		return false;
+
+	if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
+		return intel_hdmi->has_audio;
+	else
+		return intel_conn_state->force_audio == HDMI_AUDIO_ON;
+}
+
 int intel_hdmi_compute_config(struct intel_encoder *encoder,
 			      struct intel_crtc_state *pipe_config,
 			      struct drm_connector_state *conn_state)
@@ -2414,8 +2431,6 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	struct drm_connector *connector = conn_state->connector;
 	struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
-	struct intel_digital_connector_state *intel_conn_state =
-		to_intel_digital_connector_state(conn_state);
 	int ret;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -2444,13 +2459,8 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 	if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))
 		pipe_config->has_pch_encoder = true;
 
-	if (pipe_config->has_hdmi_sink) {
-		if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
-			pipe_config->has_audio = intel_hdmi->has_audio;
-		else
-			pipe_config->has_audio =
-				intel_conn_state->force_audio == HDMI_AUDIO_ON;
-	}
+	pipe_config->has_audio =
+		intel_hdmi_has_audio(encoder, pipe_config, conn_state);
 
 	ret = intel_hdmi_compute_clock(encoder, pipe_config);
 	if (ret)
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 20/26] drm/i915: Extract intel_hdmi_has_audio()
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Pull the "do we want to enable audio?" computation into a small helper
to make intel_hdmi_compute_config() less messy. Will make it easier to
add more checks for this later (eg. we should actually be checking
at the hblank is long enough for audio transmission).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 28 +++++++++++++++--------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 5991a99c43a8..31fec0050f8d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2405,6 +2405,23 @@ static bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_s
 	}
 }
 
+static bool intel_hdmi_has_audio(struct intel_encoder *encoder,
+				 const struct intel_crtc_state *crtc_state,
+				 const struct drm_connector_state *conn_state)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	const struct intel_digital_connector_state *intel_conn_state =
+		to_intel_digital_connector_state(conn_state);
+
+	if (!crtc_state->has_hdmi_sink)
+		return false;
+
+	if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
+		return intel_hdmi->has_audio;
+	else
+		return intel_conn_state->force_audio == HDMI_AUDIO_ON;
+}
+
 int intel_hdmi_compute_config(struct intel_encoder *encoder,
 			      struct intel_crtc_state *pipe_config,
 			      struct drm_connector_state *conn_state)
@@ -2414,8 +2431,6 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	struct drm_connector *connector = conn_state->connector;
 	struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
-	struct intel_digital_connector_state *intel_conn_state =
-		to_intel_digital_connector_state(conn_state);
 	int ret;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -2444,13 +2459,8 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 	if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))
 		pipe_config->has_pch_encoder = true;
 
-	if (pipe_config->has_hdmi_sink) {
-		if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
-			pipe_config->has_audio = intel_hdmi->has_audio;
-		else
-			pipe_config->has_audio =
-				intel_conn_state->force_audio == HDMI_AUDIO_ON;
-	}
+	pipe_config->has_audio =
+		intel_hdmi_has_audio(encoder, pipe_config, conn_state);
 
 	ret = intel_hdmi_compute_clock(encoder, pipe_config);
 	if (ret)
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 21/26] drm/i915: DP->HDMI TMDS clock limits vs. deep color
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Account for the TMDS clock limits declared by the DFP/DP++ dongle
when determining what color depth we're going to use.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c   | 67 ++++++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 50 ++++++++++-------
 drivers/gpu/drm/i915/display/intel_hdmi.h |  2 +
 3 files changed, 90 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 65202615c8f1..639a0c2e5a40 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1918,18 +1918,69 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 		drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
 }
 
-static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
-				struct intel_crtc_state *pipe_config)
+static bool intel_dp_hdmi_ycbcr420(struct intel_dp *intel_dp,
+				   const struct intel_crtc_state *crtc_state)
+{
+	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420;
+}
+
+static int intel_dp_hdmi_tmds_clock(struct intel_dp *intel_dp,
+				    const struct intel_crtc_state *crtc_state, int bpc)
+{
+	int clock = crtc_state->hw.adjusted_mode.crtc_clock * bpc / 8;
+
+	if (intel_dp_hdmi_ycbcr420(intel_dp, crtc_state))
+		clock /= 2;
+
+	return clock;
+}
+
+static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
+					   const struct intel_crtc_state *crtc_state, int bpc)
+{
+	int tmds_clock = intel_dp_hdmi_tmds_clock(intel_dp, crtc_state, bpc);
+
+	if (intel_dp->dfp.min_tmds_clock &&
+	    tmds_clock < intel_dp->dfp.min_tmds_clock)
+		return false;
+
+	if (intel_dp->dfp.max_tmds_clock &&
+	    tmds_clock > intel_dp->dfp.max_tmds_clock)
+		return false;
+
+	return true;
+}
+
+static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp,
+					      const struct intel_crtc_state *crtc_state,
+					      int bpc)
+{
+	bool has_hdmi_sink = intel_dp->has_hdmi_sink;
+
+	return intel_hdmi_deep_color_possible(crtc_state, bpc, has_hdmi_sink) &&
+		intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc);
+}
+
+static int intel_dp_max_bpp(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	int bpp;
+	int bpp, bpc;
 
-	bpp = pipe_config->pipe_bpp;
+	bpc = crtc_state->pipe_bpp / 3;
 
 	if (intel_dp->dfp.max_bpc)
-		bpp = min(bpp, 3 * intel_dp->dfp.max_bpc);
+		bpc = min_t(int, bpc, intel_dp->dfp.max_bpc);
 
+	if (intel_dp->dfp.min_tmds_clock) {
+		for (; bpc >= 10; bpc -= 2) {
+			if (intel_dp_hdmi_deep_color_possible(intel_dp, crtc_state, bpc))
+				break;
+		}
+	}
+
+	bpp = bpc * 3;
 	if (intel_dp_is_edp(intel_dp)) {
 		/* Get bpp from vbt only for panels that dont have bpp in edid */
 		if (intel_connector->base.display_info.bpc == 0 &&
@@ -2244,7 +2295,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 	limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
 
 	limits.min_bpp = intel_dp_min_bpp(pipe_config);
-	limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config);
+	limits.max_bpp = intel_dp_max_bpp(intel_dp, pipe_config);
 
 	if (intel_dp_is_edp(intel_dp)) {
 		/*
@@ -3579,10 +3630,10 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
 {
 	u8 tmp;
 
-	if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
+	if (!drm_dp_is_branch(intel_dp->dpcd))
 		return;
 
-	if (!drm_dp_is_branch(intel_dp->dpcd))
+	if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
 		return;
 
 	tmp = intel_dp->has_hdmi_sink ?
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 31fec0050f8d..d6326a4a4a9a 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2218,35 +2218,18 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 	return intel_mode_valid_max_plane_size(dev_priv, mode);
 }
 
-static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
-				     int bpc)
+bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
+				    int bpc, bool has_hdmi_sink)
 {
-	struct drm_i915_private *dev_priv =
-		to_i915(crtc_state->uapi.crtc->dev);
 	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_connector_state *connector_state;
 	struct drm_connector *connector;
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
 	int i;
 
-	if (HAS_GMCH(dev_priv))
-		return false;
-
-	if (bpc == 10 && INTEL_GEN(dev_priv) < 11)
-		return false;
-
 	if (crtc_state->pipe_bpp < bpc * 3)
 		return false;
 
-	if (!crtc_state->has_hdmi_sink)
-		return false;
-
-	/*
-	 * HDMI deep color affects the clocks, so it's only possible
-	 * when not cloning with other encoder types.
-	 */
-	if (crtc_state->output_types != 1 << INTEL_OUTPUT_HDMI)
+	if (!has_hdmi_sink)
 		return false;
 
 	for_each_new_connector_in_state(state, connector, connector_state, i) {
@@ -2274,6 +2257,30 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		}
 	}
 
+	return true;
+}
+
+static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
+				     int bpc)
+{
+	struct drm_i915_private *dev_priv =
+		to_i915(crtc_state->uapi.crtc->dev);
+	const struct drm_display_mode *adjusted_mode =
+		&crtc_state->hw.adjusted_mode;
+
+	if (HAS_GMCH(dev_priv))
+		return false;
+
+	if (bpc == 10 && INTEL_GEN(dev_priv) < 11)
+		return false;
+
+	/*
+	 * HDMI deep color affects the clocks, so it's only possible
+	 * when not cloning with other encoder types.
+	 */
+	if (crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI))
+		return false;
+
 	/* Display Wa_1405510057:icl,ehl */
 	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
 	    bpc == 10 && IS_GEN(dev_priv, 11) &&
@@ -2281,7 +2288,8 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 	     adjusted_mode->crtc_hblank_start) % 8 == 2)
 		return false;
 
-	return true;
+	return intel_hdmi_deep_color_possible(crtc_state, bpc,
+					      crtc_state->has_hdmi_sink);
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index d3659d0b408b..bd58c929f816 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -48,5 +48,7 @@ void intel_read_infoframe(struct intel_encoder *encoder,
 			  const struct intel_crtc_state *crtc_state,
 			  enum hdmi_infoframe_type type,
 			  union hdmi_infoframe *frame);
+bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
+				    int bpc, bool has_hdmi_sink);
 
 #endif /* __INTEL_HDMI_H__ */
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 21/26] drm/i915: DP->HDMI TMDS clock limits vs. deep color
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Account for the TMDS clock limits declared by the DFP/DP++ dongle
when determining what color depth we're going to use.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c   | 67 ++++++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 50 ++++++++++-------
 drivers/gpu/drm/i915/display/intel_hdmi.h |  2 +
 3 files changed, 90 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 65202615c8f1..639a0c2e5a40 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1918,18 +1918,69 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 		drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
 }
 
-static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
-				struct intel_crtc_state *pipe_config)
+static bool intel_dp_hdmi_ycbcr420(struct intel_dp *intel_dp,
+				   const struct intel_crtc_state *crtc_state)
+{
+	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420;
+}
+
+static int intel_dp_hdmi_tmds_clock(struct intel_dp *intel_dp,
+				    const struct intel_crtc_state *crtc_state, int bpc)
+{
+	int clock = crtc_state->hw.adjusted_mode.crtc_clock * bpc / 8;
+
+	if (intel_dp_hdmi_ycbcr420(intel_dp, crtc_state))
+		clock /= 2;
+
+	return clock;
+}
+
+static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
+					   const struct intel_crtc_state *crtc_state, int bpc)
+{
+	int tmds_clock = intel_dp_hdmi_tmds_clock(intel_dp, crtc_state, bpc);
+
+	if (intel_dp->dfp.min_tmds_clock &&
+	    tmds_clock < intel_dp->dfp.min_tmds_clock)
+		return false;
+
+	if (intel_dp->dfp.max_tmds_clock &&
+	    tmds_clock > intel_dp->dfp.max_tmds_clock)
+		return false;
+
+	return true;
+}
+
+static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp,
+					      const struct intel_crtc_state *crtc_state,
+					      int bpc)
+{
+	bool has_hdmi_sink = intel_dp->has_hdmi_sink;
+
+	return intel_hdmi_deep_color_possible(crtc_state, bpc, has_hdmi_sink) &&
+		intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc);
+}
+
+static int intel_dp_max_bpp(struct intel_dp *intel_dp,
+			    const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	int bpp;
+	int bpp, bpc;
 
-	bpp = pipe_config->pipe_bpp;
+	bpc = crtc_state->pipe_bpp / 3;
 
 	if (intel_dp->dfp.max_bpc)
-		bpp = min(bpp, 3 * intel_dp->dfp.max_bpc);
+		bpc = min_t(int, bpc, intel_dp->dfp.max_bpc);
 
+	if (intel_dp->dfp.min_tmds_clock) {
+		for (; bpc >= 10; bpc -= 2) {
+			if (intel_dp_hdmi_deep_color_possible(intel_dp, crtc_state, bpc))
+				break;
+		}
+	}
+
+	bpp = bpc * 3;
 	if (intel_dp_is_edp(intel_dp)) {
 		/* Get bpp from vbt only for panels that dont have bpp in edid */
 		if (intel_connector->base.display_info.bpc == 0 &&
@@ -2244,7 +2295,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 	limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
 
 	limits.min_bpp = intel_dp_min_bpp(pipe_config);
-	limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config);
+	limits.max_bpp = intel_dp_max_bpp(intel_dp, pipe_config);
 
 	if (intel_dp_is_edp(intel_dp)) {
 		/*
@@ -3579,10 +3630,10 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
 {
 	u8 tmp;
 
-	if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
+	if (!drm_dp_is_branch(intel_dp->dpcd))
 		return;
 
-	if (!drm_dp_is_branch(intel_dp->dpcd))
+	if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
 		return;
 
 	tmp = intel_dp->has_hdmi_sink ?
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 31fec0050f8d..d6326a4a4a9a 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2218,35 +2218,18 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 	return intel_mode_valid_max_plane_size(dev_priv, mode);
 }
 
-static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
-				     int bpc)
+bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
+				    int bpc, bool has_hdmi_sink)
 {
-	struct drm_i915_private *dev_priv =
-		to_i915(crtc_state->uapi.crtc->dev);
 	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_connector_state *connector_state;
 	struct drm_connector *connector;
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
 	int i;
 
-	if (HAS_GMCH(dev_priv))
-		return false;
-
-	if (bpc == 10 && INTEL_GEN(dev_priv) < 11)
-		return false;
-
 	if (crtc_state->pipe_bpp < bpc * 3)
 		return false;
 
-	if (!crtc_state->has_hdmi_sink)
-		return false;
-
-	/*
-	 * HDMI deep color affects the clocks, so it's only possible
-	 * when not cloning with other encoder types.
-	 */
-	if (crtc_state->output_types != 1 << INTEL_OUTPUT_HDMI)
+	if (!has_hdmi_sink)
 		return false;
 
 	for_each_new_connector_in_state(state, connector, connector_state, i) {
@@ -2274,6 +2257,30 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		}
 	}
 
+	return true;
+}
+
+static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
+				     int bpc)
+{
+	struct drm_i915_private *dev_priv =
+		to_i915(crtc_state->uapi.crtc->dev);
+	const struct drm_display_mode *adjusted_mode =
+		&crtc_state->hw.adjusted_mode;
+
+	if (HAS_GMCH(dev_priv))
+		return false;
+
+	if (bpc == 10 && INTEL_GEN(dev_priv) < 11)
+		return false;
+
+	/*
+	 * HDMI deep color affects the clocks, so it's only possible
+	 * when not cloning with other encoder types.
+	 */
+	if (crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI))
+		return false;
+
 	/* Display Wa_1405510057:icl,ehl */
 	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
 	    bpc == 10 && IS_GEN(dev_priv, 11) &&
@@ -2281,7 +2288,8 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 	     adjusted_mode->crtc_hblank_start) % 8 == 2)
 		return false;
 
-	return true;
+	return intel_hdmi_deep_color_possible(crtc_state, bpc,
+					      crtc_state->has_hdmi_sink);
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index d3659d0b408b..bd58c929f816 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -48,5 +48,7 @@ void intel_read_infoframe(struct intel_encoder *encoder,
 			  const struct intel_crtc_state *crtc_state,
 			  enum hdmi_infoframe_type type,
 			  union hdmi_infoframe *frame);
+bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
+				    int bpc, bool has_hdmi_sink);
 
 #endif /* __INTEL_HDMI_H__ */
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 22/26] drm/dp: Add helpers for DFP YCbCr 4:2:0 handling
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add helpers to determine whether the DFP supports
YCbCr 4:2:0 passthrough or YCbCr 4:4:4->4:2:0 conversion.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 44 +++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |  8 ++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 507282dc79ac..66d176090d6a 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -615,6 +615,50 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
 
+bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				       const u8 port_cap[4])
+{
+	if (!drm_dp_is_branch(dpcd))
+		return false;
+
+	if (dpcd[DP_DPCD_REV] < 0x13)
+		return false;
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP:
+		return true;
+	case DP_DS_PORT_TYPE_HDMI:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return false;
+
+		return port_cap[3] & DP_DS_HDMI_YCBCR420_PASS_THROUGH;
+	default:
+		return false;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_420_passthrough);
+
+bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+					     const u8 port_cap[4])
+{
+	if (!drm_dp_is_branch(dpcd))
+		return false;
+
+	if (dpcd[DP_DPCD_REV] < 0x13)
+		return false;
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_HDMI:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return false;
+
+		return port_cap[3] & DP_DS_HDMI_YCBCR444_TO_420_CONV;
+	default:
+		return false;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_444_to_420_conversion);
+
 /**
  * drm_dp_downstream_mode() - return a mode for downstream facing port
  * @dpcd: DisplayPort configuration data
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index be4a5ffe4252..9cef282064f3 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -406,6 +406,10 @@ struct drm_device;
 # define DP_DS_DVI_HIGH_COLOR_DEPTH	    (1 << 2)
 /* offset 3 for HDMI */
 # define DP_DS_HDMI_FRAME_SEQ_TO_FRAME_PACK (1 << 0)
+# define DP_DS_HDMI_YCBCR422_PASS_THROUGH   (1 << 1)
+# define DP_DS_HDMI_YCBCR420_PASS_THROUGH   (1 << 2)
+# define DP_DS_HDMI_YCBCR444_TO_422_CONV    (1 << 3)
+# define DP_DS_HDMI_YCBCR444_TO_420_CONV    (1 << 4)
 
 #define DP_MAX_DOWNSTREAM_PORTS		    0x10
 
@@ -1500,6 +1504,10 @@ int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
+bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				       const u8 port_cap[4]);
+bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+					     const u8 port_cap[4]);
 struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev,
 						const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 						const u8 port_cap[4]);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 22/26] drm/dp: Add helpers for DFP YCbCr 4:2:0 handling
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add helpers to determine whether the DFP supports
YCbCr 4:2:0 passthrough or YCbCr 4:4:4->4:2:0 conversion.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 44 +++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     |  8 ++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 507282dc79ac..66d176090d6a 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -615,6 +615,50 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 }
 EXPORT_SYMBOL(drm_dp_downstream_max_bpc);
 
+bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				       const u8 port_cap[4])
+{
+	if (!drm_dp_is_branch(dpcd))
+		return false;
+
+	if (dpcd[DP_DPCD_REV] < 0x13)
+		return false;
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_DP:
+		return true;
+	case DP_DS_PORT_TYPE_HDMI:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return false;
+
+		return port_cap[3] & DP_DS_HDMI_YCBCR420_PASS_THROUGH;
+	default:
+		return false;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_420_passthrough);
+
+bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+					     const u8 port_cap[4])
+{
+	if (!drm_dp_is_branch(dpcd))
+		return false;
+
+	if (dpcd[DP_DPCD_REV] < 0x13)
+		return false;
+
+	switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
+	case DP_DS_PORT_TYPE_HDMI:
+		if ((dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) == 0)
+			return false;
+
+		return port_cap[3] & DP_DS_HDMI_YCBCR444_TO_420_CONV;
+	default:
+		return false;
+	}
+}
+EXPORT_SYMBOL(drm_dp_downstream_444_to_420_conversion);
+
 /**
  * drm_dp_downstream_mode() - return a mode for downstream facing port
  * @dpcd: DisplayPort configuration data
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index be4a5ffe4252..9cef282064f3 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -406,6 +406,10 @@ struct drm_device;
 # define DP_DS_DVI_HIGH_COLOR_DEPTH	    (1 << 2)
 /* offset 3 for HDMI */
 # define DP_DS_HDMI_FRAME_SEQ_TO_FRAME_PACK (1 << 0)
+# define DP_DS_HDMI_YCBCR422_PASS_THROUGH   (1 << 1)
+# define DP_DS_HDMI_YCBCR420_PASS_THROUGH   (1 << 2)
+# define DP_DS_HDMI_YCBCR444_TO_422_CONV    (1 << 3)
+# define DP_DS_HDMI_YCBCR444_TO_420_CONV    (1 << 4)
 
 #define DP_MAX_DOWNSTREAM_PORTS		    0x10
 
@@ -1500,6 +1504,10 @@ int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 			      const u8 port_cap[4],
 			      const struct edid *edid);
+bool drm_dp_downstream_420_passthrough(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+				       const u8 port_cap[4]);
+bool drm_dp_downstream_444_to_420_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+					     const u8 port_cap[4]);
 struct drm_display_mode *drm_dp_downstream_mode(struct drm_device *dev,
 						const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 						const u8 port_cap[4]);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 23/26] drm/i915: Do YCbCr 444->420 conversion via DP protocol converters
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

For platforms that can't do native 4:2:0 outout we may still be
able to do it by getting the DP->HDMI protocol converter to
perform the 4:4:4->4:2:0 downsamling for us. In this case we
have to configure our hardware to output YCbCr 4:4:4, which we've
already hooked up so all we need to do is flip the switch.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 118 +++++++++++++++---
 drivers/gpu/drm/i915/display/intel_hdmi.c     |   8 +-
 drivers/gpu/drm/i915/display/intel_hdmi.h     |   4 +-
 4 files changed, 106 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 117fc17dae44..00471791d772 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1310,6 +1310,7 @@ struct intel_dp {
 		int min_tmds_clock, max_tmds_clock;
 		int max_dotclock;
 		u8 max_bpc;
+		bool ycbcr_444_to_420;
 	} dfp;
 };
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 639a0c2e5a40..3bf19d691fd5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1921,7 +1921,9 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 static bool intel_dp_hdmi_ycbcr420(struct intel_dp *intel_dp,
 				   const struct intel_crtc_state *crtc_state)
 {
-	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420;
+	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
+		(crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&
+		 intel_dp->dfp.ycbcr_444_to_420);
 }
 
 static int intel_dp_hdmi_tmds_clock(struct intel_dp *intel_dp,
@@ -1955,9 +1957,10 @@ static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp,
 					      const struct intel_crtc_state *crtc_state,
 					      int bpc)
 {
-	bool has_hdmi_sink = intel_dp->has_hdmi_sink;
 
-	return intel_hdmi_deep_color_possible(crtc_state, bpc, has_hdmi_sink) &&
+	return intel_hdmi_deep_color_possible(crtc_state, bpc,
+					      intel_dp->has_hdmi_sink,
+					      intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) &&
 		intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc);
 }
 
@@ -2368,11 +2371,17 @@ intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	int ret;
 
-	if (!drm_mode_is_420_only(info, adjusted_mode) ||
-	    !intel_dp_get_colorimetry_status(intel_dp) ||
-	    !connector->ycbcr_420_allowed)
+	if (!connector->ycbcr_420_allowed)
 		return 0;
 
+	if (!drm_mode_is_420_only(info, adjusted_mode))
+		return 0;
+
+	if (intel_dp->dfp.ycbcr_444_to_420) {
+		crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+		return 0;
+	}
+
 	crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
 
 	/* YCBCR 420 output conversion needs a scaler */
@@ -3640,11 +3649,24 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
 		DP_HDMI_DVI_OUTPUT_CONFIG : 0;
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux,
-			       DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) <= 0)
+			       DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) != 1)
 		DRM_DEBUG_KMS("Failed to set protocol converter HDMI mode to %s\n",
 			      enableddisabled(intel_dp->has_hdmi_sink));
 
-	/* TODO: configure YCbCr 4:2:2/4:2:0 conversion */
+	tmp = intel_dp->dfp.ycbcr_444_to_420 ?
+		DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux,
+			       DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)
+		DRM_DEBUG_KMS("Failed to set protocol converter YCbCr 4:2:0 conversion mode to %s\n",
+			      enableddisabled(intel_dp->dfp.ycbcr_444_to_420));
+
+	tmp = 0;
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux,
+			       DP_PROTOCOL_CONVERTER_CONTROL_2, tmp) <= 0)
+		DRM_DEBUG_KMS("Failed to set protocol converter YCbCr 4:2:2 conversion mode to %s\n",
+			      enableddisabled(false));
 }
 
 static void intel_enable_dp(struct intel_encoder *encoder,
@@ -5739,14 +5761,10 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
 }
 
 static void
-intel_dp_set_edid(struct intel_dp *intel_dp)
+intel_dp_update_dfp(struct intel_dp *intel_dp,
+		    const struct edid *edid)
 {
 	struct intel_connector *connector = intel_dp->attached_connector;
-	struct edid *edid;
-
-	intel_dp_unset_edid(intel_dp);
-	edid = intel_dp_get_edid(intel_dp);
-	connector->detect_edid = edid;
 
 	intel_dp->dfp.max_bpc =
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
@@ -5771,6 +5789,66 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 		      intel_dp->dfp.max_dotclock,
 		      intel_dp->dfp.min_tmds_clock,
 		      intel_dp->dfp.max_tmds_clock);
+}
+
+static void
+intel_dp_update_420(struct intel_dp *intel_dp)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	bool is_branch, ycbcr_420_passthrough, ycbcr_444_to_420;
+
+	/* No YCbCr output support on gmch platforms */
+	if (HAS_GMCH(dev_priv))
+		return;
+
+	/*
+	 * ILK doesn't seem capable of DP YCbCr output. The
+	 * displayed image is severly corrupted. SNB+ is fine.
+	 */
+	if (IS_GEN(dev_priv, 5))
+		return;
+
+	is_branch = drm_dp_is_branch(intel_dp->dpcd);
+	ycbcr_420_passthrough =
+		drm_dp_downstream_420_passthrough(intel_dp->dpcd,
+						  intel_dp->downstream_ports);
+	ycbcr_444_to_420 =
+		drm_dp_downstream_444_to_420_conversion(intel_dp->dpcd,
+							intel_dp->downstream_ports);
+
+	if (INTEL_GEN(dev_priv) >= 11) {
+		/* Prefer 4:2:0 passthrough over 4:4:4->4:2:0 conversion */
+		intel_dp->dfp.ycbcr_444_to_420 =
+			ycbcr_444_to_420 && !ycbcr_420_passthrough;
+
+		connector->base.ycbcr_420_allowed =
+			!is_branch || ycbcr_444_to_420 || ycbcr_420_passthrough;
+	} else {
+		/* 4:4:4->4:2:0 conversion is the only way */
+		intel_dp->dfp.ycbcr_444_to_420 = ycbcr_444_to_420;
+
+		connector->base.ycbcr_420_allowed = ycbcr_444_to_420;
+	}
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n",
+		      connector->base.base.id, connector->base.name,
+		      yesno(connector->base.ycbcr_420_allowed),
+		      yesno(intel_dp->dfp.ycbcr_444_to_420));
+}
+
+static void
+intel_dp_set_edid(struct intel_dp *intel_dp)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct edid *edid;
+
+	intel_dp_unset_edid(intel_dp);
+	edid = intel_dp_get_edid(intel_dp);
+	connector->detect_edid = edid;
+
+	intel_dp_update_dfp(intel_dp, edid);
+	intel_dp_update_420(intel_dp);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5783,11 +5861,11 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 static void
 intel_dp_unset_edid(struct intel_dp *intel_dp)
 {
-	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct intel_connector *connector = intel_dp->attached_connector;
 
 	drm_dp_cec_unset_edid(&intel_dp->aux);
-	kfree(intel_connector->detect_edid);
-	intel_connector->detect_edid = NULL;
+	kfree(connector->detect_edid);
+	connector->detect_edid = NULL;
 
 	intel_dp->has_hdmi_sink = false;
 	intel_dp->has_audio = false;
@@ -5796,6 +5874,9 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	intel_dp->dfp.max_dotclock = 0;
 	intel_dp->dfp.min_tmds_clock = 0;
 	intel_dp->dfp.max_tmds_clock = 0;
+
+	intel_dp->dfp.ycbcr_444_to_420 = false;
+	connector->base.ycbcr_420_allowed = false;
 }
 
 static int
@@ -7703,9 +7784,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 		connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
 
-	if (INTEL_GEN(dev_priv) >= 11)
-		connector->ycbcr_420_allowed = true;
-
 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
 
 	intel_dp_aux_init(intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index d6326a4a4a9a..9e0316f6eb3f 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2219,7 +2219,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 }
 
 bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
-				    int bpc, bool has_hdmi_sink)
+				    int bpc, bool has_hdmi_sink, bool ycbcr420_output)
 {
 	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_connector_state *connector_state;
@@ -2238,7 +2238,7 @@ bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		if (connector_state->crtc != crtc_state->uapi.crtc)
 			continue;
 
-		if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
+		if (ycbcr420_output) {
 			const struct drm_hdmi_info *hdmi = &info->hdmi;
 
 			if (bpc == 12 && !(hdmi->y420_dc_modes &
@@ -2289,7 +2289,9 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		return false;
 
 	return intel_hdmi_deep_color_possible(crtc_state, bpc,
-					      crtc_state->has_hdmi_sink);
+					      crtc_state->has_hdmi_sink,
+					      crtc_state->output_format ==
+					      INTEL_OUTPUT_FORMAT_YCBCR420);
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index bd58c929f816..52cea8beafbb 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -48,7 +48,7 @@ void intel_read_infoframe(struct intel_encoder *encoder,
 			  const struct intel_crtc_state *crtc_state,
 			  enum hdmi_infoframe_type type,
 			  union hdmi_infoframe *frame);
-bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
-				    int bpc, bool has_hdmi_sink);
+bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, int bpc,
+				    bool has_hdmi_sink, bool ycbcr420_output);
 
 #endif /* __INTEL_HDMI_H__ */
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 23/26] drm/i915: Do YCbCr 444->420 conversion via DP protocol converters
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

For platforms that can't do native 4:2:0 outout we may still be
able to do it by getting the DP->HDMI protocol converter to
perform the 4:4:4->4:2:0 downsamling for us. In this case we
have to configure our hardware to output YCbCr 4:4:4, which we've
already hooked up so all we need to do is flip the switch.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 118 +++++++++++++++---
 drivers/gpu/drm/i915/display/intel_hdmi.c     |   8 +-
 drivers/gpu/drm/i915/display/intel_hdmi.h     |   4 +-
 4 files changed, 106 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 117fc17dae44..00471791d772 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1310,6 +1310,7 @@ struct intel_dp {
 		int min_tmds_clock, max_tmds_clock;
 		int max_dotclock;
 		u8 max_bpc;
+		bool ycbcr_444_to_420;
 	} dfp;
 };
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 639a0c2e5a40..3bf19d691fd5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1921,7 +1921,9 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 static bool intel_dp_hdmi_ycbcr420(struct intel_dp *intel_dp,
 				   const struct intel_crtc_state *crtc_state)
 {
-	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420;
+	return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
+		(crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&
+		 intel_dp->dfp.ycbcr_444_to_420);
 }
 
 static int intel_dp_hdmi_tmds_clock(struct intel_dp *intel_dp,
@@ -1955,9 +1957,10 @@ static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp,
 					      const struct intel_crtc_state *crtc_state,
 					      int bpc)
 {
-	bool has_hdmi_sink = intel_dp->has_hdmi_sink;
 
-	return intel_hdmi_deep_color_possible(crtc_state, bpc, has_hdmi_sink) &&
+	return intel_hdmi_deep_color_possible(crtc_state, bpc,
+					      intel_dp->has_hdmi_sink,
+					      intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) &&
 		intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc);
 }
 
@@ -2368,11 +2371,17 @@ intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	int ret;
 
-	if (!drm_mode_is_420_only(info, adjusted_mode) ||
-	    !intel_dp_get_colorimetry_status(intel_dp) ||
-	    !connector->ycbcr_420_allowed)
+	if (!connector->ycbcr_420_allowed)
 		return 0;
 
+	if (!drm_mode_is_420_only(info, adjusted_mode))
+		return 0;
+
+	if (intel_dp->dfp.ycbcr_444_to_420) {
+		crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+		return 0;
+	}
+
 	crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
 
 	/* YCBCR 420 output conversion needs a scaler */
@@ -3640,11 +3649,24 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
 		DP_HDMI_DVI_OUTPUT_CONFIG : 0;
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux,
-			       DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) <= 0)
+			       DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) != 1)
 		DRM_DEBUG_KMS("Failed to set protocol converter HDMI mode to %s\n",
 			      enableddisabled(intel_dp->has_hdmi_sink));
 
-	/* TODO: configure YCbCr 4:2:2/4:2:0 conversion */
+	tmp = intel_dp->dfp.ycbcr_444_to_420 ?
+		DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux,
+			       DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)
+		DRM_DEBUG_KMS("Failed to set protocol converter YCbCr 4:2:0 conversion mode to %s\n",
+			      enableddisabled(intel_dp->dfp.ycbcr_444_to_420));
+
+	tmp = 0;
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux,
+			       DP_PROTOCOL_CONVERTER_CONTROL_2, tmp) <= 0)
+		DRM_DEBUG_KMS("Failed to set protocol converter YCbCr 4:2:2 conversion mode to %s\n",
+			      enableddisabled(false));
 }
 
 static void intel_enable_dp(struct intel_encoder *encoder,
@@ -5739,14 +5761,10 @@ intel_dp_get_edid(struct intel_dp *intel_dp)
 }
 
 static void
-intel_dp_set_edid(struct intel_dp *intel_dp)
+intel_dp_update_dfp(struct intel_dp *intel_dp,
+		    const struct edid *edid)
 {
 	struct intel_connector *connector = intel_dp->attached_connector;
-	struct edid *edid;
-
-	intel_dp_unset_edid(intel_dp);
-	edid = intel_dp_get_edid(intel_dp);
-	connector->detect_edid = edid;
 
 	intel_dp->dfp.max_bpc =
 		drm_dp_downstream_max_bpc(intel_dp->dpcd,
@@ -5771,6 +5789,66 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 		      intel_dp->dfp.max_dotclock,
 		      intel_dp->dfp.min_tmds_clock,
 		      intel_dp->dfp.max_tmds_clock);
+}
+
+static void
+intel_dp_update_420(struct intel_dp *intel_dp)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	bool is_branch, ycbcr_420_passthrough, ycbcr_444_to_420;
+
+	/* No YCbCr output support on gmch platforms */
+	if (HAS_GMCH(dev_priv))
+		return;
+
+	/*
+	 * ILK doesn't seem capable of DP YCbCr output. The
+	 * displayed image is severly corrupted. SNB+ is fine.
+	 */
+	if (IS_GEN(dev_priv, 5))
+		return;
+
+	is_branch = drm_dp_is_branch(intel_dp->dpcd);
+	ycbcr_420_passthrough =
+		drm_dp_downstream_420_passthrough(intel_dp->dpcd,
+						  intel_dp->downstream_ports);
+	ycbcr_444_to_420 =
+		drm_dp_downstream_444_to_420_conversion(intel_dp->dpcd,
+							intel_dp->downstream_ports);
+
+	if (INTEL_GEN(dev_priv) >= 11) {
+		/* Prefer 4:2:0 passthrough over 4:4:4->4:2:0 conversion */
+		intel_dp->dfp.ycbcr_444_to_420 =
+			ycbcr_444_to_420 && !ycbcr_420_passthrough;
+
+		connector->base.ycbcr_420_allowed =
+			!is_branch || ycbcr_444_to_420 || ycbcr_420_passthrough;
+	} else {
+		/* 4:4:4->4:2:0 conversion is the only way */
+		intel_dp->dfp.ycbcr_444_to_420 = ycbcr_444_to_420;
+
+		connector->base.ycbcr_420_allowed = ycbcr_444_to_420;
+	}
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n",
+		      connector->base.base.id, connector->base.name,
+		      yesno(connector->base.ycbcr_420_allowed),
+		      yesno(intel_dp->dfp.ycbcr_444_to_420));
+}
+
+static void
+intel_dp_set_edid(struct intel_dp *intel_dp)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct edid *edid;
+
+	intel_dp_unset_edid(intel_dp);
+	edid = intel_dp_get_edid(intel_dp);
+	connector->detect_edid = edid;
+
+	intel_dp_update_dfp(intel_dp, edid);
+	intel_dp_update_420(intel_dp);
 
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -5783,11 +5861,11 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 static void
 intel_dp_unset_edid(struct intel_dp *intel_dp)
 {
-	struct intel_connector *intel_connector = intel_dp->attached_connector;
+	struct intel_connector *connector = intel_dp->attached_connector;
 
 	drm_dp_cec_unset_edid(&intel_dp->aux);
-	kfree(intel_connector->detect_edid);
-	intel_connector->detect_edid = NULL;
+	kfree(connector->detect_edid);
+	connector->detect_edid = NULL;
 
 	intel_dp->has_hdmi_sink = false;
 	intel_dp->has_audio = false;
@@ -5796,6 +5874,9 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 	intel_dp->dfp.max_dotclock = 0;
 	intel_dp->dfp.min_tmds_clock = 0;
 	intel_dp->dfp.max_tmds_clock = 0;
+
+	intel_dp->dfp.ycbcr_444_to_420 = false;
+	connector->base.ycbcr_420_allowed = false;
 }
 
 static int
@@ -7703,9 +7784,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 		connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
 
-	if (INTEL_GEN(dev_priv) >= 11)
-		connector->ycbcr_420_allowed = true;
-
 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
 
 	intel_dp_aux_init(intel_dp);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index d6326a4a4a9a..9e0316f6eb3f 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2219,7 +2219,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 }
 
 bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
-				    int bpc, bool has_hdmi_sink)
+				    int bpc, bool has_hdmi_sink, bool ycbcr420_output)
 {
 	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_connector_state *connector_state;
@@ -2238,7 +2238,7 @@ bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		if (connector_state->crtc != crtc_state->uapi.crtc)
 			continue;
 
-		if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
+		if (ycbcr420_output) {
 			const struct drm_hdmi_info *hdmi = &info->hdmi;
 
 			if (bpc == 12 && !(hdmi->y420_dc_modes &
@@ -2289,7 +2289,9 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 		return false;
 
 	return intel_hdmi_deep_color_possible(crtc_state, bpc,
-					      crtc_state->has_hdmi_sink);
+					      crtc_state->has_hdmi_sink,
+					      crtc_state->output_format ==
+					      INTEL_OUTPUT_FORMAT_YCBCR420);
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index bd58c929f816..52cea8beafbb 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -48,7 +48,7 @@ void intel_read_infoframe(struct intel_encoder *encoder,
 			  const struct intel_crtc_state *crtc_state,
 			  enum hdmi_infoframe_type type,
 			  union hdmi_infoframe *frame);
-bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
-				    int bpc, bool has_hdmi_sink);
+bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state, int bpc,
+				    bool has_hdmi_sink, bool ycbcr420_output);
 
 #endif /* __INTEL_HDMI_H__ */
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 24/26] drm/i915: Decouple DP++ from the HDMI code
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decouple the DP dual mode adaptor stuff from the HDMI code so that
we can try to use it for DP branch downstream facing HDMI ports as
well.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  6 +-
 .../drm/i915/display/intel_display_types.h    | 12 ++-
 drivers/gpu/drm/i915/display/intel_hdmi.c     | 94 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_hdmi.h     |  9 +-
 4 files changed, 72 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 3d1393ff6435..92c280905f31 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3598,7 +3598,8 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
 	int level = intel_ddi_hdmi_level(encoder);
 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, true);
 	intel_ddi_clk_select(encoder, crtc_state);
 
 	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
@@ -3778,7 +3779,8 @@ static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder,
 
 	intel_ddi_clk_disable(encoder);
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, false);
 }
 
 static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 00471791d772..0d135859e9d4 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -46,6 +46,7 @@
 #include "i915_drv.h"
 #include "intel_de.h"
 
+struct i2c_adapter;
 struct drm_printer;
 struct __intel_global_objs_state;
 
@@ -1150,15 +1151,18 @@ struct cxsr_latency {
 #define to_intel_plane_state(x) container_of(x, struct intel_plane_state, uapi)
 #define intel_fb_obj(x) ((x) ? to_intel_bo((x)->obj[0]) : NULL)
 
+struct intel_dp_dual_mode {
+	struct i2c_adapter *adapter;
+	int max_tmds_clock;
+	enum drm_dp_dual_mode_type type;
+};
+
 struct intel_hdmi {
 	i915_reg_t hdmi_reg;
 	int ddc_bus;
-	struct {
-		enum drm_dp_dual_mode_type type;
-		int max_tmds_clock;
-	} dp_dual_mode;
 	bool has_hdmi_sink;
 	bool has_audio;
+	struct intel_dp_dual_mode dp_dual_mode;
 	struct intel_connector *attached_connector;
 	struct cec_notifier *cec_notifier;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 9e0316f6eb3f..ad8e974585b9 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1249,20 +1249,19 @@ static void hsw_set_infoframes(struct intel_encoder *encoder,
 			      &crtc_state->infoframes.drm);
 }
 
-void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
+void intel_dp_dual_mode_set_tmds_output(struct intel_encoder *encoder,
+					struct intel_dp_dual_mode *dp_dual_mode,
+					bool enable)
 {
-	struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
-	struct i2c_adapter *adapter =
-		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
-
-	if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+	if (dp_dual_mode->type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return;
 
-	DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
+	DRM_DEBUG_KMS("[ENCODER:%d:%s] %s DP dual mode adaptor TMDS output\n",
+		      encoder->base.base.id, encoder->base.name,
 		      enable ? "Enabling" : "Disabling");
 
-	drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
-					 adapter, enable);
+	drm_dp_dual_mode_set_tmds_output(dp_dual_mode->type,
+					 dp_dual_mode->adapter, enable);
 }
 
 static int intel_hdmi_hdcp_read(struct intel_digital_port *intel_dig_port,
@@ -1750,7 +1749,8 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	u32 hdmi_val;
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, true);
 
 	hdmi_val = SDVO_ENCODING_HDMI;
 	if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range)
@@ -2064,7 +2064,8 @@ static void intel_disable_hdmi(struct intel_encoder *encoder,
 				       false,
 				       old_crtc_state, old_conn_state);
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, false);
 }
 
 static void g4x_disable_hdmi(struct intel_encoder *encoder,
@@ -2519,28 +2520,24 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 }
 
 static void
-intel_hdmi_unset_edid(struct drm_connector *connector)
+intel_hdmi_unset_edid(struct intel_connector *connector)
 {
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 	intel_hdmi->has_hdmi_sink = false;
 	intel_hdmi->has_audio = false;
 
-	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
-	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
+	intel_dp_dual_mode_reset(&intel_hdmi->dp_dual_mode);
 
-	kfree(to_intel_connector(connector)->detect_edid);
-	to_intel_connector(connector)->detect_edid = NULL;
+	kfree(connector->detect_edid);
+	connector->detect_edid = NULL;
 }
 
-static void
-intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
+void intel_dp_dual_mode_detect(struct intel_connector *connector,
+			       struct intel_dp_dual_mode *dp_dual_mode,
+			       bool assume_type1_dvi)
 {
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
-	struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
-	enum port port = hdmi_to_dig_port(hdmi)->base.port;
-	struct i2c_adapter *adapter =
-		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
+	struct i2c_adapter *adapter = dp_dual_mode->adapter;
 	enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter);
 
 	/*
@@ -2559,9 +2556,9 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 		/* An overridden EDID imply that we want this port for testing.
 		 * Make sure not to set limits for that port.
 		 */
-		if (has_edid && !connector->override_edid &&
-		    intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
-			DRM_DEBUG_KMS("Assuming DP dual mode adaptor presence based on VBT\n");
+		if (assume_type1_dvi) {
+			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Assuming type1 DVI DP dual mode adaptor presence\n",
+				      connector->base.base.id, connector->base.name);
 			type = DRM_DP_DUAL_MODE_TYPE1_DVI;
 		} else {
 			type = DRM_DP_DUAL_MODE_NONE;
@@ -2571,20 +2568,28 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 	if (type == DRM_DP_DUAL_MODE_NONE)
 		return;
 
-	hdmi->dp_dual_mode.type = type;
-	hdmi->dp_dual_mode.max_tmds_clock =
+	dp_dual_mode->type = type;
+	dp_dual_mode->max_tmds_clock =
 		drm_dp_dual_mode_max_tmds_clock(type, adapter);
 
-	DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
+		      connector->base.base.id, connector->base.name,
 		      drm_dp_get_dual_mode_type_name(type),
-		      hdmi->dp_dual_mode.max_tmds_clock);
+		      dp_dual_mode->max_tmds_clock);
+}
+
+void intel_dp_dual_mode_reset(struct intel_dp_dual_mode *dp_dual_mode)
+{
+	dp_dual_mode->type = DRM_DP_DUAL_MODE_NONE;
+	dp_dual_mode->max_tmds_clock = 0;
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct intel_connector *connector)
 {
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	enum port port = hdmi_to_dig_port(intel_hdmi)->base.port;
 	intel_wakeref_t wakeref;
 	struct edid *edid;
 	bool connected = false;
@@ -2594,20 +2599,22 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 
 	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
 
-	edid = drm_get_edid(connector, i2c);
+	edid = drm_get_edid(&connector->base, i2c);
 
 	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
 		DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
 		intel_gmbus_force_bit(i2c, true);
-		edid = drm_get_edid(connector, i2c);
+		edid = drm_get_edid(&connector->base, i2c);
 		intel_gmbus_force_bit(i2c, false);
 	}
 
-	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
+	intel_dp_dual_mode_detect(connector, &intel_hdmi->dp_dual_mode,
+				  edid && !connector->base.override_edid &&
+				  intel_bios_is_port_dp_dual_mode(dev_priv, port));
 
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
 
-	to_intel_connector(connector)->detect_edid = edid;
+	connector->detect_edid = edid;
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
 		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -2638,9 +2645,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	    !intel_digital_port_connected(encoder))
 		goto out;
 
-	intel_hdmi_unset_edid(connector);
+	intel_hdmi_unset_edid(to_intel_connector(connector));
 
-	if (intel_hdmi_set_edid(connector))
+	if (intel_hdmi_set_edid(to_intel_connector(connector)))
 		status = connector_status_connected;
 
 out:
@@ -2664,12 +2671,12 @@ intel_hdmi_force(struct drm_connector *connector)
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
 
-	intel_hdmi_unset_edid(connector);
+	intel_hdmi_unset_edid(to_intel_connector(connector));
 
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(to_intel_connector(connector));
 }
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
@@ -3188,6 +3195,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 		connector->ycbcr_420_allowed = true;
 
+	intel_hdmi->dp_dual_mode.adapter =
+		intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
+
 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
 
 	if (HAS_DDI(dev_priv))
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index 52cea8beafbb..e6f7047697ff 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -18,6 +18,7 @@ struct drm_encoder;
 struct drm_i915_private;
 struct intel_connector;
 struct intel_digital_port;
+struct intel_dp_dual_mode;
 struct intel_encoder;
 struct intel_crtc_state;
 struct intel_hdmi;
@@ -37,7 +38,13 @@ bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
 				       struct drm_connector *connector,
 				       bool high_tmds_clock_ratio,
 				       bool scrambling);
-void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
+void intel_dp_dual_mode_detect(struct intel_connector *connector,
+			       struct intel_dp_dual_mode *dp_dual_mode,
+			       bool assume_type1_dvi);
+void intel_dp_dual_mode_reset(struct intel_dp_dual_mode *dp_dual_mode);
+void intel_dp_dual_mode_set_tmds_output(struct intel_encoder *encodr,
+					struct intel_dp_dual_mode *dp_dual_mode,
+					bool enable);
 void intel_infoframe_init(struct intel_digital_port *intel_dig_port);
 u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 24/26] drm/i915: Decouple DP++ from the HDMI code
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Decouple the DP dual mode adaptor stuff from the HDMI code so that
we can try to use it for DP branch downstream facing HDMI ports as
well.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  6 +-
 .../drm/i915/display/intel_display_types.h    | 12 ++-
 drivers/gpu/drm/i915/display/intel_hdmi.c     | 94 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_hdmi.h     |  9 +-
 4 files changed, 72 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 3d1393ff6435..92c280905f31 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3598,7 +3598,8 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
 	int level = intel_ddi_hdmi_level(encoder);
 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, true);
 	intel_ddi_clk_select(encoder, crtc_state);
 
 	intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
@@ -3778,7 +3779,8 @@ static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder,
 
 	intel_ddi_clk_disable(encoder);
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, false);
 }
 
 static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 00471791d772..0d135859e9d4 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -46,6 +46,7 @@
 #include "i915_drv.h"
 #include "intel_de.h"
 
+struct i2c_adapter;
 struct drm_printer;
 struct __intel_global_objs_state;
 
@@ -1150,15 +1151,18 @@ struct cxsr_latency {
 #define to_intel_plane_state(x) container_of(x, struct intel_plane_state, uapi)
 #define intel_fb_obj(x) ((x) ? to_intel_bo((x)->obj[0]) : NULL)
 
+struct intel_dp_dual_mode {
+	struct i2c_adapter *adapter;
+	int max_tmds_clock;
+	enum drm_dp_dual_mode_type type;
+};
+
 struct intel_hdmi {
 	i915_reg_t hdmi_reg;
 	int ddc_bus;
-	struct {
-		enum drm_dp_dual_mode_type type;
-		int max_tmds_clock;
-	} dp_dual_mode;
 	bool has_hdmi_sink;
 	bool has_audio;
+	struct intel_dp_dual_mode dp_dual_mode;
 	struct intel_connector *attached_connector;
 	struct cec_notifier *cec_notifier;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 9e0316f6eb3f..ad8e974585b9 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1249,20 +1249,19 @@ static void hsw_set_infoframes(struct intel_encoder *encoder,
 			      &crtc_state->infoframes.drm);
 }
 
-void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
+void intel_dp_dual_mode_set_tmds_output(struct intel_encoder *encoder,
+					struct intel_dp_dual_mode *dp_dual_mode,
+					bool enable)
 {
-	struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
-	struct i2c_adapter *adapter =
-		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
-
-	if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+	if (dp_dual_mode->type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return;
 
-	DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
+	DRM_DEBUG_KMS("[ENCODER:%d:%s] %s DP dual mode adaptor TMDS output\n",
+		      encoder->base.base.id, encoder->base.name,
 		      enable ? "Enabling" : "Disabling");
 
-	drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
-					 adapter, enable);
+	drm_dp_dual_mode_set_tmds_output(dp_dual_mode->type,
+					 dp_dual_mode->adapter, enable);
 }
 
 static int intel_hdmi_hdcp_read(struct intel_digital_port *intel_dig_port,
@@ -1750,7 +1749,8 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	u32 hdmi_val;
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, true);
 
 	hdmi_val = SDVO_ENCODING_HDMI;
 	if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range)
@@ -2064,7 +2064,8 @@ static void intel_disable_hdmi(struct intel_encoder *encoder,
 				       false,
 				       old_crtc_state, old_conn_state);
 
-	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_hdmi->dp_dual_mode, false);
 }
 
 static void g4x_disable_hdmi(struct intel_encoder *encoder,
@@ -2519,28 +2520,24 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 }
 
 static void
-intel_hdmi_unset_edid(struct drm_connector *connector)
+intel_hdmi_unset_edid(struct intel_connector *connector)
 {
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 
 	intel_hdmi->has_hdmi_sink = false;
 	intel_hdmi->has_audio = false;
 
-	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
-	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
+	intel_dp_dual_mode_reset(&intel_hdmi->dp_dual_mode);
 
-	kfree(to_intel_connector(connector)->detect_edid);
-	to_intel_connector(connector)->detect_edid = NULL;
+	kfree(connector->detect_edid);
+	connector->detect_edid = NULL;
 }
 
-static void
-intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
+void intel_dp_dual_mode_detect(struct intel_connector *connector,
+			       struct intel_dp_dual_mode *dp_dual_mode,
+			       bool assume_type1_dvi)
 {
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
-	struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
-	enum port port = hdmi_to_dig_port(hdmi)->base.port;
-	struct i2c_adapter *adapter =
-		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
+	struct i2c_adapter *adapter = dp_dual_mode->adapter;
 	enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter);
 
 	/*
@@ -2559,9 +2556,9 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 		/* An overridden EDID imply that we want this port for testing.
 		 * Make sure not to set limits for that port.
 		 */
-		if (has_edid && !connector->override_edid &&
-		    intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
-			DRM_DEBUG_KMS("Assuming DP dual mode adaptor presence based on VBT\n");
+		if (assume_type1_dvi) {
+			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Assuming type1 DVI DP dual mode adaptor presence\n",
+				      connector->base.base.id, connector->base.name);
 			type = DRM_DP_DUAL_MODE_TYPE1_DVI;
 		} else {
 			type = DRM_DP_DUAL_MODE_NONE;
@@ -2571,20 +2568,28 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 	if (type == DRM_DP_DUAL_MODE_NONE)
 		return;
 
-	hdmi->dp_dual_mode.type = type;
-	hdmi->dp_dual_mode.max_tmds_clock =
+	dp_dual_mode->type = type;
+	dp_dual_mode->max_tmds_clock =
 		drm_dp_dual_mode_max_tmds_clock(type, adapter);
 
-	DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
+		      connector->base.base.id, connector->base.name,
 		      drm_dp_get_dual_mode_type_name(type),
-		      hdmi->dp_dual_mode.max_tmds_clock);
+		      dp_dual_mode->max_tmds_clock);
+}
+
+void intel_dp_dual_mode_reset(struct intel_dp_dual_mode *dp_dual_mode)
+{
+	dp_dual_mode->type = DRM_DP_DUAL_MODE_NONE;
+	dp_dual_mode->max_tmds_clock = 0;
 }
 
 static bool
-intel_hdmi_set_edid(struct drm_connector *connector)
+intel_hdmi_set_edid(struct intel_connector *connector)
 {
-	struct drm_i915_private *dev_priv = to_i915(connector->dev);
-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
+	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	enum port port = hdmi_to_dig_port(intel_hdmi)->base.port;
 	intel_wakeref_t wakeref;
 	struct edid *edid;
 	bool connected = false;
@@ -2594,20 +2599,22 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 
 	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
 
-	edid = drm_get_edid(connector, i2c);
+	edid = drm_get_edid(&connector->base, i2c);
 
 	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
 		DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
 		intel_gmbus_force_bit(i2c, true);
-		edid = drm_get_edid(connector, i2c);
+		edid = drm_get_edid(&connector->base, i2c);
 		intel_gmbus_force_bit(i2c, false);
 	}
 
-	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
+	intel_dp_dual_mode_detect(connector, &intel_hdmi->dp_dual_mode,
+				  edid && !connector->base.override_edid &&
+				  intel_bios_is_port_dp_dual_mode(dev_priv, port));
 
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
 
-	to_intel_connector(connector)->detect_edid = edid;
+	connector->detect_edid = edid;
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
 		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -2638,9 +2645,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	    !intel_digital_port_connected(encoder))
 		goto out;
 
-	intel_hdmi_unset_edid(connector);
+	intel_hdmi_unset_edid(to_intel_connector(connector));
 
-	if (intel_hdmi_set_edid(connector))
+	if (intel_hdmi_set_edid(to_intel_connector(connector)))
 		status = connector_status_connected;
 
 out:
@@ -2664,12 +2671,12 @@ intel_hdmi_force(struct drm_connector *connector)
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
 
-	intel_hdmi_unset_edid(connector);
+	intel_hdmi_unset_edid(to_intel_connector(connector));
 
 	if (connector->status != connector_status_connected)
 		return;
 
-	intel_hdmi_set_edid(connector);
+	intel_hdmi_set_edid(to_intel_connector(connector));
 }
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
@@ -3188,6 +3195,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 		connector->ycbcr_420_allowed = true;
 
+	intel_hdmi->dp_dual_mode.adapter =
+		intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
+
 	intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
 
 	if (HAS_DDI(dev_priv))
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index 52cea8beafbb..e6f7047697ff 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -18,6 +18,7 @@ struct drm_encoder;
 struct drm_i915_private;
 struct intel_connector;
 struct intel_digital_port;
+struct intel_dp_dual_mode;
 struct intel_encoder;
 struct intel_crtc_state;
 struct intel_hdmi;
@@ -37,7 +38,13 @@ bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
 				       struct drm_connector *connector,
 				       bool high_tmds_clock_ratio,
 				       bool scrambling);
-void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
+void intel_dp_dual_mode_detect(struct intel_connector *connector,
+			       struct intel_dp_dual_mode *dp_dual_mode,
+			       bool assume_type1_dvi);
+void intel_dp_dual_mode_reset(struct intel_dp_dual_mode *dp_dual_mode);
+void intel_dp_dual_mode_set_tmds_output(struct intel_encoder *encodr,
+					struct intel_dp_dual_mode *dp_dual_mode,
+					bool enable);
 void intel_infoframe_init(struct intel_digital_port *intel_dig_port);
 u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 25/26] drm/i915: Try to probe DP++ dongles on DP++ downstream facing ports
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

In order to get accurate TMDS clocks limits for the DP++ ports we
can try to probe the DP dual mode adapter registers. Unfortunately
I've not yet seen a DP->DP++ branch device that would actually
forward these i2c accesses to the dual mode dongle downstream.
But we don't lose much by trying and maybe it'll work on some
branch devices, if not now then maybe in the future.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 41 +++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 0d135859e9d4..5cd052f55662 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1316,6 +1316,7 @@ struct intel_dp {
 		u8 max_bpc;
 		bool ycbcr_444_to_420;
 	} dfp;
+	struct intel_dp_dual_mode dp_dual_mode;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3bf19d691fd5..5143c1b0fd92 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -608,6 +608,10 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
 	    tmds_clock > intel_dp->dfp.max_tmds_clock)
 		return MODE_CLOCK_HIGH;
 
+	if (intel_dp->dp_dual_mode.max_tmds_clock &&
+	    tmds_clock > intel_dp->dp_dual_mode.max_tmds_clock)
+		return MODE_CLOCK_HIGH;
+
 	return MODE_OK;
 }
 
@@ -1762,6 +1766,8 @@ intel_dp_aux_init(struct intel_dp *intel_dp)
 				       aux_ch_name(dig_port->aux_ch),
 				       port_name(encoder->port));
 	intel_dp->aux.transfer = intel_dp_aux_transfer;
+
+	intel_dp->dp_dual_mode.adapter = &intel_dp->aux.ddc;
 }
 
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
@@ -1950,6 +1956,10 @@ static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
 	    tmds_clock > intel_dp->dfp.max_tmds_clock)
 		return false;
 
+	if (intel_dp->dp_dual_mode.max_tmds_clock &&
+	    tmds_clock > intel_dp->dp_dual_mode.max_tmds_clock)
+		return false;
+
 	return true;
 }
 
@@ -5850,6 +5860,35 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 	intel_dp_update_dfp(intel_dp, edid);
 	intel_dp_update_420(intel_dp);
 
+	if (drm_dp_downstream_is_tmds(intel_dp->dpcd,
+				      intel_dp->downstream_ports,
+				      edid)) {
+		/*
+		 * Most branch devices don't seem to forward the
+		 * DP dual mode i2c accesses to the dongle, so even
+		 * when you have a type2 HDMI dongle with a high TMDS
+		 * clock limit we may not be able to detect it :(
+		 * To avoid users complaining about losing high
+		 * resolution modes let's not assume type1 DVI
+		 * dongle presence when the access fails. There
+		 * doesn't seem to be any way to read the CONFIG1
+		 * pin state from the branch device.
+		 */
+		intel_dp_dual_mode_detect(connector, &intel_dp->dp_dual_mode, false);
+
+		/*
+		 * We drive LSPCON DP dual mode adaptors in PCON mode
+		 * so we should just ignore the HDMI side of it.
+		 */
+		if (intel_dp->dp_dual_mode.type == DRM_DP_DUAL_MODE_LSPCON) {
+			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Ignoring LSPCON DP dual mode adaptor presence\n",
+				      connector->base.base.id,
+				      connector->base.name);
+
+			intel_dp_dual_mode_reset(&intel_dp->dp_dual_mode);
+		}
+	}
+
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 		intel_dp->has_audio = drm_detect_monitor_audio(edid);
@@ -5877,6 +5916,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 
 	intel_dp->dfp.ycbcr_444_to_420 = false;
 	connector->base.ycbcr_420_allowed = false;
+
+	intel_dp_dual_mode_reset(&intel_dp->dp_dual_mode);
 }
 
 static int
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 25/26] drm/i915: Try to probe DP++ dongles on DP++ downstream facing ports
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

In order to get accurate TMDS clocks limits for the DP++ ports we
can try to probe the DP dual mode adapter registers. Unfortunately
I've not yet seen a DP->DP++ branch device that would actually
forward these i2c accesses to the dual mode dongle downstream.
But we don't lose much by trying and maybe it'll work on some
branch devices, if not now then maybe in the future.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c       | 41 +++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 0d135859e9d4..5cd052f55662 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1316,6 +1316,7 @@ struct intel_dp {
 		u8 max_bpc;
 		bool ycbcr_444_to_420;
 	} dfp;
+	struct intel_dp_dual_mode dp_dual_mode;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3bf19d691fd5..5143c1b0fd92 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -608,6 +608,10 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
 	    tmds_clock > intel_dp->dfp.max_tmds_clock)
 		return MODE_CLOCK_HIGH;
 
+	if (intel_dp->dp_dual_mode.max_tmds_clock &&
+	    tmds_clock > intel_dp->dp_dual_mode.max_tmds_clock)
+		return MODE_CLOCK_HIGH;
+
 	return MODE_OK;
 }
 
@@ -1762,6 +1766,8 @@ intel_dp_aux_init(struct intel_dp *intel_dp)
 				       aux_ch_name(dig_port->aux_ch),
 				       port_name(encoder->port));
 	intel_dp->aux.transfer = intel_dp_aux_transfer;
+
+	intel_dp->dp_dual_mode.adapter = &intel_dp->aux.ddc;
 }
 
 bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
@@ -1950,6 +1956,10 @@ static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp,
 	    tmds_clock > intel_dp->dfp.max_tmds_clock)
 		return false;
 
+	if (intel_dp->dp_dual_mode.max_tmds_clock &&
+	    tmds_clock > intel_dp->dp_dual_mode.max_tmds_clock)
+		return false;
+
 	return true;
 }
 
@@ -5850,6 +5860,35 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
 	intel_dp_update_dfp(intel_dp, edid);
 	intel_dp_update_420(intel_dp);
 
+	if (drm_dp_downstream_is_tmds(intel_dp->dpcd,
+				      intel_dp->downstream_ports,
+				      edid)) {
+		/*
+		 * Most branch devices don't seem to forward the
+		 * DP dual mode i2c accesses to the dongle, so even
+		 * when you have a type2 HDMI dongle with a high TMDS
+		 * clock limit we may not be able to detect it :(
+		 * To avoid users complaining about losing high
+		 * resolution modes let's not assume type1 DVI
+		 * dongle presence when the access fails. There
+		 * doesn't seem to be any way to read the CONFIG1
+		 * pin state from the branch device.
+		 */
+		intel_dp_dual_mode_detect(connector, &intel_dp->dp_dual_mode, false);
+
+		/*
+		 * We drive LSPCON DP dual mode adaptors in PCON mode
+		 * so we should just ignore the HDMI side of it.
+		 */
+		if (intel_dp->dp_dual_mode.type == DRM_DP_DUAL_MODE_LSPCON) {
+			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Ignoring LSPCON DP dual mode adaptor presence\n",
+				      connector->base.base.id,
+				      connector->base.name);
+
+			intel_dp_dual_mode_reset(&intel_dp->dp_dual_mode);
+		}
+	}
+
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
 		intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 		intel_dp->has_audio = drm_detect_monitor_audio(edid);
@@ -5877,6 +5916,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 
 	intel_dp->dfp.ycbcr_444_to_420 = false;
 	connector->base.ycbcr_420_allowed = false;
+
+	intel_dp_dual_mode_reset(&intel_dp->dp_dual_mode);
 }
 
 static int
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH 26/26] drm/i915: Try to frob the TMDS buffer enable knob on DP++ dongles on DP DFPs
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
@ 2020-02-03 15:13   ` Ville Syrjala
  -1 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

To save a bit of power let's try to power down the TMDS buffers on
DP++ dongles hooked to downstream facing DP++ ports.

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_dp.c  | 25 ++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 92c280905f31..5daa52909980 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3512,6 +3512,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	else
 		WARN_ON(is_mst && port == PORT_A);
 
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
 				 crtc_state->lane_count, is_mst);
 
@@ -3757,6 +3760,9 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 						  dig_port->ddi_io_power_domain);
 
 	intel_ddi_clk_disable(encoder);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5143c1b0fd92..0452cc9423e6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3510,19 +3510,28 @@ static void g4x_post_disable_dp(struct intel_encoder *encoder,
 	/* Only ilk+ has port A */
 	if (port == PORT_A)
 		ilk_edp_pll_off(intel_dp, old_crtc_state);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void vlv_post_disable_dp(struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
 	intel_dp_link_down(encoder, old_crtc_state);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void chv_post_disable_dp(struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
 	intel_dp_link_down(encoder, old_crtc_state);
@@ -3533,6 +3542,9 @@ static void chv_post_disable_dp(struct intel_encoder *encoder,
 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
 
 	vlv_dpio_put(dev_priv);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void
@@ -3748,6 +3760,9 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	enum port port = encoder->port;
 
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	intel_dp_prepare(encoder, pipe_config);
 
 	/* Only ilk+ has port A */
@@ -3865,6 +3880,11 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
 
 	intel_enable_dp(encoder, pipe_config, conn_state);
@@ -3883,6 +3903,11 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	chv_phy_pre_encoder_enable(encoder, pipe_config);
 
 	intel_enable_dp(encoder, pipe_config, conn_state);
-- 
2.24.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] [PATCH 26/26] drm/i915: Try to frob the TMDS buffer enable knob on DP++ dongles on DP DFPs
@ 2020-02-03 15:13   ` Ville Syrjala
  0 siblings, 0 replies; 55+ messages in thread
From: Ville Syrjala @ 2020-02-03 15:13 UTC (permalink / raw)
  To: dri-devel; +Cc: intel-gfx

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

To save a bit of power let's try to power down the TMDS buffers on
DP++ dongles hooked to downstream facing DP++ ports.

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_dp.c  | 25 ++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 92c280905f31..5daa52909980 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3512,6 +3512,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	else
 		WARN_ON(is_mst && port == PORT_A);
 
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
 				 crtc_state->lane_count, is_mst);
 
@@ -3757,6 +3760,9 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
 						  dig_port->ddi_io_power_domain);
 
 	intel_ddi_clk_disable(encoder);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5143c1b0fd92..0452cc9423e6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3510,19 +3510,28 @@ static void g4x_post_disable_dp(struct intel_encoder *encoder,
 	/* Only ilk+ has port A */
 	if (port == PORT_A)
 		ilk_edp_pll_off(intel_dp, old_crtc_state);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void vlv_post_disable_dp(struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
 	intel_dp_link_down(encoder, old_crtc_state);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void chv_post_disable_dp(struct intel_encoder *encoder,
 				const struct intel_crtc_state *old_crtc_state,
 				const struct drm_connector_state *old_conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
 	intel_dp_link_down(encoder, old_crtc_state);
@@ -3533,6 +3542,9 @@ static void chv_post_disable_dp(struct intel_encoder *encoder,
 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
 
 	vlv_dpio_put(dev_priv);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, false);
 }
 
 static void
@@ -3748,6 +3760,9 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	enum port port = encoder->port;
 
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	intel_dp_prepare(encoder, pipe_config);
 
 	/* Only ilk+ has port A */
@@ -3865,6 +3880,11 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	vlv_phy_pre_encoder_enable(encoder, pipe_config);
 
 	intel_enable_dp(encoder, pipe_config, conn_state);
@@ -3883,6 +3903,11 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *pipe_config,
 			      const struct drm_connector_state *conn_state)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	intel_dp_dual_mode_set_tmds_output(encoder,
+					   &intel_dp->dp_dual_mode, true);
+
 	chv_phy_pre_encoder_enable(encoder, pipe_config);
 
 	intel_enable_dp(encoder, pipe_config, conn_state);
-- 
2.24.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: Pimp DP DFP handling
  2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
                   ` (26 preceding siblings ...)
  (?)
@ 2020-02-04 19:20 ` Patchwork
  -1 siblings, 0 replies; 55+ messages in thread
From: Patchwork @ 2020-02-04 19:20 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Pimp DP DFP handling
URL   : https://patchwork.freedesktop.org/series/72928/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_7864 -> Patchwork_16399
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_16399 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_16399, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_16399:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_sync@basic-each:
    - fi-skl-6770hq:      [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-skl-6770hq/igt@gem_sync@basic-each.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-skl-6770hq/igt@gem_sync@basic-each.html

  
Known issues
------------

  Here are the changes found in Patchwork_16399 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_close_race@basic-threads:
    - fi-byt-j1900:       [PASS][3] -> [INCOMPLETE][4] ([i915#45])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-byt-j1900/igt@gem_close_race@basic-threads.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-byt-j1900/igt@gem_close_race@basic-threads.html

  * igt@gem_exec_parallel@fds:
    - fi-byt-n2820:       [PASS][5] -> [TIMEOUT][6] ([fdo#112271] / [i915#1084])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-byt-n2820/igt@gem_exec_parallel@fds.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-byt-n2820/igt@gem_exec_parallel@fds.html

  * igt@gem_exec_suspend@basic-s4-devices:
    - fi-tgl-y:           [PASS][7] -> [FAIL][8] ([CI#94])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-tgl-y/igt@gem_exec_suspend@basic-s4-devices.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-tgl-y/igt@gem_exec_suspend@basic-s4-devices.html

  * igt@i915_getparams_basic@basic-subslice-total:
    - fi-tgl-y:           [PASS][9] -> [DMESG-WARN][10] ([CI#94] / [i915#402]) +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-tgl-y/igt@i915_getparams_basic@basic-subslice-total.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-tgl-y/igt@i915_getparams_basic@basic-subslice-total.html

  * igt@i915_selftest@live_blt:
    - fi-hsw-4770r:       [PASS][11] -> [DMESG-FAIL][12] ([i915#553] / [i915#725])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-hsw-4770r/igt@i915_selftest@live_blt.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-hsw-4770r/igt@i915_selftest@live_blt.html

  * igt@i915_selftest@live_gem_contexts:
    - fi-cfl-guc:         [PASS][13] -> [INCOMPLETE][14] ([fdo#106070] / [i915#424])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-cfl-guc/igt@i915_selftest@live_gem_contexts.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-cfl-guc/igt@i915_selftest@live_gem_contexts.html

  * igt@i915_selftest@live_gtt:
    - fi-kbl-x1275:       [PASS][15] -> [TIMEOUT][16] ([fdo#112271])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-kbl-x1275/igt@i915_selftest@live_gtt.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-kbl-x1275/igt@i915_selftest@live_gtt.html

  * igt@i915_selftest@live_hangcheck:
    - fi-icl-u2:          [PASS][17] -> [INCOMPLETE][18] ([fdo#108569])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-icl-u2/igt@i915_selftest@live_hangcheck.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-icl-u2/igt@i915_selftest@live_hangcheck.html

  
#### Possible fixes ####

  * igt@i915_selftest@live_execlists:
    - fi-icl-y:           [DMESG-FAIL][19] ([fdo#108569]) -> [PASS][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-icl-y/igt@i915_selftest@live_execlists.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-icl-y/igt@i915_selftest@live_execlists.html

  * igt@i915_selftest@live_gtt:
    - fi-skl-6600u:       [TIMEOUT][21] ([fdo#111732] / [fdo#112271]) -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-skl-6600u/igt@i915_selftest@live_gtt.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-skl-6600u/igt@i915_selftest@live_gtt.html

  * igt@i915_selftest@live_perf:
    - fi-apl-guc:         [INCOMPLETE][23] ([fdo#103927]) -> [PASS][24]
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-apl-guc/igt@i915_selftest@live_perf.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-apl-guc/igt@i915_selftest@live_perf.html

  * igt@prime_self_import@basic-llseek-bad:
    - fi-tgl-y:           [DMESG-WARN][25] ([CI#94] / [i915#402]) -> [PASS][26] +1 similar issue
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-tgl-y/igt@prime_self_import@basic-llseek-bad.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-tgl-y/igt@prime_self_import@basic-llseek-bad.html

  
#### Warnings ####

  * igt@gem_exec_parallel@contexts:
    - fi-byt-n2820:       [TIMEOUT][27] ([fdo#112271]) -> [FAIL][28] ([i915#694])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-byt-n2820/igt@gem_exec_parallel@contexts.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-byt-n2820/igt@gem_exec_parallel@contexts.html

  * igt@i915_selftest@live_blt:
    - fi-hsw-4770:        [DMESG-FAIL][29] ([i915#725]) -> [DMESG-FAIL][30] ([i915#553] / [i915#725])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7864/fi-hsw-4770/igt@i915_selftest@live_blt.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/fi-hsw-4770/igt@i915_selftest@live_blt.html

  
  [CI#94]: https://gitlab.freedesktop.org/gfx-ci/i915-infra/issues/94
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#106070]: https://bugs.freedesktop.org/show_bug.cgi?id=106070
  [fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569
  [fdo#111732]: https://bugs.freedesktop.org/show_bug.cgi?id=111732
  [fdo#112271]: https://bugs.freedesktop.org/show_bug.cgi?id=112271
  [i915#1084]: https://gitlab.freedesktop.org/drm/intel/issues/1084
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#424]: https://gitlab.freedesktop.org/drm/intel/issues/424
  [i915#45]: https://gitlab.freedesktop.org/drm/intel/issues/45
  [i915#553]: https://gitlab.freedesktop.org/drm/intel/issues/553
  [i915#694]: https://gitlab.freedesktop.org/drm/intel/issues/694
  [i915#725]: https://gitlab.freedesktop.org/drm/intel/issues/725


Participating hosts (50 -> 43)
------------------------------

  Additional (3): fi-skl-lmem fi-glk-dsi fi-snb-2520m 
  Missing    (10): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-ctg-p8600 fi-byt-clapper fi-ivb-3770 fi-kbl-8809g fi-snb-2600 fi-bdw-samus fi-kbl-r 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_7864 -> Patchwork_16399

  CI-20190529: 20190529
  CI_DRM_7864: 5a140e2fc771e4c8b10d14e2db7bfb4996ee9d8a @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5417: 33cc93c8ba5daa0b7498f297a4f626844d895d06 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_16399: 2675d3dca335a78da4b91ef0d3b48e8c8b7f0e96 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

2675d3dca335 drm/i915: Try to frob the TMDS buffer enable knob on DP++ dongles on DP DFPs
b6df3788e42c drm/i915: Try to probe DP++ dongles on DP++ downstream facing ports
334730414489 drm/i915: Decouple DP++ from the HDMI code
4570c3326269 drm/i915: Do YCbCr 444->420 conversion via DP protocol converters
3b38188f6d4b drm/dp: Add helpers for DFP YCbCr 4:2:0 handling
258639e92a7e drm/i915: DP->HDMI TMDS clock limits vs. deep color
004b2de6a4da drm/i915: Extract intel_hdmi_has_audio()
cc7d9efd1998 drm/i915: Handle downstream facing ports w/o EDID
cfe69f08a962 drm/dp: Add drm_dp_downstream_mode()
1e8824c04e15 drm/i915: Configure DP 1.3+ protocol converted HDMI mode
2699909da08b drm/i915: Deal with TMDS DFP clock limits
bd5a85914575 drm/dp: Add drm_dp_downstream_{min, max}_tmds_clock()
18bfccf2db60 drm/i915: Dump downstream facing port caps
225204d92e23 drm/i915: Reworkd DP DFP clock handling
a3791019b244 drm/dp: Redo drm_dp_downstream_max_clock() as drm_dp_downstream_max_dotclock()
cf9506a4476b drm/dp: Pimp drm_dp_downstream_max_bpc()
93acb70d4717 drm/dp: Add helpers to identify downstream facing port types
00f28ad2ea76 drm/i915: Reworkd DFP max bpc handling
25a89b50d5de drm/dp: Define more downstream facing port caps
046014a9c3c0 drm/dp: Define protocol converter DPCD registers
9128f5651fbf drm/i915/lspcon: Do not send infoframes to non-HDMI sinks
a548dc77b11e drm/dp: Include the AUX CH name in the debug messages
ca153f382d1c drm/i915: Add glk to intel_detect_preproduction_hw()
784501bdd7bb drm/i915: Drop WaDDIIOTimeout:glk
17f2f3466819 drm/i915: Limit display Wa_1405510057 to gen11
a94d44f51a6c drm/i915: Nuke pre-production GLK HDMI w/a 1139

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_16399/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2020-02-04 19:20 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-03 15:13 [PATCH 00/26] drm/i915: Pimp DP DFP handling Ville Syrjala
2020-02-03 15:13 ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 01/26] drm/i915: Nuke pre-production GLK HDMI w/a 1139 Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 02/26] drm/i915: Limit display Wa_1405510057 to gen11 Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 03/26] drm/i915: Drop WaDDIIOTimeout:glk Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 04/26] drm/i915: Add glk to intel_detect_preproduction_hw() Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 05/26] drm/dp: Include the AUX CH name in the debug messages Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 06/26] drm/i915/lspcon: Do not send infoframes to non-HDMI sinks Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 07/26] drm/dp: Define protocol converter DPCD registers Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 08/26] drm/dp: Define more downstream facing port caps Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 09/26] drm/i915: Reworkd DFP max bpc handling Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 10/26] drm/dp: Add helpers to identify downstream facing port types Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 11/26] drm/dp: Pimp drm_dp_downstream_max_bpc() Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 12/26] drm/dp: Redo drm_dp_downstream_max_clock() as drm_dp_downstream_max_dotclock() Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 13/26] drm/i915: Reworkd DP DFP clock handling Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 14/26] drm/i915: Dump downstream facing port caps Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 15/26] drm/dp: Add drm_dp_downstream_{min,max}_tmds_clock() Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] [PATCH 15/26] drm/dp: Add drm_dp_downstream_{min, max}_tmds_clock() Ville Syrjala
2020-02-03 15:13 ` [PATCH 16/26] drm/i915: Deal with TMDS DFP clock limits Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 17/26] drm/i915: Configure DP 1.3+ protocol converted HDMI mode Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 18/26] drm/dp: Add drm_dp_downstream_mode() Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 19/26] drm/i915: Handle downstream facing ports w/o EDID Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 20/26] drm/i915: Extract intel_hdmi_has_audio() Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 21/26] drm/i915: DP->HDMI TMDS clock limits vs. deep color Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 22/26] drm/dp: Add helpers for DFP YCbCr 4:2:0 handling Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 23/26] drm/i915: Do YCbCr 444->420 conversion via DP protocol converters Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 24/26] drm/i915: Decouple DP++ from the HDMI code Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 25/26] drm/i915: Try to probe DP++ dongles on DP++ downstream facing ports Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-03 15:13 ` [PATCH 26/26] drm/i915: Try to frob the TMDS buffer enable knob on DP++ dongles on DP DFPs Ville Syrjala
2020-02-03 15:13   ` [Intel-gfx] " Ville Syrjala
2020-02-04 19:20 ` [Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: Pimp DP DFP handling Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.