Re: [PATCH v2 5/6] drm/dp: Add helper to dump an LTTPR PHY descriptor

2024-07-11 Thread Nautiyal, Ankit K

LGTM

Reviewed-by: Ankit Nautiyal 

On 7/9/2024 12:30 AM, Imre Deak wrote:

Add a helper to dump the DPCD descriptor for an LTTPR PHY. This is based
on [1] and [2] moving the helper to DRM core as suggested by Ville.

[1] https://lore.kernel.org/all/20240703155937.1674856-5-imre.d...@intel.com
[2] https://lore.kernel.org/all/20240703155937.1674856-6-imre.d...@intel.com

Cc: dri-devel@lists.freedesktop.org
Cc: Ville Syrjälä 
Signed-off-by: Imre Deak 
---
  drivers/gpu/drm/display/drm_dp_helper.c | 66 +
  include/drm/display/drm_dp.h|  4 ++
  include/drm/display/drm_dp_helper.h |  2 +
  3 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index d4c34f3641400..6ee51003de3ce 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2328,6 +2328,31 @@ drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, 
bool is_branch)
  #undef DEVICE_ID_ANY
  #undef DEVICE_ID
  
+static int drm_dp_read_ident(struct drm_dp_aux *aux, unsigned int offset,

+struct drm_dp_dpcd_ident *ident)
+{
+   int ret;
+
+   ret = drm_dp_dpcd_read(aux, offset, ident, sizeof(*ident));
+
+   return ret < 0 ? ret : 0;
+}
+
+static void drm_dp_dump_desc(struct drm_dp_aux *aux,
+const char *device_name, const struct drm_dp_desc 
*desc)
+{
+   const struct drm_dp_dpcd_ident *ident = &desc->ident;
+
+   drm_dbg_kms(aux->drm_dev,
+   "%s: %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d quirks 
0x%04x\n",
+   aux->name, device_name,
+   (int)sizeof(ident->oui), ident->oui,
+   (int)strnlen(ident->device_id, sizeof(ident->device_id)), 
ident->device_id,
+   ident->hw_rev >> 4, ident->hw_rev & 0xf,
+   ident->sw_major_rev, ident->sw_minor_rev,
+   desc->quirks);
+}
+
  /**
   * drm_dp_read_desc - read sink/branch descriptor from DPCD
   * @aux: DisplayPort AUX channel
@@ -2344,27 +2369,48 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct 
drm_dp_desc *desc,
  {
struct drm_dp_dpcd_ident *ident = &desc->ident;
unsigned int offset = is_branch ? DP_BRANCH_OUI : DP_SINK_OUI;
-   int ret, dev_id_len;
+   int ret;
  
-	ret = drm_dp_dpcd_read(aux, offset, ident, sizeof(*ident));

+   ret = drm_dp_read_ident(aux, offset, ident);
if (ret < 0)
return ret;
  
  	desc->quirks = drm_dp_get_quirks(ident, is_branch);
  
-	dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id));

-
-   drm_dbg_kms(aux->drm_dev,
-   "%s: DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d 
quirks 0x%04x\n",
-   aux->name, is_branch ? "branch" : "sink",
-   (int)sizeof(ident->oui), ident->oui, dev_id_len,
-   ident->device_id, ident->hw_rev >> 4, ident->hw_rev & 0xf,
-   ident->sw_major_rev, ident->sw_minor_rev, desc->quirks);
+   drm_dp_dump_desc(aux, is_branch ? "DP branch" : "DP sink", desc);
  
  	return 0;

  }
  EXPORT_SYMBOL(drm_dp_read_desc);
  
+/**

+ * drm_dp_dump_lttpr_desc - read and dump the DPCD descriptor for an LTTPR PHY
+ * @aux: DisplayPort AUX channel
+ * @dp_phy: LTTPR PHY instance
+ *
+ * Read the DPCD LTTPR PHY descriptor for @dp_phy and print a debug message
+ * with its details to dmesg.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_dump_lttpr_desc(struct drm_dp_aux *aux, enum drm_dp_phy dp_phy)
+{
+   struct drm_dp_desc desc = {};
+   int ret;
+
+   if (drm_WARN_ON(aux->drm_dev, dp_phy < DP_PHY_LTTPR1 || dp_phy > 
DP_MAX_LTTPR_COUNT))
+   return -EINVAL;
+
+   ret = drm_dp_read_ident(aux, DP_OUI_PHY_REPEATER(dp_phy), &desc.ident);
+   if (ret < 0)
+   return ret;
+
+   drm_dp_dump_desc(aux, drm_dp_phy_name(dp_phy), &desc);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_dump_lttpr_desc);
+
  /**
   * drm_dp_dsc_sink_bpp_incr() - Get bits per pixel increment
   * @dsc_dpcd: DSC capabilities from DPCD
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 173548c6473a9..a6f8b098c56f1 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1543,6 +1543,10 @@ enum drm_dp_phy {
  #define DP_SYMBOL_ERROR_COUNT_LANE2_PHY_REPEATER1 0xf0039 /* 1.3 */
  #define DP_SYMBOL_ERROR_COUNT_LANE3_PHY_REPEATER1 0xf003b /* 1.3 */
  
+#define DP_OUI_PHY_REPEATER10xf003d /* 1.3 */

+#define DP_OUI_PHY_REPEATER(dp_phy) \
+   DP_LTTPR_REG(dp_phy, DP_OUI_PHY_REPEATER1)
+
  #define __DP_FEC1_BASE0xf0290 /* 
1.4 */
  #define __DP_FEC2_BASE0xf0298 /* 
1.4 */
  #define DP_FEC_BASE(dp_phy) \
diff --git a/include/drm/display/dr

Re: [PATCH 3/3] drm/i915/display: Update calculation to avoid overflow

2024-06-12 Thread Nautiyal, Ankit K



On 6/12/2024 3:24 PM, Mitul Golani wrote:

Update calculation to avoid overflow.

Fixes: 1676ecd303ac ("drm/i915: Compute CMRR and calculate vtotal")
Cc: Mitul Golani 
Cc: Ankit Nautiyal 
Cc: Suraj Kandpal 
Cc: Jani Nikula 
Cc: Stephen Rothwell 

Signed-off-by: Mitul Golani 


Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_vrr.c | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index dc9cf7ddafe9..5da9d5b9936e 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -147,10 +147,11 @@ cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool 
video_mode_required)
multiplier_n = 1000;
}
  
-	crtc_state->cmrr.cmrr_n =

-   desired_refresh_rate * adjusted_mode->crtc_htotal * 
multiplier_n;
-   vtotal = (adjusted_mode->crtc_clock * 1000 * multiplier_n) / 
crtc_state->cmrr.cmrr_n;
-   adjusted_pixel_rate = adjusted_mode->crtc_clock * 1000 * multiplier_m;
+   crtc_state->cmrr.cmrr_n = mul_u32_u32(desired_refresh_rate * 
adjusted_mode->crtc_htotal,
+ multiplier_n);
+   vtotal = DIV_ROUND_UP_ULL(mul_u32_u32(adjusted_mode->crtc_clock * 1000, 
multiplier_n),
+ crtc_state->cmrr.cmrr_n);
+   adjusted_pixel_rate = mul_u32_u32(adjusted_mode->crtc_clock * 1000, 
multiplier_m);
crtc_state->cmrr.cmrr_m = do_div(adjusted_pixel_rate, 
crtc_state->cmrr.cmrr_n);
  
  	return vtotal;


Re: [PATCH 1/3] drm/dp: Describe target_rr_divider in struct drm_dp_as_sdp

2024-06-12 Thread Nautiyal, Ankit K



On 6/12/2024 3:24 PM, Mitul Golani wrote:

Describe newly added parameter target_rr_divider in struct
drm_dp_as_sdp.

Fixes: a20c6d954d75 ("drm/dp: Add refresh rate divider to struct representing AS 
SDP")
Cc: Mitul Golani 
Cc: Arun R Murthy 
Cc: Suraj Kandpal 
Cc: Ankit Nautiyal 
Cc: Jani Nikula 
Cc: Stephen Rothwell 

Signed-off-by: Mitul Golani 


Reviewed-by: Ankit Nautiyal 



---
  include/drm/display/drm_dp_helper.h | 1 +
  1 file changed, 1 insertion(+)

diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index ea03e1dd26ba..7f2567fa230d 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -112,6 +112,7 @@ struct drm_dp_vsc_sdp {
   * @target_rr: Target Refresh
   * @duration_incr_ms: Successive frame duration increase
   * @duration_decr_ms: Successive frame duration decrease
+ * @target_rr_divider: Target refresh rate divider
   * @mode: Adaptive Sync Operation Mode
   */
  struct drm_dp_as_sdp {


Re: [PATCH v13 1/9] gpu/drm/i915: Update indentation for VRR registers and bits

2024-06-06 Thread Nautiyal, Ankit K



On 6/7/2024 8:59 AM, Nautiyal, Ankit K wrote:


On 6/5/2024 10:31 PM, Mitul Golani wrote:

Update the indentation for the VRR register definition and
its bits, and fix checkpatch issues to ensure smooth movement
of registers and bits.

Signed-off-by: Mitul Golani 


LGTM

Reviewed-by: Ankit Nautiyal 


Having look at the next patch, I fee there are still few things that can 
be fixed in VRR regs since we are moving these into a new file.


IMHO, it would be great if we can make the changes so that the new file 
adheres to the formatting mentioned in i915_reg.h


Regards,

Ankit






---
  drivers/gpu/drm/i915/i915_reg.h | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h 
b/drivers/gpu/drm/i915/i915_reg.h

index 0569a23b83b2..6b39211b5469 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1152,7 +1152,7 @@
  #define _TRANS_VRR_CTL_B    0x61420
  #define _TRANS_VRR_CTL_C    0x62420
  #define _TRANS_VRR_CTL_D    0x63420
-#define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, 
_TRANS_VRR_CTL_A)
+#define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, 
_TRANS_VRR_CTL_A)

  #define   VRR_CTL_VRR_ENABLE    REG_BIT(31)
  #define   VRR_CTL_IGN_MAX_SHIFT    REG_BIT(30)
  #define   VRR_CTL_FLIP_LINE_EN    REG_BIT(29)
@@ -1160,7 +1160,8 @@
  #define   VRR_CTL_PIPELINE_FULL(x) 
REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x))

  #define   VRR_CTL_PIPELINE_FULL_OVERRIDE    REG_BIT(0)
  #define  XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0)
-#define  XELPD_VRR_CTL_VRR_GUARDBAND(x) 
REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x))
+#define  XELPD_VRR_CTL_VRR_GUARDBAND(x) 
REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, \

+    (x))
    #define _TRANS_VRR_VMAX_A    0x60424
  #define _TRANS_VRR_VMAX_B    0x61424
@@ -1190,7 +1191,7 @@
  #define _TRANS_VRR_STATUS_B    0x6142C
  #define _TRANS_VRR_STATUS_C    0x6242C
  #define _TRANS_VRR_STATUS_D    0x6342C
-#define TRANS_VRR_STATUS(dev_priv, trans) _MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_STATUS_A)
+#define TRANS_VRR_STATUS(dev_priv, trans) _MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_STATUS_A)

  #define   VRR_STATUS_VMAX_REACHED    REG_BIT(31)
  #define   VRR_STATUS_NOFLIP_TILL_BNDR    REG_BIT(30)
  #define   VRR_STATUS_FLIP_BEF_BNDR    REG_BIT(29)
@@ -1241,7 +1242,7 @@
  #define   TRANS_PUSH_SEND    REG_BIT(30)
    #define _TRANS_VRR_VSYNC_A    0x60078
-#define TRANS_VRR_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_VSYNC_A)
+#define TRANS_VRR_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_VSYNC_A)

  #define VRR_VSYNC_END_MASK    REG_GENMASK(28, 16)
  #define VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VRR_VSYNC_END_MASK, 
(vsync_end))

  #define VRR_VSYNC_START_MASK    REG_GENMASK(12, 0)


Re: [PATCH v13 1/9] gpu/drm/i915: Update indentation for VRR registers and bits

2024-06-06 Thread Nautiyal, Ankit K



On 6/5/2024 10:31 PM, Mitul Golani wrote:

Update the indentation for the VRR register definition and
its bits, and fix checkpatch issues to ensure smooth movement
of registers and bits.

Signed-off-by: Mitul Golani 


LGTM

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/i915_reg.h | 9 +
  1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0569a23b83b2..6b39211b5469 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1152,7 +1152,7 @@
  #define _TRANS_VRR_CTL_B  0x61420
  #define _TRANS_VRR_CTL_C  0x62420
  #define _TRANS_VRR_CTL_D  0x63420
-#define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_CTL_A)
+#define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, 
_TRANS_VRR_CTL_A)
  #define   VRR_CTL_VRR_ENABLE  REG_BIT(31)
  #define   VRR_CTL_IGN_MAX_SHIFT   REG_BIT(30)
  #define   VRR_CTL_FLIP_LINE_ENREG_BIT(29)
@@ -1160,7 +1160,8 @@
  #define   VRR_CTL_PIPELINE_FULL(x)
REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x))
  #define   VRR_CTL_PIPELINE_FULL_OVERRIDE  REG_BIT(0)
  #define XELPD_VRR_CTL_VRR_GUARDBAND_MASK  REG_GENMASK(15, 0)
-#define  XELPD_VRR_CTL_VRR_GUARDBAND(x)
REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x))
+#define  XELPD_VRR_CTL_VRR_GUARDBAND(x)
REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, \
+   (x))
  
  #define _TRANS_VRR_VMAX_A		0x60424

  #define _TRANS_VRR_VMAX_B 0x61424
@@ -1190,7 +1191,7 @@
  #define _TRANS_VRR_STATUS_B   0x6142C
  #define _TRANS_VRR_STATUS_C   0x6242C
  #define _TRANS_VRR_STATUS_D   0x6342C
-#define TRANS_VRR_STATUS(dev_priv, trans)  _MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_STATUS_A)
+#define TRANS_VRR_STATUS(dev_priv, trans)  _MMIO_TRANS2(dev_priv, trans, 
_TRANS_VRR_STATUS_A)
  #define   VRR_STATUS_VMAX_REACHED REG_BIT(31)
  #define   VRR_STATUS_NOFLIP_TILL_BNDR REG_BIT(30)
  #define   VRR_STATUS_FLIP_BEF_BNDRREG_BIT(29)
@@ -1241,7 +1242,7 @@
  #define   TRANS_PUSH_SEND REG_BIT(30)
  
  #define _TRANS_VRR_VSYNC_A		0x60078

-#define TRANS_VRR_VSYNC(dev_priv, trans)   _MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_VSYNC_A)
+#define TRANS_VRR_VSYNC(dev_priv, trans)   _MMIO_TRANS2(dev_priv, trans, 
_TRANS_VRR_VSYNC_A)
  #define VRR_VSYNC_END_MASKREG_GENMASK(28, 16)
  #define VRR_VSYNC_END(vsync_end)  REG_FIELD_PREP(VRR_VSYNC_END_MASK, 
(vsync_end))
  #define VRR_VSYNC_START_MASK  REG_GENMASK(12, 0)


Re: [PATCH v11 2/8] drm/i915: Define and compute Transcoder CMRR registers

2024-06-03 Thread Nautiyal, Ankit K



On 6/3/2024 11:18 AM, Mitul Golani wrote:

Add register definitions for Transcoder Fixed Average
Vtotal mode/CMRR function, with the necessary bitfields.
Compute these registers when CMRR is enabled, extending
Adaptive refresh rate capabilities.

--v2:
- Use intel_de_read64_2x32 in intel_vrr_get_config. [Jani]
- Fix indent and order based on register offset. [Jani]

--v3:
- Removing RFC tag.

--v4:
- Update place holder for CMRR register definition. (Jani)

--v5:
- Add CMRR register definitions to a separate file intel_vrr_reg.h.

--v6:
- Fixed indentation. (Jani)
- Add dependency header intel_display_reg_defs.h. (Jani)
- Rename file name to intel_vrr_regs.h instead of reg.h (Jani)

--v7:
- Remove adding CMRR flag to vrr_ctl register during set_transcoder_timing,
as it is already being done during intel_vrr_enable. (Ankit)

Signed-off-by: Mitul Golani 


LGTM.

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_display.c  | 23 ++-
  .../drm/i915/display/intel_display_types.h|  6 +
  drivers/gpu/drm/i915/display/intel_vrr.c  | 20 
  drivers/gpu/drm/i915/display/intel_vrr_regs.h | 14 +++
  4 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 7370acdd6b8b..29d750d2e6f7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1005,6 +1005,13 @@ static bool vrr_params_changed(const struct 
intel_crtc_state *old_crtc_state,
old_crtc_state->vrr.pipeline_full != 
new_crtc_state->vrr.pipeline_full;
  }
  
+static bool cmrr_params_changed(const struct intel_crtc_state *old_crtc_state,

+   const struct intel_crtc_state *new_crtc_state)
+{
+   return old_crtc_state->cmrr.cmrr_m != new_crtc_state->cmrr.cmrr_m ||
+   old_crtc_state->cmrr.cmrr_n != new_crtc_state->cmrr.cmrr_n;
+}
+
  static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
 const struct intel_crtc_state *new_crtc_state)
  {
@@ -5054,6 +5061,16 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
} \
  } while (0)
  
+#define PIPE_CONF_CHECK_LLI(name) do { \

+   if (current_config->name != pipe_config->name) { \
+   pipe_config_mismatch(&p, fastset, crtc, __stringify(name), \
+"(expected %lli, found %lli)", \
+current_config->name, \
+pipe_config->name); \
+   ret = false; \
+   } \
+} while (0)
+
  #define PIPE_CONF_CHECK_BOOL(name) do { \
if (current_config->name != pipe_config->name) { \
BUILD_BUG_ON_MSG(!__same_type(current_config->name, bool), \
@@ -5432,10 +5449,13 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_I(vrr.guardband);
PIPE_CONF_CHECK_I(vrr.vsync_start);
PIPE_CONF_CHECK_I(vrr.vsync_end);
+   PIPE_CONF_CHECK_LLI(cmrr.cmrr_m);
+   PIPE_CONF_CHECK_LLI(cmrr.cmrr_n);
}
  
  #undef PIPE_CONF_CHECK_X

  #undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_LLI
  #undef PIPE_CONF_CHECK_BOOL
  #undef PIPE_CONF_CHECK_P
  #undef PIPE_CONF_CHECK_FLAGS
@@ -6824,7 +6844,8 @@ static void intel_pre_update_crtc(struct 
intel_atomic_state *state,
intel_crtc_needs_fastset(new_crtc_state))
icl_set_pipe_chicken(new_crtc_state);
  
-		if (vrr_params_changed(old_crtc_state, new_crtc_state))

+   if (vrr_params_changed(old_crtc_state, new_crtc_state) ||
+   cmrr_params_changed(old_crtc_state, new_crtc_state))
intel_vrr_set_transcoder_timings(new_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 52d0fd2bdc82..d1a135eb6408 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1401,6 +1401,12 @@ struct intel_crtc_state {
u32 vsync_end, vsync_start;
} vrr;
  
+	/* Content Match Refresh Rate state */

+   struct {
+   bool enable;
+   u64 cmrr_n, cmrr_m;
+   } cmrr;
+
/* Stream Splitter for eDP MSO */
struct {
bool enable;
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 871e6e6a184a..d2f854d9d18b 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -219,6 +219,17 @@ void intel_vrr_set_transcoder_timings(const struct 
intel_crtc_state *crtc_state)
return;
}
  
+	if (crtc_state->cmrr.enable) {

+   intel_de_write(dev_priv, TRANS_CMRR_

Re: [PATCH v11 1/8] drm/i915: Separate VRR related register definitions

2024-06-03 Thread Nautiyal, Ankit K



On 6/3/2024 11:18 AM, Mitul Golani wrote:

Move VRR related register definitions to a separate file called
intel_vrr_regs.h.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_vrr.c  |   1 +
  drivers/gpu/drm/i915/display/intel_vrr_regs.h | 113 ++
  drivers/gpu/drm/i915/i915_reg.h   | 100 
  3 files changed, 114 insertions(+), 100 deletions(-)
  create mode 100644 drivers/gpu/drm/i915/display/intel_vrr_regs.h

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 5f3657aa8313..871e6e6a184a 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -9,6 +9,7 @@
  #include "intel_de.h"
  #include "intel_display_types.h"
  #include "intel_vrr.h"
+#include "intel_vrr_regs.h"
  #include "intel_dp.h"
  
  bool intel_vrr_is_capable(struct intel_connector *connector)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr_regs.h 
b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
new file mode 100644
index ..b5695a95dd4a
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_VRR_REGS_H__
+#define __INTEL_VRR_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+/* VRR registers */
+#define _TRANS_VRR_CTL_A   0x60420
+#define _TRANS_VRR_CTL_B   0x61420
+#define _TRANS_VRR_CTL_C   0x62420
+#define _TRANS_VRR_CTL_D   0x63420
+#define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, 
_TRANS_VRR_CTL_A)
+#define   VRR_CTL_VRR_ENABLE   REG_BIT(31)
+#define   VRR_CTL_IGN_MAX_SHIFTREG_BIT(30)
+#define   VRR_CTL_FLIP_LINE_EN REG_BIT(29)
+#define   VRR_CTL_PIPELINE_FULL_MASK   REG_GENMASK(10, 3)
+#define   VRR_CTL_PIPELINE_FULL(x) 
REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x))
+#define   VRR_CTL_PIPELINE_FULL_OVERRIDE   REG_BIT(0)
+#define   XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0)
+#define   XELPD_VRR_CTL_VRR_GUARDBAND(x)   
REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK,\
+   (x))
+
+#define _TRANS_VRR_VMAX_A  0x60424
+#define _TRANS_VRR_VMAX_B  0x61424
+#define _TRANS_VRR_VMAX_C  0x62424
+#define _TRANS_VRR_VMAX_D  0x63424
+#define TRANS_VRR_VMAX(dev_priv, trans)_MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_VMAX_A)
+#define   VRR_VMAX_MASKREG_GENMASK(19, 0)
+
+#define _TRANS_VRR_VMIN_A  0x60434
+#define _TRANS_VRR_VMIN_B  0x61434
+#define _TRANS_VRR_VMIN_C  0x62434
+#define _TRANS_VRR_VMIN_D  0x63434
+#define TRANS_VRR_VMIN(dev_priv, trans)_MMIO_TRANS2(dev_priv, 
trans, _TRANS_VRR_VMIN_A)
+#define   VRR_VMIN_MASKREG_GENMASK(15, 0)
+
+#define _TRANS_VRR_VMAXSHIFT_A 0x60428
+#define _TRANS_VRR_VMAXSHIFT_B 0x61428
+#define _TRANS_VRR_VMAXSHIFT_C 0x62428
+#define _TRANS_VRR_VMAXSHIFT_D 0x63428
+#define TRANS_VRR_VMAXSHIFT(dev_priv, trans)   _MMIO_TRANS2(dev_priv, trans, \
+   _TRANS_VRR_VMAXSHIFT_A)
+#define   VRR_VMAXSHIFT_DEC_MASK   REG_GENMASK(29, 16)
+#define   VRR_VMAXSHIFT_DECREG_BIT(16)
+#define   VRR_VMAXSHIFT_INC_MASK   REG_GENMASK(12, 0)
+
+#define _TRANS_VRR_STATUS_A0x6042C
+#define _TRANS_VRR_STATUS_B0x6142C
+#define _TRANS_VRR_STATUS_C0x6242C
+#define _TRANS_VRR_STATUS_D0x6342C
+#define TRANS_VRR_STATUS(dev_priv, trans)  _MMIO_TRANS2(dev_priv, trans, 
_TRANS_VRR_STATUS_A)
+#define   VRR_STATUS_VMAX_REACHED  REG_BIT(31)
+#define   VRR_STATUS_NOFLIP_TILL_BNDR  REG_BIT(30)
+#define   VRR_STATUS_FLIP_BEF_BNDR REG_BIT(29)
+#define   VRR_STATUS_NO_FLIP_FRAME REG_BIT(28)
+#define   VRR_STATUS_VRR_EN_LIVE   REG_BIT(27)
+#define   VRR_STATUS_FLIPS_SERVICEDREG_BIT(26)
+#define   VRR_STATUS_VBLANK_MASK   REG_GENMASK(22, 20)
+#define   STATUS_FSM_IDLE  REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 
0)
+#define   STATUS_FSM_WAIT_TILL_FDB REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 
1)
+#define   STATUS_FSM_WAIT_TILL_FS  REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 
2)
+#define   STATUS_FSM_WAIT_TILL_FLIPREG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 
3)
+#define   STATUS_FSM_PIPELINE_FILL REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 
4)
+#define   STATUS_FSM_ACTIVEREG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 
5)
+#define   STATUS_FSM_LEGACY_VBLANK REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 
6)
+
+#define _TRANS_VRR_VTOTAL_PREV_A   0x60480
+#define _TRANS_VRR_VTOTAL_PREV_B   0x61480
+#define _TRANS_VRR_VTOTAL_PREV_C   0x62480
+#define _TRANS_VRR_VTOTAL_PREV_D   0x63480
+#def

Re: [PATCH v11 6/8] drm/i915/display: Compute Adaptive sync SDP params

2024-06-03 Thread Nautiyal, Ankit K



On 6/3/2024 11:19 AM, Mitul Golani wrote:

Compute params for Adaptive Sync SDP when Fixed Average Vtotal
mode is enabled.

--v2:
Since vrr.enable is set in case of cmrr also, handle accordingly(Ankit).

--v3:
- Since vrr.enable is set in case of cmrr also, handle
accordingly(Ankit).
- check cmrr.enable when CMRR flags are set during intel_dp_compute_as_sdp.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_dp.c | 15 ---
  1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index ac81b172b1ec..be3b9ba943a5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2637,11 +2637,20 @@ static void intel_dp_compute_as_sdp(struct intel_dp 
*intel_dp,
/* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
as_sdp->length = 0x9;
-   as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
-   as_sdp->vtotal = adjusted_mode->vtotal;
-   as_sdp->target_rr = 0;
as_sdp->duration_incr_ms = 0;
as_sdp->duration_incr_ms = 0;
+
+   if (crtc_state->cmrr.enable) {
+   as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+   as_sdp->target_rr = DIV_ROUND_UP(adjusted_mode->clock * 1000,
+adjusted_mode->htotal * 
adjusted_mode->vtotal);


Perhpas drm_mode_vrefresh() here.

With that change, this is:

Reviewed-by: Ankit Nautiyal 



+   as_sdp->target_rr_divider = true;
+   } else {
+   as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+   as_sdp->target_rr = 0;
+   }
  }
  
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,


Re: [PATCH v10 2/8] drm/i915: Define and compute Transcoder CMRR registers

2024-05-30 Thread Nautiyal, Ankit K



On 5/30/2024 11:34 AM, Mitul Golani wrote:

Add register definitions for Transcoder Fixed Average
Vtotal mode/CMRR function, with the necessary bitfields.
Compute these registers when CMRR is enabled, extending
Adaptive refresh rate capabilities.

--v2:
- Use intel_de_read64_2x32 in intel_vrr_get_config. [Jani]
- Fix indent and order based on register offset. [Jani]

--v3:
- Removing RFC tag.

--v4:
- Update place holder for CMRR register definition. (Jani)

--v5:
- Add CMRR register definitions to a separate file intel_vrr_reg.h.

--v6:
- Fixed indentation. (Jani)
- Add dependency header intel_display_reg_defs.h. (Jani)
- Rename file name to intel_vrr_regs.h instead of reg.h (Jani)
Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display.c  | 23 ++-
  .../drm/i915/display/intel_display_types.h|  6 +
  drivers/gpu/drm/i915/display/intel_vrr.c  | 22 ++
  drivers/gpu/drm/i915/display/intel_vrr_regs.h | 16 +
  4 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 071ba95a1472..5cbec4b19c3d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1004,6 +1004,13 @@ static bool vrr_params_changed(const struct 
intel_crtc_state *old_crtc_state,
old_crtc_state->vrr.pipeline_full != 
new_crtc_state->vrr.pipeline_full;
  }
  
+static bool cmrr_params_changed(const struct intel_crtc_state *old_crtc_state,

+   const struct intel_crtc_state *new_crtc_state)
+{
+   return old_crtc_state->cmrr.cmrr_m != new_crtc_state->cmrr.cmrr_m ||
+   old_crtc_state->cmrr.cmrr_n != new_crtc_state->cmrr.cmrr_n;
+}
+
  static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
 const struct intel_crtc_state *new_crtc_state)
  {
@@ -5034,6 +5041,16 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
} \
  } while (0)
  
+#define PIPE_CONF_CHECK_LLI(name) do { \

+   if (current_config->name != pipe_config->name) { \
+   pipe_config_mismatch(&p, fastset, crtc, __stringify(name), \
+"(expected %lli, found %lli)", \
+current_config->name, \
+pipe_config->name); \
+   ret = false; \
+   } \
+} while (0)
+
  #define PIPE_CONF_CHECK_BOOL(name) do { \
if (current_config->name != pipe_config->name) { \
BUILD_BUG_ON_MSG(!__same_type(current_config->name, bool), \
@@ -5398,10 +5415,13 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_I(vrr.guardband);
PIPE_CONF_CHECK_I(vrr.vsync_start);
PIPE_CONF_CHECK_I(vrr.vsync_end);
+   PIPE_CONF_CHECK_LLI(cmrr.cmrr_m);
+   PIPE_CONF_CHECK_LLI(cmrr.cmrr_n);
}
  
  #undef PIPE_CONF_CHECK_X

  #undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_LLI
  #undef PIPE_CONF_CHECK_BOOL
  #undef PIPE_CONF_CHECK_P
  #undef PIPE_CONF_CHECK_FLAGS
@@ -6790,7 +6810,8 @@ static void intel_pre_update_crtc(struct 
intel_atomic_state *state,
intel_crtc_needs_fastset(new_crtc_state))
icl_set_pipe_chicken(new_crtc_state);
  
-		if (vrr_params_changed(old_crtc_state, new_crtc_state))

+   if (vrr_params_changed(old_crtc_state, new_crtc_state) ||
+   cmrr_params_changed(old_crtc_state, new_crtc_state))
intel_vrr_set_transcoder_timings(new_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 6fbfe8a18f45..51d10b7e1011 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1401,6 +1401,12 @@ struct intel_crtc_state {
u32 vsync_end, vsync_start;
} vrr;
  
+	/* Content Match Refresh Rate state */

+   struct {
+   bool enable;
+   u64 cmrr_n, cmrr_m;
+   } cmrr;
+
/* Stream Splitter for eDP MSO */
struct {
bool enable;
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 871e6e6a184a..1f363e34495e 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -219,6 +219,19 @@ void intel_vrr_set_transcoder_timings(const struct 
intel_crtc_state *crtc_state)
return;
}
  
+	if (crtc_state->cmrr.enable) {

+   intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, 
cpu_transcoder),
+  VRR_CTL_CMRR_ENABLE | trans_vrr_ctl(crtc_state));


This is not required here. We enable CMRR bit in intel_vrr_enable a

Re: [PATCH v10 8/8] drm/i915/display: Compute vrr vsync params

2024-05-30 Thread Nautiyal, Ankit K



On 5/30/2024 11:34 AM, Mitul Golani wrote:

Compute vrr vsync params in case of FAVT as well instead of
only to AVT mode of operation.

--v2:
- Remove redundant computation for vrr_vsync_start
and vrr_vsync_end(Ankit).

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_vrr.c | 17 +
  1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 1e4e2d8a0927..2090a12b38aa 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -217,14 +217,6 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
if (crtc_state->uapi.vrr_enabled) {
crtc_state->vrr.enable = true;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
-   if (intel_dp_as_sdp_supported(intel_dp)) {
-   crtc_state->vrr.vsync_start =
-   (crtc_state->hw.adjusted_mode.crtc_vtotal -
-   
crtc_state->hw.adjusted_mode.vsync_start);
-   crtc_state->vrr.vsync_end =
-   (crtc_state->hw.adjusted_mode.crtc_vtotal -
-   crtc_state->hw.adjusted_mode.vsync_end);
-   }
} else if (is_cmrr_frac_required(crtc_state) && is_edp) {
crtc_state->vrr.enable = true;
crtc_state->cmrr.enable = true;
@@ -234,6 +226,15 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
}
  
