]> www.infradead.org Git - users/willy/xarray.git/commitdiff
drm/amd/display: Add eDP AUXless ALPM
authorDuncan Ma <Duncan.Ma@amd.com>
Wed, 4 Dec 2024 17:35:05 +0000 (12:35 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 28 Jul 2025 20:40:31 +0000 (16:40 -0400)
[Why & How]
Add AUX-less ALPM capability check and initialization

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Signed-off-by: Duncan Ma <Duncan.Ma@amd.com>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
drivers/gpu/drm/amd/display/dc/inc/link.h
drivers/gpu/drm/amd/display/dc/link/link_factory.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c

index 130455f2802a71575b94d0fb790443adb7f2c548..b7a5de4ecb61ef310803eed18b4e5c609f3fd994 100644 (file)
@@ -520,3 +520,10 @@ enum dc_status dc_link_validate_dp_tunneling_bandwidth(const struct dc *dc, cons
        return dc->link_srv->validate_dp_tunnel_bandwidth(dc, new_ctx);
 }
 
+void dc_link_get_alpm_support(struct dc_link *link,
+       bool *auxless_support,
+       bool *auxwake_support)
+{
+       link->dc->link_srv->edp_get_alpm_support(link, auxless_support, auxwake_support);
+}
+
index 779b39e334436bf862c4444c66267921012d06ce..fee54cc0f7d4867d02b6f961f431c59081194d14 100644 (file)
@@ -1145,6 +1145,11 @@ struct dc_debug_options {
        bool enable_hblank_borrow;
        bool force_subvp_df_throttle;
        uint32_t acpi_transition_bitmasks[MAX_PIPES];
+       unsigned int auxless_alpm_lfps_setup_ns;
+       unsigned int auxless_alpm_lfps_period_ns;
+       unsigned int auxless_alpm_lfps_silence_ns;
+       unsigned int auxless_alpm_lfps_t1t2_us;
+       short auxless_alpm_lfps_t1t2_offset_us;
 };
 
 
@@ -2447,6 +2452,12 @@ void dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(
  */
 enum dc_status dc_link_validate_dp_tunneling_bandwidth(const struct dc *dc, const struct dc_state *new_ctx);
 
+/*
+ * Get if ALPM is supported by the link
+ */
+void dc_link_get_alpm_support(struct dc_link *link, bool *auxless_support,
+       bool *auxwake_support);
+
 /* Sink Interfaces - A sink corresponds to a display output device */
 
 struct dc_container_id {
index 5ce1be362534dc97329409c6b08adeb64e80e84f..3a3ec38cdf8be09a11b92dc16740c32bb9ba0c4d 100644 (file)
@@ -1021,7 +1021,8 @@ union dp_128b_132b_supported_lttpr_link_rates {
 union dp_alpm_lttpr_cap {
        struct {
                uint8_t AUX_LESS_ALPM_SUPPORTED :1;
-               uint8_t RESERVED                                :7;
+               uint8_t ASSR_SUPPORTED                  :1;
+               uint8_t RESERVED                        :6;
        } bits;
        uint8_t raw;
 };
@@ -1119,10 +1120,11 @@ union dp_128b_132b_training_aux_rd_interval {
 
 union edp_alpm_caps {
        struct {
-               uint8_t AUX_WAKE_ALPM_CAP       :1;
-               uint8_t PM_STATE_2A_SUPPORT     :1;
-               uint8_t AUX_LESS_ALPM_CAP       :1;
-               uint8_t RESERVED                :5;
+               uint8_t AUX_WAKE_ALPM_CAP                               :1;
+               uint8_t PM_STATE_2A_SUPPORT                             :1;
+               uint8_t AUX_LESS_ALPM_CAP                               :1;
+               uint8_t AUX_LESS_ALPM_ML_PHY_SLEEP_STATUS_SUPPORTED     :1;
+               uint8_t RESERVED                                        :4;
        } bits;
        uint8_t raw;
 };
@@ -1347,7 +1349,9 @@ union dpcd_alpm_configuration {
        struct {
                unsigned char ENABLE                    : 1;
                unsigned char IRQ_HPD_ENABLE            : 1;
-               unsigned char RESERVED                  : 6;
+               unsigned char ALPM_MODE_SEL             : 1;
+               unsigned char ACDS_PERIOD_DURATION      : 1;
+               unsigned char RESERVED                  : 4;
        } bits;
        unsigned char raw;
 };
index 2a86058c3bfa6f3cb63d055b37ef54e13f6f3ffe..2e2dea21b332103d22825ebe94fe6978822c88d9 100644 (file)
@@ -577,6 +577,12 @@ struct dc_plane_flip_time {
        unsigned int prev_update_time_in_us;
 };
 
+enum dc_alpm_mode {
+       DC_ALPM_AUXWAKE = 0,
+       DC_ALPM_AUXLESS = 1,
+       DC_ALPM_UNSUPPORTED = 0xF,
+};
+
 enum dc_psr_state {
        PSR_STATE0 = 0x0,
        PSR_STATE1,
@@ -1143,6 +1149,8 @@ struct replay_config {
        bool low_rr_supported;
        /* Replay Video Conferencing Optimization Enabled */
        bool replay_video_conferencing_optimization_enabled;
+       /* Replay alpm mode */
+       enum dc_alpm_mode alpm_mode;
 };
 
 /* Replay feature flags*/
index fcd3d86ad5173a0e6c7663c7624857eee9526525..65b979617b0cf42d6cf76721d195859c43c83918 100644 (file)
@@ -3,6 +3,7 @@
 // Copyright 2024 Advanced Micro Devices, Inc.
 
 #include "dc.h"
+#include "link.h"
 #include "dc_dmub_srv.h"
 #include "dmub/dmub_srv.h"
 #include "core_types.h"
@@ -189,6 +190,18 @@ static bool dmub_replay_copy_settings(struct dmub_replay *dmub,
        else
                copy_settings_data->flags.bitfields.force_wakeup_by_tps3 = 0;
 
+       copy_settings_data->flags.bitfields.alpm_mode = (enum dmub_alpm_mode)link->replay_settings.config.alpm_mode;
+       if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) {
+               copy_settings_data->auxless_alpm_data.lfps_setup_ns = dc->dc->debug.auxless_alpm_lfps_setup_ns;
+               copy_settings_data->auxless_alpm_data.lfps_period_ns = dc->dc->debug.auxless_alpm_lfps_period_ns;
+               copy_settings_data->auxless_alpm_data.lfps_silence_ns = dc->dc->debug.auxless_alpm_lfps_silence_ns;
+               copy_settings_data->auxless_alpm_data.lfps_t1_t2_override_us =
+                       dc->dc->debug.auxless_alpm_lfps_t1t2_us;
+               copy_settings_data->auxless_alpm_data.lfps_t1_t2_offset_us =
+                       dc->dc->debug.auxless_alpm_lfps_t1t2_offset_us;
+               copy_settings_data->auxless_alpm_data.lttpr_count = link->dc->link_srv->dp_get_lttpr_count(link);
+       }
+
        dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
 
        return true;
index f2503402c10e74537878eaa5e5f490474a8ee13b..0cce49d95e261baa2763a8ce06b1a3528a45e51e 100644 (file)
@@ -218,7 +218,10 @@ struct link_service {
        bool (*dp_overwrite_extended_receiver_cap)(struct dc_link *link);
        enum lttpr_mode (*dp_decide_lttpr_mode)(struct dc_link *link,
                        struct dc_link_settings *link_setting);
-
+       uint8_t (*dp_get_lttpr_count)(struct dc_link *link);
+       void (*edp_get_alpm_support)(struct dc_link *link,
+               bool *auxless_support,
+               bool *auxwake_support);
 
        /*************************** DP DPIA/PHY ******************************/
        void (*dpia_handle_usb4_bandwidth_allocation_for_link)(
index de1143dbbd25f83b15b25dcfc0455852371b8cc5..31a73867cd4cf527f593e90dcd7431fdcd5ce77a 100644 (file)
@@ -165,6 +165,8 @@ static void construct_link_service_dp_capability(struct link_service *link_srv)
        link_srv->dp_overwrite_extended_receiver_cap =
                        dp_overwrite_extended_receiver_cap;
        link_srv->dp_decide_lttpr_mode = dp_decide_lttpr_mode;
+       link_srv->dp_get_lttpr_count = dp_get_lttpr_count;
+       link_srv->edp_get_alpm_support = edp_get_alpm_support;
 }
 
 /* link dp phy/dpia implements basic dp phy/dpia functionality such as
index 651926e547b9046edf89065fba0eb6d0626b2334..e0c4416993d948f033c67682a07bcaeee585b717 100644 (file)
@@ -2506,3 +2506,40 @@ bool dp_is_sink_present(struct dc_link *link)
 
        return present;
 }
+
+uint8_t dp_get_lttpr_count(struct dc_link *link)
+{
+       if (dp_is_lttpr_present(link))
+               return dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
+
+       return 0;
+}
+
+void edp_get_alpm_support(struct dc_link *link,
+       bool *auxless_support,
+       bool *auxwake_support)
+{
+       bool lttpr_present = dp_is_lttpr_present(link);
+
+       if (auxless_support == NULL || auxwake_support == NULL)
+               return;
+
+       *auxless_support = false;
+       *auxwake_support = false;
+
+       if (!dc_is_embedded_signal(link->connector_signal))
+               return;
+
+       if (link->dpcd_caps.alpm_caps.bits.AUX_LESS_ALPM_CAP) {
+               if (lttpr_present) {
+                       if (link->dpcd_caps.lttpr_caps.alpm.bits.AUX_LESS_ALPM_SUPPORTED)
+                               *auxless_support = true;
+               } else
+                       *auxless_support = true;
+       }
+
+       if (link->dpcd_caps.alpm_caps.bits.AUX_WAKE_ALPM_CAP) {
+               if (!lttpr_present)
+                       *auxwake_support = true;
+       }
+}
index 940b147cc5d426bcdd0516a003b3ed5be9f7f5dc..7170db5a1c13e8f6c6fb6e30927a90c4de9e1eb5 100644 (file)
@@ -108,4 +108,10 @@ uint32_t link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw);
 
 bool dp_overwrite_extended_receiver_cap(struct dc_link *link);
 
+uint8_t dp_get_lttpr_count(struct dc_link *link);
+
+void edp_get_alpm_support(struct dc_link *link,
+       bool *auxless_support,
+       bool *auxwake_support);
+
 #endif /* __DC_LINK_DP_CAPABILITY_H__ */
index 98ec9b5a559c80463c0c07fc82a37a92596864e2..be714cbf66155b23d3621437185f929485e830dd 100644 (file)
@@ -1042,7 +1042,13 @@ bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream
                        (uint8_t *)&(replay_config.raw), sizeof(uint8_t));
 
                memset(&alpm_config, 0, sizeof(alpm_config));
-               alpm_config.bits.ENABLE = 1;
+               alpm_config.bits.ENABLE = link->replay_settings.config.alpm_mode != DC_ALPM_UNSUPPORTED ? 1 : 0;
+
+               if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) {
+                       alpm_config.bits.ALPM_MODE_SEL = 1;
+                       alpm_config.bits.ACDS_PERIOD_DURATION = 1;
+               }
+
                dm_helpers_dp_write_dpcd(
                        link->ctx,
                        link,