[PATCH 11/11] drm/i915/dp_mst: Add support for forcing dsc fractional bpp via debugfs

2023-11-10 Thread Ankit Nautiyal
If force_dsc_fractional_bpp_en is set through debugfs allow DSC iff
compressed bpp is fractional. Continue if the computed compressed bpp
turns out to be a integer.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 322046bb7d42..26b51ba6871d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -172,6 +172,10 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct 
intel_encoder *encoder,
struct intel_link_m_n remote_m_n;
int link_bpp_x16;
 
+   if (dsc && intel_dp->force_dsc_fractional_bpp_en &&
+   !to_bpp_frac(bpp_x16))
+   continue;
+
drm_dbg_kms(>drm, "Trying bpp " BPP_X16_FMT "\n", 
BPP_X16_ARGS(bpp_x16));
 
ret = intel_dp_mst_check_constraints(i915, bpp_x16, 
adjusted_mode, crtc_state, dsc);
@@ -225,12 +229,16 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct 
intel_encoder *encoder,
drm_dbg_kms(>drm, "failed finding vcpi slots:%d\n",
slots);
} else {
-   if (!dsc)
-   crtc_state->pipe_bpp = to_bpp_int(bpp_x16);
-   else
+   if (dsc) {
crtc_state->dsc.compressed_bpp_x16 = bpp_x16;
+   if (intel_dp->force_dsc_fractional_bpp_en && 
to_bpp_frac(bpp_x16))
+   drm_dbg_kms(>drm, "Forcing DSC fractional 
bpp\n");
+   } else {
+   crtc_state->pipe_bpp = to_bpp_int(bpp_x16);
+   }
drm_dbg_kms(>drm, "Got %d slots for pipe bpp " 
BPP_X16_FMT " dsc %d\n",
slots, BPP_X16_ARGS(bpp_x16), dsc);
+
}
 
return slots;
-- 
2.40.1



[PATCH 08/11] drm/i915/dsc: Allow DSC only with fractional bpp when forced from debugfs

2023-11-10 Thread Ankit Nautiyal
From: Swati Sharma 

If force_dsc_fractional_bpp_en is set through debugfs allow DSC iff
compressed bpp is fractional. Continue if the computed compressed bpp
turns out to be a integer.

v2:
-Use helpers for fractional, integral bits of bits_per_pixel. (Suraj)
-Fix comment (Suraj)

Signed-off-by: Swati Sharma 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index e53c87825194..607d03382db8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1928,6 +1928,9 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
for (compressed_bppx16 = dsc_max_bpp;
 compressed_bppx16 >= dsc_min_bpp;
 compressed_bppx16 -= bppx16_step) {
+   if (intel_dp->force_dsc_fractional_bpp_en &&
+   !to_bpp_frac(compressed_bppx16))
+   continue;
ret = dsc_compute_link_config(intel_dp,
  pipe_config,
  limits,
@@ -1935,6 +1938,10 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
  timeslots);
if (ret == 0) {
pipe_config->dsc.compressed_bpp_x16 = compressed_bppx16;
+   if (intel_dp->force_dsc_fractional_bpp_en &&
+   to_bpp_frac(compressed_bppx16))
+   drm_dbg_kms(>drm, "Forcing DSC fractional 
bpp\n");
+
return 0;
}
}
-- 
2.40.1



[PATCH 10/11] drm/i916/dp_mst: Iterate over the DSC bpps as per DSC precision support

2023-11-10 Thread Ankit Nautiyal
Currently we iterate over the bpp_x16 in step of 16.
Use DSC fractional bpp precision supported by the sink to compute
the appropriate steps to iterate over the bpps.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index e7806fe11b9d..322046bb7d42 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -273,6 +273,8 @@ static int intel_dp_dsc_mst_compute_link_config(struct 
intel_encoder *encoder,
int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp;
u8 dsc_max_bpc;
int min_compressed_bpp, max_compressed_bpp;
+   int bppx16_incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
+   int bppx16_step;
 
/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */
if (DISPLAY_VER(i915) >= 12)
@@ -327,11 +329,16 @@ static int intel_dp_dsc_mst_compute_link_config(struct 
intel_encoder *encoder,
min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(i915, 
min_compressed_bpp,

crtc_state->pipe_bpp);
 
+   if (DISPLAY_VER(i915) < 14 || bppx16_incr <= 1)
+   bppx16_step = 16;
+   else
+   bppx16_step = 16 / bppx16_incr;
+
slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state,
 
to_bpp_x16(max_compressed_bpp),
 
to_bpp_x16(min_compressed_bpp),
 limits,
-conn_state, 16, true);
+conn_state, bppx16_step, 
true);
 
if (slots < 0)
return slots;
-- 
2.40.1



[PATCH 09/11] drm/i915/dp_mst: Use precision of 1/16 for computing bpp

2023-11-10 Thread Ankit Nautiyal
Modify the functions to deal with bpps with 1/16 precision.
This will make way for cases when DSC with fractional bpp is used.
For bpp without DSC, there is no change, as we still use whole numbers.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 5c7e9d296483..e7806fe11b9d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -47,20 +47,21 @@
 #include "intel_vdsc.h"
 #include "skl_scaler.h"
 
-static int intel_dp_mst_check_constraints(struct drm_i915_private *i915, int 
bpp,
+static int intel_dp_mst_check_constraints(struct drm_i915_private *i915, int 
bpp_x16,
  const struct drm_display_mode 
*adjusted_mode,
  struct intel_crtc_state *crtc_state,
  bool dsc)
 {
if (intel_dp_is_uhbr(crtc_state) && DISPLAY_VER(i915) <= 13 && dsc) {
-   int output_bpp = bpp;
+   int output_bpp_x16 = bpp_x16;
/* DisplayPort 2 128b/132b, bits per lane is always 32 */
int symbol_clock = crtc_state->port_clock / 32;
 
-   if (output_bpp * adjusted_mode->crtc_clock >=
+   if (DIV_ROUND_UP(output_bpp_x16 * adjusted_mode->crtc_clock, 
16) >=
symbol_clock * 72) {
drm_dbg_kms(>drm, "UHBR check failed(required bw 
%d available %d)\n",
-   output_bpp * adjusted_mode->crtc_clock, 
symbol_clock * 72);
+   DIV_ROUND_UP(output_bpp_x16 * 
adjusted_mode->crtc_clock, 16),
+   symbol_clock * 72);
return -EINVAL;
}
}
@@ -127,8 +128,8 @@ static void intel_dp_mst_compute_m_n(const struct 
intel_crtc_state *crtc_state,
 
 static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
struct intel_crtc_state 
*crtc_state,
-   int max_bpp,
-   int min_bpp,
+   int max_bpp_x16,
+   int min_bpp_x16,
struct link_config_limits 
*limits,
struct drm_connector_state 
*conn_state,
int step,
@@ -143,7 +144,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct 
intel_encoder *encoder,
struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct drm_display_mode *adjusted_mode =
_state->hw.adjusted_mode;
-   int bpp, slots = -EINVAL;
+   int bpp_x16, slots = -EINVAL;
int ret = 0;
 
mst_state = drm_atomic_get_mst_topology_state(state, 
_dp->mst_mgr);
@@ -164,25 +165,25 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct 
intel_encoder *encoder,
  crtc_state->port_clock,
  crtc_state->lane_count);
 
-   drm_dbg_kms(>drm, "Looking for slots in range min bpp %d max bpp 
%d\n",
-   min_bpp, max_bpp);
+   drm_dbg_kms(>drm, "Looking for slots in range min bpp " 
BPP_X16_FMT " max bpp " BPP_X16_FMT "\n",
+   BPP_X16_ARGS(min_bpp_x16), BPP_X16_ARGS(max_bpp_x16));
 
-   for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
+   for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= step) {
struct intel_link_m_n remote_m_n;
-   int link_bpp;
+   int link_bpp_x16;
 
-   drm_dbg_kms(>drm, "Trying bpp %d\n", bpp);
+   drm_dbg_kms(>drm, "Trying bpp " BPP_X16_FMT "\n", 
BPP_X16_ARGS(bpp_x16));
 
-   ret = intel_dp_mst_check_constraints(i915, bpp, adjusted_mode, 
crtc_state, dsc);
+   ret = intel_dp_mst_check_constraints(i915, bpp_x16, 
adjusted_mode, crtc_state, dsc);
if (ret)
continue;
 
-   link_bpp = dsc ? bpp :
-   intel_dp_output_bpp(crtc_state->output_format, bpp);
+   link_bpp_x16 = dsc ? bpp_x16 :
+   intel_dp_output_bpp(crtc_state->output_format, 
to_bpp_int(bpp_x16));
 
-   intel_dp_mst_compute_m_n(crtc_state, connector, false, dsc, 
to_bpp_x16(link_bpp),
+   intel_dp_mst_compute_m_n(crtc_state, 

[PATCH 06/11] drm/i915/dp: Iterate over output bpp with fractional step size

2023-11-10 Thread Ankit Nautiyal
This patch adds support to iterate over compressed output bpp as per the
fractional step, supported by DP sink.

v2:
-Avoid ending up with compressed bpp, same as pipe bpp. (Stan)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 41 +++--
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 246f50d1f030..e53c87825194 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1737,15 +1737,15 @@ static bool intel_dp_dsc_supports_format(const struct 
intel_connector *connector
return drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd, 
sink_dsc_format);
 }
 
-static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 
link_clock,
u32 lane_count, u32 mode_clock,
enum intel_output_format 
output_format,
int timeslots)
 {
u32 available_bw, required_bw;
 
-   available_bw = (link_clock * lane_count * timeslots)  / 8;
-   required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
+   available_bw = (link_clock * lane_count * timeslots * 16)  / 8;
+   required_bw = compressed_bppx16 * 
(intel_dp_mode_to_fec_clock(mode_clock));
 
return available_bw > required_bw;
 }
@@ -1753,7 +1753,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 
compressed_bpp, u32 link_clock,
 static int dsc_compute_link_config(struct intel_dp *intel_dp,
   struct intel_crtc_state *pipe_config,
   struct link_config_limits *limits,
-  u16 compressed_bpp,
+  u16 compressed_bppx16,
   int timeslots)
 {
const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
@@ -1768,8 +1768,8 @@ static int dsc_compute_link_config(struct intel_dp 
*intel_dp,
for (lane_count = limits->min_lane_count;
 lane_count <= limits->max_lane_count;
 lane_count <<= 1) {
-   if (!is_bw_sufficient_for_dsc_config(compressed_bpp, 
link_rate, lane_count,
-
adjusted_mode->clock,
+   if (!is_bw_sufficient_for_dsc_config(compressed_bppx16, 
link_rate,
+lane_count, 
adjusted_mode->clock,
 
pipe_config->output_format,
 timeslots))
continue;
@@ -1882,7 +1882,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
ret = dsc_compute_link_config(intel_dp,
  pipe_config,
  limits,
- valid_dsc_bpp[i],
+ valid_dsc_bpp[i] << 4,
  timeslots);
if (ret == 0) {
pipe_config->dsc.compressed_bpp_x16 =
@@ -1902,6 +1902,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
  */
 static int
 xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
+ const struct intel_connector *connector,
  struct intel_crtc_state *pipe_config,
  struct link_config_limits *limits,
  int dsc_max_bpp,
@@ -1909,23 +1910,31 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
  int pipe_bpp,
  int timeslots)
 {
-   u16 compressed_bpp;
+   u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   u16 compressed_bppx16;
+   u8 bppx16_step;
int ret;
 
+   if (DISPLAY_VER(i915) < 14 || bppx16_incr <= 1)
+   bppx16_step = 16;
+   else
+   bppx16_step = 16 / bppx16_incr;
+
/* Compressed BPP should be less than the Input DSC bpp */
-   dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
+   dsc_max_bpp = min(dsc_max_bpp << 4, (pipe_bpp << 4) - bppx16_step);
+   dsc_min_bpp = dsc_min_bpp << 4;
 
-   for (compressed_bpp = dsc_max_bpp;
-compressed_bpp >= dsc_min_bpp;
-compressed_bpp--) {
+   for (compressed_bppx16 = dsc_max_bpp;
+compres

[PATCH 07/11] drm/i915/dsc: Add debugfs entry to validate DSC fractional bpp

2023-11-10 Thread Ankit Nautiyal
From: Swati Sharma 

DSC_Sink_BPP_Precision entry is added to i915_dsc_fec_support_show
to depict sink's precision.
Also, new debugfs entry is created to enforce fractional bpp.
If Force_DSC_Fractional_BPP_en is set then while iterating over
output bpp with fractional step size we will continue if output_bpp is
computed as integer. With this approach, we will be able to validate
DSC with fractional bpp.

v2:
Add drm_modeset_unlock to new line(Suraj)

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
Signed-off-by: Mitul Golani 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
---
 .../drm/i915/display/intel_display_debugfs.c  | 84 +++
 .../drm/i915/display/intel_display_types.h|  1 +
 2 files changed, 85 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index f3700c18d685..915420d0cef8 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -1256,6 +1256,8 @@ static int i915_dsc_fec_support_show(struct seq_file *m, 
void *data)
  
DP_DSC_YCbCr420_Native)),
   
str_yes_no(drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd,
  
DP_DSC_YCbCr444)));
+   seq_printf(m, "DSC_Sink_BPP_Precision: %d\n",
+  drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd));
seq_printf(m, "Force_DSC_Enable: %s\n",
   str_yes_no(intel_dp->force_dsc_en));
if (!intel_dp_is_edp(intel_dp))
@@ -1448,6 +1450,85 @@ static const struct file_operations 
i915_dsc_output_format_fops = {
.write = i915_dsc_output_format_write
 };
 
+static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data)
+{
+   struct drm_connector *connector = m->private;
+   struct drm_device *dev = connector->dev;
+   struct drm_crtc *crtc;
+   struct intel_dp *intel_dp;
+   struct intel_connector *intel_connector = to_intel_connector(connector);
+   struct intel_encoder *encoder = intel_attached_encoder(intel_connector);
+   int ret;
+
+   if (!encoder)
+   return -ENODEV;
+
+   ret = 
drm_modeset_lock_single_interruptible(>mode_config.connection_mutex);
+   if (ret)
+   return ret;
+
+   crtc = connector->state->crtc;
+   if (connector->status != connector_status_connected || !crtc) {
+   ret = -ENODEV;
+   goto out;
+   }
+
+   intel_dp = intel_attached_dp(intel_connector);
+   seq_printf(m, "Force_DSC_Fractional_BPP_Enable: %s\n",
+  str_yes_no(intel_dp->force_dsc_fractional_bpp_en));
+
+out:
+   drm_modeset_unlock(>mode_config.connection_mutex);
+
+   return ret;
+}
+
+static ssize_t i915_dsc_fractional_bpp_write(struct file *file,
+const char __user *ubuf,
+size_t len, loff_t *offp)
+{
+   struct drm_connector *connector =
+   ((struct seq_file *)file->private_data)->private;
+   struct intel_encoder *encoder = 
intel_attached_encoder(to_intel_connector(connector));
+   struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+   bool dsc_fractional_bpp_enable = false;
+   int ret;
+
+   if (len == 0)
+   return 0;
+
+   drm_dbg(>drm,
+   "Copied %zu bytes from user to force fractional bpp for DSC\n", 
len);
+
+   ret = kstrtobool_from_user(ubuf, len, _fractional_bpp_enable);
+   if (ret < 0)
+   return ret;
+
+   drm_dbg(>drm, "Got %s for DSC Fractional BPP Enable\n",
+   (dsc_fractional_bpp_enable) ? "true" : "false");
+   intel_dp->force_dsc_fractional_bpp_en = dsc_fractional_bpp_enable;
+
+   *offp += len;
+
+   return len;
+}
+
+static int i915_dsc_fractional_bpp_open(struct inode *inode,
+   struct file *file)
+{
+   return single_open(file, i915_dsc_fractional_bpp_show, 
inode->i_private);
+}
+
+static const struct file_operations i915_dsc_fractional_bpp_fops = {
+   .owner = THIS_MODULE,
+   .open = i915_dsc_fractional_bpp_open,
+   .read = seq_read,
+   .llseek = seq_lseek,
+   .release = single_release,
+   .write = i915_dsc_fractional_bpp_write
+};
+
 /*
  * Returns the Current CRTC's bpc.
  * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc
@@ -1525,6 +1606,9 @@ void intel_connector_debugfs_add(struct intel_connector 
*intel_connector)
 
debugfs_create_file("i915_dsc_output

[PATCH 05/11] drm/i915/dsc/mtl: Add support for fractional bpp

2023-11-10 Thread Ankit Nautiyal
From: Vandita Kulkarni 

Consider the fractional bpp while reading the qp values.

v2: Use helpers for fractional, integral bits of bits_per_pixel. (Suraj)

Signed-off-by: Vandita Kulkarni 
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
---
 .../gpu/drm/i915/display/intel_qp_tables.c|  3 ---
 drivers/gpu/drm/i915/display/intel_vdsc.c | 25 +++
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_qp_tables.c 
b/drivers/gpu/drm/i915/display/intel_qp_tables.c
index 543cdc46aa1d..600c815e37e4 100644
--- a/drivers/gpu/drm/i915/display/intel_qp_tables.c
+++ b/drivers/gpu/drm/i915/display/intel_qp_tables.c
@@ -34,9 +34,6 @@
  * These qp tables are as per the C model
  * and it has the rows pointing to bpps which increment
  * in steps of 0.5
- * We do not support fractional bpps as of today,
- * hence we would skip the fractional bpps during
- * our references for qp calclulations.
  */
 static const u8 
rc_range_minqp444_8bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_8BPC_MAX_NUM_BPP] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c 
b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 3a1ed574edbb..5f2fb702e367 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -77,8 +77,8 @@ intel_vdsc_set_min_max_qp(struct drm_dsc_config *vdsc_cfg, 
int buf,
 static void
 calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
 {
+   int bpp = to_bpp_int(vdsc_cfg->bits_per_pixel);
int bpc = vdsc_cfg->bits_per_component;
-   int bpp = vdsc_cfg->bits_per_pixel >> 4;
int qp_bpc_modifier = (bpc - 8) * 2;
int uncompressed_bpg_rate;
int first_line_bpg_offset;
@@ -148,7 +148,13 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
static const s8 ofs_und8[] = {
10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, 
-12
};
-
+   /*
+* For 420 format since bits_per_pixel (bpp) is set to target 
bpp * 2,
+* QP table values for target bpp 4.0 to 4.4375 (rounded to 
4.0) are
+* actually for bpp 8 to 8.875 (rounded to 4.0 * 2 i.e 8).
+* Similarly values for target bpp 4.5 to 4.8375 (rounded to 
4.5)
+* are for bpp 9 to 9.875 (rounded to 4.5 * 2 i.e 9), and so on.
+*/
bpp_i  = bpp - 8;
for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
u8 range_bpg_offset;
@@ -178,6 +184,9 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK;
}
} else {
+   /* fractional bpp part * 1 (for precision up to 4 decimal 
places) */
+   int fractional_bits = to_bpp_frac(vdsc_cfg->bits_per_pixel);
+
static const s8 ofs_und6[] = {
0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, 
-12, -12
};
@@ -191,7 +200,14 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, 
-12
};
 
-   bpp_i  = (2 * (bpp - 6));
+   /*
+* QP table rows have values in increment of 0.5.
+* So 6.0 bpp to 6.4375 will have index 0, 6.5 to 6.9375 will 
have index 1,
+* and so on.
+* 0.5 fractional part with 4 decimal precision becomes 5000
+*/
+   bpp_i  = ((bpp - 6) + (fractional_bits < 5000 ? 0 : 1));
+
for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
u8 range_bpg_offset;
 
@@ -279,8 +295,7 @@ int intel_dsc_compute_params(struct intel_crtc_state 
*pipe_config)
/* Gen 11 does not support VBR */
vdsc_cfg->vbr_enable = false;
 
-   /* Gen 11 only supports integral values of bpp */
-   vdsc_cfg->bits_per_pixel = compressed_bpp << 4;
+   vdsc_cfg->bits_per_pixel = pipe_config->dsc.compressed_bpp_x16;
 
/*
 * According to DSC 1.2 specs in Section 4.1 if native_420 is set
-- 
2.40.1



[PATCH 04/11] drm/i915/audio: Consider fractional vdsc bpp while computing tu_data

2023-11-10 Thread Ankit Nautiyal
MTL+ supports fractional compressed bits_per_pixel, with precision of
1/16. This compressed bpp is stored in U6.4 format.
Accommodate the precision during calculation of transfer unit data
for hblank_early calculation.

v2:
-Fix tu_data calculation while dealing with U6.4 format. (Stan)

v3:
-Use BPP_X16_FMT to print vdsc bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
---
 drivers/gpu/drm/i915/display/intel_audio.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_audio.c 
b/drivers/gpu/drm/i915/display/intel_audio.c
index aa93ccd6c2aa..8796d90c46a6 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -521,25 +521,25 @@ static unsigned int calc_hblank_early_prog(struct 
intel_encoder *encoder,
unsigned int link_clks_available, link_clks_required;
unsigned int tu_data, tu_line, link_clks_active;
unsigned int h_active, h_total, hblank_delta, pixel_clk;
-   unsigned int fec_coeff, cdclk, vdsc_bpp;
+   unsigned int fec_coeff, cdclk, vdsc_bppx16;
unsigned int link_clk, lanes;
unsigned int hblank_rise;
 
h_active = crtc_state->hw.adjusted_mode.crtc_hdisplay;
h_total = crtc_state->hw.adjusted_mode.crtc_htotal;
pixel_clk = crtc_state->hw.adjusted_mode.crtc_clock;
-   vdsc_bpp = to_bpp_int(crtc_state->dsc.compressed_bpp_x16);
+   vdsc_bppx16 = crtc_state->dsc.compressed_bpp_x16;
cdclk = i915->display.cdclk.hw.cdclk;
/* fec= 0.972261, using rounding multiplier of 100 */
fec_coeff = 972261;
link_clk = crtc_state->port_clock;
lanes = crtc_state->lane_count;
 
-   drm_dbg_kms(>drm, "h_active = %u link_clk = %u :"
-   "lanes = %u vdsc_bpp = %u cdclk = %u\n",
-   h_active, link_clk, lanes, vdsc_bpp, cdclk);
+   drm_dbg_kms(>drm,
+   "h_active = %u link_clk = %u : lanes = %u vdsc_bpp = " 
BPP_X16_FMT " cdclk = %u\n",
+   h_active, link_clk, lanes, BPP_X16_ARGS(vdsc_bppx16), 
cdclk);
 
-   if (WARN_ON(!link_clk || !pixel_clk || !lanes || !vdsc_bpp || !cdclk))
+   if (WARN_ON(!link_clk || !pixel_clk || !lanes || !vdsc_bppx16 || 
!cdclk))
return 0;
 
link_clks_available = (h_total - h_active) * link_clk / pixel_clk - 28;
@@ -551,8 +551,8 @@ static unsigned int calc_hblank_early_prog(struct 
intel_encoder *encoder,
hblank_delta = DIV64_U64_ROUND_UP(mul_u32_u32(5 * (link_clk + 
cdclk), pixel_clk),
  mul_u32_u32(link_clk, cdclk));
 
-   tu_data = div64_u64(mul_u32_u32(pixel_clk * vdsc_bpp * 8, 100),
-   mul_u32_u32(link_clk * lanes, fec_coeff));
+   tu_data = div64_u64(mul_u32_u32(pixel_clk * vdsc_bppx16 * 8, 100),
+   mul_u32_u32(link_clk * lanes * 16, fec_coeff));
tu_line = div64_u64(h_active * mul_u32_u32(link_clk, fec_coeff),
mul_u32_u32(64 * pixel_clk, 100));
link_clks_active  = (tu_line - 1) * 64 + tu_data;
-- 
2.40.1



[PATCH 02/11] drm/i915/display: Store compressed bpp in U6.4 format

2023-11-10 Thread Ankit Nautiyal
DSC parameter bits_per_pixel is stored in U6.4 format.
The 4 bits represent the fractional part of the bpp.
Currently we use compressed_bpp member of dsc structure to store
only the integral part of the bits_per_pixel.
To store the full bits_per_pixel along with the fractional part,
compressed_bpp is changed to store bpp in U6.4 formats. Intergral
part is retrieved by simply right shifting the member compressed_bpp by 4.

v2:
-Use to_bpp_int, to_bpp_frac_dec, to_bpp_x16 helpers while dealing
 with compressed bpp. (Suraj)
-Fix comment styling. (Suraj)

v3:
-Add separate file for 6.4 fixed point helper(Jani, Nikula)
-Add comment for magic values(Suraj)

v4:
-Fix checkpatch warnings caused by renaming(Suraj)

v5:
-Rebase.
-Use existing helpers for conversion of bpp_int to bpp_x16
 and vice versa.

Signed-off-by: Ankit Nautiyal 
Signed-off-by: Mitul Golani 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
---
 drivers/gpu/drm/i915/display/icl_dsi.c| 10 +++
 drivers/gpu/drm/i915/display/intel_audio.c|  2 +-
 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  |  2 +-
 .../drm/i915/display/intel_display_types.h|  3 ++-
 drivers/gpu/drm/i915/display/intel_dp.c   | 27 ++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  2 +-
 drivers/gpu/drm/i915/display/intel_link_bw.c  |  2 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c |  4 +--
 10 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
b/drivers/gpu/drm/i915/display/icl_dsi.c
index c4585e445198..481fcb650850 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -330,7 +330,7 @@ static int afe_clk(struct intel_encoder *encoder,
int bpp;
 
if (crtc_state->dsc.compression_enable)
-   bpp = crtc_state->dsc.compressed_bpp;
+   bpp = to_bpp_int(crtc_state->dsc.compressed_bpp_x16);
else
bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
 
@@ -860,7 +860,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder 
*encoder,
 * compressed and non-compressed bpp.
 */
if (crtc_state->dsc.compression_enable) {
-   mul = crtc_state->dsc.compressed_bpp;
+   mul = to_bpp_int(crtc_state->dsc.compressed_bpp_x16);
div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
}
 
@@ -884,7 +884,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder 
*encoder,
int bpp, line_time_us, byte_clk_period_ns;
 
if (crtc_state->dsc.compression_enable)
-   bpp = crtc_state->dsc.compressed_bpp;
+   bpp = to_bpp_int(crtc_state->dsc.compressed_bpp_x16);
else
bpp = 
mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
 
@@ -1451,8 +1451,8 @@ static void gen11_dsi_get_timings(struct intel_encoder 
*encoder,
struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
 
-   if (pipe_config->dsc.compressed_bpp) {
-   int div = pipe_config->dsc.compressed_bpp;
+   if (pipe_config->dsc.compressed_bpp_x16) {
+   int div = to_bpp_int(pipe_config->dsc.compressed_bpp_x16);
int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
 
adjusted_mode->crtc_htotal =
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c 
b/drivers/gpu/drm/i915/display/intel_audio.c
index 19605264a35c..aa93ccd6c2aa 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -528,7 +528,7 @@ static unsigned int calc_hblank_early_prog(struct 
intel_encoder *encoder,
h_active = crtc_state->hw.adjusted_mode.crtc_hdisplay;
h_total = crtc_state->hw.adjusted_mode.crtc_htotal;
pixel_clk = crtc_state->hw.adjusted_mode.crtc_clock;
-   vdsc_bpp = crtc_state->dsc.compressed_bpp;
+   vdsc_bpp = to_bpp_int(crtc_state->dsc.compressed_bpp_x16);
cdclk = i915->display.cdclk.hw.cdclk;
/* fec= 0.972261, using rounding multiplier of 100 */
fec_coeff = 972261;
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index 719fb550342b..2fd72b2fd109 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -3414,8 +3414,8 @@ static void fill_dsc(struct intel_crtc_state *crtc_state,
 
crtc_state->pipe_bpp = bpc * 3;
 
-   crtc_state->dsc.compressed_bpp = min(crtc_state->pipe_bpp,
-VBT_DSC_MAX_BPP(dsc->max_bpp));
+   crtc_state->dsc.compressed_bpp_x16 = 
to_bpp_x16(min(crtc_sta

[PATCH 03/11] drm/i915/display: Consider fractional vdsc bpp while computing m_n values

2023-11-10 Thread Ankit Nautiyal
MTL+ supports fractional compressed bits_per_pixel, with precision of
1/16. This compressed bpp is stored in U6.4 format.
Accommodate this precision while computing m_n values.

v1:
Replace the computation of 'data_clock' with 'data_clock =
DIV_ROUND_UP(data_clock, 16).' (Sui Jingfeng).

v2:
Rebase and pass bits_per_pixel in U6.4 format.

Signed-off-by: Ankit Nautiyal 
Signed-off-by: Mitul Golani 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
---
 drivers/gpu/drm/i915/display/intel_display.c |  4 ++--
 drivers/gpu/drm/i915/display/intel_dp.c  | 16 
 drivers/gpu/drm/i915/display/intel_dp_mst.c  | 14 +++---
 drivers/gpu/drm/i915/display/intel_fdi.c |  3 ++-
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index b4a8e3087e50..125903007a29 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2415,12 +2415,12 @@ add_bw_alloc_overhead(int link_clock, int bw_overhead,
 }
 
 void
-intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
+intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes,
   int pixel_clock, int link_clock,
   int bw_overhead,
   struct intel_link_m_n *m_n)
 {
-   u32 data_clock = bits_per_pixel * pixel_clock;
+   u32 data_clock = DIV_ROUND_UP(bits_per_pixel_x16 * pixel_clock, 16);
u32 data_m;
u32 data_n;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4ad3718c3c7d..246f50d1f030 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2663,7 +2663,7 @@ static bool can_enable_drrs(struct intel_connector 
*connector,
 static void
 intel_dp_drrs_compute_config(struct intel_connector *connector,
 struct intel_crtc_state *pipe_config,
-int link_bpp)
+int link_bpp_x16)
 {
struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct drm_display_mode *downclock_mode =
@@ -2688,7 +2688,7 @@ intel_dp_drrs_compute_config(struct intel_connector 
*connector,
if (pipe_config->splitter.enable)
pixel_clock /= pipe_config->splitter.link_count;
 
-   intel_link_compute_m_n(link_bpp, pipe_config->lane_count, pixel_clock,
+   intel_link_compute_m_n(link_bpp_x16, pipe_config->lane_count, 
pixel_clock,
   pipe_config->port_clock,
   
intel_dp_bw_fec_overhead(pipe_config->fec_enable),
   _config->dp_m2_n2);
@@ -2792,7 +2792,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
const struct drm_display_mode *fixed_mode;
struct intel_connector *connector = intel_dp->attached_connector;
-   int ret = 0, link_bpp;
+   int ret = 0, link_bpp_x16;
 
if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != 
PORT_A)
pipe_config->has_pch_encoder = true;
@@ -2841,10 +2841,10 @@ intel_dp_compute_config(struct intel_encoder *encoder,
drm_dp_enhanced_frame_cap(intel_dp->dpcd);
 
if (pipe_config->dsc.compression_enable)
-   link_bpp = to_bpp_int(pipe_config->dsc.compressed_bpp_x16);
+   link_bpp_x16 = pipe_config->dsc.compressed_bpp_x16;
else
-   link_bpp = intel_dp_output_bpp(pipe_config->output_format,
-  pipe_config->pipe_bpp);
+   link_bpp_x16 = 
to_bpp_x16(intel_dp_output_bpp(pipe_config->output_format,
+ 
pipe_config->pipe_bpp));
 
if (intel_dp->mso_link_count) {
int n = intel_dp->mso_link_count;
@@ -2868,7 +2868,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 
intel_dp_audio_compute_config(encoder, pipe_config, conn_state);
 
-   intel_link_compute_m_n(link_bpp,
+   intel_link_compute_m_n(link_bpp_x16,
   pipe_config->lane_count,
   adjusted_mode->crtc_clock,
   pipe_config->port_clock,
@@ -2884,7 +2884,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 
intel_vrr_compute_config(pipe_config, conn_state);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
-   intel_dp_drrs_compute_config(connector, pipe_config, link_bpp);
+   intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, 
co

[PATCH 01/11] drm/display/dp: Add helper function to get DSC bpp precision

2023-11-10 Thread Ankit Nautiyal
Add helper to get the DSC bits_per_pixel precision for the DP sink.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Suraj Kandpal 
Reviewed-by: Sui Jingfeng 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/display/drm_dp_helper.c | 27 +
 include/drm/display/drm_dp_helper.h |  1 +
 2 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 72ba9ae89f86..d72b6f9a352c 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2328,6 +2328,33 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct 
drm_dp_desc *desc,
 }
 EXPORT_SYMBOL(drm_dp_read_desc);
 
+/**
+ * drm_dp_dsc_sink_bpp_incr() - Get bits per pixel increment
+ * @dsc_dpcd: DSC capabilities from DPCD
+ *
+ * Returns the bpp precision supported by the DP sink.
+ */
+u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
+{
+   u8 bpp_increment_dpcd = dsc_dpcd[DP_DSC_BITS_PER_PIXEL_INC - 
DP_DSC_SUPPORT];
+
+   switch (bpp_increment_dpcd) {
+   case DP_DSC_BITS_PER_PIXEL_1_16:
+   return 16;
+   case DP_DSC_BITS_PER_PIXEL_1_8:
+   return 8;
+   case DP_DSC_BITS_PER_PIXEL_1_4:
+   return 4;
+   case DP_DSC_BITS_PER_PIXEL_1_2:
+   return 2;
+   case DP_DSC_BITS_PER_PIXEL_1_1:
+   return 1;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_dsc_sink_bpp_incr);
+
 /**
  * drm_dp_dsc_sink_max_slice_count() - Get the max slice count
  * supported by the DSC sink.
diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index caee29d28463..c5f1079acb3b 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -164,6 +164,7 @@ drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 }
 
 /* DP/eDP DSC support */
+u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]);
 u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
   bool is_edp);
 u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]);
-- 
2.40.1



[PATCH 00/11] Add DSC fractional bpp support

2023-11-10 Thread Ankit Nautiyal
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.

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(-)

-- 
2.40.1



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

2023-08-24 Thread Ankit Nautiyal
Edid specific BPC constraints are stored in limits->max_bpp. Honor these
limits while computing the input bpp for DSC.

v2: Use int instead of u8 for computations. (Jani)
Add closes tag. (Ankit)

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9161
Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 7067ee3a4bd3..8f3dc79089ea 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2061,9 +2061,10 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
if (forced_bpp) {
pipe_bpp = forced_bpp;
} else {
+   int max_bpc = min(limits->max_bpp / 3, 
(int)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,
-   
conn_state->max_requested_bpc);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, max_bpc);
if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
"Computed BPC is not in DSC BPC limits\n");
-- 
2.40.1



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

2023-08-24 Thread Ankit Nautiyal
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 get check dsc support. (Ankit)
v3: Fix styling and other typos. (Jani)

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/display/drm_dp_helper.c | 8 ++--
 1 file changed, 6 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..8a1b64c57dfd 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2449,12 +2449,16 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 
dsc_dpcd[DP_DSC_RECEIVER_CAP_S
int num_bpc = 0;
u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];
 
+   if (!drm_dp_sink_supports_dsc(dsc_dpcd))
+   return 0;
+
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 device shall support 8 bpc. */
+   dsc_bpc[num_bpc++] = 8;
 
return num_bpc;
 }
-- 
2.40.1



[PATCH 0/2] eDP DSC fixes

2023-08-24 Thread Ankit Nautiyal
Assume 8bpc is supported if Sink claims DSC support.
Also consider bpc constraint coming from EDID while computing
input BPC for DSC.

Rev2: Fix check for dsc support.
Rev3: Minor styling and typos fix.

Ankit Nautiyal (2):
  drm/display/dp: Assume 8 bpc support when DSC is supported
  drivers/drm/i915: Honor limits->max_bpp while computing DSC max input
bpp

 drivers/gpu/drm/display/drm_dp_helper.c | 8 ++--
 drivers/gpu/drm/i915/display/intel_dp.c | 5 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

-- 
2.40.1



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

2023-08-23 Thread Ankit Nautiyal
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))
+   return 0;
+
u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];
 
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. */
+   dsc_bpc[num_bpc++] = 8;
 
return num_bpc;
 }
-- 
2.40.1



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

2023-08-23 Thread Ankit Nautiyal
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;
+
/* 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(>drm,
"Computed BPC is not in DSC BPC limits\n");
-- 
2.40.1



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

2023-08-23 Thread Ankit Nautiyal
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.

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..0aa4ce17420c 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 (!dsc_dpcd[DP_DSC_SUPPORT] & DP_DSC_DECOMPRESSION_IS_SUPPORTED)
+   return 0;
+
u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];
 
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. */
+   dsc_bpc[num_bpc++] = 8;
 
return num_bpc;
 }
-- 
2.40.1



[PATCH 0/2] eDP DSC fixes

2023-08-23 Thread Ankit Nautiyal
Assume 8bpc is supported if Sink claims DSC support.
Also consider bpc constraint coming from EDID while computing
input BPC for DSC.

Ankit Nautiyal (2):
  drm/display/dp: Default 8 bpc support when DSC is supported
  drivers/drm/i915: Honor limits->max_bpp while computing DSC max input
bpp

 drivers/gpu/drm/display/drm_dp_helper.c | 9 +++--
 drivers/gpu/drm/i915/display/intel_dp.c | 4 +++-
 2 files changed, 10 insertions(+), 3 deletions(-)

-- 
2.40.1



[PATCH] drm/display/dp: Fix the DP DSC Receiver cap size

2023-08-17 Thread Ankit Nautiyal
DP DSC Receiver Capabilities are exposed via DPCD 60h-6Fh.
Fix the DSC RECEIVER CAP SIZE accordingly.

Fixes: ffddc4363c28 ("drm/dp: Add DP DSC DPCD receiver capability size define 
and missing SHIFT")
Cc: Anusha Srivatsa 
Cc: Manasi Navare 
Cc:  # v5.0+

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 include/drm/display/drm_dp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 02f2ac4dd2df..e69cece404b3 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1537,7 +1537,7 @@ enum drm_dp_phy {
 
 #define DP_BRANCH_OUI_HEADER_SIZE  0xc
 #define DP_RECEIVER_CAP_SIZE   0xf
-#define DP_DSC_RECEIVER_CAP_SIZE0xf
+#define DP_DSC_RECEIVER_CAP_SIZE0x10 /* DSC Capabilities 0x60 through 
0x6F */
 #define EDP_PSR_RECEIVER_CAP_SIZE  2
 #define EDP_DISPLAY_CTL_CAP_SIZE   3
 #define DP_LTTPR_COMMON_CAP_SIZE   8
-- 
2.40.1



[PATCH 16/18] drm/i915/dp: Get optimal link config to have best compressed bpp

2023-08-17 Thread Ankit Nautiyal
Currently, we take the max lane, rate and pipe bpp, to get the maximum
compressed bpp possible. We then set the output bpp to this value.
This patch provides support to have max bpp, min rate and min lanes,
that can support the min compressed bpp.

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.

v5:
-Get rid of magic numbers for max and min bpp,
and improve documentation. (Stan).
-Use functions for {src_sink}_{min_max}_compressed_bpp (Ville).

v6:
-Remove lines to set link config to max.

v7:
-Split the part to separate edp and dp functions for computing DSC BPP
into separate patch.

v8:
-Separate mechanism to get compressed bpp for ICL,TGL and XELPD+.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 294 +---
 1 file changed, 261 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 3ccdf765c1f0..b295dd32e076 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1689,6 +1689,231 @@ 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_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+   u32 lane_count, u32 mode_clock,
+   enum intel_output_format 
output_format,
+   int timeslots)
+{
+   u32 available_bw, required_bw;
+
+   available_bw = (link_clock * lane_count * timeslots)  / 8;
+   required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
+
+   return available_bw > required_bw;
+}
+
+static int dsc_compute_link_config(struct intel_dp *intel_dp,
+  struct intel_crtc_state *pipe_config,
+  struct link_config_limits *limits,
+  u16 compressed_bpp,
+  int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   int link_rate, lane_count;
+   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) {
+   if (!is_bw_sufficient_for_dsc_config(compressed_bpp, 
link_rate, lane_count,
+
adjusted_mode->clock,
+
pipe_config->output_format,
+timeslots))
+   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 *intel_dp,
+   struct intel_crtc_state 
*pipe_config,
+   int bpc)
+{
+   u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
+
+   if (max_bppx16)
+   return max_bppx16;
+   /*
+* If support not given in DPCD 67h, 68h use the Maximum Allowed bit 
rate
+* values as given in spec Table 2-157 DP v2.0
+*/
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return (3 * bpc) << 4;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return (3 * (bpc / 2)) << 4;
+   default:
+   MISSING_CASE(pipe_config->output_format);
+   break;
+   }
+
+   return 0;
+}
+
+static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+{
+   /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return 8;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return 6;
+   default:
+   MISSING_CASE(pipe_config->o

[PATCH 18/18] drm/i915/dp: Check if force_dsc_output_format is possible

2023-08-17 Thread Ankit Nautiyal
Currently for testing an output format with DSC, we just force the
output format, without checking if it can be supported.
This also creates an issue where there is a PCON which might need to
convert from forced output format to the format to sink format.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 764663cd73ea..5b48bfe09d0e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -935,16 +935,42 @@ dfp_can_convert_from_ycbcr444(struct intel_dp *intel_dp,
return false;
 }
 
+static bool
+dfp_can_convert(struct intel_dp *intel_dp,
+   enum intel_output_format output_format,
+   enum intel_output_format sink_format)
+{
+   switch (output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   return dfp_can_convert_from_rgb(intel_dp, sink_format);
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return dfp_can_convert_from_ycbcr444(intel_dp, sink_format);
+   default:
+   MISSING_CASE(output_format);
+   return false;
+   }
+
+   return false;
+}
+
 static enum intel_output_format
 intel_dp_output_format(struct intel_connector *connector,
   enum intel_output_format sink_format)
 {
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   enum intel_output_format force_dsc_output_format =
+   intel_dp->force_dsc_output_format;
enum intel_output_format output_format;
+   if (force_dsc_output_format) {
+   if (source_can_output(intel_dp, force_dsc_output_format) &&
+   (!drm_dp_is_branch(intel_dp->dpcd) ||
+sink_format != force_dsc_output_format ||
+dfp_can_convert(intel_dp, force_dsc_output_format, 
sink_format)))
+   return force_dsc_output_format;
 
-   if (intel_dp->force_dsc_output_format)
-   return intel_dp->force_dsc_output_format;
+   drm_dbg_kms(>drm, "Cannot force DSC output format\n");
+   }
 
if (sink_format == INTEL_OUTPUT_FORMAT_RGB ||
dfp_can_convert_from_rgb(intel_dp, sink_format))
-- 
2.40.1



[PATCH 13/18] drm/i915/dp: Separate out functions for edp/DP for computing DSC bpp

2023-08-17 Thread Ankit Nautiyal
Refactor code to separate functions for eDP and DP for computing
pipe_bpp/compressed bpp when DSC is involved.

This will help to optimize the link configuration for DP later.

v2: Fix checkpatch warning.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 191 
 1 file changed, 126 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index db136349d82d..6dfad64b8379 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1696,6 +1696,115 @@ bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private 
*i915, int pipe_bpp)
return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
 }
 
+static
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int forced_bpp;
+
+   if (!intel_dp->force_dsc_bpc)
+   return 0;
+
+   forced_bpp = intel_dp->force_dsc_bpc * 3;
+
+   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
+   return forced_bpp;
+   }
+
+   drm_dbg_kms(>drm, "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+   intel_dp->force_dsc_bpc);
+
+   return 0;
+}
+
+static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+struct drm_connector_state *conn_state,
+struct link_config_limits *limits,
+int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   u16 output_bpp, dsc_max_compressed_bpp = 0;
+   int forced_bpp, pipe_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   drm_dbg_kms(>drm,
+   "Computed BPC less than min supported by 
source for DSC\n");
+   return -EINVAL;
+   }
+   }
+   /*
+* For now enable DSC for max link rate, max lane count.
+* Optimize this later for the minimum possible link rate/lane count
+* with DSC enabled for the requested mode.
+*/
+   pipe_config->port_clock = limits->max_rate;
+   pipe_config->lane_count = limits->max_lane_count;
+   dsc_max_compressed_bpp = intel_dp_dsc_get_max_compressed_bpp(i915,
+
pipe_config->port_clock,
+
pipe_config->lane_count,
+
adjusted_mode->crtc_clock,
+
adjusted_mode->crtc_hdisplay,
+
pipe_config->bigjoiner_pipes,
+
pipe_config->output_format,
+pipe_bpp,
+timeslots);
+   if (!dsc_max_compressed_bpp) {
+   drm_dbg_kms(>drm, "Compressed BPP not supported\n");
+   return -EINVAL;
+   }
+
+   output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp);
+
+   pipe_config->dsc.compressed_bpp = min_t(u16, dsc_max_compressed_bpp, 
output_bpp);
+
+   pipe_config->pipe_bpp = pipe_bpp;
+
+   return 0;
+}
+
+static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct drm_connector_state 
*conn_state,
+ struct link_config_limits *limits)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int pipe_bpp, forced_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   /* For eDP use max bpp that can be supported with DSC. */
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp,
+   
conn_state->max_requeste

[PATCH 11/18] drm/i915/dp: Avoid left shift of DSC output bpp by 4

2023-08-17 Thread Ankit Nautiyal
To make way for fractional bpp support, avoid left shifting the
output_bpp by 4 in helper intel_dp_dsc_get_output_bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 10 +++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  2 +-
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 52c47e1b42a0..60c66cc720be 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -814,11 +814,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-   /*
-* Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-* fractional part is 0
-*/
-   return bits_per_pixel << 4;
+   return bits_per_pixel;
 }
 
 u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
@@ -1208,7 +1204,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,

mode->hdisplay,
bigjoiner,

output_format,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1811,7 +1807,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 
pipe_config->pipe_bpp);
 
pipe_config->dsc.compressed_bpp = min_t(u16,
-   
dsc_max_compressed_bpp >> 4,
+   
dsc_max_compressed_bpp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index dff4717edbd0..4895d6242915 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -982,7 +982,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,

mode->hdisplay,
bigjoiner,

INTEL_OUTPUT_FORMAT_RGB,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
-- 
2.40.1



[PATCH 14/18] drm/i915/dp: Add DSC BPC/BPP constraints while selecting pipe bpp with DSC

2023-08-17 Thread Ankit Nautiyal
Currently we check if the pipe_bpp selected is >= the
min DSC bpc/bpp requirement. We do not check if it is <= the max DSC
bpc/bpp requirement.

Add checks for max DSC BPC/BPP constraints while computing the
pipe_bpp when DSC is in use.

v2: Fix the commit message.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6dfad64b8379..109d7756ede4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1691,13 +1691,27 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
 }
 
 static
-bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits,
+   int pipe_bpp)
 {
-   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+   u8 dsc_max_bpc, dsc_min_bpc, dsc_max_pipe_bpp, dsc_min_pipe_bpp;
+
+   dsc_max_bpc = min(intel_dp_dsc_max_src_input_bpc(i915), 
conn_state->max_requested_bpc);
+   dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
+
+   dsc_max_pipe_bpp = min(dsc_max_bpc * 3, limits->max_bpp);
+   dsc_min_pipe_bpp = max(dsc_min_bpc * 3, limits->min_bpp);
+
+   return pipe_bpp >= dsc_min_pipe_bpp &&
+  pipe_bpp <= dsc_max_pipe_bpp;
 }
 
 static