+	if (intel_dp_as_sdp_supported(intel_dp)) {


Need to add check for vrr.enable as we set this only when vrr.enable is set.

Otherwise looks good to me.

Reviewed-by: Ankit Nautiyal 


Regards,

Ankit


+   crtc_state->vrr.vsync_start =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+crtc_state->hw.adjusted_mode.vsync_start);
+   crtc_state->vrr.vsync_end =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+crtc_state->hw.adjusted_mode.vsync_end);
+   }
+
/*
 * For XE_LPD+, we use guardband and pipeline override
 * is deprecated.


Re: [PATCH v10 7/8] drm/i915/display: Compute Adaptive sync SDP params

2024-05-30 Thread Nautiyal, Ankit K



On 5/30/2024 11:34 AM, Mitul Golani wrote:

Compute params for Adaptive Sync SDP when Fixed Average Vtotal
mode is enabled.

--v2:
Since vrr.enable is set in case of cmrr also, handle accordingly(Ankit).

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_dp.c | 17 +
  1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 95cf586f3bed..7007a509363a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2627,7 +2627,7 @@ static void intel_dp_compute_as_sdp(struct intel_dp 
*intel_dp,
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
  
-	if (!crtc_state->vrr.enable ||

+   if (!(crtc_state->vrr.enable || crtc_state->cmrr.enable) ||


This is not required, vrr.enable is set even when cmrr.enable is set.



!intel_dp_as_sdp_supported(intel_dp))
return;
  
@@ -2636,11 +2636,20 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,

/* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
as_sdp->length = 0x9;
-   as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
-   as_sdp->vtotal = adjusted_mode->vtotal;
-   as_sdp->target_rr = 0;
as_sdp->duration_incr_ms = 0;
as_sdp->duration_incr_ms = 0;
+
+   if (crtc_state->vrr.enable) {


I think there is a typo here, it should be crtc_state->cmrr.enable


Regards,

Ankit


+   as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+   as_sdp->target_rr = DIV_ROUND_UP(adjusted_mode->clock * 1000,
+adjusted_mode->htotal * 
adjusted_mode->vtotal);
+   as_sdp->target_rr_divider = true;
+   } else{
+   as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+   as_sdp->target_rr = 0;
+   }
  }
  
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,


Re: [PATCH v10 6/8] drm/i915/display: Add support for pack and unpack

2024-05-30 Thread Nautiyal, Ankit K



On 5/30/2024 11:34 AM, Mitul Golani wrote:

Add support of pack and unpack for target_rr_divider.

--v2:
- Set Target Refresh Rate Divider bit when related
AS SDP bit is set (Ankit).

--v3:
- target_rr_divider is bools so set accordingly (Ankit).
Signed-off-by: Mitul Golani 


LGTM.

Reviewed-by: Ankit Nautiyal 


---
  drivers/gpu/drm/i915/display/intel_dp.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4fa977f1e6c4..95cf586f3bed 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4230,6 +4230,9 @@ static ssize_t intel_dp_as_sdp_pack(const struct 
drm_dp_as_sdp *as_sdp,
sdp->db[3] = as_sdp->target_rr & 0xFF;
sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
  
+	if (as_sdp->target_rr_divider)

+   sdp->db[4] |= 0x20;
+
return length;
  }
  
@@ -4411,6 +4414,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,

as_sdp->mode = sdp->db[0] & DP_ADAPTIVE_SYNC_SDP_OPERATION_MODE;
as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1];
as_sdp->target_rr = (u64)sdp->db[3] | ((u64)sdp->db[4] & 0x3);
+   as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false;
  
  	return 0;

  }


Re: [PATCH v10 4/8] drm/i915: Compute CMRR and calculate vtotal

2024-05-30 Thread Nautiyal, Ankit K



On 5/30/2024 11:34 AM, Mitul Golani wrote:

Compute Fixed Average Vtotal/CMRR with resepect to
userspace VRR enablement. Also calculate required
parameters in case of CMRR is  enabled. During
intel_vrr_compute_config, CMRR is getting enabled
based on userspace has enabled Variable refresh mode
with VRR timing generator or not. Make CMRR as small subset of
FAVT mode, when Panel is running on Fixed refresh rate
and on VRR framework then only enable CMRR to match with
actual refresh rate.

--v2:
- Update is_cmrr_frac_required function return as bool, not int. [Jani]
- Use signed int math instead of unsigned in cmrr_get_vtotal2. [Jani]
- Fix typo and usage of camel case in cmrr_get_vtotal. [Jani]
- Use do_div in cmrr_get_vtotalwhile calculating cmrr_m. [ Jani]
- Simplify cmrr and vrr compute config in intel_vrr_compute_config. [Jani]
- Correct valiable name usage in is_cmrr_frac_required. [Ville]

--v3:
- Removing RFC tag.

--v4:
- Added edp check to address edp usecase for now. (ville)
- Updated is_cmrr_fraction_required to more simplified calculation.
- on longterm goal to be worked upon uapi as suggestion from ville.

--v5:
- Correct vtotal paramas accuracy and add 2 digit precision.
- Avoid using DIV_ROUND_UP and improve scanline precision.

--v6:
- Make CMRR a small subset of FAVT mode.

--v7:
- Update commit message to avoid confusion with Legacy VRR (Ankit).
- Add cmrr.enable in last, so remove from this patch.

--v8:
- Set cmrr.enable in current patch instead of separate patch (Ankit).
- Since vrr.enable and cmrr.enable are not mutually exclusive,
handle accordingly (Ankit).
- is_edp is not required inside is_cmrr_frac_required function (Ankit).
- Add video_mode_required flag for future enhancement.
- Correct cmrr_m/cmrr_n calculation.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display.c  |  1 +
  .../drm/i915/display/intel_display_device.h   |  1 +
  drivers/gpu/drm/i915/display/intel_vrr.c  | 86 ---
  3 files changed, 77 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 5cbec4b19c3d..926dc1e531ee 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5417,6 +5417,7 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_I(vrr.vsync_end);
PIPE_CONF_CHECK_LLI(cmrr.cmrr_m);
PIPE_CONF_CHECK_LLI(cmrr.cmrr_n);
+   PIPE_CONF_CHECK_BOOL(cmrr.enable);
}
  
  #undef PIPE_CONF_CHECK_X

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
b/drivers/gpu/drm/i915/display/intel_display_device.h
index 17ddf82f0b6e..b372b1acc19b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -71,6 +71,7 @@ struct drm_printer;
  BIT(trans)) != 0)
  #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
  #define HAS_AS_SDP(i915)  (DISPLAY_VER(i915) >= 13)
+#define HAS_CMRR(i915) (DISPLAY_VER(i915) >= 20)
  #define INTEL_NUM_PIPES(i915) 
(hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
  #define I915_HAS_HOTPLUG(i915)
(DISPLAY_INFO(i915)->has_hotplug)
  #define OVERLAY_NEEDS_PHYSICAL(i915)  
(DISPLAY_INFO(i915)->overlay_needs_physical)
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index c2b5424f53db..1e4e2d8a0927 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -12,6 +12,9 @@
  #include "intel_vrr_regs.h"
  #include "intel_dp.h"
  
+#define FIXED_POINT_PRECISION		100

+#define CMRR_PRECISION_TOLERANCE   10
+
  bool intel_vrr_is_capable(struct intel_connector *connector)
  {
const struct drm_display_info *info = &connector->base.display_info;
@@ -107,6 +110,52 @@ int intel_vrr_vmax_vblank_start(const struct 
intel_crtc_state *crtc_state)
return crtc_state->vrr.vmax - intel_vrr_vblank_exit_length(crtc_state);
  }
  
+static bool

+is_cmrr_frac_required(struct intel_crtc_state *crtc_state)
+{
+   int calculated_refresh_k, actual_refresh_k, pixel_clock_per_line;
+   struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+   struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+   if (!HAS_CMRR(i915))
+   return false;
+
+   actual_refresh_k =
+   drm_mode_vrefresh(adjusted_mode) * FIXED_POINT_PRECISION;
+   pixel_clock_per_line =
+   adjusted_mode->crtc_clock * 1000 / adjusted_mode->crtc_htotal;
+   calculated_refresh_k =
+   pixel_clock_per_line * FIXED_POINT_PRECISION / 
adjusted_mode->crtc_vtotal;
+
+   if ((actual_refresh_k - calculated_refresh_k) < 
CMRR_PRECISION_TOLERANCE)
+   return false;

Re: [PATCH v10 3/8] drm/i915: Update trans_vrr_ctl flag when cmrr is computed

2024-05-30 Thread Nautiyal, Ankit K



On 5/30/2024 11:34 AM, Mitul Golani wrote:

Add/update trans_vrr_ctl flag when crtc_state->cmrr.enable
is set, With this commit setting the stage for subsequent
CMRR enablement.

--v2:
- Check pipe active state in cmrr enabling. [Jani]
- Remove usage of bitwise OR on booleans. [Jani]
- Revert unrelated changes. [Jani]
- Update intel_vrr_enable, vrr and cmrr enable conditions. [Jani]
- Simplify whole if-ladder in intel_vrr_enable. [Jani]
- Revert patch restructuring mistakes in intel_vrr_get_config. [Jani]

--v3:
- Check pipe active state in cmrr disabling.[Jani]
- Correct messed up condition in intel_vrr_enable. [Jani]

--v4:
- Removing RFC tag.

--v5:
- CMRR handling in co-existatnce of LRR and DRRS.

--v7:
- Rebase on top of AS SDP merge.

--v8:
- Remove cmrr_enabling/disabling and update commit message. (Ankit)

--v9:
- Revert removed line(Ankit).

Signed-off-by: Mitul Golani 


LGTM

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_vrr.c | 10 --
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 1f363e34495e..c2b5424f53db 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -284,8 +284,14 @@ void intel_vrr_enable(const struct intel_crtc_state 
*crtc_state)
   VRR_VSYNC_END(crtc_state->vrr.vsync_end) |
   VRR_VSYNC_START(crtc_state->vrr.vsync_start));
  
-	intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),

-  VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
+   if (crtc_state->cmrr.enable) {
+   intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, 
cpu_transcoder),
+  VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE |
+  trans_vrr_ctl(crtc_state));
+   } else {
+   intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, 
cpu_transcoder),
+  VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
+   }
  }
  
  void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)


Re: [PATCH v6 3/6] drm/display: Add missing aux less alpm wake related bits

2024-05-28 Thread Nautiyal, Ankit K



On 5/27/2024 1:56 PM, Animesh Manna wrote:

From: Jouni Högander 

eDP1.5 adds some more bits into DP_RECEIVER_ALPM_CAP and
DP_RECEIVER_ALPM_CONFIG registers. Add definitions for these.

Signed-off-by: Jouni Högander 
---
  include/drm/display/drm_dp.h | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 906949ca3cee..3317ff88ed59 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -232,6 +232,8 @@
  
  #define DP_RECEIVER_ALPM_CAP		0x02e   /* eDP 1.4 */

  # define DP_ALPM_CAP  (1 << 0)
+# define DP_ALPM_PM_STATE_2A_SUPPORT   (1 << 1) /* eDP 1.5 */
+# define DP_ALPM_AUX_LESS_CAP  (1 << 2) /* eDP 1.5 */


This bit seems to be derived from DP 2.1.

As per eDP1.5: Only bits [1 and 0] are eDP-specific. The register’s 
other bits are defined in DP Standard.


In any case, patch looks good to me.

Reviewed-by: Ankit Nautiyal 


Regards,

Ankit

  
  #define DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP   0x02f   /* eDP 1.4 */

  # define DP_AUX_FRAME_SYNC_CAP(1 << 0)
@@ -683,7 +685,8 @@
  
  #define DP_RECEIVER_ALPM_CONFIG		0x116   /* eDP 1.4 */

  # define DP_ALPM_ENABLE   (1 << 0)
-# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE  (1 << 1)
+# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE  (1 << 1) /* eDP 1.5 */
+# define DP_ALPM_MODE_AUX_LESS (1 << 2) /* eDP 1.5 */
  
  #define DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF  0x117   /* eDP 1.4 */

  # define DP_AUX_FRAME_SYNC_ENABLE (1 << 0)


Re: [PATCH v17 0/9] Enable Adaptive Sync SDP Support for DP

2024-04-20 Thread Nautiyal, Ankit K



On 4/19/2024 6:05 PM, Jani Nikula wrote:

On Thu, 04 Apr 2024, "Nautiyal, Ankit K"  wrote:

On 3/19/2024 3:16 PM, Maxime Ripard wrote:

On Mon, Mar 18, 2024 at 04:37:58PM +0200, Jani Nikula wrote:

On Mon, 11 Mar 2024, Mitul Golani  wrote:

   An Adaptive-Sync-capable DP protocol converter indicates its
support by setting the related bit in the DPCD register. This
is valid for DP and edp as well.

Computes AS SDP values based on the display configuration,
ensuring proper handling of Variable Refresh Rate (VRR)
in the context of Adaptive Sync.

[snip]


Mitul Golani (9):
drm/dp: Add support to indicate if sink supports AS SDP
drm: Add Adaptive Sync SDP logging

Maarten, Maxime, Thomas, ack for merging these two patches via
drm-intel-next?

Ack

Maxime

Thanks for the patch, ack and reviews, pushed to drm-intel-next.

This came up again today [1]. The acks absolutely must be recorded in
the commit messages when pushing the patches.


I apologize for the oversight. Moving forward, I will ensure to 
consistently include the "acked-by" tag when pushing such changes.


Regards,

Ankit



dim should complain about applying non-i915 patches without acks.

BR,
Jani.


[1] https://lore.kernel.org/r/zh_q72gykmmbg...@intel.com




Re: [PATCH v17 0/9] Enable Adaptive Sync SDP Support for DP

2024-04-04 Thread Nautiyal, Ankit K



On 3/19/2024 3:16 PM, Maxime Ripard wrote:

On Mon, Mar 18, 2024 at 04:37:58PM +0200, Jani Nikula wrote:

On Mon, 11 Mar 2024, Mitul Golani  wrote:

  An Adaptive-Sync-capable DP protocol converter indicates its
support by setting the related bit in the DPCD register. This
is valid for DP and edp as well.

Computes AS SDP values based on the display configuration,
ensuring proper handling of Variable Refresh Rate (VRR)
in the context of Adaptive Sync.

[snip]


Mitul Golani (9):
   drm/dp: Add support to indicate if sink supports AS SDP
   drm: Add Adaptive Sync SDP logging

Maarten, Maxime, Thomas, ack for merging these two patches via
drm-intel-next?

Ack

Maxime


Thanks for the patch, ack and reviews, pushed to drm-intel-next.

Regards,

Ankit



Re: [PATCH 09/11] drm/dp_mst: Add drm_dp_mst_aux_for_parent()

2024-03-27 Thread Nautiyal, Ankit K



On 3/27/2024 7:55 PM, Imre Deak wrote:

On Wed, Mar 27, 2024 at 02:30:53PM +0530, Nautiyal, Ankit K wrote:

On 3/21/2024 1:41 AM, Imre Deak wrote:

Add a function to get the AUX device of the parent of an MST port, used
by a follow-up i915 patch in the patchset.

Cc: Lyude Paul 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Imre Deak 
---
   drivers/gpu/drm/display/drm_dp_mst_topology.c | 16 
   1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 6bd471a2266ce..d70f7de644371 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -6004,6 +6004,22 @@ static bool drm_dp_mst_is_virtual_dpcd(struct 
drm_dp_mst_port *port)
return false;
   }
+/**
+ * drm_dp_mst_aux_for_parent() - Get the AUX device for an MST port's parent
+ * @port: MST port whose parent's AUX device is returned
+ *
+ * Return the AUX device for @port's parent or NULL if port's parent is the
+ * root port.
+ */
+struct drm_dp_aux *drm_dp_mst_aux_for_parent(struct drm_dp_mst_port *port)
+{
+   if (!port->parent || !port->parent->port_parent)
+   return NULL;
+
+   return &port->parent->port_parent->aux;
+}
+EXPORT_SYMBOL(drm_dp_mst_aux_for_parent);

As mentioned in previous patch, the declaration of this in the header,
got included in previous patch.

Yes thanks, the header change should've been in this patch, will move it here
(while applying the patches if nothing else comes up).


With the above fixed, this is:

Reviewed-by: Ankit Nautiyal 


Regards,

Ankit


+
   /**
* drm_dp_mst_dsc_aux_for_port() - Find the correct aux for DSC
* @port: The port to check. A leaf of the MST tree with an attached display.


Re: [PATCH 09/11] drm/dp_mst: Add drm_dp_mst_aux_for_parent()

2024-03-27 Thread Nautiyal, Ankit K



On 3/21/2024 1:41 AM, Imre Deak wrote:

Add a function to get the AUX device of the parent of an MST port, used
by a follow-up i915 patch in the patchset.

Cc: Lyude Paul 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Imre Deak 
---
  drivers/gpu/drm/display/drm_dp_mst_topology.c | 16 
  1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 6bd471a2266ce..d70f7de644371 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -6004,6 +6004,22 @@ static bool drm_dp_mst_is_virtual_dpcd(struct 
drm_dp_mst_port *port)
return false;
  }
  
+/**

+ * drm_dp_mst_aux_for_parent() - Get the AUX device for an MST port's parent
+ * @port: MST port whose parent's AUX device is returned
+ *
+ * Return the AUX device for @port's parent or NULL if port's parent is the
+ * root port.
+ */
+struct drm_dp_aux *drm_dp_mst_aux_for_parent(struct drm_dp_mst_port *port)
+{
+   if (!port->parent || !port->parent->port_parent)
+   return NULL;
+
+   return &port->parent->port_parent->aux;
+}
+EXPORT_SYMBOL(drm_dp_mst_aux_for_parent);


As mentioned in previous patch, the declaration of this in the header, 
got included in previous patch.


Regards,

Ankit


+
  /**
   * drm_dp_mst_dsc_aux_for_port() - Find the correct aux for DSC
   * @port: The port to check. A leaf of the MST tree with an attached display.


Re: [PATCH 11/11] drm/i915/dp_mst: Enable HBLANK expansion quirk for UHBR rates

2024-03-27 Thread Nautiyal, Ankit K



On 3/21/2024 1:41 AM, Imre Deak wrote:

Enabling the 5k@60Hz uncompressed mode on the MediaTek/Dell U3224KBA
monitor results in a blank screen, at least on MTL platforms on UHBR
link rates with some (<30) uncompressed bpp values. Enabling compression
fixes the problem, so do that for now. Windows enables DSC always if the
sink supports it and forcing it to enable the mode without compression
leads to the same problem above (which suggests a panel issue with
uncompressed mode).

The same 5k mode on non-UHBR link rates is not affected and lower
resolution modes are not affected either. The problem is similar to the
one fixed by the HBLANK expansion quirk on Synaptics hubs, with the
difference that the problematic mode has a longer HBLANK duration. Also
the monitor doesn't report supporting HBLANK expansion; either its
internal MST hub does the expansion internally - similarly to the
Synaptics hub - or the issue has another root cause, but still related
to the mode's short HBLANK duration. Enable the quirk for the monitor
adjusting the detection for the above differences.

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Imre Deak 


LGTM.

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/display/drm_dp_helper.c |  2 ++
  drivers/gpu/drm/i915/display/intel_dp_mst.c | 22 +
  2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index f5d4be8978660..3e8e1bb59dea3 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2281,6 +2281,8 @@ static const struct dpcd_quirk dpcd_quirk_list[] = {
{ OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, 
BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
/* Synaptics DP1.4 MST hubs require DSC for some modes on which it 
applies HBLANK expansion. */
{ OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, 
BIT(DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC) },
+   /* MediaTek panels (at least in U3224KBA) require DSC for modes with a 
short HBLANK on UHBR links. */
+   { OUI(0x00, 0x0C, 0xE7), DEVICE_ID_ANY, false, 
BIT(DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC) },
/* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low 
DP_MAX_LINK_RATE */
{ OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, 
BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) },
  };
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 76a8fb21b8e52..b5224fe6cc16b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -407,15 +407,22 @@ static int mode_hblank_period_ns(const struct 
drm_display_mode *mode)
  
  static bool

  hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector,
-const struct intel_crtc_state *crtc_state)
+const struct intel_crtc_state *crtc_state,
+const struct link_config_limits *limits)
  {
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
+   bool is_uhbr_sink = connector->mst_port &&
+   
drm_dp_uhbr_channel_coding_supported(connector->mst_port->dpcd);
+   int hblank_limit = is_uhbr_sink ? 500 : 300;
  
  	if (!connector->dp.dsc_hblank_expansion_quirk)

return false;
  
-	if (mode_hblank_period_ns(adjusted_mode) > 300)

+   if (is_uhbr_sink && !drm_dp_is_uhbr_rate(limits->max_rate))
+   return false;
+
+   if (mode_hblank_period_ns(adjusted_mode) > hblank_limit)
return false;
  
  	return true;

@@ -431,7 +438,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct 
intel_connector *conne
const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
int min_bpp_x16 = limits->link.min_bpp_x16;
  
-	if (!hblank_expansion_quirk_needs_dsc(connector, crtc_state))

+   if (!hblank_expansion_quirk_needs_dsc(connector, crtc_state, limits))
return true;
  
  	if (!dsc) {

@@ -1539,7 +1546,14 @@ static bool detect_dsc_hblank_expansion_quirk(const 
struct intel_connector *conn
  DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC))
return false;
  
-	if (!(dpcd[DP_RECEIVE_PORT_0_CAP_0] & DP_HBLANK_EXPANSION_CAPABLE))

+   /*
+* UHBR (MST sink) devices requiring this quirk doesn't advertise the
+* HBLANK expansion support. Presuming that they perform HBLANK
+* expansion internally, or are affected by this issue on modes with a
+* short HBLANK for other reasons.
+*/
+   if (!drm_dp_uhbr_channel_coding_supported(dpcd) &&
+   !(dpcd[DP_RECEIVE_PORT_0_CAP_0] & DP_HBLANK_EXPANSION_CAPABLE))
return false;
  
  	drm_dbg_kms(&i915->drm,


Re: [PATCH 07/11] drm/dp: Add drm_dp_uhbr_channel_coding_supported()

2024-03-26 Thread Nautiyal, Ankit K



On 3/21/2024 1:41 AM, Imre Deak wrote:

Factor out a function to check for UHBR channel coding support used by a
follow-up patch in the patchset.

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Imre Deak 


LGTM.

Reviewed-by: Ankit Nautiyal 


---
  drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
  include/drm/display/drm_dp_helper.h | 6 ++
  2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index dbe65651bf277..1d13a1ba2b97d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -217,7 +217,7 @@ static void intel_dp_set_dpcd_sink_rates(struct intel_dp 
*intel_dp)
 * Sink rates for 128b/132b. If set, sink should support all 8b/10b
 * rates and 10 Gbps.
 */
-   if (intel_dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_128B132B) 
{
+   if (drm_dp_uhbr_channel_coding_supported(intel_dp->dpcd)) {
u8 uhbr_rates = 0;
  
  		BUILD_BUG_ON(ARRAY_SIZE(intel_dp->sink_rates) < ARRAY_SIZE(dp_rates) + 3);

diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index a62fcd051d4d4..150c37a99a16f 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -221,6 +221,12 @@ drm_dp_channel_coding_supported(const u8 
dpcd[DP_RECEIVER_CAP_SIZE])
return dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_8B10B;
  }
  
+static inline bool

+drm_dp_uhbr_channel_coding_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+   return dpcd[DP_MAIN_LINK_CHANNEL_CODING] & DP_CAP_ANSI_128B132B;
+}
+
  static inline bool
  drm_dp_alternate_scrambler_reset_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
  {


Re: [PATCH 08/11] drm/dp_mst: Factor out drm_dp_mst_port_is_logical()

2024-03-26 Thread Nautiyal, Ankit K



On 3/21/2024 1:41 AM, Imre Deak wrote:

Factor out a function to check if an MST port is logical, used by a
follow-up i915 patch in the patchset.

Cc: Lyude Paul 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Imre Deak 
---
  drivers/gpu/drm/display/drm_dp_mst_topology.c | 6 +++---
  include/drm/display/drm_dp_mst_helper.h   | 7 +++
  2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 03d5282094262..6bd471a2266ce 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -2274,7 +2274,7 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch 
*mstb,
  
  	if (port->pdt != DP_PEER_DEVICE_NONE &&

drm_dp_mst_is_end_device(port->pdt, port->mcs) &&
-   port->port_num >= DP_MST_LOGICAL_PORT_0)
+   drm_dp_mst_port_is_logical(port))
port->cached_edid = drm_edid_read_ddc(port->connector,
  &port->aux.ddc);
  
@@ -4213,7 +4213,7 @@ drm_dp_mst_detect_port(struct drm_connector *connector,

case DP_PEER_DEVICE_SST_SINK:
ret = connector_status_connected;
/* for logical ports - cache the EDID */
-   if (port->port_num >= DP_MST_LOGICAL_PORT_0 && 
!port->cached_edid)
+   if (drm_dp_mst_port_is_logical(port) && !port->cached_edid)
port->cached_edid = drm_edid_read_ddc(connector, 
&port->aux.ddc);
break;
case DP_PEER_DEVICE_DP_LEGACY_CONV:
@@ -5977,7 +5977,7 @@ static bool drm_dp_mst_is_virtual_dpcd(struct 
drm_dp_mst_port *port)
return false;
  
  	/* Virtual DP Sink (Internal Display Panel) */

-   if (port->port_num >= 8)
+   if (drm_dp_mst_port_is_logical(port))
return true;
  
  	/* DP-to-HDMI Protocol Converter */

diff --git a/include/drm/display/drm_dp_mst_helper.h 
b/include/drm/display/drm_dp_mst_helper.h
index 3ae88a383a41f..c12f18b744d01 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -927,6 +927,13 @@ int __must_check drm_dp_mst_root_conn_atomic_check(struct 
drm_connector_state *n
  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
  void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port);
  
+static inline

+bool drm_dp_mst_port_is_logical(struct drm_dp_mst_port *port)
+{
+   return port->port_num >= DP_MST_LOGICAL_PORT_0;
+}
+
+struct drm_dp_aux *drm_dp_mst_aux_for_parent(struct drm_dp_mst_port *port);


This line should be part of next patch, where this helper is defined.

Otherwise LGTM.

With the above line removed, this is:

Reviewed-by: Ankit Nautiyal 


Regards,

Ankit


  struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port);
  
  static inline struct drm_dp_mst_topology_state *


Re: [PATCH 01/11] drm/i915/dp: Fix DSC line buffer depth programming

2024-03-26 Thread Nautiyal, Ankit K



On 3/21/2024 1:41 AM, Imre Deak wrote:

Fix the calculation of the DSC line buffer depth. This is limited both
by the source's and sink's maximum line buffer depth, but the former one
was not taken into account. On all Intel platform's the source's maximum
buffer depth is 13, so the overall limit is simply the minimum of the
source/sink's limit, regardless of the DSC version.

This leaves the DSI DSC line buffer depth calculation as-is, trusting
VBT.

On DSC version 1.2 for sinks reporting a maximum line buffer depth of 16
the line buffer depth was incorrectly programmed as 0, leading to a
corruption in color gradients / lines on the decompressed screen image.

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Imre Deak 


LGTM.

Reviewed-by: Ankit Nautiyal 


---
  drivers/gpu/drm/i915/display/intel_dp.c | 16 ++--
  include/drm/display/drm_dsc.h   |  3 ---
  2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index af7ca00e9bc0a..dbe65651bf277 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -89,6 +89,9 @@
  #define DP_DSC_MAX_ENC_THROUGHPUT_0   34
  #define DP_DSC_MAX_ENC_THROUGHPUT_1   40
  
+/* Max DSC line buffer depth supported by HW. */

+#define INTEL_DP_DSC_MAX_LINE_BUF_DEPTH13
+
  /* DP DSC FEC Overhead factor in ppm = 1/(0.972261) = 1.028530 */
  #define DP_DSC_FEC_OVERHEAD_FACTOR1028530
  
@@ -1703,7 +1706,6 @@ static int intel_dp_dsc_compute_params(const struct intel_connector *connector,

  {
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
-   u8 line_buf_depth;
int ret;
  
  	/*

@@ -1732,20 +1734,14 @@ static int intel_dp_dsc_compute_params(const struct 
intel_connector *connector,
connector->dp.dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - 
DP_DSC_SUPPORT] &
DP_DSC_RGB;
  
-	line_buf_depth = drm_dp_dsc_sink_line_buf_depth(connector->dp.dsc_dpcd);

-   if (!line_buf_depth) {
+   vdsc_cfg->line_buf_depth = min(INTEL_DP_DSC_MAX_LINE_BUF_DEPTH,
+  
drm_dp_dsc_sink_line_buf_depth(connector->dp.dsc_dpcd));
+   if (!vdsc_cfg->line_buf_depth) {
drm_dbg_kms(&i915->drm,
"DSC Sink Line Buffer Depth invalid\n");
return -EINVAL;
}
  
-	if (vdsc_cfg->dsc_version_minor == 2)

-   vdsc_cfg->line_buf_depth = (line_buf_depth == 
DSC_1_2_MAX_LINEBUF_DEPTH_BITS) ?
-   DSC_1_2_MAX_LINEBUF_DEPTH_VAL : line_buf_depth;
-   else
-   vdsc_cfg->line_buf_depth = (line_buf_depth > 
DSC_1_1_MAX_LINEBUF_DEPTH_BITS) ?
-   DSC_1_1_MAX_LINEBUF_DEPTH_BITS : line_buf_depth;
-
vdsc_cfg->block_pred_enable =
connector->dp.dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT - 
DP_DSC_SUPPORT] &
DP_DSC_BLK_PREDICTION_IS_SUPPORTED;
diff --git a/include/drm/display/drm_dsc.h b/include/drm/display/drm_dsc.h
index bc90273d06a62..bbbe7438473d3 100644
--- a/include/drm/display/drm_dsc.h
+++ b/include/drm/display/drm_dsc.h
@@ -40,9 +40,6 @@
  #define DSC_PPS_RC_RANGE_MINQP_SHIFT  11
  #define DSC_PPS_RC_RANGE_MAXQP_SHIFT  6
  #define DSC_PPS_NATIVE_420_SHIFT  1
-#define DSC_1_2_MAX_LINEBUF_DEPTH_BITS 16
-#define DSC_1_2_MAX_LINEBUF_DEPTH_VAL  0
-#define DSC_1_1_MAX_LINEBUF_DEPTH_BITS 13
  
  /**

   * struct drm_dsc_rc_range_parameters - DSC Rate Control range parameters


Re: [PATCH v18 8/9] drm/i915/display: Compute vrr_vsync params

2024-03-14 Thread Nautiyal, Ankit K



On 3/13/2024 9:26 AM, Mitul Golani wrote:

Compute vrr_vsync_start/end, which sets the position
for hardware to send the Vsync at a fixed position
relative to the end of the Vblank.

--v2:
- Updated VSYNC_START/END macros to VRR_VSYNC_START/END. (Ankit)
- Updated bit fields of VRR_VSYNC_START/END. (Ankit)

--v3:
- Add PIPE_CONF_CHECK_I(vrr.vsync_start/end).
- Read/write vrr_vsync params only when we intend to send
adaptive_sync sdp.

--v4:
- Use VRR_SYNC_START/END macros correctly.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display.c  |  2 ++
  .../drm/i915/display/intel_display_types.h|  1 +
  drivers/gpu/drm/i915/display/intel_vrr.c  | 30 +--
  drivers/gpu/drm/i915/i915_reg.h   |  7 +
  4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 8f1d948408d3..fed4ed18d53b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5377,6 +5377,8 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_I(vrr.flipline);
PIPE_CONF_CHECK_I(vrr.pipeline_full);
PIPE_CONF_CHECK_I(vrr.guardband);
+   PIPE_CONF_CHECK_I(vrr.vsync_start);
+   PIPE_CONF_CHECK_I(vrr.vsync_end);
}
  
  #undef PIPE_CONF_CHECK_X

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 8a286751dc39..c2e08f641989 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1430,6 +1430,7 @@ struct intel_crtc_state {
bool enable, in_range;
u8 pipeline_full;
u16 flipline, vmin, vmax, guardband;
+   u32 vsync_end, vsync_start;
} vrr;
  
  	/* Stream Splitter for eDP MSO */

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index eb5bd0743902..ed38fee196b8 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -9,6 +9,7 @@
  #include "intel_de.h"
  #include "intel_display_types.h"
  #include "intel_vrr.h"
+#include "intel_dp.h"
  
  bool intel_vrr_is_capable(struct intel_connector *connector)

  {
@@ -113,6 +114,7 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
+   struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
const struct drm_display_info *info = &connector->base.display_info;
int vmin, vmax;
@@ -165,6 +167,15 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
if (crtc_state->uapi.vrr_enabled) {
crtc_state->vrr.enable = true;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+
+   if (intel_dp_as_sdp_supported(intel_dp)) {
+   crtc_state->vrr.vsync_start =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   
crtc_state->hw.adjusted_mode.vsync_start);
+   crtc_state->vrr.vsync_end =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   crtc_state->hw.adjusted_mode.vsync_end);
+   }
}
  }
  
@@ -204,6 +215,11 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)

intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), 
crtc_state->vrr.vmax - 1);
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), 
trans_vrr_ctl(crtc_state));
intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder), 
crtc_state->vrr.flipline - 1);
+
+   if (crtc_state->vrr.vsync_end && crtc_state->vrr.vsync_start)
+   intel_de_write(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder),
+  
VRR_VSYNC_END(crtc_state->hw.adjusted_mode.vsync_end) |
+  
VRR_VSYNC_START(crtc_state->hw.adjusted_mode.vsync_start));


Typo here, need to use crtc_state->vrr.vsync_end, 
crtc_state->vrr.vsync_start.


That also explains the mismatch in bat-arls-2

Regards,

Ankit



  }
  
  void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)

@@ -264,7 +280,7 @@ void intel_vrr_get_config(struct intel_crtc_state 
*crtc_state)
  {
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-   u32 trans_vrr_ctl;
+   u32 trans_vrr_ctl, trans_vrr_vsync;
  
  	trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_

Re: [PATCH v16 9/9] drm/i915/display: Read/Write Adaptive Sync SDP

2024-03-07 Thread Nautiyal, Ankit K



On 3/7/2024 11:23 AM, Mitul Golani wrote:

Add read/write calls for Adaptive Sync SDP.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_ddi.c | 1 +
  drivers/gpu/drm/i915/display/intel_dp.c  | 1 +
  2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index c587a8efeafc..f164020a4773 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3972,6 +3972,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, DP_SDP_ADAPTIVE_SYNC);
  
  	intel_audio_codec_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 cf89e69d2e7a..7f87876651e7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4330,6 +4330,7 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
return;
  
  	intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC);

+   intel_write_dp_sdp(encoder, crtc_state, DP_SDP_ADAPTIVE_SYNC);
  



Though not related to this patch, but IMHO we can remove extra space 
between consecutive intel_write_dp_sdp.


In any case, patch looks good to me.

Reviewed-by: Ankit Nautiyal 


intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }


Re: [PATCH v16 8/9] drm/i915/display: Compute vrr_vsync params

2024-03-07 Thread Nautiyal, Ankit K



On 3/7/2024 11:23 AM, Mitul Golani wrote:

Compute vrr_vsync_start/end, which sets the position
for hardware to send the Vsync at a fixed position
relative to the end of the Vblank.

--v2:
- Updated VSYNC_START/END macros to VRR_VSYNC_START/END. (Ankit)
- Updated bit fields of VRR_VSYNC_START/END. (Ankit)

--v3:
- Add PIPE_CONF_CHECK_I(vrr.vsync_start/end).
- Read/write vrr_vsync params only when we intend to send
adaptive_sync sdp.

--v4:
- Use VRR_SYNC_START/END macros correctly.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display.c  |  2 ++
  .../drm/i915/display/intel_display_types.h|  1 +
  drivers/gpu/drm/i915/display/intel_vrr.c  | 30 +--
  drivers/gpu/drm/i915/i915_reg.h   |  7 +
  4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 88158f06bf82..f62c3ae7f0fd 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5377,6 +5377,8 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_I(vrr.flipline);
PIPE_CONF_CHECK_I(vrr.pipeline_full);
PIPE_CONF_CHECK_I(vrr.guardband);
+   PIPE_CONF_CHECK_I(vrr.vsync_start);
+   PIPE_CONF_CHECK_I(vrr.vsync_end);
}
  
  #undef PIPE_CONF_CHECK_X

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 098957cea25b..e8ba3c077569 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1423,6 +1423,7 @@ struct intel_crtc_state {
bool enable, in_range;
u8 pipeline_full;
u16 flipline, vmin, vmax, guardband;
+   u32 vsync_end, vsync_start;
} vrr;
  
  	/* Stream Splitter for eDP MSO */

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 5d905f932cb4..8f4605884052 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -9,6 +9,7 @@
  #include "intel_de.h"
  #include "intel_display_types.h"
  #include "intel_vrr.h"
+#include "intel_dp.h"
  
  bool intel_vrr_is_capable(struct intel_connector *connector)

  {
@@ -113,6 +114,7 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
+   struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
const struct drm_display_info *info = &connector->base.display_info;
int vmin, vmax;
@@ -165,6 +167,15 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
if (crtc_state->uapi.vrr_enabled) {
crtc_state->vrr.enable = true;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+
+   if (intel_dp_as_sdp_supported(intel_dp)) {
+   crtc_state->vrr.vsync_start =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   
crtc_state->hw.adjusted_mode.vsync_start);
+   crtc_state->vrr.vsync_end =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   crtc_state->hw.adjusted_mode.vsync_end);
+   }
}
  }
  
@@ -203,6 +214,11 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)

intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), 
crtc_state->vrr.vmax - 1);
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), 
trans_vrr_ctl(crtc_state));
intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder), 
crtc_state->vrr.flipline - 1);
+
+   if (crtc_state->vrr.vsync_end && crtc_state->vrr.vsync_start)
+   intel_de_write(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder),
+  
VRR_VSYNC_END(crtc_state->hw.adjusted_mode.vsync_end) |
+  
VRR_VSYNC_START(crtc_state->hw.adjusted_mode.vsync_start));
  }
  
  void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)

@@ -263,7 +279,7 @@ void intel_vrr_get_config(struct intel_crtc_state 
*crtc_state)
  {
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-   u32 trans_vrr_ctl;
+   u32 trans_vrr_ctl, trans_vrr_vsync;
  
  	trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_CTL(cpu_transcoder));
  
@@ -283,6 +299,16 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)

crtc_state->vrr.vmin = i

Re: [PATCH v16 4/9] drm/i915/dp: Add Read/Write support for Adaptive Sync SDP

2024-03-07 Thread Nautiyal, Ankit K



On 3/7/2024 11:23 AM, Mitul Golani wrote:

Add the necessary structures and functions to handle reading and
unpacking Adaptive Sync Secondary Data Packets. Also add support
to write and pack AS SDP.

--v2:
- Correct use of REG_BIT and REG_GENMASK. [Jani]
- Use as_sdp instead of async. [Jani]
- Remove unrelated comments and changes. [Jani]
- Correct code indent. [Jani]

--v3:
- Update definition names for AS SDP which are starting from
HSW, as these defines are applicable for ADLP+.(Ankit)

--v4:
- Remove as_sdp_mode from crtc_state.
- Drop metadata keyword.
- For consistency, update ADL_ prefix or post fix as required.

--v5:
- Check if AS_SDP bit is set in crtc_state->infoframes.enable. If not
   return.
- Check for HAS_AS_SDP() before setting VIDEO_DIP_ENABLE_AS_ADL mask.

--v6:
- Rename intel_read_dp_infoframe_as_sdp to intel_read_dp_as_sdp.

--v7:
- Add read back for length and vtotal correction.

