[Intel-gfx] [PATCH v5 00/15] Add support for DP-HDMI2.1 PCON

2020-12-15 Thread Ankit Nautiyal
This patch series attempts to add support for a DP-HDMI2.1 Protocol
Convertor. The VESA spec for the HDMI2.1 PCON are proposed in Errata
E5 to DisplayPort_v2.0:
https://vesa.org/join-vesamemberships/member-downloads/?action=stamp&fileid=42299
The details are mentioned in:
VESA DP-to-HDMI PCON Specification Standalone Document
https://groups.vesa.org/wg/DP/document/15651

This series starts with adding support for FRL (Fixed Rate Link)
Training between the PCON and HDMI2.1 sink.
As per HDMI2.1 specification, a new data-channel or lane is added in
FRL mode, by repurposing the TMDS clock Channel. Through FRL, higher
bit-rate can be supported, ie. up to 12 Gbps/lane (48 Gbps over 4
lanes).

With these patches, the HDMI2.1 PCON can be configured to achieve FRL
training based on the maximum FRL rate supported by the panel, source
and the PCON.
The approach is to add the support for FRL training between PCON and
HDMI2.1 sink and gradually add other blocks for supporting higher
resolutions and other HDMI2.1 features, that can be supported by pcon
for the sources that do not natively support HDMI2.1.

This is done before the DP Link training between the source and PCON
is started. In case of FRL training is not achieved, the PCON will
work in the regular TMDS mode, without HDMI2.1 feature support.
Any interruption in FRL training between the PCON and HDMI2.1 sink is
notified through IRQ_HPD. On receiving the IRQ_HPD the concerned DPCD
registers are read and FRL training is re-attempted.

Currently, we have tested the FRL training and are able to enable 4K
display with TGL Platform + Realtek PCON RTD2173 with HDMI2.1 supporting
panel.

v2: Addressed review comments and re-organized patches as suggested in
comments on RFC patches.

v3: Addressed review comments on previous version.

v4: Added support for RGB->YCBCR conversion through PCON

v5: Addressed review comments on previous version.

Ankit Nautiyal (11):
  drm/edid: Parse DSC1.2 cap fields from HFVSDB block
  drm/dp_helper: Add Helpers for FRL Link Training support for
DP-HDMI2.1 PCON
  drm/dp_helper: Add support for Configuring DSC for HDMI2.1 Pcon
  drm/dp_helper: Add helpers to configure PCONs RGB-YCbCr Conversion
  drm/i915: Capture max frl rate for PCON in dfp cap structure
  drm/i915: Add support for starting FRL training for HDMI2.1 via PCON
  drm/i915: Check for FRL training before DP Link training
  drm/i915: Read DSC capabilities of the HDMI2.1 PCON encoder
  drm/i915: Add helper functions for calculating DSC parameters for
HDMI2.1
  drm/i915/display: Configure PCON for DSC1.1 to DSC1.2 encoding
  drm/i915/display: Let PCON convert from RGB to YUV if it can

Swati Sharma (4):
  drm/edid: Add additional HFVSDB fields for HDMI2.1
  drm/edid: Parse MAX_FRL field from HFVSDB block
  drm/dp_helper: Add support for link failure detection
  drm/i915: Add support for enabling link status and recovery

 drivers/gpu/drm/drm_dp_helper.c   | 566 ++
 drivers/gpu/drm/drm_edid.c| 103 
 drivers/gpu/drm/i915/display/intel_ddi.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  10 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 438 +-
 drivers/gpu/drm/i915/display/intel_dp.h   |   7 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 233 +++
 drivers/gpu/drm/i915/display/intel_hdmi.h |   7 +
 include/drm/drm_connector.h   |  49 ++
 include/drm/drm_dp_helper.h   | 218 +++
 include/drm/drm_edid.h|  30 +
 11 files changed, 1645 insertions(+), 22 deletions(-)

-- 
2.17.1

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


[Intel-gfx] [PATCH v5 01/15] drm/edid: Add additional HFVSDB fields for HDMI2.1

2020-12-15 Thread Ankit Nautiyal
From: Swati Sharma 

The HDMI2.1 extends HFVSDB (HDMI Forum Vendor Specific
Data block) to have fields related to newly defined methods of FRL
(Fixed Rate Link) levels, number of lanes supported, DSC Color bit
depth, VRR min/max, FVA (Fast Vactive), ALLM etc.

This patch adds the new HFVSDB fields that are required for
HDMI2.1.

v2: Minor fixes + consistent naming for DPCD register masks
(Uma Shankar)

Signed-off-by: Sharma, Swati2 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 include/drm/drm_edid.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index e97daf6ffbb1..a158f585f658 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -229,6 +229,36 @@ struct detailed_timing {
DRM_EDID_YCBCR420_DC_36 | \
DRM_EDID_YCBCR420_DC_30)
 
+/* HDMI 2.1 additional fields */
+#define DRM_EDID_MAX_FRL_RATE_MASK 0xf0
+#define DRM_EDID_FAPA_START_LOCATION   (1 << 0)
+#define DRM_EDID_ALLM  (1 << 1)
+#define DRM_EDID_FVA   (1 << 2)
+
+/* Deep Color specific */
+#define DRM_EDID_DC_30BIT_420  (1 << 0)
+#define DRM_EDID_DC_36BIT_420  (1 << 1)
+#define DRM_EDID_DC_48BIT_420  (1 << 2)
+
+/* VRR specific */
+#define DRM_EDID_CNMVRR(1 << 3)
+#define DRM_EDID_CINEMA_VRR(1 << 4)
+#define DRM_EDID_MDELTA(1 << 5)
+#define DRM_EDID_VRR_MAX_UPPER_MASK0xc0
+#define DRM_EDID_VRR_MAX_LOWER_MASK0xff
+#define DRM_EDID_VRR_MIN_MASK  0x3f
+
+/* DSC specific */
+#define DRM_EDID_DSC_10BPC (1 << 0)
+#define DRM_EDID_DSC_12BPC (1 << 1)
+#define DRM_EDID_DSC_16BPC (1 << 2)
+#define DRM_EDID_DSC_ALL_BPP   (1 << 3)
+#define DRM_EDID_DSC_NATIVE_420(1 << 6)
+#define DRM_EDID_DSC_1P2   (1 << 7)
+#define DRM_EDID_DSC_MAX_FRL_RATE_MASK 0xf0
+#define DRM_EDID_DSC_MAX_SLICES0xf
+#define DRM_EDID_DSC_TOTAL_CHUNK_KBYTES0x3f
+
 /* ELD Header Block */
 #define DRM_ELD_HEADER_BLOCK_SIZE  4
 
-- 
2.17.1

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


[Intel-gfx] [PATCH v5 02/15] drm/edid: Parse MAX_FRL field from HFVSDB block

2020-12-15 Thread Ankit Nautiyal
From: Swati Sharma 

This patch parses MAX_FRL field to get the MAX rate in Gbps that
the HDMI 2.1 panel can support in FRL mode. Source need this
field to determine the optimal rate between the source and sink
during FRL training.

v2: Fixed minor bugs, and removed extra wrapper function (Uma Shankar)

Signed-off-by: Sharma, Swati2 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/drm_edid.c  | 44 +
 include/drm/drm_connector.h |  6 +
 2 files changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 74f5a3197214..e657c321d9e4 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4851,6 +4851,41 @@ static void drm_parse_vcdb(struct drm_connector 
*connector, const u8 *db)
info->rgb_quant_range_selectable = true;
 }
 
+static
+void drm_get_max_frl_rate(int max_frl_rate, u8 *max_lanes, u8 
*max_rate_per_lane)
+{
+   switch (max_frl_rate) {
+   case 1:
+   *max_lanes = 3;
+   *max_rate_per_lane = 3;
+   break;
+   case 2:
+   *max_lanes = 3;
+   *max_rate_per_lane = 6;
+   break;
+   case 3:
+   *max_lanes = 4;
+   *max_rate_per_lane = 6;
+   break;
+   case 4:
+   *max_lanes = 4;
+   *max_rate_per_lane = 8;
+   break;
+   case 5:
+   *max_lanes = 4;
+   *max_rate_per_lane = 10;
+   break;
+   case 6:
+   *max_lanes = 4;
+   *max_rate_per_lane = 12;
+   break;
+   case 0:
+   default:
+   *max_lanes = 0;
+   *max_rate_per_lane = 0;
+   }
+}
+
 static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
   const u8 *db)
 {
@@ -4904,6 +4939,15 @@ static void drm_parse_hdmi_forum_vsdb(struct 
drm_connector *connector,
}
}
 
+   if (hf_vsdb[7]) {
+   u8 max_frl_rate;
+
+   DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
+   max_frl_rate = (hf_vsdb[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
+   drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
+   &hdmi->max_frl_rate_per_lane);
+   }
+
drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
 }
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fcdc58d8b88b..1a3b4776b458 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -207,6 +207,12 @@ struct drm_hdmi_info {
 
/** @y420_dc_modes: bitmap of deep color support index */
u8 y420_dc_modes;
+
+   /** @max_frl_rate_per_lane: support fixed rate link */
+   u8 max_frl_rate_per_lane;
+
+   /** @max_lanes: supported by sink */
+   u8 max_lanes;
 };
 
 /**
-- 
2.17.1

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


[Intel-gfx] [PATCH v5 03/15] drm/edid: Parse DSC1.2 cap fields from HFVSDB block

2020-12-15 Thread Ankit Nautiyal
This patch parses HFVSDB fields for DSC1.2 capabilities of an
HDMI2.1 sink. These fields are required by a source to understand the
DSC capability of the sink, to set appropriate PPS parameters,
before transmitting compressed data stream.

v2: Addressed following issues as suggested by Uma Shankar:
-Added a new struct for hdmi dsc cap
-Fixed bugs in macros usage.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/drm_edid.c  | 59 +
 include/drm/drm_connector.h | 43 +++
 2 files changed, 102 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e657c321d9e4..ca368df2e5ac 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4941,11 +4941,70 @@ static void drm_parse_hdmi_forum_vsdb(struct 
drm_connector *connector,
 
if (hf_vsdb[7]) {
u8 max_frl_rate;
+   u8 dsc_max_frl_rate;
+   u8 dsc_max_slices;
+   struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
 
DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
max_frl_rate = (hf_vsdb[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
&hdmi->max_frl_rate_per_lane);
+   hdmi_dsc->v_1p2 = hf_vsdb[11] & DRM_EDID_DSC_1P2;
+
+   if (hdmi_dsc->v_1p2) {
+   hdmi_dsc->native_420 = hf_vsdb[11] & 
DRM_EDID_DSC_NATIVE_420;
+   hdmi_dsc->all_bpp = hf_vsdb[11] & DRM_EDID_DSC_ALL_BPP;
+
+   if (hf_vsdb[11] & DRM_EDID_DSC_16BPC)
+   hdmi_dsc->bpc_supported = 16;
+   else if (hf_vsdb[11] & DRM_EDID_DSC_12BPC)
+   hdmi_dsc->bpc_supported = 12;
+   else if (hf_vsdb[11] & DRM_EDID_DSC_10BPC)
+   hdmi_dsc->bpc_supported = 10;
+   else
+   hdmi_dsc->bpc_supported = 0;
+
+   dsc_max_frl_rate = (hf_vsdb[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
+   drm_get_max_frl_rate(dsc_max_frl_rate, 
&hdmi_dsc->max_lanes,
+   &hdmi_dsc->max_frl_rate_per_lane);
+   hdmi_dsc->total_chunk_kbytes = hf_vsdb[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
+
+   dsc_max_slices = hf_vsdb[12] & DRM_EDID_DSC_MAX_SLICES;
+   switch (dsc_max_slices) {
+   case 1:
+   hdmi_dsc->max_slices = 1;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 2:
+   hdmi_dsc->max_slices = 2;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 3:
+   hdmi_dsc->max_slices = 4;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 4:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 5:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 6:
+   hdmi_dsc->max_slices = 12;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 7:
+   hdmi_dsc->max_slices = 16;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 0:
+   default:
+   hdmi_dsc->max_slices = 0;
+   hdmi_dsc->clk_per_slice = 0;
+   }
+   }
}
 
drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 1a3b4776b458..1922b278ffad 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -175,6 +175,46 @@ struct drm_scdc {
struct drm_scrambling scrambling;
 };
 
+/**
+ * struct drm_hdmi_dsc_cap - DSC capabilities of HDMI sink
+ *
+ * Describes the DSC support provided by HDMI 2.1 sink.
+ * The information is fetched fom additional HFVSDB blocks defined
+ * for HDMI 2.1.
+ */
+struct drm_hdmi_dsc_cap {
+   /** @v_1p2: flag for dsc1.2 version support by sink */
+   

[Intel-gfx] [PATCH v5 04/15] drm/dp_helper: Add Helpers for FRL Link Training support for DP-HDMI2.1 PCON

2020-12-15 Thread Ankit Nautiyal
This patch adds support for configuring a PCON device,
connected as a DP branched device to enable FRL Link training
with a HDMI2.1 + sink.

v2: Fixed typos and addressed other review comments from Uma Shankar.
-changed the commit message for better clarity (Uma Shankar)
-removed unnecessary argument supplied to a drm helper function.
-fixed return value for max frl read from pcon.

v3: Removed DPCD 0x3035 for MAX Sink FRL b/w as per new version of spec.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 drivers/gpu/drm/drm_dp_helper.c | 263 
 include/drm/drm_dp_helper.h |  70 +
 2 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 5bd0934004e3..f501e3890921 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -2596,3 +2596,266 @@ void drm_dp_vsc_sdp_log(const char *level, struct 
device *dev,
 #undef DP_SDP_LOG
 }
 EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
+
+/**
+ * drm_dp_get_pcon_max_frl_bw() - maximum frl supported by PCON
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ *
+ * Returns maximum frl bandwidth supported by PCON in GBPS,
+ * returns 0 if not supported.
+ */
+int drm_dp_get_pcon_max_frl_bw(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+  const u8 port_cap[4])
+{
+   int bw;
+   u8 buf;
+
+   buf = port_cap[2];
+   bw = buf & DP_PCON_MAX_FRL_BW;
+
+   switch (bw) {
+   case DP_PCON_MAX_9GBPS:
+   return 9;
+   case DP_PCON_MAX_18GBPS:
+   return 18;
+   case DP_PCON_MAX_24GBPS:
+   return 24;
+   case DP_PCON_MAX_32GBPS:
+   return 32;
+   case DP_PCON_MAX_40GBPS:
+   return 40;
+   case DP_PCON_MAX_48GBPS:
+   return 48;
+   case DP_PCON_MAX_0GBPS:
+   default:
+   return 0;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_get_pcon_max_frl_bw);
+
+/**
+ * drm_dp_pcon_frl_prepare() - Prepare PCON for FRL.
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns 0 if success, else returns negative error code.
+ */
+int drm_dp_pcon_frl_prepare(struct drm_dp_aux *aux, bool enable_frl_ready_hpd)
+{
+   int ret;
+   u8 buf = DP_PCON_ENABLE_SOURCE_CTL_MODE |
+DP_PCON_ENABLE_LINK_FRL_MODE;
+
+   if (enable_frl_ready_hpd)
+   buf |= DP_PCON_ENABLE_HPD_READY;
+
+   ret = drm_dp_dpcd_writeb(aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
+
+   return ret;
+}
+EXPORT_SYMBOL(drm_dp_pcon_frl_prepare);
+
+/**
+ * drm_dp_pcon_is_frl_ready() - Is PCON ready for FRL
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns true if success, else returns false.
+ */
+bool drm_dp_pcon_is_frl_ready(struct drm_dp_aux *aux)
+{
+   int ret;
+   u8 buf;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PCON_HDMI_TX_LINK_STATUS, &buf);
+   if (ret < 0)
+   return false;
+
+   if (buf & DP_PCON_FRL_READY)
+   return true;
+
+   return false;
+}
+EXPORT_SYMBOL(drm_dp_pcon_is_frl_ready);
+
+/**
+ * drm_dp_pcon_frl_configure_1() - Set HDMI LINK Configuration-Step1
+ * @aux: DisplayPort AUX channel
+ * @max_frl_gbps: maximum frl bw to be configured between PCON and HDMI sink
+ * @concurrent_mode: true if concurrent mode or operation is required,
+ * false otherwise.
+ *
+ * Returns 0 if success, else returns negative error code.
+ */
+
+int drm_dp_pcon_frl_configure_1(struct drm_dp_aux *aux, int max_frl_gbps,
+   bool concurrent_mode)
+{
+   int ret;
+   u8 buf;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PCON_HDMI_LINK_CONFIG_1, &buf);
+   if (ret < 0)
+   return ret;
+
+   if (concurrent_mode)
+   buf |= DP_PCON_ENABLE_CONCURRENT_LINK;
+   else
+   buf &= ~DP_PCON_ENABLE_CONCURRENT_LINK;
+
+   switch (max_frl_gbps) {
+   case 9:
+   buf |=  DP_PCON_ENABLE_MAX_BW_9GBPS;
+   break;
+   case 18:
+   buf |=  DP_PCON_ENABLE_MAX_BW_18GBPS;
+   break;
+   case 24:
+   buf |=  DP_PCON_ENABLE_MAX_BW_24GBPS;
+   break;
+   case 32:
+   buf |=  DP_PCON_ENABLE_MAX_BW_32GBPS;
+   break;
+   case 40:
+   buf |=  DP_PCON_ENABLE_MAX_BW_40GBPS;
+   break;
+   case 48:
+   buf |=  DP_PCON_ENABLE_MAX_BW_48GBPS;
+   break;
+   case 0:
+   buf |=  DP_PCON_ENABLE_MAX_BW_0GBPS;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   ret = drm_dp_dpcd_writeb(aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_frl_configure_1);
+
+/**
+ * drm_dp_pcon_frl_configure_2() - Set HDMI Link configuration Step-2
+ * @aux: DisplayPort AUX ch

[Intel-gfx] [PATCH v5 06/15] drm/dp_helper: Add support for Configuring DSC for HDMI2.1 Pcon

2020-12-15 Thread Ankit Nautiyal
This patch adds registers for getting DSC encoder capability for
a HDMI2.1 PCon. It also addes helper functions to configure
DSC between the PCON and HDMI2.1 sink.

v2: Corrected offset for DSC encoder bpc and minor changes.
Also added helper functions for getting pcon dsc encoder capabilities
as suggested by Uma Shankar.

v3: Only setting the DSC bits for the Protocol Convertor control
registers, avoiding overwritining color conversion bits.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 drivers/gpu/drm/drm_dp_helper.c | 203 
 include/drm/drm_dp_helper.h | 114 ++
 2 files changed, 317 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index a1d518b3a173..689fd0d5f6c5 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -2898,3 +2898,206 @@ void drm_dp_pcon_hdmi_frl_link_error_count(struct 
drm_dp_aux *aux,
}
 }
 EXPORT_SYMBOL(drm_dp_pcon_hdmi_frl_link_error_count);
+
+/*
+ * drm_dp_pcon_enc_is_dsc_1_2 - Does PCON Encoder supports DSC 1.2
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns true is PCON encoder is DSC 1.2 else returns false.
+ */
+bool drm_dp_pcon_enc_is_dsc_1_2(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 buf;
+   u8 major_v, minor_v;
+
+   buf = pcon_dsc_dpcd[DP_PCON_DSC_VERSION - DP_PCON_DSC_ENCODER];
+   major_v = (buf & DP_PCON_DSC_MAJOR_MASK) >> DP_PCON_DSC_MAJOR_SHIFT;
+   minor_v = (buf & DP_PCON_DSC_MINOR_MASK) >> DP_PCON_DSC_MINOR_SHIFT;
+
+   if (major_v == 1 && minor_v == 2)
+   return true;
+
+   return false;
+}
+EXPORT_SYMBOL(drm_dp_pcon_enc_is_dsc_1_2);
+
+/*
+ * drm_dp_pcon_dsc_max_slices - Get max slices supported by PCON DSC Encoder
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns maximum no. of slices supported by the PCON DSC Encoder.
+ */
+int drm_dp_pcon_dsc_max_slices(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 slice_cap1, slice_cap2;
+
+   slice_cap1 = pcon_dsc_dpcd[DP_PCON_DSC_SLICE_CAP_1 - 
DP_PCON_DSC_ENCODER];
+   slice_cap2 = pcon_dsc_dpcd[DP_PCON_DSC_SLICE_CAP_2 - 
DP_PCON_DSC_ENCODER];
+
+   if (slice_cap2 & DP_PCON_DSC_24_PER_DSC_ENC)
+   return 24;
+   if (slice_cap2 & DP_PCON_DSC_20_PER_DSC_ENC)
+   return 20;
+   if (slice_cap2 & DP_PCON_DSC_16_PER_DSC_ENC)
+   return 16;
+   if (slice_cap1 & DP_PCON_DSC_12_PER_DSC_ENC)
+   return 12;
+   if (slice_cap1 & DP_PCON_DSC_10_PER_DSC_ENC)
+   return 10;
+   if (slice_cap1 & DP_PCON_DSC_8_PER_DSC_ENC)
+   return 8;
+   if (slice_cap1 & DP_PCON_DSC_6_PER_DSC_ENC)
+   return 6;
+   if (slice_cap1 & DP_PCON_DSC_4_PER_DSC_ENC)
+   return 4;
+   if (slice_cap1 & DP_PCON_DSC_2_PER_DSC_ENC)
+   return 2;
+   if (slice_cap1 & DP_PCON_DSC_1_PER_DSC_ENC)
+   return 1;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_dsc_max_slices);
+
+/*
+ * drm_dp_pcon_dsc_max_slice_width() - Get max slice width for Pcon DSC encoder
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns maximum width of the slices in pixel width i.e. no. of pixels x 320.
+ */
+int drm_dp_pcon_dsc_max_slice_width(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 buf;
+
+   buf = pcon_dsc_dpcd[DP_PCON_DSC_MAX_SLICE_WIDTH - DP_PCON_DSC_ENCODER];
+
+   return buf * DP_DSC_SLICE_WIDTH_MULTIPLIER;
+}
+EXPORT_SYMBOL(drm_dp_pcon_dsc_max_slice_width);
+
+/*
+ * drm_dp_pcon_dsc_bpp_incr() - Get bits per pixel increment for PCON DSC 
encoder
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns the bpp precision supported by the PCON encoder.
+ */
+int drm_dp_pcon_dsc_bpp_incr(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 buf;
+
+   buf = pcon_dsc_dpcd[DP_PCON_DSC_BPP_INCR - DP_PCON_DSC_ENCODER];
+
+   switch (buf & DP_PCON_DSC_BPP_INCR_MASK) {
+   case DP_PCON_DSC_ONE_16TH_BPP:
+   return 16;
+   case DP_PCON_DSC_ONE_8TH_BPP:
+   return 8;
+   case DP_PCON_DSC_ONE_4TH_BPP:
+   return 4;
+   case DP_PCON_DSC_ONE_HALF_BPP:
+   return 2;
+   case DP_PCON_DSC_ONE_BPP:
+   return 1;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_dsc_bpp_incr);
+
+static
+int drm_dp_pcon_configure_dsc_enc(struct drm_dp_aux *aux, u8 pps_buf_config)
+{
+   u8 buf;
+   int ret;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PROTOCOL_CONVERTER_CONTROL_2, &buf);
+   if (ret < 0)
+   return ret;
+
+   buf |= DP_PCON_ENABLE_DSC_ENCODER;
+
+   if (pps_buf_config <= DP_PCON_ENC_PPS_OVERRIDE_EN_BUFFER) {
+   buf

[Intel-gfx] [PATCH v5 05/15] drm/dp_helper: Add support for link failure detection

2020-12-15 Thread Ankit Nautiyal
From: Swati Sharma 

There are specific DPCDs defined for detecting link failures between
the PCON and HDMI sink and check the link status. In case of link
failure, PCON will communicate the same using an IRQ_HPD to source.
HDMI sink would have indicated the same to PCON using SCDC interrupt
mechanism. While source can always read final HDMI sink's status using
I2C over AUX, it is easier and faster to read the PCONs already read
HDMI sink status registers.

This patch adds the DPCDs required for link failure detection and
provide a helper function for printing error count/lane which might
help in debugging the link failure issues.

v2: Addressed comments from Uma Shankar:
-rephrased the commit message, as per the code.
-fixed styling issues
-added documentation for the helper function.

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/drm_dp_helper.c | 39 +
 include/drm/drm_dp_helper.h | 17 ++
 2 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index f501e3890921..a1d518b3a173 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -2859,3 +2859,42 @@ int drm_dp_pcon_hdmi_link_mode(struct drm_dp_aux *aux, 
u8 *frl_trained_mask)
return mode;
 }
 EXPORT_SYMBOL(drm_dp_pcon_hdmi_link_mode);
+
+/**
+ * drm_dp_pcon_hdmi_frl_link_error_count() - print the error count per lane
+ * during link failure between PCON and HDMI sink
+ * @aux: DisplayPort AUX channel
+ * @connector: DRM connector
+ * code.
+ **/
+
+void drm_dp_pcon_hdmi_frl_link_error_count(struct drm_dp_aux *aux,
+  struct drm_connector *connector)
+{
+   u8 buf, error_count;
+   int i, num_error;
+   struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+   for (i = 0; i < hdmi->max_lanes; i++) {
+   if (drm_dp_dpcd_readb(aux, DP_PCON_HDMI_ERROR_STATUS_LN0 + i, 
&buf) < 0)
+   return;
+
+   error_count = buf & DP_PCON_HDMI_ERROR_COUNT_MASK;
+   switch (error_count) {
+   case DP_PCON_HDMI_ERROR_COUNT_HUNDRED_PLUS:
+   num_error = 100;
+   break;
+   case DP_PCON_HDMI_ERROR_COUNT_TEN_PLUS:
+   num_error = 10;
+   break;
+   case DP_PCON_HDMI_ERROR_COUNT_THREE_PLUS:
+   num_error = 3;
+   break;
+   default:
+   num_error = 0;
+   }
+
+   DRM_ERROR("More than %d errors since the last read for lane 
%d", num_error, i);
+   }
+}
+EXPORT_SYMBOL(drm_dp_pcon_hdmi_frl_link_error_count);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index c66f570eadc2..871e8c051642 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -946,6 +946,11 @@ struct drm_device;
 # define DP_CEC_IRQ  (1 << 2)
 
 #define DP_LINK_SERVICE_IRQ_VECTOR_ESI0 0x2005   /* 1.2 */
+# define RX_CAP_CHANGED  (1 << 0)
+# define LINK_STATUS_CHANGED (1 << 1)
+# define STREAM_STATUS_CHANGED   (1 << 2)
+# define HDMI_LINK_STATUS_CHANGED(1 << 3)
+# define CONNECTED_OFF_ENTRY_REQUESTED   (1 << 4)
 
 #define DP_PSR_ERROR_STATUS 0x2006  /* XXX 1.2? */
 # define DP_PSR_LINK_CRC_ERROR  (1 << 0)
@@ -1120,6 +1125,16 @@ struct drm_device;
 #define DP_PROTOCOL_CONVERTER_CONTROL_20x3052 /* DP 1.3 */
 # define DP_CONVERSION_TO_YCBCR422_ENABLE  (1 << 0) /* DP 1.3 */
 
+/* PCON Downstream HDMI ERROR Status per Lane */
+#define DP_PCON_HDMI_ERROR_STATUS_LN0  0x3037
+#define DP_PCON_HDMI_ERROR_STATUS_LN1  0x3038
+#define DP_PCON_HDMI_ERROR_STATUS_LN2  0x3039
+#define DP_PCON_HDMI_ERROR_STATUS_LN3  0x303A
+# define DP_PCON_HDMI_ERROR_COUNT_MASK (0x7 << 0)
+# define DP_PCON_HDMI_ERROR_COUNT_THREE_PLUS   (1 << 0)
+# define DP_PCON_HDMI_ERROR_COUNT_TEN_PLUS (1 << 1)
+# define DP_PCON_HDMI_ERROR_COUNT_HUNDRED_PLUS (1 << 2)
+
 /* HDCP 1.3 and HDCP 2.2 */
 #define DP_AUX_HDCP_BKSV   0x68000
 #define DP_AUX_HDCP_RI_PRIME   0x68005
@@ -2036,5 +2051,7 @@ int drm_dp_pcon_frl_enable(struct drm_dp_aux *aux);
 
 bool drm_dp_pcon_hdmi_link_active(struct drm_dp_aux *aux);
 int drm_dp_pcon_hdmi_link_mode(struct drm_dp_aux *aux, u8 *frl_trained_mask);
+void drm_dp_pcon_hdmi_frl_link_error_count(struct drm_dp_aux *aux,
+ struct drm_connector *connector);
 
 #endif /* _DRM_DP_HELPER_H_ */
-- 
2.17.1

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


[Intel-gfx] [PATCH v5 07/15] drm/dp_helper: Add helpers to configure PCONs RGB-YCbCr Conversion

2020-12-15 Thread Ankit Nautiyal
DP Specification for DP2.0 to HDMI2.1 Pcon specifies support for conversion
of colorspace from RGB to YCbCr.
https://groups.vesa.org/wg/DP/document/previewpdf/15651

This patch adds the relavant registers and helper functions to
get the capability and set the color conversion bits for rgb->ycbcr
conversion through PCON.

v2: As suggested in review comments:
-Fixed bug in the check condition in a drm_helper as reported by
 Dan Carpenter and Kernel test robot. (Dan Carepenter)
-Modified the color-conversion cap helper function, to accomodate
 BT709 and BT2020 colorspace. (Uma Shankar)
-Added spec details for the new cap for color conversion. (Uma Shankar)

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_dp_helper.c | 61 +
 include/drm/drm_dp_helper.h | 19 +-
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 689fd0d5f6c5..9abd65c694ab 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -949,6 +949,38 @@ bool drm_dp_downstream_444_to_420_conversion(const u8 
dpcd[DP_RECEIVER_CAP_SIZE]
 }
 EXPORT_SYMBOL(drm_dp_downstream_444_to_420_conversion);
 
+/**
+ * drm_dp_downstream_rgb_to_ycbcr_conversion() - determine downstream facing 
port
+ *   RGB->YCbCr conversion 
capability
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: downstream facing port capabilities
+ * @colorspc: Colorspace for which conversion cap is sought
+ *
+ * Returns: whether the downstream facing port can convert RGB->YCbCr for a 
given
+ * colorspace.
+ */
+bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 
dpcd[DP_RECEIVER_CAP_SIZE],
+  const u8 port_cap[4],
+  u8 color_spc)
+{
+   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] & color_spc;
+   default:
+   return false;
+   }
+}
+EXPORT_SYMBOL(drm_dp_downstream_rgb_to_ycbcr_conversion);
+
 /**
  * drm_dp_downstream_mode() - return a mode for downstream facing port
  * @dev: DRM device
@@ -3101,3 +3133,32 @@ int drm_dp_pcon_pps_override_param(struct drm_dp_aux 
*aux, u8 pps_param[6])
return 0;
 }
 EXPORT_SYMBOL(drm_dp_pcon_pps_override_param);
+
+/*
+ * drm_dp_pcon_convert_rgb_to_ycbcr() - Configure the PCon to convert RGB to 
Ycbcr
+ * @aux: displayPort AUX channel
+ * @color_spc: Color-space/s for which conversion is to be enabled, 0 for 
disable.
+ *
+ * Returns 0 on success, else returns negative error code.
+ */
+int drm_dp_pcon_convert_rgb_to_ycbcr(struct drm_dp_aux *aux, u8 color_spc)
+{
+   int ret;
+   u8 buf;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PROTOCOL_CONVERTER_CONTROL_2, &buf);
+   if (ret < 0)
+   return ret;
+
+   if (color_spc & DP_CONVERSION_RGB_YCBCR_MASK)
+   buf |= (color_spc & DP_CONVERSION_RGB_YCBCR_MASK);
+   else
+   buf &= ~DP_CONVERSION_RGB_YCBCR_MASK;
+
+   ret = drm_dp_dpcd_writeb(aux, DP_PROTOCOL_CONVERTER_CONTROL_2, buf);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_convert_rgb_to_ycbcr);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index baad87fe6b0a..e096ee98842b 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -432,6 +432,17 @@ struct drm_device;
 # define DP_DS_HDMI_YCBCR444_TO_422_CONV(1 << 3)
 # define DP_DS_HDMI_YCBCR444_TO_420_CONV(1 << 4)
 
+/*
+ * VESA DP-to-HDMI PCON Specification adds caps for colorspace
+ * conversion in DFP cap DPCD 83h. Sec6.1 Table-3.
+ * Based on the available support the source can enable
+ * color conversion by writing into PROTOCOL_COVERTER_CONTROL_2
+ * DPCD 3052h.
+ */
+# define DP_DS_HDMI_BT601_RGB_YCBCR_CONV(1 << 5)
+# define DP_DS_HDMI_BT709_RGB_YCBCR_CONV(1 << 6)
+# define DP_DS_HDMI_BT2020_RGB_YCBCR_CONV   (1 << 7)
+
 #define DP_MAX_DOWNSTREAM_PORTS0x10
 
 /* DP Forward error Correction Registers */
@@ -1207,7 +1218,10 @@ struct drm_device;
 # define DP_PCON_ENC_PPS_OVERRIDE_DISABLED  0
 # define DP_PCON_ENC_PPS_OVERRIDE_EN_PARAMS 1
 # define DP_PCON_ENC_PPS_OVERRIDE_EN_BUFFER 2
-
+# define DP_CONVERSION_RGB_YCBCR_MASK (7 << 4)
+# define DP_CONVERSION_BT601_RGB_YCBCR_ENABLE  (1 << 4)
+# define DP_CONVERSION_BT709_RGB_YCBCR_ENABLE  (1 << 5)
+# define DP_CONVERSION_BT2020_RGB_YCBCR_ENABLE (1 << 6)
 
 /* PCON Downst

[Intel-gfx] [PATCH v5 08/15] drm/i915: Capture max frl rate for PCON in dfp cap structure

2020-12-15 Thread Ankit Nautiyal
HDMI2.1 PCON advertises Max FRL bandwidth supported by the PCON.

This patch captures this in dfp cap structure in intel_dp and uses
this to prune connector modes that cannot be supported by the PCON
and FRL bandwidth.

v2: Addressed review comments from Uma Shankar:
-tweaked the comparison of target bw and pcon frl bw to avoid roundup errors.
-minor modification of field names and comments.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 30 +--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5bc5bfbc4551..c88d2b918d9f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1451,6 +1451,7 @@ struct intel_dp {
struct {
int min_tmds_clock, max_tmds_clock;
int max_dotclock;
+   int pcon_max_frl_bw;
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 cb5e42c3ecd5..660b4bd2280a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -716,6 +716,25 @@ intel_dp_mode_valid_downstream(struct intel_connector 
*connector,
const struct drm_display_info *info = &connector->base.display_info;
int tmds_clock;
 
+   /* If PCON supports FRL MODE, check FRL bandwidth constraints */
+   if (intel_dp->dfp.pcon_max_frl_bw) {
+   int target_bw;
+   int max_frl_bw;
+   int bpp = intel_dp_mode_min_output_bpp(&connector->base, mode);
+
+   target_bw = bpp * target_clock;
+
+   max_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
+
+   /* converting bw from Gbps to Kbps*/
+   max_frl_bw = max_frl_bw * 100;
+
+   if (target_bw > max_frl_bw)
+   return MODE_CLOCK_HIGH;
+
+   return MODE_OK;
+   }
+
if (intel_dp->dfp.max_dotclock &&
target_clock > intel_dp->dfp.max_dotclock)
return MODE_CLOCK_HIGH;
@@ -6484,13 +6503,18 @@ intel_dp_update_dfp(struct intel_dp *intel_dp,
 intel_dp->downstream_ports,
 edid);
 
+   intel_dp->dfp.pcon_max_frl_bw =
+   drm_dp_get_pcon_max_frl_bw(intel_dp->dpcd,
+  intel_dp->downstream_ports);
+
drm_dbg_kms(&i915->drm,
-   "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS 
clock %d-%d\n",
+   "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS 
clock %d-%d, PCON Max FRL BW %dGbps\n",
connector->base.base.id, connector->base.name,
intel_dp->dfp.max_bpc,
intel_dp->dfp.max_dotclock,
intel_dp->dfp.min_tmds_clock,
-   intel_dp->dfp.max_tmds_clock);
+   intel_dp->dfp.max_tmds_clock,
+   intel_dp->dfp.pcon_max_frl_bw);
 }
 
 static void