-int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int forced_bpp;
@@ -1707,7 +1721,7 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
 
forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   if (is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, forced_bpp)) {
drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
return forced_bpp;
}
@@ -1729,16 +1743,16 @@ static int intel_dp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
u16 output_bpp, dsc_max_compressed_bpp = 0;
int forced_bpp, pipe_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
} else {
pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
 
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
@@ -1780,7 +1794,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int pipe_bpp, forced_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
@@ -1788,9 +1802,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
/* 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);
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
-- 
2.40.1



[PATCH 04/18] drm/i915/dp: Use consistent name for link bpp and compressed bpp

2023-08-17 Thread Ankit Nautiyal
Currently there are many places where we use output_bpp for link bpp and
compressed bpp.
Lets use consistent naming:
output_bpp : The intermediate value taking into account the
output_format chroma subsampling.
compressed_bpp : target bpp for the DSC encoder.
link_bpp : final bpp used in the link.

For 444 sampling without DSC:
link_bpp = output_bpp = pipe_bpp

For 420 sampling without DSC:
output_bpp = pipe_bpp / 2
link_bpp = output_bpp

For 444 sampling with DSC:
output_bpp = pipe_bpp
link_bpp = compressed_bpp, computed with output_bpp (i.e. pipe_bpp in
this case)

For 420 sampling with DSC:
output_bpp = pipe_bpp/2
link_bpp = compressed_bpp, computed with output_bpp

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 84 ++---
 drivers/gpu/drm/i915/display/intel_dp.h | 14 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 22 +++---
 3 files changed, 60 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index a8b67805f3d4..9775c1cbed2b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,13 +740,13 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct 
drm_i915_private *i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
-u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
-   u32 link_clock, u32 lane_count,
-   u32 mode_clock, u32 mode_hdisplay,
-   bool bigjoiner,
-   enum intel_output_format output_format,
-   u32 pipe_bpp,
-   u32 timeslots)
+u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
+   u32 link_clock, u32 lane_count,
+   u32 mode_clock, u32 mode_hdisplay,
+   bool bigjoiner,
+   enum intel_output_format output_format,
+   u32 pipe_bpp,
+   u32 timeslots)
 {
u32 bits_per_pixel, max_bpp_small_joiner_ram;
 
@@ -1136,7 +1136,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
int target_clock = mode->clock;
int max_rate, mode_rate, max_lanes, max_link_clock;
int max_dotclk = dev_priv->max_dotclk_freq;
-   u16 dsc_max_output_bpp = 0;
+   u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
enum drm_mode_status status;
bool dsc = false, bigjoiner = false;
@@ -1191,21 +1191,21 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * integer value since we support only integer values of bpp.
 */
if (intel_dp_is_edp(intel_dp)) {
-   dsc_max_output_bpp =
+   dsc_max_compressed_bpp =
drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) 
>> 4;
dsc_slice_count =

drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
true);
} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
-   dsc_max_output_bpp =
-   intel_dp_dsc_get_output_bpp(dev_priv,
-   max_link_clock,
-   max_lanes,
-   target_clock,
-   mode->hdisplay,
-   bigjoiner,
-   output_format,
-   pipe_bpp, 64) >> 4;
+   dsc_max_compressed_bpp =
+   intel_dp_dsc_get_max_compressed_bpp(dev_priv,
+   
max_link_clock,
+   max_lanes,
+   
target_clock,
+   
mode->hdisplay,
+   bigjoiner,
+   
output_format,
+   pipe_bpp, 
64) >> 4;
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1213,7 +1213,7 @@ intel_dp_mode

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

