On 2026-02-03 13:56, Tomasz Pakuła wrote:
> [Why]
> Some users prefer to always manually control ALLM/Gaming mode while
> others might want it permanently forced on.
> 
> [How]
> Since there isn't yet an API to control this, expose module parameter
> 
> Changes in v3:
> - Include a fix for possible NULL pointer dereference by Peter
> 
> Closes: https://github.com/CachyOS/linux-cachyos/issues/680
> 
> Co-developed-by: Peter Jung <[email protected]>
> Signed-off-by: Peter Jung <[email protected]>
> Signed-off-by: Tomasz Pakuła <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       | 14 +++++-
>  .../gpu/drm/amd/display/dc/core/dc_resource.c |  7 +--
>  .../amd/display/modules/inc/mod_info_packet.h |  1 +
>  .../display/modules/info_packet/info_packet.c | 46 ++++++++++++++++---
>  5 files changed, 56 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 447e734c362b..312aa32064d5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -268,6 +268,7 @@ extern int amdgpu_rebar;
>  
>  extern int amdgpu_wbrf;
>  extern int amdgpu_user_queue;
> +extern uint amdgpu_allm_mode;
>  
>  extern uint amdgpu_hdmi_hpd_debounce_delay_ms;
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index d6d0a6e34c6b..4b038c8bbf9f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -248,6 +248,7 @@ int amdgpu_umsch_mm_fwlog;
>  int amdgpu_rebar = -1; /* auto */
>  int amdgpu_user_queue = -1;
>  uint amdgpu_hdmi_hpd_debounce_delay_ms;
> +uint amdgpu_allm_mode = 1;
>  
>  DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
>                       "DRM_UT_CORE",
> @@ -1124,7 +1125,7 @@ module_param_named(rebar, amdgpu_rebar, int, 0444);
>  MODULE_PARM_DESC(user_queue, "Enable user queues (-1 = auto (default), 0 = 
> disable, 1 = enable, 2 = enable UQs and disable KQs)");
>  module_param_named(user_queue, amdgpu_user_queue, int, 0444);
>  
> -/*
> +/**
>   * DOC: hdmi_hpd_debounce_delay_ms (uint)
>   * HDMI HPD disconnect debounce delay in milliseconds.
>   *
> @@ -1134,6 +1135,17 @@ module_param_named(user_queue, amdgpu_user_queue, int, 
> 0444);
>  MODULE_PARM_DESC(hdmi_hpd_debounce_delay_ms, "HDMI HPD disconnect debounce 
> delay in milliseconds (0 to disable (by default), 1500 is common)");
>  module_param_named(hdmi_hpd_debounce_delay_ms, 
> amdgpu_hdmi_hpd_debounce_delay_ms, uint, 0644);
>  
> +/**
> + * DOC: allm_mode (int)
> + * Changes ALLM triggering mode (if sink supports ALLM). Possible values:
> + *
> + * - 0 = ALLM disabled
> + * - 1 = ALLM dynamically triggered based on VRR state / Game Content Type 
> Hint
> + * - 2 = ALLM forced always on
> + */
> +MODULE_PARM_DESC(allm_mode, "Changes ALLM trigger mode (0 = disable, 1 = 
> enable (default), 2 = force enable)");
> +module_param_named(allm_mode, amdgpu_allm_mode, uint, 0644);
> +
>  /* These devices are not supported by amdgpu.
>   * They are supported by the mach64, r128, radeon drivers
>   */
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> index 4a7c9f810e35..b779aac28dfa 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> @@ -44,6 +44,7 @@
>  #include "clk_mgr.h"
>  #include "dc_state_priv.h"
>  #include "dc_stream_priv.h"
> +#include "modules/inc/mod_info_packet.h"

Architecturally DC can't have a dependency on modules.
Is there a different way we can handle this?

Could we do the determination in amdgpu_dm (with help of
the module) and then set a flag on the stream?

Harry