@@ -6582,6 +6606,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
intel_dp->dfp.min_tmds_clock = 0;
intel_dp->dfp.max_tmds_clock = 0;
 
+   intel_dp->dfp.pcon_max_frl_bw = 0;
+
intel_dp->dfp.ycbcr_444_to_420 = false;
connector->base.ycbcr_420_allowed = false;
 }
-- 
2.17.1

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


[Intel-gfx] [PATCH v5 10/15] drm/i915: Check for FRL training before DP Link training

2020-12-15 Thread Ankit Nautiyal
This patch calls functions to check FRL training requirements
for an HDMI2.1 sink, when connected through PCON.
The call is made before the DP link training. In case FRL is not
required or failure during FRL training, the TMDS mode is selected
for the pcon.

v2: moved check_frl_training() just after FEC READY, before
starting DP link training.

v3: rebase

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 2 ++
 drivers/gpu/drm/i915/display/intel_dp.c  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 6863236df1d0..974cf42351bc 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3652,6 +3652,8 @@ static void tgl_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
 */
intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
 
+   intel_dp_check_frl_training(intel_dp);
+
/*
 * 7.i Follow DisplayPort specification training sequence (see notes for
 * failure handling)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 1fdcb7672ad0..9d0adce14613 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4256,6 +4256,7 @@ static void intel_enable_dp(struct intel_atomic_state 
*state,
 
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp);
+   intel_dp_check_frl_training(intel_dp);
intel_dp_start_link_train(intel_dp, pipe_config);
intel_dp_stop_link_train(intel_dp, pipe_config);
 
@@ -6177,6 +6178,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
!intel_dp_mst_is_master_trans(crtc_state))
continue;
 
+   intel_dp_check_frl_training(intel_dp);
intel_dp_start_link_train(intel_dp, crtc_state);
intel_dp_stop_link_train(intel_dp, crtc_state);
break;
-- 
2.17.1

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


[Intel-gfx] [PATCH v5 09/15] drm/i915: Add support for starting FRL training for HDMI2.1 via PCON

2020-12-15 Thread Ankit Nautiyal
This patch adds functions to start FRL training for an HDMI2.1 sink,
connected via a PCON as a DP branch device.
This patch also adds a new structure for storing frl training related
data, when FRL training is completed.

v2: As suggested by Uma Shankar:
-renamed couple of variables for better clarity
-tweaked the macros used for correct semantics for true/false
-fixed other styling issues.

v3: Completed the TODO for condition for going to FRL mode.
Modified the condition to determine the required FRL b/w
based only on the Pcon and Sink's max FRL values.
Moved the frl structure initialization to intel_dp_init_connector().

v4: Fixed typo in initialization of frl structure.

v5: Always use FRL if its possible, instead of enabling only for
higher modes as done in v3.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 .../drm/i915/display/intel_display_types.h|   7 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 151 ++
 drivers/gpu/drm/i915/display/intel_dp.h   |   2 +
 3 files changed, 160 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index c88d2b918d9f..daecff9783ea 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1339,6 +1339,11 @@ struct intel_dp_compliance {
u8 test_lane_count;
 };
 
+struct intel_dp_pcon_frl {
+   bool is_trained;
+   int trained_rate_gbps;
+};
+
 struct intel_dp {
i915_reg_t output_reg;
u32 DP;
@@ -1461,6 +1466,8 @@ struct intel_dp {
 
bool hobl_failed;
bool hobl_active;
+
+   struct intel_dp_pcon_frl frl;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 660b4bd2280a..1fdcb7672ad0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3883,6 +3883,8 @@ static void intel_disable_dp(struct intel_atomic_state 
*state,
intel_edp_backlight_off(old_conn_state);
intel_dp_set_power(intel_dp, DP_SET_POWER_D3);
intel_edp_panel_off(intel_dp);
+   intel_dp->frl.is_trained = false;
+   intel_dp->frl.trained_rate_gbps = 0;
 }
 
 static void g4x_disable_dp(struct intel_atomic_state *state,
@@ -3978,6 +3980,152 @@ cpt_set_link_train(struct intel_dp *intel_dp,
intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
+static int intel_dp_pcon_get_frl_mask(u8 frl_bw_mask)
+{
+   int bw_gbps[] = {9, 18, 24, 32, 40, 48};
+   int i;
+
+   for (i = ARRAY_SIZE(bw_gbps) - 1; i >= 0; i--) {
+   if (frl_bw_mask & (1 << i))
+   return bw_gbps[i];
+   }
+   return 0;
+}
+
+static int intel_dp_pcon_set_frl_mask(int max_frl)
+{
+
+   switch (max_frl) {
+   case 48:
+   return DP_PCON_FRL_BW_MASK_48GBPS;
+   case 40:
+   return DP_PCON_FRL_BW_MASK_40GBPS;
+   case 32:
+   return DP_PCON_FRL_BW_MASK_32GBPS;
+   case 24:
+   return DP_PCON_FRL_BW_MASK_24GBPS;
+   case 18:
+   return DP_PCON_FRL_BW_MASK_18GBPS;
+   case 9:
+   return DP_PCON_FRL_BW_MASK_9GBPS;
+   }
+
+   return 0;
+}
+
+static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+
+   return (connector->display_info.hdmi.max_frl_rate_per_lane *
+   connector->display_info.hdmi.max_lanes);
+}
+
+static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)
+{
+#define PCON_EXTENDED_TRAIN_MODE (1 > 0)
+#define PCON_CONCURRENT_MODE (1 > 0)
+#define PCON_SEQUENTIAL_MODE !PCON_CONCURRENT_MODE
+#define PCON_NORMAL_TRAIN_MODE !PCON_EXTENDED_TRAIN_MODE
+#define TIMEOUT_FRL_READY_MS 500
+#define TIMEOUT_HDMI_LINK_ACTIVE_MS 1000
+
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int max_frl_bw, max_pcon_frl_bw, max_edid_frl_bw, ret;
+   u8 max_frl_bw_mask = 0, frl_trained_mask;
+   bool is_active;
+
+   ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);
+   if (ret < 0)
+   return ret;
+
+   max_pcon_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
+   drm_dbg(&i915->drm, "PCON max rate = %d Gbps\n", max_pcon_frl_bw);
+
+   max_edid_frl_bw = intel_dp_hdmi_sink_max_frl(intel_dp);
+   drm_dbg(&i915->drm, "Sink max rate from EDID = %d Gbps\n", 
max_edid_frl_bw);
+
+   max_frl_bw = min(max_edid_frl_bw, max_pcon_frl_bw);
+
+   if (max_frl_bw <= 0)
+   return -EINVAL;
+
+   ret = drm_dp_pcon_frl_prepare(&intel_dp->aux, false);
+   if (ret < 0)
+   return ret;
+   /* Wait for PCON to be FRL Ready */
+ 

[Intel-gfx] [PATCH v5 11/15] drm/i915: Add support for enabling link status and recovery

2020-12-15 Thread Ankit Nautiyal
From: Swati Sharma 

In this patch enables support for detecting link failures between
PCON and HDMI sink in i915 driver. HDMI link loss indication to
upstream DP source is indicated via IRQ_HPD. This is followed by
reading of HDMI link configuration status (HDMI_TX_LINK_ACTIVE_STATUS).
If the PCON → HDMI 2.1 link status is off; reinitiate frl link
training to recover. Also, report HDMI FRL link error count range for
each individual FRL active lane is indicated by
DOWNSTREAM_HDMI_ERROR_STATUS_LN registers.

v2: Checked for dpcd read and write failures and added debug message.
(Uma Shankar)

v3: Rearranged code to re-start FRL link training or fall back to
TMDS mode.

v4: Resused function to check frl which inturn restarts FRL and
fallback to TMDS mode.

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 drivers/gpu/drm/i915/display/intel_dp.c | 53 +++--
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9d0adce14613..daf2faaa40fb 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6005,6 +6005,28 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
return link_ok;
 }
 
+static void
+intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
+{
+   bool is_active;
+   u8 buf = 0;
+
+   is_active = drm_dp_pcon_hdmi_link_active(&intel_dp->aux);
+   if (intel_dp->frl.is_trained && !is_active) {
+   if (drm_dp_dpcd_readb(&intel_dp->aux, 
DP_PCON_HDMI_LINK_CONFIG_1, &buf) < 0)
+   return;
+
+   buf &=  ~DP_PCON_ENABLE_HDMI_LINK;
+   if (drm_dp_dpcd_writeb(&intel_dp->aux, 
DP_PCON_HDMI_LINK_CONFIG_1, buf) < 0)
+   return;
+
+   drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, 
&intel_dp->attached_connector->base);
+
+   /* Restart FRL training or fall back to TMDS mode */
+   intel_dp_check_frl_training(intel_dp);
+   }
+}
+
 static bool
 intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
 {
@@ -6370,7 +6392,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
return state;
 }
 
-static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
+static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 val;
@@ -6394,6 +6416,30 @@ static void intel_dp_check_service_irq(struct intel_dp 
*intel_dp)
drm_dbg_kms(&i915->drm, "Sink specific irq unhandled\n");
 }
 
+static void intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   u8 val;
+
+   if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
+   return;
+
+   if (drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &val) != 1 || 
!val) {
+   drm_dbg_kms(&i915->drm, "Error in reading link service irq 
vector\n");
+   return;
+   }
+
+   if (drm_dp_dpcd_writeb(&intel_dp->aux,
+  DP_LINK_SERVICE_IRQ_VECTOR_ESI0, val) != 1) {
+   drm_dbg_kms(&i915->drm, "Error in writing link service irq 
vector\n");
+   return;
+   }
+
+   if (val & HDMI_LINK_STATUS_CHANGED)
+   intel_dp_handle_hdmi_link_status_change(intel_dp);
+}
+
 /*
  * According to DP spec
  * 5.1.2:
@@ -6433,7 +6479,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
return false;
}
 
-   intel_dp_check_service_irq(intel_dp);
+   intel_dp_check_device_service_irq(intel_dp);
+   intel_dp_check_link_service_irq(intel_dp);
 
/* Handle CEC interrupts, if any */
drm_dp_cec_irq(&intel_dp->aux);
@@ -6863,7 +6910,7 @@ intel_dp_detect(struct drm_connector *connector,
to_intel_connector(connector)->detect_edid)
status = connector_status_connected;
 
-   intel_dp_check_service_irq(intel_dp);
+   intel_dp_check_device_service_irq(intel_dp);
 
 out:
if (status != connector_status_connected && !intel_dp->is_mst)
-- 
2.17.1

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


[Intel-gfx] [PATCH v5 13/15] drm/i915: Add helper functions for calculating DSC parameters for HDMI2.1

2020-12-15 Thread Ankit Nautiyal
The DP-HDMI2.1 PCON spec provides way for a source to set PPS
parameters: slice height, slice width and bits_per_pixel, based on
the HDMI2.1 sink capabilities. The DSC encoder of the PCON will
respect these parameters, while preparing the 128 byte PPS.

This patch adds helper functions to calculate these PPS paremeters as
per the HDMI2.1 specification.

v2: Addressed review comments given by Uma Shankar:
-added documentation for functions
-fixed typos and errors

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 233 ++
 drivers/gpu/drm/i915/display/intel_hdmi.h |   7 +
 2 files changed, 240 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index e10fdb369daa..41eb1c175a0e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3428,3 +3428,236 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port);
intel_hdmi_init_connector(dig_port, intel_connector);
 }
+
+/*
+ * intel_hdmi_dsc_get_slice_height - get the dsc slice_height
+ * @vactive: Vactive of a display mode
+ *
+ * @return: appropriate dsc slice height for a given mode.
+ */
+int intel_hdmi_dsc_get_slice_height(int vactive)
+{
+   int slice_height;
+
+   /*
+* Slice Height determination : HDMI2.1 Section 7.7.5.2
+* Select smallest slice height >=96, that results in a valid PPS and
+* requires minimum padding lines required for final slice.
+*
+* Assumption : Vactive is even.
+*/
+   for (slice_height = 96; slice_height <= vactive; slice_height += 2)
+   if (vactive % slice_height == 0)
+   return slice_height;
+
+   return 0;
+}
+
+/*
+ * intel_hdmi_dsc_get_num_slices - get no. of dsc slices based on dsc encoder
+ * and dsc decoder capabilites
+ *
+ * @crtc_state: intel crtc_state
+ * @src_max_slices: maximum slices supported by the DSC encoder
+ * @src_max_slice_width: maximum slice width supported by DSC encoder
+ * @hdmi_max_slices: maximum slices supported by sink DSC decoder
+ * @hdmi_throughput: maximum clock per slice (MHz) supported by HDMI sink
+ *
+ * @return: num of dsc slices that can be supported by the dsc encoder
+ * and decoder.
+ */
+int
+intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
+ int src_max_slices, int src_max_slice_width,
+ int hdmi_max_slices, int hdmi_throughput)
+{
+/* Pixel rates in KPixels/sec */
+#define HDMI_DSC_PEAK_PIXEL_RATE   272
+/*
+ * Rates at which the source and sink are required to process pixels in each
+ * slice, can be two levels: either atleast 34KHz or atleast 4KHz.
+ */
+#define HDMI_DSC_MAX_ENC_THROUGHPUT_0  34
+#define HDMI_DSC_MAX_ENC_THROUGHPUT_1  40
+
+/* Spec limits the slice width to 2720 pixels */
+#define MAX_HDMI_SLICE_WIDTH   2720
+   int kslice_adjust;
+   int adjusted_clk_khz;
+   int min_slices;
+   int target_slices;
+   int max_throughput; /* max clock freq. in khz per slice */
+   int max_slice_width;
+   int slice_width;
+   int pixel_clock = crtc_state->hw.adjusted_mode.crtc_clock;
+
+   if (!hdmi_throughput)
+   return 0;
+
+   /*
+* Slice Width determination : HDMI2.1 Section 7.7.5.1
+* kslice_adjust factor for 4:2:0, and 4:2:2 formats is 0.5, where as
+* for 4:4:4 is 1.0. Multiplying these factors by 10 and later
+* dividing adjusted clock value by 10.
+*/
+   if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 ||
+   crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB)
+   kslice_adjust = 10;
+   else
+   kslice_adjust = 5;
+
+   /*
+* As per spec, the rate at which the source and the sink process
+* the pixels per slice are at two levels: atleast 340Mhz or 400Mhz.
+* This depends upon the pixel clock rate and output formats
+* (kslice adjust).
+* If pixel clock * kslice adjust >= 2720MHz slices can be processed
+* at max 340MHz, otherwise they can be processed at max 400MHz.
+*/
+
+   adjusted_clk_khz = DIV_ROUND_UP(kslice_adjust * pixel_clock, 10);
+
+   if (adjusted_clk_khz <= HDMI_DSC_PEAK_PIXEL_RATE)
+   max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_0;
+   else
+   max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_1;
+
+   /*
+* Taking into account the sink's capability for maximum
+* clock per slice (in MHz) as read from HF-VSDB.
+*/
+   max_throughput = min(max_throughput, hdmi_throughput * 1000);
+
+   min_slices = DIV_ROUND_UP(adjusted_clk_khz, max_throughput);

[Intel-gfx] [PATCH v5 12/15] drm/i915: Read DSC capabilities of the HDMI2.1 PCON encoder

2020-12-15 Thread Ankit Nautiyal
This patch adds support to read and store the DSC capabilities of the
HDMI2.1 PCon encoder. It also adds a new field to store these caps,
The caps are read during dfp update and can later be used to get the
PPS parameters for PCON-HDMI2.1 sink pair. Which inturn will be used
to take a call to override the existing PPS-metadata, by either
writing the entire new PPS metadata, or by writing only the
PPS override parameters.

v2: Restructured the code to read all capability DPCDs at once and store
in an array in intel_dp structure.

v3: rebase

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 20 +++
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index daecff9783ea..4c01c7c23dfd 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1362,6 +1362,7 @@ struct intel_dp {
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
u8 lttpr_phy_caps[DP_MAX_LTTPR_COUNT][DP_LTTPR_PHY_CAP_SIZE];
u8 fec_capable;
+   u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE];
/* source rates */
int num_source_rates;
const int *source_rates;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index daf2faaa40fb..87592bebff01 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3980,6 +3980,24 @@ cpt_set_link_train(struct intel_dp *intel_dp,
intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
+static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+   /* Clear the cached register set to avoid using stale values */
+
+   memset(intel_dp->pcon_dsc_dpcd, 0, sizeof(intel_dp->pcon_dsc_dpcd));
+
+   if (drm_dp_dpcd_read(&intel_dp->aux, DP_PCON_DSC_ENCODER,
+intel_dp->pcon_dsc_dpcd,
+sizeof(intel_dp->pcon_dsc_dpcd)) < 0)
+   drm_err(&i915->drm, "Failed to read DPCD register 0x%x\n",
+   DP_PCON_DSC_ENCODER);
+
+   drm_dbg_kms(&i915->drm, "PCON ENCODER DSC DPCD: %*ph\n",
+  (int)sizeof(intel_dp->pcon_dsc_dpcd), 
intel_dp->pcon_dsc_dpcd);
+}
+
 static int intel_dp_pcon_get_frl_mask(u8 frl_bw_mask)
 {
int bw_gbps[] = {9, 18, 24, 32, 40, 48};
@@ -6712,6 +6730,8 @@ intel_dp_update_dfp(struct intel_dp *intel_dp,
intel_dp->dfp.min_tmds_clock,
intel_dp->dfp.max_tmds_clock,
intel_dp->dfp.pcon_max_frl_bw);
+
+   intel_dp_get_pcon_dsc_cap(intel_dp);
 }
 
 static void
-- 
2.17.1

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


[Intel-gfx] [PATCH v5 14/15] drm/i915/display: Configure PCON for DSC1.1 to DSC1.2 encoding

2020-12-15 Thread Ankit Nautiyal
When a source supporting DSC1.1 is connected to DSC1.2 HDMI2.1 sink
via DP HDMI2.1 PCON, the PCON can be configured to decode the
DSC1.1 compressed stream and encode to DSC1.2. It then sends the
DSC1.2 compressed stream to the HDMI2.1 sink.

This patch configures the PCON for DSC1.1 to DSC1.2 encoding, based
on the PCON's DSC encoder capablities and HDMI2.1 sink's DSC decoder
capabilities.

v2: Addressed review comments from Uma Shankar:
-fixed the error in packing pps parameter values
-added check for pcon in the pcon related function
-appended display in commit message

v3: Only consider non-zero DSC FRL b/w for determining max FRL b/w
supported by sink.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_ddi.c |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c  | 118 ++-
 drivers/gpu/drm/i915/display/intel_dp.h  |   2 +
 3 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 974cf42351bc..fbc07a93504b 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3653,6 +3653,7 @@ static void tgl_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
 
intel_dp_check_frl_training(intel_dp);
+   intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
 
/*
 * 7.i Follow DisplayPort specification training sequence (see notes for
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 87592bebff01..abc9b772d1c8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4035,9 +4035,22 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
 {
struct intel_connector *intel_connector = intel_dp->attached_connector;
struct drm_connector *connector = &intel_connector->base;
+   int max_frl_rate;
+   int max_lanes, rate_per_lane;
+   int max_dsc_lanes, dsc_rate_per_lane;
 
-   return (connector->display_info.hdmi.max_frl_rate_per_lane *
-   connector->display_info.hdmi.max_lanes);
+   max_lanes = connector->display_info.hdmi.max_lanes;
+   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
+   max_frl_rate = max_lanes * rate_per_lane;
+
+   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
+   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
+   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
+   if (max_dsc_lanes && dsc_rate_per_lane)
+   max_frl_rate = min(max_frl_rate, max_dsc_lanes * 
dsc_rate_per_lane);
+   }
+
+   return max_frl_rate;
 }
 
 static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)
@@ -4144,6 +4157,105 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
}
 }
 
+static int
+intel_dp_pcon_dsc_enc_slice_height(const struct intel_crtc_state *crtc_state)
+{
+
+   int vactive = crtc_state->hw.adjusted_mode.vdisplay;
+
+   return intel_hdmi_dsc_get_slice_height(vactive);
+}
+
+static int
+intel_dp_pcon_dsc_enc_slices(struct intel_dp *intel_dp,
+const struct intel_crtc_state *crtc_state)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+   int hdmi_throughput = 
connector->display_info.hdmi.dsc_cap.clk_per_slice;
+   int hdmi_max_slices = connector->display_info.hdmi.dsc_cap.max_slices;
+   int pcon_max_slices = 
drm_dp_pcon_dsc_max_slices(intel_dp->pcon_dsc_dpcd);
+   int pcon_max_slice_width = 
drm_dp_pcon_dsc_max_slice_width(intel_dp->pcon_dsc_dpcd);
+
+
+   return intel_hdmi_dsc_get_num_slices(crtc_state, pcon_max_slices,
+pcon_max_slice_width,
+hdmi_max_slices, hdmi_throughput);
+}
+
+static int
+intel_dp_pcon_dsc_enc_bpp(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ int num_slices, int slice_width)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+   int output_format = crtc_state->output_format;
+   bool hdmi_all_bpp = connector->display_info.hdmi.dsc_cap.all_bpp;
+   int pcon_fractional_bpp = 
drm_dp_pcon_dsc_bpp_incr(intel_dp->pcon_dsc_dpcd);
+   int hdmi_max_chunk_bytes =
+   connector->display_info.hdmi.dsc_cap.total_chunk_kbytes * 1024;
+
+   return intel_hdmi_dsc_get_bpp(pcon_fractional_bpp, slice_width,
+ num

[Intel-gfx] [PATCH v5 15/15] drm/i915/display: Let PCON convert from RGB to YUV if it can

2020-12-15 Thread Ankit Nautiyal
If PCON has capability to convert RGB->YUV colorspace and also
to 444->420 downsampling then for any YUV420 only mode, we can
let the PCON do all the conversion.

v2: As suggested by Uma Shankar, considered case for colorspace
BT709 and BT2020, and default to BT609. Also appended dir
'display' in commit message.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  3 +-
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 68 +++
 drivers/gpu/drm/i915/display/intel_dp.h   |  3 +-
 4 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index fbc07a93504b..17eaa56c5a99 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3644,6 +3644,7 @@ static void tgl_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
 
+   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
/*
 * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
@@ -3731,7 +3732,7 @@ static void hsw_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
-   intel_dp_configure_protocol_converter(intel_dp);
+   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
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_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 4c01c7c23dfd..2009ae9e9678 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1460,6 +1460,7 @@ struct intel_dp {
int pcon_max_frl_bw;
u8 max_bpc;
bool ycbcr_444_to_420;
+   bool rgb_to_ycbcr;
} dfp;
 
/* Display stream compression testing */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index abc9b772d1c8..7781245c2afe 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -651,6 +651,10 @@ intel_dp_output_format(struct drm_connector *connector,
!drm_mode_is_420_only(info, mode))
return INTEL_OUTPUT_FORMAT_RGB;
 
+   if (intel_dp->dfp.rgb_to_ycbcr &&
+   intel_dp->dfp.ycbcr_444_to_420)
+   return INTEL_OUTPUT_FORMAT_RGB;
+
if (intel_dp->dfp.ycbcr_444_to_420)
return INTEL_OUTPUT_FORMAT_YCBCR444;
else
@@ -4311,7 +4315,8 @@ 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)
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
+  const struct intel_crtc_state 
*crtc_state)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 tmp;
@@ -4338,14 +4343,34 @@ void intel_dp_configure_protocol_converter(struct 
intel_dp *intel_dp)
drm_dbg_kms(&i915->drm,
"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)
+   if (intel_dp->dfp.rgb_to_ycbcr) {
+   bool bt2020, bt709;
+
+   bt2020 = 
drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd,
+   
intel_dp->downstream_ports,
+   
DP_DS_HDMI_BT2020_RGB_YCBCR_CONV);
+   bt709 = 
drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd,
+   
intel_dp->downstream_ports,
+   
DP_DS_HDMI_BT709_RGB_YCBCR_CONV);
+   switch (crtc_state->infoframes.vsc.colorimetry) {
+   case DP_COLORIMETRY_BT2020_RGB:
+   case DP_COLORIMETRY_BT2020_YCC:
+   tmp = bt2020 ? DP_CONVERSION_BT2020_RGB_YCBCR_ENABLE : 
0;
+   break;
+   case DP_COLORIMETRY_BT709_YCC:
+   case DP_COLORIMETRY_XVYCC_709:
+   

[Intel-gfx] [PATCH v6 15/15] drm/i915/display: Let PCON convert from RGB to YUV if it can

2020-12-16 Thread Ankit Nautiyal
If PCON has capability to convert RGB->YUV colorspace and also
to 444->420 downsampling then for any YUV420 only mode, we can
let the PCON do all the conversion.

v2: As suggested by Uma Shankar, considered case for colorspace
BT709 and BT2020, and default to BT609. Also appended dir
'display' in commit message.

v3: Fixed typo in condition for printing one of the error msg.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  3 +-
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 68 +++
 drivers/gpu/drm/i915/display/intel_dp.h   |  3 +-
 4 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index fbc07a93504b..17eaa56c5a99 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3644,6 +3644,7 @@ static void tgl_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
 
+   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
/*
 * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
@@ -3731,7 +3732,7 @@ static void hsw_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
-   intel_dp_configure_protocol_converter(intel_dp);
+   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
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_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 4c01c7c23dfd..2009ae9e9678 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1460,6 +1460,7 @@ struct intel_dp {
int pcon_max_frl_bw;
u8 max_bpc;
bool ycbcr_444_to_420;
+   bool rgb_to_ycbcr;
} dfp;
 
/* Display stream compression testing */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index abc9b772d1c8..366b2e4e7f4a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -651,6 +651,10 @@ intel_dp_output_format(struct drm_connector *connector,
!drm_mode_is_420_only(info, mode))
return INTEL_OUTPUT_FORMAT_RGB;
 
+   if (intel_dp->dfp.rgb_to_ycbcr &&
+   intel_dp->dfp.ycbcr_444_to_420)
+   return INTEL_OUTPUT_FORMAT_RGB;
+
if (intel_dp->dfp.ycbcr_444_to_420)
return INTEL_OUTPUT_FORMAT_YCBCR444;
else
@@ -4311,7 +4315,8 @@ 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)
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
+  const struct intel_crtc_state 
*crtc_state)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 tmp;
@@ -4338,14 +4343,34 @@ void intel_dp_configure_protocol_converter(struct 
intel_dp *intel_dp)
drm_dbg_kms(&i915->drm,
"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)
+   if (intel_dp->dfp.rgb_to_ycbcr) {
+   bool bt2020, bt709;
+
+   bt2020 = 
drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd,
+   
intel_dp->downstream_ports,
+   
DP_DS_HDMI_BT2020_RGB_YCBCR_CONV);
+   bt709 = 
drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd,
+   
intel_dp->downstream_ports,
+   
DP_DS_HDMI_BT709_RGB_YCBCR_CONV);
+   switch (crtc_state->infoframes.vsc.colorimetry) {
+   case DP_COLORIMETRY_BT2020_RGB:
+   case DP_COLORIMETRY_BT2020_YCC:
+   tmp = bt2020 ? DP_CONVERSION_BT2020_RGB_YCBCR_ENABLE : 
0;
+   break;
+   case DP_COLORIMETRY_BT70

[Intel-gfx] [PATCH v7 00/15] Add support for DP-HDMI2.1 PCON

2020-12-18 Thread Ankit Nautiyal
This patch series attempts to add support for a DP-HDMI2.1 Protocol
Convertor. The VESA spec for the HDMI2.1 PCON are proposed in Errata
E5 to DisplayPort_v2.0:
https://vesa.org/join-vesamemberships/member-downloads/?action=stamp&fileid=42299
The details are mentioned in:
VESA DP-to-HDMI PCON Specification Standalone Document
https://groups.vesa.org/wg/DP/document/15651

This series starts with adding support for FRL (Fixed Rate Link)
Training between the PCON and HDMI2.1 sink.
As per HDMI2.1 specification, a new data-channel or lane is added in
FRL mode, by repurposing the TMDS clock Channel. Through FRL, higher
bit-rate can be supported, ie. up to 12 Gbps/lane (48 Gbps over 4
lanes).

With these patches, the HDMI2.1 PCON can be configured to achieve FRL
training based on the maximum FRL rate supported by the panel, source
and the PCON.
The approach is to add the support for FRL training between PCON and
HDMI2.1 sink and gradually add other blocks for supporting higher
resolutions and other HDMI2.1 features, that can be supported by pcon
for the sources that do not natively support HDMI2.1.

This is done before the DP Link training between the source and PCON
is started. In case of FRL training is not achieved, the PCON will
work in the regular TMDS mode, without HDMI2.1 feature support.
Any interruption in FRL training between the PCON and HDMI2.1 sink is
notified through IRQ_HPD. On receiving the IRQ_HPD the concerned DPCD
registers are read and FRL training is re-attempted.

Currently, we have tested the FRL training and are able to enable 4K
display with TGL Platform + Realtek PCON RTD2173 with HDMI2.1 supporting
panel.

v2: Addressed review comments and re-organized patches as suggested in
comments on RFC patches.

v3: Addressed review comments on previous version.

v4: Added support for RGB->YCBCR conversion through PCON

v5: Addressed review comments on previous version.

v6: Fix typo in one of the patch.

v7: Rebased on latest drm-tip and addressed the review comments.

Ankit Nautiyal (11):
  drm/edid: Parse DSC1.2 cap fields from HFVSDB block
  drm/dp_helper: Add Helpers for FRL Link Training support for
DP-HDMI2.1 PCON
  drm/dp_helper: Add support for Configuring DSC for HDMI2.1 Pcon
  drm/dp_helper: Add helpers to configure PCONs RGB-YCbCr Conversion
  drm/i915: Capture max frl rate for PCON in dfp cap structure
  drm/i915: Add support for starting FRL training for HDMI2.1 via PCON
  drm/i915: Check for FRL training before DP Link training
  drm/i915: Read DSC capabilities of the HDMI2.1 PCON encoder
  drm/i915: Add helper functions for calculating DSC parameters for
HDMI2.1
  drm/i915/display: Configure PCON for DSC1.1 to DSC1.2 encoding
  drm/i915/display: Let PCON convert from RGB to YCbCr if it can

Swati Sharma (4):
  drm/edid: Add additional HFVSDB fields for HDMI2.1
  drm/edid: Parse MAX_FRL field from HFVSDB block
  drm/dp_helper: Add support for link failure detection
  drm/i915: Add support for enabling link status and recovery

 drivers/gpu/drm/drm_dp_helper.c   | 566 ++
 drivers/gpu/drm/drm_edid.c| 103 
 drivers/gpu/drm/i915/display/intel_ddi.c  |   6 +-
 .../drm/i915/display/intel_display_types.h|  10 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 442 +-
 drivers/gpu/drm/i915/display/intel_dp.h   |   7 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 233 +++
 drivers/gpu/drm/i915/display/intel_hdmi.h |   7 +
 include/drm/drm_connector.h   |  49 ++
 include/drm/drm_dp_helper.h   | 218 +++
 include/drm/drm_edid.h|  30 +
 11 files changed, 1652 insertions(+), 19 deletions(-)

-- 
2.17.1

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


[Intel-gfx] [PATCH v7 01/15] drm/edid: Add additional HFVSDB fields for HDMI2.1

2020-12-18 Thread Ankit Nautiyal
From: Swati Sharma 

The HDMI2.1 extends HFVSDB (HDMI Forum Vendor Specific
Data block) to have fields related to newly defined methods of FRL
(Fixed Rate Link) levels, number of lanes supported, DSC Color bit
depth, VRR min/max, FVA (Fast Vactive), ALLM etc.

This patch adds the new HFVSDB fields that are required for
HDMI2.1.

v2: Minor fixes + consistent naming for DPCD register masks
(Uma Shankar)

Signed-off-by: Sharma, Swati2 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 include/drm/drm_edid.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index e97daf6ffbb1..a158f585f658 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -229,6 +229,36 @@ struct detailed_timing {
DRM_EDID_YCBCR420_DC_36 | \
DRM_EDID_YCBCR420_DC_30)
 
+/* HDMI 2.1 additional fields */
+#define DRM_EDID_MAX_FRL_RATE_MASK 0xf0
+#define DRM_EDID_FAPA_START_LOCATION   (1 << 0)
+#define DRM_EDID_ALLM  (1 << 1)
+#define DRM_EDID_FVA   (1 << 2)
+
+/* Deep Color specific */
+#define DRM_EDID_DC_30BIT_420  (1 << 0)
+#define DRM_EDID_DC_36BIT_420  (1 << 1)
+#define DRM_EDID_DC_48BIT_420  (1 << 2)
+
+/* VRR specific */
+#define DRM_EDID_CNMVRR(1 << 3)
+#define DRM_EDID_CINEMA_VRR(1 << 4)
+#define DRM_EDID_MDELTA(1 << 5)
+#define DRM_EDID_VRR_MAX_UPPER_MASK0xc0
+#define DRM_EDID_VRR_MAX_LOWER_MASK0xff
+#define DRM_EDID_VRR_MIN_MASK  0x3f
+
+/* DSC specific */
+#define DRM_EDID_DSC_10BPC (1 << 0)
+#define DRM_EDID_DSC_12BPC (1 << 1)
+#define DRM_EDID_DSC_16BPC (1 << 2)
+#define DRM_EDID_DSC_ALL_BPP   (1 << 3)
+#define DRM_EDID_DSC_NATIVE_420(1 << 6)
+#define DRM_EDID_DSC_1P2   (1 << 7)
+#define DRM_EDID_DSC_MAX_FRL_RATE_MASK 0xf0
+#define DRM_EDID_DSC_MAX_SLICES0xf
+#define DRM_EDID_DSC_TOTAL_CHUNK_KBYTES0x3f
+
 /* ELD Header Block */
 #define DRM_ELD_HEADER_BLOCK_SIZE  4
 
-- 
2.17.1

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


[Intel-gfx] [PATCH v7 02/15] drm/edid: Parse MAX_FRL field from HFVSDB block

2020-12-18 Thread Ankit Nautiyal
From: Swati Sharma 

This patch parses MAX_FRL field to get the MAX rate in Gbps that
the HDMI 2.1 panel can support in FRL mode. Source need this
field to determine the optimal rate between the source and sink
during FRL training.

v2: Fixed minor bugs, and removed extra wrapper function (Uma Shankar)

Signed-off-by: Sharma, Swati2 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/drm_edid.c  | 44 +
 include/drm/drm_connector.h |  6 +
 2 files changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 74f5a3197214..e657c321d9e4 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4851,6 +4851,41 @@ static void drm_parse_vcdb(struct drm_connector 
*connector, const u8 *db)
info->rgb_quant_range_selectable = true;
 }
 