2023-08-17 Thread Ankit Nautiyal
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)

v5: Added note for 2 PPC. (Stan)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9775c1cbed2b..a7c706a2327f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -802,8 +802,11 @@ 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;
+   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
+   int ppc = 2;
u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * 48 /
+   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
intel_dp_mode_to_fec_clock(mode_clock);
 
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
-- 
2.40.1



[PATCH 10/18] drm/i915/dp: Check min bpc DSC limits for dsc_force_bpc also

2023-08-17 Thread Ankit Nautiyal
For DSC the min BPC is 8 for ICL+ and so the min pipe_bpp is 24.
Check this condition for cases where bpc is forced by debugfs flag
dsc_force_bpc. If the check fails, then WARN and ignore the debugfs
flag.

For MST case the pipe_bpp is already computed (hardcoded to be 24),
and this check is not required.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 48 -
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fcf94b22e99d..52c47e1b42a0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1694,6 +1694,12 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
return HAS_DSC(i915) ? 8 : 0;
 }
 
+static
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+{
+   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+}
+
 int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
@@ -1705,7 +1711,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
-   int pipe_bpp;
int ret;
 
pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
@@ -1717,28 +1722,37 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
return -EINVAL;
 
-   if (intel_dp->force_dsc_bpc && compute_pipe_bpp) {
-   pipe_bpp = intel_dp->force_dsc_bpc * 3;
-   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to %d\n",
-   intel_dp->force_dsc_bpc);
-   } else if (compute_pipe_bpp) {
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, 
conn_state->max_requested_bpc);
-   } else {
-   pipe_bpp = pipe_config->pipe_bpp;
-   }
+   if (compute_pipe_bpp) {
+   int pipe_bpp;
+   int forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (pipe_bpp < intel_dp_dsc_min_src_input_bpc(dev_priv) * 3) {
-   drm_dbg_kms(_priv->drm,
-   "Computed BPC less than min supported by source for 
DSC\n");
-   return -EINVAL;
+   if (forced_bpp && is_dsc_pipe_bpp_sufficient(dev_priv, 
forced_bpp)) {
+   pipe_bpp = forced_bpp;
+   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to 
%d\n",
+   intel_dp->force_dsc_bpc);
+   } else {
+   drm_WARN(_priv->drm, forced_bpp,
+"Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+intel_dp->force_dsc_bpc);
+
+   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
+   drm_dbg_kms(_priv->drm,
+   "Computed BPC less than min 
supported by source for DSC\n");
+   return -EINVAL;
+   }
+   }
+
+   pipe_config->pipe_bpp = pipe_bpp;
}
 
/*
-* For now enable DSC for max bpp, max link rate, max lane count.
+* For now enable DSC for max link rate, max lane count.
 * Optimize this later for the minimum possible link rate/lane count
 * with DSC enabled for the requested mode.
 */
-   pipe_config->pipe_bpp = pipe_bpp;
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
 
@@ -1767,7 +1781,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,

pipe_config->output_format,
-   pipe_bpp,
+   
pipe_config->pipe_bpp,
timeslots);
if (!dsc_max_compressed_bpp) {
drm_dbg_kms(_priv->drm,
-- 
2.40.1



[PATCH 07/18] drm/i915/dp: Remove extra logs for printing DSC info

2023-08-17 Thread Ankit Nautiyal
DSC compressed bpp and slice counts are already getting printed at the
end of dsc compute config. Remove extra logs.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index a7c706a2327f..0b85af7316f4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1782,9 +1782,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
-   drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count 
%d\n",
-   pipe_config->dsc.compressed_bpp,
-   pipe_config->dsc.slice_count);
}
/*
 * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
-- 
2.40.1



[PATCH 00/18] DSC misc fixes

2023-08-17 Thread Ankit Nautiyal
This series is an attempt to address multiple issues with DSC,
scattered in separate existing series.

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/

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.

Rev8: Dropped few patches to be taken into separate series.
Fixed typo in commit message in Patch#2 and rebased.

Ankit Nautiyal (18):
  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/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

 drivers/gpu/drm/i915/display/intel_cdclk.c  |  59 +-
 drivers/gpu/drm/i915/display/intel_dp.c | 651 
 drivers/gpu/drm/i915/display/intel_dp.h |  16 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  33 +-
 4 files changed, 596 insertions(+), 163 deletions(-)

-- 
2.40.1



[PATCH 06/18] drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck

2023-08-17 Thread Ankit Nautiyal
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)

v3: Use helper to account for FEC overhead. (Stan)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 59 +-
 1 file changed, 45 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 2fb030b1ff1d..de04a6fe54f3 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -32,6 +32,7 @@
 #include "intel_cdclk.h"
 #include "intel_crtc.h"
 #include "intel_de.h"
+#include "intel_dp.h"
 #include "intel_display_types.h"
 #include "intel_mchbar_regs.h"
 #include "intel_pci_config.h"
@@ -2533,6 +2534,48 @@ 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 = 
intel_dp_mode_to_fec_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
+*/
+   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);
+
+   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 +2647,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));
 
/*
 * HACK. Currently for TGL/DG2 platforms we calculate
-- 
2.40.1



[PATCH 15/18] drm/i915/dp: Separate out function to get compressed bpp with joiner

2023-08-17 Thread Ankit Nautiyal
Pull the code to get joiner constraints on maximum compressed bpp into
separate function.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 54 ++---
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 109d7756ede4..3ccdf765c1f0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,6 +740,32 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private 
*i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
+static
+u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
+  u32 mode_clock, u32 mode_hdisplay,
+  bool bigjoiner)
+{
+   u32 max_bpp_small_joiner_ram;
+
+   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / 
mode_hdisplay;
+
+   if (bigjoiner) {
+   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
+   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
+   int ppc = 2;
+   u32 max_bpp_bigjoiner =
+   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
+   intel_dp_mode_to_fec_clock(mode_clock);
+
+   max_bpp_small_joiner_ram *= 2;
+
+   return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner);
+   }
+
+   return max_bpp_small_joiner_ram;
+}
+
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
@@ -748,7 +774,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
u32 pipe_bpp,
u32 timeslots)
 {
-   u32 bits_per_pixel, max_bpp_small_joiner_ram;
+   u32 bits_per_pixel, joiner_max_bpp;
 
/*
 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
@@ -788,29 +814,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
(link_clock * lane_count * 8),
intel_dp_mode_to_fec_clock(mode_clock));
 
-   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
-   mode_hdisplay;
-
-   if (bigjoiner)
-   max_bpp_small_joiner_ram *= 2;
-
-   /*
-* Greatest allowed DSC BPP = MIN (output BPP from available Link BW
-* check, output bpp from small joiner RAM check)
-*/
-   bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-   if (bigjoiner) {
-   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
-   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
-   int ppc = 2;
-   u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
-   intel_dp_mode_to_fec_clock(mode_clock);
-
-   bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
-   }
+   joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock,
+   mode_hdisplay, 
bigjoiner);
+   bits_per_pixel = min(bits_per_pixel, joiner_max_bpp);
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-- 
2.40.1



[PATCH 17/18] drm/i915/dp: Check src/sink compressed bpp limit for edp

2023-08-17 Thread Ankit Nautiyal
Use checks for src and sink limits before computing compressed bpp for
eDP.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index b295dd32e076..764663cd73ea 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2027,6 +2027,8 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int pipe_bpp, forced_bpp;
+   int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
+   int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
 
forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
@@ -2044,9 +2046,19 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
}
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
-   pipe_config->dsc.compressed_bpp =
-   min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
- pipe_bpp);
+
+   dsc_src_min_bpp = dsc_src_min_compressed_bpp();
+   dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+   dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
+
+   dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
+   dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
pipe_bpp / 3);
+   dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
: dsc_src_max_bpp;
+
+   /* Compressed BPP should be less than the Input DSC bpp */
+   dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
+
+   pipe_config->dsc.compressed_bpp = max(dsc_min_bpp, dsc_max_bpp);
 
pipe_config->pipe_bpp = pipe_bpp;
 
-- 
2.40.1



[PATCH 08/18] drm/i915/dp: Avoid forcing DSC BPC for MST case

2023-08-17 Thread Ankit Nautiyal
For MST the bpc is hardcoded to 8, and pipe bpp to 24.
So avoid forcing DSC bpc for MST case.

v2: Warn and ignore the debug flag than to bail out. (Jani)

v3: Fix dbg message to mention forced bpc instead of bpp.

