Add accessor function for Combo to read requested table from VBT #57.
Parse the requested table and transform data into port's buffer.

For EHL, in cases when eDP encoder uses low vswing, choose 3rd table if
encoder supports HBR3. Otherwise use 2nd table for eDP using low vswing.

In cases when eDP encoder does not use low vswing, choose 2nd table if
encoder supports mode higher or including HBR2. Otherwise use 3rd table
for eDP not using low vswing.

For external DP use 2nd table if encoder supports modes higher than or
including HBR2. Use 1st table if external DP encoder supports modes
lower than HBR2.

For JSL, always use 1st table for external DP. For eDPs not using low
vswing use 1st table as well.

In cases when eDP encoder uses low vswing, choose 1st table if encoder
supports HBR3. When encoder supports HBR2 choose 3rd table. When
encoder supports modes lower than HBR2 choose 2nd table.

There are no changes to intel_ddi_dp_level() since selection of correct
row of intel_ddi_buf_trans_entry is same as when no override request has
been done.

Looking from other OSes, in case when encoder does not support DP we
could theoretically use 1st table. However, as of now, use default
tables.

v6->v7
- handle VS/PE-O's VBT details in intel_bios_* functions (Jani)
- remove vspeo's cast to (void *) (Jani)
- call encoder->get_buf_trans() once (Jani)
- return NULL from intel_bios_get_* when using default (Jani)
- validate VS/PE-O in intel_bios.c (Jani)
- check devdata->vspeo if VS/PE-O was requested
- inline {jsl,ehl}_combo_get_vspeo_buf_trans()
- remove temporarily LT

v4->v5
- blend index computation with table parsing
- remove enums entirely
- add spaces around operators (Suraj)
- remove spaces after type casting (Suraj)
- remove INTEL_DISPLAY_STATE_WARN (Suraj)

Signed-off-by: Michał Grzelak <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_bios.c     | 98 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_bios.h     |  6 ++
 .../drm/i915/display/intel_ddi_buf_trans.c    |  6 ++
 3 files changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c 
b/drivers/gpu/drm/i915/display/intel_bios.c
index 59ffb5bc8848..46766dfb8989 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -3961,6 +3961,104 @@ intel_bios_get_c10_vspeo(const struct 
intel_bios_encoder_data *devdata,
        return vspeo;
 }
 