+static
+void drm_get_max_frl_rate(int max_frl_rate, u8 *max_lanes, u8 
*max_rate_per_lane)
+{
+   switch (max_frl_rate) {
+   case 1:
+   *max_lanes = 3;
+   *max_rate_per_lane = 3;
+   break;
+   case 2:
+   *max_lanes = 3;
+   *max_rate_per_lane = 6;
+   break;
+   case 3:
+   *max_lanes = 4;
+   *max_rate_per_lane = 6;
+   break;
+   case 4:
+   *max_lanes = 4;
+   *max_rate_per_lane = 8;
+   break;
+   case 5:
+   *max_lanes = 4;
+   *max_rate_per_lane = 10;
+   break;
+   case 6:
+   *max_lanes = 4;
+   *max_rate_per_lane = 12;
+   break;
+   case 0:
+   default:
+   *max_lanes = 0;
+   *max_rate_per_lane = 0;
+   }
+}
+
 static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
   const u8 *db)
 {
@@ -4904,6 +4939,15 @@ static void drm_parse_hdmi_forum_vsdb(struct 
drm_connector *connector,
}
}
 
+   if (hf_vsdb[7]) {
+   u8 max_frl_rate;
+
+   DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
+   max_frl_rate = (hf_vsdb[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
+   drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
+   &hdmi->max_frl_rate_per_lane);
+   }
+
drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
 }
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fcdc58d8b88b..1a3b4776b458 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -207,6 +207,12 @@ struct drm_hdmi_info {
 
/** @y420_dc_modes: bitmap of deep color support index */
u8 y420_dc_modes;
+
+   /** @max_frl_rate_per_lane: support fixed rate link */
+   u8 max_frl_rate_per_lane;
+
+   /** @max_lanes: supported by sink */
+   u8 max_lanes;
 };
 
 /**
-- 
2.17.1

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


[Intel-gfx] [PATCH v7 03/15] drm/edid: Parse DSC1.2 cap fields from HFVSDB block

2020-12-18 Thread Ankit Nautiyal
This patch parses HFVSDB fields for DSC1.2 capabilities of an
HDMI2.1 sink. These fields are required by a source to understand the
DSC capability of the sink, to set appropriate PPS parameters,
before transmitting compressed data stream.

v2: Addressed following issues as suggested by Uma Shankar:
-Added a new struct for hdmi dsc cap
-Fixed bugs in macros usage.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/drm_edid.c  | 59 +
 include/drm/drm_connector.h | 43 +++
 2 files changed, 102 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e657c321d9e4..ca368df2e5ac 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4941,11 +4941,70 @@ static void drm_parse_hdmi_forum_vsdb(struct 
drm_connector *connector,
 
if (hf_vsdb[7]) {
u8 max_frl_rate;
+   u8 dsc_max_frl_rate;
+   u8 dsc_max_slices;
+   struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
 
DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
max_frl_rate = (hf_vsdb[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
&hdmi->max_frl_rate_per_lane);
+   hdmi_dsc->v_1p2 = hf_vsdb[11] & DRM_EDID_DSC_1P2;
+
+   if (hdmi_dsc->v_1p2) {
+   hdmi_dsc->native_420 = hf_vsdb[11] & 
DRM_EDID_DSC_NATIVE_420;
+   hdmi_dsc->all_bpp = hf_vsdb[11] & DRM_EDID_DSC_ALL_BPP;
+
+   if (hf_vsdb[11] & DRM_EDID_DSC_16BPC)
+   hdmi_dsc->bpc_supported = 16;
+   else if (hf_vsdb[11] & DRM_EDID_DSC_12BPC)
+   hdmi_dsc->bpc_supported = 12;
+   else if (hf_vsdb[11] & DRM_EDID_DSC_10BPC)
+   hdmi_dsc->bpc_supported = 10;
+   else
+   hdmi_dsc->bpc_supported = 0;
+
+   dsc_max_frl_rate = (hf_vsdb[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
+   drm_get_max_frl_rate(dsc_max_frl_rate, 
&hdmi_dsc->max_lanes,
+   &hdmi_dsc->max_frl_rate_per_lane);
+   hdmi_dsc->total_chunk_kbytes = hf_vsdb[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
+
+   dsc_max_slices = hf_vsdb[12] & DRM_EDID_DSC_MAX_SLICES;
+   switch (dsc_max_slices) {
+   case 1:
+   hdmi_dsc->max_slices = 1;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 2:
+   hdmi_dsc->max_slices = 2;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 3:
+   hdmi_dsc->max_slices = 4;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 4:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 5:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 6:
+   hdmi_dsc->max_slices = 12;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 7:
+   hdmi_dsc->max_slices = 16;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 0:
+   default:
+   hdmi_dsc->max_slices = 0;
+   hdmi_dsc->clk_per_slice = 0;
+   }
+   }
}
 
drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 1a3b4776b458..1922b278ffad 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -175,6 +175,46 @@ struct drm_scdc {
struct drm_scrambling scrambling;
 };
 
+/**
+ * struct drm_hdmi_dsc_cap - DSC capabilities of HDMI sink
+ *
+ * Describes the DSC support provided by HDMI 2.1 sink.
+ * The information is fetched fom additional HFVSDB blocks defined
+ * for HDMI 2.1.
+ */
+struct drm_hdmi_dsc_cap {
+   /** @v_1p2: flag for dsc1.2 version support by sink */
+   

[Intel-gfx] [PATCH v7 04/15] drm/dp_helper: Add Helpers for FRL Link Training support for DP-HDMI2.1 PCON

2020-12-18 Thread Ankit Nautiyal
This patch adds support for configuring a PCON device,
connected as a DP branched device to enable FRL Link training
with a HDMI2.1 + sink.

v2: Fixed typos and addressed other review comments from Uma Shankar.
-changed the commit message for better clarity (Uma Shankar)
-removed unnecessary argument supplied to a drm helper function.
-fixed return value for max frl read from pcon.

v3: Removed DPCD 0x3035 for MAX Sink FRL b/w as per new version of spec.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 drivers/gpu/drm/drm_dp_helper.c | 263 
 include/drm/drm_dp_helper.h |  70 +
 2 files changed, 333 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 5bd0934004e3..f501e3890921 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -2596,3 +2596,266 @@ void drm_dp_vsc_sdp_log(const char *level, struct 
device *dev,
 #undef DP_SDP_LOG
 }
 EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
+
+/**
+ * drm_dp_get_pcon_max_frl_bw() - maximum frl supported by PCON
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: port capabilities
+ *
+ * Returns maximum frl bandwidth supported by PCON in GBPS,
+ * returns 0 if not supported.
+ */
+int drm_dp_get_pcon_max_frl_bw(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
+  const u8 port_cap[4])
+{
+   int bw;
+   u8 buf;
+
+   buf = port_cap[2];
+   bw = buf & DP_PCON_MAX_FRL_BW;
+
+   switch (bw) {
+   case DP_PCON_MAX_9GBPS:
+   return 9;
+   case DP_PCON_MAX_18GBPS:
+   return 18;
+   case DP_PCON_MAX_24GBPS:
+   return 24;
+   case DP_PCON_MAX_32GBPS:
+   return 32;
+   case DP_PCON_MAX_40GBPS:
+   return 40;
+   case DP_PCON_MAX_48GBPS:
+   return 48;
+   case DP_PCON_MAX_0GBPS:
+   default:
+   return 0;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_get_pcon_max_frl_bw);
+
+/**
+ * drm_dp_pcon_frl_prepare() - Prepare PCON for FRL.
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns 0 if success, else returns negative error code.
+ */
+int drm_dp_pcon_frl_prepare(struct drm_dp_aux *aux, bool enable_frl_ready_hpd)
+{
+   int ret;
+   u8 buf = DP_PCON_ENABLE_SOURCE_CTL_MODE |
+DP_PCON_ENABLE_LINK_FRL_MODE;
+
+   if (enable_frl_ready_hpd)
+   buf |= DP_PCON_ENABLE_HPD_READY;
+
+   ret = drm_dp_dpcd_writeb(aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
+
+   return ret;
+}
+EXPORT_SYMBOL(drm_dp_pcon_frl_prepare);
+
+/**
+ * drm_dp_pcon_is_frl_ready() - Is PCON ready for FRL
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns true if success, else returns false.
+ */
+bool drm_dp_pcon_is_frl_ready(struct drm_dp_aux *aux)
+{
+   int ret;
+   u8 buf;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PCON_HDMI_TX_LINK_STATUS, &buf);
+   if (ret < 0)
+   return false;
+
+   if (buf & DP_PCON_FRL_READY)
+   return true;
+
+   return false;
+}
+EXPORT_SYMBOL(drm_dp_pcon_is_frl_ready);
+
+/**
+ * drm_dp_pcon_frl_configure_1() - Set HDMI LINK Configuration-Step1
+ * @aux: DisplayPort AUX channel
+ * @max_frl_gbps: maximum frl bw to be configured between PCON and HDMI sink
+ * @concurrent_mode: true if concurrent mode or operation is required,
+ * false otherwise.
+ *
+ * Returns 0 if success, else returns negative error code.
+ */
+
+int drm_dp_pcon_frl_configure_1(struct drm_dp_aux *aux, int max_frl_gbps,
+   bool concurrent_mode)
+{
+   int ret;
+   u8 buf;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PCON_HDMI_LINK_CONFIG_1, &buf);
+   if (ret < 0)
+   return ret;
+
+   if (concurrent_mode)
+   buf |= DP_PCON_ENABLE_CONCURRENT_LINK;
+   else
+   buf &= ~DP_PCON_ENABLE_CONCURRENT_LINK;
+
+   switch (max_frl_gbps) {
+   case 9:
+   buf |=  DP_PCON_ENABLE_MAX_BW_9GBPS;
+   break;
+   case 18:
+   buf |=  DP_PCON_ENABLE_MAX_BW_18GBPS;
+   break;
+   case 24:
+   buf |=  DP_PCON_ENABLE_MAX_BW_24GBPS;
+   break;
+   case 32:
+   buf |=  DP_PCON_ENABLE_MAX_BW_32GBPS;
+   break;
+   case 40:
+   buf |=  DP_PCON_ENABLE_MAX_BW_40GBPS;
+   break;
+   case 48:
+   buf |=  DP_PCON_ENABLE_MAX_BW_48GBPS;
+   break;
+   case 0:
+   buf |=  DP_PCON_ENABLE_MAX_BW_0GBPS;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   ret = drm_dp_dpcd_writeb(aux, DP_PCON_HDMI_LINK_CONFIG_1, buf);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_frl_configure_1);
+
+/**
+ * drm_dp_pcon_frl_configure_2() - Set HDMI Link configuration Step-2
+ * @aux: DisplayPort AUX ch

[Intel-gfx] [PATCH v7 05/15] drm/dp_helper: Add support for link failure detection

2020-12-18 Thread Ankit Nautiyal
From: Swati Sharma 

There are specific DPCDs defined for detecting link failures between
the PCON and HDMI sink and check the link status. In case of link
failure, PCON will communicate the same using an IRQ_HPD to source.
HDMI sink would have indicated the same to PCON using SCDC interrupt
mechanism. While source can always read final HDMI sink's status using
I2C over AUX, it is easier and faster to read the PCONs already read
HDMI sink status registers.

This patch adds the DPCDs required for link failure detection and
provide a helper function for printing error count/lane which might
help in debugging the link failure issues.

v2: Addressed comments from Uma Shankar:
-rephrased the commit message, as per the code.
-fixed styling issues
-added documentation for the helper function.

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/drm_dp_helper.c | 39 +
 include/drm/drm_dp_helper.h | 17 ++
 2 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index f501e3890921..a1d518b3a173 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -2859,3 +2859,42 @@ int drm_dp_pcon_hdmi_link_mode(struct drm_dp_aux *aux, 
u8 *frl_trained_mask)
return mode;
 }
 EXPORT_SYMBOL(drm_dp_pcon_hdmi_link_mode);
+
+/**
+ * drm_dp_pcon_hdmi_frl_link_error_count() - print the error count per lane
+ * during link failure between PCON and HDMI sink
+ * @aux: DisplayPort AUX channel
+ * @connector: DRM connector
+ * code.
+ **/
+
+void drm_dp_pcon_hdmi_frl_link_error_count(struct drm_dp_aux *aux,
+  struct drm_connector *connector)
+{
+   u8 buf, error_count;
+   int i, num_error;
+   struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+   for (i = 0; i < hdmi->max_lanes; i++) {
+   if (drm_dp_dpcd_readb(aux, DP_PCON_HDMI_ERROR_STATUS_LN0 + i, 
&buf) < 0)
+   return;
+
+   error_count = buf & DP_PCON_HDMI_ERROR_COUNT_MASK;
+   switch (error_count) {
+   case DP_PCON_HDMI_ERROR_COUNT_HUNDRED_PLUS:
+   num_error = 100;
+   break;
+   case DP_PCON_HDMI_ERROR_COUNT_TEN_PLUS:
+   num_error = 10;
+   break;
+   case DP_PCON_HDMI_ERROR_COUNT_THREE_PLUS:
+   num_error = 3;
+   break;
+   default:
+   num_error = 0;
+   }
+
+   DRM_ERROR("More than %d errors since the last read for lane 
%d", num_error, i);
+   }
+}
+EXPORT_SYMBOL(drm_dp_pcon_hdmi_frl_link_error_count);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index c66f570eadc2..871e8c051642 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -946,6 +946,11 @@ struct drm_device;
 # define DP_CEC_IRQ  (1 << 2)
 
 #define DP_LINK_SERVICE_IRQ_VECTOR_ESI0 0x2005   /* 1.2 */
+# define RX_CAP_CHANGED  (1 << 0)
+# define LINK_STATUS_CHANGED (1 << 1)
+# define STREAM_STATUS_CHANGED   (1 << 2)
+# define HDMI_LINK_STATUS_CHANGED(1 << 3)
+# define CONNECTED_OFF_ENTRY_REQUESTED   (1 << 4)
 
 #define DP_PSR_ERROR_STATUS 0x2006  /* XXX 1.2? */
 # define DP_PSR_LINK_CRC_ERROR  (1 << 0)
@@ -1120,6 +1125,16 @@ struct drm_device;
 #define DP_PROTOCOL_CONVERTER_CONTROL_20x3052 /* DP 1.3 */
 # define DP_CONVERSION_TO_YCBCR422_ENABLE  (1 << 0) /* DP 1.3 */
 
+/* PCON Downstream HDMI ERROR Status per Lane */
+#define DP_PCON_HDMI_ERROR_STATUS_LN0  0x3037
+#define DP_PCON_HDMI_ERROR_STATUS_LN1  0x3038
+#define DP_PCON_HDMI_ERROR_STATUS_LN2  0x3039
+#define DP_PCON_HDMI_ERROR_STATUS_LN3  0x303A
+# define DP_PCON_HDMI_ERROR_COUNT_MASK (0x7 << 0)
+# define DP_PCON_HDMI_ERROR_COUNT_THREE_PLUS   (1 << 0)
+# define DP_PCON_HDMI_ERROR_COUNT_TEN_PLUS (1 << 1)
+# define DP_PCON_HDMI_ERROR_COUNT_HUNDRED_PLUS (1 << 2)
+
 /* HDCP 1.3 and HDCP 2.2 */
 #define DP_AUX_HDCP_BKSV   0x68000
 #define DP_AUX_HDCP_RI_PRIME   0x68005
@@ -2036,5 +2051,7 @@ int drm_dp_pcon_frl_enable(struct drm_dp_aux *aux);
 
 bool drm_dp_pcon_hdmi_link_active(struct drm_dp_aux *aux);
 int drm_dp_pcon_hdmi_link_mode(struct drm_dp_aux *aux, u8 *frl_trained_mask);
+void drm_dp_pcon_hdmi_frl_link_error_count(struct drm_dp_aux *aux,
+ struct drm_connector *connector);
 
 #endif /* _DRM_DP_HELPER_H_ */
-- 
2.17.1

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


[Intel-gfx] [PATCH v7 06/15] drm/dp_helper: Add support for Configuring DSC for HDMI2.1 Pcon

2020-12-18 Thread Ankit Nautiyal
This patch adds registers for getting DSC encoder capability for
a HDMI2.1 PCon. It also addes helper functions to configure
DSC between the PCON and HDMI2.1 sink.

v2: Corrected offset for DSC encoder bpc and minor changes.
Also added helper functions for getting pcon dsc encoder capabilities
as suggested by Uma Shankar.

v3: Only setting the DSC bits for the Protocol Convertor control
registers, avoiding overwritining color conversion bits.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 drivers/gpu/drm/drm_dp_helper.c | 203 
 include/drm/drm_dp_helper.h | 114 ++
 2 files changed, 317 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index a1d518b3a173..689fd0d5f6c5 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -2898,3 +2898,206 @@ void drm_dp_pcon_hdmi_frl_link_error_count(struct 
drm_dp_aux *aux,
}
 }
 EXPORT_SYMBOL(drm_dp_pcon_hdmi_frl_link_error_count);
+
+/*
+ * drm_dp_pcon_enc_is_dsc_1_2 - Does PCON Encoder supports DSC 1.2
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns true is PCON encoder is DSC 1.2 else returns false.
+ */
+bool drm_dp_pcon_enc_is_dsc_1_2(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 buf;
+   u8 major_v, minor_v;
+
+   buf = pcon_dsc_dpcd[DP_PCON_DSC_VERSION - DP_PCON_DSC_ENCODER];
+   major_v = (buf & DP_PCON_DSC_MAJOR_MASK) >> DP_PCON_DSC_MAJOR_SHIFT;
+   minor_v = (buf & DP_PCON_DSC_MINOR_MASK) >> DP_PCON_DSC_MINOR_SHIFT;
+
+   if (major_v == 1 && minor_v == 2)
+   return true;
+
+   return false;
+}
+EXPORT_SYMBOL(drm_dp_pcon_enc_is_dsc_1_2);
+
+/*
+ * drm_dp_pcon_dsc_max_slices - Get max slices supported by PCON DSC Encoder
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns maximum no. of slices supported by the PCON DSC Encoder.
+ */
+int drm_dp_pcon_dsc_max_slices(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 slice_cap1, slice_cap2;
+
+   slice_cap1 = pcon_dsc_dpcd[DP_PCON_DSC_SLICE_CAP_1 - 
DP_PCON_DSC_ENCODER];
+   slice_cap2 = pcon_dsc_dpcd[DP_PCON_DSC_SLICE_CAP_2 - 
DP_PCON_DSC_ENCODER];
+
+   if (slice_cap2 & DP_PCON_DSC_24_PER_DSC_ENC)
+   return 24;
+   if (slice_cap2 & DP_PCON_DSC_20_PER_DSC_ENC)
+   return 20;
+   if (slice_cap2 & DP_PCON_DSC_16_PER_DSC_ENC)
+   return 16;
+   if (slice_cap1 & DP_PCON_DSC_12_PER_DSC_ENC)
+   return 12;
+   if (slice_cap1 & DP_PCON_DSC_10_PER_DSC_ENC)
+   return 10;
+   if (slice_cap1 & DP_PCON_DSC_8_PER_DSC_ENC)
+   return 8;
+   if (slice_cap1 & DP_PCON_DSC_6_PER_DSC_ENC)
+   return 6;
+   if (slice_cap1 & DP_PCON_DSC_4_PER_DSC_ENC)
+   return 4;
+   if (slice_cap1 & DP_PCON_DSC_2_PER_DSC_ENC)
+   return 2;
+   if (slice_cap1 & DP_PCON_DSC_1_PER_DSC_ENC)
+   return 1;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_dsc_max_slices);
+
+/*
+ * drm_dp_pcon_dsc_max_slice_width() - Get max slice width for Pcon DSC encoder
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns maximum width of the slices in pixel width i.e. no. of pixels x 320.
+ */
+int drm_dp_pcon_dsc_max_slice_width(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 buf;
+
+   buf = pcon_dsc_dpcd[DP_PCON_DSC_MAX_SLICE_WIDTH - DP_PCON_DSC_ENCODER];
+
+   return buf * DP_DSC_SLICE_WIDTH_MULTIPLIER;
+}
+EXPORT_SYMBOL(drm_dp_pcon_dsc_max_slice_width);
+
+/*
+ * drm_dp_pcon_dsc_bpp_incr() - Get bits per pixel increment for PCON DSC 
encoder
+ * @pcon_dsc_dpcd: DSC capabilities of the PCON DSC Encoder
+ *
+ * Returns the bpp precision supported by the PCON encoder.
+ */
+int drm_dp_pcon_dsc_bpp_incr(const u8 
pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE])
+{
+   u8 buf;
+
+   buf = pcon_dsc_dpcd[DP_PCON_DSC_BPP_INCR - DP_PCON_DSC_ENCODER];
+
+   switch (buf & DP_PCON_DSC_BPP_INCR_MASK) {
+   case DP_PCON_DSC_ONE_16TH_BPP:
+   return 16;
+   case DP_PCON_DSC_ONE_8TH_BPP:
+   return 8;
+   case DP_PCON_DSC_ONE_4TH_BPP:
+   return 4;
+   case DP_PCON_DSC_ONE_HALF_BPP:
+   return 2;
+   case DP_PCON_DSC_ONE_BPP:
+   return 1;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_dsc_bpp_incr);
+
+static
+int drm_dp_pcon_configure_dsc_enc(struct drm_dp_aux *aux, u8 pps_buf_config)
+{
+   u8 buf;
+   int ret;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PROTOCOL_CONVERTER_CONTROL_2, &buf);
+   if (ret < 0)
+   return ret;
+
+   buf |= DP_PCON_ENABLE_DSC_ENCODER;
+
+   if (pps_buf_config <= DP_PCON_ENC_PPS_OVERRIDE_EN_BUFFER) {
+   buf

[Intel-gfx] [PATCH v7 07/15] drm/dp_helper: Add helpers to configure PCONs RGB-YCbCr Conversion

2020-12-18 Thread Ankit Nautiyal
DP Specification for DP2.0 to HDMI2.1 Pcon specifies support for conversion
of colorspace from RGB to YCbCr.
https://groups.vesa.org/wg/DP/document/previewpdf/15651

This patch adds the relavant registers and helper functions to
get the capability and set the color conversion bits for rgb->ycbcr
conversion through PCON.

v2: As suggested in review comments:
-Fixed bug in the check condition in a drm_helper as reported by
 Dan Carpenter and Kernel test robot. (Dan Carepenter)
-Modified the color-conversion cap helper function, to accomodate
 BT709 and BT2020 colorspace. (Uma Shankar)
-Added spec details for the new cap for color conversion. (Uma Shankar)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/drm_dp_helper.c | 61 +
 include/drm/drm_dp_helper.h | 19 +-
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 689fd0d5f6c5..9abd65c694ab 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -949,6 +949,38 @@ bool drm_dp_downstream_444_to_420_conversion(const u8 
dpcd[DP_RECEIVER_CAP_SIZE]
 }
 EXPORT_SYMBOL(drm_dp_downstream_444_to_420_conversion);
 
+/**
+ * drm_dp_downstream_rgb_to_ycbcr_conversion() - determine downstream facing 
port
+ *   RGB->YCbCr conversion 
capability
+ * @dpcd: DisplayPort configuration data
+ * @port_cap: downstream facing port capabilities
+ * @colorspc: Colorspace for which conversion cap is sought
+ *
+ * Returns: whether the downstream facing port can convert RGB->YCbCr for a 
given
+ * colorspace.
+ */
+bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 
dpcd[DP_RECEIVER_CAP_SIZE],
+  const u8 port_cap[4],
+  u8 color_spc)
+{
+   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] & color_spc;
+   default:
+   return false;
+   }
+}
+EXPORT_SYMBOL(drm_dp_downstream_rgb_to_ycbcr_conversion);
+
 /**
  * drm_dp_downstream_mode() - return a mode for downstream facing port
  * @dev: DRM device
@@ -3101,3 +3133,32 @@ int drm_dp_pcon_pps_override_param(struct drm_dp_aux 
*aux, u8 pps_param[6])
return 0;
 }
 EXPORT_SYMBOL(drm_dp_pcon_pps_override_param);
+
+/*
+ * drm_dp_pcon_convert_rgb_to_ycbcr() - Configure the PCon to convert RGB to 
Ycbcr
+ * @aux: displayPort AUX channel
+ * @color_spc: Color-space/s for which conversion is to be enabled, 0 for 
disable.
+ *
+ * Returns 0 on success, else returns negative error code.
+ */
+int drm_dp_pcon_convert_rgb_to_ycbcr(struct drm_dp_aux *aux, u8 color_spc)
+{
+   int ret;
+   u8 buf;
+
+   ret = drm_dp_dpcd_readb(aux, DP_PROTOCOL_CONVERTER_CONTROL_2, &buf);
+   if (ret < 0)
+   return ret;
+
+   if (color_spc & DP_CONVERSION_RGB_YCBCR_MASK)
+   buf |= (color_spc & DP_CONVERSION_RGB_YCBCR_MASK);
+   else
+   buf &= ~DP_CONVERSION_RGB_YCBCR_MASK;
+
+   ret = drm_dp_dpcd_writeb(aux, DP_PROTOCOL_CONVERTER_CONTROL_2, buf);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_pcon_convert_rgb_to_ycbcr);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index baad87fe6b0a..e096ee98842b 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -432,6 +432,17 @@ struct drm_device;
 # define DP_DS_HDMI_YCBCR444_TO_422_CONV(1 << 3)
 # define DP_DS_HDMI_YCBCR444_TO_420_CONV(1 << 4)
 
+/*
+ * VESA DP-to-HDMI PCON Specification adds caps for colorspace
+ * conversion in DFP cap DPCD 83h. Sec6.1 Table-3.
+ * Based on the available support the source can enable
+ * color conversion by writing into PROTOCOL_COVERTER_CONTROL_2
+ * DPCD 3052h.
+ */
+# define DP_DS_HDMI_BT601_RGB_YCBCR_CONV(1 << 5)
+# define DP_DS_HDMI_BT709_RGB_YCBCR_CONV(1 << 6)
+# define DP_DS_HDMI_BT2020_RGB_YCBCR_CONV   (1 << 7)
+
 #define DP_MAX_DOWNSTREAM_PORTS0x10
 
 /* DP Forward error Correction Registers */
@@ -1207,7 +1218,10 @@ struct drm_device;
 # define DP_PCON_ENC_PPS_OVERRIDE_DISABLED  0
 # define DP_PCON_ENC_PPS_OVERRIDE_EN_PARAMS 1
 # define DP_PCON_ENC_PPS_OVERRIDE_EN_BUFFER 2
-
+# define DP_CONVERSION_RGB_YCBCR_MASK (7 << 4)
+# define DP_CONVERSION_BT601_RGB_YCBCR_ENABLE  (1 << 4)
+# define DP_CONVERSION_BT709_RGB_YCBCR_ENABLE  (1 << 5)
+# define DP_CONVERSION_BT2020_RGB_YCBCR_ENABLE (1 &l

[Intel-gfx] [PATCH v7 08/15] drm/i915: Capture max frl rate for PCON in dfp cap structure

2020-12-18 Thread Ankit Nautiyal
HDMI2.1 PCON advertises Max FRL bandwidth supported by the PCON.

This patch captures this in dfp cap structure in intel_dp and uses
this to prune connector modes that cannot be supported by the PCON
and FRL bandwidth.

v2: Addressed review comments from Uma Shankar:
-tweaked the comparison of target bw and pcon frl bw to avoid roundup errors.
-minor modification of field names and comments.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 30 +--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5bc5bfbc4551..c88d2b918d9f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1451,6 +1451,7 @@ struct intel_dp {
struct {
int min_tmds_clock, max_tmds_clock;
int max_dotclock;
+   int pcon_max_frl_bw;
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 b2bc0c8c39c7..0596d6c24e73 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -716,6 +716,25 @@ intel_dp_mode_valid_downstream(struct intel_connector 
*connector,
const struct drm_display_info *info = &connector->base.display_info;
int tmds_clock;
 
+   /* If PCON supports FRL MODE, check FRL bandwidth constraints */
+   if (intel_dp->dfp.pcon_max_frl_bw) {
+   int target_bw;
+   int max_frl_bw;
+   int bpp = intel_dp_mode_min_output_bpp(&connector->base, mode);
+
+   target_bw = bpp * target_clock;
+
+   max_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
+
+   /* converting bw from Gbps to Kbps*/
+   max_frl_bw = max_frl_bw * 100;
+
+   if (target_bw > max_frl_bw)
+   return MODE_CLOCK_HIGH;
+
+   return MODE_OK;
+   }
+
if (intel_dp->dfp.max_dotclock &&
target_clock > intel_dp->dfp.max_dotclock)
return MODE_CLOCK_HIGH;
@@ -6492,13 +6511,18 @@ intel_dp_update_dfp(struct intel_dp *intel_dp,
 intel_dp->downstream_ports,
 edid);
 
+   intel_dp->dfp.pcon_max_frl_bw =
+   drm_dp_get_pcon_max_frl_bw(intel_dp->dpcd,
+  intel_dp->downstream_ports);
+
drm_dbg_kms(&i915->drm,
-   "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS 
clock %d-%d\n",
+   "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS 
clock %d-%d, PCON Max FRL BW %dGbps\n",
connector->base.base.id, connector->base.name,
intel_dp->dfp.max_bpc,
intel_dp->dfp.max_dotclock,
intel_dp->dfp.min_tmds_clock,
-   intel_dp->dfp.max_tmds_clock);
+   intel_dp->dfp.max_tmds_clock,
+   intel_dp->dfp.pcon_max_frl_bw);
 }
 
 static void
@@ -6590,6 +6614,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
intel_dp->dfp.min_tmds_clock = 0;
intel_dp->dfp.max_tmds_clock = 0;
 
+   intel_dp->dfp.pcon_max_frl_bw = 0;
+
intel_dp->dfp.ycbcr_444_to_420 = false;
connector->base.ycbcr_420_allowed = false;
 }
-- 
2.17.1

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


[Intel-gfx] [PATCH v7 09/15] drm/i915: Add support for starting FRL training for HDMI2.1 via PCON

2020-12-18 Thread Ankit Nautiyal
This patch adds functions to start FRL training for an HDMI2.1 sink,
connected via a PCON as a DP branch device.
This patch also adds a new structure for storing frl training related
data, when FRL training is completed.

v2: As suggested by Uma Shankar:
-renamed couple of variables for better clarity
-tweaked the macros used for correct semantics for true/false
-fixed other styling issues.

v3: Completed the TODO for condition for going to FRL mode.
Modified the condition to determine the required FRL b/w
based only on the Pcon and Sink's max FRL values.
Moved the frl structure initialization to intel_dp_init_connector().

v4: Fixed typo in initialization of frl structure.

v5: Always use FRL if its possible, instead of enabling only for
higher modes as done in v3.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 .../drm/i915/display/intel_display_types.h|   7 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 151 ++
 drivers/gpu/drm/i915/display/intel_dp.h   |   2 +
 3 files changed, 160 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index c88d2b918d9f..daecff9783ea 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1339,6 +1339,11 @@ struct intel_dp_compliance {
u8 test_lane_count;
 };
 