v4: Fix checkpatch longline warning.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 12 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  5 +
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0b85af7316f4..d6fd453ade6b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1697,14 +1697,14 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
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(_priv->drm, "Input DSC BPC forced to %d\n",
+   intel_dp->force_dsc_bpc);
+   } 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(_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 1f00713fb1ad..dff4717edbd0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -361,6 +361,11 @@ static int intel_dp_mst_compute_config(struct 
intel_encoder *encoder,
/* enable compression if the mode doesn't fit available BW */
drm_dbg_kms(_priv->drm, "Force DSC en = %d\n", 
intel_dp->force_dsc_en);
if (ret || intel_dp->force_dsc_en) {
+   /*
+* FIXME: As bpc is hardcoded to 8, as mentioned above,
+* WARN and ignore the debug flag force_dsc_bpc for now.
+*/
+   drm_WARN(_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force 
BPC for MST\n");
/*
 * Try to get at least some timeslots and then see, if
 * we can fit there with DSC.
-- 
2.40.1



[PATCH 12/18] drm/i915/dp: Rename helper to get DSC max pipe_bpp

2023-08-17 Thread Ankit Nautiyal
The helper intel_dp_dsc_compute_bpp gives the maximum
pipe bpp that is allowed with DSC.

Rename the this to reflect that it returns max pipe bpp supported
with DSC.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 8 
 drivers/gpu/drm/i915/display/intel_dp.h | 2 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 60c66cc720be..db136349d82d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1183,7 +1183,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
/*
 * Output bpp is stored in 6.4 format so right shift by 4 to 
get the
@@ -1543,7 +1543,7 @@ u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private 
*i915)
return 0;
 }
 
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i, num_bpc;
@@ -1731,8 +1731,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
 intel_dp->force_dsc_bpc);
 
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
-   
conn_state->max_requested_bpc);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
 
if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
drm_dbg_kms(_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 6fd423463f5c..788a577ebe16 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -106,7 +106,7 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
   struct intel_crtc_state *crtc_state,
   unsigned int type);
 bool intel_digital_port_connected(struct intel_encoder *encoder);
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4895d6242915..3eb085fbc7c8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -971,7 +971,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
dsc_max_compressed_bpp =
-- 
2.40.1



[PATCH 09/18] drm/i915/dp: Add functions to get min/max src input bpc with DSC

2023-08-17 Thread Ankit Nautiyal
Separate out functions for getting maximum and minimum input BPC based
on platforms, when DSC is used.

v2: Use HAS_DSC macro instead of platform check while getting min input
bpc. (Stan)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 35 +++--
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index d6fd453ade6b..fcf94b22e99d 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,13 @@ 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 */
+   return HAS_DSC(i915) ? 8 : 0;
+}
+
 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 +1727,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(_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



[PATCH 03/18] drm/i915/dp_mst: Use output_format to get the final link bpp

2023-08-17 Thread Ankit Nautiyal
The final link bpp used to calculate the m_n values depend on the
output_format. Though the output_format is set to RGB for MST case and
the link bpp will be same as the pipe bpp, for the sake of semantics,
lets calculate the m_n values with the link bpp, instead of pipe_bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
 drivers/gpu/drm/i915/display/intel_dp.h | 1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 -
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index ebf216596fdd..a8b67805f3d4 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -965,7 +965,7 @@ int intel_dp_min_bpp(enum intel_output_format output_format)
return 8 * 3;
 }
 
-static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
 {
/*
 * bpp value was assumed to RGB format. And YCbCr 4:2:0 output
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index bb4f976af296..7dd015385054 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -144,5 +144,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
 void intel_dp_phy_test(struct intel_encoder *encoder);
 
 void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
 
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index aa8d9d570626..ef5375eb923e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -155,6 +155,7 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
const struct drm_display_mode *adjusted_mode =
_state->hw.adjusted_mode;
int slots = -EINVAL;
+   int link_bpp;
 
slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, 
limits->max_bpp,
 limits->min_bpp, limits,
@@ -163,7 +164,9 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
if (slots < 0)
return slots;
 
-   intel_link_compute_m_n(crtc_state->pipe_bpp,
+   link_bpp = intel_dp_output_bpp(crtc_state->output_format, 
crtc_state->pipe_bpp);
+
+   intel_link_compute_m_n(link_bpp,
   crtc_state->lane_count,
   adjusted_mode->crtc_clock,
   crtc_state->port_clock,
-- 
2.40.1



[PATCH 02/18] drm/i915/dp: Move compressed bpp check with 420 format inside the helper

2023-08-17 Thread Ankit Nautiyal
Move the check for limiting compressed bits_per_pixel for 420,422
formats in the helper to compute bits_per_pixel.

v2: Fix typo in commit message. (Ankit)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 29aab055ef11..ebf216596fdd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -773,6 +773,15 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
bits_per_pixel *= 2;
 
+   /*
+* 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 for 420, 422 formats, bpp should be programmed double
+* the target bpp restricting our target bpp to be 31.9375 at max.
+*/
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   bits_per_pixel = min_t(u32, bits_per_pixel, 31);
+
drm_dbg_kms(>drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
@@ -1738,15 +1747,6 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,

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_output_bpp = min_t(u16, 
dsc_max_output_bpp, 31 << 4);
-
if (!dsc_max_output_bpp) {
drm_dbg_kms(_priv->drm,
"Compressed BPP not supported\n");
-- 
2.40.1



[PATCH 01/18] drm/i915/dp: Consider output_format while computing dsc bpp

2023-08-17 Thread Ankit Nautiyal
While using DSC the compressed bpp is computed assuming RGB output
format. Consider the output_format and compute the compressed bpp
during mode valid and compute config steps.

For DP-MST we currently use RGB output format only, so continue
using RGB while computing compressed bpp for MST case.

v2: Use output_bpp instead for pipe_bpp to clamp compressed_bpp. (Ville)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 964bf0551bdc..29aab055ef11 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -744,6 +744,7 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
bool bigjoiner,
+   enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots)
 {
@@ -768,6 +769,10 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
bits_per_pixel = ((link_clock * lane_count) * timeslots) /
 (intel_dp_mode_to_fec_clock(mode_clock) * 8);
 
+   /* Bandwidth required for 420 is half, that of 444 format */
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   bits_per_pixel *= 2;
+
drm_dbg_kms(>drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
@@ -1161,11 +1166,16 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 
if (HAS_DSC(dev_priv) &&
drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
+   enum intel_output_format sink_format, output_format;
+   int pipe_bpp;
+
+   sink_format = intel_dp_sink_format(connector, mode);
+   output_format = intel_dp_output_format(connector, sink_format);
/*
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
 
/*
 * Output bpp is stored in 6.4 format so right shift by 4 to 
get the
@@ -1185,6 +1195,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock,
mode->hdisplay,
bigjoiner,
+   output_format,
pipe_bpp, 64) >> 4;
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
@@ -1724,6 +1735,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,

adjusted_mode->crtc_clock,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,
+   
pipe_config->output_format,
pipe_bpp,
timeslots);
/*
@@ -1759,9 +1771,12 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
 * calculation procedure is bit different for MST case.
 */
if (compute_pipe_bpp) {
+   u16 output_bpp = 
intel_dp_output_bpp(pipe_config->output_format,
+
pipe_config->pipe_bpp);
+
pipe_config->dsc.compressed_bpp = min_t(u16,

dsc_max_output_bpp >> 4,
-   
pipe_config->pipe_bpp);
+   output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count 
%d\n",
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
in

[PATCH 14/20] drm/i915/dp: Separate out functions for edp/DP for computing DSC bpp

2023-08-10 Thread Ankit Nautiyal
Refactor code to separate functions for eDP and DP for computing
pipe_bpp/compressed bpp when DSC is involved.

This will help to optimize the link configuration for DP later.

v2: Fix checkpatch warning.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 191 
 1 file changed, 126 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fd321b314f91..f4870c9b0db6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1696,6 +1696,115 @@ bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private 
*i915, int pipe_bpp)
return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
 }
 
+static
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int forced_bpp;
+
+   if (!intel_dp->force_dsc_bpc)
+   return 0;
+
+   forced_bpp = intel_dp->force_dsc_bpc * 3;
+
+   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
+   return forced_bpp;
+   }
+
+   drm_dbg_kms(>drm, "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+   intel_dp->force_dsc_bpc);
+
+   return 0;
+}
+
+static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+struct drm_connector_state *conn_state,
+struct link_config_limits *limits,
+int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   u16 output_bpp, dsc_max_compressed_bpp = 0;
+   int forced_bpp, pipe_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   drm_dbg_kms(>drm,
+   "Computed BPC less than min supported by 
source for DSC\n");
+   return -EINVAL;
+   }
+   }
+   /*
+* For now enable DSC for max link rate, max lane count.
+* Optimize this later for the minimum possible link rate/lane count
+* with DSC enabled for the requested mode.
+*/
+   pipe_config->port_clock = limits->max_rate;
+   pipe_config->lane_count = limits->max_lane_count;
+   dsc_max_compressed_bpp = intel_dp_dsc_get_max_compressed_bpp(i915,
+
pipe_config->port_clock,
+
pipe_config->lane_count,
+
adjusted_mode->crtc_clock,
+
adjusted_mode->crtc_hdisplay,
+
pipe_config->bigjoiner_pipes,
+
pipe_config->output_format,
+pipe_bpp,
+timeslots);
+   if (!dsc_max_compressed_bpp) {
+   drm_dbg_kms(>drm, "Compressed BPP not supported\n");
+   return -EINVAL;
+   }
+
+   output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp);
+
+   pipe_config->dsc.compressed_bpp = min_t(u16, dsc_max_compressed_bpp, 
output_bpp);
+
+   pipe_config->pipe_bpp = pipe_bpp;
+
+   return 0;
+}
+
+static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct drm_connector_state 
*conn_state,
+ struct link_config_limits *limits)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int pipe_bpp, forced_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   /* For eDP use max bpp that can be supported with DSC. */
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp,
+   
conn_state->max_requeste

[PATCH 15/20] drm/i915/dp: Add DSC BPC/BPP constraints while selecting pipe bpp with DSC

2023-08-10 Thread Ankit Nautiyal
Currently we check if the pipe_bpp selected is >= the
min DSC bpc/bpp requirement. We do not check if it is <= the max DSC
bpc/bpp requirement.

Add checks for max DSC BPC/BPP constraints while computing the
pipe_bpp when DSC is in use.

v2: Fix the commit message.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f4870c9b0db6..67e8a9abe6ce 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1691,13 +1691,27 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
 }
 
 static
-bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits,
+   int pipe_bpp)
 {
-   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+   u8 dsc_max_bpc, dsc_min_bpc, dsc_max_pipe_bpp, dsc_min_pipe_bpp;
+
+   dsc_max_bpc = min(intel_dp_dsc_max_src_input_bpc(i915), 
conn_state->max_requested_bpc);
+   dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
+
+   dsc_max_pipe_bpp = min(dsc_max_bpc * 3, limits->max_bpp);
+   dsc_min_pipe_bpp = max(dsc_min_bpc * 3, limits->min_bpp);
+
+   return pipe_bpp >= dsc_min_pipe_bpp &&
+  pipe_bpp <= dsc_max_pipe_bpp;
 }
 
 static
-int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int forced_bpp;
@@ -1707,7 +1721,7 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
 
forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   if (is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, forced_bpp)) {
drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
return forced_bpp;
}
@@ -1729,16 +1743,16 @@ static int intel_dp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
u16 output_bpp, dsc_max_compressed_bpp = 0;
int forced_bpp, pipe_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
} else {
pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
 
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
@@ -1780,7 +1794,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int pipe_bpp, forced_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
@@ -1788,9 +1802,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
/* 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);
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
-- 
2.40.1



[PATCH 16/20] drm/i915/dp: Separate out function to get compressed bpp with joiner

2023-08-10 Thread Ankit Nautiyal
Pull the code to get joiner constraints on maximum compressed bpp into
separate function.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 54 ++---
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 67e8a9abe6ce..6901ab809587 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,6 +740,32 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private 
*i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
+static
+u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
+  u32 mode_clock, u32 mode_hdisplay,
+  bool bigjoiner)
+{
+   u32 max_bpp_small_joiner_ram;
+
+   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / 
mode_hdisplay;
+
+   if (bigjoiner) {
+   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
+   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
+   int ppc = 2;
+   u32 max_bpp_bigjoiner =
+   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
+   intel_dp_mode_to_fec_clock(mode_clock);
+
+   max_bpp_small_joiner_ram *= 2;
+
+   return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner);
+   }
+
+   return max_bpp_small_joiner_ram;
+}
+
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
@@ -748,7 +774,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
u32 pipe_bpp,
u32 timeslots)
 {
-   u32 bits_per_pixel, max_bpp_small_joiner_ram;
+   u32 bits_per_pixel, joiner_max_bpp;
 
/*
 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
@@ -788,29 +814,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
(link_clock * lane_count * 8),
intel_dp_mode_to_fec_clock(mode_clock));
 
-   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
-   mode_hdisplay;
-
-   if (bigjoiner)
-   max_bpp_small_joiner_ram *= 2;
-
-   /*
-* Greatest allowed DSC BPP = MIN (output BPP from available Link BW
-* check, output bpp from small joiner RAM check)
-*/
-   bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-   if (bigjoiner) {
-   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
-   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
-   int ppc = 2;
-   u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
-   intel_dp_mode_to_fec_clock(mode_clock);
-
-   bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
-   }
+   joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock,
+   mode_hdisplay, 
bigjoiner);
+   bits_per_pixel = min(bits_per_pixel, joiner_max_bpp);
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-- 
2.40.1



[PATCH 19/20] drm/i915/dp: Check if force_dsc_output_format is possible

2023-08-10 Thread Ankit Nautiyal
Currently for testing an output format with DSC, we just force the
output format, without checking if it can be supported.
This also creates an issue where there is a PCON which might need to
convert from forced output format to the format to sink format.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 8c2e5393c6ec..9e904bb4ac5c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -935,16 +935,42 @@ dfp_can_convert_from_ycbcr444(struct intel_dp *intel_dp,
return false;
 }
 
+static bool
+dfp_can_convert(struct intel_dp *intel_dp,
+   enum intel_output_format output_format,
+   enum intel_output_format sink_format)
+{
+   switch (output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   return dfp_can_convert_from_rgb(intel_dp, sink_format);
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return dfp_can_convert_from_ycbcr444(intel_dp, sink_format);
+   default:
+   MISSING_CASE(output_format);
+   return false;
+   }
+
+   return false;
+}
+
 static enum intel_output_format
 intel_dp_output_format(struct intel_connector *connector,
   enum intel_output_format sink_format)
 {
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   enum intel_output_format force_dsc_output_format =
+   intel_dp->force_dsc_output_format;
enum intel_output_format output_format;
+   if (force_dsc_output_format) {
+   if (source_can_output(intel_dp, force_dsc_output_format) &&
+   (!drm_dp_is_branch(intel_dp->dpcd) ||
+sink_format != force_dsc_output_format ||
+dfp_can_convert(intel_dp, force_dsc_output_format, 
sink_format)))
+   return force_dsc_output_format;
 
-   if (intel_dp->force_dsc_output_format)
-   return intel_dp->force_dsc_output_format;
+   drm_dbg_kms(>drm, "Cannot force DSC output format\n");
+   }
 
if (sink_format == INTEL_OUTPUT_FORMAT_RGB ||
dfp_can_convert_from_rgb(intel_dp, sink_format))
-- 
2.40.1



[PATCH 20/20] drm/i915: Query compressed bpp properly using correct DPCD and DP Spec info

2023-08-10 Thread Ankit Nautiyal
From: Stanislav Lisovskiy 

Currently we seem to be using wrong DPCD register for reading
compressed bpps, reading min/max input bpc instead of compressed bpp.
Fix that, so that we now apply min/max compressed bpp limitations we
get from DP Spec Table 2-157 DP v2.0 and/or correspondent DPCD
register DP_DSC_MAX_BITS_PER_PIXEL_LOW/HIGH.

This might also allow us to get rid of an ugly compressed bpp
recalculation, which we had to add to make some MST hubs usable.

v2: - Fix operator precedence
v3: - Added debug info about compressed bpps
v4: - Don't try to intersect Sink input bpp and compressed bpps.
v5: - Decrease step while looking for suitable compressed bpp to
  accommodate.
v6: - Use helper for getting min and max compressed_bpp (Ankit)
v7: - Fix checkpatch warning (Ankit)

Signed-off-by: Stanislav Lisovskiy 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 20 +
 drivers/gpu/drm/i915/display/intel_dp.h |  4 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 47 +
 3 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9e904bb4ac5c..bdaa2249409d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1789,7 +1789,7 @@ u16 intel_dp_dsc_max_sink_compressed_bppx16(struct 
intel_dp *intel_dp,
return 0;
 }
 
-static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+int intel_dp_dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
 {
/* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
switch (pipe_config->output_format) {
@@ -1806,9 +1806,9 @@ static int dsc_sink_min_compressed_bpp(struct 
intel_crtc_state *pipe_config)
return 0;
 }
 
-static int dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
-  struct intel_crtc_state *pipe_config,
-  int bpc)
+int intel_dp_dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+int bpc)
 {
return intel_dp_dsc_max_sink_compressed_bppx16(intel_dp,
   pipe_config, bpc) >> 4;
@@ -1921,11 +1921,13 @@ static int dsc_compute_compressed_bpp(struct intel_dp 
*intel_dp,
int dsc_joiner_max_bpp;
 
dsc_src_min_bpp = dsc_src_min_compressed_bpp();
-   dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+   dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(pipe_config);
dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
 
dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
-   dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
pipe_bpp / 3);
+   dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(intel_dp,
+   pipe_config,
+   pipe_bpp / 3);
dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
: dsc_src_max_bpp;
 
dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, 
adjusted_mode->clock,
@@ -2074,11 +2076,13 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
pipe_config->lane_count = limits->max_lane_count;
 
dsc_src_min_bpp = dsc_src_min_compressed_bpp();
-   dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+   dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(pipe_config);
dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
 
dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
-   dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
pipe_bpp / 3);
+   dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(intel_dp,
+   pipe_config,
+   pipe_bpp / 3);
dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
: dsc_src_max_bpp;
 
/* Compressed BPP should be less than the Input DSC bpp */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 788a577ebe16..f29e48028f39 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -114,6 +114,10 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots);
+int intel_dp_dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config);
+int intel_dp_dsc_sink_max_compressed_bpp(struct 

[PATCH 12/20] drm/i915/dp: Avoid left shift of DSC output bpp by 4

2023-08-10 Thread Ankit Nautiyal
To make way for fractional bpp support, avoid left shifting the
output_bpp by 4 in helper intel_dp_dsc_get_output_bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 10 +++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  2 +-
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index d0cf0021df70..40ba2069ca69 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -814,11 +814,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-   /*
-* Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-* fractional part is 0
-*/
-   return bits_per_pixel << 4;
+   return bits_per_pixel;
 }
 
 u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
@@ -1208,7 +1204,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,

mode->hdisplay,
bigjoiner,

output_format,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1811,7 +1807,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 
pipe_config->pipe_bpp);
 
pipe_config->dsc.compressed_bpp = min_t(u16,
-   
dsc_max_compressed_bpp >> 4,
+   
dsc_max_compressed_bpp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index dff4717edbd0..4895d6242915 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -982,7 +982,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,

mode->hdisplay,
bigjoiner,

INTEL_OUTPUT_FORMAT_RGB,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
-- 
2.40.1



[PATCH 18/20] drm/i915/dp: Check src/sink compressed bpp limit for edp

2023-08-10 Thread Ankit Nautiyal
Use checks for src and sink limits before computing compressed bpp for
eDP.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 196bda630944..8c2e5393c6ec 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2027,6 +2027,8 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int pipe_bpp, forced_bpp;
+   int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
+   int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
 
forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
@@ -2044,9 +2046,19 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
}
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
-   pipe_config->dsc.compressed_bpp =
-   min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
- pipe_bpp);
+
+   dsc_src_min_bpp = dsc_src_min_compressed_bpp();
+   dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+   dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
+
+   dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
+   dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
pipe_bpp / 3);
+   dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
: dsc_src_max_bpp;
+
+   /* Compressed BPP should be less than the Input DSC bpp */
+   dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
+
+   pipe_config->dsc.compressed_bpp = max(dsc_min_bpp, dsc_max_bpp);
 