+const struct intel_ddi_buf_trans *
+intel_bios_get_ehl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
+                              bool has_dp, int port_clock, bool has_edp)
+{
+       struct intel_display *display;
+       union intel_ddi_buf_trans_entry *entries;
+       int num_columns, num_rows, level, idx;
+       struct intel_ddi_buf_trans *vspeo;
+       const u32 *tables;
+       size_t offset = 0;
+
+       if (!validate_vspeo(devdata, has_dp))
+               return NULL;
+
+       display = devdata->display;
+       vspeo = devdata->vspeo;
+       entries = (void *)vspeo->entries;
+       tables = display->vbt.vspeo.tables;
+       num_columns = display->vbt.vspeo.num_columns;
+       num_rows = display->vbt.vspeo.num_rows;
+
+       idx = port_clock > 270000 ? 1 : 0;
+       if (has_edp)
+               idx = port_clock > 540000 ? 2 : 1;
+
+       offset += idx * num_rows * num_columns;
+
+       for (level = 0; level < num_rows; level++) {
+               u32 dw2_swing_sel = tables[offset];
+               u32 dw7_n_scalar = tables[offset + 1];
+               u32 dw4_cursor_coeff = tables[offset + 2];
+               u32 dw4_post_cursor_2 = tables[offset + 3];
+               u32 dw4_post_cursor_1 = tables[offset + 4];
+
+               entries[level].icl.dw2_swing_sel = dw2_swing_sel;
+               entries[level].icl.dw7_n_scalar = dw7_n_scalar;
+               entries[level].icl.dw4_cursor_coeff = dw4_cursor_coeff;
+               entries[level].icl.dw4_post_cursor_2 = dw4_post_cursor_2;
+               entries[level].icl.dw4_post_cursor_1 = dw4_post_cursor_1;
+
+               offset += num_columns;
+       }
+
+       return vspeo;
+}
+
+const struct intel_ddi_buf_trans *
+intel_bios_get_jsl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
+                              bool has_dp, int port_clock, bool low_vswing_edp)
+{
+       struct intel_display *display;
+       union intel_ddi_buf_trans_entry *entries;
+       int num_columns, num_rows, level, idx;
+       struct intel_ddi_buf_trans *vspeo;
+       const u32 *tables;
+       size_t offset = 0;
+
+       if (!validate_vspeo(devdata, has_dp))
+               return NULL;
+
+       display = devdata->display;
+       vspeo = devdata->vspeo;
+       entries = (void *)vspeo->entries;
+       tables = display->vbt.vspeo.tables;
+       num_columns = display->vbt.vspeo.num_columns;
+       num_rows = display->vbt.vspeo.num_rows;
+
+       idx = 0;
+       if (low_vswing_edp) {
+               if (port_clock > 540000)
+                       idx = 0;
+               else if (port_clock > 270000)
+                       idx = 1;
+               else
+                       idx = 2;
+       }
+
+       offset += idx * num_rows * num_columns;
+
+       for (level = 0; level < num_rows; level++) {
+               u32 dw2_swing_sel = tables[offset];
+               u32 dw7_n_scalar = tables[offset + 1];
+               u32 dw4_cursor_coeff = tables[offset + 2];
+               u32 dw4_post_cursor_2 = tables[offset + 3];
+               u32 dw4_post_cursor_1 = tables[offset + 4];
+
+               entries[level].icl.dw2_swing_sel = dw2_swing_sel;
+               entries[level].icl.dw7_n_scalar = dw7_n_scalar;
+               entries[level].icl.dw4_cursor_coeff = dw4_cursor_coeff;
+               entries[level].icl.dw4_post_cursor_2 = dw4_post_cursor_2;
+               entries[level].icl.dw4_post_cursor_1 = dw4_post_cursor_1;
+
+               offset += num_columns;
+       }
+
+       return vspeo;
+}
+
 bool intel_bios_encoder_is_dedicated_external(const struct 
intel_bios_encoder_data *devdata)
 {
        return devdata->display->vbt.version >= 264 &&
diff --git a/drivers/gpu/drm/i915/display/intel_bios.h 
b/drivers/gpu/drm/i915/display/intel_bios.h
index 49acf8c405e2..c55765a94594 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.h
+++ b/drivers/gpu/drm/i915/display/intel_bios.h
@@ -79,6 +79,12 @@ intel_bios_get_c20_vspeo(const struct 
intel_bios_encoder_data *devdata,
 const struct intel_ddi_buf_trans *
 intel_bios_get_c10_vspeo(const struct intel_bios_encoder_data *devdata,
                         bool has_dp, int port_clock, bool has_edp);
+const struct intel_ddi_buf_trans *
+intel_bios_get_ehl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
+                              bool has_dp, int port_clock, bool has_edp);
+const struct intel_ddi_buf_trans *
+intel_bios_get_jsl_combo_vspeo(const struct intel_bios_encoder_data *devdata,
+                              bool has_dp, int port_clock, bool 
low_vswing_edp);
 
 bool intel_bios_encoder_requests_vspeo(const struct intel_bios_encoder_data 
*devdata);
 bool intel_bios_encoder_supports_dvi(const struct intel_bios_encoder_data 
*devdata);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c 
b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index b4120b9c49b2..b62ce58b9bdc 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -1873,6 +1873,12 @@ const struct intel_ddi_buf_trans 
*intel_ddi_buf_trans_get(struct intel_encoder *
                        buf_trans = intel_bios_get_c10_vspeo(devdata, has_dp, 
port_clock, has_edp);
                else
                        buf_trans = intel_bios_get_c20_vspeo(devdata, has_dp, 
is_uhbr);
+       } else if (DISPLAY_VER(display) == 11) {
+               if (display->platform.jasperlake)
+                       buf_trans = intel_bios_get_jsl_combo_vspeo(devdata, 
has_dp, port_clock,
+                                                                  has_edp && 
use_edp_low_vswing(encoder));
+               else if (display->platform.elkhartlake)
+                       buf_trans = intel_bios_get_ehl_combo_vspeo(devdata, 
has_dp, port_clock, has_edp);
        }
 
        if (buf_trans)
-- 
2.45.2

Reply via email to