--v8:
- Use as_sdp->target_rr & 0xFF.
- Shift by 8 instead of 32, and drop casting to u64.
-  Remove changes which are does not belong to this patch.

Signed-off-by: Mitul Golani 


LGTM.

Reviewed-by: Ankit Nautiyal 


---
  .../drm/i915/display/intel_display_device.h   |  1 +
  drivers/gpu/drm/i915/display/intel_dp.c   | 92 +++
  drivers/gpu/drm/i915/display/intel_hdmi.c | 14 ++-
  drivers/gpu/drm/i915/i915_reg.h   |  8 ++
  4 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
b/drivers/gpu/drm/i915/display/intel_display_device.h
index fe4268813786..6399fbc6c738 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -68,6 +68,7 @@ struct drm_printer;
  #define HAS_TRANSCODER(i915, trans)   
((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
  BIT(trans)) != 0)
  #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
+#define HAS_AS_SDP(i915)   (DISPLAY_VER(i915) >= 13)
  #define INTEL_NUM_PIPES(i915) 
(hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
  #define I915_HAS_HOTPLUG(i915)
(DISPLAY_INFO(i915)->has_hotplug)
  #define OVERLAY_NEEDS_PHYSICAL(i915)  
(DISPLAY_INFO(i915)->overlay_needs_physical)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index b485ec320085..4a8638502d04 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4127,6 +4127,32 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state 
*crtc_state,
return false;
  }
  
+static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,

+   struct dp_sdp *sdp, size_t size)
+{
+   size_t length = sizeof(struct dp_sdp);
+
+   if (size < length)
+   return -ENOSPC;
+
+   memset(sdp, 0, size);
+
+   /* Prepare AS (Adaptive Sync) SDP Header */
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = as_sdp->sdp_type;
+   sdp->sdp_header.HB2 = 0x02;
+   sdp->sdp_header.HB3 = as_sdp->length;
+
+   /* Fill AS (Adaptive Sync) SDP Payload */
+   sdp->db[0] = as_sdp->mode;
+   sdp->db[1] = as_sdp->vtotal & 0xFF;
+   sdp->db[2] = (as_sdp->vtotal >> 8) & 0xFF;
+   sdp->db[3] = as_sdp->target_rr & 0xFF;
+   sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
+
+   return length;
+}
+
  static ssize_t
  intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915,
 const struct hdmi_drm_infoframe 
*drm_infoframe,
@@ -4226,6 +4252,10 @@ static void intel_write_dp_sdp(struct intel_encoder 
*encoder,
   
&crtc_state->infoframes.drm.drm,
   &sdp, 
sizeof(sdp));
break;
+   case DP_SDP_ADAPTIVE_SYNC:
+   len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
+  sizeof(sdp));
+   break;
default:
MISSING_CASE(type);
return;
@@ -4247,6 +4277,10 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
 VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+
+   if (HAS_AS_SDP(dev_priv))
+   dip_enable |= VIDEO_DIP_ENABLE_AS_ADL;
+
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

@@ -4268,6 +4302,37 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
+static

+int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
+

Re: [PATCH v15 9/9] drm/i915/display: Read/Write AS sdp only when sink/source has enabled

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:15 PM, Mitul Golani wrote:

Write/Read Adaptive sync SDP only when Sink and Source is enabled
for the same. Also along with write TRANS_VRR_VSYNC values.


The subject line and commit message need to be updated.

Now we are just enabling Adaptive sync SDP.


Regards,

Ankit




Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_ddi.c | 1 +
  drivers/gpu/drm/i915/display/intel_dp.c  | 1 +
  2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index c587a8efeafc..f164020a4773 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3972,6 +3972,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, DP_SDP_ADAPTIVE_SYNC);
  
  	intel_audio_codec_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 ef1543205ee9..9abe245ac1ee 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4332,6 +4332,7 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
return;
  
  	intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC);

+   intel_write_dp_sdp(encoder, crtc_state, DP_SDP_ADAPTIVE_SYNC);
  
  	intel_write_dp_sdp(encoder, crtc_state, HDMI_PACKET_TYPE_GAMUT_METADATA);

  }


Re: [PATCH v15 8/9] drm/i915/display: Compute vrr_vsync params

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:15 PM, Mitul Golani wrote:

Compute vrr_vsync_start/end, which sets the position
for hardware to send the Vsync at a fixed position
relative to the end of the Vblank.

--v2:
- Updated VSYNC_START/END macros to VRR_VSYNC_START/END. (Ankit)
- Updated bit fields of VRR_VSYNC_START/END. (Ankit)

--v3:
- Add PIPE_CONF_CHECK_I(vrr.vsync_start/end).
- Read/write vrr_vsync params only when we intend to send
adaptive_sync sdp.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display.c  |  2 ++
  .../drm/i915/display/intel_display_types.h|  1 +
  drivers/gpu/drm/i915/display/intel_vrr.c  | 29 +--
  drivers/gpu/drm/i915/i915_reg.h   |  7 +
  4 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 88158f06bf82..f62c3ae7f0fd 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5377,6 +5377,8 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_I(vrr.flipline);
PIPE_CONF_CHECK_I(vrr.pipeline_full);
PIPE_CONF_CHECK_I(vrr.guardband);
+   PIPE_CONF_CHECK_I(vrr.vsync_start);
+   PIPE_CONF_CHECK_I(vrr.vsync_end);
}
  
  #undef PIPE_CONF_CHECK_X

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 098957cea25b..e8ba3c077569 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1423,6 +1423,7 @@ struct intel_crtc_state {
bool enable, in_range;
u8 pipeline_full;
u16 flipline, vmin, vmax, guardband;
+   u32 vsync_end, vsync_start;
} vrr;
  
  	/* Stream Splitter for eDP MSO */

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 5d905f932cb4..d24a42902e69 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -9,6 +9,7 @@
  #include "intel_de.h"
  #include "intel_display_types.h"
  #include "intel_vrr.h"
+#include "intel_dp.h"
  
  bool intel_vrr_is_capable(struct intel_connector *connector)

  {
@@ -113,6 +114,7 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
+   struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
const struct drm_display_info *info = &connector->base.display_info;
int vmin, vmax;
@@ -165,6 +167,15 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
if (crtc_state->uapi.vrr_enabled) {
crtc_state->vrr.enable = true;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+
+   if (intel_dp_as_sdp_supported(intel_dp)) {
+   crtc_state->vrr.vsync_start =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   
VRR_VSYNC_START(crtc_state->hw.adjusted_mode.vsync_start));
+   crtc_state->vrr.vsync_end =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   
(VRR_VSYNC_END(crtc_state->hw.adjusted_mode.vsync_end) >> 16));


I think you are using the VRR_SYNC_START/END macros incorrectly.

We dont need to use these macros here.


+   }
}
  }
  
@@ -203,6 +214,10 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)

intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), 
crtc_state->vrr.vmax - 1);
intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), 
trans_vrr_ctl(crtc_state));
intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder), 
crtc_state->vrr.flipline - 1);
+
+   if (crtc_state->vrr.vsync_end && crtc_state->vrr.vsync_start)
+   intel_de_write(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder),
+  crtc_state->vrr.vsync_end << 16 | 
crtc_state->vrr.vsync_start);


Here is where the macros should be used.

VRR_SYNC_END(crtc_state->vrr.vsync_end) | 
VRR_SYNC_START(crtc_state->vrr.vsync_start);




  }
  
  void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)

@@ -263,7 +278,7 @@ void intel_vrr_get_config(struct intel_crtc_state 
*crtc_state)
  {
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-   u32 trans_vrr_ctl;
+   u32 trans_vrr_ctl, trans_vrr_vsync;
  
  	trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_CTL(cpu_transcoder)

Re: [PATCH v15 7/9] drm/i915/display: Add state checker for Adaptive Sync SDP

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:15 PM, Mitul Golani wrote:

Enable infoframe and add state checker for Adaptive Sync
SDP enablement.

--v1:
- crtc_state->infoframes.enable, to add on correct place holder.

Signed-off-by: Mitul Golani 


LGTM.

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_display.c | 46 
  1 file changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index ab2f52d21bad..88158f06bf82 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4791,6 +4791,17 @@ intel_compare_dp_vsc_sdp(const struct drm_dp_vsc_sdp *a,
a->content_type == b->content_type;
  }
  
+static bool

+intel_compare_dp_as_sdp(const struct drm_dp_as_sdp *a,
+   const struct drm_dp_as_sdp *b)
+{
+   return a->vtotal == b->vtotal &&
+   a->target_rr == b->target_rr &&
+   a->duration_incr_ms == b->duration_incr_ms &&
+   a->duration_decr_ms == b->duration_decr_ms &&
+   a->mode == b->mode;
+}
+
  static bool
  intel_compare_buffer(const u8 *a, const u8 *b, size_t len)
  {
@@ -4846,6 +4857,30 @@ pipe_config_dp_vsc_sdp_mismatch(struct drm_i915_private 
*i915,
drm_dp_vsc_sdp_log(&p, b);
  }
  
+static void

+pipe_config_dp_as_sdp_mismatch(struct drm_i915_private *i915,
+  bool fastset, const char *name,
+  const struct drm_dp_as_sdp *a,
+  const struct drm_dp_as_sdp *b)
+{
+   struct drm_printer p;
+
+   if (fastset) {
+   p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, NULL);
+
+   drm_printf(&p, "fastset requirement not met in %s dp sdp\n", 
name);
+   } else {
+   p = drm_err_printer(&i915->drm, NULL);
+
+   drm_printf(&p, "mismatch in %s dp sdp\n", name);
+   }
+
+   drm_printf(&p, "expected:\n");
+   drm_dp_as_sdp_log(&p, a);
+   drm_printf(&p, "found:\n");
+   drm_dp_as_sdp_log(&p, b);
+}
+
  /* Returns the length up to and including the last differing byte */
  static size_t
  memcmp_diff_len(const u8 *a, const u8 *b, size_t len)
@@ -5099,6 +5134,16 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
} \
  } while (0)
  
+#define PIPE_CONF_CHECK_DP_AS_SDP(name) do { \

+   if (!intel_compare_dp_as_sdp(¤t_config->infoframes.name, \
+ &pipe_config->infoframes.name)) { \
+   pipe_config_dp_as_sdp_mismatch(dev_priv, fastset, 
__stringify(name), \
+   
¤t_config->infoframes.name, \
+   &pipe_config->infoframes.name); 
\
+   ret = false; \
+   } \
+} while (0)
+
  #define PIPE_CONF_CHECK_BUFFER(name, len) do { \
BUILD_BUG_ON(sizeof(current_config->name) != (len)); \
BUILD_BUG_ON(sizeof(pipe_config->name) != (len)); \
@@ -5280,6 +5325,7 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_INFOFRAME(hdmi);
PIPE_CONF_CHECK_INFOFRAME(drm);
PIPE_CONF_CHECK_DP_VSC_SDP(vsc);
+   PIPE_CONF_CHECK_DP_AS_SDP(as_sdp);
  
  	PIPE_CONF_CHECK_X(sync_mode_slaves_mask);

PIPE_CONF_CHECK_I(master_transcoder);


Re: [PATCH v15 6/9] drm/i915/display: Compute AS SDP parameters

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:15 PM, Mitul Golani wrote:

Add necessary function definitions to compute AS SDP data.
The new intel_dp_compute_as_sdp function computes AS SDP
values based on the display configuration, ensuring proper
handling of Variable Refresh Rate (VRR).

--v2:
- Added DP_SDP_ADAPTIVE_SYNC to infoframe_type_to_idx(). [Ankit]
- Separated patch for intel_read/write_dp_sdp. [Ankit]
- _HSW_VIDEO_DIP_ASYNC_DATA_A should be from ADL onward. [Ankit]
- Fixed indentation issues. [Ankit]

--v3:
- Added VIDEO_DIP_ENABLE_AS_HSW flag to intel_dp_set_infoframes.

--v4:
- Added HAS_VRR check before writing AS SDP.

--v5:
Added missed HAS_VRR check before reading AS SDP.

--v6:
- Used Adaptive Sync sink status as a check for read/write SDP. (Ankit)

--v7:
- Remove as_sdp_enable from crtc_state.
- Add a comment mentioning current support of
   DP_AS_SDP_AVT_FIXED_VTOTAL.
- Add state checker for AS_SDP infoframe enable.

--v8:
- Drop conn_state from intel_dp_compute_as_sdp, as not used.
- Remove fullstop in subject line.

--v9:
- Add vrr.enable instead of is_in_vrr_range.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 1b3e7ae3dd76..ef1543205ee9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2620,6 +2620,31 @@ static void intel_dp_compute_vsc_colorimetry(const 
struct intel_crtc_state *crtc
vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED;
  }
  
+static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,

+   struct intel_crtc_state *crtc_state)
+{
+   struct drm_dp_as_sdp *as_sdp = &crtc_state->infoframes.as_sdp;
+   struct intel_connector *connector = intel_dp->attached_connector;
+   const struct drm_display_mode *adjusted_mode =
+   &crtc_state->hw.adjusted_mode;
+   int vrefresh = drm_mode_vrefresh(adjusted_mode);



I think you missed to remove vrefresh and connector, as they are no 
longer required.



Regards,

Ankit


+
+   if (!crtc_state->vrr.enable ||
+   !intel_dp_as_sdp_supported(intel_dp))
+   return;
+
+   crtc_state->infoframes.enable |= 
intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);
+
+   /* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */
+   as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
+   as_sdp->length = 0x9;
+   as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+   as_sdp->target_rr = 0;
+   as_sdp->duration_incr_ms = 0;
+   as_sdp->duration_incr_ms = 0;
+}
+
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
 struct intel_crtc_state *crtc_state,
 const struct drm_connector_state 
*conn_state)
@@ -2980,6 +3005,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
g4x_dp_set_clock(encoder, pipe_config);
  
  	intel_vrr_compute_config(pipe_config, conn_state);

+   intel_dp_compute_as_sdp(intel_dp, pipe_config);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);


Re: [PATCH v15 5/9] drm/i915/dp: Add wrapper function to check AS SDP

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:14 PM, Mitul Golani wrote:

Add a wrapper function to check if both the source and
sink support Adaptive Sync SDP.

--v1:
Just use drm/i915/dp in subject line.

Signed-off-by: Mitul Golani 


LGTM.

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_dp.c | 8 
  drivers/gpu/drm/i915/display/intel_dp.h | 1 +
  2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 99732ac1475d..1b3e7ae3dd76 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -122,6 +122,14 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
return dig_port->base.type == INTEL_OUTPUT_EDP;
  }
  
+bool intel_dp_as_sdp_supported(struct intel_dp *intel_dp)

+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+   return HAS_AS_SDP(i915) &&
+   drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd);
+}
+
  static void intel_dp_unset_edid(struct intel_dp *intel_dp);
  
  /* Is link rate UHBR and thus 128b/132b? */

diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 564a587e2d01..0b15fd4750ee 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -86,6 +86,7 @@ void intel_dp_audio_compute_config(struct intel_encoder 
*encoder,
   struct drm_connector_state *conn_state);
  bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp);
  bool intel_dp_is_edp(struct intel_dp *intel_dp);
+bool intel_dp_as_sdp_supported(struct intel_dp *intel_dp);
  bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);
  int intel_dp_link_symbol_size(int rate);
  int intel_dp_link_symbol_clock(int rate);


Re: [PATCH v15 4/9] drm/i915/dp: Add Read/Write support for Adaptive Sync SDP

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:14 PM, Mitul Golani wrote:

Add the necessary structures and functions to handle reading and
unpacking Adaptive Sync Secondary Data Packets. Also add support
to write and pack AS SDP.

--v2:
- Correct use of REG_BIT and REG_GENMASK. [Jani]
- Use as_sdp instead of async. [Jani]
- Remove unrelated comments and changes. [Jani]
- Correct code indent. [Jani]

--v3:
- Update definition names for AS SDP which are starting from
HSW, as these defines are applicable for ADLP+.(Ankit)

--v4:
- Remove as_sdp_mode from crtc_state.
- Drop metadata keyword.
- For consistency, update ADL_ prefix or post fix as required.

--v5:
- Check if AS_SDP bit is set in crtc_state->infoframes.enable. If not
   return.
- Check for HAS_AS_SDP() before setting VIDEO_DIP_ENABLE_AS_ADL mask.

--v6:
- Rename intel_read_dp_infoframe_as_sdp to intel_read_dp_as_sdp.
-

Signed-off-by: Mitul Golani 
---
  .../drm/i915/display/intel_display_device.h   |  1 +
  drivers/gpu/drm/i915/display/intel_dp.c   | 91 +++
  drivers/gpu/drm/i915/display/intel_hdmi.c | 14 ++-
  drivers/gpu/drm/i915/i915_reg.h   |  8 ++
  include/drm/display/drm_dp_helper.h   |  2 +-
  5 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
b/drivers/gpu/drm/i915/display/intel_display_device.h
index fe4268813786..6399fbc6c738 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -68,6 +68,7 @@ struct drm_printer;
  #define HAS_TRANSCODER(i915, trans)   
((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
  BIT(trans)) != 0)
  #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
+#define HAS_AS_SDP(i915)   (DISPLAY_VER(i915) >= 13)
  #define INTEL_NUM_PIPES(i915) 
(hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
  #define I915_HAS_HOTPLUG(i915)
(DISPLAY_INFO(i915)->has_hotplug)
  #define OVERLAY_NEEDS_PHYSICAL(i915)  
(DISPLAY_INFO(i915)->overlay_needs_physical)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6ece2c563c7a..99732ac1475d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4127,6 +4127,32 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state 
*crtc_state,
return false;
  }
  
+static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,

+   struct dp_sdp *sdp, size_t size)
+{
+   size_t length = sizeof(struct dp_sdp);
+
+   if (size < length)
+   return -ENOSPC;
+
+   memset(sdp, 0, size);
+
+   /* Prepare AS (Adaptive Sync) SDP Header */
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = as_sdp->sdp_type;
+   sdp->sdp_header.HB2 = 0x02;
+   sdp->sdp_header.HB3 = as_sdp->length;
+
+   /* Fill AS (Adaptive Sync) SDP Payload */
+   sdp->db[0] = as_sdp->mode;
+   sdp->db[1] = as_sdp->vtotal & 0xFF;
+   sdp->db[2] = (as_sdp->vtotal >> 8) & 0xFF;
+   sdp->db[3] = as_sdp->target_rr;


Use as_sdp->target_rr & 0xFF;



+   sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
+
+   return length;
+}
+
  static ssize_t
  intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915,
 const struct hdmi_drm_infoframe 
*drm_infoframe,
@@ -4226,6 +4252,10 @@ static void intel_write_dp_sdp(struct intel_encoder 
*encoder,
   
&crtc_state->infoframes.drm.drm,
   &sdp, 
sizeof(sdp));
break;
+   case DP_SDP_ADAPTIVE_SYNC:
+   len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
+  sizeof(sdp));
+   break;
default:
MISSING_CASE(type);
return;
@@ -4247,6 +4277,10 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
 VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+
+   if (HAS_AS_SDP(dev_priv))
+   dip_enable |= VIDEO_DIP_ENABLE_AS_ADL;
+
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

@@ -4268,6 +4302,36 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
+static

+int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
+  const void *buffer, size_t size)
+{
+   const struct dp_sdp *sdp = buffer;
+
+   if (size < sizeof(struct dp_sdp))
+   retur

Re: [PATCH v15 3/9] drm: Add crtc state dump for Adaptive Sync SDP

2024-03-04 Thread Nautiyal, Ankit K

Add drm/i915/display in subject line.

With that fixed this is:

Reviewed-by: Ankit Nautiyal 

On 3/1/2024 2:14 PM, Mitul Golani wrote:

Add crtc state dump for Adaptive Sync SDP to know which
crtc specifically caused the failure.

Signed-off-by: Mitul Golani 
---
  .../gpu/drm/i915/display/intel_crtc_state_dump.c| 13 +
  drivers/gpu/drm/i915/display/intel_display_types.h  |  1 +
  2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c 
b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
index 4bcf446c75f4..1e4618271156 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
@@ -51,6 +51,15 @@ intel_dump_infoframe(struct drm_i915_private *i915,
hdmi_infoframe_log(KERN_DEBUG, i915->drm.dev, frame);
  }
  
+static void

+intel_dump_dp_as_sdp(struct drm_i915_private *i915,
+const struct drm_dp_as_sdp *as_sdp)
+{
+   struct drm_printer p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, 
"AS_SDP");
+
+   drm_dp_as_sdp_log(&p, as_sdp);
+}
+
  static void
  intel_dump_dp_vsc_sdp(struct drm_i915_private *i915,
  const struct drm_dp_vsc_sdp *vsc)
@@ -302,6 +311,10 @@ void intel_crtc_state_dump(const struct intel_crtc_state 
*pipe_config,
if (pipe_config->infoframes.enable &
intel_hdmi_infoframe_enable(DP_SDP_VSC))
intel_dump_dp_vsc_sdp(i915, &pipe_config->infoframes.vsc);
+   if (pipe_config->infoframes.enable &
+   intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC))
+   intel_dump_dp_as_sdp(i915, &pipe_config->infoframes.as_sdp);
+
  
  	if (pipe_config->has_audio)

intel_dump_buffer(i915, "ELD: ", pipe_config->eld,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 860e867586f4..098957cea25b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1338,6 +1338,7 @@ struct intel_crtc_state {
union hdmi_infoframe hdmi;
union hdmi_infoframe drm;
struct drm_dp_vsc_sdp vsc;
+   struct drm_dp_as_sdp as_sdp;
} infoframes;
  
  	u8 eld[MAX_ELD_BYTES];


Re: [PATCH v15 2/9] drm: Add Adaptive Sync SDP logging

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:14 PM, Mitul Golani wrote:

Add structure representing Adaptive Sync Secondary Data Packet (AS SDP).
Also, add Adaptive Sync SDP logging in drm_dp_helper.c to facilitate
debugging.

--v2:
- Update logging. [Jani, Ankit]
- Use 'as_sdp' instead of 'async' [Ankit]
- Correct define placeholders to where they are actually used. [Jani]
- Update members in 'as_sdp' structure to make it uniform. [Jani]

--v3:
- Added changes to dri-devel mailing list. No code changes.

--v4:
- Instead of directly using operation mode, use an enum to accommodate
all operation modes (Ankit).

--v5:
Nit-pick changes to commit message.

--v6:
- Add correct place holder and name change for AS_SDP_OP_MODE.
- Separate i915 changes from drm changes.
- Remove extra lines.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/display/drm_dp_helper.c | 12 ++
  include/drm/display/drm_dp.h| 10 +
  include/drm/display/drm_dp_helper.h | 29 +
  3 files changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index f2fabb673aa4..f880bc7b2153 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2948,6 +2948,18 @@ void drm_dp_vsc_sdp_log(struct drm_printer *p, const 
struct drm_dp_vsc_sdp *vsc)
  }
  EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
  
+void drm_dp_as_sdp_log(struct drm_printer *p, const struct drm_dp_as_sdp *as_sdp)

+{
+   drm_printf(p, "DP SDP: AS_SDP, revision %u, length %u\n",
+  as_sdp->revision, as_sdp->length);
+   drm_printf(p, "vtotal: %d\n", as_sdp->vtotal);
+   drm_printf(p, "target_rr: %d\n", as_sdp->target_rr);
+   drm_printf(p, "duration_incr_ms: %d\n", as_sdp->duration_incr_ms);
+   drm_printf(p, "duration_decr_ms: %d\n", as_sdp->duration_decr_ms);
+   drm_printf(p, "operation_mode: %d\n", as_sdp->mode);
+}
+EXPORT_SYMBOL(drm_dp_as_sdp_log);
+
  /**
   * drm_dp_as_sdp_supported() - check if adaptive sync sdp is supported
   * @aux: DisplayPort AUX channel
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 4891bd916d26..e39a22a714e2 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1150,6 +1150,7 @@
  
  #define DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1 0x2214 /* 2.0 E11 */

  # define DP_ADAPTIVE_SYNC_SDP_SUPPORTED(1 << 0)
+# define DP_ADAPTIVE_SYNC_SDP_OPERATION_MODE   GENMASK(1, 0)


I am wondering if GENMASK can be used here, without including linux/bits.h

I might be wrong though.

Other than patch looks good to me.


Regards,

Ankit




  # define DP_AS_SDP_FIRST_HALF_LINE_OR_3840_PIXEL_CYCLE_WINDOW_NOT_SUPPORTED (1 
<< 1)
  # define DP_VSC_EXT_SDP_FRAMEWORK_VERSION_1_SUPPORTED  (1 << 4)
  
@@ -1639,10 +1640,12 @@ enum drm_dp_phy {

  #define DP_SDP_AUDIO_COPYMANAGEMENT   0x05 /* DP 1.2 */
  #define DP_SDP_ISRC   0x06 /* DP 1.2 */
  #define DP_SDP_VSC0x07 /* DP 1.2 */
+#define DP_SDP_ADAPTIVE_SYNC   0x22 /* DP 1.4 */
  #define DP_SDP_CAMERA_GENERIC(i)  (0x08 + (i)) /* 0-7, DP 1.3 */
  #define DP_SDP_PPS0x10 /* DP 1.4 */
  #define DP_SDP_VSC_EXT_VESA   0x20 /* DP 1.4 */
  #define DP_SDP_VSC_EXT_CEA0x21 /* DP 1.4 */
+
  /* 0x80+ CEA-861 infoframe types */
  
  #define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b

@@ -1798,4 +1801,11 @@ enum dp_content_type {
DP_CONTENT_TYPE_GAME = 0x04,
  };
  
+enum operation_mode {

+   DP_AS_SDP_AVT_DYNAMIC_VTOTAL = 0x00,
+   DP_AS_SDP_AVT_FIXED_VTOTAL = 0x01,
+   DP_AS_SDP_FAVT_TRR_NOT_REACHED = 0x02,
+   DP_AS_SDP_FAVT_TRR_REACHED = 0x03
+};
+
  #endif /* _DRM_DP_H_ */
diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index 7df19acdc790..10147ae96326 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -98,6 +98,35 @@ struct drm_dp_vsc_sdp {
enum dp_content_type content_type;
  };
  
+/**

+ * struct drm_dp_as_sdp - drm DP Adaptive Sync SDP
+ *
+ * This structure represents a DP AS SDP of drm
+ * It is based on DP 2.1 spec [Table 2-126:  Adaptive-Sync SDP Header Bytes] 
and
+ * [Table 2-127: Adaptive-Sync SDP Payload for DB0 through DB8]
+ *
+ * @sdp_type: Secondary-data packet type
+ * @revision: Revision Number
+ * @length: Number of valid data bytes
+ * @vtotal: Minimum Vertical Vtotal
+ * @target_rr: Target Refresh
+ * @duration_incr_ms: Successive frame duration increase
+ * @duration_decr_ms: Successive frame duration decrease
+ * @operation_mode: Adaptive Sync Operation Mode
+ */
+struct drm_dp_as_sdp {
+   unsigned char sdp_type;
+   unsigned char revision;
+   unsigned char length;
+   int vtotal;
+   int target_rr;
+   int duration_incr_ms;
+   int duration_decr_ms;
+   enum operation_mode mode;
+};
+
+void drm_dp_as_sdp_log(struct drm_printer *p,

Re: [PATCH v15 1/9] drm/dp: Add support to indicate if sink supports AS SDP

2024-03-04 Thread Nautiyal, Ankit K



On 3/1/2024 2:14 PM, Mitul Golani wrote:

Add an API that indicates support for Adaptive Sync SDP in
the sink, which can be utilized by the rest of the DP programming.

--v1:
- Format commit message properly.

Signed-off-by: Mitul Golani 


LGTM.

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/display/drm_dp_helper.c | 25 +
  include/drm/display/drm_dp_helper.h |  1 +
  2 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 266826eac4a7..f2fabb673aa4 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2948,6 +2948,31 @@ void drm_dp_vsc_sdp_log(struct drm_printer *p, const 
struct drm_dp_vsc_sdp *vsc)
  }
  EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
  
+/**

+ * drm_dp_as_sdp_supported() - check if adaptive sync sdp is supported
+ * @aux: DisplayPort AUX channel
+ * @dpcd: DisplayPort configuration data
+ *
+ * Returns true if adaptive sync sdp is supported, else returns false
+ */
+bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 
dpcd[DP_RECEIVER_CAP_SIZE])
+{
+   u8 rx_feature;
+
+   if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_13)
+   return false;
+
+   if (drm_dp_dpcd_readb(aux, DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1,
+ &rx_feature) != 1) {
+   drm_dbg_dp(aux->drm_dev,
+  "Failed to read 
DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1\n");
+   return false;
+   }
+
+   return (rx_feature & DP_ADAPTIVE_SYNC_SDP_SUPPORTED);
+}
+EXPORT_SYMBOL(drm_dp_as_sdp_supported);
+
  /**
   * drm_dp_vsc_sdp_supported() - check if vsc sdp is supported
   * @aux: DisplayPort AUX channel
diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index a62fcd051d4d..7df19acdc790 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -101,6 +101,7 @@ struct drm_dp_vsc_sdp {
  void drm_dp_vsc_sdp_log(struct drm_printer *p, const struct drm_dp_vsc_sdp 
*vsc);
  
  bool drm_dp_vsc_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE]);

+bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 
dpcd[DP_RECEIVER_CAP_SIZE]);
  
  int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]);
  


Re: [PATCH v14 6/9] drm/i915/display: Compute AS SDP parameters

2024-03-01 Thread Nautiyal, Ankit K



On 2/29/2024 10:09 PM, Mitul Golani wrote:

Add necessary function definitions to compute AS SDP data.
The new intel_dp_compute_as_sdp function computes AS SDP
values based on the display configuration, ensuring proper
handling of Variable Refresh Rate (VRR).

--v2:
- Added DP_SDP_ADAPTIVE_SYNC to infoframe_type_to_idx(). [Ankit]
- Separated patch for intel_read/write_dp_sdp. [Ankit]
- _HSW_VIDEO_DIP_ASYNC_DATA_A should be from ADL onward. [Ankit]
- Fixed indentation issues. [Ankit]

--v3:
- Added VIDEO_DIP_ENABLE_AS_HSW flag to intel_dp_set_infoframes.

--v4:
- Added HAS_VRR check before writing AS SDP.

--v5:
Added missed HAS_VRR check before reading AS SDP.

--v6:
- Used Adaptive Sync sink status as a check for read/write SDP. (Ankit)

--v7:
- Remove as_sdp_enable from crtc_state.
- Add a comment mentioning current support of
   DP_AS_SDP_AVT_FIXED_VTOTAL.
- Add state checker for AS_SDP infoframe enable.

--v8:
- Drop conn_state from intel_dp_compute_as_sdp, as not used.
- Remove fullstop in subject line.
Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_dp.c | 26 +
  1 file changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index b26efce4a041..86de854516ef 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2626,6 +2626,31 @@ static void intel_dp_compute_vsc_colorimetry(const 
struct intel_crtc_state *crtc
vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED;
  }
  
+static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,

+   struct intel_crtc_state *crtc_state)
+{
+   struct drm_dp_as_sdp *as_sdp = &crtc_state->infoframes.as_sdp;
+   struct intel_connector *connector = intel_dp->attached_connector;
+   const struct drm_display_mode *adjusted_mode =
+   &crtc_state->hw.adjusted_mode;
+   int vrefresh = drm_mode_vrefresh(adjusted_mode);
+
+   if (!intel_vrr_is_in_range(connector, vrefresh) ||



Instead of this we should check for crtc_state->vrr.enable as we intend 
to send the AS SDP when VRR is to be enabled. Sorry for missing this 
earlier.


Otherwise LGTM.

Reviewed-by: Ankit Nautiyal 




+   !intel_dp_as_sdp_supported(intel_dp))
+   return;
+
+   crtc_state->infoframes.enable |= 
intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);
+
+   /* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */
+   as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
+   as_sdp->length = 0x9;
+   as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+   as_sdp->target_rr = 0;
+   as_sdp->duration_incr_ms = 0;
+   as_sdp->duration_incr_ms = 0;
+}
+
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
 struct intel_crtc_state *crtc_state,
 const struct drm_connector_state 
*conn_state)
@@ -2951,6 +2976,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
g4x_dp_set_clock(encoder, pipe_config);
  
  	intel_vrr_compute_config(pipe_config, conn_state);

+   intel_dp_compute_as_sdp(intel_dp, pipe_config);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);


Re: [PATCH v14 4/9] drm/i915/dp: Add Read/Write support for Adaptive Sync SDP

2024-02-29 Thread Nautiyal, Ankit K



On 2/29/2024 10:09 PM, Mitul Golani wrote:

Add the necessary structures and functions to handle reading and
unpacking Adaptive Sync Secondary Data Packets. Also add support
to write and pack AS SDP.

--v2:
- Correct use of REG_BIT and REG_GENMASK. [Jani]
- Use as_sdp instead of async. [Jani]
- Remove unrelated comments and changes. [Jani]
- Correct code indent. [Jani]

--v3:
- Update definition names for AS SDP which are starting from
HSW, as these defines are applicable for ADLP+.(Ankit)

--v4:
- Remove as_sdp_mode from crtc_state.
- Drop metadata keyword.
- For consistency, update ADL_ prefix or post fix as required.

--v5:
- Check if AS_SDP bit is set in crtc_state->infoframes.enable. If not
   return.
- Check for HAS_AS_SDP() before setting VIDEO_DIP_ENABLE_AS_ADL mask.
Signed-off-by: Mitul Golani 
---
  .../drm/i915/display/intel_display_device.h   |  1 +
  drivers/gpu/drm/i915/display/intel_dp.c   | 91 +++
  drivers/gpu/drm/i915/display/intel_hdmi.c | 12 ++-
  drivers/gpu/drm/i915/i915_reg.h   |  8 ++
  include/drm/display/drm_dp_helper.h   |  2 +-
  5 files changed, 112 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
b/drivers/gpu/drm/i915/display/intel_display_device.h
index fe4268813786..6399fbc6c738 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -68,6 +68,7 @@ struct drm_printer;
  #define HAS_TRANSCODER(i915, trans)   
((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
  BIT(trans)) != 0)
  #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
+#define HAS_AS_SDP(i915)   (DISPLAY_VER(i915) >= 13)
  #define INTEL_NUM_PIPES(i915) 
(hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
  #define I915_HAS_HOTPLUG(i915)
(DISPLAY_INFO(i915)->has_hotplug)
  #define OVERLAY_NEEDS_PHYSICAL(i915)  
(DISPLAY_INFO(i915)->overlay_needs_physical)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index e13121dc3a03..7cf849015797 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4089,6 +4089,32 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state 
*crtc_state,
return false;
  }
  
+static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,

+   struct dp_sdp *sdp, size_t size)
+{
+   size_t length = sizeof(struct dp_sdp);
+
+   if (size < length)
+   return -ENOSPC;
+
+   memset(sdp, 0, size);
+
+   /* Prepare AS (Adaptive Sync) SDP Header */
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = as_sdp->sdp_type;
+   sdp->sdp_header.HB2 = 0x02;
+   sdp->sdp_header.HB3 = as_sdp->length;
+
+   /* Fill AS (Adaptive Sync) SDP Payload */
+   sdp->db[0] = as_sdp->mode;
+   sdp->db[1] = as_sdp->vtotal & 0xFF;
+   sdp->db[2] = (as_sdp->vtotal >> 8) & 0xFF;
+   sdp->db[3] = as_sdp->target_rr;
+   sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
+
+   return length;
+}
+
  static ssize_t
  intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915,
 const struct hdmi_drm_infoframe 
*drm_infoframe,
@@ -4188,6 +4214,10 @@ static void intel_write_dp_sdp(struct intel_encoder 
*encoder,
   
&crtc_state->infoframes.drm.drm,
   &sdp, 
sizeof(sdp));
break;
+   case DP_SDP_ADAPTIVE_SYNC:
+   len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
+  sizeof(sdp));
+   break;
default:
MISSING_CASE(type);
return;
@@ -4209,6 +4239,10 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
 VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+
+   if (HAS_AS_SDP(dev_priv))
+   dip_enable |= VIDEO_DIP_ENABLE_AS_ADL;
+
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