>  
>  #include "virtual/virtual_link_hwss.h"
>  #include "link/hwss/link_hwss_dio.h"
> @@ -4503,8 +4504,6 @@ static void set_avi_info_frame(
>       unsigned int vic = pipe_ctx->stream->timing.vic;
>       unsigned int rid = pipe_ctx->stream->timing.rid;
>       unsigned int fr_ind = pipe_ctx->stream->timing.fr_index;
> -     enum dc_timing_3d_format format;
> -     bool allm;
>  
>       if (stream->avi_infopacket.valid) {
>               *info_packet = stream->avi_infopacket;
> @@ -4658,10 +4657,8 @@ static void set_avi_info_frame(
>       ///VIC
>       if (pipe_ctx->stream->timing.hdmi_vic != 0)
>               vic = 0;
> -     format = stream->timing.timing_3d_format;
> -     allm = stream->link->local_sink->edid_caps.allm;
>       /*todo, add 3DStereo support*/
> -     if ((format != TIMING_3D_FORMAT_NONE) || allm) {
> +     if (!is_hdmi_vic_mode(pipe_ctx->stream)) {
>               // Based on HDMI specs hdmi vic needs to be converted to cea 
> vic when 3D is enabled
>               switch (pipe_ctx->stream->timing.hdmi_vic) {
>               case 1:
> diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h 
> b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
> index 306eb7355c25..9ec123ecc7c4 100644
> --- a/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
> +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
> @@ -41,6 +41,7 @@ void set_vsc_packet_colorimetry_data(
>               enum dc_color_space cs,
>               enum color_transfer_func tf);
>  
> +bool is_hdmi_vic_mode(const struct dc_stream_state *stream);
>  void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
>               struct dc_info_packet *info_packet,
>               enum dc_color_space cs,
> diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c 
> b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
> index 53e488fdb4ea..829cce9455db 100644
> --- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
> +++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
> @@ -23,12 +23,13 @@
>   *
>   */
>  
> -#include "mod_info_packet.h"
> +#include "amdgpu.h"
>  #include "core_types.h"
> -#include "dc_types.h"
> -#include "mod_shared.h"
> -#include "mod_freesync.h"
>  #include "dc.h"
> +#include "dc_types.h"
> +#include "mod_freesync.h"
> +#include "mod_info_packet.h"
> +#include "mod_shared.h"
>  
>  enum vsc_packet_revision {
>       vsc_packet_undefined = 0,
> @@ -54,6 +55,12 @@ enum vsc_packet_revision {
>  #define HF_VSIF_3D_BIT   0
>  #define HF_VSIF_ALLM_BIT 1
>  
> +enum allm_trigger_mode {
> +     ALLM_MODE_DISABLED        = 0,
> +     ALLM_MODE_ENABLED_DYNAMIC = 1,
> +     ALLM_MODE_ENABLED_FORCED  = 2,
> +};
> +
>  // VTEM Byte Offset
>  #define VTEM_PB0             0
>  #define VTEM_PB1             1
> @@ -499,7 +506,32 @@ void mod_build_vsc_infopacket(const struct 
> dc_stream_state *stream,
>       }
>  }
>  
> -static bool is_hdmi_vic_mode(const struct dc_stream_state *stream)
> +static bool is_hdmi_allm_mode(const struct dc_stream_state *stream)
> +{
> +     /* No local sink */
> +     if (!stream->link->local_sink)
> +             return false;
> +
> +     /* Sink doesn't expose ALLM support in edid */
> +     if (!stream->link->local_sink->edid_caps.allm)
> +             return false;
> +
> +     switch (amdgpu_allm_mode) {
> +     case ALLM_MODE_DISABLED:
> +             return false;
> +
> +     case ALLM_MODE_ENABLED_DYNAMIC:
> +             break;
> +
> +     case ALLM_MODE_ENABLED_FORCED:
> +             return true;
> +     }
> +
> +     return stream->content_type == DISPLAY_CONTENT_TYPE_GAME ||
> +            stream->vrr_active_variable;
> +}
> +
> +bool is_hdmi_vic_mode(const struct dc_stream_state *stream)
>  {
>       if (stream->timing.hdmi_vic == 0)
>               return false;
> @@ -512,7 +544,7 @@ static bool is_hdmi_vic_mode(const struct dc_stream_state 
> *stream)
>       if (stream->view_format != VIEW_3D_FORMAT_NONE)
>               return false;
>  
> -     if (stream->link->local_sink->edid_caps.allm)
> +     if (is_hdmi_allm_mode(stream))
>               return false;
>  
>       return true;
> @@ -541,7 +573,7 @@ void mod_build_hf_vsif_infopacket(const struct 
> dc_stream_state *stream,
>  
>               info_packet->valid = false;
>  
> -             allm = stream->link->local_sink->edid_caps.allm;
> +             allm = is_hdmi_allm_mode(stream);
>               format = stream->view_format == VIEW_3D_FORMAT_NONE ?
>                        TIMING_3D_FORMAT_NONE :
>                        stream->timing.timing_3d_format;

Reply via email to