pipe_config->pipe_bpp = pipe_bpp;
 
-- 
2.40.1



[PATCH 03/20] drm/i915/dp_mst: Use output_format to get the final link bpp

2023-08-10 Thread Ankit Nautiyal
The final link bpp used to calculate the m_n values depend on the
output_format. Though the output_format is set to RGB for MST case and
the link bpp will be same as the pipe bpp, for the sake of semantics,
lets calculate the m_n values with the link bpp, instead of pipe_bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
 drivers/gpu/drm/i915/display/intel_dp.h | 1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 -
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6bb8fa4a3c96..0252cce76519 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -965,7 +965,7 @@ int intel_dp_min_bpp(enum intel_output_format output_format)
return 8 * 3;
 }
 
-static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
 {
/*
 * bpp value was assumed to RGB format. And YCbCr 4:2:0 output
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index bb4f976af296..7dd015385054 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -144,5 +144,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
 void intel_dp_phy_test(struct intel_encoder *encoder);
 
 void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
 
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index aa8d9d570626..ef5375eb923e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -155,6 +155,7 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
const struct drm_display_mode *adjusted_mode =
_state->hw.adjusted_mode;
int slots = -EINVAL;
+   int link_bpp;
 
slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, 
limits->max_bpp,
 limits->min_bpp, limits,
@@ -163,7 +164,9 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
if (slots < 0)
return slots;
 
-   intel_link_compute_m_n(crtc_state->pipe_bpp,
+   link_bpp = intel_dp_output_bpp(crtc_state->output_format, 
crtc_state->pipe_bpp);
+
+   intel_link_compute_m_n(link_bpp,
   crtc_state->lane_count,
   adjusted_mode->crtc_clock,
   crtc_state->port_clock,
-- 
2.40.1



[PATCH 09/20] drm/i915/dp: Avoid forcing DSC BPC for MST case

2023-08-10 Thread Ankit Nautiyal
For MST the bpc is hardcoded to 8, and pipe bpp to 24.
So avoid forcing DSC bpc for MST case.

v2: Warn and ignore the debug flag than to bail out. (Jani)

v3: Fix dbg message to mention forced bpc instead of bpp.

v4: Fix checkpatch longline warning.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 12 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  5 +
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6bded67d986d..c13efd0b7c98 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1697,14 +1697,14 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
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(_priv->drm, "Input DSC BPC forced to %d\n",
+   intel_dp->force_dsc_bpc);
+   } 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(_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 1f00713fb1ad..dff4717edbd0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -361,6 +361,11 @@ static int intel_dp_mst_compute_config(struct 
intel_encoder *encoder,
/* enable compression if the mode doesn't fit available BW */
drm_dbg_kms(_priv->drm, "Force DSC en = %d\n", 
intel_dp->force_dsc_en);
if (ret || intel_dp->force_dsc_en) {
+   /*
+* FIXME: As bpc is hardcoded to 8, as mentioned above,
+* WARN and ignore the debug flag force_dsc_bpc for now.
+*/
+   drm_WARN(_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force 
BPC for MST\n");
/*
 * Try to get at least some timeslots and then see, if
 * we can fit there with DSC.
-- 
2.40.1



[PATCH 08/20] drm/display/dp: Fix the DP DSC Receiver cap size

2023-08-10 Thread Ankit Nautiyal
DP DSC Receiver Capabilities are exposed via DPCD 60h-6Fh.
Fix the DSC RECEIVER CAP SIZE accordingly.

Fixes: ffddc4363c28 ("drm/dp: Add DP DSC DPCD receiver capability size define 
and missing SHIFT")
Cc: Anusha Srivatsa 
Cc: Manasi Navare 
Cc:  # v5.0+

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 include/drm/display/drm_dp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 02f2ac4dd2df..e69cece404b3 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1537,7 +1537,7 @@ enum drm_dp_phy {
 
 #define DP_BRANCH_OUI_HEADER_SIZE  0xc
 #define DP_RECEIVER_CAP_SIZE   0xf
-#define DP_DSC_RECEIVER_CAP_SIZE0xf
+#define DP_DSC_RECEIVER_CAP_SIZE0x10 /* DSC Capabilities 0x60 through 
0x6F */
 #define EDP_PSR_RECEIVER_CAP_SIZE  2
 #define EDP_DISPLAY_CTL_CAP_SIZE   3
 #define DP_LTTPR_COMMON_CAP_SIZE   8
-- 
2.40.1



[PATCH 13/20] drm/i915/dp: Rename helper to get DSC max pipe_bpp

2023-08-10 Thread Ankit Nautiyal
The helper intel_dp_dsc_compute_bpp gives the maximum
pipe bpp that is allowed with DSC.

Rename the this to reflect that it returns max pipe bpp supported
with DSC.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 8 
 drivers/gpu/drm/i915/display/intel_dp.h | 2 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 40ba2069ca69..fd321b314f91 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1183,7 +1183,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
/*
 * Output bpp is stored in 6.4 format so right shift by 4 to 
get the
@@ -1543,7 +1543,7 @@ u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private 
*i915)
return 0;
 }
 
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i, num_bpc;
@@ -1731,8 +1731,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
 intel_dp->force_dsc_bpc);
 
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
-   
conn_state->max_requested_bpc);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
 
if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
drm_dbg_kms(_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 6fd423463f5c..788a577ebe16 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -106,7 +106,7 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
   struct intel_crtc_state *crtc_state,
   unsigned int type);
 bool intel_digital_port_connected(struct intel_encoder *encoder);
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4895d6242915..3eb085fbc7c8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -971,7 +971,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
dsc_max_compressed_bpp =
-- 
2.40.1



[PATCH 04/20] drm/i915/dp: Use consistent name for link bpp and compressed bpp

2023-08-10 Thread Ankit Nautiyal
Currently there are many places where we use output_bpp for link bpp and
compressed bpp.
Lets use consistent naming:
output_bpp : The intermediate value taking into account the
output_format chroma subsampling.
compressed_bpp : target bpp for the DSC encoder.
link_bpp : final bpp used in the link.

For 444 sampling without DSC:
link_bpp = output_bpp = pipe_bpp

For 420 sampling without DSC:
output_bpp = pipe_bpp / 2
link_bpp = output_bpp

For 444 sampling with DSC:
output_bpp = pipe_bpp
link_bpp = compressed_bpp, computed with output_bpp (i.e. pipe_bpp in
this case)

For 420 sampling with DSC:
output_bpp = pipe_bpp/2
link_bpp = compressed_bpp, computed with output_bpp

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 84 ++---
 drivers/gpu/drm/i915/display/intel_dp.h | 14 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 22 +++---
 3 files changed, 60 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0252cce76519..35608b9de573 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,13 +740,13 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct 
drm_i915_private *i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
-u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
-   u32 link_clock, u32 lane_count,
-   u32 mode_clock, u32 mode_hdisplay,
-   bool bigjoiner,
-   enum intel_output_format output_format,
-   u32 pipe_bpp,
-   u32 timeslots)
+u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
+   u32 link_clock, u32 lane_count,
+   u32 mode_clock, u32 mode_hdisplay,
+   bool bigjoiner,
+   enum intel_output_format output_format,
+   u32 pipe_bpp,
+   u32 timeslots)
 {
u32 bits_per_pixel, max_bpp_small_joiner_ram;
 
@@ -1136,7 +1136,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
int target_clock = mode->clock;
int max_rate, mode_rate, max_lanes, max_link_clock;
int max_dotclk = dev_priv->max_dotclk_freq;
-   u16 dsc_max_output_bpp = 0;
+   u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
enum drm_mode_status status;
bool dsc = false, bigjoiner = false;
@@ -1191,21 +1191,21 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * integer value since we support only integer values of bpp.
 */
if (intel_dp_is_edp(intel_dp)) {
-   dsc_max_output_bpp =
+   dsc_max_compressed_bpp =
drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) 
>> 4;
dsc_slice_count =

drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
true);
} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
-   dsc_max_output_bpp =
-   intel_dp_dsc_get_output_bpp(dev_priv,
-   max_link_clock,
-   max_lanes,
-   target_clock,
-   mode->hdisplay,
-   bigjoiner,
-   output_format,
-   pipe_bpp, 64) >> 4;
+   dsc_max_compressed_bpp =
+   intel_dp_dsc_get_max_compressed_bpp(dev_priv,
+   
max_link_clock,
+   max_lanes,
+   
target_clock,
+   
mode->hdisplay,
+   bigjoiner,
+   
output_format,
+   pipe_bpp, 
64) >> 4;
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1213,7 +1213,7 @@ intel_dp_mode

[PATCH 06/20] drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck

2023-08-10 Thread Ankit Nautiyal
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)

v3: Use helper to account for FEC overhead. (Stan)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 59 +-
 1 file changed, 45 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 2fb030b1ff1d..de04a6fe54f3 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -32,6 +32,7 @@
 #include "intel_cdclk.h"
 #include "intel_crtc.h"
 #include "intel_de.h"
+#include "intel_dp.h"
 #include "intel_display_types.h"
 #include "intel_mchbar_regs.h"
 #include "intel_pci_config.h"
@@ -2533,6 +2534,48 @@ 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 = 
intel_dp_mode_to_fec_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
+*/
+   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);
+
+   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 +2647,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));
 
/*
 * HACK. Currently for TGL/DG2 platforms we calculate
-- 
2.40.1



[PATCH 17/20] drm/i915/dp: Get optimal link config to have best compressed bpp

2023-08-10 Thread Ankit Nautiyal
Currently, we take the max lane, rate and pipe bpp, to get the maximum
compressed bpp possible. We then set the output bpp to this value.
This patch provides support to have max bpp, min rate and min lanes,
that can support the min compressed bpp.

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.

v5:
-Get rid of magic numbers for max and min bpp,
and improve documentation. (Stan).
-Use functions for {src_sink}_{min_max}_compressed_bpp (Ville).

v6:
-Remove lines to set link config to max.

v7:
-Split the part to separate edp and dp functions for computing DSC BPP
into separate patch.

v8:
-Separate mechanism to get compressed bpp for ICL,TGL and XELPD+.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 294 +---
 1 file changed, 261 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6901ab809587..196bda630944 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1689,6 +1689,231 @@ 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_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+   u32 lane_count, u32 mode_clock,
+   enum intel_output_format 
output_format,
+   int timeslots)
+{
+   u32 available_bw, required_bw;
+
+   available_bw = (link_clock * lane_count * timeslots)  / 8;
+   required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
+
+   return available_bw > required_bw;
+}
+
+static int dsc_compute_link_config(struct intel_dp *intel_dp,
+  struct intel_crtc_state *pipe_config,
+  struct link_config_limits *limits,
+  u16 compressed_bpp,
+  int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   int link_rate, lane_count;
+   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) {
+   if (!is_bw_sufficient_for_dsc_config(compressed_bpp, 
link_rate, lane_count,
+
adjusted_mode->clock,
+
pipe_config->output_format,
+timeslots))
+   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 *intel_dp,
+   struct intel_crtc_state 
*pipe_config,
+   int bpc)
+{
+   u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
+
+   if (max_bppx16)
+   return max_bppx16;
+   /*
+* If support not given in DPCD 67h, 68h use the Maximum Allowed bit 
rate
+* values as given in spec Table 2-157 DP v2.0
+*/
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return (3 * bpc) << 4;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return (3 * (bpc / 2)) << 4;
+   default:
+   MISSING_CASE(pipe_config->output_format);
+   break;
+   }
+
+   return 0;
+}
+
+static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+{
+   /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return 8;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return 6;
+   default:
+   MISSING_CASE(pipe_config->o

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

2023-08-10 Thread Ankit Nautiyal
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)

v5: Added note for 2 PPC. (Stan)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 35608b9de573..fc08fc85d665 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -802,8 +802,11 @@ 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;
+   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
+   int ppc = 2;
u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * 48 /
+   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
intel_dp_mode_to_fec_clock(mode_clock);
 
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
-- 
2.40.1



[PATCH 11/20] drm/i915/dp: Check min bpc DSC limits for dsc_force_bpc also

2023-08-10 Thread Ankit Nautiyal
For DSC the min BPC is 8 for ICL+ and so the min pipe_bpp is 24.
Check this condition for cases where bpc is forced by debugfs flag
dsc_force_bpc. If the check fails, then WARN and ignore the debugfs
flag.

For MST case the pipe_bpp is already computed (hardcoded to be 24),
and this check is not required.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 48 -
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index b414d09b5e80..d0cf0021df70 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1694,6 +1694,12 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
return HAS_DSC(i915) ? 8 : 0;
 }
 
+static
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+{
+   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+}
+
 int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
@@ -1705,7 +1711,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
-   int pipe_bpp;
int ret;
 
pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
@@ -1717,28 +1722,37 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
return -EINVAL;
 