@@ -4230,6 +4264,36 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
+static

+int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
+  const void *buffer, size_t size)
+{
+   const struct dp_sdp *sdp = buffer;
+
+   if (size < sizeof(struct dp_sdp))
+   return -EINVAL;
+
+   memset(as_sdp, 0, sizeof(*as_sdp));
+
+   if (sdp->sdp_header.HB0 != 0)
+  

Re: [PATCH v12 2/8] drm: Add Adaptive Sync SDP logging

2024-02-29 Thread Nautiyal, Ankit K



On 2/29/2024 4:53 PM, Jani Nikula wrote:

On Thu, 29 Feb 2024, "Nautiyal, Ankit K"  wrote:

On 2/28/2024 8:08 PM, Mitul Golani wrote:

+enum operation_mode {
+   DP_AS_SDP_AVT_DYNAMIC_VTOTAL = 0x00,
+   DP_AS_SDP_AVT_FIXED_VTOTAL = 0x01,
+   DP_AS_SDP_FAVT_TRR_NOT_REACHED = 0x02,
+   DP_AS_SDP_FAVT_TRR_REACHED = 0x03
+};

We can drop the initialization here.

For stuff that needs to match the spec it's common to include the
initializations instead of relying on the auto enumeration.


Ah alright, got it.

Regards,

Ankit




BR,
Jani.




Re: [PATCH v12 6/8] drm/i915/display: Add state checker for Adaptive Sync SDP

2024-02-29 Thread Nautiyal, Ankit K



On 2/28/2024 8:08 PM, Mitul Golani wrote:

Enable infoframe and add state checker for Adaptive Sync
SDP enablement.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display.c | 46 
  drivers/gpu/drm/i915/display/intel_dp.c  |  2 +
  2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 00ac65a14029..be0a5fae4e58 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4781,6 +4781,17 @@ intel_compare_dp_vsc_sdp(const struct drm_dp_vsc_sdp *a,
a->content_type == b->content_type;
  }
  
+static bool

+intel_compare_dp_as_sdp(const struct drm_dp_as_sdp *a,
+   const struct drm_dp_as_sdp *b)
+{
+   return a->vtotal == b->vtotal &&
+   a->target_rr == b->target_rr &&
+   a->duration_incr_ms == b->duration_incr_ms &&
+   a->duration_decr_ms == b->duration_decr_ms &&
+   a->mode == b->mode;
+}
+
  static bool
  intel_compare_buffer(const u8 *a, const u8 *b, size_t len)
  {
@@ -4836,6 +4847,30 @@ pipe_config_dp_vsc_sdp_mismatch(struct drm_i915_private 
*i915,
drm_dp_vsc_sdp_log(&p, b);
  }
  
+static void

+pipe_config_dp_as_sdp_mismatch(struct drm_i915_private *i915,
+  bool fastset, const char *name,
+  const struct drm_dp_as_sdp *a,
+  const struct drm_dp_as_sdp *b)
+{
+   struct drm_printer p;
+
+   if (fastset) {
+   p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, NULL);
+
+   drm_printf(&p, "fastset requirement not met in %s dp sdp\n", 
name);
+   } else {
+   p = drm_err_printer(&i915->drm, NULL);
+
+   drm_printf(&p, "mismatch in %s dp sdp\n", name);
+   }
+
+   drm_printf(&p, "expected:\n");
+   drm_dp_as_sdp_log(&p, a);
+   drm_printf(&p, "found:\n");
+   drm_dp_as_sdp_log(&p, b);
+}
+
  /* Returns the length up to and including the last differing byte */
  static size_t
  memcmp_diff_len(const u8 *a, const u8 *b, size_t len)
@@ -5089,6 +5124,16 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
} \
  } while (0)
  
+#define PIPE_CONF_CHECK_DP_AS_SDP(name) do { \

+   if (!intel_compare_dp_as_sdp(¤t_config->infoframes.name, \
+ &pipe_config->infoframes.name)) { \
+   pipe_config_dp_as_sdp_mismatch(dev_priv, fastset, 
__stringify(name), \
+   
¤t_config->infoframes.name, \
+   &pipe_config->infoframes.name); 
\
+   ret = false; \
+   } \
+} while (0)
+
  #define PIPE_CONF_CHECK_BUFFER(name, len) do { \
BUILD_BUG_ON(sizeof(current_config->name) != (len)); \
BUILD_BUG_ON(sizeof(pipe_config->name) != (len)); \
@@ -5270,6 +5315,7 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_INFOFRAME(hdmi);
PIPE_CONF_CHECK_INFOFRAME(drm);
PIPE_CONF_CHECK_DP_VSC_SDP(vsc);
+   PIPE_CONF_CHECK_DP_AS_SDP(as_sdp);
  
  	PIPE_CONF_CHECK_X(sync_mode_slaves_mask);

PIPE_CONF_CHECK_I(master_transcoder);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 1cd3cc0d0c0b..2ec1f923a5a0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2648,6 +2648,8 @@ static void intel_dp_compute_as_sdp(struct intel_dp 
*intel_dp,
as_sdp->target_rr = 0;
as_sdp->duration_incr_ms = 0;
as_sdp->duration_incr_ms = 0;
+
+   crtc_state->infoframes.enable |= 
intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);



This change does not seem to belong to this patch.

Regards,

Ankit


  }
  
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,


Re: [PATCH v12 5/8] drm/i915/display: Compute AS SDP parameters.

2024-02-29 Thread Nautiyal, Ankit K



On 2/28/2024 8:08 PM, Mitul Golani wrote:

Add necessary function definitions to compute AS SDP data.
The new intel_dp_compute_as_sdp function computes AS SDP
values based on the display configuration, ensuring proper
handling of Variable Refresh Rate (VRR).

--v2:
- Added DP_SDP_ADAPTIVE_SYNC to infoframe_type_to_idx(). [Ankit]
- Separated patch for intel_read/write_dp_sdp. [Ankit]
- _HSW_VIDEO_DIP_ASYNC_DATA_A should be from ADL onward. [Ankit]
- Fixed indentation issues. [Ankit]

--v3:
- Added VIDEO_DIP_ENABLE_AS_HSW flag to intel_dp_set_infoframes.

--v4:
- Added HAS_VRR check before writing AS SDP.

--v5:
Added missed HAS_VRR check before reading AS SDP.

--v6:
- Used Adaptive Sync sink status as a check for read/write SDP. (Ankit)

--v7:
- Remove as_sdp_enable from crtc_state.
- Add a comment mentioning current support of
   DP_AS_SDP_AVT_FIXED_VTOTAL.
- Add state checker for AS_SDP infoframe enable.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 7eb83924f3fe..1cd3cc0d0c0b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2626,6 +2626,30 @@ static void intel_dp_compute_vsc_colorimetry(const 
struct intel_crtc_state *crtc
vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED;
  }
  
+static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,

+   struct intel_crtc_state *crtc_state,
+   const struct drm_connector_state 
*conn_state)


Drop conn_state, it is not used in the function.

Also remove fullstop in subject line.

With the above addressed, this is:

Reviewed-by: Ankit Nautiyal 



+{
+   struct drm_dp_as_sdp *as_sdp = &crtc_state->infoframes.as_sdp;
+   struct intel_connector *connector = intel_dp->attached_connector;
+   const struct drm_display_mode *adjusted_mode =
+   &crtc_state->hw.adjusted_mode;
+   int vrefresh = drm_mode_vrefresh(adjusted_mode);
+
+   if (!intel_vrr_is_in_range(connector, vrefresh) ||
+   !intel_dp_as_sdp_supported(intel_dp))
+   return;
+
+   /* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */
+   as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
+   as_sdp->length = 0x9;
+   as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+   as_sdp->target_rr = 0;
+   as_sdp->duration_incr_ms = 0;
+   as_sdp->duration_incr_ms = 0;
+}
+
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
 struct intel_crtc_state *crtc_state,
 const struct drm_connector_state 
*conn_state)
@@ -2951,6 +2975,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
g4x_dp_set_clock(encoder, pipe_config);
  
  	intel_vrr_compute_config(pipe_config, conn_state);

+   intel_dp_compute_as_sdp(intel_dp, pipe_config, conn_state);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);


Re: [PATCH v12 4/8] drm/i915/display/dp: Add wrapper function to check AS SDP

2024-02-29 Thread Nautiyal, Ankit K



On 2/28/2024 8:08 PM, Mitul Golani wrote:

Add a wrapper function to check if both the source and
sink support Adaptive Sync SDP.

Signed-off-by: Mitul Golani 


Just use drm/i915/dp in subject line


Otherwise LGTM.

Reviewed-by: Ankit Nautiyal 



---
  drivers/gpu/drm/i915/display/intel_display_device.h | 1 +
  drivers/gpu/drm/i915/display/intel_dp.c | 8 
  drivers/gpu/drm/i915/display/intel_dp.h | 1 +
  3 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h 
b/drivers/gpu/drm/i915/display/intel_display_device.h
index fe4268813786..6399fbc6c738 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -68,6 +68,7 @@ struct drm_printer;
  #define HAS_TRANSCODER(i915, trans)   
((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
  BIT(trans)) != 0)
  #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
+#define HAS_AS_SDP(i915)   (DISPLAY_VER(i915) >= 13)
  #define INTEL_NUM_PIPES(i915) 
(hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
  #define I915_HAS_HOTPLUG(i915)
(DISPLAY_INFO(i915)->has_hotplug)
  #define OVERLAY_NEEDS_PHYSICAL(i915)  
(DISPLAY_INFO(i915)->overlay_needs_physical)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index e5377cdc71c6..7eb83924f3fe 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -120,6 +120,14 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
return dig_port->base.type == INTEL_OUTPUT_EDP;
  }
  
+bool intel_dp_as_sdp_supported(struct intel_dp *intel_dp)

+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+   return HAS_AS_SDP(i915) &&
+   drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd);
+}
+
  static void intel_dp_unset_edid(struct intel_dp *intel_dp);
  
  /* Is link rate UHBR and thus 128b/132b? */

diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 530cc97bc42f..cc5e069091ff 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -80,6 +80,7 @@ void intel_dp_audio_compute_config(struct intel_encoder 
*encoder,
   struct drm_connector_state *conn_state);
  bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp);
  bool intel_dp_is_edp(struct intel_dp *intel_dp);
+bool intel_dp_as_sdp_supported(struct intel_dp *intel_dp);
  bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);
  int intel_dp_link_symbol_size(int rate);
  int intel_dp_link_symbol_clock(int rate);


Re: [PATCH v12 3/8] drm/i915/dp: Add Read/Write support for Adaptive Sync SDP

2024-02-29 Thread Nautiyal, Ankit K



On 2/28/2024 8:08 PM, Mitul Golani wrote:

Add the necessary structures and functions to handle reading and
unpacking Adaptive Sync Secondary Data Packets. Also add support
to write and pack AS SDP.

--v2:
- Correct use of REG_BIT and REG_GENMASK. [Jani]
- Use as_sdp instead of async. [Jani]
- Remove unrelated comments and changes. [Jani]
- Correct code indent. [Jani]

--v3:
- Update definition names for AS SDP which are starting from
HSW, as these defines are applicable for ADLP+.(Ankit)

--v4:
- Remove as_sdp_mode from crtc_state.
- Drop metadata keyword.
- For consistency, update ADL_ prefix or post fix as required.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_dp.c   | 88 ++-
  drivers/gpu/drm/i915/display/intel_hdmi.c | 12 +++-
  drivers/gpu/drm/i915/i915_reg.h   |  8 +++
  include/drm/display/drm_dp_helper.h   |  1 +
  4 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index e13121dc3a03..e5377cdc71c6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4089,6 +4089,32 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state 
*crtc_state,
return false;
  }
  
+static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,

+   struct dp_sdp *sdp, size_t size)
+{
+   size_t length = sizeof(struct dp_sdp);
+
+   if (size < length)
+   return -ENOSPC;
+
+   memset(sdp, 0, size);
+
+   /* Prepare AS (Adaptive Sync) SDP Header */
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = as_sdp->sdp_type;
+   sdp->sdp_header.HB2 = 0x02;
+   sdp->sdp_header.HB3 = as_sdp->length;
+
+   /* Fill AS (Adaptive Sync) SDP Payload */
+   sdp->db[0] = as_sdp->mode;
+   sdp->db[1] = as_sdp->vtotal & 0xFF;
+   sdp->db[2] = (as_sdp->vtotal >> 8) & 0xFF;
+   sdp->db[3] = as_sdp->target_rr;
+   sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
+
+   return length;
+}
+
  static ssize_t
  intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915,
 const struct hdmi_drm_infoframe 
*drm_infoframe,
@@ -4188,6 +4214,10 @@ static void intel_write_dp_sdp(struct intel_encoder 
*encoder,
   
&crtc_state->infoframes.drm.drm,
   &sdp, 
sizeof(sdp));
break;
+   case DP_SDP_ADAPTIVE_SYNC:
+   len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
+  sizeof(sdp));
+   break;
default:
MISSING_CASE(type);
return;
@@ -4208,7 +4238,8 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
-VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK |
+VIDEO_DIP_ENABLE_AS_ADL;
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

@@ -4230,6 +4261,36 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
+static

+int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
+  const void *buffer, size_t size)
+{
+   const struct dp_sdp *sdp = buffer;
+
+   if (size < sizeof(struct dp_sdp))
+   return -EINVAL;
+
+   memset(as_sdp, 0, sizeof(*as_sdp));
+
+   if (sdp->sdp_header.HB0 != 0)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB1 != DP_SDP_ADAPTIVE_SYNC)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB2 != 0x02)
+   return -EINVAL;
+
+   if ((sdp->sdp_header.HB3 & 0x3F) != 9)
+   return -EINVAL;
+
+   as_sdp->mode = sdp->db[0] & AS_SDP_OP_MODE;
+   as_sdp->vtotal = ((u64)sdp->db[2] << 32) | (u64)sdp->db[1];
+   as_sdp->target_rr = (u64)sdp->db[3] | ((u64)sdp->db[4] & 0x3);
+
+   return 0;
+}
+
  static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
   const void *buffer, size_t size)
  {
@@ -4300,6 +4361,27 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp 
*vsc,
return 0;
  }
  
+static int

+intel_read_dp_infoframe_as_sdp(struct intel_encoder *encoder,
+   struct intel_crtc_state *crtc_state,
+   struct drm_dp_as_sdp *as_sdp)
+{
+   struct i

Re: [PATCH v12 2/8] drm: Add Adaptive Sync SDP logging

2024-02-29 Thread Nautiyal, Ankit K



On 2/28/2024 8:08 PM, Mitul Golani wrote:

Add structure representing Adaptive Sync Secondary Data Packet (AS SDP).
Also, add Adaptive Sync SDP logging in drm_dp_helper.c to facilitate
debugging.

--v2:
- Update logging. [Jani, Ankit]
- Use 'as_sdp' instead of 'async' [Ankit]
- Correct define placeholders to where they are actually used. [Jani]
- Update members in 'as_sdp' structure to make it uniform. [Jani]

--v3:
- Added changes to dri-devel mailing list. No code changes.

--v4:
- Instead of directly using operation mode, use an enum to accommodate
all operation modes (Ankit).

--v5:
Nit-pick changes to commit message.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/display/drm_dp_helper.c   | 12 +++
  .../drm/i915/display/intel_crtc_state_dump.c  | 12 +++
  .../drm/i915/display/intel_display_types.h|  1 +
  include/drm/display/drm_dp.h  |  9 +
  include/drm/display/drm_dp_helper.h   | 33 +++
  5 files changed, 67 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index f94c04db7187..b1459ac92aea 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2913,6 +2913,18 @@ void drm_dp_vsc_sdp_log(struct drm_printer *p, const 
struct drm_dp_vsc_sdp *vsc)
  }
  EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
  
+void drm_dp_as_sdp_log(struct drm_printer *p, const struct drm_dp_as_sdp *as_sdp)

+{
+   drm_printf(p, "DP SDP: AS_SDP, revision %u, length %u\n",
+  as_sdp->revision, as_sdp->length);
+   drm_printf(p, "vtotal: %d\n", as_sdp->vtotal);
+   drm_printf(p, "target_rr: %d\n", as_sdp->target_rr);
+   drm_printf(p, "duration_incr_ms: %d\n", as_sdp->duration_incr_ms);
+   drm_printf(p, "duration_decr_ms: %d\n", as_sdp->duration_decr_ms);
+   drm_printf(p, "operation_mode: %d\n", as_sdp->mode);
+}
+EXPORT_SYMBOL(drm_dp_as_sdp_log);
+
  /**
   * drm_dp_as_sdp_supported() - check if adaptive sync sdp is supported
   * @aux: DisplayPort AUX channel
diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c 
b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
index 4bcf446c75f4..26d77c2934e8 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
@@ -60,6 +60,15 @@ intel_dump_dp_vsc_sdp(struct drm_i915_private *i915,
drm_dp_vsc_sdp_log(&p, vsc);
  }
  
+static void

+intel_dump_dp_as_sdp(struct drm_i915_private *i915,
+const struct drm_dp_as_sdp *as_sdp)
+{
+   struct drm_printer p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, 
"AS_SDP");
+
+   drm_dp_as_sdp_log(&p, as_sdp);
+}
+
  static void
  intel_dump_buffer(struct drm_i915_private *i915,
  const char *prefix, const u8 *buf, size_t len)
@@ -299,6 +308,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state 
*pipe_config,
if (pipe_config->infoframes.enable &
intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA))
intel_dump_infoframe(i915, &pipe_config->infoframes.drm);
+   if (pipe_config->infoframes.enable &
+   intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC))
+   intel_dump_dp_as_sdp(i915, &pipe_config->infoframes.as_sdp);
if (pipe_config->infoframes.enable &
intel_hdmi_infoframe_enable(DP_SDP_VSC))
intel_dump_dp_vsc_sdp(i915, &pipe_config->infoframes.vsc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 8ce986fadd9a..1256730ea276 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1335,6 +1335,7 @@ struct intel_crtc_state {
union hdmi_infoframe hdmi;
union hdmi_infoframe drm;
struct drm_dp_vsc_sdp vsc;
+   struct drm_dp_as_sdp as_sdp;
} infoframes;
  
  	u8 eld[MAX_ELD_BYTES];

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 281afff6ee4e..0601b95d53db 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1578,10 +1578,12 @@ enum drm_dp_phy {
  #define DP_SDP_AUDIO_COPYMANAGEMENT   0x05 /* DP 1.2 */
  #define DP_SDP_ISRC   0x06 /* DP 1.2 */
  #define DP_SDP_VSC0x07 /* DP 1.2 */
+#define DP_SDP_ADAPTIVE_SYNC   0x22 /* DP 1.4 */
  #define DP_SDP_CAMERA_GENERIC(i)  (0x08 + (i)) /* 0-7, DP 1.3 */
  #define DP_SDP_PPS0x10 /* DP 1.4 */
  #define DP_SDP_VSC_EXT_VESA   0x20 /* DP 1.4 */
  #define DP_SDP_VSC_EXT_CEA0x21 /* DP 1.4 */
+
  /* 0x80+ CEA-861 infoframe types */
  
  #define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b

@@ -1737,4 +1739,11 @@ enum dp_content_type {
DP_CONTENT_TYPE_GAME = 0x04,
  };
  
+enum operation_mode {

+   DP_AS_SDP_AVT_DYNAMI

Re: [PATCH v12 1/8] drm/dp: Add support to indicate if sink supports AS SDP

2024-02-29 Thread Nautiyal, Ankit K



On 2/28/2024 8:08 PM, Mitul Golani wrote:

Add an API that indicates support for Adaptive Sync SDP in
the sink, which can be utilized by the rest of the DP programming.

--v1:
- Format commit message properly.

Signed-off-by: Mitul Golani 


LGTM.

Reviewed-by: Ankit Nautiyal 


---
  drivers/gpu/drm/display/drm_dp_helper.c | 25 +
  include/drm/display/drm_dp_helper.h |  1 +
  2 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 9ac52cf5d4d8..f94c04db7187 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2913,6 +2913,31 @@ void drm_dp_vsc_sdp_log(struct drm_printer *p, const 
struct drm_dp_vsc_sdp *vsc)
  }
  EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
  
+/**

+ * drm_dp_as_sdp_supported() - check if adaptive sync sdp is supported
+ * @aux: DisplayPort AUX channel
+ * @dpcd: DisplayPort configuration data
+ *
+ * Returns true if adaptive sync sdp is supported, else returns false
+ */
+bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 
dpcd[DP_RECEIVER_CAP_SIZE])
+{
+   u8 rx_feature;
+
+   if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_13)
+   return false;
+
+   if (drm_dp_dpcd_readb(aux, DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1,
+ &rx_feature) != 1) {
+   drm_dbg_dp(aux->drm_dev,
+  "Failed to read 
DP_DPRX_FEATURE_ENUMERATION_LIST_CONT_1\n");
+   return false;
+   }
+
+   return (rx_feature & DP_ADAPTIVE_SYNC_SDP_SUPPORTED);
+}
+EXPORT_SYMBOL(drm_dp_as_sdp_supported);
+
  /**
   * drm_dp_vsc_sdp_supported() - check if vsc sdp is supported
   * @aux: DisplayPort AUX channel
diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index 0c1a4021e098..7c1aa3a703c8 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -101,6 +101,7 @@ struct drm_dp_vsc_sdp {
  void drm_dp_vsc_sdp_log(struct drm_printer *p, const struct drm_dp_vsc_sdp 
*vsc);
  
  bool drm_dp_vsc_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE]);

+bool drm_dp_as_sdp_supported(struct drm_dp_aux *aux, const u8 
dpcd[DP_RECEIVER_CAP_SIZE]);
  
  int drm_dp_psr_setup_time(const u8 psr_cap[EDP_PSR_RECEIVER_CAP_SIZE]);
  


Re: [PATCH 5/6] drm/i915/display: Compute vrr_vsync params

2024-02-26 Thread Nautiyal, Ankit K



On 2/22/2024 5:42 PM, Mitul Golani wrote:

Compute vrr_vsync_start/end  which sets the position
for hardware to send the Vsync at a fixed position
relative to the end of the Vblank.

--v2:
- Update, VSYNC_START/END macros to VRR_VSYNC_START/END.(Ankit)
- Update bit fields of VRR_VSYNC_START/END.(Ankit)

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display.c   |  1 +
  drivers/gpu/drm/i915/display/intel_display_types.h |  1 +
  drivers/gpu/drm/i915/display/intel_vrr.c   | 12 
  drivers/gpu/drm/i915/i915_reg.h|  7 +++
  4 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 00ac65a14029..5994f7fcbb6a 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5321,6 +5321,7 @@ intel_pipe_config_compare(const struct intel_crtc_state 
*current_config,
PIPE_CONF_CHECK_I(vrr.flipline);
PIPE_CONF_CHECK_I(vrr.pipeline_full);
PIPE_CONF_CHECK_I(vrr.guardband);
+   PIPE_CONF_CHECK_BOOL(vrr.as_sdp_enable);


Need to add PIPE_CONF_CHECK_I(vrr.vsync_start/end).



}
  
  #undef PIPE_CONF_CHECK_X

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 93b4b7dff1d0..7859e4baad4b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1416,6 +1416,7 @@ struct intel_crtc_state {
u16 flipline, vmin, vmax, guardband;
u8 as_sdp_mode;
bool as_sdp_enable;
+   u32 vsync_end, vsync_start;
} vrr;
  
  	/* Stream Splitter for eDP MSO */

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 08e3ba69bd30..29ddf504d94b 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -150,6 +150,13 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
  
  	crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
  
+	crtc_state->vrr.vsync_start =

+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   
VRR_VSYNC_START(crtc_state->hw.adjusted_mode.vsync_start));
+   crtc_state->vrr.vsync_end =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   (VRR_VSYNC_END(crtc_state->hw.adjusted_mode.vsync_end) 
>> 16));


Need to add trans_vrr_start/end also in vrr_get_config.

Make sure to read/write these only when we intend to send adaptive_sync sdp.


Regards,

Ankit



+
/*
 * For XE_LPD+, we use guardband and pipeline override
 * is deprecated.
@@ -273,8 +280,13 @@ void intel_vrr_get_config(struct intel_crtc_state 
*crtc_state)
u32 trans_vrr_ctl;
  
  	trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_CTL(cpu_transcoder));

+   bool as_sdp_enabled =
+   intel_de_read(dev_priv,
+ HSW_TVIDEO_DIP_CTL(cpu_transcoder));
  
  	crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE;

+   crtc_state->vrr.as_sdp_enable =
+   as_sdp_enabled & VIDEO_DIP_ENABLE_ADAPTIVE_SYNC;
  
  	if (DISPLAY_VER(dev_priv) >= 13)

crtc_state->vrr.guardband =
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c02ea07af4c2..3e0853458ef4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2007,7 +2007,9 @@
  #define _TRANS_VRR_CTL_B  0x61420
  #define _TRANS_VRR_CTL_C  0x62420
  #define _TRANS_VRR_CTL_D  0x63420
+#define _TRANS_VRR_VSYNC_A 0x60078
  #define TRANS_VRR_CTL(trans)  _MMIO_TRANS2(trans, 
_TRANS_VRR_CTL_A)
+#define TRANS_VRR_VSYNC(trans) _MMIO_TRANS2(trans, 
_TRANS_VRR_VSYNC_A)
  #define   VRR_CTL_VRR_ENABLE  REG_BIT(31)
  #define   VRR_CTL_IGN_MAX_SHIFT   REG_BIT(30)
  #define   VRR_CTL_FLIP_LINE_ENREG_BIT(29)
@@ -2087,6 +2089,11 @@
  #define TRANS_VRR_STATUS2(trans)  _MMIO_TRANS2(trans, 
_TRANS_VRR_STATUS2_A)
  #define   VRR_STATUS2_VERT_LN_CNT_MASKREG_GENMASK(19, 0)
  
+#define   VRR_VSYNC_END_MASK		REG_GENMASK(28, 16)

+#define   VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VSYNC_END_MASK, 
(vsync_end))
+#define   VRR_VSYNC_START_MASK REG_GENMASK(12, 0)
+#define   VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VSYNC_START_MASK, 
(vsync_start))
+
  #define _TRANS_PUSH_A 0x60A70
  #define _TRANS_PUSH_B 0x61A70
  #define _TRANS_PUSH_C 0x62A70


Re: [PATCH 4/6] drm/i915/display: Compute AS SDP parameters.

2024-02-26 Thread Nautiyal, Ankit K



On 2/22/2024 5:42 PM, Mitul Golani wrote:

Add necessary functions definitions to enable
and compute AS SDP data. The new `intel_dp_compute_as_sdp`
function computes AS SDP values based on the display
configuration, ensuring proper handling of Variable Refresh
Rate (VRR).

--v2:
- Add DP_SDP_ADAPTIVE_SYNC to infoframe_type_to_idx().[Ankit]
- separate patch for intel_read/write_dp_sdp [Ankit].
- _HSW_VIDEO_DIP_ASYNC_DATA_A should be from ADL onward [Ankit]
- To fix indentation [Ankit]

--v3:
- Add VIDEO_DIP_ENABLE_AS_HSW flag to intel_dp_set_infoframes.

--v4:
- Add HAS_VRR check before write as sdp.

--v5:
- Add missed HAS_VRR check before read as sdp.

--v6:
Use Adaptive Sync sink status, which can be
used as a check for read/write sdp. (Ankit)

Signed-off-by: Mitul Golani 
---
  .../drm/i915/display/intel_display_types.h|  1 +
  drivers/gpu/drm/i915/display/intel_dp.c   | 28 +++
  drivers/gpu/drm/i915/display/intel_vrr.c  |  4 ++-
  3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 2accfe41160d..93b4b7dff1d0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1415,6 +1415,7 @@ struct intel_crtc_state {
u8 pipeline_full;
u16 flipline, vmin, vmax, guardband;
u8 as_sdp_mode;
+   bool as_sdp_enable;


This is again specific to DP, we can do away with this in vrr struct.


} vrr;
  
  	/* Stream Splitter for eDP MSO */

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index b370e1da4735..5c1e2301dd52 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2617,6 +2617,33 @@ static void intel_dp_compute_vsc_colorimetry(const 
struct intel_crtc_state *crtc
vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED;
  }
  
+static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,

+   struct intel_crtc_state *crtc_state,
+   const struct drm_connector_state 
*conn_state)
+{
+   struct drm_dp_as_sdp *as_sdp = &crtc_state->infoframes.as_sdp;
+   struct intel_connector *connector = intel_dp->attached_connector;
+   const struct drm_display_mode *adjusted_mode =
+   &crtc_state->hw.adjusted_mode;
+   int vrefresh = drm_mode_vrefresh(adjusted_mode);
+
+   if (!intel_vrr_is_in_range(connector, vrefresh) || 
!crtc_state->vrr.as_sdp_enable)
+   return;
+
+   as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
+   as_sdp->length = 0x9;
+   as_sdp->mode = crtc_state->vrr.as_sdp_mode;
+   as_sdp->vtotal = adjusted_mode->vtotal;
+
+   if (as_sdp->mode == DP_AS_SDP_AVT_FIXED_VTOTAL) {


Currently we are just supporting DP_AS_SDP_AVT_FIXED_VTOTAL so this 
check is not required.


But we can add a comment mentioning the same.



+   as_sdp->target_rr = 0;
+   as_sdp->duration_incr_ms = 0;
+   as_sdp->duration_incr_ms = 0;
+   }
+
+   crtc_state->infoframes.enable |= 
intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);
+}


We will need to add this to state checker, something like 
PIPE_CONF_CHECK_DP_AS_SDP and add function to compare the adaptive sync 
sdp struct.



Regards,

Ankit


+
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
 struct intel_crtc_state *crtc_state,
 const struct drm_connector_state 
*conn_state)
@@ -2942,6 +2969,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
g4x_dp_set_clock(encoder, pipe_config);
  
  	intel_vrr_compute_config(pipe_config, conn_state);

+   intel_dp_compute_as_sdp(intel_dp, pipe_config, conn_state);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index d2ab7e571e62..08e3ba69bd30 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -167,9 +167,11 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
crtc_state->vrr.enable = true;
crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
  
-		if (drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd))

+   if (drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd)) {
+   crtc_state->vrr.as_sdp_enable = true;
crtc_state->vrr.as_sdp_mode =
DP_AS_SDP_AVT_DYNAMIC_VTOTAL;
+   }
}
  }
  


Re: [PATCH 3/6] drm/i915/dp: Add Read/Write support for Adaptive Sync SDP

2024-02-26 Thread Nautiyal, Ankit K



On 2/22/2024 5:42 PM, Mitul Golani wrote:

Add the necessary structures and functions to handle reading and
unpacking Adaptive Sync Secondary Data Packets. Also add support
to write and pack AS SDP.

--v2:
- Correct use of REG_BIT and REG_GENMASK. [Jani]
- Use as_sdp instead of async. [Jani]
- Remove unrelated comments and changes. [Jani]
- Correct code indent. [Jani]

--v3:
- Update definition names for AS SDP which are starting from
HSW, as these defines are applicable for ADLP+.(Ankit)

Signed-off-by: Mitul Golani 
---
  .../drm/i915/display/intel_display_types.h|  1 +
  drivers/gpu/drm/i915/display/intel_dp.c   | 89 ++-
  drivers/gpu/drm/i915/display/intel_hdmi.c | 12 ++-
  drivers/gpu/drm/i915/display/intel_vrr.c  |  5 ++
  drivers/gpu/drm/i915/i915_reg.h   |  8 ++
  5 files changed, 111 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index a6991bc3f07b..2accfe41160d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1414,6 +1414,7 @@ struct intel_crtc_state {
bool enable, in_range;
u8 pipeline_full;
u16 flipline, vmin, vmax, guardband;
+   u8 as_sdp_mode;



I think this is DP specific, lets not add this thing here.



} vrr;
  
  	/* Stream Splitter for eDP MSO */

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 217196196e50..b370e1da4735 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -95,7 +95,6 @@
  #define INTEL_DP_RESOLUTION_STANDARD  (2 << INTEL_DP_RESOLUTION_SHIFT_MASK)
  #define INTEL_DP_RESOLUTION_FAILSAFE  (3 << INTEL_DP_RESOLUTION_SHIFT_MASK)
  
-

  /* Constants for DP DSC configurations */
  static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15};
  
@@ -4089,6 +4088,32 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,

return false;
  }
  
+static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,

+   struct dp_sdp *sdp, size_t size)
+{
+   size_t length = sizeof(struct dp_sdp);
+
+   if (size < length)
+   return -ENOSPC;
+
+   memset(sdp, 0, size);
+
+   /* Prepare AS (Adaptive Sync) SDP Header */
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = as_sdp->sdp_type;
+   sdp->sdp_header.HB2 = 0x02;
+   sdp->sdp_header.HB3 = as_sdp->length;
+
+   /* Fill AS (Adaptive Sync) SDP Payload */
+   sdp->db[0] = as_sdp->mode;
+   sdp->db[1] = as_sdp->vtotal & 0xFF;
+   sdp->db[2] = (as_sdp->vtotal >> 8) & 0xFF;
+   sdp->db[3] = as_sdp->target_rr;
+   sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
+
+   return length;
+}
+
  static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
 struct dp_sdp *sdp, size_t size)
  {
@@ -4256,6 +4281,10 @@ static void intel_write_dp_sdp(struct intel_encoder 
*encoder,
   
&crtc_state->infoframes.drm.drm,
   &sdp, 
sizeof(sdp));
break;
+   case DP_SDP_ADAPTIVE_SYNC:
+   len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
+  sizeof(sdp));
+   break;
default:
MISSING_CASE(type);
return;
@@ -4276,7 +4305,8 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
-VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK |
+VIDEO_DIP_ENABLE_ADAPTIVE_SYNC;
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

@@ -4298,6 +4328,36 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
+static

+int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
+  const void *buffer, size_t size)
+{
+   const struct dp_sdp *sdp = buffer;
+
+   if (size < sizeof(struct dp_sdp))
+   return -EINVAL;
+
+   memset(as_sdp, 0, sizeof(*as_sdp));
+
+   if (sdp->sdp_header.HB0 != 0)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB1 != DP_SDP_ADAPTIVE_SYNC)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB2 != 0x02)
+   return -EINVAL;
+

Re: [PATCH 3/6] drm/i915/dp: Add Read/Write support for Adaptive Sync SDP

2024-02-19 Thread Nautiyal, Ankit K



On 2/16/2024 7:50 PM, Mitul Golani wrote:

Add the necessary structures and functions to handle reading and
unpacking Adaptive Sync Secondary Data Packets. Also add support
to write and pack AS SDP.

--v2:
- Correct use of REG_BIT and REG_GENMASK. [Jani]
- Use as_sdp instead of async. [Jani]
- Remove unrelated comments and changes. [Jani]
- Correct code indent. [Jani]

--v3:
- Update definition names for AS SDP which are starting from
HSW, as these defines are applicable for ADLP+.(Ankit)

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_dp.c   | 95 ++-
  drivers/gpu/drm/i915/display/intel_hdmi.c | 12 ++-
  drivers/gpu/drm/i915/i915_reg.h   |  8 ++
  include/drm/display/drm_dp.h  |  2 +-
  include/drm/display/drm_dp_helper.h   |  2 +
  5 files changed, 114 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 217196196e50..d68fb9d45054 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -95,7 +95,6 @@
  #define INTEL_DP_RESOLUTION_STANDARD  (2 << INTEL_DP_RESOLUTION_SHIFT_MASK)
  #define INTEL_DP_RESOLUTION_FAILSAFE  (3 << INTEL_DP_RESOLUTION_SHIFT_MASK)
  
-

  /* Constants for DP DSC configurations */
  static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15};
  
@@ -4089,6 +4088,34 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,

return false;
  }
  
+static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,

