Add accessor function for LT to read requested table from VBT #57. Parse the requested table and transform data into port's buffer.
LT's VS/PE-O tables have less columns than xe3plpd_lt_phy_buf_trans contains fields. Thus copy txswing and txswing_level from default VS/PE values onto VS/PE-O tables. Use 6th table if encoder supports DP 2.0 or higher. Otherwise use 5th table for DP. 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. Tables 1-4 are not used at all and are most likely to be zeroed. 5th table is used for any mode below DP 2.0 (exclusive). 6th table is used for any mode above DP 2.0 (inclusive). Indices for other tables have not yet been observed to be used as of now. v6->v7 - handle VS/PE-O's VBT details in intel_bios_* functions (Jani) - remove vspeo's cast to (void *) (Jani) - check devdata->vspeo if VS/PE-O was requested - 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) - inline xe3plpd_lt_get_vspeo_buf_trans() - remove temporarily LT v5->v6 - remove drm_WARN_ONCE (Suraj) - pass default VS/PE tables to LT's VBT accessor (Suraj) - set txswing & _level from default VS/PE tables (Suraj) - add helper checking if VS/PE-O has been allocated (Suraj) - check if devdata is not NULL v4->v5 - add if-ladder instead of function pointer - blend index computation with table parsing - remove WARN and debug messages - remove enums entirely - add spaces around operators (Suraj) - remove spaces after type casting (Suraj) - remove INTEL_DISPLAY_STATE_WARN (Suraj) v3->v4 - stick to solely changing VBT data into current structures (Jani) - move iterator declaration to declaration block (Suraj) v2->v3 - remove unnecessary braces from if block (Suraj) - return -EINVAL instead of -1 (Suraj) Signed-off-by: Michał Grzelak <[email protected]> --- drivers/gpu/drm/i915/display/intel_bios.c | 43 +++++++++++++++++++ drivers/gpu/drm/i915/display/intel_bios.h | 4 ++ .../drm/i915/display/intel_ddi_buf_trans.c | 4 +- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 3b0f30ea7135..b9c168d7e4e6 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -3872,6 +3872,49 @@ validate_vspeo(const struct intel_bios_encoder_data *devdata, bool has_dp) return true; } +const struct intel_ddi_buf_trans * +intel_bios_get_lt_vspeo(const struct intel_bios_encoder_data *devdata, + const struct intel_ddi_buf_trans *buf_trans, + bool has_dp, bool is_uhbr) +{ + 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; + entries = (void *)vspeo->entries; + tables = display->vbt.vspeo.tables; + num_columns = display->vbt.vspeo.num_columns; + num_rows = display->vbt.vspeo.num_rows; + idx = is_uhbr ? 5 : 4; + + offset += idx * num_rows * num_columns; + + for (level = 0; level < num_rows; level++) { + u8 txswing = buf_trans->entries[level].lt.txswing; + u8 txswing_level = buf_trans->entries[level].lt.txswing_level; + u32 main_cursor = tables[offset]; + u32 pre_cursor = tables[offset + 1]; + u32 post_cursor = tables[offset + 2]; + + entries[level].lt.txswing = txswing; + entries[level].lt.txswing_level = txswing_level; + entries[level].lt.main_cursor = main_cursor; + entries[level].lt.pre_cursor = pre_cursor; + entries[level].lt.post_cursor = post_cursor; + + offset += num_columns; + } + + return vspeo; +} + const struct intel_ddi_buf_trans * intel_bios_get_c20_vspeo(const struct intel_bios_encoder_data *devdata, bool has_dp, bool is_uhbr) diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h index c55765a94594..e8c82f1e876f 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.h +++ b/drivers/gpu/drm/i915/display/intel_bios.h @@ -73,6 +73,10 @@ bool intel_bios_get_dsc_params(struct intel_encoder *encoder, const struct intel_bios_encoder_data * intel_bios_encoder_data_lookup(struct intel_display *display, enum port port); +const struct intel_ddi_buf_trans * +intel_bios_get_lt_vspeo(const struct intel_bios_encoder_data *devdata, + const struct intel_ddi_buf_trans *buf_trans, + bool has_dp, bool is_uhbr); const struct intel_ddi_buf_trans * intel_bios_get_c20_vspeo(const struct intel_bios_encoder_data *devdata, bool has_dp, bool is_uhbr); 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 b62ce58b9bdc..7fccb21f9e89 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -1868,7 +1868,9 @@ const struct intel_ddi_buf_trans *intel_ddi_buf_trans_get(struct intel_encoder * is_uhbr = intel_dp_is_uhbr(crtc_state); port_clock = crtc_state->port_clock; - if (DISPLAY_VER(display) >= 14) { + if (HAS_LT_PHY(display)) { + buf_trans = intel_bios_get_lt_vspeo(devdata, buf_trans, has_dp, is_uhbr); + } else if (DISPLAY_VER(display) >= 14) { if (intel_encoder_is_c10phy(encoder)) buf_trans = intel_bios_get_c10_vspeo(devdata, has_dp, port_clock, has_edp); else -- 2.45.2