-   if (intel_dp->force_dsc_bpc && compute_pipe_bpp) {
-   pipe_bpp = intel_dp->force_dsc_bpc * 3;
-   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to %d\n",
-   intel_dp->force_dsc_bpc);
-   } else if (compute_pipe_bpp) {
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, 
conn_state->max_requested_bpc);
-   } else {
-   pipe_bpp = pipe_config->pipe_bpp;
-   }
+   if (compute_pipe_bpp) {
+   int pipe_bpp;
+   int forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (pipe_bpp < intel_dp_dsc_min_src_input_bpc(dev_priv) * 3) {
-   drm_dbg_kms(_priv->drm,
-   "Computed BPC less than min supported by source for 
DSC\n");
-   return -EINVAL;
+   if (forced_bpp && is_dsc_pipe_bpp_sufficient(dev_priv, 
forced_bpp)) {
+   pipe_bpp = forced_bpp;
+   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to 
%d\n",
+   intel_dp->force_dsc_bpc);
+   } else {
+   drm_WARN(_priv->drm, forced_bpp,
+"Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+intel_dp->force_dsc_bpc);
+
+   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
+   drm_dbg_kms(_priv->drm,
+   "Computed BPC less than min 
supported by source for DSC\n");
+   return -EINVAL;
+   }
+   }
+
+   pipe_config->pipe_bpp = pipe_bpp;
}
 
/*
-* For now enable DSC for max bpp, max link rate, max lane count.
+* For now enable DSC for max link rate, max lane count.
 * Optimize this later for the minimum possible link rate/lane count
 * with DSC enabled for the requested mode.
 */
-   pipe_config->pipe_bpp = pipe_bpp;
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
 
@@ -1767,7 +1781,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,

pipe_config->output_format,
-   pipe_bpp,
+   
pipe_config->pipe_bpp,
timeslots);
if (!dsc_max_compressed_bpp) {
drm_dbg_kms(_priv->drm,
-- 
2.40.1



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

2023-08-10 Thread Ankit Nautiyal
Separate out functions for getting maximum and minimum input BPC based
on platforms, when DSC is used.

v2: Use HAS_DSC macro instead of platform check while getting min input
bpc. (Stan)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c13efd0b7c98..b414d09b5e80 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,13 @@ 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 */
+   return HAS_DSC(i915) ? 8 : 0;
+}
+
 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 +1727,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(_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



[PATCH 07/20] drm/i915/dp: Remove extra logs for printing DSC info

2023-08-10 Thread Ankit Nautiyal
DSC compressed bpp and slice counts are already getting printed at the
end of dsc compute config. Remove extra logs.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index fc08fc85d665..6bded67d986d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1782,9 +1782,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
-   drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count 
%d\n",
-   pipe_config->dsc.compressed_bpp,
-   pipe_config->dsc.slice_count);
}
/*
 * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
-- 
2.40.1



[PATCH 02/20] drm/i915/dp: Move compressed bpp check with 420 format inside the helper

2023-08-10 Thread Ankit Nautiyal
Move the check for limiting compressed bite_per_pixel for 420,422
formats in the helper to compute bits_per_pixel.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f138dfa5a2a2..6bb8fa4a3c96 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -773,6 +773,15 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
bits_per_pixel *= 2;
 
+   /*
+* 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 for 420, 422 formats, bpp should be programmed double
+* the target bpp restricting our target bpp to be 31.9375 at max.
+*/
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   bits_per_pixel = min_t(u32, bits_per_pixel, 31);
+
drm_dbg_kms(>drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
@@ -1738,15 +1747,6 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,

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_output_bpp = min_t(u16, 
dsc_max_output_bpp, 31 << 4);
-
if (!dsc_max_output_bpp) {
drm_dbg_kms(_priv->drm,
"Compressed BPP not supported\n");
-- 
2.40.1



[PATCH 01/20] drm/i915/dp: Consider output_format while computing dsc bpp

2023-08-10 Thread Ankit Nautiyal
While using DSC the compressed bpp is computed assuming RGB output
format. Consider the output_format and compute the compressed bpp
during mode valid and compute config steps.

For DP-MST we currently use RGB output format only, so continue
using RGB while computing compressed bpp for MST case.

v2: Use output_bpp instead for pipe_bpp to clamp compressed_bpp. (Ville)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 12bd2f322e62..f138dfa5a2a2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -744,6 +744,7 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
bool bigjoiner,
+   enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots)
 {
@@ -768,6 +769,10 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
bits_per_pixel = ((link_clock * lane_count) * timeslots) /
 (intel_dp_mode_to_fec_clock(mode_clock) * 8);
 
+   /* Bandwidth required for 420 is half, that of 444 format */
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   bits_per_pixel *= 2;
+
drm_dbg_kms(>drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
@@ -1161,11 +1166,16 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 
if (HAS_DSC(dev_priv) &&
drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
+   enum intel_output_format sink_format, output_format;
+   int pipe_bpp;
+
+   sink_format = intel_dp_sink_format(connector, mode);
+   output_format = intel_dp_output_format(connector, sink_format);
/*
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
 
/*
 * Output bpp is stored in 6.4 format so right shift by 4 to 
get the
@@ -1185,6 +1195,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock,
mode->hdisplay,
bigjoiner,
+   output_format,
pipe_bpp, 64) >> 4;
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
@@ -1724,6 +1735,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,

adjusted_mode->crtc_clock,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,
+   
pipe_config->output_format,
pipe_bpp,
timeslots);
/*
@@ -1759,9 +1771,12 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
 * calculation procedure is bit different for MST case.
 */
if (compute_pipe_bpp) {
+   u16 output_bpp = 
intel_dp_output_bpp(pipe_config->output_format,
+
pipe_config->pipe_bpp);
+
pipe_config->dsc.compressed_bpp = min_t(u16,

dsc_max_output_bpp >> 4,
-   
pipe_config->pipe_bpp);
+   output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count 
%d\n",
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
in

[PATCH 00/20] DSC misc fixes

2023-08-10 Thread Ankit Nautiyal
This series is an attempt to address multiple issues with DSC,
scattered in separate existing series.

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(-)

-- 
2.40.1



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

2023-08-08 Thread Ankit Nautiyal
Separate out functions for getting maximum and minimum input BPC based
on platforms, when DSC is used.

v2: Use HAS_DSC macro instead of platform check while getting min input
bpc. (Stan)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c13efd0b7c98..b414d09b5e80 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,13 @@ 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 */
+   return HAS_DSC(i915) ? 8 : 0;
+}
+
 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 +1727,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(_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



[PATCH 09/20] drm/i915/dp: Avoid forcing DSC BPC for MST case

2023-07-27 Thread Ankit Nautiyal
For MST the bpc is hardcoded to 8, and pipe bpp to 24.
So avoid forcing DSC bpc for MST case.

v2: Warn and ignore the debug flag than to bail out. (Jani)

v3: Fix dbg message to mention forced bpc instead of bpp.

v4: Fix checkpatch longline warning.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 12 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  5 +
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c5d2e6f538ed..7ec8a478e000 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1697,14 +1697,14 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
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(_priv->drm, "Input DSC BPC forced to %d\n",
+   intel_dp->force_dsc_bpc);
+   } 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(_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 1f00713fb1ad..dff4717edbd0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -361,6 +361,11 @@ static int intel_dp_mst_compute_config(struct 
intel_encoder *encoder,
/* enable compression if the mode doesn't fit available BW */
drm_dbg_kms(_priv->drm, "Force DSC en = %d\n", 
intel_dp->force_dsc_en);
if (ret || intel_dp->force_dsc_en) {
+   /*
+* FIXME: As bpc is hardcoded to 8, as mentioned above,
+* WARN and ignore the debug flag force_dsc_bpc for now.
+*/
+   drm_WARN(_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force 
BPC for MST\n");
/*
 * Try to get at least some timeslots and then see, if
 * we can fit there with DSC.
-- 
2.40.1



[PATCH 17/20] drm/i915/dp: Get optimal link config to have best compressed bpp

2023-07-27 Thread Ankit Nautiyal
Currently, we take the max lane, rate and pipe bpp, to get the maximum
compressed bpp possible. We then set the output bpp to this value.
This patch provides support to have max bpp, min rate and min lanes,
that can support the min compressed bpp.

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.

v5:
-Get rid of magic numbers for max and min bpp,
and improve documentation. (Stan).
-Use functions for {src_sink}_{min_max}_compressed_bpp (Ville).

v6:
-Remove lines to set link config to max.

v7:
-Split the part to separate edp and dp functions for computing DSC BPP
into separate patch.

v8:
-Separate mechanism to get compressed bpp for ICL,TGL and XELPD+.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 294 +---
 1 file changed, 261 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9720d32c6301..7e755bea919c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1689,6 +1689,231 @@ 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_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+   u32 lane_count, u32 mode_clock,
+   enum intel_output_format 
output_format,
+   int timeslots)
+{
+   u32 available_bw, required_bw;
+
+   available_bw = (link_clock * lane_count * timeslots)  / 8;
+   required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
+
+   return available_bw > required_bw;
+}
+
+static int dsc_compute_link_config(struct intel_dp *intel_dp,
+  struct intel_crtc_state *pipe_config,
+  struct link_config_limits *limits,
+  u16 compressed_bpp,
+  int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   int link_rate, lane_count;
+   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) {
+   if (!is_bw_sufficient_for_dsc_config(compressed_bpp, 
link_rate, lane_count,
+
adjusted_mode->clock,
+
pipe_config->output_format,
+timeslots))
+   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 *intel_dp,
+   struct intel_crtc_state 
*pipe_config,
+   int bpc)
+{
+   u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
+
+   if (max_bppx16)
+   return max_bppx16;
+   /*
+* If support not given in DPCD 67h, 68h use the Maximum Allowed bit 
rate
+* values as given in spec Table 2-157 DP v2.0
+*/
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return (3 * bpc) << 4;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return (3 * (bpc / 2)) << 4;
+   default:
+   MISSING_CASE(pipe_config->output_format);
+   break;
+   }
+
+   return 0;
+}
+
+static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+{
+   /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return 8;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return 6;
+   default:
+   MISSING_CASE(pipe_config->o

[PATCH 18/20] drm/i915: Query compressed bpp properly using correct DPCD and DP Spec info

2023-07-27 Thread Ankit Nautiyal
From: Stanislav Lisovskiy 

Currently we seem to be using wrong DPCD register for reading
compressed bpps, reading min/max input bpc instead of compressed bpp.
Fix that, so that we now apply min/max compressed bpp limitations we
get from DP Spec Table 2-157 DP v2.0 and/or correspondent DPCD
register DP_DSC_MAX_BITS_PER_PIXEL_LOW/HIGH.

This might also allow us to get rid of an ugly compressed bpp
recalculation, which we had to add to make some MST hubs usable.

v2: - Fix operator precedence
v3: - Added debug info about compressed bpps
v4: - Don't try to intersect Sink input bpp and compressed bpps.
v5: - Decrease step while looking for suitable compressed bpp to
  accommodate.
v6: - Use helper for getting min and max compressed_bpp (Ankit)
v7: - Fix checkpatch warning (Ankit)

Signed-off-by: Stanislav Lisovskiy 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 14 +++---
 drivers/gpu/drm/i915/display/intel_dp.h |  4 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 47 +
 3 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 7e755bea919c..9b71934e662e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1763,7 +1763,7 @@ u16 intel_dp_dsc_max_sink_compressed_bppx16(struct 
intel_dp *intel_dp,
return 0;
 }
 
-static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+int intel_dp_dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
 {
/* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
switch (pipe_config->output_format) {
@@ -1780,9 +1780,9 @@ static int dsc_sink_min_compressed_bpp(struct 
intel_crtc_state *pipe_config)
return 0;
 }
 
-static int dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
-  struct intel_crtc_state *pipe_config,
-  int bpc)
+int intel_dp_dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+int bpc)
 {
return intel_dp_dsc_max_sink_compressed_bppx16(intel_dp,
   pipe_config, bpc) >> 4;
@@ -1895,11 +1895,13 @@ static int dsc_compute_compressed_bpp(struct intel_dp 
*intel_dp,
int dsc_joiner_max_bpp;
 
dsc_src_min_bpp = dsc_src_min_compressed_bpp();
-   dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+   dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(pipe_config);
dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
 
dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
-   dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
pipe_bpp / 3);
+   dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(intel_dp,
+   pipe_config,
+   pipe_bpp / 3);
dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
: dsc_src_max_bpp;
 
dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, 
adjusted_mode->clock,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 788a577ebe16..f29e48028f39 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -114,6 +114,10 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots);
+int intel_dp_dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config);
+int intel_dp_dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+int bpc);
 u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
int mode_clock, int mode_hdisplay,
bool bigjoiner);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 3eb085fbc7c8..06a456517383 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -101,6 +101,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct 
intel_encoder *encoder,
  
crtc_state->lane_count);
}
 
+   drm_dbg_kms(>drm, "Looking for slots in range min bpp %d max bpp 
%d\n",
+   min_bpp, max_bpp);
+
for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
d

[PATCH 15/20] drm/i915/dp: Add DSC BPC/BPP constraints while selecting pipe bpp with DSC

2023-07-27 Thread Ankit Nautiyal
Currently we check if the pipe_bpp selected is >= the
min DSC bpc/bpp requirement. We do not check if it is <= the max DSC
bpc/bpp requirement.

Add checks for max DSC BPC/BPP constraints while computing the
pipe_bpp when DSC is in use.

v2: Fix the commit message.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c87c3836966c..b296db026fd8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1694,13 +1694,27 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
 }
 
 static
-bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits,
+   int pipe_bpp)
 {
-   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+   u8 dsc_max_bpc, dsc_min_bpc, dsc_max_pipe_bpp, dsc_min_pipe_bpp;
+
+   dsc_max_bpc = min(intel_dp_dsc_max_src_input_bpc(i915), 
conn_state->max_requested_bpc);
+   dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
+
+   dsc_max_pipe_bpp = min(dsc_max_bpc * 3, limits->max_bpp);
+   dsc_min_pipe_bpp = max(dsc_min_bpc * 3, limits->min_bpp);
+
+   return pipe_bpp >= dsc_min_pipe_bpp &&
+  pipe_bpp <= dsc_max_pipe_bpp;
 }
 
 static
-int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int forced_bpp;
@@ -1710,7 +1724,7 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
 
forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   if (is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, forced_bpp)) {
drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
return forced_bpp;
}
@@ -1732,16 +1746,16 @@ static int intel_dp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
u16 output_bpp, dsc_max_compressed_bpp = 0;
int forced_bpp, pipe_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
} else {
pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
 
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
@@ -1783,7 +1797,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int pipe_bpp, forced_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
@@ -1791,9 +1805,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
/* 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);
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
-- 
2.40.1



[PATCH 16/20] drm/i915/dp: Separate out function to get compressed bpp with joiner

2023-07-27 Thread Ankit Nautiyal
Pull the code to get joiner constraints on maximum compressed bpp into
separate function.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index b296db026fd8..9720d32c6301 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,6 +740,32 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private 
*i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
+static
+u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
+  u32 mode_clock, u32 mode_hdisplay,
+  bool bigjoiner)
+{
+   u32 max_bpp_small_joiner_ram;
+
+   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / 
mode_hdisplay;
+
+   if (bigjoiner) {
+   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
+   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
+   int ppc = 2;
+   u32 max_bpp_bigjoiner =
+   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
+   intel_dp_mode_to_fec_clock(mode_clock);
+
+   max_bpp_small_joiner_ram *= 2;
+
+   return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner);
+   }
+
+   return max_bpp_small_joiner_ram;
+}
+
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
@@ -748,7 +774,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
u32 pipe_bpp,
u32 timeslots)
 {
-   u32 bits_per_pixel, max_bpp_small_joiner_ram;
+   u32 bits_per_pixel, joiner_max_bpp;
 
/*
 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
@@ -788,29 +814,9 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
(link_clock * lane_count * 8),
intel_dp_mode_to_fec_clock(mode_clock));
 
-   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
-   mode_hdisplay;
-
-   if (bigjoiner)
-   max_bpp_small_joiner_ram *= 2;
-
-   /*
-* Greatest allowed DSC BPP = MIN (output BPP from available Link BW
-* check, output bpp from small joiner RAM check)
-*/
-   bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-   if (bigjoiner) {
-   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
-   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
-   int ppc = 2;
-   u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
-   intel_dp_mode_to_fec_clock(mode_clock);
-
-   bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
-   }
+   joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock,
+   mode_hdisplay, 
bigjoiner);
+   bits_per_pixel = min(bits_per_pixel, joiner_max_bpp);
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-- 
2.40.1



[PATCH 19/20] drm/i915/dp: Check src/sink compressed bpp limit for edp

2023-07-27 Thread Ankit Nautiyal
Use checks for src and sink limits before computing compressed bpp for
eDP.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9b71934e662e..0299b378ba6e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2032,6 +2032,8 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int pipe_bpp, forced_bpp;
+   int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
+   int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
 
forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
@@ -2049,9 +2051,21 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
}
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
-   pipe_config->dsc.compressed_bpp =
-   min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
- pipe_bpp);
+
+   dsc_src_min_bpp = dsc_src_min_compressed_bpp();
+   dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(pipe_config);
+   dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
+
+   dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
+   dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(intel_dp,
+   pipe_config,
+   pipe_bpp / 3);
+   dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
: dsc_src_max_bpp;
+
+   /* Compressed BPP should be less than the Input DSC bpp */
+   dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
+
+   pipe_config->dsc.compressed_bpp = max(dsc_min_bpp, dsc_max_bpp);
 
pipe_config->pipe_bpp = pipe_bpp;
 
-- 
2.40.1



[PATCH 20/20] drm/i915/dp: Check if force_dsc_output_format is possible

2023-07-27 Thread Ankit Nautiyal
Currently for testing an output format with DSC, we just force the
output format, without checking if it can be supported.
This also creates an issue where there is a PCON which might need to
convert from forced output format to the format to sink format.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0299b378ba6e..1aee27c0fb55 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -935,16 +935,42 @@ dfp_can_convert_from_ycbcr444(struct intel_dp *intel_dp,
return false;
 }
 
+static bool
+dfp_can_convert(struct intel_dp *intel_dp,
+   enum intel_output_format output_format,
+   enum intel_output_format sink_format)
+{
+   switch (output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   return dfp_can_convert_from_rgb(intel_dp, sink_format);
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return dfp_can_convert_from_ycbcr444(intel_dp, sink_format);
+   default:
+   MISSING_CASE(output_format);
+   return false;
+   }
+
+   return false;
+}
+
 static enum intel_output_format
 intel_dp_output_format(struct intel_connector *connector,
   enum intel_output_format sink_format)
 {
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   enum intel_output_format force_dsc_output_format =
+   intel_dp->force_dsc_output_format;
enum intel_output_format output_format;
+   if (force_dsc_output_format) {
+   if (source_can_output(intel_dp, force_dsc_output_format) &&
+   (!drm_dp_is_branch(intel_dp->dpcd) ||
+sink_format != force_dsc_output_format ||
+dfp_can_convert(intel_dp, force_dsc_output_format, 
sink_format)))
+   return force_dsc_output_format;
 
-   if (intel_dp->force_dsc_output_format)
-   return intel_dp->force_dsc_output_format;
+   drm_dbg_kms(>drm, "Cannot force DSC output format\n");
+   }
 
if (sink_format == INTEL_OUTPUT_FORMAT_RGB ||
dfp_can_convert_from_rgb(intel_dp, sink_format))
-- 
2.40.1



[PATCH 14/20] drm/i915/dp: Separate out functions for edp/DP for computing DSC bpp

2023-07-27 Thread Ankit Nautiyal
Refactor code to separate functions for eDP and DP for computing
pipe_bpp/compressed bpp when DSC is involved.

This will help to optimize the link configuration for DP later.

v2: Fix checkpatch warning.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 6228cfc44055..c87c3836966c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1699,6 +1699,115 @@ bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private 
*i915, int pipe_bpp)
return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
 }
 
+static
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int forced_bpp;
+
+   if (!intel_dp->force_dsc_bpc)
+   return 0;
+
+   forced_bpp = intel_dp->force_dsc_bpc * 3;
+
+   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
+   return forced_bpp;
+   }
+
+   drm_dbg_kms(>drm, "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+   intel_dp->force_dsc_bpc);
+
+   return 0;
+}
+
+static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+struct drm_connector_state *conn_state,
+struct link_config_limits *limits,
+int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   u16 output_bpp, dsc_max_compressed_bpp = 0;
+   int forced_bpp, pipe_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   drm_dbg_kms(>drm,
+   "Computed BPC less than min supported by 
source for DSC\n");
+   return -EINVAL;
+   }
+   }
+   /*
+* For now enable DSC for max link rate, max lane count.
+* Optimize this later for the minimum possible link rate/lane count
+* with DSC enabled for the requested mode.
+*/
+   pipe_config->port_clock = limits->max_rate;
+   pipe_config->lane_count = limits->max_lane_count;
+   dsc_max_compressed_bpp = intel_dp_dsc_get_max_compressed_bpp(i915,
+
pipe_config->port_clock,
+
pipe_config->lane_count,
+
adjusted_mode->crtc_clock,
+
adjusted_mode->crtc_hdisplay,
+
pipe_config->bigjoiner_pipes,
+
pipe_config->output_format,
+pipe_bpp,
+timeslots);
+   if (!dsc_max_compressed_bpp) {
+   drm_dbg_kms(>drm, "Compressed BPP not supported\n");
+   return -EINVAL;
+   }
+
+   output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp);
+
+   pipe_config->dsc.compressed_bpp = min_t(u16, dsc_max_compressed_bpp, 
output_bpp);
+
+   pipe_config->pipe_bpp = pipe_bpp;
+
+   return 0;
+}
+
+static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct drm_connector_state 
*conn_state,
+ struct link_config_limits *limits)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int pipe_bpp, forced_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   /* 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);
+   if (!is_dsc_pipe_bpp_suffic

[PATCH 08/20] drm/display/dp: Fix the DP DSC Receiver cap size

2023-07-27 Thread Ankit Nautiyal
DP DSC Receiver Capabilities are exposed via DPCD 60h-6Fh.
Fix the DSC RECEIVER CAP SIZE accordingly.

Fixes: ffddc4363c28 ("drm/dp: Add DP DSC DPCD receiver capability size define 
and missing SHIFT")
Cc: Anusha Srivatsa 
Cc: Manasi Navare 
Cc:  # v5.0+

Signed-off-by: Ankit Nautiyal 
---
 include/drm/display/drm_dp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 02f2ac4dd2df..e69cece404b3 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1537,7 +1537,7 @@ enum drm_dp_phy {
 
 #define DP_BRANCH_OUI_HEADER_SIZE  0xc
 #define DP_RECEIVER_CAP_SIZE   0xf
-#define DP_DSC_RECEIVER_CAP_SIZE0xf
+#define DP_DSC_RECEIVER_CAP_SIZE0x10 /* DSC Capabilities 0x60 through 
0x6F */
 #define EDP_PSR_RECEIVER_CAP_SIZE  2
 #define EDP_DISPLAY_CTL_CAP_SIZE   3
 #define DP_LTTPR_COMMON_CAP_SIZE   8
-- 
2.40.1



[PATCH 13/20] drm/i915/dp: Rename helper to get DSC max pipe_bpp

2023-07-27 Thread Ankit Nautiyal
The helper intel_dp_dsc_compute_bpp gives the maximum
pipe bpp that is allowed with DSC.

Rename the this to reflect that it returns max pipe bpp supported
with DSC.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 8 
 drivers/gpu/drm/i915/display/intel_dp.h | 2 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c1eb0d1e229e..6228cfc44055 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1183,7 +1183,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
/*
 * Output bpp is stored in 6.4 format so right shift by 4 to 
get the
@@ -1543,7 +1543,7 @@ u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private 
*i915)
return 0;
 }
 
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i, num_bpc;
@@ -1734,8 +1734,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
 intel_dp->force_dsc_bpc);
 
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
-   
conn_state->max_requested_bpc);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
 
if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
drm_dbg_kms(_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 6fd423463f5c..788a577ebe16 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -106,7 +106,7 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
   struct intel_crtc_state *crtc_state,
   unsigned int type);
 bool intel_digital_port_connected(struct intel_encoder *encoder);
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4895d6242915..3eb085fbc7c8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -971,7 +971,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
dsc_max_compressed_bpp =
-- 
2.40.1



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

2023-07-27 Thread Ankit Nautiyal
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;
+}
+
 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(_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



[PATCH 11/20] drm/i915/dp: Check min bpc DSC limits for dsc_force_bpc also

2023-07-27 Thread Ankit Nautiyal
For DSC the min BPC is 8 for ICL+ and so the min pipe_bpp is 24.
Check this condition for cases where bpc is forced by debugfs flag
dsc_force_bpc. If the check fails, then WARN and ignore the debugfs
flag.

For MST case the pipe_bpp is already computed (hardcoded to be 24),
and this check is not required.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index f41de126a8d3..78ac8f4fd348 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1697,6 +1697,12 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
return 0;
 }
 
+static
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+{
+   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+}
+
 int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
@@ -1708,7 +1714,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
-   int pipe_bpp;
int ret;
 
pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
@@ -1720,28 +1725,37 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
return -EINVAL;
 
-   if (intel_dp->force_dsc_bpc && compute_pipe_bpp) {
-   pipe_bpp = intel_dp->force_dsc_bpc * 3;
-   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to %d\n",
-   intel_dp->force_dsc_bpc);
-   } else if (compute_pipe_bpp) {
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, 
conn_state->max_requested_bpc);
-   } else {
-   pipe_bpp = pipe_config->pipe_bpp;
-   }
+   if (compute_pipe_bpp) {
+   int pipe_bpp;
+   int forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (pipe_bpp < intel_dp_dsc_min_src_input_bpc(dev_priv) * 3) {
-   drm_dbg_kms(_priv->drm,
-   "Computed BPC less than min supported by source for 
DSC\n");
-   return -EINVAL;
+   if (forced_bpp && is_dsc_pipe_bpp_sufficient(dev_priv, 
forced_bpp)) {
+   pipe_bpp = forced_bpp;
+   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to 
%d\n",
+   intel_dp->force_dsc_bpc);
+   } else {
+   drm_WARN(_priv->drm, forced_bpp,
+"Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+intel_dp->force_dsc_bpc);
+
+   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
+   drm_dbg_kms(_priv->drm,
+   "Computed BPC less than min 
supported by source for DSC\n");
+   return -EINVAL;
+   }
+   }
+
+   pipe_config->pipe_bpp = pipe_bpp;
}
 
/*
-* For now enable DSC for max bpp, max link rate, max lane count.
+* For now enable DSC for max link rate, max lane count.
 * Optimize this later for the minimum possible link rate/lane count
 * with DSC enabled for the requested mode.
 */
-   pipe_config->pipe_bpp = pipe_bpp;
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
 
@@ -1770,7 +1784,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,

pipe_config->output_format,
-   pipe_bpp,
+   
pipe_config->pipe_bpp,
timeslots);
if (!dsc_max_compressed_bpp) {
drm_dbg_kms(_priv->drm,
-- 
2.40.1



[PATCH 12/20] drm/i915/dp: Avoid left shift of DSC output bpp by 4

2023-07-27 Thread Ankit Nautiyal
To make way for fractional bpp support, avoid left shifting the
output_bpp by 4 in helper intel_dp_dsc_get_output_bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 10 +++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  2 +-
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 78ac8f4fd348..c1eb0d1e229e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -814,11 +814,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-   /*
-* Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-* fractional part is 0
-*/
-   return bits_per_pixel << 4;
+   return bits_per_pixel;
 }
 
 u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
@@ -1208,7 +1204,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,

mode->hdisplay,
bigjoiner,

output_format,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1814,7 +1810,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 
pipe_config->pipe_bpp);
 