+struct intel_dp_pcon_frl {
+   bool is_trained;
+   int trained_rate_gbps;
+};
+
 struct intel_dp {
i915_reg_t output_reg;
u32 DP;
@@ -1461,6 +1466,8 @@ struct intel_dp {
 
bool hobl_failed;
bool hobl_active;
+
+   struct intel_dp_pcon_frl frl;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0596d6c24e73..43027a6d5e5e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3891,6 +3891,8 @@ static void intel_disable_dp(struct intel_atomic_state 
*state,
intel_edp_backlight_off(old_conn_state);
intel_dp_set_power(intel_dp, DP_SET_POWER_D3);
intel_edp_panel_off(intel_dp);
+   intel_dp->frl.is_trained = false;
+   intel_dp->frl.trained_rate_gbps = 0;
 }
 
 static void g4x_disable_dp(struct intel_atomic_state *state,
@@ -3986,6 +3988,152 @@ cpt_set_link_train(struct intel_dp *intel_dp,
intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
+static int intel_dp_pcon_get_frl_mask(u8 frl_bw_mask)
+{
+   int bw_gbps[] = {9, 18, 24, 32, 40, 48};
+   int i;
+
+   for (i = ARRAY_SIZE(bw_gbps) - 1; i >= 0; i--) {
+   if (frl_bw_mask & (1 << i))
+   return bw_gbps[i];
+   }
+   return 0;
+}
+
+static int intel_dp_pcon_set_frl_mask(int max_frl)
+{
+
+   switch (max_frl) {
+   case 48:
+   return DP_PCON_FRL_BW_MASK_48GBPS;
+   case 40:
+   return DP_PCON_FRL_BW_MASK_40GBPS;
+   case 32:
+   return DP_PCON_FRL_BW_MASK_32GBPS;
+   case 24:
+   return DP_PCON_FRL_BW_MASK_24GBPS;
+   case 18:
+   return DP_PCON_FRL_BW_MASK_18GBPS;
+   case 9:
+   return DP_PCON_FRL_BW_MASK_9GBPS;
+   }
+
+   return 0;
+}
+
+static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+
+   return (connector->display_info.hdmi.max_frl_rate_per_lane *
+   connector->display_info.hdmi.max_lanes);
+}
+
+static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)
+{
+#define PCON_EXTENDED_TRAIN_MODE (1 > 0)
+#define PCON_CONCURRENT_MODE (1 > 0)
+#define PCON_SEQUENTIAL_MODE !PCON_CONCURRENT_MODE
+#define PCON_NORMAL_TRAIN_MODE !PCON_EXTENDED_TRAIN_MODE
+#define TIMEOUT_FRL_READY_MS 500
+#define TIMEOUT_HDMI_LINK_ACTIVE_MS 1000
+
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int max_frl_bw, max_pcon_frl_bw, max_edid_frl_bw, ret;
+   u8 max_frl_bw_mask = 0, frl_trained_mask;
+   bool is_active;
+
+   ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);
+   if (ret < 0)
+   return ret;
+
+   max_pcon_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
+   drm_dbg(&i915->drm, "PCON max rate = %d Gbps\n", max_pcon_frl_bw);
+
+   max_edid_frl_bw = intel_dp_hdmi_sink_max_frl(intel_dp);
+   drm_dbg(&i915->drm, "Sink max rate from EDID = %d Gbps\n", 
max_edid_frl_bw);
+
+   max_frl_bw = min(max_edid_frl_bw, max_pcon_frl_bw);
+
+   if (max_frl_bw <= 0)
+   return -EINVAL;
+
+   ret = drm_dp_pcon_frl_prepare(&intel_dp->aux, false);
+   if (ret < 0)
+   return ret;
+   /* Wait for PCON to be FRL Ready */
+ 

[Intel-gfx] [PATCH v7 11/15] drm/i915: Add support for enabling link status and recovery

2020-12-18 Thread Ankit Nautiyal
From: Swati Sharma 

In this patch enables support for detecting link failures between
PCON and HDMI sink in i915 driver. HDMI link loss indication to
upstream DP source is indicated via IRQ_HPD. This is followed by
reading of HDMI link configuration status (HDMI_TX_LINK_ACTIVE_STATUS).
If the PCON → HDMI 2.1 link status is off; reinitiate frl link
training to recover. Also, report HDMI FRL link error count range for
each individual FRL active lane is indicated by
DOWNSTREAM_HDMI_ERROR_STATUS_LN registers.

v2: Checked for dpcd read and write failures and added debug message.
(Uma Shankar)

v3: Rearranged code to re-start FRL link training or fall back to
TMDS mode.

v4: Resused function to check frl which inturn restarts FRL and
fallback to TMDS mode.

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar  (v2)
---
 drivers/gpu/drm/i915/display/intel_dp.c | 53 +++--
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 1e0ff39bb927..66f35e7c9903 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6013,6 +6013,28 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
return link_ok;
 }
 
+static void
+intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
+{
+   bool is_active;
+   u8 buf = 0;
+
+   is_active = drm_dp_pcon_hdmi_link_active(&intel_dp->aux);
+   if (intel_dp->frl.is_trained && !is_active) {
+   if (drm_dp_dpcd_readb(&intel_dp->aux, 
DP_PCON_HDMI_LINK_CONFIG_1, &buf) < 0)
+   return;
+
+   buf &=  ~DP_PCON_ENABLE_HDMI_LINK;
+   if (drm_dp_dpcd_writeb(&intel_dp->aux, 
DP_PCON_HDMI_LINK_CONFIG_1, buf) < 0)
+   return;
+
+   drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, 
&intel_dp->attached_connector->base);
+
+   /* Restart FRL training or fall back to TMDS mode */
+   intel_dp_check_frl_training(intel_dp);
+   }
+}
+
 static bool
 intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
 {
@@ -6378,7 +6400,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
return state;
 }
 
-static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
+static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 val;
@@ -6402,6 +6424,30 @@ static void intel_dp_check_service_irq(struct intel_dp 
*intel_dp)
drm_dbg_kms(&i915->drm, "Sink specific irq unhandled\n");
 }
 
+static void intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   u8 val;
+
+   if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
+   return;
+
+   if (drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &val) != 1 || 
!val) {
+   drm_dbg_kms(&i915->drm, "Error in reading link service irq 
vector\n");
+   return;
+   }
+
+   if (drm_dp_dpcd_writeb(&intel_dp->aux,
+  DP_LINK_SERVICE_IRQ_VECTOR_ESI0, val) != 1) {
+   drm_dbg_kms(&i915->drm, "Error in writing link service irq 
vector\n");
+   return;
+   }
+
+   if (val & HDMI_LINK_STATUS_CHANGED)
+   intel_dp_handle_hdmi_link_status_change(intel_dp);
+}
+
 /*
  * According to DP spec
  * 5.1.2:
@@ -6441,7 +6487,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
return false;
}
 
-   intel_dp_check_service_irq(intel_dp);
+   intel_dp_check_device_service_irq(intel_dp);
+   intel_dp_check_link_service_irq(intel_dp);
 
/* Handle CEC interrupts, if any */
drm_dp_cec_irq(&intel_dp->aux);
@@ -6871,7 +6918,7 @@ intel_dp_detect(struct drm_connector *connector,
to_intel_connector(connector)->detect_edid)
status = connector_status_connected;
 
-   intel_dp_check_service_irq(intel_dp);
+   intel_dp_check_device_service_irq(intel_dp);
 
 out:
if (status != connector_status_connected && !intel_dp->is_mst)
-- 
2.17.1

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


[Intel-gfx] [PATCH v7 10/15] drm/i915: Check for FRL training before DP Link training

2020-12-18 Thread Ankit Nautiyal
This patch calls functions to check FRL training requirements
for an HDMI2.1 sink, when connected through PCON.
The call is made before the DP link training. In case FRL is not
required or failure during FRL training, the TMDS mode is selected
for the pcon.

v2: moved check_frl_training() just after FEC READY, before
starting DP link training.

v3: rebase

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 2 ++
 drivers/gpu/drm/i915/display/intel_dp.c  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 6863236df1d0..974cf42351bc 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3652,6 +3652,8 @@ static void tgl_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
 */
intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
 
+   intel_dp_check_frl_training(intel_dp);
+
/*
 * 7.i Follow DisplayPort specification training sequence (see notes for
 * failure handling)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 43027a6d5e5e..1e0ff39bb927 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4264,6 +4264,7 @@ static void intel_enable_dp(struct intel_atomic_state 
*state,
 
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp);
+   intel_dp_check_frl_training(intel_dp);
intel_dp_start_link_train(intel_dp, pipe_config);
intel_dp_stop_link_train(intel_dp, pipe_config);
 
@@ -6185,6 +6186,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
!intel_dp_mst_is_master_trans(crtc_state))
continue;
 
+   intel_dp_check_frl_training(intel_dp);
intel_dp_start_link_train(intel_dp, crtc_state);
intel_dp_stop_link_train(intel_dp, crtc_state);
break;
-- 
2.17.1

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


[Intel-gfx] [PATCH v7 12/15] drm/i915: Read DSC capabilities of the HDMI2.1 PCON encoder

2020-12-18 Thread Ankit Nautiyal
This patch adds support to read and store the DSC capabilities of the
HDMI2.1 PCon encoder. It also adds a new field to store these caps,
The caps are read during dfp update and can later be used to get the
PPS parameters for PCON-HDMI2.1 sink pair. Which inturn will be used
to take a call to override the existing PPS-metadata, by either
writing the entire new PPS metadata, or by writing only the
PPS override parameters.

v2: Restructured the code to read all capability DPCDs at once and store
in an array in intel_dp structure.

v3: rebase

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 20 +++
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index daecff9783ea..4c01c7c23dfd 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1362,6 +1362,7 @@ struct intel_dp {
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
u8 lttpr_phy_caps[DP_MAX_LTTPR_COUNT][DP_LTTPR_PHY_CAP_SIZE];
u8 fec_capable;
+   u8 pcon_dsc_dpcd[DP_PCON_DSC_ENCODER_CAP_SIZE];
/* source rates */
int num_source_rates;
const int *source_rates;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 66f35e7c9903..7e2c334b3a17 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3988,6 +3988,24 @@ cpt_set_link_train(struct intel_dp *intel_dp,
intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
+static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+   /* Clear the cached register set to avoid using stale values */
+
+   memset(intel_dp->pcon_dsc_dpcd, 0, sizeof(intel_dp->pcon_dsc_dpcd));
+
+   if (drm_dp_dpcd_read(&intel_dp->aux, DP_PCON_DSC_ENCODER,
+intel_dp->pcon_dsc_dpcd,
+sizeof(intel_dp->pcon_dsc_dpcd)) < 0)
+   drm_err(&i915->drm, "Failed to read DPCD register 0x%x\n",
+   DP_PCON_DSC_ENCODER);
+
+   drm_dbg_kms(&i915->drm, "PCON ENCODER DSC DPCD: %*ph\n",
+  (int)sizeof(intel_dp->pcon_dsc_dpcd), 
intel_dp->pcon_dsc_dpcd);
+}
+
 static int intel_dp_pcon_get_frl_mask(u8 frl_bw_mask)
 {
int bw_gbps[] = {9, 18, 24, 32, 40, 48};
@@ -6720,6 +6738,8 @@ intel_dp_update_dfp(struct intel_dp *intel_dp,
intel_dp->dfp.min_tmds_clock,
intel_dp->dfp.max_tmds_clock,
intel_dp->dfp.pcon_max_frl_bw);
+
+   intel_dp_get_pcon_dsc_cap(intel_dp);
 }
 
 static void
-- 
2.17.1

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


[Intel-gfx] [PATCH v7 13/15] drm/i915: Add helper functions for calculating DSC parameters for HDMI2.1

2020-12-18 Thread Ankit Nautiyal
The DP-HDMI2.1 PCON spec provides way for a source to set PPS
parameters: slice height, slice width and bits_per_pixel, based on
the HDMI2.1 sink capabilities. The DSC encoder of the PCON will
respect these parameters, while preparing the 128 byte PPS.

This patch adds helper functions to calculate these PPS paremeters as
per the HDMI2.1 specification.

v2: Addressed review comments given by Uma Shankar:
-added documentation for functions
-fixed typos and errors

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 233 ++
 drivers/gpu/drm/i915/display/intel_hdmi.h |   7 +
 2 files changed, 240 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index e10fdb369daa..41eb1c175a0e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3428,3 +3428,236 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port);
intel_hdmi_init_connector(dig_port, intel_connector);
 }
+
+/*
+ * intel_hdmi_dsc_get_slice_height - get the dsc slice_height
+ * @vactive: Vactive of a display mode
+ *
+ * @return: appropriate dsc slice height for a given mode.
+ */
+int intel_hdmi_dsc_get_slice_height(int vactive)
+{
+   int slice_height;
+
+   /*
+* Slice Height determination : HDMI2.1 Section 7.7.5.2
+* Select smallest slice height >=96, that results in a valid PPS and
+* requires minimum padding lines required for final slice.
+*
+* Assumption : Vactive is even.
+*/
+   for (slice_height = 96; slice_height <= vactive; slice_height += 2)
+   if (vactive % slice_height == 0)
+   return slice_height;
+
+   return 0;
+}
+
+/*
+ * intel_hdmi_dsc_get_num_slices - get no. of dsc slices based on dsc encoder
+ * and dsc decoder capabilites
+ *
+ * @crtc_state: intel crtc_state
+ * @src_max_slices: maximum slices supported by the DSC encoder
+ * @src_max_slice_width: maximum slice width supported by DSC encoder
+ * @hdmi_max_slices: maximum slices supported by sink DSC decoder
+ * @hdmi_throughput: maximum clock per slice (MHz) supported by HDMI sink
+ *
+ * @return: num of dsc slices that can be supported by the dsc encoder
+ * and decoder.
+ */
+int
+intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
+ int src_max_slices, int src_max_slice_width,
+ int hdmi_max_slices, int hdmi_throughput)
+{
+/* Pixel rates in KPixels/sec */
+#define HDMI_DSC_PEAK_PIXEL_RATE   272
+/*
+ * Rates at which the source and sink are required to process pixels in each
+ * slice, can be two levels: either atleast 34KHz or atleast 4KHz.
+ */
+#define HDMI_DSC_MAX_ENC_THROUGHPUT_0  34
+#define HDMI_DSC_MAX_ENC_THROUGHPUT_1  40
+
+/* Spec limits the slice width to 2720 pixels */
+#define MAX_HDMI_SLICE_WIDTH   2720
+   int kslice_adjust;
+   int adjusted_clk_khz;
+   int min_slices;
+   int target_slices;
+   int max_throughput; /* max clock freq. in khz per slice */
+   int max_slice_width;
+   int slice_width;
+   int pixel_clock = crtc_state->hw.adjusted_mode.crtc_clock;
+
+   if (!hdmi_throughput)
+   return 0;
+
+   /*
+* Slice Width determination : HDMI2.1 Section 7.7.5.1
+* kslice_adjust factor for 4:2:0, and 4:2:2 formats is 0.5, where as
+* for 4:4:4 is 1.0. Multiplying these factors by 10 and later
+* dividing adjusted clock value by 10.
+*/
+   if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 ||
+   crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB)
+   kslice_adjust = 10;
+   else
+   kslice_adjust = 5;
+
+   /*
+* As per spec, the rate at which the source and the sink process
+* the pixels per slice are at two levels: atleast 340Mhz or 400Mhz.
+* This depends upon the pixel clock rate and output formats
+* (kslice adjust).
+* If pixel clock * kslice adjust >= 2720MHz slices can be processed
+* at max 340MHz, otherwise they can be processed at max 400MHz.
+*/
+
+   adjusted_clk_khz = DIV_ROUND_UP(kslice_adjust * pixel_clock, 10);
+
+   if (adjusted_clk_khz <= HDMI_DSC_PEAK_PIXEL_RATE)
+   max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_0;
+   else
+   max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_1;
+
+   /*
+* Taking into account the sink's capability for maximum
+* clock per slice (in MHz) as read from HF-VSDB.
+*/
+   max_throughput = min(max_throughput, hdmi_throughput * 1000);
+
+   min_slices = DIV_ROUND_UP(adjusted_clk_khz, max_throughput);

[Intel-gfx] [PATCH v7 14/15] drm/i915/display: Configure PCON for DSC1.1 to DSC1.2 encoding

2020-12-18 Thread Ankit Nautiyal
When a source supporting DSC1.1 is connected to DSC1.2 HDMI2.1 sink
via DP HDMI2.1 PCON, the PCON can be configured to decode the
DSC1.1 compressed stream and encode to DSC1.2. It then sends the
DSC1.2 compressed stream to the HDMI2.1 sink.

This patch configures the PCON for DSC1.1 to DSC1.2 encoding, based
on the PCON's DSC encoder capablities and HDMI2.1 sink's DSC decoder
capabilities.

v2: Addressed review comments from Uma Shankar:
-fixed the error in packing pps parameter values
-added check for pcon in the pcon related function
-appended display in commit message

v3: Only consider non-zero DSC FRL b/w for determining max FRL b/w
supported by sink.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_ddi.c |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c  | 118 ++-
 drivers/gpu/drm/i915/display/intel_dp.h  |   2 +
 3 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 974cf42351bc..fbc07a93504b 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3653,6 +3653,7 @@ static void tgl_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
 
intel_dp_check_frl_training(intel_dp);
+   intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
 
/*
 * 7.i Follow DisplayPort specification training sequence (see notes for
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 7e2c334b3a17..fdc028b7db07 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4043,9 +4043,22 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
 {
struct intel_connector *intel_connector = intel_dp->attached_connector;
struct drm_connector *connector = &intel_connector->base;
+   int max_frl_rate;
+   int max_lanes, rate_per_lane;
+   int max_dsc_lanes, dsc_rate_per_lane;
 
-   return (connector->display_info.hdmi.max_frl_rate_per_lane *
-   connector->display_info.hdmi.max_lanes);
+   max_lanes = connector->display_info.hdmi.max_lanes;
+   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
+   max_frl_rate = max_lanes * rate_per_lane;
+
+   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
+   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
+   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
+   if (max_dsc_lanes && dsc_rate_per_lane)
+   max_frl_rate = min(max_frl_rate, max_dsc_lanes * 
dsc_rate_per_lane);
+   }
+
+   return max_frl_rate;
 }
 
 static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)
@@ -4152,6 +4165,105 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
}
 }
 
+static int
+intel_dp_pcon_dsc_enc_slice_height(const struct intel_crtc_state *crtc_state)
+{
+
+   int vactive = crtc_state->hw.adjusted_mode.vdisplay;
+
+   return intel_hdmi_dsc_get_slice_height(vactive);
+}
+
+static int
+intel_dp_pcon_dsc_enc_slices(struct intel_dp *intel_dp,
+const struct intel_crtc_state *crtc_state)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+   int hdmi_throughput = 
connector->display_info.hdmi.dsc_cap.clk_per_slice;
+   int hdmi_max_slices = connector->display_info.hdmi.dsc_cap.max_slices;
+   int pcon_max_slices = 
drm_dp_pcon_dsc_max_slices(intel_dp->pcon_dsc_dpcd);
+   int pcon_max_slice_width = 
drm_dp_pcon_dsc_max_slice_width(intel_dp->pcon_dsc_dpcd);
+
+
+   return intel_hdmi_dsc_get_num_slices(crtc_state, pcon_max_slices,
+pcon_max_slice_width,
+hdmi_max_slices, hdmi_throughput);
+}
+
+static int
+intel_dp_pcon_dsc_enc_bpp(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
+ int num_slices, int slice_width)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+   int output_format = crtc_state->output_format;
+   bool hdmi_all_bpp = connector->display_info.hdmi.dsc_cap.all_bpp;
+   int pcon_fractional_bpp = 
drm_dp_pcon_dsc_bpp_incr(intel_dp->pcon_dsc_dpcd);
+   int hdmi_max_chunk_bytes =
+   connector->display_info.hdmi.dsc_cap.total_chunk_kbytes * 1024;
+
+   return intel_hdmi_dsc_get_bpp(pcon_fractional_bpp, slice_width,
+ num

[Intel-gfx] [PATCH v7 15/15] drm/i915/display: Let PCON convert from RGB to YCbCr if it can

2020-12-18 Thread Ankit Nautiyal
If PCON has capability to convert RGB->YCbCr colorspace and also
to 444->420 downsampling then for any YUV420 only mode, we can
let the PCON do all the conversion. If the PCON supports
RGB->YCbCr conversion for all BT2020, BT709, BT601, choose
the one that is selected by userspace via connector colorspace
property, otherwise default to BT601.

v2: As suggested by Uma Shankar, considered case for colorspace
BT709 and BT2020, and default to BT601. Also appended dir
'display' in commit message.

v3: Fixed typo in condition for printing one of the error msg.

v4: As suggested by Uma Shankar:
-Fixed bug in determining the colorspace for RGB->YCbCr conversion.
-Fixed minor formatting issues
Also updated the commit message as per latest changes.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  3 +-
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 72 +++
 drivers/gpu/drm/i915/display/intel_dp.h   |  3 +-
 4 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index fbc07a93504b..17eaa56c5a99 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3644,6 +3644,7 @@ static void tgl_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
 
+   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
/*
 * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
@@ -3731,7 +3732,7 @@ static void hsw_ddi_pre_enable_dp(struct 
intel_atomic_state *state,
intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
-   intel_dp_configure_protocol_converter(intel_dp);
+   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
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_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 4c01c7c23dfd..2009ae9e9678 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1460,6 +1460,7 @@ struct intel_dp {
int pcon_max_frl_bw;
u8 max_bpc;
bool ycbcr_444_to_420;
+   bool rgb_to_ycbcr;
} dfp;
 
/* Display stream compression testing */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fdc028b7db07..d7e01482c808 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -651,6 +651,10 @@ intel_dp_output_format(struct drm_connector *connector,
!drm_mode_is_420_only(info, mode))
return INTEL_OUTPUT_FORMAT_RGB;
 
+   if (intel_dp->dfp.rgb_to_ycbcr &&
+   intel_dp->dfp.ycbcr_444_to_420)
+   return INTEL_OUTPUT_FORMAT_RGB;
+
if (intel_dp->dfp.ycbcr_444_to_420)
return INTEL_OUTPUT_FORMAT_YCBCR444;
else
@@ -4319,7 +4323,8 @@ 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)
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
+  const struct intel_crtc_state 
*crtc_state)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 tmp;
@@ -4348,12 +4353,42 @@ void intel_dp_configure_protocol_converter(struct 
intel_dp *intel_dp)
enableddisabled(intel_dp->dfp.ycbcr_444_to_420));
 
tmp = 0;
+   if (intel_dp->dfp.rgb_to_ycbcr) {
+   bool bt2020, bt709;
 
-   if (drm_dp_dpcd_writeb(&intel_dp->aux,
-  DP_PROTOCOL_CONVERTER_CONTROL_2, tmp) <= 0)
+   /*
+* FIXME: Currently if userspace selects BT2020 or BT709, but 
PCON supports only
+* RGB->YCbCr for BT601 colorspace, we go ahead with BT601, as 
default.
+*
+*/
+   tmp = DP_CONVERSION_BT601_RGB_YCBCR_ENABLE;
+
+   bt2020 = 
drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd,
+  
intel_dp->downstream_ports,
+  
DP_DS_HDMI_BT2020_RGB_YCBCR_CONV);
+

[Intel-gfx] [PATCH] drm/i915/display: Remove check for low voltage sku for max dp source rate

2021-10-25 Thread Ankit Nautiyal
The low voltage sku check can be ignored as OEMs need to consider that
when designing the board and then put any limits in VBT.

Same is now changed in Bspec pages.

v2: Added debug print for combo PHY procmon reference values
to get voltage configuration of combo PHY ports. (Imre)

Signed-off-by: Ankit Nautiyal 
---
 .../gpu/drm/i915/display/intel_combo_phy.c|  4 +++
 drivers/gpu/drm/i915/display/intel_dp.c   | 32 ++-
 2 files changed, 7 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 634e8d449457..01ff86b3ff91 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -112,6 +112,10 @@ static bool icl_verify_procmon_ref_values(struct 
drm_i915_private *dev_priv,
 
procmon = icl_get_procmon_ref_values(dev_priv, phy);
 
+   drm_dbg(&dev_priv->drm,
+   "Combo PHY %c PROCMON values : 0x%x, 0x%x, 0x%x\n",
+   phy_name(phy), procmon->dw1, procmon->dw9, procmon->dw10);
+
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f5dc2126d140..693d7e097295 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -385,23 +385,13 @@ static int dg2_max_source_rate(struct intel_dp *intel_dp)
return intel_dp_is_edp(intel_dp) ? 81 : 135;
 }
 
-static bool is_low_voltage_sku(struct drm_i915_private *i915, enum phy phy)
-{
-   u32 voltage;
-
-   voltage = intel_de_read(i915, ICL_PORT_COMP_DW3(phy)) & 
VOLTAGE_INFO_MASK;
-
-   return voltage == VOLTAGE_INFO_0_85V;
-}
-
 static int icl_max_source_rate(struct intel_dp *intel_dp)
 {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
 
-   if (intel_phy_is_combo(dev_priv, phy) &&
-   (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
+   if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -409,23 +399,7 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
 
 static int ehl_max_source_rate(struct intel_dp *intel_dp)
 {
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
-
-   if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
-   return 54;
-
-   return 81;
-}
-
-static int dg1_max_source_rate(struct intel_dp *intel_dp)
-{
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
-
-   if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
+   if (intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -468,7 +442,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
max_rate = dg2_max_source_rate(intel_dp);
else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
 IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
-   max_rate = dg1_max_source_rate(intel_dp);
+   max_rate = 81;
else if (IS_JSL_EHL(dev_priv))
max_rate = ehl_max_source_rate(intel_dp);
else
-- 
2.25.1



[Intel-gfx] [PATCH 0/2] Remove check for ComboPHY I/O voltage for DP source rate

2021-10-26 Thread Ankit Nautiyal
This patch series is continuation of the discussion in:
https://patchwork.freedesktop.org/patch/457398/?series=95444&rev=1

Along with a patch to add debug print voltage configuration for
combo PHY ports.

Ankit Nautiyal (2):
  drm/i915/display: Remove check for low voltage sku for max dp source
rate
  drm/i915/intel_combo_phy: Print procmon ref values

 .../gpu/drm/i915/display/intel_combo_phy.c|  4 +++
 drivers/gpu/drm/i915/display/intel_dp.c   | 32 ++-
 2 files changed, 7 insertions(+), 29 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH 1/2] drm/i915/display: Remove check for low voltage sku for max dp source rate

2021-10-26 Thread Ankit Nautiyal
The low voltage sku check can be ignored as OEMs need to consider that
when designing the board and then put any limits in VBT.

Same is now changed in Bspec pages.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 32 +++--
 1 file changed, 3 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f5dc2126d140..693d7e097295 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -385,23 +385,13 @@ static int dg2_max_source_rate(struct intel_dp *intel_dp)
return intel_dp_is_edp(intel_dp) ? 81 : 135;
 }
 
-static bool is_low_voltage_sku(struct drm_i915_private *i915, enum phy phy)
-{
-   u32 voltage;
-
-   voltage = intel_de_read(i915, ICL_PORT_COMP_DW3(phy)) & 
VOLTAGE_INFO_MASK;
-
-   return voltage == VOLTAGE_INFO_0_85V;
-}
-
 static int icl_max_source_rate(struct intel_dp *intel_dp)
 {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
 
-   if (intel_phy_is_combo(dev_priv, phy) &&
-   (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
+   if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -409,23 +399,7 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
 
 static int ehl_max_source_rate(struct intel_dp *intel_dp)
 {
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
-
-   if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
-   return 54;
-
-   return 81;
-}
-
-static int dg1_max_source_rate(struct intel_dp *intel_dp)
-{
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
-
-   if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
+   if (intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -468,7 +442,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
max_rate = dg2_max_source_rate(intel_dp);
else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
 IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
-   max_rate = dg1_max_source_rate(intel_dp);
+   max_rate = 81;
else if (IS_JSL_EHL(dev_priv))
max_rate = ehl_max_source_rate(intel_dp);
else
-- 
2.25.1



[Intel-gfx] [PATCH 2/2] drm/i915/intel_combo_phy: Print procmon ref values

2021-10-26 Thread Ankit Nautiyal
Add debug print for Procmon Ref values, to help get the
voltage configurations of combo PHYs.

Signed-off-by: Ankit Nautiyal 
Suggested-by: Imre Deak 
---
 drivers/gpu/drm/i915/display/intel_combo_phy.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 634e8d449457..01ff86b3ff91 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -112,6 +112,10 @@ static bool icl_verify_procmon_ref_values(struct 
drm_i915_private *dev_priv,
 
procmon = icl_get_procmon_ref_values(dev_priv, phy);
 
+   drm_dbg(&dev_priv->drm,
+   "Combo PHY %c PROCMON values : 0x%x, 0x%x, 0x%x\n",
+   phy_name(phy), procmon->dw1, procmon->dw9, procmon->dw10);
+
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
-- 
2.25.1



[Intel-gfx] [PATCH v2 2/2] drm/i915/intel_combo_phy: Print procmon ref values

2021-10-26 Thread Ankit Nautiyal
Add debug print for Procmon Ref values, to help get the
voltage configurations of combo PHYs.

v2: Corrected drm_dbg to drm_dbg_kms (Jani)

Suggested-by: Imre Deak 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_combo_phy.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 634e8d449457..72985cd5a263 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -112,6 +112,10 @@ static bool icl_verify_procmon_ref_values(struct 
drm_i915_private *dev_priv,
 
procmon = icl_get_procmon_ref_values(dev_priv, phy);
 
+   drm_dbg_kms(&dev_priv->drm,
+   "Combo PHY %c PROCMON values : 0x%x, 0x%x, 0x%x\n",
+   phy_name(phy), procmon->dw1, procmon->dw9, procmon->dw10);
+
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
-- 
2.25.1



[Intel-gfx] [PATCH 0/2] Some fixes in HDMI2.1 PCON FRL configuration

2021-10-28 Thread Ankit Nautiyal
Some optimizations in HDMI2.1 PCON configuration and avoiding
resetting the config DPCD.

Ankit Nautiyal (2):
  drm/i915/dp: Optimize the FRL configuration for HDMI2.1 PCON
  drm/i915/dp: For PCON TMDS mode set only the relavant bits in config
DPCD

 drivers/gpu/drm/i915/display/intel_dp.c | 62 +++--
 1 file changed, 47 insertions(+), 15 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH 1/2] drm/i915/dp: Optimize the FRL configuration for HDMI2.1 PCON

2021-10-28 Thread Ankit Nautiyal
Currently the HDMI2.1 PCON's frl link config DPCD registers are
reset and configured even if they are already configured.
Also the HDMI Link Mode does not settle to FRL MODE immediately after
HDMI Link Status is active.

This patch:
-Checks if the PCON is already configured for FRL.
-Include HDMI Link Mode in wait for loop along with HDMI Link status DPCD.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6d5988f0f067..f5fd106e555c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2198,6 +2198,18 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
return max_frl_rate;
 }
 
+static bool
+intel_dp_pcon_is_frl_trained(struct intel_dp *intel_dp,
+u8 max_frl_bw_mask, u8 *frl_trained_mask)
+{
+   if (drm_dp_pcon_hdmi_link_active(&intel_dp->aux) &&
+   drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, frl_trained_mask) == 
DP_PCON_HDMI_MODE_FRL &&
+   *frl_trained_mask >= max_frl_bw_mask)
+   return true;
+
+   return false;
+}
+
 static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)
 {
 #define TIMEOUT_FRL_READY_MS 500
@@ -2208,10 +2220,6 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
u8 max_frl_bw_mask = 0, frl_trained_mask;
bool is_active;
 
-   ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);
-   if (ret < 0)
-   return ret;
-
max_pcon_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
drm_dbg(&i915->drm, "PCON max rate = %d Gbps\n", max_pcon_frl_bw);
 
@@ -2223,6 +2231,12 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
if (max_frl_bw <= 0)
return -EINVAL;
 
+   max_frl_bw_mask = intel_dp_pcon_set_frl_mask(max_frl_bw);
+   drm_dbg(&i915->drm, "MAX_FRL_BW_MASK = %u\n", max_frl_bw_mask);
+
+   if (intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, 
&frl_trained_mask))
+   goto frl_trained;
+
ret = drm_dp_pcon_frl_prepare(&intel_dp->aux, false);
if (ret < 0)
return ret;
@@ -2232,7 +2246,6 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
if (!is_active)
return -ETIMEDOUT;
 
-   max_frl_bw_mask = intel_dp_pcon_set_frl_mask(max_frl_bw);
ret = drm_dp_pcon_frl_configure_1(&intel_dp->aux, max_frl_bw,
  DP_PCON_ENABLE_SEQUENTIAL_LINK);
if (ret < 0)
@@ -2248,19 +2261,15 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
 * Wait for FRL to be completed
 * Check if the HDMI Link is up and active.
 */
-   wait_for(is_active = drm_dp_pcon_hdmi_link_active(&intel_dp->aux) == 
true, TIMEOUT_HDMI_LINK_ACTIVE_MS);
+   wait_for(is_active =
+intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, 
&frl_trained_mask),
+TIMEOUT_HDMI_LINK_ACTIVE_MS);
 
if (!is_active)
return -ETIMEDOUT;
 
-   /* Verify HDMI Link configuration shows FRL Mode */
-   if (drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, &frl_trained_mask) !=
-   DP_PCON_HDMI_MODE_FRL) {
-   drm_dbg(&i915->drm, "HDMI couldn't be trained in FRL Mode\n");
-   return -EINVAL;
-   }
-   drm_dbg(&i915->drm, "MAX_FRL_MASK = %u, FRL_TRAINED_MASK = %u\n", 
max_frl_bw_mask, frl_trained_mask);
-
+frl_trained:
+   drm_dbg(&i915->drm, "FRL_TRAINED_MASK = %u\n", frl_trained_mask);
intel_dp->frl.trained_rate_gbps = 
intel_dp_pcon_get_frl_mask(frl_trained_mask);
intel_dp->frl.is_trained = true;
drm_dbg(&i915->drm, "FRL trained with : %d Gbps\n", 
intel_dp->frl.trained_rate_gbps);
-- 
2.25.1



[Intel-gfx] [PATCH 2/2] drm/i915/dp: For PCON TMDS mode set only the relavant bits in config DPCD

2021-10-28 Thread Ankit Nautiyal
Currently we reset the whole PCON linkConfig DPCD to set the TMDS mode.
This also resets the Source control bit and HDMI link enable bit and
goes to autonomous mode of operation, which is seen to spoil the PCONs
internal state.

This patch avoids resetting the PCON link config register and sets only
TMDS mode bit, Source control bit in the configuration DPCD.
It then enables the HDMI Link Enable bit.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f5fd106e555c..3df35079580a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2287,6 +2287,29 @@ static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp 
*intel_dp)
return false;
 }
 
+static
+int intel_dp_pcon_set_tmds_mode(struct intel_dp *intel_dp)
+{
+   int ret;
+   u8 buf = 0;
+
+   /* Set PCON source control mode and TMDS */
+   buf |= DP_PCON_ENABLE_SOURCE_CTL_MODE;
+   buf &= ~DP_PCON_ENABLE_MAX_FRL_BW;
+
+   ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, 
buf);
+   if (ret < 0)
+   return ret;
+
+   /* Set HDMI LINK ENABLE */
+   buf |= DP_PCON_ENABLE_HDMI_LINK;
+   ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, 
buf);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+
 void intel_dp_check_frl_training(struct intel_dp *intel_dp)
 {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -2305,7 +2328,7 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
int ret, mode;
 
drm_dbg(&dev_priv->drm, "Couldn't set FRL mode, continuing with 
TMDS mode\n");
-   ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);
+   ret = intel_dp_pcon_set_tmds_mode(intel_dp);
mode = drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, NULL);
 
if (ret < 0 || mode != DP_PCON_HDMI_MODE_TMDS)
-- 
2.25.1



[Intel-gfx] [PATCH] drm/i915/display: Remove check for low voltage sku for max dp source rate

2021-10-05 Thread Ankit Nautiyal
The low voltage sku check can be ignored as OEMs need to consider that
when designing the board and then put any limits in VBT.

Same is now changed in Bspec (53720).

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 32 +++--
 1 file changed, 3 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 74a657ae131a..75c364c3c88e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -297,23 +297,13 @@ static int dg2_max_source_rate(struct intel_dp *intel_dp)
return intel_dp_is_edp(intel_dp) ? 81 : 135;
 }
 