+   struct dp_sdp *sdp, size_t size)
+{
+   size_t length = sizeof(struct dp_sdp);
+
+   if (size < length)
+   return -ENOSPC;
+
+   memset(sdp, 0, size);
+
+   /* Prepare AS (Adaptive Sync) SDP Header */
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = as_sdp->sdp_type;
+   sdp->sdp_header.HB2 = 0x02;
+   sdp->sdp_header.HB3 = as_sdp->length;
+
+   /* Fill AS (Adaptive Sync) SDP Payload */
+   sdp->db[1] = 0x0;
+   sdp->db[1] = as_sdp->vtotal & 0xFF;
+   sdp->db[2] = (as_sdp->vtotal >> 8) & 0xF;
+   sdp->db[3] = 0x0;
+   sdp->db[4] = 0x0;
+   sdp->db[7] = 0x0;
+   sdp->db[8] = 0x0;
+
+   return length;
+}
+
  static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
 struct dp_sdp *sdp, size_t size)
  {
@@ -4256,6 +4283,10 @@ static void intel_write_dp_sdp(struct intel_encoder 
*encoder,
   
&crtc_state->infoframes.drm.drm,
   &sdp, 
sizeof(sdp));
break;
+   case DP_SDP_ADAPTIVE_SYNC:
+   len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
+  sizeof(sdp));
+   break;
default:
MISSING_CASE(type);
return;
@@ -4276,7 +4307,8 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
-VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK |
+VIDEO_DIP_ENABLE_ADAPTIVE_SYNC;
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

@@ -4298,6 +4330,40 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
+static

+int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
+  const void *buffer, size_t size)
+{
+   const struct dp_sdp *sdp = buffer;
+
+   if (size < sizeof(struct dp_sdp))
+   return -EINVAL;
+
+   memset(as_sdp, 0, sizeof(*as_sdp));
+
+   if (sdp->sdp_header.HB0 != 0)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB1 != DP_SDP_ADAPTIVE_SYNC)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB2 != 0x02)
+   return -EINVAL;
+
+   if ((sdp->sdp_header.HB3 & 0x3F) != 9)
+   return -EINVAL;
+
+   if ((sdp->db[0] & AS_SDP_OP_MODE) != 0x0)
+   return -EINVAL;
+
+   as_sdp->vtotal = ((u64)sdp->db[2] << 32) | (u64)sdp->db[1];
+   as_sdp->target_rr = 0;
+   as_sdp->duration_incr_ms = 0;
+   as_sdp->duration_decr_ms = 0;
+
+   return 0;
+}
+
  static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
   const void *buffer, size_t size)
  {
@@ -4368,6 +4434,27 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp 
*vsc,
return 0;
  }
  

Re: [PATCH 6/6] drm/i915/display: Read/Write AS sdp only when sink/source has enabled

2024-02-19 Thread Nautiyal, Ankit K



On 2/16/2024 7:50 PM, Mitul Golani wrote:

Write/Read Adaptive sync SDP only when Sink and Source is enabled
for the same. Also along with write TRANS_VRR_VSYNC values.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_ddi.c  |  4 
  .../gpu/drm/i915/display/intel_display_device.h   |  1 +
  drivers/gpu/drm/i915/display/intel_dp.c   | 15 +++
  drivers/gpu/drm/i915/display/intel_dp.h   |  1 +
  drivers/gpu/drm/i915/display/intel_vrr.c  |  7 +++
  5 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index bea441590204..68cd49193d03 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3926,6 +3926,7 @@ static void intel_ddi_get_config(struct intel_encoder 
*encoder,
  {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
  
  	/* XXX: DSI transcoder paranoia */

if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
@@ -3972,6 +3973,9 @@ 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);
  
+	if (HAS_AS_SDP(dev_priv) && intel_dp_sink_as_sdp_supported(intel_dp))



+   intel_read_dp_sdp(encoder, pipe_config, DP_SDP_ADAPTIVE_SYNC);
+
intel_audio_codec_get_config(encoder, pipe_config);
  }
  
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h

index fe4268813786..6399fbc6c738 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -68,6 +68,7 @@ struct drm_printer;
  #define HAS_TRANSCODER(i915, trans)   
((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
  BIT(trans)) != 0)
  #define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
+#define HAS_AS_SDP(i915)   (DISPLAY_VER(i915) >= 13)
  #define INTEL_NUM_PIPES(i915) 
(hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
  #define I915_HAS_HOTPLUG(i915)
(DISPLAY_INFO(i915)->has_hotplug)
  #define OVERLAY_NEEDS_PHYSICAL(i915)  
(DISPLAY_INFO(i915)->overlay_needs_physical)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0759266e7bfb..5bd99fa8f200 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -119,6 +119,17 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
return dig_port->base.type == INTEL_OUTPUT_EDP;
  }
  
+bool

+intel_dp_sink_as_sdp_supported(struct intel_dp *intel_dp)
+{
+   u8 dpcd[DP_RECEIVER_CAP_SIZE];
+
+   if (drm_dp_read_dpcd_caps(&intel_dp->aux, dpcd))
+   return -EIO;
+


This is already read in intel_dp->dpcd, we can use that.




+   return drm_dp_as_sdp_supported(&intel_dp->aux, dpcd);
+}
+
  static void intel_dp_unset_edid(struct intel_dp *intel_dp);
  
  /* Is link rate UHBR and thus 128b/132b? */

@@ -4330,6 +4341,7 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
 VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK |
 VIDEO_DIP_ENABLE_ADAPTIVE_SYNC;
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
+   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

if (!enable && HAS_DSC(dev_priv))
@@ -4347,6 +4359,9 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
  
  	intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC);
  
+	if (HAS_AS_SDP(dev_priv) && intel_dp_sink_as_sdp_supported(intel_dp))

+   intel_write_dp_sdp(encoder, crtc_state, DP_SDP_ADAPTIVE_SYNC);
+
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h

index 530cc97bc42f..09ab313af896 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -180,5 +180,6 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp 
*intel_dp,
struct link_config_limits *limits);
  
  void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector);

+bool intel_dp_sink_as_sdp_supported(struct intel_dp *intel_dp);
  
  #endif /* __INTEL_DP_H__ */

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 2fa0004d00c7..86729e145991 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -192,6 +192,9 @@ 

Re: [PATCH 5/6] drm/i915/display: Compute vrr_vsync params

2024-02-19 Thread Nautiyal, Ankit K



On 2/16/2024 7:50 PM, Mitul Golani wrote:

Compute vrr_vsync_start/end  which sets the position
for hardware to send the Vsync at a fixed position
relative to the end of the Vblank.

--v2:
- Update, VSYNC_START/END macros to VRR_VSYNC_START/END.(Ankit)
- Update bit fields of VRR_VSYNC_START/END.(Ankit)

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_display_types.h |  1 +
  drivers/gpu/drm/i915/display/intel_vrr.c   |  7 +++
  drivers/gpu/drm/i915/i915_reg.h| 11 +++
  3 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index a6991bc3f07b..015ed846b896 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1414,6 +1414,7 @@ struct intel_crtc_state {
bool enable, in_range;
u8 pipeline_full;
u16 flipline, vmin, vmax, guardband;
+   u32 vsync_end, vsync_start;
} vrr;
  
  	/* Stream Splitter for eDP MSO */

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 5d905f932cb4..2fa0004d00c7 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -149,6 +149,13 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
  
  	crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
  
+	crtc_state->vrr.vsync_start =

+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   
VRR_VSYNC_START(crtc_state->hw.adjusted_mode.vsync_start));
+   crtc_state->vrr.vsync_end =
+   (crtc_state->hw.adjusted_mode.crtc_vtotal -
+   (VRR_VSYNC_END(crtc_state->hw.adjusted_mode.vsync_end) 
>> 16));
+
/*
 * For XE_LPD+, we use guardband and pipeline override
 * is deprecated.
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c02ea07af4c2..f73e95b18819 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1955,6 +1955,10 @@
  #define   VSYNC_END(vsync_end)REG_FIELD_PREP(VSYNC_END_MASK, 
(vsync_end))
  #define   VSYNC_START_MASKREG_GENMASK(15, 0)
  #define   VSYNC_START(vsync_start)REG_FIELD_PREP(VSYNC_START_MASK, 
(vsync_start))
+#define   VSYNC_END_MASK   REG_GENMASK(31, 16)
+#define   VSYNC_END(vsync_end) REG_FIELD_PREP(VSYNC_END_MASK, 
(vsync_end))
+#define   VSYNC_START_MASK REG_GENMASK(15, 0)
+#define   VSYNC_START(vsync_start) REG_FIELD_PREP(VSYNC_START_MASK, 
(vsync_start))


I think this is typo, we really dont need to touch these.



  #define _TRANS_EXITLINE_A 0x60018
  #define _PIPEASRC 0x6001c
  #define   PIPESRC_WIDTH_MASK  REG_GENMASK(31, 16)
@@ -2007,7 +2011,9 @@
  #define _TRANS_VRR_CTL_B  0x61420
  #define _TRANS_VRR_CTL_C  0x62420
  #define _TRANS_VRR_CTL_D  0x63420
+#define _TRANS_VRR_VSYNC_A 0x60078
  #define TRANS_VRR_CTL(trans)  _MMIO_TRANS2(trans, 
_TRANS_VRR_CTL_A)
+#define TRANS_VRR_VSYNC(trans) _MMIO_TRANS2(trans, 
_TRANS_VRR_VSYNC_A)
  #define   VRR_CTL_VRR_ENABLE  REG_BIT(31)
  #define   VRR_CTL_IGN_MAX_SHIFT   REG_BIT(30)
  #define   VRR_CTL_FLIP_LINE_ENREG_BIT(29)
@@ -2087,6 +2093,11 @@
  #define TRANS_VRR_STATUS2(trans)  _MMIO_TRANS2(trans, 
_TRANS_VRR_STATUS2_A)
  #define   VRR_STATUS2_VERT_LN_CNT_MASKREG_GENMASK(19, 0)
  
+#define   VRR_VSYNC_END_MASK		REG_GENMASK(28, 16)

+#define   VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VSYNC_END_MASK, 
(vsync_end))
+#define   VRR_VSYNC_START_MASK REG_GENMASK(12, 0)
+#define   VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VSYNC_START_MASK, 
(vsync_start))


Here too, we need to use the correct VRR_VSYNC_STAR/END_MASK


Regards,

Ankit


+
  #define _TRANS_PUSH_A 0x60A70
  #define _TRANS_PUSH_B 0x61A70
  #define _TRANS_PUSH_C 0x62A70


Re: [PATCH 4/6] drm/i915/display: Compute and Enable AS SDP

2024-02-19 Thread Nautiyal, Ankit K



On 2/16/2024 7:50 PM, Mitul Golani wrote:

Add necessary functions definitions to enable
and compute AS SDP data. The new `intel_dp_compute_as_sdp`
function computes AS SDP values based on the display
configuration, ensuring proper handling of Variable Refresh
Rate (VRR).

--v2:
- Add DP_SDP_ADAPTIVE_SYNC to infoframe_type_to_idx().[Ankit]
- separate patch for intel_read/write_dp_sdp [Ankit].
- _HSW_VIDEO_DIP_ASYNC_DATA_A should be from ADL onward [Ankit]
- To fix indentation [Ankit]

--v3:
- Add VIDEO_DIP_ENABLE_AS_HSW flag to intel_dp_set_infoframes.

--v4:
- Add HAS_VRR check before write as sdp.

--v5:
- Add missed HAS_VRR check before read as sdp.

--v6:
Use Adaptive Sync sink status, which can be
used as a check for read/write sdp. (Ankit)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index d68fb9d45054..0759266e7bfb 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2617,6 +2617,25 @@ static void intel_dp_compute_vsc_colorimetry(const 
struct intel_crtc_state *crtc
vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED;
  }
  
+static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,

+   struct intel_crtc_state *crtc_state,
+   const struct drm_connector_state 
*conn_state)
+{
+   struct drm_dp_as_sdp *as_sdp = &crtc_state->infoframes.as_sdp;
+   struct intel_connector *connector = intel_dp->attached_connector;
+   const struct drm_display_mode *adjusted_mode =
+   &crtc_state->hw.adjusted_mode;
+   int vrefresh = drm_mode_vrefresh(adjusted_mode);
+
+   if (!intel_vrr_is_in_range(connector, vrefresh))
+   return;



I think there should be 2 variables in crtc_state->vrras_sdp_enable and 
as_sdp_mode.


as_sdp_enable to track, if we really need to send the as_sdp and the 
as_sdp_mode to track which mode we want (AVT/FAVT)



We fill these in vrr_compute_config, along with other members like trans 
vrr_sync_start/end.



Here we can check if as_sdp_enable is set, if not we return early.




+
+   crtc_state->infoframes.enable |= 
intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC);
+   as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
+   as_sdp->length = 0x9;
+   as_sdp->vtotal = adjusted_mode->vtotal;


Here the as_sdp->operation_mode should be set which is computed in 
vrr_compute_config, as mentioned above.


Other fields will depend on mode that is selected.


Regards,

Ankit




+}
+
  static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
 struct intel_crtc_state *crtc_state,
 const struct drm_connector_state 
*conn_state)
@@ -2942,6 +2961,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
g4x_dp_set_clock(encoder, pipe_config);
  
  	intel_vrr_compute_config(pipe_config, conn_state);

+   intel_dp_compute_as_sdp(intel_dp, pipe_config, conn_state);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);


Re: [PATCH 3/6] drm/i915/dp: Add Read/Write support for Adaptive Sync SDP

2024-02-19 Thread Nautiyal, Ankit K



On 2/16/2024 7:50 PM, Mitul Golani wrote:

Add the necessary structures and functions to handle reading and
unpacking Adaptive Sync Secondary Data Packets. Also add support
to write and pack AS SDP.

--v2:
- Correct use of REG_BIT and REG_GENMASK. [Jani]
- Use as_sdp instead of async. [Jani]
- Remove unrelated comments and changes. [Jani]
- Correct code indent. [Jani]

--v3:
- Update definition names for AS SDP which are starting from
HSW, as these defines are applicable for ADLP+.(Ankit)

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/i915/display/intel_dp.c   | 95 ++-
  drivers/gpu/drm/i915/display/intel_hdmi.c | 12 ++-
  drivers/gpu/drm/i915/i915_reg.h   |  8 ++
  include/drm/display/drm_dp.h  |  2 +-
  include/drm/display/drm_dp_helper.h   |  2 +
  5 files changed, 114 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 217196196e50..d68fb9d45054 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -95,7 +95,6 @@
  #define INTEL_DP_RESOLUTION_STANDARD  (2 << INTEL_DP_RESOLUTION_SHIFT_MASK)
  #define INTEL_DP_RESOLUTION_FAILSAFE  (3 << INTEL_DP_RESOLUTION_SHIFT_MASK)
  
-

  /* Constants for DP DSC configurations */
  static const u8 valid_dsc_bpp[] = {6, 8, 10, 12, 15};
  
@@ -4089,6 +4088,34 @@ intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,

return false;
  }
  
+static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,

+   struct dp_sdp *sdp, size_t size)
+{
+   size_t length = sizeof(struct dp_sdp);
+
+   if (size < length)
+   return -ENOSPC;
+
+   memset(sdp, 0, size);
+
+   /* Prepare AS (Adaptive Sync) SDP Header */
+   sdp->sdp_header.HB0 = 0;
+   sdp->sdp_header.HB1 = as_sdp->sdp_type;
+   sdp->sdp_header.HB2 = 0x02;
+   sdp->sdp_header.HB3 = as_sdp->length;
+
+   /* Fill AS (Adaptive Sync) SDP Payload */
+   sdp->db[1] = 0x0;



Operation_mode, target_rr etc should be filled from as_sdp struct.



+   sdp->db[1] = as_sdp->vtotal & 0xFF;
+   sdp->db[2] = (as_sdp->vtotal >> 8) & 0xF;
+   sdp->db[3] = 0x0;
+   sdp->db[4] = 0x0;
+   sdp->db[7] = 0x0;
+   sdp->db[8] = 0x0;
+
+   return length;
+}
+
  static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
 struct dp_sdp *sdp, size_t size)
  {
@@ -4256,6 +4283,10 @@ static void intel_write_dp_sdp(struct intel_encoder 
*encoder,
   
&crtc_state->infoframes.drm.drm,
   &sdp, 
sizeof(sdp));
break;
+   case DP_SDP_ADAPTIVE_SYNC:
+   len = intel_dp_as_sdp_pack(&crtc_state->infoframes.as_sdp, &sdp,
+  sizeof(sdp));
+   break;
default:
MISSING_CASE(type);
return;
@@ -4276,7 +4307,8 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
-VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
+VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK |
+VIDEO_DIP_ENABLE_ADAPTIVE_SYNC;
u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
  
  	/* TODO: Sanitize DSC enabling wrt. intel_dsc_dp_pps_write(). */

@@ -4298,6 +4330,40 @@ void intel_dp_set_infoframes(struct intel_encoder 
*encoder,
intel_write_dp_sdp(encoder, crtc_state, 
HDMI_PACKET_TYPE_GAMUT_METADATA);
  }
  
+static

+int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
+  const void *buffer, size_t size)
+{
+   const struct dp_sdp *sdp = buffer;
+
+   if (size < sizeof(struct dp_sdp))
+   return -EINVAL;
+
+   memset(as_sdp, 0, sizeof(*as_sdp));
+
+   if (sdp->sdp_header.HB0 != 0)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB1 != DP_SDP_ADAPTIVE_SYNC)
+   return -EINVAL;
+
+   if (sdp->sdp_header.HB2 != 0x02)
+   return -EINVAL;
+
+   if ((sdp->sdp_header.HB3 & 0x3F) != 9)
+   return -EINVAL;
+
+   if ((sdp->db[0] & AS_SDP_OP_MODE) != 0x0)
+   return -EINVAL;


lets not check this thing here, but fill as_sdp->operation_mode, read 
from the sdp.


Checking should be done in intel_pipe_config_compare, perhaps need to 
add a new PIPE_CONF_CHECK_ for adaptive sync SDP.




+
+   as_sdp->vtotal = ((u64)sdp->db[2] << 32) | (u64)sdp->db[1];
+   as_sdp->target_rr = 0;
+   as_sdp->duration_incr_ms = 0;
+   as_sdp->duration_

Re: [PATCH 2/6] drm: Add Adaptive Sync SDP logging

2024-02-19 Thread Nautiyal, Ankit K



On 2/16/2024 7:50 PM, Mitul Golani wrote:

Add structure representing Adaptive Sync Secondary Data
Packet (AS SDP). Also, add Adaptive Sync SDP logging in
drm_dp_helper.c to facilitate debugging.

--v2:
- Update logging. [Jani, Ankit]
- use as_sdp instead of async [Ankit]
- Correct define placeholders to where it is being actually used. [Jani]
- Update members in as_sdp structure and make it uniform. [Jani]

--v3:
- Add changes dri-devel mail list. No code changes.

Signed-off-by: Mitul Golani 
---
  drivers/gpu/drm/display/drm_dp_helper.c   | 12 
  .../drm/i915/display/intel_crtc_state_dump.c  | 12 
  .../drm/i915/display/intel_display_types.h|  1 +
  include/drm/display/drm_dp.h  |  2 ++
  include/drm/display/drm_dp_helper.h   | 30 +++
  5 files changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 81c5507928f5..5911b20de2ea 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2913,6 +2913,18 @@ void drm_dp_vsc_sdp_log(struct drm_printer *p, const 
struct drm_dp_vsc_sdp *vsc)
  }
  EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
  
+void drm_dp_as_sdp_log(struct drm_printer *p, const struct drm_dp_as_sdp *as_sdp)

+{
+   drm_printf(p, "DP SDP: AS_SDP, revision %u, length %u\n",
+  as_sdp->revision, as_sdp->length);
+   drm_printf(p, "vtotal: %d\n", as_sdp->vtotal);
+   drm_printf(p, "target_rr: %d\n", as_sdp->target_rr);
+   drm_printf(p, "duration_incr_ms: %d\n", as_sdp->duration_incr_ms);
+   drm_printf(p, "duration_decr_ms: %d\n", as_sdp->duration_decr_ms);
+   drm_printf(p, "operation_mode: %d\n", as_sdp->operation_mode);
+}
+EXPORT_SYMBOL(drm_dp_as_sdp_log);
+
  /**
   * drm_dp_as_sdp_supported() - check if adaptive sync sdp is supported
   * @aux: DisplayPort AUX channel
diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c 
b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
index 4bcf446c75f4..26d77c2934e8 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
@@ -60,6 +60,15 @@ intel_dump_dp_vsc_sdp(struct drm_i915_private *i915,
drm_dp_vsc_sdp_log(&p, vsc);
  }
  
+static void

+intel_dump_dp_as_sdp(struct drm_i915_private *i915,
+const struct drm_dp_as_sdp *as_sdp)
+{
+   struct drm_printer p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, 
"AS_SDP");
+
+   drm_dp_as_sdp_log(&p, as_sdp);
+}
+
  static void
  intel_dump_buffer(struct drm_i915_private *i915,
  const char *prefix, const u8 *buf, size_t len)
@@ -299,6 +308,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state 
*pipe_config,
if (pipe_config->infoframes.enable &
intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA))
intel_dump_infoframe(i915, &pipe_config->infoframes.drm);
+   if (pipe_config->infoframes.enable &
+   intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC))
+   intel_dump_dp_as_sdp(i915, &pipe_config->infoframes.as_sdp);
if (pipe_config->infoframes.enable &
intel_hdmi_infoframe_enable(DP_SDP_VSC))
intel_dump_dp_vsc_sdp(i915, &pipe_config->infoframes.vsc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 0d4012097db1..a6991bc3f07b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1332,6 +1332,7 @@ struct intel_crtc_state {
union hdmi_infoframe hdmi;
union hdmi_infoframe drm;
struct drm_dp_vsc_sdp vsc;
+   struct drm_dp_as_sdp as_sdp;
} infoframes;
  
  	u8 eld[MAX_ELD_BYTES];

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 281afff6ee4e..af6790fb4791 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1578,10 +1578,12 @@ enum drm_dp_phy {
  #define DP_SDP_AUDIO_COPYMANAGEMENT   0x05 /* DP 1.2 */
  #define DP_SDP_ISRC   0x06 /* DP 1.2 */
  #define DP_SDP_VSC0x07 /* DP 1.2 */
+#define DP_SDP_ADAPTIVE_SYNC0x22 /* DP 1.4 */
  #define DP_SDP_CAMERA_GENERIC(i)  (0x08 + (i)) /* 0-7, DP 1.3 */
  #define DP_SDP_PPS0x10 /* DP 1.4 */
  #define DP_SDP_VSC_EXT_VESA   0x20 /* DP 1.4 */
  #define DP_SDP_VSC_EXT_CEA0x21 /* DP 1.4 */
+
  /* 0x80+ CEA-861 infoframe types */
  
  #define DP_SDP_AUDIO_INFOFRAME_HB2	0x1b

diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index a0356721de0f..8a692a86d8d6 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -98,6 +98,36 @@ struct drm_dp_vsc_sdp {
enum dp_content_type content_type;
  }

Re: [Intel-gfx] [PATCH 00/11] Add DSC fractional bpp support

2023-11-14 Thread Nautiyal, Ankit K



On 11/10/2023 3:40 PM, Ankit Nautiyal wrote:

This patch series adds support for DSC fractional compressed bpp
for MTL+. The series starts with some fixes, followed by patches that
lay groundwork to iterate over valid compressed bpps to select the
'best' compressed bpp with optimal link configuration (taken from
upstream series: https://patchwork.freedesktop.org/series/105200/).

The later patches, add changes to accommodate compressed bpp with
fractional part, including changes to QP calculations.
To get the 'best' compressed bpp, we iterate over the valid compressed
bpp values, but with fractional step size 1/16, 1/8, 1/4 or 1/2 as per
sink support.

The last 2 patches add support to depict DSC sink's fractional support,
and debugfs to enforce use of fractional bpp, while choosing an
appropriate compressed bpp.

Rev10: Rebased and added DSC Fractional support for DP MST.


Pushed patches 1-8 to drm-intel-next, thanks for the reviews, acks.

Regards,

Ankit




Ankit Nautiyal (8):
   drm/display/dp: Add helper function to get DSC bpp precision
   drm/i915/display: Store compressed bpp in U6.4 format
   drm/i915/display: Consider fractional vdsc bpp while computing m_n
 values
   drm/i915/audio: Consider fractional vdsc bpp while computing tu_data
   drm/i915/dp: Iterate over output bpp with fractional step size
   drm/i915/dp_mst: Use precision of 1/16 for computing bpp
   drm/i916/dp_mst: Iterate over the DSC bpps as per DSC precision
 support
   drm/i915/dp_mst: Add support for forcing dsc fractional bpp via
 debugfs

Swati Sharma (2):
   drm/i915/dsc: Add debugfs entry to validate DSC fractional bpp
   drm/i915/dsc: Allow DSC only with fractional bpp when forced from
 debugfs

Vandita Kulkarni (1):
   drm/i915/dsc/mtl: Add support for fractional bpp

  drivers/gpu/drm/display/drm_dp_helper.c   | 27 ++
  drivers/gpu/drm/i915/display/icl_dsi.c| 10 +--
  drivers/gpu/drm/i915/display/intel_audio.c| 16 ++--
  drivers/gpu/drm/i915/display/intel_bios.c |  4 +-
  drivers/gpu/drm/i915/display/intel_cdclk.c|  5 +-
  drivers/gpu/drm/i915/display/intel_display.c  |  6 +-
  .../drm/i915/display/intel_display_debugfs.c  | 84 ++
  .../drm/i915/display/intel_display_types.h|  4 +-
  drivers/gpu/drm/i915/display/intel_dp.c   | 87 +++
  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 85 +++---
  drivers/gpu/drm/i915/display/intel_fdi.c  |  3 +-
  drivers/gpu/drm/i915/display/intel_link_bw.c  |  2 +-
  .../gpu/drm/i915/display/intel_qp_tables.c|  3 -
  drivers/gpu/drm/i915/display/intel_vdsc.c | 29 +--
  include/drm/display/drm_dp_helper.h   |  1 +
  15 files changed, 266 insertions(+), 100 deletions(-)



Re: [PATCH 1/2] drm/display/dp: Default 8 bpc support when DSC is supported

2023-08-24 Thread Nautiyal, Ankit K

Thanks Jani for the corrections and suggestions.

I agree to them and will fix them in next version.

Now that I see the commit subject line also should have been "Assume 8 
bpc support when DSC is supported", will change that too.


Regards,

Ankit

On 8/24/2023 3:15 PM, Jani Nikula wrote:

On Thu, 24 Aug 2023, Ankit Nautiyal  wrote:

As per DP v1.4, a DP DSC Sink device shall support 8bpc in DPCD 6Ah.
Apparently some panels that do support DSC, are not setting the bit for
8bpc.

So always assume 8bpc support by DSC decoder, when DSC is claimed to be
supported.

v2: Use helper to check dsc support. (Ankit)

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

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index e6a78fd32380..309fc10cde78 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2447,14 +2447,19 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 
dsc_dpcd[DP_DSC_RECEIVER_CAP_S
 u8 dsc_bpc[3])
  {
int num_bpc = 0;
+
+ if(!drm_dp_sink_supports_dsc(dsc_dpcd))

   ^

Missing space.


+   return 0;
+
u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];

All declarations should be before code.

  
  	if (color_depth & DP_DSC_12_BPC)

dsc_bpc[num_bpc++] = 12;
if (color_depth & DP_DSC_10_BPC)
dsc_bpc[num_bpc++] = 10;
-   if (color_depth & DP_DSC_8_BPC)
-   dsc_bpc[num_bpc++] = 8;
+
+   /* A DP DSC Sink devices shall support 8 bpc. */

Mixed singular and plural, a ... devices.


+   dsc_bpc[num_bpc++] = 8;
  
  	return num_bpc;

  }


Re: [Intel-gfx] [PATCH 2/2] drivers/drm/i915: Honor limits->max_bpp while computing DSC max input bpp

2023-08-24 Thread Nautiyal, Ankit K



On 8/24/2023 3:14 PM, Jani Nikula wrote:

On Wed, 23 Aug 2023, Ankit Nautiyal  wrote:

Edid specific BPC constraints are stored in limits->max_bpp. Honor these
limits while computing the input bpp for DSC.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 5b48bfe09d0e..2a7f6cfe2832 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2061,9 +2061,11 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
if (forced_bpp) {
pipe_bpp = forced_bpp;
} else {
+   u8 max_bpc = limits->max_bpp / 3;
+

int max_bpc = min_t(int, limits->max_bpp / 3, 
conn_state->max_requested_bpc);


/* For eDP use max bpp that can be supported with DSC. */
pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, max_bbc);

Nitpick, IMO looks cleaner this way, as well as uses int instead of u8
for computations.

BR,
Jani.


Thanks Jani for the comments, it does makes sense. Will fix in next 
version shortly.


Regards,

Ankit


if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(&i915->drm,
"Computed BPC is not in DSC BPC limits\n");


Re: [Intel-gfx] [PATCH 2/2] drivers/drm/i915: Honor limits->max_bpp while computing DSC max input bpp

2023-08-24 Thread Nautiyal, Ankit K

Thanks Stan for the review.

Regards,

Ankit

On 8/24/2023 2:59 PM, Lisovskiy, Stanislav wrote:

On Wed, Aug 23, 2023 at 05:24:25PM +0530, Ankit Nautiyal wrote:

Edid specific BPC constraints are stored in limits->max_bpp. Honor these
limits while computing the input bpp for DSC.

Signed-off-by: Ankit Nautiyal 

Reviewed-by: Stanislav Lisovskiy 

That is kind of funny, I can see this patch in my mails but can't
see the other one you had "Default 8 bpc support when DSC is supported",
which is visible from patchwork.
Anyways I give r-b for that one as well.


---
  drivers/gpu/drm/i915/display/intel_dp.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 5b48bfe09d0e..2a7f6cfe2832 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2061,9 +2061,11 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
if (forced_bpp) {
pipe_bpp = forced_bpp;
} else {
+   u8 max_bpc = limits->max_bpp / 3;
+
/* For eDP use max bpp that can be supported with DSC. */
pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp,
-   
conn_state->max_requested_bpc);
+   min(max_bpc, 
conn_state->max_requested_bpc));
if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(&i915->drm,
"Computed BPC is not in DSC BPC limits\n");
--
2.40.1



Re: [PATCH 00/20] DSC misc fixes

2023-08-17 Thread Nautiyal, Ankit K



On 8/17/2023 3:19 PM, Jani Nikula wrote:

On Thu, 10 Aug 2023, Ankit Nautiyal  wrote:

This series is an attempt to address multiple issues with DSC,
scattered in separate existing series.

I think it's a good idea to have one person manage the series, and
combine it all together, because it touches the same areas.

However, once you have smaller batches of patches that are all reviewed,
send them out as smaller series, and get them merged. Re-sending and
rebasing ready patches as part of a 19-patch series where some patches
aren't ready has become counter-productive.

Getting patches upstream is like working on a machine that has a certain
peak throughput. Send patches one by one, and it's inefficient. Send too
many at once, and it bogs down. Personally, I think 5-10 non-trivial
patches at a time is about right, get them reviewed and merged, rebase
the rest locally, and again send the next 5-10.

Or you can initially send a longer series, but once the first 5-10 have
been reviewed, send them separately.


Yeah this indeed become bloated with assortment of fixes. Should have 
separated series as they got reviewed. Will take care going forward.


For this series, I will merge the reviewed i915 patches and send a 
separate series for the drm patch#8 (drm/display/dp: Fix the DP DSC 
Receiver cap size).


Regards,

Ankit





BR,
Jani.



Patches 1-4 are DSC fixes from series to Handle BPC for HDMI2.1 PCON
https://patchwork.freedesktop.org/series/107550/

Patches 5-6 are from series DSC fixes for Bigjoiner:
https://patchwork.freedesktop.org/series/115773/

Patches 7-17 are based on series to add DSC fractional BPP support:
https://patchwork.freedesktop.org/series/111391/

Patch 20 is to fix compressed bpc for MST DSC, from Stan's series :
https://patchwork.freedesktop.org/series/116179/

Rev2: Addressed review comments from Stan, Ville.

Rev3: Split larger patches. Separate out common helpers.

Rev4: Rebased, fixed checkpatch warnings.

Rev5: Addressed review comments from Stan.
Added a patch to check if forced dsc format can be used before forcing.

Rev6: Addressed review comments from Stan.

Rev7: Reordered and rebased.

Ankit Nautiyal (19):
   drm/i915/dp: Consider output_format while computing dsc bpp
   drm/i915/dp: Move compressed bpp check with 420 format inside the
 helper
   drm/i915/dp_mst: Use output_format to get the final link bpp
   drm/i915/dp: Use consistent name for link bpp and compressed bpp
   drm/i915/dp: Update Bigjoiner interface bits for computing compressed
 bpp
   drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck
   drm/i915/dp: Remove extra logs for printing DSC info
   drm/display/dp: Fix the DP DSC Receiver cap size
   drm/i915/dp: Avoid forcing DSC BPC for MST case
   drm/i915/dp: Add functions to get min/max src input bpc with DSC
   drm/i915/dp: Check min bpc DSC limits for dsc_force_bpc also
   drm/i915/dp: Avoid left shift of DSC output bpp by 4
   drm/i915/dp: Rename helper to get DSC max pipe_bpp
   drm/i915/dp: Separate out functions for edp/DP for computing DSC bpp
   drm/i915/dp: Add DSC BPC/BPP constraints while selecting pipe bpp with
 DSC
   drm/i915/dp: Separate out function to get compressed bpp with joiner
   drm/i915/dp: Get optimal link config to have best compressed bpp
   drm/i915/dp: Check src/sink compressed bpp limit for edp
   drm/i915/dp: Check if force_dsc_output_format is possible

Stanislav Lisovskiy (1):
   drm/i915: Query compressed bpp properly using correct DPCD and DP Spec
 info

  drivers/gpu/drm/i915/display/intel_cdclk.c  |  59 +-
  drivers/gpu/drm/i915/display/intel_dp.c | 655 
  drivers/gpu/drm/i915/display/intel_dp.h |  20 +-
  drivers/gpu/drm/i915/display/intel_dp_mst.c |  80 +--
  include/drm/display/drm_dp.h|   2 +-
  5 files changed, 625 insertions(+), 191 deletions(-)


Re: [PATCH 10/20] drm/i915/dp: Add functions to get min/max src input bpc with DSC

2023-08-03 Thread Nautiyal, Ankit K



On 8/2/2023 5:35 PM, Lisovskiy, Stanislav wrote:

On Fri, Jul 28, 2023 at 09:41:40AM +0530, Ankit Nautiyal wrote:

Separate out functions for getting maximum and minimum input BPC based
on platforms, when DSC is used.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 7ec8a478e000..f41de126a8d3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1535,6 +1535,18 @@ intel_dp_compute_link_config_wide(struct intel_dp 
*intel_dp,
return -EINVAL;
  }
  
+static

+u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private *i915)
+{
+   /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */
+   if (DISPLAY_VER(i915) >= 12)
+   return 12;
+   if (DISPLAY_VER(i915) == 11)
+   return 10;
+
+   return 0;
+}
+
  int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
  {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -1542,11 +1554,12 @@ int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, 
u8 max_req_bpc)
u8 dsc_bpc[3] = {0};
u8 dsc_max_bpc;
  
-	/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */

-   if (DISPLAY_VER(i915) >= 12)
-   dsc_max_bpc = min_t(u8, 12, max_req_bpc);
-   else
-   dsc_max_bpc = min_t(u8, 10, max_req_bpc);
+   dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(i915);
+
+   if (!dsc_max_bpc)
+   return dsc_max_bpc;
+
+   dsc_max_bpc = min_t(u8, dsc_max_bpc, max_req_bpc);
  
  	num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,

   dsc_bpc);
@@ -1674,6 +1687,16 @@ static bool intel_dp_dsc_supports_format(struct intel_dp 
*intel_dp,
return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, 
sink_dsc_format);
  }
  
+static