pipe_config->dsc.compressed_bpp = min_t(u16,
-   
dsc_max_compressed_bpp >> 4,
+   
dsc_max_compressed_bpp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index dff4717edbd0..4895d6242915 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -982,7 +982,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,

mode->hdisplay,
bigjoiner,

INTEL_OUTPUT_FORMAT_RGB,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
-- 
2.40.1



[PATCH 06/20] drm/i915/intel_cdclk: Add vdsc with bigjoiner constraints on min_cdlck

2023-07-27 Thread Ankit Nautiyal
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)

v3: Use helper to account for FEC overhead. (Stan)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 59 +-
 1 file changed, 45 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index dcc1f6941b60..0205368ebcb8 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -32,6 +32,7 @@
 #include "intel_cdclk.h"
 #include "intel_crtc.h"
 #include "intel_de.h"
+#include "intel_dp.h"
 #include "intel_display_types.h"
 #include "intel_mchbar_regs.h"
 #include "intel_pci_config.h"
@@ -2533,6 +2534,48 @@ 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 = 
intel_dp_mode_to_fec_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
+*/
+   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);
+
+   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 +2647,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));
 
/*
 * HACK. Currently for TGL/DG2 platforms we calculate
-- 
2.40.1



[PATCH 07/20] drm/i915/dp: Remove extra logs for printing DSC info

2023-07-27 Thread Ankit Nautiyal
DSC compressed bpp and slice counts are already getting printed at the
end of dsc compute config. Remove extra logs.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c80744e7ecdf..c5d2e6f538ed 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1782,9 +1782,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
-   drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count 
%d\n",
-   pipe_config->dsc.compressed_bpp,
-   pipe_config->dsc.slice_count);
}
/*
 * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
-- 
2.40.1



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

2023-07-27 Thread Ankit Nautiyal
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)

v5: Added note for 2 PPC. (Stan)

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 5 -
 1 file changed, 4 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..c80744e7ecdf 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -802,8 +802,11 @@ 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;
+   /* With bigjoiner multiple dsc engines are used in parallel so 
PPC is 2 */
+   int ppc = 2;
u32 max_bpp_bigjoiner =
-   i915->display.cdclk.max_cdclk_freq * 48 /
+   i915->display.cdclk.max_cdclk_freq * ppc * 
bigjoiner_interface_bits /
intel_dp_mode_to_fec_clock(mode_clock);
 
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
-- 
2.40.1



[PATCH 03/20] drm/i915/dp_mst: Use output_format to get the final link bpp

2023-07-27 Thread Ankit Nautiyal
The final link bpp used to calculate the m_n values depend on the
output_format. Though the output_format is set to RGB for MST case and
the link bpp will be same as the pipe bpp, for the sake of semantics,
lets calculate the m_n values with the link bpp, instead of pipe_bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
 drivers/gpu/drm/i915/display/intel_dp.h | 1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 -
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index d1db457fb17c..eb158efdb414 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -965,7 +965,7 @@ int intel_dp_min_bpp(enum intel_output_format output_format)
return 8 * 3;
 }
 
-static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
 {
/*
 * bpp value was assumed to RGB format. And YCbCr 4:2:0 output
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index bb4f976af296..7dd015385054 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -144,5 +144,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
 void intel_dp_phy_test(struct intel_encoder *encoder);
 
 void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
 
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index aa8d9d570626..ef5375eb923e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -155,6 +155,7 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
const struct drm_display_mode *adjusted_mode =
_state->hw.adjusted_mode;
int slots = -EINVAL;
+   int link_bpp;
 
slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, 
limits->max_bpp,
 limits->min_bpp, limits,
@@ -163,7 +164,9 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
if (slots < 0)
return slots;
 
-   intel_link_compute_m_n(crtc_state->pipe_bpp,
+   link_bpp = intel_dp_output_bpp(crtc_state->output_format, 
crtc_state->pipe_bpp);
+
+   intel_link_compute_m_n(link_bpp,
   crtc_state->lane_count,
   adjusted_mode->crtc_clock,
   crtc_state->port_clock,
-- 
2.40.1



[PATCH 04/20] drm/i915/dp: Use consistent name for link bpp and compressed bpp

2023-07-27 Thread Ankit Nautiyal
Currently there are many places where we use output_bpp for link bpp and
compressed bpp.
Lets use consistent naming:
output_bpp : The intermediate value taking into account the
output_format chroma subsampling.
compressed_bpp : target bpp for the DSC encoder.
link_bpp : final bpp used in the link.

For 444 sampling without DSC:
link_bpp = output_bpp = pipe_bpp

For 420 sampling without DSC:
output_bpp = pipe_bpp / 2
link_bpp = output_bpp

For 444 sampling with DSC:
output_bpp = pipe_bpp
link_bpp = compressed_bpp, computed with output_bpp (i.e. pipe_bpp in
this case)

For 420 sampling with DSC:
output_bpp = pipe_bpp/2
link_bpp = compressed_bpp, computed with output_bpp

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 84 ++---
 drivers/gpu/drm/i915/display/intel_dp.h | 14 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 22 +++---
 3 files changed, 60 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index eb158efdb414..19768ac658ba 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,13 +740,13 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct 
drm_i915_private *i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
-u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
-   u32 link_clock, u32 lane_count,
-   u32 mode_clock, u32 mode_hdisplay,
-   bool bigjoiner,
-   enum intel_output_format output_format,
-   u32 pipe_bpp,
-   u32 timeslots)
+u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
+   u32 link_clock, u32 lane_count,
+   u32 mode_clock, u32 mode_hdisplay,
+   bool bigjoiner,
+   enum intel_output_format output_format,
+   u32 pipe_bpp,
+   u32 timeslots)
 {
u32 bits_per_pixel, max_bpp_small_joiner_ram;
 
@@ -1136,7 +1136,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
int target_clock = mode->clock;
int max_rate, mode_rate, max_lanes, max_link_clock;
int max_dotclk = dev_priv->max_dotclk_freq;
-   u16 dsc_max_output_bpp = 0;
+   u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
enum drm_mode_status status;
bool dsc = false, bigjoiner = false;
@@ -1191,21 +1191,21 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * integer value since we support only integer values of bpp.
 */
if (intel_dp_is_edp(intel_dp)) {
-   dsc_max_output_bpp =
+   dsc_max_compressed_bpp =
drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) 
>> 4;
dsc_slice_count =

drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
true);
} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
-   dsc_max_output_bpp =
-   intel_dp_dsc_get_output_bpp(dev_priv,
-   max_link_clock,
-   max_lanes,
-   target_clock,
-   mode->hdisplay,
-   bigjoiner,
-   output_format,
-   pipe_bpp, 64) >> 4;
+   dsc_max_compressed_bpp =
+   intel_dp_dsc_get_max_compressed_bpp(dev_priv,
+   
max_link_clock,
+   max_lanes,
+   
target_clock,
+   
mode->hdisplay,
+   bigjoiner,
+   
output_format,
+   pipe_bpp, 
64) >> 4;
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1213,7 +1213,7 @@ intel_dp_mode

[PATCH 02/20] drm/i915/dp: Move compressed bpp check with 420 format inside the helper

2023-07-27 Thread Ankit Nautiyal
Move the check for limiting compressed bite_per_pixel for 420,422
formats in the helper to compute bits_per_pixel.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index e0d9618fccab..d1db457fb17c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -773,6 +773,15 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
bits_per_pixel *= 2;
 
+   /*
+* 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 for 420, 422 formats, bpp should be programmed double
+* the target bpp restricting our target bpp to be 31.9375 at max.
+*/
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   bits_per_pixel = min_t(u32, bits_per_pixel, 31);
+
drm_dbg_kms(>drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
@@ -1738,15 +1747,6 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,

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_output_bpp = min_t(u16, 
dsc_max_output_bpp, 31 << 4);
-
if (!dsc_max_output_bpp) {
drm_dbg_kms(_priv->drm,
"Compressed BPP not supported\n");
-- 
2.40.1



[PATCH 01/20] drm/i915/dp: Consider output_format while computing dsc bpp

2023-07-27 Thread Ankit Nautiyal
While using DSC the compressed bpp is computed assuming RGB output
format. Consider the output_format and compute the compressed bpp
during mode valid and compute config steps.

For DP-MST we currently use RGB output format only, so continue
using RGB while computing compressed bpp for MST case.

v2: Use output_bpp instead for pipe_bpp to clamp compressed_bpp. (Ville)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 03675620e3ea..e0d9618fccab 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -744,6 +744,7 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
bool bigjoiner,
+   enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots)
 {
@@ -768,6 +769,10 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
bits_per_pixel = ((link_clock * lane_count) * timeslots) /
 (intel_dp_mode_to_fec_clock(mode_clock) * 8);
 
+   /* Bandwidth required for 420 is half, that of 444 format */
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   bits_per_pixel *= 2;
+
drm_dbg_kms(>drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
@@ -1161,11 +1166,16 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 
if (HAS_DSC(dev_priv) &&
drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
+   enum intel_output_format sink_format, output_format;
+   int pipe_bpp;
+
+   sink_format = intel_dp_sink_format(connector, mode);
+   output_format = intel_dp_output_format(connector, sink_format);
/*
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
 
/*
 * Output bpp is stored in 6.4 format so right shift by 4 to 
get the
@@ -1185,6 +1195,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock,
mode->hdisplay,
bigjoiner,
+   output_format,
pipe_bpp, 64) >> 4;
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
@@ -1724,6 +1735,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,

adjusted_mode->crtc_clock,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,
+   
pipe_config->output_format,
pipe_bpp,
timeslots);
/*
@@ -1759,9 +1771,12 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
 * calculation procedure is bit different for MST case.
 */
if (compute_pipe_bpp) {
+   u16 output_bpp = 
intel_dp_output_bpp(pipe_config->output_format,
+
pipe_config->pipe_bpp);
+
pipe_config->dsc.compressed_bpp = min_t(u16,

dsc_max_output_bpp >> 4,
-   
pipe_config->pipe_bpp);
+   output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count 
%d\n",
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
in

[PATCH 00/20] DSC misc fixes

2023-07-27 Thread Ankit Nautiyal
This series is an attempt to address multiple issues with DSC,
scattered in separate existing series.

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 18 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.

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 | 658 
 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, 628 insertions(+), 191 deletions(-)

-- 
2.40.1



[PATCH 19/19] drm/i915: Query compressed bpp properly using correct DPCD and DP Spec info

2023-07-13 Thread Ankit Nautiyal
From: Stanislav Lisovskiy 

Currently we seem to be using wrong DPCD register for reading
compressed bpps, reading min/max input bpc instead of compressed bpp.
Fix that, so that we now apply min/max compressed bpp limitations we
get from DP Spec Table 2-157 DP v2.0 and/or correspondent DPCD
register DP_DSC_MAX_BITS_PER_PIXEL_LOW/HIGH.

This might also allow us to get rid of an ugly compressed bpp
recalculation, which we had to add to make some MST hubs usable.

v2: - Fix operator precedence
v3: - Added debug info about compressed bpps
v4: - Don't try to intersect Sink input bpp and compressed bpps.
v5: - Decrease step while looking for suitable compressed bpp to
  accommodate.
v6: - Use helper for getting min and max compressed_bpp (Ankit)
v7: - Fix checkpatch warning (Ankit)

Signed-off-by: Stanislav Lisovskiy 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 14 +++---
 drivers/gpu/drm/i915/display/intel_dp.h |  4 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 47 +
 3 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 25a6c162332f..ce8b28ca1cfa 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1762,7 +1762,7 @@ u16 intel_dp_dsc_max_sink_compressed_bppx16(struct 
intel_dp *intel_dp,
return 0;
 }
 
-static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+int intel_dp_dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
 {
/* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
switch (pipe_config->output_format) {
@@ -1779,9 +1779,9 @@ static int dsc_sink_min_compressed_bpp(struct 
intel_crtc_state *pipe_config)
return 0;
 }
 
-static int dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
-  struct intel_crtc_state *pipe_config,
-  int bpc)
+int intel_dp_dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+int bpc)
 {
return intel_dp_dsc_max_sink_compressed_bppx16(intel_dp,
   pipe_config, bpc) >> 4;
@@ -1894,11 +1894,13 @@ static int dsc_compute_compressed_bpp(struct intel_dp 
*intel_dp,
int dsc_joiner_max_bpp;
 
dsc_src_min_bpp = dsc_src_min_compressed_bpp();
-   dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
+   dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(pipe_config);
dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
 
dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
-   dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
pipe_bpp / 3);
+   dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(intel_dp,
+   pipe_config,
+   pipe_bpp / 3);
dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
: dsc_src_max_bpp;
 
dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, 
adjusted_mode->clock,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 788a577ebe16..f29e48028f39 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -114,6 +114,10 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
enum intel_output_format output_format,
u32 pipe_bpp,
u32 timeslots);
+int intel_dp_dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config);
+int intel_dp_dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+int bpc);
 u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
int mode_clock, int mode_hdisplay,
bool bigjoiner);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 3eb085fbc7c8..06a456517383 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -101,6 +101,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct 
intel_encoder *encoder,
  
crtc_state->lane_count);
}
 
+   drm_dbg_kms(>drm, "Looking for slots in range min bpp %d max bpp 
%d\n",
+   min_bpp, max_bpp);
+
for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
d

[PATCH 17/19] drm/i915/dp: Separate out function to get compressed bpp with joiner

2023-07-13 Thread Ankit Nautiyal
Pull the code to get joiner constraints on maximum compressed bpp into
separate function.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c39039e214ff..54fc60eb94a0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,6 +740,30 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private 
*i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
+static
+u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
+  u32 mode_clock, u32 mode_hdisplay,
+  bool bigjoiner)
+{
+   u32 max_bpp_small_joiner_ram;
+
+   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / 
mode_hdisplay;
+
+   if (bigjoiner) {
+   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
+   u32 max_bpp_bigjoiner =
+   i915->display.cdclk.max_cdclk_freq * 2 * 
bigjoiner_interface_bits /
+   intel_dp_mode_to_fec_clock(mode_clock);
+
+   max_bpp_small_joiner_ram *= 2;
+
+   return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner);
+   }
+
+   return max_bpp_small_joiner_ram;
+}
+
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
@@ -748,7 +772,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
u32 pipe_bpp,
u32 timeslots)
 {
-   u32 bits_per_pixel, max_bpp_small_joiner_ram;
+   u32 bits_per_pixel, joiner_max_bpp;
 
/*
 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
@@ -788,27 +812,10 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
(link_clock * lane_count * 8),
intel_dp_mode_to_fec_clock(mode_clock));
 
-   /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-   max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
-   mode_hdisplay;
-
-   if (bigjoiner)
-   max_bpp_small_joiner_ram *= 2;
-
-   /*
-* Greatest allowed DSC BPP = MIN (output BPP from available Link BW
-* check, output bpp from small joiner RAM check)
-*/
-   bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
+   joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock,
+   mode_hdisplay, 
bigjoiner);
 
-   if (bigjoiner) {
-   int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 
24;
-   u32 max_bpp_bigjoiner =
-   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);
-   }
+   bits_per_pixel = min(bits_per_pixel, joiner_max_bpp);
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-- 
2.40.1



[PATCH 16/19] drm/i915/dp: Add DSC BPC/BPP constraints while selecting pipe bpp with DSC

2023-07-13 Thread Ankit Nautiyal
Currently we check if the pipe_bpp selected is >= the
min DSC bpc/bpp requirement. We do not check if it is <= the max DSC
bpc/bpp requirement.

Add checks for max DSC BPC/BPP constraints while computing the
pipe_bpp when DSC is in use.

v2: Fix the commit message.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c925cae40c49..c39039e214ff 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1692,13 +1692,27 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
 }
 
 static
-bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits,
+   int pipe_bpp)
 {
-   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+   u8 dsc_max_bpc, dsc_min_bpc, dsc_max_pipe_bpp, dsc_min_pipe_bpp;
+
+   dsc_max_bpc = min(intel_dp_dsc_max_src_input_bpc(i915), 
conn_state->max_requested_bpc);
+   dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
+
+   dsc_max_pipe_bpp = min(dsc_max_bpc * 3, limits->max_bpp);
+   dsc_min_pipe_bpp = max(dsc_min_bpc * 3, limits->min_bpp);
+
+   return pipe_bpp >= dsc_min_pipe_bpp &&
+  pipe_bpp <= dsc_max_pipe_bpp;
 }
 
 static
-int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
+   struct drm_connector_state *conn_state,
+   struct link_config_limits *limits)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int forced_bpp;
@@ -1708,7 +1722,7 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
 
forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   if (is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, forced_bpp)) {
drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
return forced_bpp;
}
@@ -1730,16 +1744,16 @@ static int intel_dp_dsc_compute_pipe_bpp(struct 
intel_dp *intel_dp,
u16 output_bpp, dsc_max_compressed_bpp = 0;
int forced_bpp, pipe_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
} else {
pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
 
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
@@ -1781,7 +1795,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int pipe_bpp, forced_bpp;
 
-   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
 
if (forced_bpp) {
pipe_bpp = forced_bpp;
@@ -1789,9 +1803,9 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp 
*intel_dp,
/* 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);
-   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
pipe_bpp)) {
drm_dbg_kms(>drm,
-   "Computed BPC less than min supported by 
source for DSC\n");
+   "Computed BPC is not in DSC BPC limits\n");
return -EINVAL;
}
}
-- 
2.40.1



[PATCH 18/19] drm/i915/dp: Get optimal link config to have best compressed bpp

2023-07-13 Thread Ankit Nautiyal
Currently, we take the max lane, rate and pipe bpp, to get the maximum
compressed bpp possible. We then set the output bpp to this value.
This patch provides support to have max bpp, min rate and min lanes,
that can support the min compressed bpp.

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.

v5:
-Get rid of magic numbers for max and min bpp,
and improve documentation. (Stan).
-Use functions for {src_sink}_{min_max}_compressed_bpp (Ville).

v6:
-Remove lines to set link config to max.

v7:
-Split the part to separate edp and dp functions for computing DSC BPP
into separate patch.

v8:
-Separate mechanism to get compressed bpp for ICL,TGL and XELPD+.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Stanislav Lisovskiy 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 294 +---
 1 file changed, 261 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 54fc60eb94a0..25a6c162332f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1688,6 +1688,231 @@ 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_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
+   u32 lane_count, u32 mode_clock,
+   enum intel_output_format 
output_format,
+   int timeslots)
+{
+   u32 available_bw, required_bw;
+
+   available_bw = (link_clock * lane_count * timeslots)  / 8;
+   required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
+
+   return available_bw > required_bw;
+}
+
+static int dsc_compute_link_config(struct intel_dp *intel_dp,
+  struct intel_crtc_state *pipe_config,
+  struct link_config_limits *limits,
+  u16 compressed_bpp,
+  int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   int link_rate, lane_count;
+   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) {
+   if (!is_bw_sufficient_for_dsc_config(compressed_bpp, 
link_rate, lane_count,
+
adjusted_mode->clock,
+
pipe_config->output_format,
+timeslots))
+   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 *intel_dp,
+   struct intel_crtc_state 
*pipe_config,
+   int bpc)
+{
+   u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
+
+   if (max_bppx16)
+   return max_bppx16;
+   /*
+* If support not given in DPCD 67h, 68h use the Maximum Allowed bit 
rate
+* values as given in spec Table 2-157 DP v2.0
+*/
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return (3 * bpc) << 4;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return (3 * (bpc / 2)) << 4;
+   default:
+   MISSING_CASE(pipe_config->output_format);
+   break;
+   }
+
+   return 0;
+}
+
+static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
+{
+   /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
+   switch (pipe_config->output_format) {
+   case INTEL_OUTPUT_FORMAT_RGB:
+   case INTEL_OUTPUT_FORMAT_YCBCR444:
+   return 8;
+   case INTEL_OUTPUT_FORMAT_YCBCR420:
+   return 6;
+   default:
+   MISSING_CASE(pipe_config->o

[PATCH 14/19] drm/i915/dp: Rename helper to get DSC max pipe_bpp

2023-07-13 Thread Ankit Nautiyal
The helper intel_dp_dsc_compute_bpp gives the maximum
pipe bpp that is allowed with DSC.

Rename the this to reflect that it returns max pipe bpp supported
with DSC.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 8 
 drivers/gpu/drm/i915/display/intel_dp.h | 2 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index a7d58eb914c6..c437ec23698a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1181,7 +1181,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
/*
 * Output bpp is stored in 6.4 format so right shift by 4 to 
get the
@@ -1541,7 +1541,7 @@ u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private 
*i915)
return 0;
 }
 
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i, num_bpc;
@@ -1732,8 +1732,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
 intel_dp->force_dsc_bpc);
 
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
-   
conn_state->max_requested_bpc);
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
 
if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
drm_dbg_kms(_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 6fd423463f5c..788a577ebe16 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -106,7 +106,7 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
   struct intel_crtc_state *crtc_state,
   unsigned int type);
 bool intel_digital_port_connected(struct intel_encoder *encoder);
-int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
+int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
 u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4895d6242915..3eb085fbc7c8 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -971,7 +971,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 * TBD pass the connector BPC,
 * for now U8_MAX so that max BPC on that platform would be 
picked
 */
-   int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
+   int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
 
if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
dsc_max_compressed_bpp =
-- 
2.40.1



[PATCH 10/19] drm/i915/dp: Avoid forcing DSC BPC for MST case

2023-07-13 Thread Ankit Nautiyal
For MST the bpc is hardcoded to 8, and pipe bpp to 24.
So avoid forcing DSC bpc for MST case.

v2: Warn and ignore the debug flag than to bail out. (Jani)

v3: Fix dbg message to mention forced bpc instead of bpp.

v4: Fix checkpatch longline warning.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 12 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  5 +
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 23ede846202c..11e54e6ee985 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1695,14 +1695,14 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
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(_priv->drm, "Input DSC BPC forced to %d\n",
+   intel_dp->force_dsc_bpc);
+   } 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(_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 1f00713fb1ad..dff4717edbd0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -361,6 +361,11 @@ static int intel_dp_mst_compute_config(struct 
intel_encoder *encoder,
/* enable compression if the mode doesn't fit available BW */
drm_dbg_kms(_priv->drm, "Force DSC en = %d\n", 
intel_dp->force_dsc_en);
if (ret || intel_dp->force_dsc_en) {
+   /*
+* FIXME: As bpc is hardcoded to 8, as mentioned above,
+* WARN and ignore the debug flag force_dsc_bpc for now.
+*/
+   drm_WARN(_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force 
BPC for MST\n");
/*
 * Try to get at least some timeslots and then see, if
 * we can fit there with DSC.
-- 
2.40.1



[PATCH 13/19] drm/i915/dp: Avoid left shift of DSC output bpp by 4

2023-07-13 Thread Ankit Nautiyal
To make way for fractional bpp support, avoid left shifting the
output_bpp by 4 in helper intel_dp_dsc_get_output_bpp.

Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 10 +++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  2 +-
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9d2d05da594b..a7d58eb914c6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -812,11 +812,7 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct 
drm_i915_private *i915,
 
bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, 
pipe_bpp);
 
-   /*
-* Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-* fractional part is 0
-*/
-   return bits_per_pixel << 4;
+   return bits_per_pixel;
 }
 
 u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
@@ -1206,7 +1202,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,

mode->hdisplay,
bigjoiner,

output_format,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1812,7 +1808,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 
pipe_config->pipe_bpp);
 
pipe_config->dsc.compressed_bpp = min_t(u16,
-   
dsc_max_compressed_bpp >> 4,
+   
dsc_max_compressed_bpp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index dff4717edbd0..4895d6242915 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -982,7 +982,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,

mode->hdisplay,
bigjoiner,

INTEL_OUTPUT_FORMAT_RGB,
-   pipe_bpp, 
64) >> 4;
+   pipe_bpp, 
64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
-- 
2.40.1



[PATCH 15/19] drm/i915/dp: Separate out functions for edp/DP for computing DSC bpp

2023-07-13 Thread Ankit Nautiyal
Refactor code to separate functions for eDP and DP for computing
pipe_bpp/compressed bpp when DSC is involved.

This will help to optimize the link configuration for DP later.

v2: Fix checkpatch warning.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c437ec23698a..c925cae40c49 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1697,6 +1697,115 @@ bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private 
*i915, int pipe_bpp)
return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
 }
 
+static
+int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int forced_bpp;
+
+   if (!intel_dp->force_dsc_bpc)
+   return 0;
+
+   forced_bpp = intel_dp->force_dsc_bpc * 3;
+
+   if (is_dsc_pipe_bpp_sufficient(i915, forced_bpp)) {
+   drm_dbg_kms(>drm, "Input DSC BPC forced to %d\n", 
intel_dp->force_dsc_bpc);
+   return forced_bpp;
+   }
+
+   drm_dbg_kms(>drm, "Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+   intel_dp->force_dsc_bpc);
+
+   return 0;
+}
+
+static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+struct intel_crtc_state *pipe_config,
+struct drm_connector_state *conn_state,
+struct link_config_limits *limits,
+int timeslots)
+{
+   const struct drm_display_mode *adjusted_mode = 
_config->hw.adjusted_mode;
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   u16 output_bpp, dsc_max_compressed_bpp = 0;
+   int forced_bpp, pipe_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, 
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(i915, pipe_bpp)) {
+   drm_dbg_kms(>drm,
+   "Computed BPC less than min supported by 
source for DSC\n");
+   return -EINVAL;
+   }
+   }
+   /*
+* For now enable DSC for max link rate, max lane count.
+* Optimize this later for the minimum possible link rate/lane count
+* with DSC enabled for the requested mode.
+*/
+   pipe_config->port_clock = limits->max_rate;
+   pipe_config->lane_count = limits->max_lane_count;
+   dsc_max_compressed_bpp = intel_dp_dsc_get_max_compressed_bpp(i915,
+
pipe_config->port_clock,
+
pipe_config->lane_count,
+
adjusted_mode->crtc_clock,
+
adjusted_mode->crtc_hdisplay,
+
pipe_config->bigjoiner_pipes,
+
pipe_config->output_format,
+pipe_bpp,
+timeslots);
+   if (!dsc_max_compressed_bpp) {
+   drm_dbg_kms(>drm, "Compressed BPP not supported\n");
+   return -EINVAL;
+   }
+
+   output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp);
+
+   pipe_config->dsc.compressed_bpp = min_t(u16, dsc_max_compressed_bpp, 
output_bpp);
+
+   pipe_config->pipe_bpp = pipe_bpp;
+
+   return 0;
+}
+
+static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
+ struct intel_crtc_state *pipe_config,
+ struct drm_connector_state 
*conn_state,
+ struct link_config_limits *limits)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+   int pipe_bpp, forced_bpp;
+
+   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp);
+
+   if (forced_bpp) {
+   pipe_bpp = forced_bpp;
+   } else {
+   /* 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);
+   if (!is_dsc_pipe_bpp_suffic

[PATCH 12/19] drm/i915/dp: Check min bpc DSC limits for dsc_force_bpc also

2023-07-13 Thread Ankit Nautiyal
For DSC the min BPC is 8 for ICL+ and so the min pipe_bpp is 24.
Check this condition for cases where bpc is forced by debugfs flag
dsc_force_bpc. If the check fails, then WARN and ignore the debugfs
flag.

For MST case the pipe_bpp is already computed (hardcoded to be 24),
and this check is not required.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 5cc62c51372d..9d2d05da594b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1695,6 +1695,12 @@ u8 intel_dp_dsc_min_src_input_bpc(struct 
drm_i915_private *i915)
return 0;
 }
 
+static
+bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915, int pipe_bpp)
+{
+   return pipe_bpp >= intel_dp_dsc_min_src_input_bpc(i915) * 3;
+}
+
 int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
@@ -1706,7 +1712,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
-   int pipe_bpp;
int ret;
 
pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
@@ -1718,28 +1723,37 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,
if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
return -EINVAL;
 
-   if (intel_dp->force_dsc_bpc && compute_pipe_bpp) {
-   pipe_bpp = intel_dp->force_dsc_bpc * 3;
-   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to %d\n",
-   intel_dp->force_dsc_bpc);
-   } else if (compute_pipe_bpp) {
-   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, 
conn_state->max_requested_bpc);
-   } else {
-   pipe_bpp = pipe_config->pipe_bpp;
-   }
+   if (compute_pipe_bpp) {
+   int pipe_bpp;
+   int forced_bpp = intel_dp->force_dsc_bpc * 3;
 
-   if (pipe_bpp < intel_dp_dsc_min_src_input_bpc(dev_priv) * 3) {
-   drm_dbg_kms(_priv->drm,
-   "Computed BPC less than min supported by source for 
DSC\n");
-   return -EINVAL;
+   if (forced_bpp && is_dsc_pipe_bpp_sufficient(dev_priv, 
forced_bpp)) {
+   pipe_bpp = forced_bpp;
+   drm_dbg_kms(_priv->drm, "Input DSC BPC forced to 
%d\n",
+   intel_dp->force_dsc_bpc);
+   } else {
+   drm_WARN(_priv->drm, forced_bpp,
+"Cannot force DSC BPC:%d, due to DSC BPC 
limits\n",
+intel_dp->force_dsc_bpc);
+
+   pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp,
+   
conn_state->max_requested_bpc);
+
+   if (!is_dsc_pipe_bpp_sufficient(dev_priv, pipe_bpp)) {
+   drm_dbg_kms(_priv->drm,
+   "Computed BPC less than min 
supported by source for DSC\n");
+   return -EINVAL;
+   }
+   }
+
+   pipe_config->pipe_bpp = pipe_bpp;
}
 
/*
-* For now enable DSC for max bpp, max link rate, max lane count.
+* For now enable DSC for max link rate, max lane count.
 * Optimize this later for the minimum possible link rate/lane count
 * with DSC enabled for the requested mode.
 */
-   pipe_config->pipe_bpp = pipe_bpp;
pipe_config->port_clock = limits->max_rate;
pipe_config->lane_count = limits->max_lane_count;
 
@@ -1768,7 +1782,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,

adjusted_mode->crtc_hdisplay,

pipe_config->bigjoiner_pipes,

pipe_config->output_format,
-   pipe_bpp,
+   
pipe_config->pipe_bpp,
timeslots);
if (!dsc_max_compressed_bpp) {
drm_dbg_kms(_priv->drm,
-- 
2.40.1



[PATCH 08/19] drm/i915/dp: Remove extra logs for printing DSC info

2023-07-13 Thread Ankit Nautiyal
DSC compressed bpp and slice counts are already getting printed at the
end of dsc compute config. Remove extra logs.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index c1fd448d80e1..23ede846202c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1780,9 +1780,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
output_bpp);
}
pipe_config->dsc.slice_count = dsc_dp_slice_count;
-   drm_dbg_kms(_priv->drm, "DSC: compressed bpp %d slice count 
%d\n",
-   pipe_config->dsc.compressed_bpp,
-   pipe_config->dsc.slice_count);
}
/*
 * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
-- 
2.40.1



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

2023-07-13 Thread Ankit Nautiyal
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.
+*/
+   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);
+
+   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));
 