-static bool is_low_voltage_sku(struct drm_i915_private *i915, enum phy phy)
-{
-   u32 voltage;
-
-   voltage = intel_de_read(i915, ICL_PORT_COMP_DW3(phy)) & 
VOLTAGE_INFO_MASK;
-
-   return voltage == VOLTAGE_INFO_0_85V;
-}
-
 static int icl_max_source_rate(struct intel_dp *intel_dp)
 {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
 
-   if (intel_phy_is_combo(dev_priv, phy) &&
-   (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
+   if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -321,23 +311,7 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
 
 static int ehl_max_source_rate(struct intel_dp *intel_dp)
 {
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
-
-   if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
-   return 54;
-
-   return 81;
-}
-
-static int dg1_max_source_rate(struct intel_dp *intel_dp)
-{
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
-
-   if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
+   if (intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -380,7 +354,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
max_rate = dg2_max_source_rate(intel_dp);
else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
 IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
-   max_rate = dg1_max_source_rate(intel_dp);
+   max_rate = 81;
else if (IS_JSL_EHL(dev_priv))
max_rate = ehl_max_source_rate(intel_dp);
else
-- 
2.25.1



[Intel-gfx] [PATCH v3] drm/i915/display: Fix the 12 BPC bits for PIPE_MISC reg

2021-08-10 Thread Ankit Nautiyal
Till DISPLAY12 the PIPE_MISC bits 5-7 are used to set the
Dithering BPC, with valid values of 6, 8, 10 BPC.
For ADLP+ these bits are used to set the PORT OUTPUT BPC, with valid
values of: 6, 8, 10, 12 BPC, and need to be programmed whether
dithering is enabled or not.

This patch:
-corrects the bits 5-7 for PIPE MISC register for 12 BPC.
-renames the bits and mask to have generic names for these bits for
dithering bpc and port output bpc.

v3: Added a note for MIPI DSI which uses the PIPE_MISC for readout
for pipe_bpp. (Uma Shankar)

v2: Added 'display' to the subject and fixes tag. (Uma Shankar)

Fixes: 756f85cffef2 ("drm/i915/bdw: Broadwell has PIPEMISC")
Cc: Paulo Zanoni  (v1)
Cc: Ville Syrjälä 
Cc: Daniel Vetter 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: intel-gfx@lists.freedesktop.org
Cc:  # v3.13+

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_display.c | 34 ++--
 drivers/gpu/drm/i915/i915_reg.h  | 16 ++---
 2 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index b25c596f6f7e..a257e5dc381c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5838,16 +5838,18 @@ static void bdw_set_pipemisc(const struct 
intel_crtc_state *crtc_state)
 
switch (crtc_state->pipe_bpp) {
case 18:
-   val |= PIPEMISC_DITHER_6_BPC;
+   val |= PIPEMISC_6_BPC;
break;
case 24:
-   val |= PIPEMISC_DITHER_8_BPC;
+   val |= PIPEMISC_8_BPC;
break;
case 30:
-   val |= PIPEMISC_DITHER_10_BPC;
+   val |= PIPEMISC_10_BPC;
break;
case 36:
-   val |= PIPEMISC_DITHER_12_BPC;
+   /* Port output 12BPC defined for ADLP+ */
+   if (DISPLAY_VER(dev_priv) > 12)
+   val |= PIPEMISC_12_BPC_ADLP;
break;
default:
MISSING_CASE(crtc_state->pipe_bpp);
@@ -5900,15 +5902,27 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
 
tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe));
 
-   switch (tmp & PIPEMISC_DITHER_BPC_MASK) {
-   case PIPEMISC_DITHER_6_BPC:
+   switch (tmp & PIPEMISC_BPC_MASK) {
+   case PIPEMISC_6_BPC:
return 18;
-   case PIPEMISC_DITHER_8_BPC:
+   case PIPEMISC_8_BPC:
return 24;
-   case PIPEMISC_DITHER_10_BPC:
+   case PIPEMISC_10_BPC:
return 30;
-   case PIPEMISC_DITHER_12_BPC:
-   return 36;
+   /*
+* PORT OUTPUT 12 BPC defined for ADLP+.
+*
+* TODO:
+* For previous platforms with DSI interface, bits 5:7
+* are used for storing pipe_bpp irrespective of dithering.
+* Since the value of 12 BPC is not defined for these bits
+* on older platforms, need to find a workaround for 12 BPC
+* MIPI DSI HW readout.
+*/
+   case PIPEMISC_12_BPC_ADLP:
+   if (DISPLAY_VER(dev_priv) > 12)
+   return 36;
+   fallthrough;
default:
MISSING_CASE(tmp);
return 0;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 167eaa87501b..664970f2bc62 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6203,11 +6203,17 @@ enum {
 #define   PIPEMISC_HDR_MODE_PRECISION  (1 << 23) /* icl+ */
 #define   PIPEMISC_OUTPUT_COLORSPACE_YUV  (1 << 11)
 #define   PIPEMISC_PIXEL_ROUNDING_TRUNCREG_BIT(8) /* tgl+ */
-#define   PIPEMISC_DITHER_BPC_MASK (7 << 5)
-#define   PIPEMISC_DITHER_8_BPC(0 << 5)
-#define   PIPEMISC_DITHER_10_BPC   (1 << 5)
-#define   PIPEMISC_DITHER_6_BPC(2 << 5)
-#define   PIPEMISC_DITHER_12_BPC   (3 << 5)
+/*
+ * For Display < 13, Bits 5-7 of PIPE MISC represent DITHER BPC with
+ * valid values of: 6, 8, 10 BPC.
+ * ADLP+, the bits 5-7 represent PORT OUTPUT BPC with valid values of:
+ * 6, 8, 10, 12 BPC.
+ */
+#define   PIPEMISC_BPC_MASK(7 << 5)
+#define   PIPEMISC_8_BPC   (0 << 5)
+#define   PIPEMISC_10_BPC  (1 << 5)
+#define   PIPEMISC_6_BPC   (2 << 5)
+#define   PIPEMISC_12_BPC_ADLP (4 << 5) /* adlp+ */
 #define   PIPEMISC_DITHER_ENABLE   (1 << 4)
 #define   PIPEMISC_DITHER_TYPE_MASK(3 << 2)
 #define   PIPEMISC_DITHER_TYPE_SP  (0 << 2)
-- 
2.25.1



[Intel-gfx] [PATCH v2 0/6] Infoframe changes for DP-HDMI2.1 PCON

2021-08-13 Thread Ankit Nautiyal
Currently we rely on HDMI2.1 PCON to create default AVI infoframes
based on DP VSC packets for HDMI sink. For better control, source
can write the AVI infoframe and send as DP GMP SDP packet.
The PCON unpacks the AVI infoframe encapsulated in DP GMP SDP packet,
and forwards the same to HDMI2.1.
This series is continuation of the RFC :
https://patchwork.freedesktop.org/series/85073/
It adds support for writing infoframe for HDMI2.1 sink, connected via
HDMI2.1 PCON. This series also adds AVI infoframe version 3,
which is requied for new modes supported by HDMI2.1.

Ankit Nautiyal (3):
  video/hdmi: Separate function for unpacking AVI Infoframe Data
  video/hdmi: Add AVI version 3 defined in CTA-861-G
  drm/drm_edid: Avoid HDMI2.1 VICs in AVIInfoframe for older HDMI sinks

Swati Sharma (3):
  drm/i915: Export intel_hdmi_compute_avi_infoframe()
  drm/i915: Sending AVI infoframe through GMP DIP
  drm/i915: Implement readout for AVI infoframe SDP

 drivers/gpu/drm/drm_edid.c|  28 ++-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   4 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 238 +++---
 drivers/gpu/drm/i915/display/intel_dp.h   |   3 +
 drivers/gpu/drm/i915/display/intel_hdmi.c |   9 +-
 drivers/gpu/drm/i915/display/intel_hdmi.h |   3 +
 drivers/video/hdmi.c  |  94 +++--
 include/linux/hdmi.h  |   3 +
 8 files changed, 322 insertions(+), 60 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH v2 1/6] drm/i915: Export intel_hdmi_compute_avi_infoframe()

2021-08-13 Thread Ankit Nautiyal
From: Swati Sharma 

Instead of re-writing the avi_infoframe_compute func in intel_dp;
exporting hdmi_compute_avi_infoframe func so that it can be called
directly while encapsulating AVI infoframes in GMP dip.

This is required when HDMI 2.1 PCON (dp to hdmi) is used and we need
to send AVI infoframes to PCON in source control mode.

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 8 
 drivers/gpu/drm/i915/display/intel_hdmi.h | 3 +++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index b04685bb6439..0fbcdddb7ad5 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -702,10 +702,9 @@ void intel_read_infoframe(struct intel_encoder *encoder,
frame->any.type, type);
 }
 
-static bool
-intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
-struct intel_crtc_state *crtc_state,
-struct drm_connector_state *conn_state)
+bool intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
 {
struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
const struct drm_display_mode *adjusted_mode =
@@ -758,6 +757,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder 
*encoder,
 
return true;
 }
+EXPORT_SYMBOL(intel_hdmi_compute_avi_infoframe);
 
 static bool
 intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h 
b/drivers/gpu/drm/i915/display/intel_hdmi.h
index b43a180d007e..2bdfd0838753 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -54,5 +54,8 @@ int intel_hdmi_dsc_get_num_slices(const struct 
intel_crtc_state *crtc_state,
  int src_max_slices, int src_max_slice_width,
  int hdmi_max_slices, int hdmi_throughput);
 int intel_hdmi_dsc_get_slice_height(int vactive);
+bool intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state);
 
 #endif /* __INTEL_HDMI_H__ */
-- 
2.25.1



[Intel-gfx] [PATCH v2 2/6] drm/i915: Sending AVI infoframe through GMP DIP

2021-08-13 Thread Ankit Nautiyal
From: Swati Sharma 

DP does not support sending AVI info frame to panel. So we need to
send AVI info frame to HDMI through some other DIP.

When DP-to-HDMI protocol converter is present GMP DIP will be used
to send AVI infoframe instead of static HDR infoframes.

While VESA spec indicates support within PCON to built AVI IF, it
gives better control with source sending the infoframe by itself as
per HDMI/CTA spec. Minimum of version 3 need to be used for VIC >= 128
(i.e. for 8k mode as an example).

v2:
-Added the case for AVI infoframe type in intel_write_sdp (Gwan-gyeong Mun)
-Used the type AVI infoframe instead of GMP in crtc_state, and only used
type GMP while writing infoframe (Gwan-gyeong Mun).
-Avoided writing the AVI infoframe Header twice in sdp packet (Ankit).
-Corrected the buffer size for AVI infoframe packing (Ankit).

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 142 ++--
 1 file changed, 109 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 75d4ebc66941..2990a9e78a9d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1603,6 +1603,17 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct 
intel_dp *intel_dp,
intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
 }
 
+static void
+intel_dp_compute_avi_infoframe_sdp(struct intel_encoder *encoder,
+  struct intel_crtc_state *crtc_state,
+  struct drm_connector_state *conn_state)
+{
+   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+   if (!intel_hdmi_compute_avi_infoframe(encoder, crtc_state, conn_state))
+   drm_dbg_kms(&dev_priv->drm, "bad AVI infoframe\n");
+}
+
 static void
 intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
 struct intel_crtc_state *pipe_config,
@@ -1643,6 +1654,38 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
pipe_config->dp_m2_n2.gmch_m *= 
pipe_config->splitter.link_count;
 }
 
+static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+   int max_frl_rate;
+   int max_lanes, rate_per_lane;
+   int max_dsc_lanes, dsc_rate_per_lane;
+
+   max_lanes = connector->display_info.hdmi.max_lanes;
+   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
+   max_frl_rate = max_lanes * rate_per_lane;
+
+   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
+   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
+   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
+   if (max_dsc_lanes && dsc_rate_per_lane)
+   max_frl_rate = min(max_frl_rate, max_dsc_lanes * 
dsc_rate_per_lane);
+   }
+
+   return max_frl_rate;
+}
+
+static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp)
+{
+   if (drm_dp_is_branch(intel_dp->dpcd) &&
+   intel_dp->has_hdmi_sink &&
+   intel_dp_hdmi_sink_max_frl(intel_dp) > 0)
+   return true;
+
+   return false;
+}
+
 int
 intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -1754,7 +1797,13 @@ intel_dp_compute_config(struct intel_encoder *encoder,
intel_dp_drrs_compute_config(intel_dp, pipe_config, output_bpp,
 constant_n);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
-   intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, 
conn_state);
+
+   if (intel_dp_is_hdmi_2_1_sink(intel_dp)) {
+   pipe_config->has_infoframe = true;
+   intel_dp_compute_avi_infoframe_sdp(encoder, pipe_config, 
conn_state);
+   } else {
+   intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, 
pipe_config, conn_state);
+   }
 
return 0;
 }
@@ -2016,28 +2065,6 @@ static int intel_dp_pcon_set_frl_mask(int max_frl)
return 0;
 }
 
-static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
-{
-   struct intel_connector *intel_connector = intel_dp->attached_connector;
-   struct drm_connector *connector = &intel_connector->base;
-   int max_frl_rate;
-   int max_lanes, rate_per_lane;
-   int max_dsc_lanes, dsc_rate_per_lane;
-
-   max_lanes = connector->display_info.hdmi.max_lanes;
-   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
-   max_frl_rate = max_lanes * rate_per_lane;
-
-   if (connector->disp

[Intel-gfx] [PATCH v2 3/6] video/hdmi: Separate function for unpacking AVI Infoframe Data

2021-08-13 Thread Ankit Nautiyal
Currently while unpacking the AVI Infoframe, the Infoframe Headers
and data are checked in same unpack function.

This patch separates the unpacking of AVI infoframe Data only,
so that it can be used for the DP cases, where the AVI Infoframe is
encapsulated in DP SDP packets. In such a case we need to only
unpack the data bytes as the header bits for DP SDP will be different.

Signed-off-by: Ankit Nautiyal 
---
 drivers/video/hdmi.c | 65 
 include/linux/hdmi.h |  2 ++
 2 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..f8e325cccfee 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -1537,38 +1537,30 @@ void hdmi_infoframe_log(const char *level,
 EXPORT_SYMBOL(hdmi_infoframe_log);
 
 /**
- * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe
+ * hdmi_avi_infoframe_unpack_only() - unpack binary buffer of CTA-861-G AVI
+ *infoframe DataBytes to a HDMI AVI
+ *infoframe
  * @frame: HDMI AVI infoframe
  * @buffer: source buffer
  * @size: size of buffer
  *
- * Unpacks the information contained in binary @buffer into a structured
- * @frame of the HDMI Auxiliary Video (AVI) information frame.
- * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
- * specification.
+ * Unpacks CTA-861-G AVI infoframe DataBytes contained in the binary @buffer
+ * into a structured @frame of the HDMI Auxiliary Video Information (AVI)
+ * infoframe.
  *
  * Returns 0 on success or a negative error code on failure.
  */
-static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
-const void *buffer, size_t size)
+
+int hdmi_avi_infoframe_unpack_only(struct hdmi_avi_infoframe *frame,
+  const void *buffer, size_t size)
 {
const u8 *ptr = buffer;
 
-   if (size < HDMI_INFOFRAME_SIZE(AVI))
-   return -EINVAL;
-
-   if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
-   ptr[1] != 2 ||
-   ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
-   return -EINVAL;
-
-   if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
+   if (size < HDMI_AVI_INFOFRAME_SIZE)
return -EINVAL;
 
hdmi_avi_infoframe_init(frame);
 
-   ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
frame->colorspace = (ptr[0] >> 5) & 0x3;
if (ptr[0] & 0x10)
frame->active_aspect = ptr[1] & 0xf;
@@ -1599,6 +1591,43 @@ static int hdmi_avi_infoframe_unpack(struct 
hdmi_avi_infoframe *frame,
 
return 0;
 }
+EXPORT_SYMBOL(hdmi_avi_infoframe_unpack_only);
+
+/**
+ * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe
+ * @frame: HDMI AVI infoframe
+ * @buffer: source buffer
+ * @size: size of buffer
+ *
+ * Unpacks the information contained in binary @buffer into a structured
+ * @frame of the HDMI Auxiliary Video (AVI) information frame.
+ * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
+ * specification.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
+const void *buffer, size_t size)
+{
+   const u8 *ptr = buffer;
+   int ret;
+
+   if (size < HDMI_INFOFRAME_SIZE(AVI))
+   return -EINVAL;
+
+   if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
+   ptr[1] != 2 ||
+   ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
+   return -EINVAL;
+
+   if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
+   return -EINVAL;
+
+   ret = hdmi_avi_infoframe_unpack_only(frame, ptr + 
HDMI_INFOFRAME_HEADER_SIZE,
+size - HDMI_INFOFRAME_HEADER_SIZE);
+
+   return ret;
+}
 
 /**
  * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..dda209fb77e3 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -222,6 +222,8 @@ ssize_t hdmi_drm_infoframe_pack_only(const struct 
hdmi_drm_infoframe *frame,
 int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame);
 int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame,
   const void *buffer, size_t size);
+int hdmi_avi_infoframe_unpack_only(struct hdmi_avi_infoframe *frame,
+  const void *buffer, size_t size);
 
 enum hdmi_spd_sdi {
HDMI_SPD_SDI_UNKNOWN,
-- 
2.25.1



[Intel-gfx] [PATCH v2 5/6] video/hdmi: Add AVI version 3 defined in CTA-861-G

2021-08-13 Thread Ankit Nautiyal
CTA-861-G adds AVI Infoframe version 3 for sending VIC codes 193-219
and IDO defined new colorspace information.

Specifically, bits 5-7 of Data Byte 1 is used for representing
colorspaces instead of bits 5-6 in version 2.
Similarly the bits 0-7 of Data Byte 4 is to be used to accommodate
VICs between 193-219, as compared to 0-6 in version 2.

This patch adds a new helper function to set the AVI version
to 3 if any of the above information is added to the
AVI infoframe. It also calls this function to set the appropriate
version while computing avi infoframes for i915 driver.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_hdmi.c |  1 +
 drivers/video/hdmi.c  | 29 ---
 include/linux/hdmi.h  |  1 +
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 0fbcdddb7ad5..0950d48e4e5f 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -751,6 +751,7 @@ bool intel_hdmi_compute_avi_infoframe(struct intel_encoder 
*encoder,
 
/* TODO: handle pixel repetition for YCBCR420 outputs */
 
+   hdmi_avi_infoframe_set_version(frame);
ret = hdmi_avi_infoframe_check(frame);
if (drm_WARN_ON(encoder->base.dev, ret))
return false;
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index f8e325cccfee..aab8900efa24 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -50,6 +50,20 @@ static void hdmi_infoframe_set_checksum(void *buffer, size_t 
size)
ptr[3] = hdmi_infoframe_checksum(buffer, size);
 }
 
+/**
+ * hdmi_avi_infoframe_set_version() - fill the HDMI AVI infoframe
+ *   version information
+ * @frame: HDMI AVI infoframe
+ */
+void
+hdmi_avi_infoframe_set_version(struct hdmi_avi_infoframe *frame)
+{
+   if (frame->video_code > 127 ||
+   frame->colorspace == HDMI_COLORSPACE_IDO_DEFINED)
+   frame->version = 3;
+}
+EXPORT_SYMBOL(hdmi_avi_infoframe_set_version);
+
 /**
  * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
  * @frame: HDMI AVI infoframe
@@ -67,10 +81,17 @@ EXPORT_SYMBOL(hdmi_avi_infoframe_init);
 static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe 
*frame)
 {
if (frame->type != HDMI_INFOFRAME_TYPE_AVI ||
-   frame->version != 2 ||
frame->length != HDMI_AVI_INFOFRAME_SIZE)
return -EINVAL;
 
+   if (frame->video_code > 127 ||
+   frame->colorspace == HDMI_COLORSPACE_IDO_DEFINED) {
+   if (frame->version != 3)
+   return -EINVAL;
+   } else if (frame->version != 2) {
+   return -EINVAL;
+   }
+
if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
return -EINVAL;
 
@@ -159,7 +180,7 @@ ssize_t hdmi_avi_infoframe_pack_only(const struct 
hdmi_avi_infoframe *frame,
if (frame->itc)
ptr[2] |= BIT(7);
 
-   ptr[3] = frame->video_code & 0x7f;
+   ptr[3] = frame->video_code;
 
ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
 ((frame->content_type & 0x3) << 4) |
@@ -1583,12 +1604,14 @@ int hdmi_avi_infoframe_unpack_only(struct 
hdmi_avi_infoframe *frame,
frame->quantization_range = (ptr[2] >> 2) & 0x3;
frame->nups = ptr[2] & 0x3;
 
-   frame->video_code = ptr[3] & 0x7f;
+   frame->video_code = ptr[3];
frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3;
frame->content_type = (ptr[4] >> 4) & 0x3;
 
frame->pixel_repeat = ptr[4] & 0xf;
 
+   hdmi_avi_infoframe_set_version(frame);
+
return 0;
 }
 EXPORT_SYMBOL(hdmi_avi_infoframe_unpack_only);
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index dda209fb77e3..2fe012670ad3 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -438,5 +438,6 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
  const void *buffer, size_t size);
 void hdmi_infoframe_log(const char *level, struct device *dev,
const union hdmi_infoframe *frame);
+void hdmi_avi_infoframe_set_version(struct hdmi_avi_infoframe *frame);
 
 #endif /* _DRM_HDMI_H */
-- 
2.25.1



[Intel-gfx] [PATCH v2 4/6] drm/i915: Implement readout for AVI infoframe SDP

2021-08-13 Thread Ankit Nautiyal
From: Swati Sharma 

In this patch readout for AVI infoframes enclosed in GMP
DIP is implemented.

v2:
-Added new case for AVI infoframe in intel_dp_read_sdp, and a call
to test AVI infoframe during ddi_get_config (Gwan-gyeong Mun).
-Used AVI infoframe unpack only to avoid parsing the header twice
(Ankit).
-Added new infoframes_enabled function for DP with HDMI2.1 as branched
device (Ankit).

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_ddi.c |  4 +
 drivers/gpu/drm/i915/display/intel_dp.c  | 98 +++-
 drivers/gpu/drm/i915/display/intel_dp.h  |  3 +
 3 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index d8162951b78f..7c0c689d4ce2 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3576,6 +3576,9 @@ static void intel_ddi_read_func_ctl(struct intel_encoder 
*encoder,
if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
pipe_config->infoframes.enable |=
intel_lspcon_infoframes_enabled(encoder, 
pipe_config);
+   else if (intel_dp_is_hdmi_2_1_sink(&dig_port->dp))
+   pipe_config->infoframes.enable |=
+   intel_dp_hdmi_21_infoframes_enabled(encoder, 
pipe_config);
else
pipe_config->infoframes.enable |=
intel_hdmi_infoframes_enabled(encoder, 
pipe_config);
@@ -3677,6 +3680,7 @@ static void intel_ddi_get_config(struct intel_encoder 
*encoder,
 
intel_read_dp_sdp(encoder, pipe_config, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC);
+   intel_read_dp_sdp(encoder, pipe_config, HDMI_INFOFRAME_TYPE_AVI);
 
intel_psr_get_config(encoder, pipe_config);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 2990a9e78a9d..66595931e548 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1676,7 +1676,7 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
return max_frl_rate;
 }
 
-static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp)
+bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp)
 {
if (drm_dp_is_branch(intel_dp->dpcd) &&
intel_dp->has_hdmi_sink &&
@@ -3044,6 +3044,44 @@ intel_dp_hdr_metadata_infoframe_sdp_unpack(struct 
hdmi_drm_infoframe *drm_infofr
return ret;
 }
 
+static int
+intel_dp_avi_infoframe_sdp_unpack(struct hdmi_avi_infoframe *frame,
+ const void *buffer, size_t size)
+{
+   int ret;
+
+   const struct dp_sdp *sdp = buffer;
+
+   if (size < sizeof(struct dp_sdp))
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB0 != 0)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB1 != HDMI_INFOFRAME_TYPE_AVI)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB2 != 0x1D)
+   return -EINVAL;
+
+   if ((sdp->sdp_header.HB3 & 0x3) != 0)
+   return -EINVAL;
+
+   if (((sdp->sdp_header.HB3 >> 2) & 0x3f) != 0x13)
+   return -EINVAL;
+
+   if (sdp->db[0] != 2)
+   return -EINVAL;
+
+   if (sdp->db[1] != HDMI_AVI_INFOFRAME_SIZE)
+   return -EINVAL;
+
+   ret = hdmi_avi_infoframe_unpack_only(frame, &sdp->db[2],
+HDMI_AVI_INFOFRAME_SIZE);
+
+   return ret;
+}
+
 static void intel_read_dp_vsc_sdp(struct intel_encoder *encoder,
  struct intel_crtc_state *crtc_state,
  struct drm_dp_vsc_sdp *vsc)
@@ -3095,19 +3133,59 @@ static void 
intel_read_dp_hdr_metadata_infoframe_sdp(struct intel_encoder *encod
"Failed to unpack DP HDR Metadata Infoframe SDP\n");
 }
 
