summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/bios
diff options
context:
space:
mode:
authorRafal Ostrowski <rostrows@amd.com>2025-02-12 08:08:07 +0100
committerAlex Deucher <alexander.deucher@amd.com>2025-02-25 11:44:36 -0500
commitab021b9f3194c16bb766eec084d22529e503f2c5 (patch)
tree09636968cc72f11202723aca8b2ea3a010653a02 /drivers/gpu/drm/amd/display/dc/bios
parent02a2793ab27e3aa3f345f4e7761005e5c9e3ebd4 (diff)
downloadlinux-next-ab021b9f3194c16bb766eec084d22529e503f2c5.tar.gz
linux-next-ab021b9f3194c16bb766eec084d22529e503f2c5.zip
drm/amd/display: ACPI Re-timer Programming
[Why] We must implement an ACPI re-timer programming interface and notify ACPI driver whenever a PHY transition is about to take place. Because some trace lengths on certain platforms are very long, then a re-timer may need to be programmed whenever a PHY transition takes place. The implementation of this re-timer programming interface will notify ACPI driver that PHY transition is taking place and it will trigger the re-timer as needed. First we need to gather retimer information from ACPI interface. Then, in the PRE case, the re-timer interface needs to be called before we call transmitter ENABLE. In the POST case, it has to be called after we call transmitter DISABLE. [How] Implemented ACPI retimer programming interface. Reviewed-by: Alvin Lee <alvin.lee2@amd.com> Signed-off-by: Rafal Ostrowski <rostrows@amd.com> Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/bios')
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table2.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
index 7d18f372ce7a..2c96a5e64567 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -210,6 +210,7 @@ static enum bp_result encoder_control_fallback(
******************************************************************************
*****************************************************************************/
+
static enum bp_result transmitter_control_v1_6(
struct bios_parser *bp,
struct bp_transmitter_control *cntl);
@@ -325,6 +326,21 @@ static void transmitter_control_dmcub_v1_7(
dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}
+static struct dc_link *get_link_by_phy_id(struct dc *p_dc, uint32_t phy_id)
+{
+ struct dc_link *link = NULL;
+
+ // Get Transition Bitmask from dc_link structure associated with PHY
+ for (uint8_t link_id = 0; link_id < MAX_LINKS; link_id++) {
+ if (phy_id == p_dc->links[link_id]->link_enc->transmitter) {
+ link = p_dc->links[link_id];
+ break;
+ }
+ }
+
+ return link;
+}
+
static enum bp_result transmitter_control_v1_7(
struct bios_parser *bp,
struct bp_transmitter_control *cntl)
@@ -363,7 +379,37 @@ static enum bp_result transmitter_control_v1_7(
if (bp->base.ctx->dc->ctx->dmub_srv &&
bp->base.ctx->dc->debug.dmub_command_table) {
+ struct dm_process_phy_transition_init_params process_phy_transition_init_params = {0};
+ struct dc_link *link = get_link_by_phy_id(bp->base.ctx->dc, dig_v1_7.phyid);
+ bool is_phy_transition_interlock_allowed = false;
+ uint8_t action = dig_v1_7.action;
+
+ if (link) {
+ if (link->phy_transition_bitmask &&
+ (action == TRANSMITTER_CONTROL_ENABLE || action == TRANSMITTER_CONTROL_DISABLE)) {
+ is_phy_transition_interlock_allowed = true;
+
+ // Prepare input parameters for processing ACPI retimers
+ process_phy_transition_init_params.action = action;
+ process_phy_transition_init_params.display_port_lanes_count = cntl->lanes_number;
+ process_phy_transition_init_params.phy_id = dig_v1_7.phyid;
+ process_phy_transition_init_params.signal = cntl->signal;
+ process_phy_transition_init_params.sym_clock_10khz = dig_v1_7.symclk_units.symclk_10khz;
+ process_phy_transition_init_params.display_port_link_rate = link->cur_link_settings.link_rate;
+ process_phy_transition_init_params.transition_bitmask = link->phy_transition_bitmask;
+ }
+ }
+
+ // Handle PRE_OFF_TO_ON: Process ACPI PHY Transition Interlock
+ if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_ENABLE)
+ dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params);
+
transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7);
+
+ // Handle POST_ON_TO_OFF: Process ACPI PHY Transition Interlock
+ if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_DISABLE)
+ dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params);
+
return BP_RESULT_OK;
}
@@ -1046,3 +1092,4 @@ void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
init_enable_lvtma_control(bp);
}
+