[PATCH v3 16/19] drm/amd/display: Add parameter to control ALLM behavior

Tomasz Pakuła posted 19 patches 5 days, 19 hours ago
[PATCH v3 16/19] drm/amd/display: Add parameter to control ALLM behavior
Posted by Tomasz Pakuła 5 days, 19 hours ago
[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 <admin@ptr1337.dev>
Signed-off-by: Peter Jung <admin@ptr1337.dev>
Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
---
 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"
 
 #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;
-- 
2.52.0

Re: [PATCH v3 16/19] drm/amd/display: Add parameter to control ALLM behavior
Posted by Harry Wentland 2 days, 19 hours ago
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 <admin@ptr1337.dev>
> Signed-off-by: Peter Jung <admin@ptr1337.dev>
> Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
> ---
>  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;

Re: [PATCH v3 16/19] drm/amd/display: Add parameter to control ALLM behavior
Posted by Tomasz Pakuła 2 days, 17 hours ago
On Fri, 2026-02-06 at 13:52 -0500, Harry Wentland wrote:
> 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 <admin@ptr1337.dev>
> > Signed-off-by: Peter Jung <admin@ptr1337.dev>
> > Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
> > ---
> >  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

Sure. I don't have any opinion on how it should be done. I think I only
did this like that because I wanted it to be easily changeable at
runtime, but the value of having this RW is next to none.

> 
> >  
> >  #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;
Re: [PATCH v3 16/19] drm/amd/display: Add parameter to control ALLM behavior
Posted by Alex Deucher 2 days, 15 hours ago
On Fri, Feb 6, 2026 at 4:12 PM Tomasz Pakuła
<tomasz.pakula.oficjalny@gmail.com> wrote:
>
> On Fri, 2026-02-06 at 13:52 -0500, Harry Wentland wrote:
> > 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 <admin@ptr1337.dev>
> > > Signed-off-by: Peter Jung <admin@ptr1337.dev>
> > > Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
> > > ---
> > >  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)

Would be good to define ALLM.

> > > + * 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);

Also, maybe a per connector kms property would be preferable.  Then
you could change it per display.

Alex

> > > +
> > >  /* 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
>
> Sure. I don't have any opinion on how it should be done. I think I only
> did this like that because I wanted it to be easily changeable at
> runtime, but the value of having this RW is next to none.
>
> >
> > >
> > >  #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;