+static void intel_read_dp_avi_infoframe_sdp(struct intel_encoder *encoder,
+   struct intel_crtc_state *crtc_state,
+   struct hdmi_avi_infoframe *frame)
+{
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+   unsigned int type = HDMI_PACKET_TYPE_GAMUT_METADATA;
+   struct dp_sdp sdp = {};
+   int ret;
+
+   if ((crtc_state->infoframes.enable &
+   intel_hdmi_infoframe_enable(type)) == 0)
+   return;
+
+   dig_port->read_infoframe(encoder, crtc_state, type, &sdp,
+sizeof(sdp));
+
+   ret = intel_dp_avi_infoframe_sdp_unpack(frame, &

[Intel-gfx] [PATCH v2 6/6] drm/drm_edid: Avoid HDMI2.1 VICs in AVIInfoframe for older HDMI sinks

2021-08-13 Thread Ankit Nautiyal
Modify the check for CEA modes, to avoid writing VICs added in
CEA-861-G (meant for HDMI2.1) in AVI infoframes for older HDMI sinks.

This patch also adds a function to determine if sink is HDMI2.1
and uses corrects the drm message to show HDMI2.1 sink detetction.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6325877c5fd6..0e7da78c842f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4915,10 +4915,12 @@ static void drm_parse_hdmi_forum_vsdb(struct 
drm_connector *connector,
u8 dsc_max_slices;
struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
 
-   DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
max_frl_rate = (hf_vsdb[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
 &hdmi->max_frl_rate_per_lane);
+   if (max_frl_rate)
+   DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
+
hdmi_dsc->v_1p2 = hf_vsdb[11] & DRM_EDID_DSC_1P2;
 
if (hdmi_dsc->v_1p2) {
@@ -5490,6 +5492,18 @@ void drm_set_preferred_mode(struct drm_connector 
*connector,
 }
 EXPORT_SYMBOL(drm_set_preferred_mode);
 
+static bool is_hdmi21_sink(const struct drm_connector *connector)
+{
+   /*
+* FIXME: sil-sii8620 doesn't have a connector around when
+* we need one, so we have to be prepared for a NULL connector.
+*/
+   if (!connector)
+   return true;
+
+   return connector->display_info.hdmi.max_frl_rate_per_lane ? true : 
false;
+}
+
 static bool is_hdmi2_sink(const struct drm_connector *connector)
 {
/*
@@ -5611,8 +5625,18 @@ static u8 drm_mode_cea_vic(const struct drm_connector 
*connector,
 * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but
 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
 * have to make sure we dont break HDMI 1.4 sinks.
+* Similarly,
+* HDMI 2.1 VIC range: 1 <= VIC <= 219 (CEA-861-G), we have
+* to make sure we dont break HDMI2.0 sinks.
 */
-   if (!is_hdmi2_sink(connector) && vic > 64)
+
+   if (!is_hdmi21_sink(connector) && !is_hdmi2_sink(connector) && vic > 64)
+   return 0;
+
+   if (!is_hdmi21_sink(connector) && vic > 107)
+   return 0;
+
+   if (vic > 219)
return 0;
 
return vic;
-- 
2.25.1



[Intel-gfx] [PATCH v2] drm/i915: Use correct downstream caps for check Src-Ctl mode for PCON

2021-05-05 Thread Ankit Nautiyal
Fix the typo in DPCD caps used for checking SRC CTL mode of
HDMI2.1 PCON

v2: Corrected Fixes tag (Jani Nikula).

Fixes: 04b6603d13be ("drm/i915/display: Configure HDMI2.1 Pcon for FRL
only if Src-Ctl mode is available")
Cc: Ankit Nautiyal 
Cc: Uma Shankar 
Cc: Jani Nikula 
Cc: "Ville Syrj_l_" 
Cc: Imre Deak 
Cc: Manasi Navare 
Cc: Gwan-gyeong Mun 
Cc: Lucas De Marchi 
Cc: Sean Paul 

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index dfa7da928ae5..b3e82aa8b4f8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2112,7 +2112,7 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
 * -PCON supports SRC_CTL_MODE (VESA DP2.0-HDMI2.1 PCON Spec Draft-1 
Sec-7)
 * -sink is HDMI2.1
 */
-   if (!(intel_dp->dpcd[2] & DP_PCON_SOURCE_CTL_MODE) ||
+   if (!(intel_dp->downstream_ports[2] & DP_PCON_SOURCE_CTL_MODE) ||
!intel_dp_is_hdmi_2_1_sink(intel_dp) ||
intel_dp->frl.is_trained)
return;
-- 
2.29.2

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


[Intel-gfx] [PATCH v3] drm/i915: Use correct downstream caps for check Src-Ctl mode for PCON

2021-05-11 Thread Ankit Nautiyal
Fix the typo in DPCD caps used for checking SRC CTL mode of
HDMI2.1 PCON

v2: Corrected Fixes tag (Jani Nikula).
v3: Rebased.

Fixes: 04b6603d13be ("drm/i915/display: Configure HDMI2.1 Pcon for FRL only if 
Src-Ctl mode is available")

Cc: Ankit Nautiyal 
Cc: Uma Shankar 
Cc: Jani Nikula 
Cc: "Ville Syrj_l_" 
Cc: Imre Deak 
Cc: Manasi Navare 
Cc: Gwan-gyeong Mun 
Cc: Lucas De Marchi 
Cc: Sean Paul 

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9a8dfdf15530..072d3edf9197 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2113,7 +2113,7 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
 * -PCON supports SRC_CTL_MODE (VESA DP2.0-HDMI2.1 PCON Spec Draft-1 
Sec-7)
 * -sink is HDMI2.1
 */
-   if (!(intel_dp->dpcd[2] & DP_PCON_SOURCE_CTL_MODE) ||
+   if (!(intel_dp->downstream_ports[2] & DP_PCON_SOURCE_CTL_MODE) ||
!intel_dp_is_hdmi_2_1_sink(intel_dp) ||
intel_dp->frl.is_trained)
return;
-- 
2.29.2

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


[Intel-gfx] [PATCH] drm/i915: Use correct downstream caps for check Src-Ctl mode for PCON

2021-04-29 Thread Ankit Nautiyal
Fix the typo in DPCD caps used for checking SRC CTL mode of
HDMI2.1 PCON

Fixes: 04b6603d13be (drm/i915/display: Configure HDMI2.1 Pcon for FRL
only if Src-Ctl mode is available)

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index dfa7da928ae5..b3e82aa8b4f8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2112,7 +2112,7 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
 * -PCON supports SRC_CTL_MODE (VESA DP2.0-HDMI2.1 PCON Spec Draft-1 
Sec-7)
 * -sink is HDMI2.1
 */
-   if (!(intel_dp->dpcd[2] & DP_PCON_SOURCE_CTL_MODE) ||
+   if (!(intel_dp->downstream_ports[2] & DP_PCON_SOURCE_CTL_MODE) ||
!intel_dp_is_hdmi_2_1_sink(intel_dp) ||
intel_dp->frl.is_trained)
return;
-- 
2.29.2

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


[Intel-gfx] [RFC PATCH 0/3] Get dsc optimal output bpp

2022-06-15 Thread Ankit Nautiyal
Currently, when going with DSC for DP, we take the max lane, rate
and pipe bpp, to get the maximum compressed bpp possible. We then
set the output bpp to this value. It might be possible to have lesser
rate or lane count, for which the same compressed bpp works.

This RFC series attempts to get the best compressed bpp such that we
have maximum bpc, with minimum link rate and lane possible.

The policy here is chosen such that 'best compressed bpp' mean minimum
compression, ie. maximum compressed bpp. It means compress only that
is sufficient to sent over the link, and for that compressed bpp,
use minimum lanes, and rate.

Current series, only touches the DSC for DisplayPort. eDP might require
some more changes and also a different policy.

Ankit Nautiyal (3):
  drm/i915/dp: Rename helper to calculate dsc output bpp
  drm/i915/dp: Rename helper to get max pipe bpp with DSC
  drm/i915/dp: Get optimal link config to have best compressed bpp

 drivers/gpu/drm/i915/display/intel_dp.c | 263 ++--
 1 file changed, 201 insertions(+), 62 deletions(-)

-- 
2.25.1



[Intel-gfx] [RFC PATCH 1/3] drm/i915/dp: Rename helper to calculate dsc output bpp

2022-06-15 Thread Ankit Nautiyal
Currently we the required dsc output bpp is set to be the largest
compressed bpp supported for max, lane, rate, and bpp.
The helper intel_dp_dsc_get_output_bpp gets the maximum supported
compressed bpp taking into account link configuration, input bpp,
bigjoiner considerations etc.

This patch appends 'max' suffix to the function, and also avoid
unnecessary left shifting by 4, which we are anyway shifting back
later.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 49 +++--
 1 file changed, 22 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 2fac76bcf06d..eb00fdf5a3ad 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -660,11 +660,11 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
return 6144 * 8;
 }
 
-static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
-  u32 link_clock, u32 lane_count,
-  u32 mode_clock, u32 mode_hdisplay,
-  bool bigjoiner,
-  u32 pipe_bpp)
+static u16 intel_dp_dsc_get_output_bpp_max(struct drm_i915_private *i915,
+  u32 link_clock, u32 lane_count,
+  u32 mode_clock, u32 mode_hdisplay,
+  bool bigjoiner,
+  u32 pipe_bpp)
 {
u32 bits_per_pixel, max_bpp_small_joiner_ram;
int i;
@@ -718,11 +718,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct 
drm_i915_private *i915,
bits_per_pixel = valid_dsc_bpp[i];
}
 
-   /*
-* Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-* fractional part is 0
-*/
-   return bits_per_pixel << 4;
+   return bits_per_pixel;
 }
 
 static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
@@ -1016,13 +1012,13 @@ intel_dp_mode_valid(struct drm_connector *_connector,
true);
} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
dsc_max_output_bpp =
-   intel_dp_dsc_get_output_bpp(dev_priv,
-   max_link_clock,
-   max_lanes,
-   target_clock,
-   mode->hdisplay,
-   bigjoiner,
-   pipe_bpp) >> 4;
+   intel_dp_dsc_get_output_bpp_max(dev_priv,
+   max_link_clock,
+   max_lanes,
+   target_clock,
+   mode->hdisplay,
+   bigjoiner,
+   pipe_bpp);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1465,13 +1461,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
u8 dsc_dp_slice_count;
 
dsc_max_output_bpp =
-   intel_dp_dsc_get_output_bpp(dev_priv,
-   pipe_config->port_clock,
-   pipe_config->lane_count,
-   adjusted_mode->crtc_clock,
-   
adjusted_mode->crtc_hdisplay,
-   
pipe_config->bigjoiner_pipes,
-   pipe_bpp);
+   intel_dp_dsc_get_output_bpp_max(dev_priv,
+   pipe_config->port_clock,
+   pipe_config->lane_count,
+   
adjusted_mode->crtc_clock,
+   
adjusted_mode->crtc_hdisplay,
+   
pipe_config->bigjoiner_pipes,
+   pipe_bpp);
dsc_dp_slice_count =

[Intel-gfx] [RFC PATCH 2/3] drm/i915/dp: Rename helper to get max pipe bpp with DSC

2022-06-15 Thread Ankit Nautiyal
The helper intel_dp_dsc_compute_bpp gives the maximum pipe bpp that is
allowed with DSC. Renaming the function to reflect the same.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index eb00fdf5a3ad..d0c63888dfff 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -115,7 +115,7 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
 }
 
 static void intel_dp_unset_edid(struct intel_dp *intel_dp);
-static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
+static int intel_dp_dsc_get_bpp_max(struct intel_dp *intel_dp, u8 dsc_max_bpc);
 
 /* Is link rate UHBR and thus 128b/132b? */
 bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state)
@@ -1002,7 +1002,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   int pipe_bpp_max = intel_dp_dsc_get_bpp_max(intel_dp, U8_MAX);
 
if (intel_dp_is_edp(intel_dp)) {
dsc_max_output_bpp =
@@ -1018,7 +1018,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock,
mode->hdisplay,
bigjoiner,
-   pipe_bpp);
+   pipe_bpp_max);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1323,7 +1323,7 @@ intel_dp_compute_link_config_wide(struct intel_dp 
*intel_dp,
return -EINVAL;
 }
 
-static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
+static int intel_dp_dsc_get_bpp_max(struct intel_dp *intel_dp, u8 max_req_bpc)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i, num_bpc;
@@ -1422,7 +1422,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
-   int pipe_bpp;
+   int pipe_bpp_max;
int ret;
 
pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
@@ -1431,10 +1431,10 @@ static int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_supports_dsc(intel_dp, pipe_config))
return -EINVAL;
 
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, 
conn_state->max_requested_bpc);
+   pipe_bpp_max = intel_dp_dsc_get_bpp_max(intel_dp, 
conn_state->max_requested_bpc);
 
/* Min Input BPC for ICL+ is 8 */
-   if (pipe_bpp < 8 * 3) {
+   if (pipe_bpp_max < 8 * 3) {
drm_dbg_kms(&dev_priv->drm,
"No DSC support for less than 8bpc\n");
return -EINVAL;
@@ -1445,7 +1445,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
 * Optimize this later for the minimum possible link rate/lane count
 * with DSC enabled for the requested mode.
 */
-   pipe_config->pipe_bpp = pipe_bpp;
+   pipe_config->pipe_bpp = pipe_bpp_max;
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
 
@@ -1467,7 +1467,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,

adjusted_mode->crtc_clock,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,
-   pipe_bpp);
+   pipe_bpp_max);
dsc_dp_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 adjusted_mode->crtc_clock,
@@ -1486,7 +1486,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
/* As of today we support DSC for only RGB */
if (intel_dp->force_dsc_bpp) {
if (intel_dp->force_dsc_bpp >= 8 &&
-   intel_dp->force_dsc_bpp < pipe_bpp) {
+   intel_dp->force_dsc_bpp < pipe_bpp_max)

[Intel-gfx] [RFC PATCH 3/3] drm/i915/dp: Get optimal link config to have best compressed bpp

2022-06-15 Thread Ankit Nautiyal
Currently, we take the max lane, rate and pipe bpp, to get the maximum
compressed bpp possible. We then set the output bpp to this value.
This patch provides support to have max bpp, min rate and min lanes,
that can support the min compressed bpp.
This patch also takes care of the validation case where bpp is forced
via debugfs.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 220 
 1 file changed, 182 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index d0c63888dfff..4d06f245110f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1413,6 +1413,173 @@ static int intel_dp_dsc_compute_params(struct 
intel_encoder *encoder,
return drm_dsc_compute_rc_parameters(vdsc_cfg);
 }
 
+static bool is_dsc_bw_sufficient(int link_rate, int lane_count, int 
compressed_bpp,
+const struct drm_display_mode *adjusted_mode)
+{
+   int mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, 
compressed_bpp);
+   int link_avail = intel_dp_max_data_rate(link_rate, lane_count);
+
+   return mode_rate <= link_avail;
+}
+
+static int dsc_compute_link_config(struct intel_dp *intel_dp,
+  struct intel_crtc_state *pipe_config,
+  struct link_config_limits *limits,
+  int pipe_bpp,
+  u16 compressed_bpp)
+{
+   const struct drm_display_mode *adjusted_mode =
+   &pipe_config->hw.adjusted_mode;
+   int link_rate, lane_count;
+   int dsc_max_bpp;
+   struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+   int i;
+
+   for (i = 0; i < intel_dp->num_common_rates; i++) {
+   link_rate = intel_dp_common_rate(intel_dp, i);
+   if (link_rate < limits->min_rate || link_rate > 
limits->max_rate)
+   continue;
+
+   for (lane_count = limits->min_lane_count;
+lane_count <= limits->max_lane_count;
+lane_count <<= 1) {
+   dsc_max_bpp = intel_dp_dsc_get_output_bpp_max(dev_priv,
+ link_rate,
+ 
lane_count,
+ 
adjusted_mode->crtc_clock,
+ 
adjusted_mode->crtc_hdisplay,
+ 
pipe_config->bigjoiner_pipes,
+ pipe_bpp);
+   if (compressed_bpp > dsc_max_bpp)
+   continue;
+
+   if (!is_dsc_bw_sufficient(link_rate, lane_count,
+ compressed_bpp, 
adjusted_mode))
+   continue;
+
+   pipe_config->lane_count = lane_count;
+   pipe_config->port_clock = link_rate;
+
+   return 0;
+   }
+   }
+
+   return -EINVAL;
+}
+
+static int _dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
+  struct intel_crtc_state *pipe_config,
+  struct link_config_limits *limits,
+  int pipe_bpp)
+{
+   struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+   u16 compressed_bpp;
+   int dsc_min_bpp, dsc_max_bpp;
+   int ret;
+
+   dsc_min_bpp = 8;
+   if (DISPLAY_VER(dev_priv) <= 12)
+   dsc_max_bpp = 23;
+   else
+   dsc_max_bpp = 27;
+
+   for (compressed_bpp = dsc_max_bpp;
+compressed_bpp >= dsc_min_bpp;
+compressed_bpp--) {
+   ret = dsc_compute_link_config(intel_dp,
+ pipe_config,
+ limits,
+ pipe_bpp,
+ compressed_bpp);
+   if (ret == 0) {
+   pipe_config->dsc.compressed_bpp = compressed_bpp;
+   return 0;
+   }
+   }
+
+   return -EINVAL;
+}
+
+static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct link_config_limits *limits,
+ int pipe_bpp)
+{
+   int ret;
+
+   if (intel_dp->force_dsc_bpp) {
+   u16 compressed_bpp = intel

[Intel-gfx] [PATCH] drm/i915/dp: Check for Low voltage IO only for eDP

2022-06-23 Thread Ankit Nautiyal
The low voltage sku check can be ignored as OEMs need to consider that
when designing the board and then put any limits in VBT.

Due to this check many DP sink that can be run with higher link rate,
are run at lower link rate, thereby pruning the resolutions that are
intended to be working as per bspec.

However, some eDP panels are getting issues [1] with higher link rate.
So keep the low voltage check for eDP, but ignore for DP sinks.
[1] https://gitlab.freedesktop.org/drm/intel/-/issues/6205

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5272

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 32292c0be2bd..c31ea2b418cf 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -405,7 +405,8 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
 
if (intel_phy_is_combo(dev_priv, phy) &&
-   (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
+   intel_dp_is_edp(intel_dp) &&
+   is_low_voltage_sku(dev_priv, phy))
return 54;
 
return 81;
@@ -413,11 +414,7 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
 
 static int ehl_max_source_rate(struct intel_dp *intel_dp)
 {
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
-
-   if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
+   if (intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -429,7 +426,9 @@ static int dg1_max_source_rate(struct intel_dp *intel_dp)
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
 
-   if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
+   if (intel_phy_is_combo(i915, phy) &&
+   intel_dp_is_edp(intel_dp) &&
+   is_low_voltage_sku(i915, phy))
return 54;
 
return 81;
-- 
2.25.1



[Intel-gfx] [PATCH] drm/i915/hdmi: Prune modes that require HDMI2.1 FRL

2022-07-06 Thread Ankit Nautiyal
HDMI2.1 requires some higher resolution video modes to be enumerated
only if HDMI2.1 Fixed Rate Link (FRL) is supported.
Current platforms do not support FRL transmission so prune modes
that require HDMI2.1 FRL.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ebd91aa69dd2..93c00b61795f 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1974,6 +1974,20 @@ intel_hdmi_mode_clock_valid(struct drm_connector 
*connector, int clock,
return status;
 }
 
+/*
+ * HDMI2.1 requires higher resolution modes like 8k60, 4K120 to be
+ * enumerated only if FRL is supported. Platforms not supporting FRL
+ * must prune these modes.
+ */
+static bool
+hdmi21_frl_quirk(int dotclock, bool frl_supported)
+{
+   if (dotclock >= 60 && !frl_supported)
+   return true;
+
+   return false;
+}
+
 static enum drm_mode_status
 intel_hdmi_mode_valid(struct drm_connector *connector,
  struct drm_display_mode *mode)
@@ -2001,6 +2015,13 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
clock *= 2;
}
 
+   /*
+* Current Platforms do not support HDMI2.1 FRL mode of transmission,
+* so prune the modes that require FRL.
+*/
+   if (hdmi21_frl_quirk(clock, false))
+   return MODE_BAD;
+
ycbcr_420_only = drm_mode_is_420_only(&connector->display_info, mode);
 
status = intel_hdmi_mode_clock_valid(connector, clock, has_hdmi_sink, 
ycbcr_420_only);
-- 
2.25.1



[Intel-gfx] [PATCH] drm/i915/display: Fix the PIPE_MISC 12 BPC PORT_OUTPUT for DG2

2022-01-06 Thread Ankit Nautiyal
Currently 12 BPC PORT_OUTPUT_BPC bits are set in PIPE_MISC register
for all Display > 12. DG2 is an exception.
This patch tweaks the condition to read and write the above bits
for DG2.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_display.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index bf7ce684dd8e..1655cff7794f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3774,8 +3774,8 @@ static void bdw_set_pipemisc(const struct 
intel_crtc_state *crtc_state)
val |= PIPEMISC_10_BPC;
break;
case 36:
-   /* Port output 12BPC defined for ADLP+ */
-   if (DISPLAY_VER(dev_priv) > 12)
+   /* Port output 12BPC defined for ADLP+ except for DG2 */
+   if (DISPLAY_VER(dev_priv) > 12 && !IS_DG2(dev_priv))
val |= PIPEMISC_12_BPC_ADLP;
break;
default:
@@ -3835,7 +3835,7 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
case PIPEMISC_10_BPC:
return 30;
/*
-* PORT OUTPUT 12 BPC defined for ADLP+.
+* PORT OUTPUT 12 BPC defined for ADLP+ (except DG2)
 *
 * TODO:
 * For previous platforms with DSI interface, bits 5:7
@@ -3845,7 +3845,7 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
 * MIPI DSI HW readout.
 */
case PIPEMISC_12_BPC_ADLP:
-   if (DISPLAY_VER(dev_priv) > 12)
+   if (DISPLAY_VER(dev_priv) > 12 && !IS_DG2(dev_priv))
return 36;
fallthrough;
default:
-- 
2.25.1



[Intel-gfx] [PATCH v3 1/2] drm/i915/display: Remove check for low voltage sku for max dp source rate

2022-03-15 Thread Ankit Nautiyal
The low voltage sku check can be ignored as OEMs need to consider that
when designing the board and then put any limits in VBT.

Same is now changed in Bspec pages.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5272

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Imre Deak 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 32 +++--
 1 file changed, 3 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index a4e4a286230f..94217ef58775 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -388,23 +388,13 @@ static int dg2_max_source_rate(struct intel_dp *intel_dp)
return intel_dp_is_edp(intel_dp) ? 81 : 135;
 }
 
-static bool is_low_voltage_sku(struct drm_i915_private *i915, enum phy phy)
-{
-   u32 voltage;
-
-   voltage = intel_de_read(i915, ICL_PORT_COMP_DW3(phy)) & 
VOLTAGE_INFO_MASK;
-
-   return voltage == VOLTAGE_INFO_0_85V;
-}
-
 static int icl_max_source_rate(struct intel_dp *intel_dp)
 {
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
 
-   if (intel_phy_is_combo(dev_priv, phy) &&
-   (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
+   if (intel_phy_is_combo(dev_priv, phy) && !intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -412,23 +402,7 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
 
 static int ehl_max_source_rate(struct intel_dp *intel_dp)
 {
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
-
-   if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
-   return 54;
-
-   return 81;
-}
-
-static int dg1_max_source_rate(struct intel_dp *intel_dp)
-{
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
-
-   if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
+   if (intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -471,7 +445,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
max_rate = dg2_max_source_rate(intel_dp);
else if (IS_ALDERLAKE_P(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
 IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
-   max_rate = dg1_max_source_rate(intel_dp);
+   max_rate = 81;
else if (IS_JSL_EHL(dev_priv))
max_rate = ehl_max_source_rate(intel_dp);
else
-- 
2.25.1



[Intel-gfx] [PATCH v3 0/2] Remove check for ComboPHY I/O voltage for DP source rate

2022-03-15 Thread Ankit Nautiyal
This patch series is continuation of the discussion in:
https://patchwork.freedesktop.org/patch/457398/?series=95444&rev=1

along with a patch to add debug print voltage configuration for
combo PHY ports.

Rev3: Added names for voltage levels (Imre)

Ankit Nautiyal (2):
  drm/i915/display: Remove check for low voltage sku for max dp source
rate
  drm/i915/intel_combo_phy: Print procmon ref values

 .../gpu/drm/i915/display/intel_combo_phy.c| 36 +--
 drivers/gpu/drm/i915/display/intel_dp.c   | 32 ++---
 2 files changed, 29 insertions(+), 39 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH v3 2/2] drm/i915/intel_combo_phy: Print procmon ref values

2022-03-15 Thread Ankit Nautiyal
Add debug print for Procmon Ref values, to help get the
voltage configurations of combo PHYs.

v2: Used drm_dbg_kms for logs. (Jani)
Added names for different voltage levels. (Imre)

Suggested-by: Imre Deak 
Signed-off-by: Ankit Nautiyal 
---
 .../gpu/drm/i915/display/intel_combo_phy.c| 36 +--
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 4dfe77351b8b..7ccf45578a7f 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -25,18 +25,29 @@ enum {
 };
 
 static const struct icl_procmon {
+   char name[30];
u32 dw1, dw9, dw10;
 } icl_procmon_values[] = {
-   [PROCMON_0_85V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96, },
-   [PROCMON_0_95V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB, },
-   [PROCMON_0_95V_DOT_1] =
-   { .dw1 = 0x, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5, },
-   [PROCMON_1_05V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1, },
-   [PROCMON_1_05V_DOT_1] =
-   { .dw1 = 0x0044, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1, },
+   [PROCMON_0_85V_DOT_0] = {
+   .name = "0.85V dot0 (low-voltage)\0",
+   .dw1 = 0x, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96,
+   },
+   [PROCMON_0_95V_DOT_0] = {
+   .name = "0.95V dot0\0",
+   .dw1 = 0x, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB,
+   },
+   [PROCMON_0_95V_DOT_1] = {
+   .name = "0.95V dot1\0",
+   .dw1 = 0x, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5,
+   },
+   [PROCMON_1_05V_DOT_0] = {
+   .name = "1.05V dot0\0",
+   .dw1 = 0x, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1,
+   },
+   [PROCMON_1_05V_DOT_1] = {
+   .name = "1.05V dot1\0",
+   .dw1 = 0x0044, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1,
+   },
 };
 
 static const struct icl_procmon *
@@ -113,6 +124,11 @@ static bool icl_verify_procmon_ref_values(struct 
drm_i915_private *dev_priv,
 
procmon = icl_get_procmon_ref_values(dev_priv, phy);
 
+   drm_dbg_kms(&dev_priv->drm,
+   "Combo PHY %c %s PROCMON values : 0x%x, 0x%x, 0x%x\n",
+   phy_name(phy), procmon->name, procmon->dw1, procmon->dw9,
+   procmon->dw10);
+
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
-- 
2.25.1



[Intel-gfx] [PATCH v4 2/2] drm/i915/intel_combo_phy: Print procmon ref values

2022-03-15 Thread Ankit Nautiyal
Add debug print for Procmon Ref values, to help get the
voltage configurations of combo PHYs.

v2: Used drm_dbg_kms for logs. (Jani)
Added names for different voltage levels. (Imre)

v3: Used const char * for names. (Jani)

Suggested-by: Imre Deak 
Signed-off-by: Ankit Nautiyal 
---
 .../gpu/drm/i915/display/intel_combo_phy.c| 36 +--
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 4dfe77351b8b..5abd4a285610 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -25,18 +25,29 @@ enum {
 };
 
 static const struct icl_procmon {
+   const char *name;
u32 dw1, dw9, dw10;
 } icl_procmon_values[] = {
-   [PROCMON_0_85V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96, },
-   [PROCMON_0_95V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB, },
-   [PROCMON_0_95V_DOT_1] =
-   { .dw1 = 0x, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5, },
-   [PROCMON_1_05V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1, },
-   [PROCMON_1_05V_DOT_1] =
-   { .dw1 = 0x0044, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1, },
+   [PROCMON_0_85V_DOT_0] = {
+   .name = "0.85V dot0 (low-voltage)",
+   .dw1 = 0x, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96,
+   },
+   [PROCMON_0_95V_DOT_0] = {
+   .name = "0.95V dot0",
+   .dw1 = 0x, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB,
+   },
+   [PROCMON_0_95V_DOT_1] = {
+   .name = "0.95V dot1",
+   .dw1 = 0x, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5,
+   },
+   [PROCMON_1_05V_DOT_0] = {
+   .name = "1.05V dot0",
+   .dw1 = 0x, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1,
+   },
+   [PROCMON_1_05V_DOT_1] = {
+   .name = "1.05V dot1",
+   .dw1 = 0x0044, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1,
+   },
 };
 
 static const struct icl_procmon *
@@ -113,6 +124,11 @@ static bool icl_verify_procmon_ref_values(struct 
drm_i915_private *dev_priv,
 
procmon = icl_get_procmon_ref_values(dev_priv, phy);
 
+   drm_dbg_kms(&dev_priv->drm,
+   "Combo PHY %c Voltage/Process Info : %s, PROCMON values : 
0x%x, 0x%x, 0x%x\n",
+   phy_name(phy), procmon->name, procmon->dw1, procmon->dw9,
+   procmon->dw10);
+
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
-- 
2.25.1



[Intel-gfx] [PATCH v5 2/2] drm/i915/intel_combo_phy: Print I/O voltage info

2022-03-23 Thread Ankit Nautiyal
Print I/O voltage and process info for each combo phy ports.

v2: Used drm_dbg_kms for logs. (Jani)
Added names for different voltage levels. (Imre)

v3: Used const char * for names. (Jani)

v4: Dropped the procom values and changed commit msg (Imre)

Suggested-by: Imre Deak 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Imre Deak 
---
 .../gpu/drm/i915/display/intel_combo_phy.c| 35 +--
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 4dfe77351b8b..64890f39c3cc 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -25,18 +25,29 @@ enum {
 };
 
 static const struct icl_procmon {
+   const char *name;
u32 dw1, dw9, dw10;
 } icl_procmon_values[] = {
-   [PROCMON_0_85V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96, },
-   [PROCMON_0_95V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB, },
-   [PROCMON_0_95V_DOT_1] =
-   { .dw1 = 0x, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5, },
-   [PROCMON_1_05V_DOT_0] =
-   { .dw1 = 0x, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1, },
-   [PROCMON_1_05V_DOT_1] =
-   { .dw1 = 0x0044, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1, },
+   [PROCMON_0_85V_DOT_0] = {
+   .name = "0.85V dot0 (low-voltage)",
+   .dw1 = 0x, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96,
+   },
+   [PROCMON_0_95V_DOT_0] = {
+   .name = "0.95V dot0",
+   .dw1 = 0x, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB,
+   },
+   [PROCMON_0_95V_DOT_1] = {
+   .name = "0.95V dot1",
+   .dw1 = 0x, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5,
+   },
+   [PROCMON_1_05V_DOT_0] = {
+   .name = "1.05V dot0",
+   .dw1 = 0x, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1,
+   },
+   [PROCMON_1_05V_DOT_1] = {
+   .name = "1.05V dot1",
+   .dw1 = 0x0044, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1,
+   },
 };
 
 static const struct icl_procmon *
@@ -113,6 +124,10 @@ static bool icl_verify_procmon_ref_values(struct 
drm_i915_private *dev_priv,
 
procmon = icl_get_procmon_ref_values(dev_priv, phy);
 
+   drm_dbg_kms(&dev_priv->drm,
+   "Combo PHY %c Voltage/Process Info : %s\n",
+   phy_name(phy), procmon->name);
+
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
-- 
2.25.1



[Intel-gfx] [PATCH 1/2] drm/edid: Fix minimum bpc supported with DSC1.2 for HDMI sink

2022-05-09 Thread Ankit Nautiyal
HF-VSDB/SCDB has bits to advertise support for 16, 12 and 10 bpc.
If none of the bits are set, the minimum bpc supported with DSC is 8.

This patch corrects the min bpc supported to be 8, instead of 0.

Fixes: 76ee7b905678 ("drm/edid: Parse DSC1.2 cap fields from HFVSDB block")
Cc: Ankit Nautiyal 
Cc: Uma Shankar 
Cc: Jani Nikula 
Cc: Maarten Lankhorst 

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 47d121e99201..ce5e23897c9e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5288,7 +5288,8 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
hdmi_dsc->bpc_supported = 10;
else
-   hdmi_dsc->bpc_supported = 0;
+   /* Supports min 8 BPC if DSC1.2 is supported*/
+   hdmi_dsc->bpc_supported = 8;
 
dsc_max_frl_rate = (hf_scds[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
drm_get_max_frl_rate(dsc_max_frl_rate, 
&hdmi_dsc->max_lanes,
-- 
2.25.1



[Intel-gfx] [PATCH 0/2] Prune unsupported modes as per HDMI2.1 spec

2022-05-09 Thread Ankit Nautiyal
Modes like 4K100, 4K120, 8K50, 8K60 need FRL and/or DSC from source.
Since FRL and DSC are not currently supported natively by intel
platforms (are supported only via DP-HDMI2.1 PCONs), these modes must
be pruned as per spec.
Currently these modes are not getting pruned as we check the TMDS clock,
which passes some of these with YCbCr420 format and with lower bpc.
This causes failures during compliance test (e.g. HFR1-67).

This patch prunes the modes, if FRL, DSC not supported, or the support
requirement not met as per the spec.
Although the spec mentions 4K100, 4K120, 8K50, and 8K60 video timings,
I have used the check for clock >= 2376 MHz (or 1188 MHz with 420
format), instead of using individual VICs.

While at it, fix a bug while parsing the compressed bpc supported
from edid.

Ankit Nautiyal (2):
  drm/edid: Fix minimum bpc supported with DSC1.2 for HDMI sink
  drm/i915/hdmi: Prune unsupported modes as per HDMI2.1 spec

 drivers/gpu/drm/drm_edid.c|  3 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c | 48 +++
 2 files changed, 50 insertions(+), 1 deletion(-)

-- 
2.25.1



[Intel-gfx] [PATCH 2/2] drm/i915/hdmi: Prune unsupported modes as per HDMI2.1 spec

2022-05-09 Thread Ankit Nautiyal
As per Sec 7.8.1 of HDMI2.1 spec, sources that support modes:
4K100, 4K120, 8K50, 8K60 must support these modes in at least one of
the below formats:
i) uncompressed FRL, 420 format and min of 10 bpc, or
ii) compressed FRL, 444 format and min of 10 bpc.

Since FRL and DSC are not supported natively with HDMI, the above
modes must be pruned as per the spec, and is a requirement for the
HDMI2.1 compliance test.

This patch adds a condition to check for the modes with clock
requirement more than 2376 MHz (1188 MHz with 420 format),
and prune them if none of the above two formats are supported.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 48 +++
 1 file changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 1ae09431f53a..2ee1262f6427 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1940,6 +1940,44 @@ static bool intel_hdmi_sink_bpc_possible(struct 
drm_connector *connector,
}
 }
 
+/*
+ * HDMI2.1 Sec7.8.1
+ * Support requirement for 4K100, 4K120, 8K50, and 8K60.
+ *
+ * The modes with timings same as above modes are supported only with min of 
10 bpc
+ * along with:
+ *
+ * i) 444 format only with FRL mode support with DSC
+ * ii) 420 format only with FRL mode without DSC.
+ */
+static bool
+intel_hdmi21_bpc_possible(struct drm_connector *connector,
+ int clock, int bpc, bool ycbcr420_output,
+ bool frl, bool dsc)
+{
+   const struct drm_display_info *info = &connector->display_info;
+   const struct drm_hdmi_info *hdmi = &info->hdmi;
+
+   int pixel_clock = ycbcr420_output ? clock * 2 : clock;
+
+   if (pixel_clock < 2376000)
+   return true;
+
+   if (!frl)
+   return false;
+
+   if (dsc && bpc > hdmi->dsc_cap.bpc_supported)
+   return false;
+
+   if (!ycbcr420_output && !dsc)
+   return false;
+
+   if (bpc < 10)
+   return false;
+
+   return true;
+}
+
 static enum drm_mode_status
 intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock,
bool has_hdmi_sink, bool ycbcr420_output)
@@ -1948,6 +1986,13 @@ intel_hdmi_mode_clock_valid(struct drm_connector 
*connector, int clock,
struct intel_hdmi *hdmi = 
intel_attached_hdmi(to_intel_connector(connector));
enum drm_mode_status status = MODE_OK;
int bpc;
+   bool frl, dsc;
+
+   /*
+* FRL and DSC not supported for HDMI from source as of now.
+*/
+   frl = false;
+   dsc = false;
 
/*
 * Try all color depths since valid port clock range
@@ -1963,6 +2008,9 @@ intel_hdmi_mode_clock_valid(struct drm_connector 
*connector, int clock,
if (!intel_hdmi_sink_bpc_possible(connector, bpc, 
has_hdmi_sink, ycbcr420_output))
continue;
 
+   if (!intel_hdmi21_bpc_possible(connector, clock, bpc, 
ycbcr420_output, frl, dsc))
+   continue;
+
status = hdmi_port_clock_valid(hdmi, tmds_clock, true, 
has_hdmi_sink);
if (status == MODE_OK)
return MODE_OK;
-- 
2.25.1



[Intel-gfx] [PATCH] drm/i915/dg2: Support 4k@30 on HDMI

2022-05-11 Thread Ankit Nautiyal
From: Vandita Kulkarni 

This patch adds a fix to support 297MHz of dot clock by calculating
the pll values using synopsis algorithm.
This will help to support 4k@30 mode for HDMI monitors on DG2.

Signed-off-by: Vandita Kulkarni 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_snps_phy.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c 
b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index 0dd4775e8195..ec1700dd3bc6 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -517,6 +517,36 @@ static const struct intel_mpllb_state dg2_hdmi_148_5 = {
REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
 };
 
+/* values in the below table are calculted using the algo */
+static const struct intel_mpllb_state dg2_hdmi_297 = {
+   .clock = 297000,
+   .ref_control =
+   REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+   .mpllb_cp =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+   .mpllb_div =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+   .mpllb_div2 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+   .mpllb_fracn1 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
+   .mpllb_fracn2 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
+   .mpllb_sscen =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
 static const struct intel_mpllb_state dg2_hdmi_594 = {
.clock = 594000,
.ref_control =
@@ -551,6 +581,7 @@ static const struct intel_mpllb_state * const 
dg2_hdmi_tables[] = {
&dg2_hdmi_27_0,
&dg2_hdmi_74_25,
&dg2_hdmi_148_5,
+   &dg2_hdmi_297,
&dg2_hdmi_594,
NULL,
 };
-- 
2.25.1



[Intel-gfx] [PATCH v2] drm/i915/dg2: Support 4k@30 on HDMI

2022-05-25 Thread Ankit Nautiyal
From: Vandita Kulkarni 

This patch adds a fix to support 297MHz of dot clock by calculating
the pll values using synopsis algorithm.
This will help to support 4k@30 mode for HDMI monitors on DG2.

v2: As per the algorithm, set MPLLB VCO range control bits to 3,
in register SNPS_PHY_MPLLB_DIV for 297Mhz. (Matt)

Signed-off-by: Vandita Kulkarni 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_snps_phy.c | 32 +++
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c 
b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index 0dd4775e8195..69fe32b8a662 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -517,6 +517,37 @@ static const struct intel_mpllb_state dg2_hdmi_148_5 = {
REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
 };
 
+/* values in the below table are calculted using the algo */
+static const struct intel_mpllb_state dg2_hdmi_297 = {
+   .clock = 297000,
+   .ref_control =
+   REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+   .mpllb_cp =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+   .mpllb_div =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+   .mpllb_div2 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+   .mpllb_fracn1 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
+   .mpllb_fracn2 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
+   .mpllb_sscen =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
 static const struct intel_mpllb_state dg2_hdmi_594 = {
.clock = 594000,
.ref_control =
@@ -551,6 +582,7 @@ static const struct intel_mpllb_state * const 
dg2_hdmi_tables[] = {
&dg2_hdmi_27_0,
&dg2_hdmi_74_25,
&dg2_hdmi_148_5,
+   &dg2_hdmi_297,
&dg2_hdmi_594,
NULL,
 };
-- 
2.25.1



[Intel-gfx] [PATCH v3] drm/i915/dg2: Support 4k@30 on HDMI

2022-05-25 Thread Ankit Nautiyal
From: Vandita Kulkarni 

This patch adds a fix to support 297MHz of dot clock by calculating
the pll values using synopsis algorithm.
This will help to support 4k@30 mode for HDMI monitors on DG2.

v2: As per the algorithm, set MPLLB VCO range control bits to 3,
in register SNPS_PHY_MPLLB_DIV for 297Mhz. (Matt)

v3: Fix typo. (Ankit)

Signed-off-by: Vandita Kulkarni 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_snps_phy.c | 32 +++
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c 
b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index 0dd4775e8195..cc1270978b67 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -517,6 +517,37 @@ static const struct intel_mpllb_state dg2_hdmi_148_5 = {
REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
 };
 
+/* values in the below table are calculted using the algo */
+static const struct intel_mpllb_state dg2_hdmi_297 = {
+   .clock = 297000,
+   .ref_control =
+   REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+   .mpllb_cp =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 14) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+   .mpllb_div =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+   .mpllb_div2 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+   .mpllb_fracn1 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 65535),
+   .mpllb_fracn2 =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 26214),
+   .mpllb_sscen =
+   REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
 static const struct intel_mpllb_state dg2_hdmi_594 = {
.clock = 594000,
.ref_control =
@@ -551,6 +582,7 @@ static const struct intel_mpllb_state * const 
dg2_hdmi_tables[] = {
&dg2_hdmi_27_0,
&dg2_hdmi_74_25,
&dg2_hdmi_148_5,
+   &dg2_hdmi_297,
&dg2_hdmi_594,
NULL,
 };
-- 
2.25.1



[Intel-gfx] [PATCH v2] drm/i915/hdmi: Prune modes that require HDMI2.1 FRL

2022-07-21 Thread Ankit Nautiyal
HDMI2.1 requires some higher resolution video modes to be enumerated
only if HDMI2.1 Fixed Rate Link (FRL) is supported.
Current platforms do not support FRL transmission so prune modes that
require HDMI2.1 FRL.

v2: Fixed the condition to check for dotclock > 600.
Return MODE_CLOCK_HIGH as mode status.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Arun R Murthy  (v1)
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ebd91aa69dd2..a88f589351fa 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2001,6 +2001,15 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
clock *= 2;
}
 
+   /*
+* HDMI2.1 requires higher resolution modes like 8k60, 4K120 to be
+* enumerated only if FRL is supported. Current platforms do not support
+* FRL so prune the higher resolution modes that require doctclock more
+* than 600MHz.
+*/
+   if (clock > 60)
+   return MODE_CLOCK_HIGH;
+
ycbcr_420_only = drm_mode_is_420_only(&connector->display_info, mode);
 
status = intel_hdmi_mode_clock_valid(connector, clock, has_hdmi_sink, 
ycbcr_420_only);
-- 
2.25.1



[Intel-gfx] [PATCH] drm/drm_edid: Refactor HFVSDB parsing for DSC1.2

2022-07-21 Thread Ankit Nautiyal
DSC capabilities are given in bytes 11-13 of VSDB (i.e. bytes 8-10 of
SCDS). Since minimum length of Data block is 7, all bytes greater than 7
must be read only after checking the length of the data block.

This patch adds check for data block length before reading relavant DSC
bytes. It also corrects min DSC BPC to 8, and minor refactoring for
better readability, and proper log messages.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 124 +++--
 1 file changed, 77 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index bbc25e3b7220..f683a8d5fd31 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5703,12 +5703,58 @@ static void drm_parse_ycbcr420_deep_color_info(struct 
drm_connector *connector,
hdmi->y420_dc_modes = dc_mask;
 }
 
+static void drm_parse_dsc_slice_info(u8 dsc_max_slices,
+struct drm_hdmi_dsc_cap *hdmi_dsc)
+{
+   switch (dsc_max_slices) {
+   case 1:
+   hdmi_dsc->max_slices = 1;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 2:
+   hdmi_dsc->max_slices = 2;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 3:
+   hdmi_dsc->max_slices = 4;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 4:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 5:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 6:
+   hdmi_dsc->max_slices = 12;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 7:
+   hdmi_dsc->max_slices = 16;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 0:
+   default:
+   hdmi_dsc->max_slices = 0;
+   hdmi_dsc->clk_per_slice = 0;
+   }
+}
+
 /* Sink Capability Data Structure */
 static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
  const u8 *hf_scds)
 {
struct drm_display_info *display = &connector->display_info;
struct drm_hdmi_info *hdmi = &display->hdmi;
+   u8 db_length = hf_scds[0] & 0x1F;
+   u8 dsc_max_frl_rate;
+   u8 dsc_max_slices;
+   struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
+
+   if (db_length < 7 || db_length > 31)
+   return;
 
display->has_hdmi_infoframe = true;
 
@@ -5749,17 +5795,25 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
 
if (hf_scds[7]) {
u8 max_frl_rate;
-   u8 dsc_max_frl_rate;
-   u8 dsc_max_slices;
-   struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
 
-   DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
max_frl_rate = (hf_scds[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
+   if (max_frl_rate)
+   DRM_DEBUG_KMS("HDMI2.1 FRL support detected\n");
+
drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
 &hdmi->max_frl_rate_per_lane);
+
+   drm_parse_ycbcr420_deep_color_info(connector, hf_scds);
+   }
+
+   if (db_length < 11)
+   return;
+
+   if (hf_scds[11]) {
hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
 
if (hdmi_dsc->v_1p2) {
+   DRM_DEBUG_KMS("HDMI DSC1.2 support detected\n");
hdmi_dsc->native_420 = hf_scds[11] & 
DRM_EDID_DSC_NATIVE_420;
hdmi_dsc->all_bpp = hf_scds[11] & DRM_EDID_DSC_ALL_BPP;
 
@@ -5770,52 +5824,28 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
hdmi_dsc->bpc_supported = 10;
else
-   hdmi_dsc->bpc_supported = 0;
-
-   dsc_max_frl_rate = (hf_scds[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
-   drm_get_max_frl_rate(dsc_max_frl_rate, 
&hdmi_dsc->max_lanes,
-&hdmi_dsc->max_frl_rate_per_lane);
-   hdmi_dsc->total_chunk_kbytes = hf_scds[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
-
-   dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
-   switch (dsc_max_slices) {
-   case 1:
-   hdmi_dsc->max_slices = 1;
-  

[Intel-gfx] [PATCH] drm/i915/dp: Check for Low voltage IO only for eDP

2022-07-26 Thread Ankit Nautiyal
The low voltage sku check can be ignored as OEMs need to consider that
when designing the board and then put any limits in VBT.

Due to this check many DP sink that can be run with higher link rate,
are run at lower link rate, thereby pruning the resolutions that are
intended to be working as per bspec.

However, some eDP panels are getting issues [1] with higher link rate.
So keep the low voltage check for eDP, but ignore for DP sinks.
[1] https://gitlab.freedesktop.org/drm/intel/-/issues/6205

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5272

v2: Added comment about eDP HBR2 restriction for JSL/EHL (Arun).

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Arun R Murthy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 32292c0be2bd..e50bba14e8c5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -405,7 +405,8 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
 
if (intel_phy_is_combo(dev_priv, phy) &&
-   (is_low_voltage_sku(dev_priv, phy) || !intel_dp_is_edp(intel_dp)))
+   intel_dp_is_edp(intel_dp) &&
+   is_low_voltage_sku(dev_priv, phy))
return 54;
 
return 81;
@@ -413,11 +414,8 @@ static int icl_max_source_rate(struct intel_dp *intel_dp)
 
 static int ehl_max_source_rate(struct intel_dp *intel_dp)
 {
-   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-   enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
-
-   if (intel_dp_is_edp(intel_dp) || is_low_voltage_sku(dev_priv, phy))
+   /* For JSL/EHL, eDP supports only HBR2 5.4 (SOC PHY restriction) */
+   if (intel_dp_is_edp(intel_dp))
return 54;
 
return 81;
@@ -429,7 +427,9 @@ static int dg1_max_source_rate(struct intel_dp *intel_dp)
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
 
-   if (intel_phy_is_combo(i915, phy) && is_low_voltage_sku(i915, phy))
+   if (intel_phy_is_combo(i915, phy) &&
+   intel_dp_is_edp(intel_dp) &&
+   is_low_voltage_sku(i915, phy))
return 54;
 
return 81;
-- 
2.25.1



[Intel-gfx] [PATCH] drm/i915/combo_phy: Add Workaround to avoid flicker with HBR3 eDP Panels

2022-08-04 Thread Ankit Nautiyal
WA_14014367875 : When Display PHY is configured in continuous
DCC calibration mode, the DCC (duty cycle correction) for the clock
erroneously goes through a state where the DCC code is 0x00 when it is
supposed to be transitioning from 0x10 to 0x0F. This glitch causes a
distortion in the clock, which leads to a bit error. The issue is known
to be causing flickering with eDP HBR3 panels.

The work around configures the DCC in one-time-update mode.
This mode updates the DCC code one time during training and then
it does not change.  This will prevent on-the-fly updates so that the
glitch does not occur.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_combo_phy.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 64890f39c3cc..1b8bdc47671d 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -242,9 +242,10 @@ static bool icl_combo_phy_verify_state(struct 
drm_i915_private *dev_priv,
 ICL_PORT_TX_DW8_ODCC_CLK_SEL |
 ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2);
 
+   /* WA_14014367875 Set DCC calibration mode to Read once*/
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_PCS_DW1_LN(0, phy),
 DCC_MODE_SELECT_MASK,
-DCC_MODE_SELECT_CONTINUOSLY);
+~DCC_MODE_SELECT_MASK);
}
 
ret &= icl_verify_procmon_ref_values(dev_priv, phy);
@@ -366,8 +367,9 @@ static void icl_combo_phys_init(struct drm_i915_private 
*dev_priv)
intel_de_write(dev_priv, ICL_PORT_TX_DW8_GRP(phy), val);
 
val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, 
phy));
+
+   /* WA_14014367875 Set DCC calibration mode to Read 
once*/
val &= ~DCC_MODE_SELECT_MASK;
-   val |= DCC_MODE_SELECT_CONTINUOSLY;
intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), 
val);
}
 
-- 
2.25.1



[Intel-gfx] [PATCH v2] drm/i915/combo_phy: Add Workaround to avoid flicker with HBR3 eDP Panels

2022-08-10 Thread Ankit Nautiyal
Wa_22012718247 : When Display PHY is configured in continuous
DCC calibration mode, the DCC (duty cycle correction) for the clock
erroneously goes through a state where the DCC code is 0x00 when it is
supposed to be transitioning from 0x10 to 0x0F. This glitch causes a
distortion in the clock, which leads to a bit error. The issue is known
to be causing flickering with eDP HBR3 panels.

The work around configures the DCC in one-time-update mode.
This mode updates the DCC code one time during training and then
it does not change.  This will prevent on-the-fly updates so that the
glitch does not occur.

v2: Added helper function for DCC_MODE (Imre).

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_combo_phy.c   | 16 ++--
 .../gpu/drm/i915/display/intel_combo_phy_regs.h  |  1 +
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 64890f39c3cc..b3be0e3ca984 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -226,6 +226,17 @@ static bool phy_is_master(struct drm_i915_private 
*dev_priv, enum phy phy)
return false;
 }
 
+static u32 tgl_dcc_calibration_mode(struct drm_i915_private *dev_priv)
+{
+   /* Wa_22012718247:tgl,adlp,adls */
+   if (IS_TIGERLAKE(dev_priv) ||
+   IS_ALDERLAKE_P(dev_priv) ||
+   IS_ALDERLAKE_S(dev_priv))
+   return DCC_MODE_SELECT_ONCE;
+
+   return DCC_MODE_SELECT_CONTINUOSLY;
+}
+
 static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
   enum phy phy)
 {
@@ -244,7 +255,7 @@ static bool icl_combo_phy_verify_state(struct 
drm_i915_private *dev_priv,
 
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_PCS_DW1_LN(0, phy),
 DCC_MODE_SELECT_MASK,
-DCC_MODE_SELECT_CONTINUOSLY);
+tgl_dcc_calibration_mode(dev_priv));
}
 
ret &= icl_verify_procmon_ref_values(dev_priv, phy);
@@ -366,8 +377,9 @@ static void icl_combo_phys_init(struct drm_i915_private 
*dev_priv)
intel_de_write(dev_priv, ICL_PORT_TX_DW8_GRP(phy), val);
 
val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, 
phy));
+
val &= ~DCC_MODE_SELECT_MASK;
-   val |= DCC_MODE_SELECT_CONTINUOSLY;
+   val |= tgl_dcc_calibration_mode(dev_priv);
intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), 
val);
}
 
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h 
b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
index 2ed65193ca19..cf46f13401d1 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
@@ -92,6 +92,7 @@
 #define ICL_PORT_PCS_DW1_LN(ln, phy)   _MMIO(_ICL_PORT_PCS_DW_LN(1, 
ln, phy))
 #define   DCC_MODE_SELECT_MASK (0x3 << 20)
 #define   DCC_MODE_SELECT_CONTINUOSLY  (0x3 << 20)
+#define   DCC_MODE_SELECT_ONCE (0x0 << 20)
 #define   COMMON_KEEPER_EN (1 << 26)
 #define   LATENCY_OPTIM_MASK   (0x3 << 2)
 #define   LATENCY_OPTIM_VAL(x) ((x) << 2)
-- 
2.25.1



[Intel-gfx] [PATCH 0/4] Fix HFVSDB parsing

2022-08-10 Thread Ankit Nautiyal
Fix issues in HFVSDB parsing for DSC support.
Also minor refactoring in Logging.

Split from original patch into a new series.
https://patchwork.freedesktop.org/patch/495193/

Ankit Nautiyal (4):
  drm/edid: Fix minimum bpc supported with DSC1.2 for HDMI sink
  drm/edid: Split DSC parsing into separate function
  drm/edid: Refactor HFVSDB parsing for DSC1.2
  drm/edid: Avoid multiple log lines for HFVSDB parsing

 drivers/gpu/drm/drm_edid.c | 153 +
 1 file changed, 87 insertions(+), 66 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH 3/4] drm/edid: Refactor HFVSDB parsing for DSC1.2

2022-08-10 Thread Ankit Nautiyal
DSC capabilities are given in bytes 11-13 of VSDB (i.e. bytes 8-10 of
SCDS). Since minimum length of Data block is 7, all bytes greater than 7
must be read only after checking the length of the data block.

This patch adds check for data block length before reading relavant DSC
bytes.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 93 --
 1 file changed, 49 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 1d08b3a4..c9c3a9c8fa26 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5706,9 +5706,6 @@ static void drm_parse_ycbcr420_deep_color_info(struct 
drm_connector *connector,
 static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap *hdmi_dsc,
   const u8 *hf_scds)
 {
-   u8 dsc_max_slices;
-   u8 dsc_max_frl_rate;
-
hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
 
if (!hdmi_dsc->v_1p2)
@@ -5727,47 +5724,54 @@ static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap 
*hdmi_dsc,
/* Supports min 8 BPC if DSC1.2 is supported*/
hdmi_dsc->bpc_supported = 8;
 
-   dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
-   drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
-&hdmi_dsc->max_frl_rate_per_lane);
-   hdmi_dsc->total_chunk_kbytes = hf_scds[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
+   if (cea_db_payload_len(hf_scds) >= 12 && hf_scds[12]) {
+   u8 dsc_max_slices;
+   u8 dsc_max_frl_rate;
 
-   dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
+   dsc_max_frl_rate = (hf_scds[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
+   drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
+&hdmi_dsc->max_frl_rate_per_lane);
 
-   switch (dsc_max_slices) {
-   case 1:
-   hdmi_dsc->max_slices = 1;
-   hdmi_dsc->clk_per_slice = 340;
-   break;
-   case 2:
-   hdmi_dsc->max_slices = 2;
-   hdmi_dsc->clk_per_slice = 340;
-   break;
-   case 3:
-   hdmi_dsc->max_slices = 4;
-   hdmi_dsc->clk_per_slice = 340;
-   break;
-   case 4:
-   hdmi_dsc->max_slices = 8;
-   hdmi_dsc->clk_per_slice = 340;
-   break;
-   case 5:
-   hdmi_dsc->max_slices = 8;
-   hdmi_dsc->clk_per_slice = 400;
-   break;
-   case 6:
-   hdmi_dsc->max_slices = 12;
-   hdmi_dsc->clk_per_slice = 400;
-   break;
-   case 7:
-   hdmi_dsc->max_slices = 16;
-   hdmi_dsc->clk_per_slice = 400;
-   break;
-   case 0:
-   default:
-   hdmi_dsc->max_slices = 0;
-   hdmi_dsc->clk_per_slice = 0;
+   dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
+
+   switch (dsc_max_slices) {
+   case 1:
+   hdmi_dsc->max_slices = 1;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 2:
+   hdmi_dsc->max_slices = 2;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 3:
+   hdmi_dsc->max_slices = 4;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 4:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 5:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 6:
+   hdmi_dsc->max_slices = 12;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 7:
+   hdmi_dsc->max_slices = 16;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 0:
+   default:
+   hdmi_dsc->max_slices = 0;
+   hdmi_dsc->clk_per_slice = 0;
+   }
}
+
+   if (cea_db_payload_len(hf_scds) >= 13 && hf_scds[13])
+   hdmi_dsc->total_chunk_kbytes = hf_scds[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
 }
 
 /* Sink Capability Data Structure */
@@ -5776,6 +5780,7 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
 {
struct drm_display_info *display = &connector->display_info;
struct

[Intel-gfx] [PATCH 4/4] drm/edid: Avoid multiple log lines for HFVSDB parsing

2022-08-10 Thread Ankit Nautiyal
Replace multiple log lines with a single log line at the end of
parsing HF-VSDB. Also use drm_dbg_kms instead of DRM_DBG_KMS, and
add log for DSC1.2 support.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c9c3a9c8fa26..7a319d570297 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5781,6 +5781,9 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
struct drm_display_info *display = &connector->display_info;
struct drm_hdmi_info *hdmi = &display->hdmi;
struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
+   u32 max_tmds_clock = 0;
+   u8 max_frl_rate = 0;
+   bool dsc_support = false;
 
display->has_hdmi_infoframe = true;
 
@@ -5800,14 +5803,13 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
 */
 
if (hf_scds[5]) {
-   /* max clock is 5000 KHz times block value */
-   u32 max_tmds_clock = hf_scds[5] * 5000;
struct drm_scdc *scdc = &hdmi->scdc;
 
+   /* max clock is 5000 KHz times block value */
+   max_tmds_clock = hf_scds[5] * 5000;
+
if (max_tmds_clock > 34) {
display->max_tmds_clock = max_tmds_clock;
-   DRM_DEBUG_KMS("HF-VSDB: max TMDS clock %d kHz\n",
-   display->max_tmds_clock);
}
 
if (scdc->supported) {
@@ -5820,9 +5822,6 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
}
 
if (hf_scds[7]) {
-   u8 max_frl_rate;
-
-   DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
max_frl_rate = (hf_scds[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
 &hdmi->max_frl_rate_per_lane);
@@ -5830,8 +5829,14 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
 
drm_parse_ycbcr420_deep_color_info(connector, hf_scds);
 
-   if (cea_db_payload_len(hf_scds) >= 11 && hf_scds[11])
+   if (cea_db_payload_len(hf_scds) >= 11 && hf_scds[11]) {
drm_parse_dsc_info(hdmi_dsc, hf_scds);
+   dsc_support = true;
+   }
+
+   drm_dbg_kms(connector->dev,
+   "HF-VSDB: max TMDS clock:%d Khz, HDMI2.1 support:%s, DSC1.2 
support:%s\n",
+   max_tmds_clock, max_frl_rate ? "yes" : "no", dsc_support ? 
"yes" : "no");
 }
 
 static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
-- 
2.25.1



[Intel-gfx] [PATCH 2/4] drm/edid: Split DSC parsing into separate function

2022-08-10 Thread Ankit Nautiyal
Move the DSC parsing logic into separate function.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 128 -
 1 file changed, 69 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index cdf10279e1bd..1d08b3a4 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5703,6 +5703,73 @@ static void drm_parse_ycbcr420_deep_color_info(struct 
drm_connector *connector,
hdmi->y420_dc_modes = dc_mask;
 }
 
+static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap *hdmi_dsc,
+  const u8 *hf_scds)
+{
+   u8 dsc_max_slices;
+   u8 dsc_max_frl_rate;
+
+   hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
+
+   if (!hdmi_dsc->v_1p2)
+   return;
+
+   hdmi_dsc->native_420 = hf_scds[11] & DRM_EDID_DSC_NATIVE_420;
+   hdmi_dsc->all_bpp = hf_scds[11] & DRM_EDID_DSC_ALL_BPP;
+
+   if (hf_scds[11] & DRM_EDID_DSC_16BPC)
+   hdmi_dsc->bpc_supported = 16;
+   else if (hf_scds[11] & DRM_EDID_DSC_12BPC)
+   hdmi_dsc->bpc_supported = 12;
+   else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
+   hdmi_dsc->bpc_supported = 10;
+   else
+   /* Supports min 8 BPC if DSC1.2 is supported*/
+   hdmi_dsc->bpc_supported = 8;
+
+   dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
+   drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
+&hdmi_dsc->max_frl_rate_per_lane);
+   hdmi_dsc->total_chunk_kbytes = hf_scds[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
+
+   dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
+
+   switch (dsc_max_slices) {
+   case 1:
+   hdmi_dsc->max_slices = 1;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 2:
+   hdmi_dsc->max_slices = 2;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 3:
+   hdmi_dsc->max_slices = 4;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 4:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 340;
+   break;
+   case 5:
+   hdmi_dsc->max_slices = 8;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 6:
+   hdmi_dsc->max_slices = 12;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 7:
+   hdmi_dsc->max_slices = 16;
+   hdmi_dsc->clk_per_slice = 400;
+   break;
+   case 0:
+   default:
+   hdmi_dsc->max_slices = 0;
+   hdmi_dsc->clk_per_slice = 0;
+   }
+}
+
 /* Sink Capability Data Structure */
 static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
  const u8 *hf_scds)
@@ -5749,71 +5816,14 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
 
if (hf_scds[7]) {
u8 max_frl_rate;
-   u8 dsc_max_frl_rate;
-   u8 dsc_max_slices;
struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
 
DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
max_frl_rate = (hf_scds[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
 &hdmi->max_frl_rate_per_lane);
-   hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
-
-   if (hdmi_dsc->v_1p2) {
-   hdmi_dsc->native_420 = hf_scds[11] & 
DRM_EDID_DSC_NATIVE_420;
-   hdmi_dsc->all_bpp = hf_scds[11] & DRM_EDID_DSC_ALL_BPP;
-
-   if (hf_scds[11] & DRM_EDID_DSC_16BPC)
-   hdmi_dsc->bpc_supported = 16;
-   else if (hf_scds[11] & DRM_EDID_DSC_12BPC)
-   hdmi_dsc->bpc_supported = 12;
-   else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
-   hdmi_dsc->bpc_supported = 10;
-   else
-   /* Supports min 8 BPC if DSC1.2 is supported*/
-   hdmi_dsc->bpc_supported = 8;
-
-   dsc_max_frl_rate = (hf_scds[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
-   drm_get_max_frl_rate(dsc_max_frl_rate, 
&hdmi_dsc->max_lanes,
-&hdmi_dsc->max_frl_rate_per_lane);
-   hdmi_dsc->total_chunk_kbytes = hf_scds[13] & 

[Intel-gfx] [PATCH 1/4] drm/edid: Fix minimum bpc supported with DSC1.2 for HDMI sink

2022-08-10 Thread Ankit Nautiyal
HF-VSDB/SCDB has bits to advertise support for 16, 12 and 10 bpc.
If none of the bits are set, the minimum bpc supported with DSC is 8.

This patch corrects the min bpc supported to be 8, instead of 0.

Fixes: 76ee7b905678 ("drm/edid: Parse DSC1.2 cap fields from HFVSDB block")
Cc: Ankit Nautiyal 
Cc: Uma Shankar 
Cc: Jani Nikula 
Cc: Maarten Lankhorst 

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index bbc25e3b7220..cdf10279e1bd 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5770,7 +5770,8 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
hdmi_dsc->bpc_supported = 10;
else
-   hdmi_dsc->bpc_supported = 0;
+   /* Supports min 8 BPC if DSC1.2 is supported*/
+   hdmi_dsc->bpc_supported = 8;
 
dsc_max_frl_rate = (hf_scds[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
drm_get_max_frl_rate(dsc_max_frl_rate, 
&hdmi_dsc->max_lanes,
-- 
2.25.1



[Intel-gfx] [PATCH 0/5] Handle BPC for HDMI2.1 PCON without DSC1.2 sink and other fixes

2022-08-22 Thread Ankit Nautiyal
This series fixes issues faced when HDMI2.1 sink connected via HDMI2.1
PCON does not support DSC, and other minor HDMI2.1 PCON
fixes/refactoring.

Patch 1 Adds helper to check HDMI2.1 DSC1.2
Patch 2 resets 'frl trained' flag before restarting FRL training.
Patch 3 Pulls the decision making to use DFP conversion capabilities
for every mode during compute config, instead of having that decision
during DP initializing phase.
Patch 4-5 calculate the max BPC that can be sufficient with either
RGB or YCbcr420 format for the maximum FRL rate supported.

Ankit Nautiyal (5):
  drm/i915/dp: Add helper to check DSC1.2 for HDMI2.1 DFP
  drm/i915/dp: Reset frl trained flag before restarting FRL training
  drm/i915/dp: Fix DFP RGB->YCBCR conversion
  drm/i915/dp: Handle BPP where HDMI2.1 DFP doesn't support DSC
  drm/i915/dp: Fix FRL BW check for HDMI2.1 DFP

 .../drm/i915/display/intel_display_types.h|   7 +
 drivers/gpu/drm/i915/display/intel_dp.c   | 245 ++
 2 files changed, 200 insertions(+), 52 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH 3/5] drm/i915/dp: Fix DFP RGB->YCBCR conversion

2022-08-22 Thread Ankit Nautiyal
The decision to use DFP output format conversion capabilities should be
during compute_config phase.

This patch:
-uses the members of intel_dp->dfp to only store the
format conversion capabilities of the DP device.
-adds new members to crtc_state to help configure the DFP
output related conversions.
-pulls the decision making to use DFP conversion capabilities
for every mode during compute config.

Signed-off-by: Ankit Nautiyal 
---
 .../drm/i915/display/intel_display_types.h|  7 ++
 drivers/gpu/drm/i915/display/intel_dp.c   | 88 +++
 2 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 0da9b208d56e..065ed19a5dd3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1311,6 +1311,12 @@ struct intel_crtc_state {
 
/* for loading single buffered registers during vblank */
struct drm_vblank_work vblank_work;
+
+   /* DP DFP color configuration */
+   struct {
+   bool rgb_to_ycbcr;
+   bool ycbcr_444_to_420;
+   } dp_dfp_config;
 };
 
 enum intel_pipe_crc_source {
@@ -1704,6 +1710,7 @@ struct intel_dp {
int pcon_max_frl_bw;
u8 max_bpc;
bool ycbcr_444_to_420;
+   bool ycbcr420_passthrough;
bool rgb_to_ycbcr;
} dfp;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fc082a933d59..8ccbe591b9e2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1201,19 +1201,21 @@ static bool intel_dp_supports_dsc(struct intel_dp 
*intel_dp,
drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
 }
 
-static bool intel_dp_is_ycbcr420(struct intel_dp *intel_dp,
-const struct intel_crtc_state *crtc_state)
+static bool intel_dp_is_ycbcr420(const struct intel_crtc_state *crtc_state)
 {
return crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
(crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&
-intel_dp->dfp.ycbcr_444_to_420);
+crtc_state->dp_dfp_config.ycbcr_444_to_420) ||
+   (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB &&
+crtc_state->dp_dfp_config.ycbcr_444_to_420 &&
+crtc_state->dp_dfp_config.rgb_to_ycbcr);
 }
 
 static int intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp,
 const struct intel_crtc_state *crtc_state,
 int bpc, bool respect_downstream_limits)
 {
-   bool ycbcr420_output = intel_dp_is_ycbcr420(intel_dp, crtc_state);
+   bool ycbcr420_output = intel_dp_is_ycbcr420(crtc_state);
int clock = crtc_state->hw.adjusted_mode.crtc_clock;
 
/*
@@ -1966,6 +1968,30 @@ static bool intel_dp_has_audio(struct intel_encoder 
*encoder,
return intel_conn_state->force_audio == HDMI_AUDIO_ON;
 }
 
+static void
+intel_dp_compute_dfp_ycbcr420(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state)
+{
+   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+   if (!drm_dp_is_branch(intel_dp->dpcd))
+   return;
+
+   /* Mode is YCBCR420, output_format is also YCBCR420: Passthrough */
+   if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   return;
+
+   /* Mode is YCBCR420, output_format is YCBCR444: Downsample */
+   if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) {
+   crtc_state->dp_dfp_config.ycbcr_444_to_420 = true;
+   return;
+   }
+
+   /* Mode is YCBCR420, output_format is RGB: Convert to YCBCR444 and 
Downsample */
+   crtc_state->dp_dfp_config.rgb_to_ycbcr = true;
+   crtc_state->dp_dfp_config.ycbcr_444_to_420 = true;
+}
+
 static int
 intel_dp_compute_output_format(struct intel_encoder *encoder,
   struct intel_crtc_state *crtc_state,
@@ -1984,7 +2010,10 @@ intel_dp_compute_output_format(struct intel_encoder 
*encoder,
 
crtc_state->output_format = intel_dp_output_format(connector, 
ycbcr_420_only);
 
-   if (ycbcr_420_only && !intel_dp_is_ycbcr420(intel_dp, crtc_state)) {
+   if (ycbcr_420_only)
+   intel_dp_compute_dfp_ycbcr420(encoder, crtc_state);
+
+   if (ycbcr_420_only && !intel_dp_is_ycbcr420(crtc_state)) {
drm_dbg_kms(&i915->drm,
"YCbCr 4:2:0 mode but YCbCr 4:2:0 output not 
possible. Falling back to RGB.\n");
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
@@ -1993,12 +2022,13 @@ intel_dp_co

[Intel-gfx] [PATCH 1/5] drm/i915/dp: Add helper to check DSC1.2 for HDMI2.1 DFP

2022-08-22 Thread Ankit Nautiyal
Add helper function to check if Downstream HDMI 2.1 sink supports
DSC1.2.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 32292c0be2bd..fdf82373a22d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -118,6 +118,15 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
 static void intel_dp_unset_edid(struct intel_dp *intel_dp);
 static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
 
+static bool
+is_dfp_hdmi_sink_dsc_1_2(struct intel_dp *intel_dp)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+
+   return connector->display_info.hdmi.dsc_cap.v_1p2;
+}
+
 /* Is link rate UHBR and thus 128b/132b? */
 bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state)
 {
@@ -2393,7 +2402,7 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
max_frl_rate = max_lanes * rate_per_lane;
 
-   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
+   if (is_dfp_hdmi_sink_dsc_1_2(intel_dp)) {
max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
if (max_dsc_lanes && dsc_rate_per_lane)
@@ -2605,7 +2614,7 @@ intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
if (!intel_connector)
return;
connector = &intel_connector->base;
-   hdmi_is_dsc_1_2 = connector->display_info.hdmi.dsc_cap.v_1p2;
+   hdmi_is_dsc_1_2 = is_dfp_hdmi_sink_dsc_1_2(intel_dp);
 
if (!drm_dp_pcon_enc_is_dsc_1_2(intel_dp->pcon_dsc_dpcd) ||
!hdmi_is_dsc_1_2)
-- 
2.25.1



[Intel-gfx] [PATCH 4/5] drm/i915/dp: Handle BPP where HDMI2.1 DFP doesn't support DSC

2022-08-22 Thread Ankit Nautiyal
Currently we use the highest input BPC supported by DP sink while using
DSC.In cases where PCON with HDMI2.1 as branch device, if PCON supports
DSC but HDMI2.1 sink does not supports DSC, The PCON tries to use same
input BPC that is used between Source and the PCON without DSC, which
might not work even with the maximum FRL rate supported by HDMI2.1
sink.

This patch calculates the max BPC that can be sufficient with either
RGB or YCBCR420 format for the maximum FRL rate supported.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 90 -
 1 file changed, 89 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 8ccbe591b9e2..f0a62f71904e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -117,6 +117,7 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
 
 static void intel_dp_unset_edid(struct intel_dp *intel_dp);
 static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
+static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp);
 
 static bool
 is_dfp_hdmi_sink_dsc_1_2(struct intel_dp *intel_dp)
@@ -1455,6 +1456,74 @@ static int intel_dp_dsc_compute_params(struct 
intel_encoder *encoder,
return drm_dsc_compute_rc_parameters(vdsc_cfg);
 }
 
+static int
+_intel_dp_pcon_hdmi21_get_bpp_nodsc(struct intel_dp *intel_dp,
+   const struct drm_display_mode 
*adjusted_mode,
+   int max_bpc, bool is_ycbcr420)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+   int i, num_bpc;
+   u8 dsc_bpc[3] = {0};
+   int req_rate_gbps;
+   int max_frl_rate = connector->display_info.hdmi.max_lanes *
+  connector->display_info.hdmi.max_frl_rate_per_lane;
+
+   /*
+* Currently DSC with Ycbcr420 is not supported. So for modes with 
Ycbcr420,
+* DSC will use RGB and support for RGB->YCBCR444->YCBCR420 conversion 
is
+* required from DP HDMI2.1 PCON.
+*/
+   if (is_ycbcr420 && !(intel_dp->dfp.rgb_to_ycbcr || 
intel_dp->dfp.ycbcr_444_to_420))
+   return 0;
+
+   num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
+  dsc_bpc);
+   for (i = 0; i < num_bpc; i++) {
+   if (dsc_bpc[i] > max_bpc)
+   continue;
+
+   req_rate_gbps = DIV_ROUND_UP(dsc_bpc[i] * 3 * 
adjusted_mode->clock, 100);
+
+   /* YCBCR420 reduces data rate by 2 */
+   if (is_ycbcr420)
+   req_rate_gbps /= 2;
+
+   if (req_rate_gbps < max_frl_rate)
+   return dsc_bpc[i] * 3;
+   }
+
+   return 0;
+}
+
+static int
+intel_dp_pcon_hdmi21_get_bpp_nodsc(struct intel_dp *intel_dp,
+  struct intel_crtc_state *pipe_config,
+  int max_bpc)
+{
+   const struct drm_display_mode *adjusted_mode =
+   &pipe_config->hw.adjusted_mode;
+   struct intel_connector *connector = intel_dp->attached_connector;
+   const struct drm_display_info *info = &connector->base.display_info;
+   bool is_ycbcr420 = drm_mode_is_420_only(info, adjusted_mode);
+   int pipe_bpp;
+
+   pipe_bpp = _intel_dp_pcon_hdmi21_get_bpp_nodsc(intel_dp, adjusted_mode,
+  max_bpc, is_ycbcr420);
+   if (!pipe_bpp && !is_ycbcr420 && drm_mode_is_420_also(info, 
adjusted_mode)) {
+   is_ycbcr420 = true;
+   pipe_bpp = _intel_dp_pcon_hdmi21_get_bpp_nodsc(intel_dp, 
adjusted_mode,
+  max_bpc, 
is_ycbcr420);
+   }
+
+   if (!pipe_bpp && is_ycbcr420) {
+   pipe_config->dp_dfp_config.rgb_to_ycbcr = true;
+   pipe_config->dp_dfp_config.ycbcr_444_to_420 = true;
+   }
+
+   return pipe_bpp;
+}
+
 static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
   struct intel_crtc_state *pipe_config,
   struct drm_connector_state *conn_state,
@@ -1473,7 +1542,26 @@ static int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_supports_dsc(intel_dp, pipe_config))
return -EINVAL;
 
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, 
conn_state->max_requested_bpc);
+   /*
+* In cases where PCON with HDMI2.1 as branch device, if PCON supports
+* DSC but HDMI2.1 sink does not supports DSC, The PCON tries to use 
same
+* input DSC bpc that is used between S

[Intel-gfx] [PATCH 2/5] drm/i915/dp: Reset frl trained flag before restarting FRL training

2022-08-22 Thread Ankit Nautiyal
For cases where DP has HDMI2.1 sink and FRL Link issues are detected,
reset the flag to state FRL trained status before restarting FRL
training.

Fixes: 9488a030ac91 ("drm/i915: Add support for enabling link status and 
recovery")
Cc: Swati Sharma 
Cc: Ankit Nautiyal 
Cc: Uma Shankar  (v2)
Cc: Jani Nikula 

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fdf82373a22d..fc082a933d59 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3957,6 +3957,8 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp 
*intel_dp)
 
drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, 
&intel_dp->attached_connector->base);
 
+   intel_dp->frl.is_trained = false;
+
/* Restart FRL training or fall back to TMDS mode */
intel_dp_check_frl_training(intel_dp);
}
-- 
2.25.1



[Intel-gfx] [PATCH 5/5] drm/i915/dp: Fix FRL BW check for HDMI2.1 DFP

2022-08-22 Thread Ankit Nautiyal
During FRL bandwidth  check for downstream HDMI2.1 sink,
the min BPC supported is incorrectly taken for DP, and the check does
not consider ybcr420 only modes.
This patch fixes the bandwidth calculation similar to the TMDS case, by
taking min 8Bpc and considering Ycbcr420 only modes.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 52 ++---
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f0a62f71904e..7f24f7633078 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -118,6 +118,7 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
 static void intel_dp_unset_edid(struct intel_dp *intel_dp);
 static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
 static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp);
+static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp);
 
 static bool
 is_dfp_hdmi_sink_dsc_1_2(struct intel_dp *intel_dp)
@@ -917,6 +918,32 @@ intel_dp_tmds_clock_valid(struct intel_dp *intel_dp,
return MODE_OK;
 }
 
+static int
+intel_dp_frl_bw_valid(struct intel_dp *intel_dp, int target_clock,
+ int bpc, bool ycbcr_420_only)
+{
+   int target_bw;
+   int max_frl_bw;
+   int bpp = bpc * 3;
+
+   if (ycbcr_420_only)
+   target_clock /= 2;
+
+   target_bw = bpp * target_clock;
+
+   /* check for MAX FRL BW for both PCON and HDMI2.1 sink */
+   max_frl_bw = min(intel_dp->dfp.pcon_max_frl_bw,
+intel_dp_hdmi_sink_max_frl(intel_dp));
+
+   /* converting bw from Gbps to Kbps*/
+   max_frl_bw = max_frl_bw * 100;
+
+   if (target_bw > max_frl_bw)
+   return MODE_CLOCK_HIGH;
+
+   return MODE_OK;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid_downstream(struct intel_connector *connector,
   const struct drm_display_mode *mode,
@@ -925,23 +952,24 @@ intel_dp_mode_valid_downstream(struct intel_connector 
*connector,
struct intel_dp *intel_dp = intel_attached_dp(connector);
const struct drm_display_info *info = &connector->base.display_info;
enum drm_mode_status status;
-   bool ycbcr_420_only;
+   bool ycbcr_420_only = drm_mode_is_420_only(info, mode);
 
/* If PCON supports FRL MODE, check FRL bandwidth constraints */
if (intel_dp->dfp.pcon_max_frl_bw) {
-   int target_bw;
-   int max_frl_bw;
-   int bpp = intel_dp_mode_min_output_bpp(connector, mode);
-
-   target_bw = bpp * target_clock;
 
-   max_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
+   /* Assume 8bpc for the HDMI2.1 FRL BW check */
+   status = intel_dp_frl_bw_valid(intel_dp, target_clock, 8, 
ycbcr_420_only);
 
-   /* converting bw from Gbps to Kbps*/
-   max_frl_bw = max_frl_bw * 100;
+   if (status != MODE_OK) {
+   if (ycbcr_420_only ||
+   !connector->base.ycbcr_420_allowed ||
+   !drm_mode_is_420_also(info, mode))
+   return status;
 
-   if (target_bw > max_frl_bw)
-   return MODE_CLOCK_HIGH;
+   status = intel_dp_frl_bw_valid(intel_dp, target_clock, 
8, true);
+   if (status != MODE_OK)
+   return status;
+   }
 
return MODE_OK;
}
@@ -950,8 +978,6 @@ intel_dp_mode_valid_downstream(struct intel_connector 
*connector,
target_clock > intel_dp->dfp.max_dotclock)
return MODE_CLOCK_HIGH;
 
-   ycbcr_420_only = drm_mode_is_420_only(info, mode);
-
/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
status = intel_dp_tmds_clock_valid(intel_dp, target_clock,
   8, ycbcr_420_only, true);
-- 
2.25.1



[Intel-gfx] [PATCH] drm/i915/combo_phy: Set DCC_MODE to one time update mode

2022-08-22 Thread Ankit Nautiyal
As per Bspec:49291 update, the DCC Mode select is to be set to one time
update mode, instead of continuous DCC calibration mode for Display > 12
combo phy.

This change is required to avoid glitches that occur, during on the fly
updates to DCC code, with continuous mode, resulting in flickers seen with
eDP HBR3 panels.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_combo_phy.c  | 4 ++--
 drivers/gpu/drm/i915/display/intel_combo_phy_regs.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c 
b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 64890f39c3cc..76e4e748823a 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -244,7 +244,7 @@ static bool icl_combo_phy_verify_state(struct 
drm_i915_private *dev_priv,
 
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_PCS_DW1_LN(0, phy),
 DCC_MODE_SELECT_MASK,
-DCC_MODE_SELECT_CONTINUOSLY);
+DCC_MODE_SELECT_ONCE);
}
 
ret &= icl_verify_procmon_ref_values(dev_priv, phy);
@@ -367,7 +367,7 @@ static void icl_combo_phys_init(struct drm_i915_private 
*dev_priv)
 
val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, 
phy));
val &= ~DCC_MODE_SELECT_MASK;
-   val |= DCC_MODE_SELECT_CONTINUOSLY;
+   val |= DCC_MODE_SELECT_ONCE;
intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), 
val);
}
 
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h 
b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
index 2ed65193ca19..cf46f13401d1 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy_regs.h
@@ -92,6 +92,7 @@
 #define ICL_PORT_PCS_DW1_LN(ln, phy)   _MMIO(_ICL_PORT_PCS_DW_LN(1, 
ln, phy))
 #define   DCC_MODE_SELECT_MASK (0x3 << 20)
 #define   DCC_MODE_SELECT_CONTINUOSLY  (0x3 << 20)
+#define   DCC_MODE_SELECT_ONCE (0x0 << 20)
 #define   COMMON_KEEPER_EN (1 << 26)
 #define   LATENCY_OPTIM_MASK   (0x3 << 2)
 #define   LATENCY_OPTIM_VAL(x) ((x) << 2)
-- 
2.25.1



[Intel-gfx] [PATCH v2 2/2] drm/i915/dp: For PCON TMDS mode set only the relavant bits in config DPCD

2021-11-07 Thread Ankit Nautiyal
Currently we reset the whole PCON linkConfig DPCD to set the TMDS mode.
This also resets the Source control bit and HDMI link enable bit and
goes to autonomous mode of operation, which is seen to spoil the PCONs
internal state.

This patch avoids resetting the PCON link config register and sets only
the source control bit, with FRL Enable bit set to 0 (TMDS mode) in the
configuration DPCD. It then enables the HDMI Link Enable bit.

v2: Removed the redundant resetting of the bits as the buffer is already
initialized to 0. (Uma)
Updated comments and commit message.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 24 +++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f5fd106e555c..a0ff16bc18f5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2287,6 +2287,28 @@ static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp 
*intel_dp)
return false;
 }
 
+static
+int intel_dp_pcon_set_tmds_mode(struct intel_dp *intel_dp)
+{
+   int ret;
+   u8 buf = 0;
+
+   /* Set PCON source control mode */
+   buf |= DP_PCON_ENABLE_SOURCE_CTL_MODE;
+
+   ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, 
buf);
+   if (ret < 0)
+   return ret;
+
+   /* Set HDMI LINK ENABLE */
+   buf |= DP_PCON_ENABLE_HDMI_LINK;
+   ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, 
buf);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+
 void intel_dp_check_frl_training(struct intel_dp *intel_dp)
 {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -2305,7 +2327,7 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
int ret, mode;
 
drm_dbg(&dev_priv->drm, "Couldn't set FRL mode, continuing with 
TMDS mode\n");
-   ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);
+   ret = intel_dp_pcon_set_tmds_mode(intel_dp);
mode = drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, NULL);
 