+u8 intel_dp_dsc_min_src_input_bpc(struct drm_i915_private *i915)
+{
+   /* Min DSC Input BPC for ICL+ is 8 */
+   if (DISPLAY_VER(i915) >= 11)
+   return 8;
+
+   return 0;

So does it mean that for anything below gen 11, there is no limit at all?
Also it means that the condition below will never be executed for gen <= 11.


Hmm. Bspec says min bpc is 8 for DSC, so idea is to have min bpc as 8 
when DSC is used.


This is supposed to be called only if DSC is supported, so perhaps 
HAS_DSC can be used?


return HAS_DSC(dev_priv) ? 8 : 0;


Regards,

Ankit



Stan


+}
+
  int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
@@ -1707,10 +1730,9 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
pipe_bpp = pipe_config->pipe_bpp;
}
  
-	/* Min Input BPC for ICL+ is 8 */

-   if (pipe_bpp < 8 * 3) {
+   if (pipe_bpp < intel_dp_dsc_min_src_input_bpc(dev_priv) * 3) {
drm_dbg_kms(&dev_priv->drm,
-   "No DSC support for less than 8bpc\n");
+   "Computed BPC less than min supported by source for 
DSC\n");
return -EINVAL;
}
  
--

2.40.1



Re: [PATCH 05/19] drm/i915/dp: Update Bigjoiner interface bits for computing compressed bpp

2023-07-27 Thread Nautiyal, Ankit K



On 7/25/2023 4:49 PM, Nautiyal, Ankit K wrote:


On 7/25/2023 3:43 PM, Lisovskiy, Stanislav wrote:

On Mon, Jul 24, 2023 at 05:49:11PM +0530, Nautiyal, Ankit K wrote:

Hi Stan,

Thanks for the reviews ans suggestions. Please my response inline:


On 7/20/2023 2:59 PM, Lisovskiy, Stanislav wrote:

On Thu, Jul 13, 2023 at 04:03:32PM +0530, Ankit Nautiyal wrote:

In Bigjoiner check for DSC, bigjoiner interface bits for DP for
DISPLAY > 13 is 36 (Bspec: 49259).

v2: Corrected Display ver to 13.

v3: Follow convention for conditional statement. (Ville)

v4: Fix check for display ver. (Ville)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
   drivers/gpu/drm/i915/display/intel_dp.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c

index 19768ac658ba..c1fd448d80e1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -802,8 +802,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
   bits_per_pixel = min(bits_per_pixel, 
max_bpp_small_joiner_ram);

   if (bigjoiner) {
+    int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 
36 : 24;

   u32 max_bpp_bigjoiner =
-    i915->display.cdclk.max_cdclk_freq * 48 /
+    i915->display.cdclk.max_cdclk_freq * 2 * 
bigjoiner_interface_bits /
Probably "num_vdsc_instances = 
intel_dsc_get_num_vdsc_instances(crtc_state);" again,

instead of "2"?

Currently intel_dsc_get_num_vdsc_instances will give total number of
vdsc_engines including joined pipes.

So with bigjoiner the function will return 4.

This was good to calculate Pipe BW check: (Pixel clock < PPC * CDCLK
frequency * Number of pipes joined

as we get PPC * number of pipes joined from
intel_dsc_get_num_vdsc_instances)

Or to calculate DSC_PIC_WIDTH PPS parameter.

But here we perhaps need intel_dsc_get_vdsc_engines_per_pipe that 
will just

return 2 if dsc_split 1 otherwise.

Thanks & Regards,

Ankit

Yes, I agree, unfortunately not applicable here.
May be yeah we need some function like that and then refactor
also the intel_dsc_get_num_vdsc_instances to use that one..

Stan


Alright, let me make the change in a separate patch and add to this 
series.


Thanks & Regards,

Ankit


Since we call this function during mode valid too, so cannot directly 
use intel_dsc_get_num_vdsc_instance,


so I have put a comment for clarification about PPC in the latest version.

Regard,

Ankit





With that clarified,

Reviewed-by: Stanislav Lisovskiy 


intel_dp_mode_to_fec_clock(mode_clock);
   bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
--
2.40.1



Re: [PATCH 06/19] drm/i915/display: Account for DSC not split case while computing cdclk

2023-07-25 Thread Nautiyal, Ankit K



On 7/25/2023 3:40 PM, Lisovskiy, Stanislav wrote:

On Tue, Jul 25, 2023 at 11:22:52AM +0530, Nautiyal, Ankit K wrote:

On 7/20/2023 2:46 PM, Lisovskiy, Stanislav wrote:

On Thu, Jul 13, 2023 at 04:03:33PM +0530, Ankit Nautiyal wrote:

Currently we assume 2 Pixels Per Clock (PPC) while computing
plane cdclk and min_cdlck. In cases where DSC single engine
is used the throughput is 1 PPC.

So account for the above case, while computing cdclk.

v2: Use helper to get the adjusted pixel rate.

Signed-off-by: Ankit Nautiyal 
---
   drivers/gpu/drm/i915/display/intel_cdclk.c |  2 +-
   drivers/gpu/drm/i915/display/intel_vdsc.c  | 12 
   drivers/gpu/drm/i915/display/intel_vdsc.h  |  2 ++
   drivers/gpu/drm/i915/display/skl_universal_plane.c |  4 ++--
   4 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index dcc1f6941b60..701909966545 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2508,7 +2508,7 @@ static int intel_pixel_rate_to_cdclk(const struct 
intel_crtc_state *crtc_state)
int pixel_rate = crtc_state->pixel_rate;
if (DISPLAY_VER(dev_priv) >= 10)
-   return DIV_ROUND_UP(pixel_rate, 2);
+   return intel_dsc_get_adjusted_pixel_rate(crtc_state, 
pixel_rate);
else if (DISPLAY_VER(dev_priv) == 9 ||
 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
return pixel_rate;
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c 
b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 9d76c2756784..bbfdbf06da68 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -1038,3 +1038,15 @@ void intel_dsc_get_config(struct intel_crtc_state 
*crtc_state)
   out:
intel_display_power_put(dev_priv, power_domain, wakeref);
   }
+
+int intel_dsc_get_adjusted_pixel_rate(const struct intel_crtc_state 
*crtc_state, int pixel_rate)
+{
+   /*
+* If single VDSC engine is used, it uses one pixel per clock
+* otherwise we use two pixels per clock.
+*/
+   if (crtc_state->dsc.compression_enable && !crtc_state->dsc.dsc_split)
+   return pixel_rate;
+
+   return DIV_ROUND_UP(pixel_rate, 2);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h 
b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 2cc41ff08909..3bb4b1980b6b 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -28,4 +28,6 @@ void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
   void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
+int intel_dsc_get_adjusted_pixel_rate(const struct intel_crtc_state 
*crtc_state, int pixel_rate);
+
   #endif /* __INTEL_VDSC_H__ */
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 6b01a0b68b97..9eeb25ec4be9 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -17,6 +17,7 @@
   #include "intel_fb.h"
   #include "intel_fbc.h"
   #include "intel_psr.h"
+#include "intel_vdsc.h"
   #include "skl_scaler.h"
   #include "skl_universal_plane.h"
   #include "skl_watermark.h"
@@ -263,8 +264,7 @@ static int icl_plane_min_cdclk(const struct 
intel_crtc_state *crtc_state,
   {
unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, 
plane_state);
-   /* two pixels per clock */
-   return DIV_ROUND_UP(pixel_rate, 2);
+   return intel_dsc_get_adjusted_pixel_rate(crtc_state, pixel_rate);

Hi Ankit,

I think the thing what you are taking of is already handled here in 
intel_cdclk.c:

/*
   * When we decide to use only one VDSC engine, since
   * each VDSC operates with 1 ppc throughput, pixel clock
   * cannot be higher than the VDSC clock (cdclk)
   * If there 2 VDSC engines, then pixel clock can't be higher than
   * VDSC clock(cdclk) * 2 and so on.
   */
  if (crtc_state->dsc.compression_enable) {
  int num_vdsc_instances = 
intel_dsc_get_num_vdsc_instances(crtc_state);

  min_cdclk = max_t(int, min_cdclk,
DIV_ROUND_UP(crtc_state->pixel_rate,
 num_vdsc_instances));
  }

As far as I understand this condition is coming from the pixel clock
limitation as an input to the splitter (Bspec: 49259):

Pipe BW check:

Pixel clock < PPC * CDCLK frequency * Number of pipes joined

PPC = 1 or 2 depending on number of DSC engines used within the pipe.

So it implies CDCLK frequency > Pixel clock / (

Re: [PATCH 05/19] drm/i915/dp: Update Bigjoiner interface bits for computing compressed bpp

2023-07-25 Thread Nautiyal, Ankit K



On 7/25/2023 3:43 PM, Lisovskiy, Stanislav wrote:

On Mon, Jul 24, 2023 at 05:49:11PM +0530, Nautiyal, Ankit K wrote:

Hi Stan,

Thanks for the reviews ans suggestions. Please my response inline:


On 7/20/2023 2:59 PM, Lisovskiy, Stanislav wrote:

On Thu, Jul 13, 2023 at 04:03:32PM +0530, Ankit Nautiyal wrote:

In Bigjoiner check for DSC, bigjoiner interface bits for DP for
DISPLAY > 13 is 36 (Bspec: 49259).

v2: Corrected Display ver to 13.

v3: Follow convention for conditional statement. (Ville)

v4: Fix check for display ver. (Ville)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
   drivers/gpu/drm/i915/display/intel_dp.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 19768ac658ba..c1fd448d80e1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -802,8 +802,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
if (bigjoiner) {
+   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * 48 /
+   i915->display.cdclk.max_cdclk_freq * 2 * 
bigjoiner_interface_bits /

Probably "num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);" 
again,
instead of "2"?

Currently intel_dsc_get_num_vdsc_instances will give total number of
vdsc_engines including joined pipes.

So with bigjoiner the function will return 4.

This was good to calculate Pipe BW check: (Pixel clock < PPC * CDCLK
frequency * Number of pipes joined

as we get PPC * number of pipes joined from
intel_dsc_get_num_vdsc_instances)

Or to calculate DSC_PIC_WIDTH PPS parameter.

But here we perhaps need intel_dsc_get_vdsc_engines_per_pipe that will just
return 2 if dsc_split 1 otherwise.

Thanks & Regards,

Ankit

Yes, I agree, unfortunately not applicable here.
May be yeah we need some function like that and then refactor
also the intel_dsc_get_num_vdsc_instances to use that one..

Stan


Alright, let me make the change in a separate patch and add to this series.

Thanks & Regards,

Ankit





With that clarified,

Reviewed-by: Stanislav Lisovskiy 


intel_dp_mode_to_fec_clock(mode_clock);
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
--
2.40.1



Re: [PATCH 07/19] drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck

2023-07-24 Thread Nautiyal, Ankit K



On 7/20/2023 2:54 PM, Lisovskiy, Stanislav wrote:

On Thu, Jul 13, 2023 at 04:03:34PM +0530, Ankit Nautiyal wrote:

As per Bsepc:49259, Bigjoiner BW check puts restriction on the
compressed bpp for a given CDCLK, pixelclock in cases where
Bigjoiner + DSC are used.

Currently compressed bpp is computed first, and it is ensured that
the bpp will work at least with the max CDCLK freq.

Since the CDCLK is computed later, lets account for Bigjoiner BW
check while calculating Min CDCLK.

v2: Use pixel clock in the bw calculations. (Ville)

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

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 701909966545..788dba576294 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2533,6 +2533,51 @@ static int intel_planes_min_cdclk(const struct 
intel_crtc_state *crtc_state)
return min_cdclk;
  }
  
+static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)

+{
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+   struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+   int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
+   int min_cdclk = 0;
+
+   /*
+* When we decide to use only one VDSC engine, since
+* each VDSC operates with 1 ppc throughput, pixel clock
+* cannot be higher than the VDSC clock (cdclk)
+* If there 2 VDSC engines, then pixel clock can't be higher than
+* VDSC clock(cdclk) * 2 and so on.
+*/
+   min_cdclk = max_t(int, min_cdclk,
+ DIV_ROUND_UP(crtc_state->pixel_rate, 
num_vdsc_instances));
+
+   if (crtc_state->bigjoiner_pipes) {
+   int pixel_clock = crtc_state->hw.adjusted_mode.clock;
+
+   /*
+* According to Bigjoiner bw check:
+* compressed_bpp <= PPC * CDCLK * Big joiner Interface bits / 
Pixel clock
+*
+* We have already computed compressed_bpp, so now compute the 
min CDCLK that
+* is required to support this compressed_bpp.
+*
+* => CDCLK >= compressed_bpp * Pixel clock / (PPC * Bigjoiner 
Interface bits)
+*
+* Since PPC = 2 with bigjoiner
+* => CDCLK >= compressed_bpp * Pixel clock  / 2 * Bigjoiner 
Interface bits
+*
+* #TODO Bspec mentions to account for FEC overhead while using 
pixel clock.
+* Check if we need to use FEC overhead in the above 
calculations.

There is already some function used in intel_dp.c:

intel_dp_mode_to_fec_clock(mode_clock) => Should you may be just use that one, 
to account FEC
overhead?


Hmm right I agree, I can use that here, thanks!





+*/
+   int bigjoiner_interface_bits = DISPLAY_VER(i915) > 13 ? 36 : 24;
+   int min_cdclk_bj = (crtc_state->dsc.compressed_bpp * 
pixel_clock) /
+  (2 * bigjoiner_interface_bits);

I would use "num_vdsc_instances" instead of 2, since we even get those 
explicitly.


Currently for the bigjoiner case, the num_vdsc_instances returns 4 for 
the pipes. Should we have a function to have num_vdsc_instances_per_pipe?


Or perhaps one function for just getting the PPC which will be 2 for 
Display>=10 and when dsc_split is used, and 1 otherwise?



Thanks & Regards,

Ankit





+
+   min_cdclk = max(min_cdclk, min_cdclk_bj);
+   }
+
+   return min_cdclk;
+}
+
  int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
  {
struct drm_i915_private *dev_priv =
@@ -2604,20 +2649,8 @@ int intel_crtc_compute_min_cdclk(const struct 
intel_crtc_state *crtc_state)
/* Account for additional needs from the planes */
min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
  
-	/*

-* When we decide to use only one VDSC engine, since
-* each VDSC operates with 1 ppc throughput, pixel clock
-* cannot be higher than the VDSC clock (cdclk)
-* If there 2 VDSC engines, then pixel clock can't be higher than
-* VDSC clock(cdclk) * 2 and so on.
-*/
-   if (crtc_state->dsc.compression_enable) {
-   int num_vdsc_instances = 
intel_dsc_get_num_vdsc_instances(crtc_state);
-
-   min_cdclk = max_t(int, min_cdclk,
- DIV_ROUND_UP(crtc_state->pixel_rate,
-  num_vdsc_instances));
-   }
+   if (crtc_state->dsc.compression_enable)
+   min_cdclk = max(min_cdclk, intel_vdsc_min_cdclk(crtc_state));


With notes above taken care of:

Reviewed-by: Stanislav Lisovskiy 

  
  	/*

 * HACK. Currently f

Re: [PATCH 06/19] drm/i915/display: Account for DSC not split case while computing cdclk

2023-07-24 Thread Nautiyal, Ankit K



On 7/20/2023 2:46 PM, Lisovskiy, Stanislav wrote:

On Thu, Jul 13, 2023 at 04:03:33PM +0530, Ankit Nautiyal wrote:

Currently we assume 2 Pixels Per Clock (PPC) while computing
plane cdclk and min_cdlck. In cases where DSC single engine
is used the throughput is 1 PPC.

So account for the above case, while computing cdclk.

v2: Use helper to get the adjusted pixel rate.

Signed-off-by: Ankit Nautiyal 
---
  drivers/gpu/drm/i915/display/intel_cdclk.c |  2 +-
  drivers/gpu/drm/i915/display/intel_vdsc.c  | 12 
  drivers/gpu/drm/i915/display/intel_vdsc.h  |  2 ++
  drivers/gpu/drm/i915/display/skl_universal_plane.c |  4 ++--
  4 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index dcc1f6941b60..701909966545 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2508,7 +2508,7 @@ static int intel_pixel_rate_to_cdclk(const struct 
intel_crtc_state *crtc_state)
int pixel_rate = crtc_state->pixel_rate;
  
  	if (DISPLAY_VER(dev_priv) >= 10)

-   return DIV_ROUND_UP(pixel_rate, 2);
+   return intel_dsc_get_adjusted_pixel_rate(crtc_state, 
pixel_rate);
else if (DISPLAY_VER(dev_priv) == 9 ||
 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
return pixel_rate;
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c 
b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 9d76c2756784..bbfdbf06da68 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -1038,3 +1038,15 @@ void intel_dsc_get_config(struct intel_crtc_state 
*crtc_state)
  out:
intel_display_power_put(dev_priv, power_domain, wakeref);
  }
+
+int intel_dsc_get_adjusted_pixel_rate(const struct intel_crtc_state 
*crtc_state, int pixel_rate)
+{
+   /*
+* If single VDSC engine is used, it uses one pixel per clock
+* otherwise we use two pixels per clock.
+*/
+   if (crtc_state->dsc.compression_enable && !crtc_state->dsc.dsc_split)
+   return pixel_rate;
+
+   return DIV_ROUND_UP(pixel_rate, 2);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h 
b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 2cc41ff08909..3bb4b1980b6b 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -28,4 +28,6 @@ void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
  void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
  
+int intel_dsc_get_adjusted_pixel_rate(const struct intel_crtc_state *crtc_state, int pixel_rate);

+
  #endif /* __INTEL_VDSC_H__ */
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 6b01a0b68b97..9eeb25ec4be9 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -17,6 +17,7 @@
  #include "intel_fb.h"
  #include "intel_fbc.h"
  #include "intel_psr.h"
+#include "intel_vdsc.h"
  #include "skl_scaler.h"
  #include "skl_universal_plane.h"
  #include "skl_watermark.h"
@@ -263,8 +264,7 @@ static int icl_plane_min_cdclk(const struct 
intel_crtc_state *crtc_state,
  {
unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, 
plane_state);
  
-	/* two pixels per clock */

-   return DIV_ROUND_UP(pixel_rate, 2);
+   return intel_dsc_get_adjusted_pixel_rate(crtc_state, pixel_rate);

Hi Ankit,

I think the thing what you are taking of is already handled here in 
intel_cdclk.c:

/*
  * When we decide to use only one VDSC engine, since
  * each VDSC operates with 1 ppc throughput, pixel clock
  * cannot be higher than the VDSC clock (cdclk)
  * If there 2 VDSC engines, then pixel clock can't be higher than
  * VDSC clock(cdclk) * 2 and so on.
  */
 if (crtc_state->dsc.compression_enable) {
 int num_vdsc_instances = 
intel_dsc_get_num_vdsc_instances(crtc_state);

 min_cdclk = max_t(int, min_cdclk,
   DIV_ROUND_UP(crtc_state->pixel_rate,
num_vdsc_instances));
 }


As far as I understand this condition is coming from the pixel clock 
limitation as an input to the splitter (Bspec: 49259):


Pipe BW check:

Pixel clock < PPC * CDCLK frequency * Number of pipes joined

PPC = 1 or 2 depending on number of DSC engines used within the pipe.

So it implies CDCLK frequency > Pixel clock / (PPC * Number of pipes joined)

num_vdsc_instances is actually giving us (PPC * number of pipes joined).


I completely agree that there will be no effect of the change on the 
min_cdclk that gets computed in any case, whether DSC, 1 engine, 2 
engine,  bigjoiner

Re: [PATCH 05/19] drm/i915/dp: Update Bigjoiner interface bits for computing compressed bpp

2023-07-24 Thread Nautiyal, Ankit K

Hi Stan,

Thanks for the reviews ans suggestions. Please my response inline:


On 7/20/2023 2:59 PM, Lisovskiy, Stanislav wrote:

On Thu, Jul 13, 2023 at 04:03:32PM +0530, Ankit Nautiyal wrote:

In Bigjoiner check for DSC, bigjoiner interface bits for DP for
DISPLAY > 13 is 36 (Bspec: 49259).

v2: Corrected Display ver to 13.

v3: Follow convention for conditional statement. (Ville)

v4: Fix check for display ver. (Ville)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
  drivers/gpu/drm/i915/display/intel_dp.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 19768ac658ba..c1fd448d80e1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -802,8 +802,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
  
  	if (bigjoiner) {

+   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * 48 /
+   i915->display.cdclk.max_cdclk_freq * 2 * 
bigjoiner_interface_bits /

Probably "num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);" 
again,
instead of "2"?


Currently intel_dsc_get_num_vdsc_instances will give total number of 
vdsc_engines including joined pipes.


So with bigjoiner the function will return 4.

This was good to calculate Pipe BW check: (Pixel clock < PPC * CDCLK 
frequency * Number of pipes joined


as we get PPC * number of pipes joined from 
intel_dsc_get_num_vdsc_instances)


Or to calculate DSC_PIC_WIDTH PPS parameter.

But here we perhaps need intel_dsc_get_vdsc_engines_per_pipe that will 
just return 2 if dsc_split 1 otherwise.


Thanks & Regards,

Ankit



With that clarified,

Reviewed-by: Stanislav Lisovskiy 


intel_dp_mode_to_fec_clock(mode_clock);
  
  		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);

--
2.40.1



Re: [Intel-gfx] [PATCH v2] drm/i915/display/lspcon: Increase LSPCON mode settle timeout

2023-07-09 Thread Nautiyal, Ankit K



On 7/8/2023 1:04 AM, Pablo Ceballos wrote:

On Wed, Jun 14, 2023 at 9:35 PM Nautiyal, Ankit K
 wrote:

I was wondering if trying to set LS/PCON mode multiple time will have
any effect.

Unfortunately I do not have access to machine with Parade LSPCON chip,
had suggested in yet another git lab issue [2].

I have a patch for this, sent to try-bot, though not sent to intel-gfx
yet [3].

I tested this patch and it did not resolve the problem. The error log
was repeated multiple times and there were still link training issues
afterwards.


Really appreciate to try this thing out, thanks. Too bad it didn't 
workout :(


I have seen increasing timeout does improves situation, but didn't have 
enough data points to come to a timeout value.


I agree with the change based on the experiments and data you have shared.

Lets just change the timeout to 800 ms when the lspcon->vendor is 
LSPCON_VENDOR_PARADE, so that it doesn't have any effect on platforms 
that don't have this.


IMHO a function to get timeout value based on lspcon vendor will be 
better (returns 800 ms for Parade, 400 otherwise.)


In the function itself, we can have the explanation of arriving at 800 
ms for the Parade chip (as given in the commit message) as a comment.



Thanks again for trying different solutions.

Regards,

Ankit



The timeout value was already increased from 100 ms to 400 ms earlier too.

If there is indeed no other way, perhaps need to have this solution.

Yes, can this please be merged?

Regards,
Pablo


Re: [Intel-gfx] [PATCH v2] drm/i915/display/lspcon: Increase LSPCON mode settle timeout

2023-06-14 Thread Nautiyal, Ankit K



On 6/15/2023 5:24 AM, Pablo Ceballos wrote:

This is to eliminate all cases of "*ERROR* LSPCON mode hasn't settled",
followed by link training errors. Intel engineers recommended increasing
this timeout and that does resolve the issue.

On some CometLake-based device designs the Parade PS175 takes more than
400ms to settle in PCON mode. 100 reboot trials on one device resulted
in a median settle time of 440ms and a maximum of 444ms. Even after
increasing the timeout to 500ms, 2% of devices still had this error. So
this increases the timeout to 800ms.


In one of the gitlab issue, it was tried with 1000ms as well, situation 
did improve, but issue didn't get fully resolved. [1].


I was wondering if trying to set LS/PCON mode multiple time will have 
any effect.


Unfortunately I do not have access to machine with Parade LSPCON chip, 
had suggested in yet another git lab issue [2].


I have a patch for this, sent to try-bot, though not sent to intel-gfx 
yet [3].



The timeout value was already increased from 100 ms to 400 ms earlier too.

If there is indeed no other way, perhaps need to have this solution.


[1] https://gitlab.freedesktop.org/drm/intel/-/issues/4516#note_1406500

[2] https://gitlab.freedesktop.org/drm/intel/-/issues/4458#note_1922654

[3] Patch : 
https://patchwork.freedesktop.org/patch/538819/?series=118208&rev=1



Regards,

Ankit




Signed-off-by: Pablo Ceballos 
---

Changelog since v1:
- Added more details in the commit message

  drivers/gpu/drm/i915/display/intel_lspcon.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c 
b/drivers/gpu/drm/i915/display/intel_lspcon.c
index bb3b5355a0d9..d7299fdc43ad 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -167,7 +167,7 @@ static enum drm_lspcon_mode lspcon_wait_mode(struct 
intel_lspcon *lspcon,
drm_dbg_kms(&i915->drm, "Waiting for LSPCON mode %s to settle\n",
lspcon_mode_name(mode));
  
-	wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);

+   wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 800);
if (current_mode != mode)
drm_err(&i915->drm, "LSPCON mode hasn't settled\n");
  


Re: [PATCH 12/13] drm/i915/dp: Get optimal link config to have best compressed bpp

2023-05-18 Thread Nautiyal, Ankit K

Thanks Stan and Ville for the review comments.

I agree can have some documentation about the values used, instead of 
magic numbers.


Also, Ville's approach for dsc_{sink,source}_{min,max}_bpp() seems good, 
and that can be used as helpers in MST case too.


Will add the changes in the next version of the patch.


Thanks & Regards,

Ankit


On 5/16/2023 5:10 PM, Ville Syrjälä wrote:

On Tue, May 16, 2023 at 01:43:44PM +0300, Lisovskiy, Stanislav wrote:

On Fri, May 12, 2023 at 11:54:16AM +0530, Ankit Nautiyal wrote:

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.

v2:
-Avoid ending up with compressed bpp, same as pipe bpp. (Stan)
-Fix the checks for limits->max/min_bpp while iterating over list of
  valid DSC bpcs. (Stan)

v3:
-Refactor the code to have pipe bpp/compressed bpp computation and slice
count calculation separately for different cases.

v4:
-Separate the pipe_bpp calculation for eDP and DP.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 39e2bf3d738d..578320220c9a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1642,6 +1642,209 @@ static bool intel_dp_dsc_supports_format(struct 
intel_dp *intel_dp,
return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, 
sink_dsc_format);
  }
  
+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,
+  int timeslots)
+{
+   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_max_compressed_bpp(dev_priv,
+ 
link_rate,
+ 
lane_count,
+ 
adjusted_mode->crtc_clock,
+ 
adjusted_mode->crtc_hdisplay,
+ 
pipe_config->bigjoiner_pipes,
+ 
pipe_config->output_format,
+ 
pipe_bpp, timeslots);
+   /*
+* According to DSC 1.2a Section 4.1.1 Table 4.1 the 
maximum
+* supported PPS value can be 63.9375 and with the 
further
+* mention that bpp should be programmed double the 
target bpp
+* restricting our target bpp to be 31.9375 at max
+*/
+   if (pipe_config->output_format == 
INTEL_OUTPUT_FORMAT_YCBCR420)
+   dsc_max_bpp = min_t(u16, dsc_max_bpp, 31);
+
+   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
+u16 intel_dp_dsc_max_sink_compressed_bppx16(struct intel_dp *i

Re: [PATCH 04/13] drm/i915/dp: Update Bigjoiner interface bits for computing compressed bpp

2023-05-18 Thread Nautiyal, Ankit K



On 5/15/2023 7:21 PM, Ville Syrjälä wrote:

On Fri, May 12, 2023 at 11:54:08AM +0530, Ankit Nautiyal wrote:

In Bigjoiner check for DSC, bigjoiner interface bits for DP for
DISPLAY > 13 is 36 (Bspec: 49259).

v2: Corrected Display ver to 13.

v3: Follow convention for conditional statement. (Ville)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 24de25551a49..bca80c0793e9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -783,8 +783,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
  
  	if (bigjoiner) {

+   int bigjoiner_interface_bits = DISPLAY_VER(i915) > 13 ? 36 : 24;

'x >= 14' is the usual convention.

with that
Reviewed-by: Ville Syrjälä 


Thanks Ville for the reviews.

Will fix the check in next version of the patch.

Regards,

Ankit




u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * 48 /
+   i915->display.cdclk.max_cdclk_freq * 2 * 
bigjoiner_interface_bits /
intel_dp_mode_to_fec_clock(mode_clock);
  
  		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);

--
2.25.1


Re: [PATCH 05/13] drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck

2023-05-18 Thread Nautiyal, Ankit K

Thanks Ville and Stan for the comments.

I agree with the changes in _plane_min_cdclk and 
intel_pixel_rate_to_cdclk regarding PPC.


But I am a little confused for about the pixel clock.

Please find my comments inline:


On 5/16/2023 3:41 PM, Lisovskiy, Stanislav wrote:

On Mon, May 15, 2023 at 05:44:51PM +0300, Ville Syrjälä wrote:

On Fri, May 12, 2023 at 11:54:09AM +0530, Ankit Nautiyal wrote:

As per Bsepc:49259, Bigjoiner BW check puts restriction on the
compressed bpp for a given CDCLK, pixelclock in cases where
Bigjoiner + DSC are used.

Currently compressed bpp is computed first, and it is ensured that
the bpp will work at least with the max CDCLK freq.

Since the CDCLK is computed later, lets account for Bigjoiner BW
check while calculating Min CDCLK.

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

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 6bed75f1541a..3532640c5027 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2520,6 +2520,46 @@ static int intel_planes_min_cdclk(const struct 
intel_crtc_state *crtc_state)
return min_cdclk;
  }
  
+static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)

+{
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+   struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+   int min_cdclk = 0;
+
+   /*
+* When we decide to use only one VDSC engine, since
+* each VDSC operates with 1 ppc throughput, pixel clock
+* cannot be higher than the VDSC clock (cdclk)
+*/
+   if (!crtc_state->dsc.dsc_split)
+   min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
+
+   if (crtc_state->bigjoiner_pipes) {
+   /*
+* According to Bigjoiner bw check:
+* compressed_bpp <= PPC * CDCLK * Big joiner Interface bits / 
Pixel clock
+*
+* We have already computed compressed_bpp, so now compute the 
min CDCLK that
+* is required to support this compressed_bpp.
+*
+* => CDCLK >= compressed_bpp * Pixel clock / (PPC * Bigjoiner 
Interface bits)
+*
+* Since Num of pipes joined = 2, and PPC = 2 with bigjoiner
+* => CDCLK >= compressed_bpp * pixel_rate  / Bigjoiner 
Interface bits
+*
+* #TODO Bspec mentions to account for FEC overhead while using 
pixel clock.
+* Check if we need to use FEC overhead in the above 
calculations.
+*/
+   int bigjoiner_interface_bits = DISPLAY_VER(i915) > 13 ? 36 : 24;
+   int min_cdclk_bj = crtc_state->dsc.compressed_bpp * 
crtc_state->pixel_rate /
+  bigjoiner_interface_bits;

pixel_rate is the downscale adjusted thing, so it doesn't seem
like the correct thing to use here.

Hmm. Assuming that the single VDSC engine really throttles the entire
pipe to 1 PPC then we should probably account for the 1 vs. 2 PPC
difference in *_plane_min_cdclk() and intel_pixel_rate_to_cdclk()
directly. Currently all of those assume 2 PPC.


Hmm alright,  I do see in plane_min_cdclk and intel_pixel_rate_to_cdclk 
we assume 2 PPC.


So I can add a check for the dsc_split and use 1 PPC/2PPC  in the two 
functions as a separate patch perhaps.




Main thing is to properly align that one you propose above with that check,
where we decide how many VDSC engines to use:

 /*
  * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
  * is greater than the maximum Cdclock and if slice count is even
  * then we need to use 2 VDSC instances.
  */
 if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq) {
 if (pipe_config->dsc.slice_count > 1) {
 pipe_config->dsc.dsc_split = true;
 } else {
 drm_dbg_kms(&dev_priv->drm,
 "Cannot split stream to use 2 VDSC 
instances\n");
 return -EINVAL;
 }
 }

Otherwise I agree that we should do that check preferrably in *_plane_min_cdclk
and use plane data rate which is adjusted after scaling is applied(I think we 
even have correspondent function there)
It is strange that scaling wasn't mentioned in BSpec formula.
I would also say that we should account for number of slices(i.e VDSC engines) 
now only in Bigjoiner case, but always, as I understand that number can be 
different not only for Bigjoiner cases.

Stan


Hmm does it mean:

if (!crtc_state->dsc.dsc_split) {

    if (bigjoiner)

        min_cdclk = compressed_bpp * Pixel clock / (PPC * Bigjoiner 
Interface bits);


    else

           

Re: [PATCH 2/2] drm/dsc: fix DP_DSC_MAX_BPP_DELTA_* macro values

2023-04-20 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

On 4/6/2023 7:16 PM, Jani Nikula wrote:

The macro values just don't match the specs. Fix them.

Fixes: 1482ec00be4a ("drm: Add missing DP DSC extended capability definitions.")
Cc: Vinod Govindapillai 
Cc: Stanislav Lisovskiy 
Signed-off-by: Jani Nikula 
---
  include/drm/display/drm_dp.h | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 89d5a700b04d..f8813c1e059b 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -286,8 +286,8 @@
  
  #define DP_DSC_MAX_BITS_PER_PIXEL_HI0x068   /* eDP 1.4 */

  # define DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK  (0x3 << 0)
-# define DP_DSC_MAX_BPP_DELTA_VERSION_MASK  0x06
-# define DP_DSC_MAX_BPP_DELTA_AVAILABILITY  0x08
+# define DP_DSC_MAX_BPP_DELTA_VERSION_MASK  (0x3 << 5)   /* eDP 1.5 & DP 2.0 */
+# define DP_DSC_MAX_BPP_DELTA_AVAILABILITY  (1 << 7) /* eDP 1.5 & DP 2.0 */
  
  #define DP_DSC_DEC_COLOR_FORMAT_CAP 0x069

  # define DP_DSC_RGB (1 << 0)


Re: [Intel-gfx] [PATCH 1/2] drm/dsc: fix drm_edp_dsc_sink_output_bpp() DPCD high byte usage

2023-04-20 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

On 4/6/2023 7:16 PM, Jani Nikula wrote:

The operator precedence between << and & is wrong, leading to the high
byte being completely ignored. For example, with the 6.4 format, 32
becomes 0 and 24 becomes 8. Fix it, and remove the slightly confusing
and unnecessary DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT macro while at it.

Fixes: 0575650077ea ("drm/dp: DRM DP helper/macros to get DP sink DSC 
parameters")
Cc: Stanislav Lisovskiy 
Cc: Manasi Navare 
Cc: Anusha Srivatsa 
Cc:  # v5.0+
Signed-off-by: Jani Nikula 
---
  include/drm/display/drm_dp.h| 1 -
  include/drm/display/drm_dp_helper.h | 5 ++---
  2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 358db4a9f167..89d5a700b04d 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -286,7 +286,6 @@
  
  #define DP_DSC_MAX_BITS_PER_PIXEL_HI0x068   /* eDP 1.4 */

  # define DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK  (0x3 << 0)
-# define DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT 8
  # define DP_DSC_MAX_BPP_DELTA_VERSION_MASK  0x06
  # define DP_DSC_MAX_BPP_DELTA_AVAILABILITY  0x08
  
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h

index 533d3ee7fe05..86f24a759268 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -181,9 +181,8 @@ static inline u16
  drm_edp_dsc_sink_output_bpp(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
  {
return dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] |
-   (dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] &
-DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK <<
-DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT);
+   ((dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] &
+ DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK) << 8);
  }
  
  static inline u32


Re: [PATCH 02/16] drm/i915/dp: Avoid forcing DSC BPC for MST case

2023-01-24 Thread Nautiyal, Ankit K



On 1/24/2023 9:53 PM, Jani Nikula wrote:

On Fri, 20 Jan 2023, Ankit Nautiyal  wrote:

For MST the bpc is hardcoded to 8, and pipe bpp to 24.
So avoid forcing DSC bpc for MST case.

It's likely better to warn and ignore the debug flag than to bail out.


Hmm..but then the test using this flag will not come to know that bpc it 
wanted to force, was indeed used.


Currently there is no way to read the bpc that was selected by the 
driver, and so the test can try to force DSC, and the bpc and rely on 
whether the ioctl passes or fails.


Regards,

Ankit




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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 93aebd3683a4..3d828ea0894d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1500,14 +1500,13 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_supports_dsc(intel_dp, pipe_config))
return -EINVAL;
  
-	if (compute_pipe_bpp)

+   if (intel_dp->force_dsc_bpc && compute_pipe_bpp) {
+   pipe_bpp = intel_dp->force_dsc_bpc * 3;
+   drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d\n", 
pipe_bpp);
+   } else if (compute_pipe_bpp) {
pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, 
conn_state->max_requested_bpc);
-   else
+   } else {
pipe_bpp = pipe_config->pipe_bpp;
-
-   if (intel_dp->force_dsc_bpc) {
-   pipe_bpp = intel_dp->force_dsc_bpc * 3;
-   drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d", 
pipe_bpp);
}
  
  	/* Min Input BPC for ICL+ is 8 */

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 8b0e4defa3f1..9be04c60cced 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -325,6 +325,14 @@ static int intel_dp_mst_compute_config(struct 
intel_encoder *encoder,
/* enable compression if the mode doesn't fit available BW */
drm_dbg_kms(&dev_priv->drm, "Force DSC en = %d\n", 
intel_dp->force_dsc_en);
if (ret || intel_dp->force_dsc_en) {
+   if (intel_dp->force_dsc_bpc) {
+   /*
+* FIXME: As bpc is hardcoed to 8 bpc as mentioned 
above,
+* Avoid force BPC for now.
+*/
+   drm_dbg_kms(&dev_priv->drm, "Cannot Force BPC for 
MST\n");
+   return -EINVAL;
+   }
/*
 * Try to get at least some timeslots and then see, if
 * we can fit there with DSC.


Re: [PATCH 4/4] drm/edid: Avoid multiple log lines for HFVSDB parsing

2022-09-14 Thread Nautiyal, Ankit K

Thanks Jani for the review and suggestions.

I agree with the suggestions and will make changes in next version.

Please find my response inline:

On 9/13/2022 7:24 PM, Jani Nikula wrote:

On Thu, 11 Aug 2022, Ankit Nautiyal  wrote:

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;

This should be int because display->max_tmds_clock is int. Yes, it's a
change from the current local var, but logging u32 would require %u
instead of %d in the format string anyway, so better just use the right
type.

Alright, makes sense.

+   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);

Hmm, the logic for what is logged gets changed.


You are right, we are now logging this always.

Should we log this only for rate > 340MHz? The logging line at last will 
require some jugglery.



}
  
  		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",

Nitpicks, %d needs int instead of u32, "kHz" not "Khz", "HDMI 2.1" and
"DSC 1.2" with spaces, would prefer a space after ":".

Noted, Will fix this.



+   max_tmds_clock, max_frl_rate ? "yes" : "no", dsc_support ? "yes" : 
"no");

See str_yes_no().


Right, should have used str_yes_no().


Thanks & Regards,

Ankit



BR,
Jani.


  }
  
  static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,


Re: [PATCH] drm/drm_edid: Refactor HFVSDB parsing for DSC1.2

2022-08-10 Thread Nautiyal, Ankit K



On 8/2/2022 8:19 PM, Jani Nikula wrote:

On Fri, 22 Jul 2022, Ankit Nautiyal  wrote:

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.

I think this patch tries to do too much at once. Please split it up. One
thing per patch.

I think the logging is excessive, and what logging remains should use
drm_dbg_kms() instead of DRM_DEBUG_KMS().

Further comments inline.


Hi Jani,

Thanks for the comments. I do agree, it makes more sense to have a 
separate patches with incremental changes.


Will send another series with the comments addressed.

Please find the response inline:




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)

Arguments should always be in the order: context, destination, source.


Noted. Will take care in the next patch.





+{
+   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;

There's cea_db_payload_len() for this, and you can use that directly
instead of caching the value to a local variable.


Right, will use the function here.





+   u8 dsc_max_frl_rate;
+   u8 dsc_max_slices;

These two are local to a tiny if block and should be declared there.

Agreed. Will fix in the next patchset.



+   struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
+
+   if (db_length < 7 || db_length > 31)
+   return;

Both cea_db_is_hdmi_forum_vsdb() and cea_db_is_hdmi_forum_scdb() check
the payload is >= 7 bytes before this one even gets called.

There's no reason to not parse the first 31 bytes if the length is > 31
bytes. That condition just breaks future compatibility for no reason.


Makes sense, will drop these checks.




  
  	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]) {

Matter of taste, but I'd probably make these

if (cea_db_payload_len(hf_scds) >= 11 && hf_scds[11])

and drop the early returns, and add a single (or very few) debug logging
call at the end.



Hmm. We can get rid of early return.

Will have a s

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

2022-05-11 Thread Nautiyal, Ankit K



On 5/10/2022 12:31 PM, Ville Syrjälä wrote:

On Mon, May 09, 2022 at 03:01:30PM +0530, Ankit Nautiyal wrote:

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.

Wy are we trying to pass HDMI-2.1 tests on a device that
doesn't even support HDMI-2.1?


Hi Ville,

As I understand, the HDMI2.1a supersedes HDMI2.0b [1], and so these 
platforms must pass the HDMI2.1 CTS.
The HDMI2.1a spec introduces Marketing Feature names for 4K100, 4K120, 
8k@50, 8k@60 with suffix A, and B.
Suffix A meaning mode supported without compression, and B meaning, mode 
supported with compression.
e.g 4K@120AB marketing feature name means the device supports 4k@120 
both with and without compression.
But as per the spec, both variants of Marketing names require FRL to be 
supported along with other requirements.
There are tests that expect these modes not to be enumerated, if the 
source does support the given requirements.


[1] https://www.hdmi.org/spec/hdmi2_1

Regards,

Ankit




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


Re: [PATCH v2 25/25] drm/edid: convert version_greater() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere. Also make version_greater()
a function for type safety.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 29 +
  1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a44818f44718..429078bcf372 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -45,10 +45,6 @@
  
  #include "drm_crtc_internal.h"
  
-#define version_greater(edid, maj, min) \

-   (((edid)->version > (maj)) || \
-((edid)->version == (maj) && (edid)->revision > (min)))
-
  static int oui(u8 first, u8 second, u8 third)
  {
return (first << 16) | (second << 8) | third;
@@ -1576,6 +1572,15 @@ struct drm_edid {
const struct edid *edid;
  };
  
+static bool version_greater(const struct drm_edid *drm_edid,

+   u8 version, u8 revision)
+{
+   const struct edid *edid = drm_edid->edid;
+
+   return edid->version > version ||
+   (edid->version == version && edid->revision > revision);
+}
+
  static int edid_extension_block_count(const struct edid *edid)
  {
return edid->extensions;
@@ -3232,7 +3237,7 @@ do_inferred_modes(const struct detailed_timing *timing, 
void *c)
  closure->drm_edid,
  timing);
  
-	if (!version_greater(closure->drm_edid->edid, 1, 1))

+   if (!version_greater(closure->drm_edid, 1, 1))
return; /* GTF not defined yet */
  
  	switch (range->flags) {

@@ -3243,7 +3248,7 @@ do_inferred_modes(const struct detailed_timing *timing, 
void *c)
  timing);
break;
case 0x04: /* cvt, only in 1.4+ */
-   if (!version_greater(closure->drm_edid->edid, 1, 3))
+   if (!version_greater(closure->drm_edid, 1, 3))
break;
  
  		closure->modes += drm_cvt_modes_for_range(closure->connector,

@@ -3264,7 +3269,7 @@ static int add_inferred_modes(struct drm_connector 
*connector,
.drm_edid = drm_edid,
};
  
-	if (version_greater(drm_edid->edid, 1, 0))

+   if (version_greater(drm_edid, 1, 0))
drm_for_each_detailed_block(drm_edid, do_inferred_modes, 
&closure);
  
  	return closure.modes;

@@ -3341,7 +3346,7 @@ static int add_established_modes(struct drm_connector 
*connector,
}
}
  
-	if (version_greater(edid, 1, 0))

+   if (version_greater(drm_edid, 1, 0))
drm_for_each_detailed_block(drm_edid, do_established_modes,
&closure);
  
@@ -3396,7 +3401,7 @@ static int add_standard_modes(struct drm_connector *connector,

}
}
  
-	if (version_greater(drm_edid->edid, 1, 0))

+   if (version_greater(drm_edid, 1, 0))
drm_for_each_detailed_block(drm_edid, do_standard_modes,
&closure);
  
@@ -3476,7 +3481,7 @@ add_cvt_modes(struct drm_connector *connector, const struct drm_edid *drm_edid)

.drm_edid = drm_edid,
};
  
-	if (version_greater(drm_edid->edid, 1, 2))

+   if (version_greater(drm_edid, 1, 2))
drm_for_each_detailed_block(drm_edid, do_cvt_mode, &closure);
  
  	/* XXX should also look for CVT codes in VTB blocks */

@@ -3532,7 +3537,7 @@ static int add_detailed_modes(struct drm_connector 
*connector,
.quirks = quirks,
};
  
-	if (closure.preferred && !version_greater(drm_edid->edid, 1, 3))

+   if (closure.preferred && !version_greater(drm_edid, 1, 3))
closure.preferred =
(drm_edid->edid->features & 
DRM_EDID_FEATURE_PREFERRED_TIMING);
  
@@ -5591,7 +5596,7 @@ static void drm_get_monitor_range(struct drm_connector *connector,

  {
struct drm_display_info *info = &connector->display_info;
  
-	if (!version_greater(drm_edid->edid, 1, 1))

+   if (!version_greater(drm_edid, 1, 1))
return;
  
  	drm_for_each_detailed_block(drm_edid, get_monitor_range,


Re: [PATCH v2 24/25] drm/displayid: convert to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Rebase

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_displayid.c | 16 
  drivers/gpu/drm/drm_edid.c  | 17 ++---
  include/drm/drm_displayid.h |  6 +++---
  include/drm/drm_edid.h  |  6 --
  4 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..38ea8203df45 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -33,11 +33,11 @@ static int validate_displayid(const u8 *displayid, int 
length, int idx)
return 0;
  }
  
-static const u8 *drm_find_displayid_extension(const struct edid *edid,

+static const u8 *drm_find_displayid_extension(const struct drm_edid *drm_edid,
  int *length, int *idx,
  int *ext_index)
  {
-   const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, 
ext_index);
+   const u8 *displayid = drm_find_edid_extension(drm_edid, DISPLAYID_EXT, 
ext_index);
const struct displayid_header *base;
int ret;
  
@@ -58,12 +58,12 @@ static const u8 *drm_find_displayid_extension(const struct edid *edid,

return displayid;
  }
  
-void displayid_iter_edid_begin(const struct edid *edid,

+void displayid_iter_edid_begin(const struct drm_edid *drm_edid,
   struct displayid_iter *iter)
  {
memset(iter, 0, sizeof(*iter));
  
-	iter->edid = edid;

+   iter->drm_edid = drm_edid;
  }
  
  static const struct displayid_block *

@@ -88,7 +88,7 @@ __displayid_iter_next(struct displayid_iter *iter)
  {
const struct displayid_block *block;
  
-	if (!iter->edid)

+   if (!iter->drm_edid)
return NULL;
  
  	if (iter->section) {

@@ -96,7 +96,7 @@ __displayid_iter_next(struct displayid_iter *iter)
block = displayid_iter_block(iter);
if (WARN_ON(!block)) {
iter->section = NULL;
-   iter->edid = NULL;
+   iter->drm_edid = NULL;
return NULL;
}
  
@@ -109,12 +109,12 @@ __displayid_iter_next(struct displayid_iter *iter)

}
  
  	for (;;) {

-   iter->section = drm_find_displayid_extension(iter->edid,
+   iter->section = drm_find_displayid_extension(iter->drm_edid,
 &iter->length,
 &iter->idx,
 &iter->ext_index);
if (!iter->section) {
-   iter->edid = NULL;
+   iter->drm_edid = NULL;
return NULL;
}
  
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c

index 26ac4d262e31..a44818f44718 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3563,10 +3563,13 @@ static int add_detailed_modes(struct drm_connector 
*connector,
  
  /*

   * Search EDID for CEA extension block.
+ *
+ * FIXME: Prefer not returning pointers to raw EDID data.
   */
-const u8 *drm_find_edid_extension(const struct edid *edid,
+const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
  int ext_id, int *ext_index)
  {
+   const struct edid *edid = drm_edid ? drm_edid->edid : NULL;
const u8 *edid_ext = NULL;
int i;
  
@@ -3598,11 +3601,11 @@ static bool drm_edid_has_cta_extension(const struct drm_edid *drm_edid)

bool found = false;
  
  	/* Look for a top level CEA extension block */

-   if (drm_find_edid_extension(drm_edid->edid, CEA_EXT, &ext_index))
+   if (drm_find_edid_extension(drm_edid, CEA_EXT, &ext_index))
return true;
  
  	/* CEA blocks can also be found embedded in a DisplayID block */

-   displayid_iter_edid_begin(drm_edid->edid, &iter);
+   displayid_iter_edid_begin(drm_edid, &iter);
displayid_iter_for_each(block, &iter) {
if (block->tag == DATA_BLOCK_CTA) {
found = true;
@@ -4454,7 +4457,7 @@ static void cea_db_iter_edid_begin(const struct drm_edid 
*drm_edid,
memset(iter, 0, sizeof(*iter));
  
  	drm_edid_iter_begin(drm_edid, &iter->edid_iter);

-   displayid_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, 
&iter->displayid_iter);
+   displayid_iter_edid_begin(drm_edid, &iter->displayid_iter);
  }
  
  static const struct cea_db *

@@ -5657,7 +5660,7 @@ static void drm_update_mso(struct drm_connector 
*connector,
const struct displayid_block *block;
struct displayid_iter iter;
  
-	displayid_iter_edid_begin(drm_edid->edid, &iter);

+   displayid_iter_ed

Re: [Intel-gfx] [PATCH v2 23/25] drm/edid: add drm_edid helper for drm_update_tile_info()

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Handle NULL EDID pointer (Ville, CI)

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 14 +++---
  1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d857d1d74c82..26ac4d262e31 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6364,15 +6364,15 @@ static void drm_parse_tiled_block(struct drm_connector 
*connector,
}
  }
  
-void drm_update_tile_info(struct drm_connector *connector,

- const struct edid *edid)
+static void _drm_update_tile_info(struct drm_connector *connector,
+ const struct drm_edid *drm_edid)
  {
const struct displayid_block *block;
struct displayid_iter iter;
  
  	connector->has_tile = false;
  
-	displayid_iter_edid_begin(edid, &iter);

+   displayid_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);
displayid_iter_for_each(block, &iter) {
if (block->tag == DATA_BLOCK_TILED_DISPLAY)
drm_parse_tiled_block(connector, block);
@@ -6384,3 +6384,11 @@ void drm_update_tile_info(struct drm_connector 
*connector,
connector->tile_group = NULL;
}
  }
+
+void drm_update_tile_info(struct drm_connector *connector,
+ const struct edid *edid)
+{
+   struct drm_edid drm_edid;
+
+   _drm_update_tile_info(connector, drm_edid_legacy_init(&drm_edid, edid));
+}


Re: [PATCH v2 22/25] drm/edid: convert drm_edid_iter_begin() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Rebase

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 22 +++---
  1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index bd14010ed1c5..d857d1d74c82 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1632,36 +1632,36 @@ static const struct drm_edid 
*drm_edid_legacy_init(struct drm_edid *drm_edid,
   * struct drm_edid_iter iter;
   * const u8 *block;
   *
- * drm_edid_iter_begin(edid, &iter);
+ * drm_edid_iter_begin(drm_edid, &iter);
   * drm_edid_iter_for_each(block, &iter) {
   * // do stuff with block
   * }
   * drm_edid_iter_end(&iter);
   */
  struct drm_edid_iter {
-   const struct edid *edid;
+   const struct drm_edid *drm_edid;
  
  	/* Current block index. */

int index;
  };
  
-static void drm_edid_iter_begin(const struct edid *edid,

+static void drm_edid_iter_begin(const struct drm_edid *drm_edid,
struct drm_edid_iter *iter)
  {
memset(iter, 0, sizeof(*iter));
  
-	iter->edid = edid;

+   iter->drm_edid = drm_edid;
  }
  
  static const void *__drm_edid_iter_next(struct drm_edid_iter *iter)

  {
const void *block = NULL;
  
-	if (!iter->edid)

+   if (!iter->drm_edid)
return NULL;
  
-	if (iter->index < edid_block_count(iter->edid))

-   block = edid_block_data(iter->edid, iter->index++);
+   if (iter->index < edid_block_count(iter->drm_edid->edid))
+   block = edid_block_data(iter->drm_edid->edid, iter->index++);
  
  	return block;

  }
@@ -2611,7 +2611,7 @@ static void drm_for_each_detailed_block(const struct 
drm_edid *drm_edid,
for (i = 0; i < EDID_DETAILED_TIMINGS; i++)
cb(&drm_edid->edid->detailed_timings[i], closure);
  
-	drm_edid_iter_begin(drm_edid->edid, &edid_iter);

+   drm_edid_iter_begin(drm_edid, &edid_iter);
drm_edid_iter_for_each(ext, &edid_iter) {
switch (*ext) {
case CEA_EXT:
@@ -4453,7 +4453,7 @@ static void cea_db_iter_edid_begin(const struct drm_edid 
*drm_edid,
  {
memset(iter, 0, sizeof(*iter));
  
-	drm_edid_iter_begin(drm_edid ? drm_edid->edid : NULL, &iter->edid_iter);

+   drm_edid_iter_begin(drm_edid, &iter->edid_iter);
displayid_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, 
&iter->displayid_iter);
  }
  
@@ -5163,7 +5163,7 @@ static bool _drm_detect_monitor_audio(const struct drm_edid *drm_edid)

const u8 *edid_ext;
bool has_audio = false;
  
-	drm_edid_iter_begin(drm_edid ? drm_edid->edid : NULL, &edid_iter);

+   drm_edid_iter_begin(drm_edid, &edid_iter);
drm_edid_iter_for_each(edid_ext, &edid_iter) {
if (edid_ext[0] == CEA_EXT) {
has_audio = edid_ext[3] & EDID_BASIC_AUDIO;
@@ -5516,7 +5516,7 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
struct cea_db_iter iter;
const u8 *edid_ext;
  
-	drm_edid_iter_begin(drm_edid->edid, &edid_iter);

+   drm_edid_iter_begin(drm_edid, &edid_iter);
drm_edid_iter_for_each(edid_ext, &edid_iter) {
if (edid_ext[0] != CEA_EXT)
continue;


Re: [PATCH v2 21/25] drm/edid: convert cea_db_iter_edid_begin() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Handle NULL drm_edid

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 21 +++--
  1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f072cfba9dd9..bd14010ed1c5 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4448,12 +4448,13 @@ static bool cea_db_is_vendor(const struct cea_db *db, 
int vendor_oui)
oui(data[2], data[1], data[0]) == vendor_oui;
  }
  
-static void cea_db_iter_edid_begin(const struct edid *edid, struct cea_db_iter *iter)

+static void cea_db_iter_edid_begin(const struct drm_edid *drm_edid,
+  struct cea_db_iter *iter)
  {
memset(iter, 0, sizeof(*iter));
  
-	drm_edid_iter_begin(edid, &iter->edid_iter);

-   displayid_iter_edid_begin(edid, &iter->displayid_iter);
+   drm_edid_iter_begin(drm_edid ? drm_edid->edid : NULL, &iter->edid_iter);
+   displayid_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, 
&iter->displayid_iter);
  }
  
  static const struct cea_db *

@@ -4675,7 +4676,7 @@ static int add_cea_modes(struct drm_connector *connector,
struct cea_db_iter iter;
int modes = 0;
  
-	cea_db_iter_edid_begin(drm_edid->edid, &iter);

+   cea_db_iter_edid_begin(drm_edid, &iter);
cea_db_iter_for_each(db, &iter) {
const u8 *hdmi = NULL, *video = NULL;
u8 hdmi_len = 0, video_len = 0;
@@ -4926,7 +4927,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector,
eld[DRM_ELD_PRODUCT_CODE0] = drm_edid->edid->prod_code[0];
eld[DRM_ELD_PRODUCT_CODE1] = drm_edid->edid->prod_code[1];
  
-	cea_db_iter_edid_begin(drm_edid->edid, &iter);

+   cea_db_iter_edid_begin(drm_edid, &iter);
cea_db_iter_for_each(db, &iter) {
const u8 *data = cea_db_data(db);
int len = cea_db_payload_len(db);
@@ -4979,7 +4980,7 @@ static int _drm_edid_to_sad(const struct drm_edid 
*drm_edid,
struct cea_db_iter iter;
int count = 0;
  
-	cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);

+   cea_db_iter_edid_begin(drm_edid, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_tag(db) == CTA_DB_AUDIO) {
int j;
@@ -5032,7 +5033,7 @@ static int _drm_edid_to_speaker_allocation(const struct 
drm_edid *drm_edid,
struct cea_db_iter iter;
int count = 0;
  
-	cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);

+   cea_db_iter_edid_begin(drm_edid, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_tag(db) == CTA_DB_SPEAKER &&
cea_db_payload_len(db) == 3) {
@@ -5123,7 +5124,7 @@ static bool _drm_detect_hdmi_monitor(const struct 
drm_edid *drm_edid)
 * Because HDMI identifier is in Vendor Specific Block,
 * search it from all data blocks of CEA extension.
 */
-   cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);
+   cea_db_iter_edid_begin(drm_edid, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_is_hdmi_vsdb(db)) {
hdmi = true;
@@ -5177,7 +5178,7 @@ static bool _drm_detect_monitor_audio(const struct 
drm_edid *drm_edid)
goto end;
}
  
-	cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);

+   cea_db_iter_edid_begin(drm_edid, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_tag(db) == CTA_DB_AUDIO) {
const u8 *data = cea_db_data(db);
@@ -5536,7 +5537,7 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
}
drm_edid_iter_end(&edid_iter);
  
-	cea_db_iter_edid_begin(drm_edid->edid, &iter);

+   cea_db_iter_edid_begin(drm_edid, &iter);
cea_db_iter_for_each(db, &iter) {
/* FIXME: convert parsers to use struct cea_db */
const u8 *data = (const u8 *)db;


Re: [Intel-gfx] [PATCH v2 20/25] drm/edid: add drm_edid helper for drm_detect_monitor_audio()

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Handle NULL EDID pointer (Ville, CI)

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 37 ++---
  1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index fc74159cd426..f072cfba9dd9 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5154,19 +5154,7 @@ bool drm_detect_hdmi_monitor(const struct edid *edid)
  }
  EXPORT_SYMBOL(drm_detect_hdmi_monitor);
  
-/**

- * drm_detect_monitor_audio - check monitor audio capability
- * @edid: EDID block to scan
- *
- * Monitor should have CEA extension block.
- * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
- * audio' only. If there is any audio extension block and supported
- * audio format, assume at least 'basic audio' support, even if 'basic
- * audio' is not defined in EDID.
- *
- * Return: True if the monitor supports audio, false otherwise.
- */
-bool drm_detect_monitor_audio(const struct edid *edid)
+static bool _drm_detect_monitor_audio(const struct drm_edid *drm_edid)
  {
struct drm_edid_iter edid_iter;
const struct cea_db *db;
@@ -5174,7 +5162,7 @@ bool drm_detect_monitor_audio(const struct edid *edid)
const u8 *edid_ext;
bool has_audio = false;
  
-	drm_edid_iter_begin(edid, &edid_iter);

+   drm_edid_iter_begin(drm_edid ? drm_edid->edid : NULL, &edid_iter);
drm_edid_iter_for_each(edid_ext, &edid_iter) {
if (edid_ext[0] == CEA_EXT) {
has_audio = edid_ext[3] & EDID_BASIC_AUDIO;
@@ -5189,7 +5177,7 @@ bool drm_detect_monitor_audio(const struct edid *edid)
goto end;
}
  
-	cea_db_iter_edid_begin(edid, &iter);

+   cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_tag(db) == CTA_DB_AUDIO) {
const u8 *data = cea_db_data(db);
@@ -5207,6 +5195,25 @@ bool drm_detect_monitor_audio(const struct edid *edid)
  end:
return has_audio;
  }
+
+/**
+ * drm_detect_monitor_audio - check monitor audio capability
+ * @edid: EDID block to scan
+ *
+ * Monitor should have CEA extension block.
+ * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
+ * audio' only. If there is any audio extension block and supported
+ * audio format, assume at least 'basic audio' support, even if 'basic
+ * audio' is not defined in EDID.
+ *
+ * Return: True if the monitor supports audio, false otherwise.
+ */
+bool drm_detect_monitor_audio(const struct edid *edid)
+{
+   struct drm_edid drm_edid;
+
+   return _drm_detect_monitor_audio(drm_edid_legacy_init(&drm_edid, edid));
+}
  EXPORT_SYMBOL(drm_detect_monitor_audio);
  
  


Re: [Intel-gfx] [PATCH v2 19/25] drm/edid: add drm_edid helper for drm_detect_hdmi_monitor()

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Handle NULL EDID pointer (Ville, CI)

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 33 -
  1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5cc851f6d3b3..fc74159cd426 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5113,18 +5113,7 @@ int drm_av_sync_delay(struct drm_connector *connector,
  }
  EXPORT_SYMBOL(drm_av_sync_delay);
  
-/**

- * drm_detect_hdmi_monitor - detect whether monitor is HDMI
- * @edid: monitor EDID information
- *
- * Parse the CEA extension according to CEA-861-B.
- *
- * Drivers that have added the modes parsed from EDID to drm_display_info
- * should use &drm_display_info.is_hdmi instead of calling this function.
- *
- * Return: True if the monitor is HDMI, false if not or unknown.
- */
-bool drm_detect_hdmi_monitor(const struct edid *edid)
+static bool _drm_detect_hdmi_monitor(const struct drm_edid *drm_edid)
  {
const struct cea_db *db;
struct cea_db_iter iter;
@@ -5134,7 +5123,7 @@ bool drm_detect_hdmi_monitor(const struct edid *edid)
 * Because HDMI identifier is in Vendor Specific Block,
 * search it from all data blocks of CEA extension.
 */
-   cea_db_iter_edid_begin(edid, &iter);
+   cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_is_hdmi_vsdb(db)) {
hdmi = true;
@@ -5145,6 +5134,24 @@ bool drm_detect_hdmi_monitor(const struct edid *edid)
  
  	return hdmi;

  }
+
+/**
+ * drm_detect_hdmi_monitor - detect whether monitor is HDMI
+ * @edid: monitor EDID information
+ *
+ * Parse the CEA extension according to CEA-861-B.
+ *
+ * Drivers that have added the modes parsed from EDID to drm_display_info
+ * should use &drm_display_info.is_hdmi instead of calling this function.
+ *
+ * Return: True if the monitor is HDMI, false if not or unknown.
+ */
+bool drm_detect_hdmi_monitor(const struct edid *edid)
+{
+   struct drm_edid drm_edid;
+
+   return _drm_detect_hdmi_monitor(drm_edid_legacy_init(&drm_edid, edid));
+}
  EXPORT_SYMBOL(drm_detect_hdmi_monitor);
  
  /**


Re: [Intel-gfx] [PATCH v2 18/25] drm/edid: add drm_edid helper for drm_edid_to_speaker_allocation()

2022-05-10 Thread Nautiyal, Ankit K

LGTM

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.'

v2: Handle NULL EDID pointer (Ville, CI)

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 37 +++--
  1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dee09359bbc3..5cc851f6d3b3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5025,25 +5025,14 @@ int drm_edid_to_sad(const struct edid *edid, struct 
cea_sad **sads)
  }
  EXPORT_SYMBOL(drm_edid_to_sad);
  
-/**

- * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks 
from EDID
- * @edid: EDID to parse
- * @sadb: pointer to the speaker block
- *
- * Looks for CEA EDID block and extracts the Speaker Allocation Data Block 
from it.
- *
- * Note: The returned pointer needs to be freed using kfree().
- *
- * Return: The number of found Speaker Allocation Blocks or negative number on
- * error.
- */
-int drm_edid_to_speaker_allocation(const struct edid *edid, u8 **sadb)
+static int _drm_edid_to_speaker_allocation(const struct drm_edid *drm_edid,
+  u8 **sadb)
  {
const struct cea_db *db;
struct cea_db_iter iter;
int count = 0;
  
-	cea_db_iter_edid_begin(edid, &iter);

+   cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_tag(db) == CTA_DB_SPEAKER &&
cea_db_payload_len(db) == 3) {
@@ -5061,6 +5050,26 @@ int drm_edid_to_speaker_allocation(const struct edid 
*edid, u8 **sadb)
  
  	return count;

  }
+
+/**
+ * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks 
from EDID
+ * @edid: EDID to parse
+ * @sadb: pointer to the speaker block
+ *
+ * Looks for CEA EDID block and extracts the Speaker Allocation Data Block 
from it.
+ *
+ * Note: The returned pointer needs to be freed using kfree().
+ *
+ * Return: The number of found Speaker Allocation Blocks or negative number on
+ * error.
+ */
+int drm_edid_to_speaker_allocation(const struct edid *edid, u8 **sadb)
+{
+   struct drm_edid drm_edid;
+
+   return _drm_edid_to_speaker_allocation(drm_edid_legacy_init(&drm_edid, 
edid),
+  sadb);
+}
  EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
  
  /**


Re: [PATCH v2 17/25] drm/edid: add drm_edid helper for drm_edid_to_sad()

2022-05-10 Thread Nautiyal, Ankit K



On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Handle NULL EDID pointer (Ville, CI)

Signed-off-by: Jani Nikula 



LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit


---
  drivers/gpu/drm/drm_edid.c | 34 +-
  1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 61551ce0db88..dee09359bbc3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4972,24 +4972,14 @@ static void drm_edid_to_eld(struct drm_connector 
*connector,
  drm_eld_size(eld), total_sad_count);
  }
  
-/**

- * drm_edid_to_sad - extracts SADs from EDID
- * @edid: EDID to parse
- * @sads: pointer that will be set to the extracted SADs
- *
- * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from 
it.
- *
- * Note: The returned pointer needs to be freed using kfree().
- *
- * Return: The number of found SADs or negative number on error.
- */
-int drm_edid_to_sad(const struct edid *edid, struct cea_sad **sads)
+static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
+   struct cea_sad **sads)
  {
const struct cea_db *db;
struct cea_db_iter iter;
int count = 0;
  
-	cea_db_iter_edid_begin(edid, &iter);

+   cea_db_iter_edid_begin(drm_edid ? drm_edid->edid : NULL, &iter);
cea_db_iter_for_each(db, &iter) {
if (cea_db_tag(db) == CTA_DB_AUDIO) {
int j;
@@ -5015,6 +5005,24 @@ int drm_edid_to_sad(const struct edid *edid, struct 
cea_sad **sads)
  
  	return count;

  }
+
+/**
+ * drm_edid_to_sad - extracts SADs from EDID
+ * @edid: EDID to parse
+ * @sads: pointer that will be set to the extracted SADs
+ *
+ * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from 
it.
+ *
+ * Note: The returned pointer needs to be freed using kfree().
+ *
+ * Return: The number of found SADs or negative number on error.
+ */
+int drm_edid_to_sad(const struct edid *edid, struct cea_sad **sads)
+{
+   struct drm_edid drm_edid;
+
+   return _drm_edid_to_sad(drm_edid_legacy_init(&drm_edid, edid), sads);
+}
  EXPORT_SYMBOL(drm_edid_to_sad);
  
  /**


Re: [PATCH v2 16/25] drm/edid: convert drm_for_each_detailed_block() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Fix checkpatch warning on superfluous parens

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 36 ++--
  1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e3ff0f31a614..61551ce0db88 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2598,20 +2598,20 @@ vtb_for_each_detailed_block(const u8 *ext, detailed_cb 
*cb, void *closure)
cb((const struct detailed_timing *)(det_base + 18 * i), 
closure);
  }
  
-static void

-drm_for_each_detailed_block(const struct edid *edid, detailed_cb *cb, void 
*closure)
+static void drm_for_each_detailed_block(const struct drm_edid *drm_edid,
+   detailed_cb *cb, void *closure)
  {
struct drm_edid_iter edid_iter;
const u8 *ext;
int i;
  
-	if (edid == NULL)

+   if (!drm_edid)
return;
  
  	for (i = 0; i < EDID_DETAILED_TIMINGS; i++)

-   cb(&(edid->detailed_timings[i]), closure);
+   cb(&drm_edid->edid->detailed_timings[i], closure);
  
-	drm_edid_iter_begin(edid, &edid_iter);

+   drm_edid_iter_begin(drm_edid->edid, &edid_iter);
drm_edid_iter_for_each(ext, &edid_iter) {
switch (*ext) {
case CEA_EXT:
@@ -2650,7 +2650,7 @@ drm_monitor_supports_rb(const struct drm_edid *drm_edid)
if (drm_edid->edid->revision >= 4) {
bool ret = false;
  
-		drm_for_each_detailed_block(drm_edid->edid, is_rb, &ret);

+   drm_for_each_detailed_block(drm_edid, is_rb, &ret);
return ret;
}
  
@@ -2677,7 +2677,7 @@ drm_gtf2_hbreak(const struct drm_edid *drm_edid)

  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.hfreq_start_khz) != 12);
  
@@ -2689,7 +2689,7 @@ drm_gtf2_2c(const struct drm_edid *drm_edid)

  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.c) != 13);
  
@@ -2701,7 +2701,7 @@ drm_gtf2_m(const struct drm_edid *drm_edid)

  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.m) != 14);
  
@@ -2713,7 +2713,7 @@ drm_gtf2_k(const struct drm_edid *drm_edid)

  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.k) != 16);
  
@@ -2725,7 +2725,7 @@ drm_gtf2_2j(const struct drm_edid *drm_edid)

  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.j) != 17);
  
@@ -3265,7 +3265,7 @@ static int add_inferred_modes(struct drm_connector *connector,

};
  
  	if (version_greater(drm_edid->edid, 1, 0))

-   drm_for_each_detailed_block(drm_edid->edid, do_inferred_modes, 
&closure);
+   drm_for_each_detailed_block(drm_edid, do_inferred_modes, 
&closure);
  
  	return closure.modes;

  }
@@ -3342,7 +3342,7 @@ static int add_established_modes(struct drm_connector 
*connector,
}
  
  	if (version_greater(edid, 1, 0))

-   drm_for_each_detailed_block(drm_edid->edid, 
do_established_modes,
+   drm_for_each_detailed_block(drm_edid, do_established_modes,
&closure);
  
  	return modes + closure.modes;

@@ -3397,7 +3397,7 @@ static int add_standard_modes(struct drm_connector 
*connector,
}
  
  	if (version_greater(drm_edid->edid, 1, 0))

-   drm_for_each_detailed_block(drm_edid->edid, do_standard_modes,
+   drm_for_each_detailed_block(drm_edid, do_standard_modes,
&closure);
  
  	/* XXX should also look for standard codes in VTB blocks */

@@ -3477,7 +3477,7 @@ add_cvt_modes(struct drm_connector *connector, const 
struct drm_edid

Re: [PATCH v2 15/25] drm/edid: convert get_monitor_name() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Drop incorrect NULL name check (Dan Carpenter)

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 24 
  1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 364949e146a9..e3ff0f31a614 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4830,15 +4830,15 @@ monitor_name(const struct detailed_timing *timing, void 
*data)
*res = timing->data.other_data.data.str.str;
  }
  
-static int get_monitor_name(const struct edid *edid, char name[13])

+static int get_monitor_name(const struct drm_edid *drm_edid, char name[13])
  {
const char *edid_name = NULL;
int mnl;
  
-	if (!edid || !name)

+   if (!drm_edid || !name)
return 0;
  
-	drm_for_each_detailed_block(edid, monitor_name, &edid_name);

+   drm_for_each_detailed_block(drm_edid->edid, monitor_name, &edid_name);
for (mnl = 0; edid_name && mnl < 13; mnl++) {
if (edid_name[mnl] == 0x0a)
break;
@@ -4858,14 +4858,22 @@ static int get_monitor_name(const struct edid *edid, 
char name[13])
   */
  void drm_edid_get_monitor_name(const struct edid *edid, char *name, int 
bufsize)
  {
-   int name_length;
-   char buf[13];
+   int name_length = 0;
  
  	if (bufsize <= 0)

return;
  
-	name_length = min(get_monitor_name(edid, buf), bufsize - 1);

-   memcpy(name, buf, name_length);
+   if (edid) {
+   char buf[13];
+   struct drm_edid drm_edid = {
+   .edid = edid,
+   .size = edid_size(edid),
+   };
+
+   name_length = min(get_monitor_name(&drm_edid, buf), bufsize - 
1);
+   memcpy(name, buf, name_length);
+   }
+
name[name_length] = '\0';
  }
  EXPORT_SYMBOL(drm_edid_get_monitor_name);
@@ -4905,7 +4913,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector,
if (!drm_edid)
return;
  
-	mnl = get_monitor_name(drm_edid->edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);

+   mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);
DRM_DEBUG_KMS("ELD monitor %s\n", &eld[DRM_ELD_MONITOR_NAME_STRING]);
  
  	eld[DRM_ELD_CEA_EDID_VER_MNL] = info->cea_rev << DRM_ELD_CEA_EDID_VER_SHIFT;


Re: [Intel-gfx] [PATCH v2 14/25] drm/edid: convert mode_in_range() and drm_monitor_supports_rb() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 27 ++-
  1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index bea8f33c58ad..364949e146a9 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2645,16 +2645,16 @@ is_rb(const struct detailed_timing *descriptor, void 
*data)
  
  /* EDID 1.4 defines this explicitly.  For EDID 1.3, we guess, badly. */

  static bool
-drm_monitor_supports_rb(const struct edid *edid)
+drm_monitor_supports_rb(const struct drm_edid *drm_edid)
  {
-   if (edid->revision >= 4) {
+   if (drm_edid->edid->revision >= 4) {
bool ret = false;
  
-		drm_for_each_detailed_block(edid, is_rb, &ret);

+   drm_for_each_detailed_block(drm_edid->edid, is_rb, &ret);
return ret;
}
  
-	return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0);

+   return ((drm_edid->edid->input & DRM_EDID_INPUT_DIGITAL) != 0);
  }
  
  static void

@@ -2838,7 +2838,7 @@ static struct drm_display_mode *drm_mode_std(struct 
drm_connector *connector,
}
  
  	/* check whether it can be found in default mode table */

-   if (drm_monitor_supports_rb(drm_edid->edid)) {
+   if (drm_monitor_supports_rb(drm_edid)) {
mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate,
 true);
if (mode)
@@ -3077,10 +3077,11 @@ range_pixel_clock(const struct edid *edid, const u8 *t)
return t[9] * 1 + 5001;
  }
  
-static bool

-mode_in_range(const struct drm_display_mode *mode, const struct edid *edid,
- const struct detailed_timing *timing)
+static bool mode_in_range(const struct drm_display_mode *mode,
+ const struct drm_edid *drm_edid,
+ const struct detailed_timing *timing)
  {
+   const struct edid *edid = drm_edid->edid;
u32 max_clock;
const u8 *t = (const u8 *)timing;
  
@@ -3099,7 +3100,7 @@ mode_in_range(const struct drm_display_mode *mode, const struct edid *edid,

if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3
return false;
  
-	if (mode_is_rb(mode) && !drm_monitor_supports_rb(edid))

+   if (mode_is_rb(mode) && !drm_monitor_supports_rb(drm_edid))
return false;
  
  	return true;

@@ -3132,7 +3133,7 @@ static int drm_dmt_modes_for_range(struct drm_connector 
*connector,
struct drm_device *dev = connector->dev;
  
  	for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {

-   if (mode_in_range(drm_dmt_modes + i, drm_edid->edid, timing) &&
+   if (mode_in_range(drm_dmt_modes + i, drm_edid, timing) &&
valid_inferred_mode(connector, drm_dmt_modes + i)) {
newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
if (newmode) {
@@ -3174,7 +3175,7 @@ static int drm_gtf_modes_for_range(struct drm_connector 
*connector,
return modes;
  
  		drm_mode_fixup_1366x768(newmode);

-   if (!mode_in_range(newmode, drm_edid->edid, timing) ||
+   if (!mode_in_range(newmode, drm_edid, timing) ||
!valid_inferred_mode(connector, newmode)) {
drm_mode_destroy(dev, newmode);
continue;
@@ -3194,7 +3195,7 @@ static int drm_cvt_modes_for_range(struct drm_connector 
*connector,
int i, modes = 0;
struct drm_display_mode *newmode;
struct drm_device *dev = connector->dev;
-   bool rb = drm_monitor_supports_rb(drm_edid->edid);
+   bool rb = drm_monitor_supports_rb(drm_edid);
  
  	for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {

const struct minimode *m = &extra_modes[i];
@@ -3204,7 +3205,7 @@ static int drm_cvt_modes_for_range(struct drm_connector 
*connector,
return modes;
  
  		drm_mode_fixup_1366x768(newmode);

-   if (!mode_in_range(newmode, drm_edid->edid, timing) ||
+   if (!mode_in_range(newmode, drm_edid, timing) ||
!valid_inferred_mode(connector, newmode)) {
drm_mode_destroy(dev, newmode);
continue;


Re: [Intel-gfx] [PATCH v2 13/25] drm/edid: convert drm_mode_std() and children to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 52 --
  1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 51d918c66a26..bea8f33c58ad 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2673,11 +2673,11 @@ find_gtf2(const struct detailed_timing *descriptor, 
void *data)
  
  /* Secondary GTF curve kicks in above some break frequency */

  static int
-drm_gtf2_hbreak(const struct edid *edid)
+drm_gtf2_hbreak(const struct drm_edid *drm_edid)
  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.hfreq_start_khz) != 12);
  
@@ -2685,11 +2685,11 @@ drm_gtf2_hbreak(const struct edid *edid)

  }
  
  static int

-drm_gtf2_2c(const struct edid *edid)
+drm_gtf2_2c(const struct drm_edid *drm_edid)
  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.c) != 13);
  
@@ -2697,11 +2697,11 @@ drm_gtf2_2c(const struct edid *edid)

  }
  
  static int

-drm_gtf2_m(const struct edid *edid)
+drm_gtf2_m(const struct drm_edid *drm_edid)
  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.m) != 14);
  
@@ -2709,11 +2709,11 @@ drm_gtf2_m(const struct edid *edid)

  }
  
  static int

-drm_gtf2_k(const struct edid *edid)
+drm_gtf2_k(const struct drm_edid *drm_edid)
  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.k) != 16);
  
@@ -2721,11 +2721,11 @@ drm_gtf2_k(const struct edid *edid)

  }
  
  static int

-drm_gtf2_2j(const struct edid *edid)
+drm_gtf2_2j(const struct drm_edid *drm_edid)
  {
const struct detailed_timing *descriptor = NULL;
  
-	drm_for_each_detailed_block(edid, find_gtf2, &descriptor);

+   drm_for_each_detailed_block(drm_edid->edid, find_gtf2, &descriptor);
  
  	BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.gtf2.j) != 17);
  
@@ -2733,12 +2733,14 @@ drm_gtf2_2j(const struct edid *edid)

  }
  
  /* Get standard timing level (CVT/GTF/DMT). */

-static int standard_timing_level(const struct edid *edid)
+static int standard_timing_level(const struct drm_edid *drm_edid)
  {
+   const struct edid *edid = drm_edid->edid;
+
if (edid->revision >= 2) {
if (edid->revision >= 4 && (edid->features & 
DRM_EDID_FEATURE_DEFAULT_GTF))
return LEVEL_CVT;
-   if (drm_gtf2_hbreak(edid))
+   if (drm_gtf2_hbreak(drm_edid))
return LEVEL_GTF2;
if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
return LEVEL_GTF;
@@ -2770,9 +2772,9 @@ static int drm_mode_hsync(const struct drm_display_mode 
*mode)
   * Take the standard timing params (in this case width, aspect, and refresh)
   * and convert them into a real mode using CVT/GTF/DMT.
   */
-static struct drm_display_mode *
-drm_mode_std(struct drm_connector *connector, const struct edid *edid,
-const struct std_timing *t)
+static struct drm_display_mode *drm_mode_std(struct drm_connector *connector,
+const struct drm_edid *drm_edid,
+const struct std_timing *t)
  {
struct drm_device *dev = connector->dev;
struct drm_display_mode *m, *mode = NULL;
@@ -2782,7 +2784,7 @@ drm_mode_std(struct drm_connector *connector, const 
struct edid *edid,
>> EDID_TIMING_ASPECT_SHIFT;
unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
>> EDID_TIMING_VFREQ_SHIFT;
-   int timing_level = standard_timing_level(edid);
+   int timing_level = standard_timing_level(drm_edid);
  
  	if (bad_std_timing(t->hsize, t->vfreq_aspect))

return NULL;
@@ -2793,7 +2795,7 @@ drm_mode_std(struct drm_connector *connector, const 
struct edid *edid,
vrefresh_rate = vfreq + 60;
/* the vdisplay is calculated based on the

Re: [Intel-gfx] [PATCH v2 12/25] drm/edid: convert drm_cvt_modes_for_range() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 12 ++--
  1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 037102a4d0b5..51d918c66a26 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3185,14 +3185,14 @@ static int drm_gtf_modes_for_range(struct drm_connector 
*connector,
return modes;
  }
  
-static int

-drm_cvt_modes_for_range(struct drm_connector *connector, const struct edid 
*edid,
-   const struct detailed_timing *timing)
+static int drm_cvt_modes_for_range(struct drm_connector *connector,
+  const struct drm_edid *drm_edid,
+  const struct detailed_timing *timing)
  {
int i, modes = 0;
struct drm_display_mode *newmode;
struct drm_device *dev = connector->dev;
-   bool rb = drm_monitor_supports_rb(edid);
+   bool rb = drm_monitor_supports_rb(drm_edid->edid);
  
  	for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {

const struct minimode *m = &extra_modes[i];
@@ -3202,7 +3202,7 @@ drm_cvt_modes_for_range(struct drm_connector *connector, 
const struct edid *edid
return modes;
  
  		drm_mode_fixup_1366x768(newmode);

-   if (!mode_in_range(newmode, edid, timing) ||
+   if (!mode_in_range(newmode, drm_edid->edid, timing) ||
!valid_inferred_mode(connector, newmode)) {
drm_mode_destroy(dev, newmode);
continue;
@@ -3244,7 +3244,7 @@ do_inferred_modes(const struct detailed_timing *timing, 
void *c)
break;
  
  		closure->modes += drm_cvt_modes_for_range(closure->connector,

- 
closure->drm_edid->edid,
+ closure->drm_edid,
  timing);
break;
case 0x01: /* just the ranges, no formula */


Re: [PATCH v2 11/25] drm/edid: convert drm_gtf_modes_for_range() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5d8744a7b62e..037102a4d0b5 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3156,9 +3156,9 @@ void drm_mode_fixup_1366x768(struct drm_display_mode 
*mode)
}
  }
  
-static int

-drm_gtf_modes_for_range(struct drm_connector *connector, const struct edid 
*edid,
-   const struct detailed_timing *timing)
+static int drm_gtf_modes_for_range(struct drm_connector *connector,
+  const struct drm_edid *drm_edid,
+  const struct detailed_timing *timing)
  {
int i, modes = 0;
struct drm_display_mode *newmode;
@@ -3172,7 +3172,7 @@ drm_gtf_modes_for_range(struct drm_connector *connector, 
const struct edid *edid
return modes;
  
  		drm_mode_fixup_1366x768(newmode);

-   if (!mode_in_range(newmode, edid, timing) ||
+   if (!mode_in_range(newmode, drm_edid->edid, timing) ||
!valid_inferred_mode(connector, newmode)) {
drm_mode_destroy(dev, newmode);
continue;
@@ -3236,7 +3236,7 @@ do_inferred_modes(const struct detailed_timing *timing, 
void *c)
case 0x02: /* secondary gtf, XXX could do more */
case 0x00: /* default gtf */
closure->modes += drm_gtf_modes_for_range(closure->connector,
- 
closure->drm_edid->edid,
+ closure->drm_edid,
  timing);
break;
case 0x04: /* cvt, only in 1.4+ */


Re: [Intel-gfx] [PATCH v2 10/25] drm/edid: convert drm_dmt_modes_for_range() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 8acdb08a8571..5d8744a7b62e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3121,16 +3121,16 @@ static bool valid_inferred_mode(const struct 
drm_connector *connector,
return ok;
  }
  
-static int

-drm_dmt_modes_for_range(struct drm_connector *connector, const struct edid 
*edid,
-   const struct detailed_timing *timing)
+static int drm_dmt_modes_for_range(struct drm_connector *connector,
+  const struct drm_edid *drm_edid,
+  const struct detailed_timing *timing)
  {
int i, modes = 0;
struct drm_display_mode *newmode;
struct drm_device *dev = connector->dev;
  
  	for (i = 0; i < ARRAY_SIZE(drm_dmt_modes); i++) {

-   if (mode_in_range(drm_dmt_modes + i, edid, timing) &&
+   if (mode_in_range(drm_dmt_modes + i, drm_edid->edid, timing) &&
valid_inferred_mode(connector, drm_dmt_modes + i)) {
newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
if (newmode) {
@@ -3226,7 +3226,7 @@ do_inferred_modes(const struct detailed_timing *timing, 
void *c)
return;
  
  	closure->modes += drm_dmt_modes_for_range(closure->connector,

- closure->drm_edid->edid,
+ closure->drm_edid,
  timing);
  
  	if (!version_greater(closure->drm_edid->edid, 1, 1))


Re: [Intel-gfx] [PATCH v2 09/25] drm/edid: convert drm_mode_detailed() to drm_edid

2022-05-10 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index c2887012add0..8acdb08a8571 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2928,7 +2928,7 @@ drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
   * drm_display_mode.
   */
  static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
- const struct edid *edid,
+ const struct drm_edid 
*drm_edid,
  const struct detailed_timing 
*timing,
  u32 quirks)
  {
@@ -3016,8 +3016,8 @@ static struct drm_display_mode *drm_mode_detailed(struct 
drm_device *dev,
}
  
  	if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {

-   mode->width_mm = edid->width_cm * 10;
-   mode->height_mm = edid->height_cm * 10;
+   mode->width_mm = drm_edid->edid->width_cm * 10;
+   mode->height_mm = drm_edid->edid->height_cm * 10;
}
  
  	mode->type = DRM_MODE_TYPE_DRIVER;

@@ -3493,7 +3493,7 @@ do_detailed_mode(const struct detailed_timing *timing, 
void *c)
return;
  
  	newmode = drm_mode_detailed(closure->connector->dev,

-   closure->drm_edid->edid, timing,
+   closure->drm_edid, timing,
closure->quirks);
if (!newmode)
return;


Re: [PATCH v2 08/25] drm/edid: convert struct detailed_mode_closure to drm_edid

2022-05-10 Thread Nautiyal, Ankit K
LGTM, The subject perhaps can be modified to suggest drm_edid being 
added to detailed_mode_closure.


In any case:

Reviewed-by: Ankit Nautiyal 


On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 27 +--
  1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f54699422bca..c2887012add0 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -96,7 +96,7 @@ static int oui(u8 first, u8 second, u8 third)
  
  struct detailed_mode_closure {

struct drm_connector *connector;
-   const struct edid *edid;
+   const struct drm_edid *drm_edid;
bool preferred;
u32 quirks;
int modes;
@@ -3226,25 +3226,25 @@ do_inferred_modes(const struct detailed_timing *timing, 
void *c)
return;
  
  	closure->modes += drm_dmt_modes_for_range(closure->connector,

- closure->edid,
+ closure->drm_edid->edid,
  timing);
  
-	if (!version_greater(closure->edid, 1, 1))

+   if (!version_greater(closure->drm_edid->edid, 1, 1))
return; /* GTF not defined yet */
  
  	switch (range->flags) {

case 0x02: /* secondary gtf, XXX could do more */
case 0x00: /* default gtf */
closure->modes += drm_gtf_modes_for_range(closure->connector,
- closure->edid,
+ 
closure->drm_edid->edid,
  timing);
break;
case 0x04: /* cvt, only in 1.4+ */
-   if (!version_greater(closure->edid, 1, 3))
+   if (!version_greater(closure->drm_edid->edid, 1, 3))
break;
  
  		closure->modes += drm_cvt_modes_for_range(closure->connector,

- closure->edid,
+ 
closure->drm_edid->edid,
  timing);
break;
case 0x01: /* just the ranges, no formula */
@@ -3258,7 +3258,7 @@ static int add_inferred_modes(struct drm_connector 
*connector,
  {
struct detailed_mode_closure closure = {
.connector = connector,
-   .edid = drm_edid->edid,
+   .drm_edid = drm_edid,
};
  
  	if (version_greater(drm_edid->edid, 1, 0))

@@ -3323,7 +3323,7 @@ static int add_established_modes(struct drm_connector 
*connector,
int i, modes = 0;
struct detailed_mode_closure closure = {
.connector = connector,
-   .edid = edid,
+   .drm_edid = drm_edid,
};
  
  	for (i = 0; i <= EDID_EST_TIMINGS; i++) {

@@ -3351,7 +3351,6 @@ do_standard_modes(const struct detailed_timing *timing, 
void *c)
struct detailed_mode_closure *closure = c;
const struct detailed_non_pixel *data = &timing->data.other_data;
struct drm_connector *connector = closure->connector;
-   const struct edid *edid = closure->edid;
int i;
  
  	if (!is_display_descriptor(timing, EDID_DETAIL_STD_MODES))

@@ -3361,7 +3360,7 @@ do_standard_modes(const struct detailed_timing *timing, 
void *c)
const struct std_timing *std = &data->data.timings[i];
struct drm_display_mode *newmode;
  
-		newmode = drm_mode_std(connector, edid, std);

+   newmode = drm_mode_std(connector, closure->drm_edid->edid, std);
if (newmode) {
drm_mode_probed_add(connector, newmode);
closure->modes++;
@@ -3380,7 +3379,7 @@ static int add_standard_modes(struct drm_connector 
*connector,
int i, modes = 0;
struct detailed_mode_closure closure = {
.connector = connector,
-   .edid = drm_edid->edid,
+   .drm_edid = drm_edid,
};
  
  	for (i = 0; i < EDID_STD_TIMINGS; i++) {

@@ -3471,7 +3470,7 @@ add_cvt_modes(struct drm_connector *connector, const 
struct drm_edid *drm_edid)
  {
struct detailed_mode_closure closure = {
.connector = connector,
-   .edid = drm_edid->edid,
+   .drm_edid = drm_edid,
};
  
  	if (version_greater(drm_edid->edid, 1, 2))

@@ -3494,7 +3493,7 @@ do_detailed_mode(const struct detailed_timing *timing, 
void *c)
return;
  
  	newmode = drm_mode_detailed(closure->connector->dev,

-   closure->edid, timing,
+   closure->drm_edid->edid, timing,
closure->quirks);
if (!newmode)
  

Re: [Intel-gfx] [PATCH v2 07/25] drm/edid: convert drm_edid_connector_update() to drm_edid fully

2022-05-09 Thread Nautiyal, Ankit K



On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 95 ++
  1 file changed, 46 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e4fdf742645b..f54699422bca 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3253,16 +3253,16 @@ do_inferred_modes(const struct detailed_timing *timing, 
void *c)
}
  }
  
-static int

-add_inferred_modes(struct drm_connector *connector, const struct edid *edid)
+static int add_inferred_modes(struct drm_connector *connector,
+ const struct drm_edid *drm_edid)
  {
struct detailed_mode_closure closure = {
.connector = connector,
-   .edid = edid,
+   .edid = drm_edid->edid,
};
  
-	if (version_greater(edid, 1, 0))

-   drm_for_each_detailed_block(edid, do_inferred_modes, &closure);
+   if (version_greater(drm_edid->edid, 1, 0))
+   drm_for_each_detailed_block(drm_edid->edid, do_inferred_modes, 
&closure);
  
  	return closure.modes;

  }
@@ -3312,10 +3312,11 @@ do_established_modes(const struct detailed_timing 
*timing, void *c)
   * bitmap of the supported "established modes" list (defined above). Tease 
them
   * out and add them to the global modes list.
   */
-static int
-add_established_modes(struct drm_connector *connector, const struct edid *edid)
+static int add_established_modes(struct drm_connector *connector,
+const struct drm_edid *drm_edid)
  {
struct drm_device *dev = connector->dev;
+   const struct edid *edid = drm_edid->edid;
unsigned long est_bits = edid->established_timings.t1 |
(edid->established_timings.t2 << 8) |
((edid->established_timings.mfg_rsvd & 0x80) << 9);
@@ -3338,7 +3339,7 @@ add_established_modes(struct drm_connector *connector, 
const struct edid *edid)
}
  
  	if (version_greater(edid, 1, 0))

-   drm_for_each_detailed_block(edid, do_established_modes,
+   drm_for_each_detailed_block(drm_edid->edid, 
do_established_modes,
&closure);
  
  	return modes + closure.modes;

@@ -3373,28 +3374,28 @@ do_standard_modes(const struct detailed_timing *timing, 
void *c)
   * using the appropriate standard (DMT, GTF, or CVT). Grab them from EDID and
   * add them to the list.
   */
-static int
-add_standard_modes(struct drm_connector *connector, const struct edid *edid)
+static int add_standard_modes(struct drm_connector *connector,
+ const struct drm_edid *drm_edid)
  {
int i, modes = 0;
struct detailed_mode_closure closure = {
.connector = connector,
-   .edid = edid,
+   .edid = drm_edid->edid,
};
  
  	for (i = 0; i < EDID_STD_TIMINGS; i++) {

struct drm_display_mode *newmode;
  
-		newmode = drm_mode_std(connector, edid,

-  &edid->standard_timings[i]);
+   newmode = drm_mode_std(connector, drm_edid->edid,
+  &drm_edid->edid->standard_timings[i]);
if (newmode) {
drm_mode_probed_add(connector, newmode);
modes++;
}
}
  
-	if (version_greater(edid, 1, 0))

-   drm_for_each_detailed_block(edid, do_standard_modes,
+   if (version_greater(drm_edid->edid, 1, 0))
+   drm_for_each_detailed_block(drm_edid->edid, do_standard_modes,
&closure);
  
  	/* XXX should also look for standard codes in VTB blocks */

@@ -3466,15 +3467,15 @@ do_cvt_mode(const struct detailed_timing *timing, void 
*c)
  }
  
  static int

-add_cvt_modes(struct drm_connector *connector, const struct edid *edid)
+add_cvt_modes(struct drm_connector *connector, const struct drm_edid *drm_edid)
  {
struct detailed_mode_closure closure = {
.connector = connector,
-   .edid = edid,
+   .edid = drm_edid->edid,
};
  
-	if (version_greater(edid, 1, 2))

-   drm_for_each_detailed_block(edid, do_cvt_mode, &closure);
+   if (version_greater(drm_edid->edid, 1, 2))
+   drm_for_each_detailed_block(drm_edid->edid, do_cvt_mode, 
&closure);
  
  	/* XXX should also look for CVT codes in VTB blocks */
  
@@ -3519,22 +3520,21 @@ do_detailed_mode(const struct detailed_timing *timing, void *c)

   * @edid: EDID block to scan


This needs to be @drm_edid

With this changed:

Reviewed-by: Ankit Nautiyal 


Regards,

Ankit


   * @quirks: quirks to apply
   */
-static int
-add_detailed_modes(struct drm_connector *connector, const struct edid *edid,
-  u32 quirks)
+static int add_detail

Re: [PATCH v2 06/25] drm/edid: propagate drm_edid to drm_edid_to_eld()

2022-05-09 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 20 ++--
  1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 96e3f9327044..e4fdf742645b 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4883,13 +4883,13 @@ static void clear_eld(struct drm_connector *connector)
  /*
   * drm_edid_to_eld - build ELD from EDID
   * @connector: connector corresponding to the HDMI/DP sink
- * @edid: EDID to parse
+ * @drm_edid: EDID to parse
   *
   * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
   * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
   */
  static void drm_edid_to_eld(struct drm_connector *connector,
-   const struct edid *edid)
+   const struct drm_edid *drm_edid)
  {
const struct drm_display_info *info = &connector->display_info;
const struct cea_db *db;
@@ -4900,10 +4900,10 @@ static void drm_edid_to_eld(struct drm_connector 
*connector,
  
  	clear_eld(connector);
  
-	if (!edid)

+   if (!drm_edid)
return;
  
-	mnl = get_monitor_name(edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);

+   mnl = get_monitor_name(drm_edid->edid, 
&eld[DRM_ELD_MONITOR_NAME_STRING]);
DRM_DEBUG_KMS("ELD monitor %s\n", &eld[DRM_ELD_MONITOR_NAME_STRING]);
  
  	eld[DRM_ELD_CEA_EDID_VER_MNL] = info->cea_rev << DRM_ELD_CEA_EDID_VER_SHIFT;

@@ -4911,12 +4911,12 @@ static void drm_edid_to_eld(struct drm_connector 
*connector,
  
  	eld[DRM_ELD_VER] = DRM_ELD_VER_CEA861D;
  
-	eld[DRM_ELD_MANUFACTURER_NAME0] = edid->mfg_id[0];

-   eld[DRM_ELD_MANUFACTURER_NAME1] = edid->mfg_id[1];
-   eld[DRM_ELD_PRODUCT_CODE0] = edid->prod_code[0];
-   eld[DRM_ELD_PRODUCT_CODE1] = edid->prod_code[1];
+   eld[DRM_ELD_MANUFACTURER_NAME0] = drm_edid->edid->mfg_id[0];
+   eld[DRM_ELD_MANUFACTURER_NAME1] = drm_edid->edid->mfg_id[1];
+   eld[DRM_ELD_PRODUCT_CODE0] = drm_edid->edid->prod_code[0];
+   eld[DRM_ELD_PRODUCT_CODE1] = drm_edid->edid->prod_code[1];
  
-	cea_db_iter_edid_begin(edid, &iter);

+   cea_db_iter_edid_begin(drm_edid->edid, &iter);
cea_db_iter_for_each(db, &iter) {
const u8 *data = cea_db_data(db);
int len = cea_db_payload_len(db);
@@ -5864,7 +5864,7 @@ static int drm_edid_connector_update(struct drm_connector 
*connector,
quirks = update_display_info(connector, drm_edid);
  
  	/* Depends on info->cea_rev set by drm_add_display_info() above */

-   drm_edid_to_eld(connector, edid);
+   drm_edid_to_eld(connector, drm_edid);
  
  	/*

 * EDID spec says modes should be preferred in this order:


Re: [Intel-gfx] [PATCH v2 03/25] drm/edid: add struct drm_edid container

2022-05-09 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

Introduce new opaque type struct drm_edid to encapsulate the EDID data
and the size allocated for it. The contents will be private to
drm_edid.c.

There are a number of reasons for adding a container around struct edid:

* struct edid is a raw blob pointer to data that usually originates
   outside of the kernel. Its size is contained within the structure.

* There's no way to attach meta information (such as allocated memory
   size) to struct edid.

* Validation of the EDID blob and its size become crucial, and it's
   spread all over the subsystem, with varying levels of accuracy.

* HDMI Forum has introduced an HF-EEODB extension that defines an
   override EDID size within an EDID extension. The size allocated for an
   EDID depends on whether the allocator understands the HF-EEODB
   extension. Given a struct edid *, it's impossible to know how much
   memory was actually allocated for it.

There are also some reasons for making the container type struct
drm_edid opaque and private to drm_edid.c:

* Have only one place for creating and parsing the EDID, to avoid
   duplicating bugs.

* Prepare for reading a pure DisplayID 2.0 from its own DDC address, and
   adding it within the same struct drm_edid container, transparently,
   and for all drivers.

* With the idea that the drm_edid objects are immutable during their
   lifetimes, it will be possible to refcount them and reduce EDID
   copying everywhere (this is left for future work).

Initially, just add the type. In follow-up, we'll start converting the
guts of drm_edid.c to use it, and finally add interfaces around it.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dcef92c8887a..480fd9fbe412 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1567,6 +1567,15 @@ static const struct drm_display_mode edid_4k_modes[] = {
  
  /*** DDC fetch and block validation ***/
  
+/*

+ * The opaque EDID type, internal to drm_edid.c.
+ */
+struct drm_edid {
+   /* Size allocated for edid */
+   size_t size;
+   const struct edid *edid;
+};
+
  static int edid_extension_block_count(const struct edid *edid)
  {
return edid->extensions;


Re: [Intel-gfx] [PATCH v2 04/25] drm/edid: start propagating drm_edid to lower levels

2022-05-09 Thread Nautiyal, Ankit K

LGTM.

Reviewed-by: Ankit Nautiyal 

Regards,

Ankit

On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere. This is a clunky start, but
a start nonetheless. We'll eventually convert all of the EDID parsing to
struct drm_edid.

Initially, we'll just create the struct drm_edid in stack. This will be
the compat layer for legacy struct edid code. In the future, we'll have
EDID read return drm_edid objects.

v2: Add legacy init helper.

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 30 +++---
  1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 480fd9fbe412..f48f1f1a1fa7 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1608,6 +1608,24 @@ static const void *edid_extension_block_data(const 
struct edid *edid, int index)
return edid_block_data(edid, index + 1);
  }
  
+/*

+ * Initializer helper for legacy interfaces, where we have no choice but to
+ * trust edid size. Not for general purpose use.
+ */
+static const struct drm_edid *drm_edid_legacy_init(struct drm_edid *drm_edid,
+  const struct edid *edid)
+{
+   if (!edid)
+   return NULL;
+
+   memset(drm_edid, 0, sizeof(*drm_edid));
+
+   drm_edid->edid = edid;
+   drm_edid->size = edid_size(edid);
+
+   return drm_edid;
+}
+
  /*
   * EDID base and extension block iterator.
   *
@@ -5814,17 +5832,20 @@ static int add_displayid_detailed_modes(struct 
drm_connector *connector,
  }
  
  static int drm_edid_connector_update(struct drm_connector *connector,

-const struct edid *edid)
+const struct drm_edid *drm_edid)
  {
+   const struct edid *edid;
int num_modes = 0;
u32 quirks;
  
-	if (edid == NULL) {

+   if (!drm_edid) {
drm_reset_display_info(connector);
clear_eld(connector);
return 0;
}
  
+	edid = drm_edid->edid;

+
/*
 * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks.
 * To avoid multiple parsing of same block, lets parse that map
@@ -5890,13 +5911,16 @@ static int drm_edid_connector_update(struct 
drm_connector *connector,
   */
  int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
  {
+   struct drm_edid drm_edid;
+
if (edid && !drm_edid_is_valid(edid)) {
drm_warn(connector->dev, "%s: EDID invalid.\n",
 connector->name);
edid = NULL;
}
  
-	return drm_edid_connector_update(connector, edid);

+   return drm_edid_connector_update(connector,
+drm_edid_legacy_init(&drm_edid, edid));
  }
  EXPORT_SYMBOL(drm_add_edid_modes);
  


Re: [PATCH v2 05/25] drm/edid: keep propagating drm_edid to display info

2022-05-09 Thread Nautiyal, Ankit K



On 5/9/2022 5:33 PM, Jani Nikula wrote:

We'll need to propagate drm_edid everywhere.

v2: Use drm_edid_legacy_init()

Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/drm_edid.c | 48 +++---
  1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f48f1f1a1fa7..96e3f9327044 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2437,13 +2437,13 @@ EXPORT_SYMBOL(drm_edid_duplicate);
  
  /**

   * edid_get_quirks - return quirk flags for a given EDID
- * @edid: EDID to process
+ * @drm_edid: EDID to process
   *
   * This tells subsequent routines what fixes they need to apply.
   */
-static u32 edid_get_quirks(const struct edid *edid)
+static u32 edid_get_quirks(const struct drm_edid *drm_edid)
  {
-   u32 panel_id = edid_extract_panel_id(edid);
+   u32 panel_id = edid_extract_panel_id(drm_edid->edid);
const struct edid_quirk *quirk;
int i;
  
@@ -5466,7 +5466,7 @@ static void drm_parse_microsoft_vsdb(struct drm_connector *connector,

  }
  
  static void drm_parse_cea_ext(struct drm_connector *connector,

- const struct edid *edid)
+ const struct drm_edid *drm_edid)
  {
struct drm_display_info *info = &connector->display_info;
struct drm_edid_iter edid_iter;
@@ -5474,7 +5474,7 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
struct cea_db_iter iter;
const u8 *edid_ext;
  
-	drm_edid_iter_begin(edid, &edid_iter);

+   drm_edid_iter_begin(drm_edid->edid, &edid_iter);
drm_edid_iter_for_each(edid_ext, &edid_iter) {
if (edid_ext[0] != CEA_EXT)
continue;
@@ -5495,7 +5495,7 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
}
drm_edid_iter_end(&edid_iter);
  
-	cea_db_iter_edid_begin(edid, &iter);

+   cea_db_iter_edid_begin(drm_edid->edid, &iter);
cea_db_iter_for_each(db, &iter) {
/* FIXME: convert parsers to use struct cea_db */
const u8 *data = (const u8 *)db;
@@ -5541,16 +5541,15 @@ void get_monitor_range(const struct detailed_timing 
*timing,
monitor_range->max_vfreq = range->max_vfreq;
  }
  
-static

-void drm_get_monitor_range(struct drm_connector *connector,
-  const struct edid *edid)
+static void drm_get_monitor_range(struct drm_connector *connector,
+ const struct drm_edid *drm_edid)
  {
struct drm_display_info *info = &connector->display_info;
  
-	if (!version_greater(edid, 1, 1))

+   if (!version_greater(drm_edid->edid, 1, 1))
return;
  
-	drm_for_each_detailed_block(edid, get_monitor_range,

+   drm_for_each_detailed_block(drm_edid->edid, get_monitor_range,
&info->monitor_range);
  
  	DRM_DEBUG_KMS("Supported Monitor Refresh rate range is %d Hz - %d Hz\n",

@@ -5610,12 +5609,13 @@ static void drm_parse_vesa_mso_data(struct 
drm_connector *connector,
info->mso_stream_count, info->mso_pixel_overlap);
  }
  
-static void drm_update_mso(struct drm_connector *connector, const struct edid *edid)

+static void drm_update_mso(struct drm_connector *connector,
+  const struct drm_edid *drm_edid)
  {
const struct displayid_block *block;
struct displayid_iter iter;
  
-	displayid_iter_edid_begin(edid, &iter);

+   displayid_iter_edid_begin(drm_edid->edid, &iter);
displayid_iter_for_each(block, &iter) {
if (block->tag == DATA_BLOCK_2_VENDOR_SPECIFIC)
drm_parse_vesa_mso_data(connector, block);
@@ -5654,18 +5654,20 @@ drm_reset_display_info(struct drm_connector *connector)
info->mso_pixel_overlap = 0;
  }
  
-u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)

+static u32 update_display_info(struct drm_connector *connector,
+  const struct drm_edid *drm_edid)
  {
struct drm_display_info *info = &connector->display_info;
+   const struct edid *edid = drm_edid->edid;
  
-	u32 quirks = edid_get_quirks(edid);

+   u32 quirks = edid_get_quirks(drm_edid);
  
  	drm_reset_display_info(connector);
  
  	info->width_mm = edid->width_cm * 10;

info->height_mm = edid->height_cm * 10;
  
-	drm_get_monitor_range(connector, edid);

+   drm_get_monitor_range(connector, drm_edid);
  
  	if (edid->revision < 3)

goto out;
@@ -5674,7 +5676,7 @@ u32 drm_add_display_info(struct drm_connector *connector, 
const struct edid *edi
goto out;
  
  	info->color_formats |= DRM_COLOR_FORMAT_RGB444;

-   drm_parse_cea_ext(connector, edid);
+   drm_parse_cea_ext(connector, drm_edid);
  
  	/*

 * Digital sink with "DFP 1.x compliant TMDS" according to EDID 1.3?
@@ -5727,7 +5729,7

  1   2   3   >