/*
 * HACK. Currently for TGL/DG2 platforms we calculate
-- 
2.40.1



[PATCH 11/19] drm/i915/dp: Add functions to get min/max src input bpc with DSC

2023-07-13 Thread Ankit Nautiyal
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 11e54e6ee985..5cc62c51372d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1533,6 +1533,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);
@@ -1540,11 +1552,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);
@@ -1672,6 +1685,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;
+}
+
 int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state,
@@ -1705,10 +1728,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(_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



[PATCH 09/19] drm/display/dp: Fix the DP DSC Receiver cap size

2023-07-13 Thread Ankit Nautiyal
DP DSC Receiver Capabilities are exposed via DPCD 60h-6Fh.
Fix the DSC RECEIVER CAP SIZE accordingly.

Fixes: ffddc4363c28 ("drm/dp: Add DP DSC DPCD receiver capability size define 
and missing SHIFT")
Cc: Anusha Srivatsa 
Cc: Manasi Navare 
Cc:  # v5.0+

Signed-off-by: Ankit Nautiyal 
---
 include/drm/display/drm_dp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 02f2ac4dd2df..e69cece404b3 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -1537,7 +1537,7 @@ enum drm_dp_phy {
 
 #define DP_BRANCH_OUI_HEADER_SIZE  0xc
 #define DP_RECEIVER_CAP_SIZE   0xf
-#define DP_DSC_RECEIVER_CAP_SIZE0xf
+#define DP_DSC_RECEIVER_CAP_SIZE0x10 /* DSC Capabilities 0x60 through 
0x6F */
 #define EDP_PSR_RECEIVER_CAP_SIZE  2
 #define EDP_DISPLAY_CTL_CAP_SIZE   3
 #define DP_LTTPR_COMMON_CAP_SIZE   8
-- 
2.40.1



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

2023-07-13 Thread Ankit Nautiyal
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);
 }
 
 static void
-- 
2.40.1



[PATCH 04/19] drm/i915/dp: Use consistent name for link bpp and compressed bpp

2023-07-13 Thread Ankit Nautiyal
Currently there are many places where we use output_bpp for link bpp and
compressed bpp.
Lets use consistent naming:
output_bpp : The intermediate value taking into account the
output_format chroma subsampling.
compressed_bpp : target bpp for the DSC encoder.
link_bpp : final bpp used in the link.

For 444 sampling without DSC:
link_bpp = output_bpp = pipe_bpp

For 420 sampling without DSC:
output_bpp = pipe_bpp / 2
link_bpp = output_bpp

For 444 sampling with DSC:
output_bpp = pipe_bpp
link_bpp = compressed_bpp, computed with output_bpp (i.e. pipe_bpp in
this case)

For 420 sampling with DSC:
output_bpp = pipe_bpp/2
link_bpp = compressed_bpp, computed with output_bpp

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 84 ++---
 drivers/gpu/drm/i915/display/intel_dp.h | 14 ++--
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 22 +++---
 3 files changed, 60 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index eb158efdb414..19768ac658ba 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -740,13 +740,13 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct 
drm_i915_private *i915, u32 bpp, u32 p
return bits_per_pixel;
 }
 
-u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
-   u32 link_clock, u32 lane_count,
-   u32 mode_clock, u32 mode_hdisplay,
-   bool bigjoiner,
-   enum intel_output_format output_format,
-   u32 pipe_bpp,
-   u32 timeslots)
+u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
+   u32 link_clock, u32 lane_count,
+   u32 mode_clock, u32 mode_hdisplay,
+   bool bigjoiner,
+   enum intel_output_format output_format,
+   u32 pipe_bpp,
+   u32 timeslots)
 {
u32 bits_per_pixel, max_bpp_small_joiner_ram;
 
@@ -1136,7 +1136,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
int target_clock = mode->clock;
int max_rate, mode_rate, max_lanes, max_link_clock;
int max_dotclk = dev_priv->max_dotclk_freq;
-   u16 dsc_max_output_bpp = 0;
+   u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
enum drm_mode_status status;
bool dsc = false, bigjoiner = false;
@@ -1191,21 +1191,21 @@ intel_dp_mode_valid(struct drm_connector *_connector,
 * integer value since we support only integer values of bpp.
 */
if (intel_dp_is_edp(intel_dp)) {
-   dsc_max_output_bpp =
+   dsc_max_compressed_bpp =
drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) 
>> 4;
dsc_slice_count =

drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
true);
} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
-   dsc_max_output_bpp =
-   intel_dp_dsc_get_output_bpp(dev_priv,
-   max_link_clock,
-   max_lanes,
-   target_clock,
-   mode->hdisplay,
-   bigjoiner,
-   output_format,
-   pipe_bpp, 64) >> 4;
+   dsc_max_compressed_bpp =
+   intel_dp_dsc_get_max_compressed_bpp(dev_priv,
+   
max_link_clock,
+   max_lanes,
+   
target_clock,
+   
mode->hdisplay,
+   bigjoiner,
+   
output_format,
+   pipe_bpp, 
64) >> 4;
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp,
 target_clock,
@@ -1213,7 +1213,7 @@ intel_dp_mode

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

2023-07-13 Thread Ankit Nautiyal
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 /
intel_dp_mode_to_fec_clock(mode_clock);
 
bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
-- 
2.40.1



[PATCH 03/19] drm/i915/dp_mst: Use output_format to get the final link bpp

2023-07-13 Thread Ankit Nautiyal
The final link bpp used to calculate the m_n values depend on the
output_format. Though the output_format is set to RGB for MST case and
the link bpp will be same as the pipe bpp, for the sake of semantics,
lets calculate the m_n values with the link bpp, instead of pipe_bpp.

Signed-off-by: Ankit Nautiyal 
Reviewed-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 2 +-
 drivers/gpu/drm/i915/display/intel_dp.h | 1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 -
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index d1db457fb17c..eb158efdb414 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -965,7 +965,7 @@ int intel_dp_min_bpp(enum intel_output_format output_format)
return 8 * 3;
 }
 
-static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
 {
/*
 * bpp value was assumed to RGB format. And YCbCr 4:2:0 output
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index bb4f976af296..7dd015385054 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -144,5 +144,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
 void intel_dp_phy_test(struct intel_encoder *encoder);
 
 void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
+int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
 
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index aa8d9d570626..ef5375eb923e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -155,6 +155,7 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
const struct drm_display_mode *adjusted_mode =
_state->hw.adjusted_mode;
int slots = -EINVAL;
+   int link_bpp;
 
slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, 
limits->max_bpp,
 limits->min_bpp, limits,
@@ -163,7 +164,9 @@ static int intel_dp_mst_compute_link_config(struct 
intel_encoder *encoder,
if (slots < 0)
return slots;
 
-   intel_link_compute_m_n(crtc_state->pipe_bpp,
+   link_bpp = intel_dp_output_bpp(crtc_state->output_format, 
crtc_state->pipe_bpp);
+
+   intel_link_compute_m_n(link_bpp,
   crtc_state->lane_count,
   adjusted_mode->crtc_clock,
   crtc_state->port_clock,
-- 
2.40.1



[PATCH 02/19] drm/i915/dp: Move compressed bpp check with 420 format inside the helper

2023-07-13 Thread Ankit Nautiyal
Move the check for limiting compressed bite_per_pixel for 420,422
formats in the helper to compute bits_per_pixel.

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index e0d9618fccab..d1db457fb17c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -773,6 +773,15 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private 
*i915,
if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
bits_per_pixel *= 2;
 
+   /*
+* 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 for 420, 422 formats, bpp should be programmed double
+* the target bpp restricting our target bpp to be 31.9375 at max.
+*/
+   if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+   bits_per_pixel = min_t(u32, bits_per_pixel, 31);
+
drm_dbg_kms(>drm, "Max link bpp is %u for %u timeslots "
"total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
@@ -1738,15 +1747,6 @@ int intel_dp_dsc_compute_config(struct intel_dp 
*intel_dp,

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_output_bpp = min_t(u16, 
dsc_max_output_bpp, 31 << 4);
-
if (!dsc_max_output_bpp) {
drm_dbg_kms(_priv->drm,
"Compressed BPP not supported\n");
-- 
2.40.1



  1   2   3   4   >