if (ret < 0 || mode != DP_PCON_HDMI_MODE_TMDS)
-- 
2.25.1



[Intel-gfx] [PATCH v3 0/2] Some fixes in HDMI2.1 PCON FRL configuration

2021-11-09 Thread Ankit Nautiyal
Some optimizations in HDMI2.1 PCON configuration and avoiding
resetting the config DPCD.
v2: Addressed comments from Uma.
v3: Rebased.

Ankit Nautiyal (2):
  drm/i915/dp: Optimize the FRL configuration for HDMI2.1 PCON
  drm/i915/dp: For PCON TMDS mode set only the relavant bits in config
DPCD

 drivers/gpu/drm/i915/display/intel_dp.c | 61 +++--
 1 file changed, 46 insertions(+), 15 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH v3 1/2] drm/i915/dp: Optimize the FRL configuration for HDMI2.1 PCON

2021-11-09 Thread Ankit Nautiyal
Currently the HDMI2.1 PCON's frl link config DPCD registers are
reset and configured even if they are already configured.
Also the HDMI Link Mode does not settle to FRL MODE immediately after
HDMI Link Status is active.

This patch:
-Checks if the PCON is already configured for FRL.
-Include HDMI Link Mode in wait for loop along with HDMI Link status DPCD.

v2: Rebase

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 45373c213d9e..020c357348b2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2198,6 +2198,18 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
return max_frl_rate;
 }
 
+static bool
+intel_dp_pcon_is_frl_trained(struct intel_dp *intel_dp,
+u8 max_frl_bw_mask, u8 *frl_trained_mask)
+{
+   if (drm_dp_pcon_hdmi_link_active(&intel_dp->aux) &&
+   drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, frl_trained_mask) == 
DP_PCON_HDMI_MODE_FRL &&
+   *frl_trained_mask >= max_frl_bw_mask)
+   return true;
+
+   return false;
+}
+
 static int intel_dp_pcon_start_frl_training(struct intel_dp *intel_dp)
 {
 #define TIMEOUT_FRL_READY_MS 500
@@ -2208,10 +2220,6 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
u8 max_frl_bw_mask = 0, frl_trained_mask;
bool is_active;
 
-   ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);
-   if (ret < 0)
-   return ret;
-
max_pcon_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
drm_dbg(&i915->drm, "PCON max rate = %d Gbps\n", max_pcon_frl_bw);
 
@@ -2223,6 +2231,12 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
if (max_frl_bw <= 0)
return -EINVAL;
 
+   max_frl_bw_mask = intel_dp_pcon_set_frl_mask(max_frl_bw);
+   drm_dbg(&i915->drm, "MAX_FRL_BW_MASK = %u\n", max_frl_bw_mask);
+
+   if (intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, 
&frl_trained_mask))
+   goto frl_trained;
+
ret = drm_dp_pcon_frl_prepare(&intel_dp->aux, false);
if (ret < 0)
return ret;
@@ -2232,7 +2246,6 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
if (!is_active)
return -ETIMEDOUT;
 
-   max_frl_bw_mask = intel_dp_pcon_set_frl_mask(max_frl_bw);
ret = drm_dp_pcon_frl_configure_1(&intel_dp->aux, max_frl_bw,
  DP_PCON_ENABLE_SEQUENTIAL_LINK);
if (ret < 0)
@@ -2248,19 +2261,15 @@ static int intel_dp_pcon_start_frl_training(struct 
intel_dp *intel_dp)
 * Wait for FRL to be completed
 * Check if the HDMI Link is up and active.
 */
-   wait_for(is_active = drm_dp_pcon_hdmi_link_active(&intel_dp->aux) == 
true, TIMEOUT_HDMI_LINK_ACTIVE_MS);
+   wait_for(is_active =
+intel_dp_pcon_is_frl_trained(intel_dp, max_frl_bw_mask, 
&frl_trained_mask),
+TIMEOUT_HDMI_LINK_ACTIVE_MS);
 
if (!is_active)
return -ETIMEDOUT;
 
-   /* Verify HDMI Link configuration shows FRL Mode */
-   if (drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, &frl_trained_mask) !=
-   DP_PCON_HDMI_MODE_FRL) {
-   drm_dbg(&i915->drm, "HDMI couldn't be trained in FRL Mode\n");
-   return -EINVAL;
-   }
-   drm_dbg(&i915->drm, "MAX_FRL_MASK = %u, FRL_TRAINED_MASK = %u\n", 
max_frl_bw_mask, frl_trained_mask);
-
+frl_trained:
+   drm_dbg(&i915->drm, "FRL_TRAINED_MASK = %u\n", frl_trained_mask);
intel_dp->frl.trained_rate_gbps = 
intel_dp_pcon_get_frl_mask(frl_trained_mask);
intel_dp->frl.is_trained = true;
drm_dbg(&i915->drm, "FRL trained with : %d Gbps\n", 
intel_dp->frl.trained_rate_gbps);
-- 
2.25.1



[Intel-gfx] [PATCH v3 2/2] drm/i915/dp: For PCON TMDS mode set only the relavant bits in config DPCD

2021-11-09 Thread Ankit Nautiyal
Currently we reset the whole PCON linkConfig DPCD to set the TMDS mode.
This also resets the Source control bit and HDMI link enable bit and
goes to autonomous mode of operation, which is seen to spoil the PCONs
internal state.

This patch avoids resetting the PCON link config register and sets only
the source control bit, with FRL Enable bit set to 0 (TMDS mode) in the
configuration DPCD. It then enables the HDMI Link Enable bit.

v2: Removed the redundant resetting of the bits as the buffer is already
initialized to 0. (Uma)
Updated comments and commit message.

v3: Rebase

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Uma Shankar 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 24 +++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 020c357348b2..0a424bf69396 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2287,6 +2287,28 @@ static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp 
*intel_dp)
return false;
 }
 
+static
+int intel_dp_pcon_set_tmds_mode(struct intel_dp *intel_dp)
+{
+   int ret;
+   u8 buf = 0;
+
+   /* Set PCON source control mode */
+   buf |= DP_PCON_ENABLE_SOURCE_CTL_MODE;
+
+   ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, 
buf);
+   if (ret < 0)
+   return ret;
+
+   /* Set HDMI LINK ENABLE */
+   buf |= DP_PCON_ENABLE_HDMI_LINK;
+   ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, 
buf);
+   if (ret < 0)
+   return ret;
+
+   return 0;
+}
+
 void intel_dp_check_frl_training(struct intel_dp *intel_dp)
 {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -2305,7 +2327,7 @@ void intel_dp_check_frl_training(struct intel_dp 
*intel_dp)
int ret, mode;
 
drm_dbg(&dev_priv->drm, "Couldn't set FRL mode, continuing with 
TMDS mode\n");
-   ret = drm_dp_pcon_reset_frl_config(&intel_dp->aux);
+   ret = intel_dp_pcon_set_tmds_mode(intel_dp);
mode = drm_dp_pcon_hdmi_link_mode(&intel_dp->aux, NULL);
 
if (ret < 0 || mode != DP_PCON_HDMI_MODE_TMDS)
-- 
2.25.1



[Intel-gfx] [RFC v3 4/5] drm/hdmi21: Add support for DFM calculation with DSC

2022-02-16 Thread Ankit Nautiyal
Add helper functions for calculating FRL capacity and DFM
requirements with given compressed bpp.

v2: Fixed:
-Build warnings/errors: Removed unused variables.
-Checkpatch warnings.

Signed-off-by: Ankit Nautiyal 
Signed-off-by: Vandita Kulkarni 
---
 drivers/gpu/drm/drm_frl_dfm_helper.c | 303 +++
 include/drm/drm_frl_dfm_helper.h |   3 +
 2 files changed, 306 insertions(+)

diff --git a/drivers/gpu/drm/drm_frl_dfm_helper.c 
b/drivers/gpu/drm/drm_frl_dfm_helper.c
index b8f4f8ee50d3..95de7a6978a2 100644
--- a/drivers/gpu/drm/drm_frl_dfm_helper.c
+++ b/drivers/gpu/drm/drm_frl_dfm_helper.c
@@ -555,3 +555,306 @@ drm_frl_dfm_nondsc_requirement_met(struct 
drm_hdmi_frl_dfm *frl_dfm)
return false;
 }
 EXPORT_SYMBOL(drm_frl_dfm_nondsc_requirement_met);
+
+/* DSC DFM functions */
+/* Get FRL Available characters */
+static u32
+drm_get_frl_available_chars(u32 overhead_max, u32 cfrl_line)
+{
+   u32 frl_char_avlb = ((EFFICIENCY_MULTIPLIER - overhead_max) * 
cfrl_line);
+
+   return frl_char_avlb / EFFICIENCY_MULTIPLIER;
+}
+
+/* Get required no. of tribytes during HCActive */
+static u32
+drm_get_frl_hcactive_tb_target(u32 dsc_bpp_x16, u32 slice_width, u32 
num_slices)
+{
+   u32 bytes_target;
+
+   bytes_target = num_slices * DIV_ROUND_UP(dsc_bpp_x16 * slice_width,
+8 * BPP_MULTIPLIER);
+
+   return DIV_ROUND_UP(bytes_target, 3);
+}
+
+/* Get required no. of tribytes (estimate1) during HCBlank */
+static u32
+drm_get_frl_hcblank_tb_est1_target(u32 hcactive_target_tb,
+  u32 hactive, u32 hblank)
+{
+   return DIV_ROUND_UP(hcactive_target_tb * hblank, hactive);
+}
+
+/* Get required no. of tribytes during HCBlank */
+static u32
+drm_get_frl_hcblank_tb_target(u32 hcactive_target_tb, u32 hactive, u32 hblank,
+ u32 hcblank_audio_min, u32 cfrl_available)
+{
+   u32 hcblank_target_tb1 = 
drm_get_frl_hcblank_tb_est1_target(hcactive_target_tb,
+   hactive, 
hblank);
+   u32 hcblank_target_tb2 = max(hcblank_target_tb1, hcblank_audio_min);
+
+   return 4 * (min(hcblank_target_tb2,
+   (2 * cfrl_available - 3 * hcactive_target_tb) / 2) / 4);
+}
+
+/* Get the avg no of tribytes sent per sec (Kbps) */
+static u32
+drm_frl_dsc_get_ftb_avg(u32 hcactive_target_tb, u32 hcblank_target_tb,
+   u32 hactive, u32 hblank,
+   u32 fpixelclock_max_khz)
+{
+   return (hcactive_target_tb + hcblank_target_tb) *
+  (fpixelclock_max_khz / (hactive + hblank));
+}
+
+/* Time to send Active tribytes in nanoseconds */
+static u32
+drm_frl_dsc_get_tactive_ref_ns(u32 line_time_ns, u32 hactive, u32 hblank)
+{
+   return (line_time_ns * hactive) / (hactive + hblank);
+}
+
+/* Time to send Blanking tribytes in nanoseconds  */
+static u32
+drm_frl_dsc_get_tblank_ref_ns(u32 line_time_ns, u32 hactive, u32 hblank)
+{
+   return (line_time_ns * hblank) / (hactive + hblank);
+}
+
+/* Get time to send all tribytes in hcactive region in nsec*/
+static u32
+drm_frl_dsc_tactive_target_ns(u32 frl_lanes, u32 hcactive_target_tb, u32 
ftb_avg_k,
+ u32 min_frl_char_rate_k, u32 overhead_max)
+{
+   u32 avg_tribyte_time_ns, tribyte_time_ns;
+   u32 num_chars_hcactive;
+   u32 frl_char_rate_k;
+
+   /* Avg time to transmit all active region tribytes */
+   avg_tribyte_time_ns = (hcactive_target_tb * FRL_TIMING_NS_MULTIPLIER) /
+ (ftb_avg_k * 1000);
+
+   /*
+* 2 bytes in active region = 1 FRL characters
+* 1 Tribyte in active region = 3/2 FRL characters
+*/
+
+   num_chars_hcactive = (hcactive_target_tb * 3) / 2;
+
+   /*
+* FRL rate = lanes * frl character rate
+* But actual bandwidth wil be less, due to FRL limitations so account
+* for the overhead involved.
+* FRL rate with overhead = FRL rate * (100 - overhead %) / 100
+*/
+   frl_char_rate_k = frl_lanes * min_frl_char_rate_k;
+   frl_char_rate_k = (frl_char_rate_k * (EFFICIENCY_MULTIPLIER - 
overhead_max)) /
+ EFFICIENCY_MULTIPLIER;
+
+   /* Time to transmit all characters with FRL limitations */
+   tribyte_time_ns = (num_chars_hcactive * FRL_TIMING_NS_MULTIPLIER) /
+ frl_char_rate_k * 1000;
+
+   return max(avg_tribyte_time_ns, tribyte_time_ns);
+}
+
+/* Get no. of tri bytes borrowed with DSC enabled */
+static u32
+drm_frl_get_dsc_tri_bytes_borrowed(u32 tactive_target_ns, u32 ftb_avg_k,
+  u32 hcactive_target_tb)
+{
+   return (tactive_target_ns * FRL_TIMING_NS_MULTIPLIER * ftb_avg_k * 
1000) -
+   hcactive_target_tb;
+}
+
+/* Get TBdelta : borrowing in tribytes relative to avg tribyte rate */
+static u32

[Intel-gfx] [PATCH 0/3] Minor Fixes and Refactoring for HDMI PCON stuff

2022-01-25 Thread Ankit Nautiyal
Misc fixes and refactoring in HDMI2.1 PCON helper functions.

Ankit Nautiyal (3):
  drm/i915_hdmi: Fix the definition of intel_hdmi_dsc_get_bpp
  drm/drm_edid: Add helper to get max FRL rate for an HDMI sink
  drm/i915/display: Simplify helpers for getting DSC slices and bpp

 drivers/gpu/drm/drm_edid.c| 38 +++
 drivers/gpu/drm/i915/display/intel_dp.c   | 26 ++--
 drivers/gpu/drm/i915/display/intel_hdmi.c | 26 +---
 drivers/gpu/drm/i915/display/intel_hdmi.h |  8 +++--
 include/drm/drm_edid.h|  2 ++
 5 files changed, 69 insertions(+), 31 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH 1/3] drm/i915_hdmi: Fix the definition of intel_hdmi_dsc_get_bpp

2022-01-25 Thread Ankit Nautiyal
Fix the data-type of the argument output_format to enum, for the
function intel_hdmi_dsc_get_bpp.

Fixes: 6e6cb758e035 ("drm/i915: Add helper functions for calculating DSC
parameters for HDMI2.1")

Cc: Ankit Nautiyal 
Cc: Uma Shankar 
Cc: Jani Nikula 
Cc: "Ville Syrj_l_" 
Cc: "Jos_ Roberto de Souza" 
Cc: Matt Roper 
Cc: Radhakrishna Sripada 
Cc: Lucas De Marchi 
Cc: Lyude Paul 
Cc: Werner Sembach 
Cc: Aditya Swarup 
Cc: Daniel Vetter 
Cc:  # v5.12+

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_hdmi.c | 4 ++--
 drivers/gpu/drm/i915/display/intel_hdmi.h | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 45cf0ab04009..381a9de3a015 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3126,8 +3126,8 @@ intel_hdmi_dsc_get_num_slices(const struct 
intel_crtc_state *crtc_state,
  */
 int
 intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, int num_slices,
-  int output_format, bool hdmi_all_bpp,
-  int hdmi_max_chunk_bytes)
+  enum intel_output_format output_format,
+  bool hdmi_all_bpp, int hdmi_max_chunk_bytes)
 {
int max_dsc_bpp, min_dsc_bpp;
int target_bytes;
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h 
b/drivers/gpu/drm/i915/display/intel_hdmi.h
index b577c38fa90c..fe40e49d2962 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -10,6 +10,7 @@
 #include 
 
 #include "i915_reg.h"
+#include "intel_display_types.h"
 
 struct drm_connector;
 struct drm_encoder;
@@ -49,8 +50,8 @@ bool intel_hdmi_limited_color_range(const struct 
intel_crtc_state *crtc_state,
 bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
 int bpc, bool has_hdmi_sink, bool ycbcr420_output);
 int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width,
-  int num_slices, int output_format, bool hdmi_all_bpp,
-  int hdmi_max_chunk_bytes);
+  int num_slices, enum intel_output_format 
output_format,
+  bool hdmi_all_bpp, int hdmi_max_chunk_bytes);
 int intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
  int src_max_slices, int src_max_slice_width,
  int hdmi_max_slices, int hdmi_throughput);
-- 
2.25.1



[Intel-gfx] [PATCH 3/3] drm/i915/display: Simplify helpers for getting DSC slices and bpp

2022-01-25 Thread Ankit Nautiyal
Genralize the helper for getting DSC slice count and compressed bpp
for HDMI sink supporting DSC.
This patch:
-Removes the assumption on the bpc and sends it as an argument for
calculating compressed bpc.
-Sends the resolution, and output format as parameters for which the
DSC paremeters are to be calculated instead of crtc_state.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c   |  7 +--
 drivers/gpu/drm/i915/display/intel_hdmi.c | 24 ---
 drivers/gpu/drm/i915/display/intel_hdmi.h |  5 +++--
 3 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f7fe7de7e553..17d08f06499b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2357,7 +2357,9 @@ intel_dp_pcon_dsc_enc_slices(struct intel_dp *intel_dp,
int pcon_max_slices = 
drm_dp_pcon_dsc_max_slices(intel_dp->pcon_dsc_dpcd);
int pcon_max_slice_width = 
drm_dp_pcon_dsc_max_slice_width(intel_dp->pcon_dsc_dpcd);
 
-   return intel_hdmi_dsc_get_num_slices(crtc_state, pcon_max_slices,
+   return intel_hdmi_dsc_get_num_slices(&crtc_state->hw.adjusted_mode,
+crtc_state->output_format,
+pcon_max_slices,
 pcon_max_slice_width,
 hdmi_max_slices, hdmi_throughput);
 }
@@ -2374,9 +2376,10 @@ intel_dp_pcon_dsc_enc_bpp(struct intel_dp *intel_dp,
int pcon_fractional_bpp = 
drm_dp_pcon_dsc_bpp_incr(intel_dp->pcon_dsc_dpcd);
int hdmi_max_chunk_bytes =
connector->display_info.hdmi.dsc_cap.total_chunk_kbytes * 1024;
+   int bpc = crtc_state->pipe_bpp / 3;
 
return intel_hdmi_dsc_get_bpp(pcon_fractional_bpp, slice_width,
- num_slices, output_format, hdmi_all_bpp,
+ num_slices, output_format, bpc, 
hdmi_all_bpp,
  hdmi_max_chunk_bytes);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 381a9de3a015..f75e2384da63 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3004,7 +3004,8 @@ int intel_hdmi_dsc_get_slice_height(int vactive)
  * intel_hdmi_dsc_get_num_slices - get no. of dsc slices based on dsc encoder
  * and dsc decoder capabilities
  *
- * @crtc_state: intel crtc_state
+ * @mode: drm_display_mode for which num of slices are needed
+ * @output_format : pipe output format
  * @src_max_slices: maximum slices supported by the DSC encoder
  * @src_max_slice_width: maximum slice width supported by DSC encoder
  * @hdmi_max_slices: maximum slices supported by sink DSC decoder
@@ -3014,7 +3015,8 @@ int intel_hdmi_dsc_get_slice_height(int vactive)
  * and decoder.
  */
 int
-intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
+intel_hdmi_dsc_get_num_slices(const struct drm_display_mode *mode,
+ enum intel_output_format output_format,
  int src_max_slices, int src_max_slice_width,
  int hdmi_max_slices, int hdmi_throughput)
 {
@@ -3036,7 +3038,7 @@ intel_hdmi_dsc_get_num_slices(const struct 
intel_crtc_state *crtc_state,
int max_throughput; /* max clock freq. in khz per slice */
int max_slice_width;
int slice_width;
-   int pixel_clock = crtc_state->hw.adjusted_mode.crtc_clock;
+   int pixel_clock = mode->crtc_clock;
 
if (!hdmi_throughput)
return 0;
@@ -3047,8 +3049,8 @@ intel_hdmi_dsc_get_num_slices(const struct 
intel_crtc_state *crtc_state,
 * for 4:4:4 is 1.0. Multiplying these factors by 10 and later
 * dividing adjusted clock value by 10.
 */
-   if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 ||
-   crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB)
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR444 ||
+   output_format == INTEL_OUTPUT_FORMAT_RGB)
kslice_adjust = 10;
else
kslice_adjust = 5;
@@ -3103,7 +3105,7 @@ intel_hdmi_dsc_get_num_slices(const struct 
intel_crtc_state *crtc_state,
else
return 0;
 
-   slice_width = 
DIV_ROUND_UP(crtc_state->hw.adjusted_mode.hdisplay, target_slices);
+   slice_width = DIV_ROUND_UP(mode->hdisplay, target_slices);
if (slice_width >= max_slice_width)
min_slices = target_slices + 1;
} while (slice_width >= max_slice_width);
@@ -3119,6 +3121,7 @@ intel_hdmi_dsc_get_num_slices(const struct 
intel_crtc_state *crtc_state,
  * @slice_width: dsc slice width support

[Intel-gfx] [PATCH 2/3] drm/drm_edid: Add helper to get max FRL rate for an HDMI sink

2022-01-25 Thread Ankit Nautiyal
Move the common function for getting the max FRL rate for an HDMI sink,
from intel_dp.c to drm/drm_edid.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c  | 38 +
 drivers/gpu/drm/i915/display/intel_dp.c | 19 -
 include/drm/drm_edid.h  |  2 ++
 3 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index eb61a1a92dc0..75b538b4c87f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6176,3 +6176,41 @@ void drm_update_tile_info(struct drm_connector 
*connector,
connector->tile_group = NULL;
}
 }
+
+/**
+ * drm_hdmi_sink_max_frl - get the max frl rate from HDMI2.1 sink
+ * @connector - connector with HDMI2.1 sink
+ *
+ * RETURNS:
+ * max frl rate supported by the HDMI2.1 sink, 0 if FRL not supported
+ */
+int drm_hdmi_sink_max_frl(struct drm_connector *connector)
+{
+   int max_lanes = connector->display_info.hdmi.max_lanes;
+   int rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
+
+   return max_lanes * rate_per_lane;
+}
+EXPORT_SYMBOL(drm_hdmi_sink_max_frl);
+
+/**
+ * drm_hdmi_sink_dsc_max_frl - get the max frl rate from HDMI2.1 sink
+ * with DSC1.2 compression.
+ * @connector - connector with HDMI2.1 sink
+ *
+ * RETURNS:
+ * max frl rate supported by the HDMI2.1 sink with DSC1.2, 0 if FRL not 
supported
+ */
+int drm_hdmi_sink_dsc_max_frl(struct drm_connector *connector)
+{
+   int max_dsc_lanes, dsc_rate_per_lane;
+
+   if (!connector->display_info.hdmi.dsc_cap.v_1p2)
+   return 0;
+
+   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
+   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
+
+   return max_dsc_lanes * dsc_rate_per_lane;
+}
+EXPORT_SYMBOL(drm_hdmi_sink_dsc_max_frl);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4d4579a301f6..f7fe7de7e553 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2190,22 +2190,13 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
 {
struct intel_connector *intel_connector = intel_dp->attached_connector;
struct drm_connector *connector = &intel_connector->base;
-   int max_frl_rate;
-   int max_lanes, rate_per_lane;
-   int max_dsc_lanes, dsc_rate_per_lane;
+   int max_frl = drm_hdmi_sink_max_frl(connector);
+   int dsc_max_frl = drm_hdmi_sink_dsc_max_frl(connector);
 
-   max_lanes = connector->display_info.hdmi.max_lanes;
-   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
-   max_frl_rate = max_lanes * rate_per_lane;
+   if (dsc_max_frl)
+   return min(max_frl, dsc_max_frl);
 
-   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
-   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
-   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
-   if (max_dsc_lanes && dsc_rate_per_lane)
-   max_frl_rate = min(max_frl_rate, max_dsc_lanes * 
dsc_rate_per_lane);
-   }
-
-   return max_frl_rate;
+   return max_frl;
 }
 
 static bool
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 18f6c700f6d0..5003e1254c44 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -592,6 +592,8 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
  u8 video_code);
 const u8 *drm_find_edid_extension(const struct edid *edid,
  int ext_id, int *ext_index);
+int drm_hdmi_sink_max_frl(struct drm_connector *connector);
+int drm_hdmi_sink_dsc_max_frl(struct drm_connector *connector);
 
 
 #endif /* __DRM_EDID_H__ */
-- 
2.25.1



[Intel-gfx] [PATCH v2 0/4] Minor Fixes and Refactoring for HDMI PCON stuff

2022-01-31 Thread Ankit Nautiyal
Misc fixes and refactoring in HDMI2.1 PCON helper functions.
V2:
Addressed review comments from Jani.
Splitted the drm_helper addition and usage in separate patches.

Ankit Nautiyal (4):
  drm/i915/hdmi: Fix the definition of intel_hdmi_dsc_get_bpp
  drm/edid: Add helper to get max FRL rate for an HDMI sink
  drm/i915/dp: Use the drm helpers for getting max FRL rate
  drm/i915/display: Simplify helpers for getting DSC slices and bpp

 drivers/gpu/drm/drm_edid.c| 38 +++
 drivers/gpu/drm/i915/display/intel_dp.c   | 26 ++--
 drivers/gpu/drm/i915/display/intel_hdmi.c | 26 +---
 drivers/gpu/drm/i915/display/intel_hdmi.h |  9 --
 include/drm/drm_edid.h|  2 ++
 5 files changed, 70 insertions(+), 31 deletions(-)

-- 
2.25.1



[Intel-gfx] [PATCH v2 2/4] drm/edid: Add helper to get max FRL rate for an HDMI sink

2022-01-31 Thread Ankit Nautiyal
Add the helpers for getting the max FRL rate with and without DSC
for an HDMI sink.

v2: Fix the subject line and documentation of the helpers (Jani).
Split the helper definitions and usage into separate patches. (Jani).

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/drm_edid.c | 38 ++
 include/drm/drm_edid.h |  2 ++
 2 files changed, 40 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index eb61a1a92dc0..c209fd6b24a2 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6176,3 +6176,41 @@ void drm_update_tile_info(struct drm_connector 
*connector,
connector->tile_group = NULL;
}
 }
+
+/**
+ * drm_hdmi_sink_max_frl - get the max frl rate, if supported
+ * @connector - connector with HDMI sink
+ *
+ * RETURNS:
+ * max frl rate supported by the HDMI sink, 0 if FRL not supported
+ */
+int drm_hdmi_sink_max_frl(struct drm_connector *connector)
+{
+   int max_lanes = connector->display_info.hdmi.max_lanes;
+   int rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
+
+   return max_lanes * rate_per_lane;
+}
+EXPORT_SYMBOL(drm_hdmi_sink_max_frl);
+
+/**
+ * drm_hdmi_sink_dsc_max_frl - get the max frl rate from HDMI sink with
+ * DSC1.2 compression.
+ * @connector - connector with HDMI sink
+ *
+ * RETURNS:
+ * max frl rate supported by the HDMI sink with DSC1.2, 0 if FRL not supported
+ */
+int drm_hdmi_sink_dsc_max_frl(struct drm_connector *connector)
+{
+   int max_dsc_lanes, dsc_rate_per_lane;
+
+   if (!connector->display_info.hdmi.dsc_cap.v_1p2)
+   return 0;
+
+   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
+   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
+
+   return max_dsc_lanes * dsc_rate_per_lane;
+}
+EXPORT_SYMBOL(drm_hdmi_sink_dsc_max_frl);
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 18f6c700f6d0..5003e1254c44 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -592,6 +592,8 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
  u8 video_code);
 const u8 *drm_find_edid_extension(const struct edid *edid,
  int ext_id, int *ext_index);
+int drm_hdmi_sink_max_frl(struct drm_connector *connector);
+int drm_hdmi_sink_dsc_max_frl(struct drm_connector *connector);
 
 
 #endif /* __DRM_EDID_H__ */
-- 
2.25.1



[Intel-gfx] [PATCH v2 3/4] drm/i915/dp: Use the drm helpers for getting max FRL rate

2022-01-31 Thread Ankit Nautiyal
Re-use the drm helpers for getting max FRL rate for an HDMI sink.
This patch removes the duplicate code and calls the already defined
drm helpers for the task.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4d4579a301f6..f7fe7de7e553 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2190,22 +2190,13 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp 
*intel_dp)
 {
struct intel_connector *intel_connector = intel_dp->attached_connector;
struct drm_connector *connector = &intel_connector->base;
-   int max_frl_rate;
-   int max_lanes, rate_per_lane;
-   int max_dsc_lanes, dsc_rate_per_lane;
+   int max_frl = drm_hdmi_sink_max_frl(connector);
+   int dsc_max_frl = drm_hdmi_sink_dsc_max_frl(connector);
 
-   max_lanes = connector->display_info.hdmi.max_lanes;
-   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
-   max_frl_rate = max_lanes * rate_per_lane;
+   if (dsc_max_frl)
+   return min(max_frl, dsc_max_frl);
 
-   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
-   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
-   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
-   if (max_dsc_lanes && dsc_rate_per_lane)
-   max_frl_rate = min(max_frl_rate, max_dsc_lanes * 
dsc_rate_per_lane);
-   }
-
-   return max_frl_rate;
+   return max_frl;
 }
 
 static bool
-- 
2.25.1



  1   2   3   4   5   6   7   8   9   10   >