mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] drm/amd/display: Don't require DMUB PSR caps before DCN 3.0
@ 2026-10-29 17:12 Hugo Sales
  2026-11-04  9:31 ` Ray Wu
  0 siblings, 1 reply; 3+ messages in thread
From: Hugo Sales @ 2026-10-29 17:12 UTC (permalink / raw)
  To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher
  Cc: Ray Wu, Chenyu Chen, Alex Hung, Christian König,
	David Airlie, Simona Vetter, amd-gfx, dri-devel, linux-kernel

Commit 3c108046e1d6 ("drm/amd/display: Add power module on Linux") made
amdgpu_dm_set_psr_caps() return false unless dc->caps.dmub_caps.psr is
set. DC fills dmub_caps from dc_dmub_srv_query_caps_cmd(), which only
the DCN 3.0 and later hwseq init calls. On DCN 2.x the flag stays false,
so DC_PSR_MASK in amdgpu.dcfeaturemask, the documented way to turn PSR
on there, no longer does anything

On a Cezanne laptop (DCN 2.1, DMUB firmware 0x0101002B) with
amdgpu.dcfeaturemask=0xa, dmesg shows
"eDP-1: PSR support 0, DC PSR ver -1, sink PSR ver 1 DPCD caps 0x0",
although DC created a dmub_psr for the ASIC

Sending the caps query on DCN 2.1 too doesn't help. That firmware
answers it without error but reports psr as 0, and with the check
skipped it runs PSR 1 fine: psr_state reaches 6 on an idle screen

Keep the check only from DCN 3.0 on, where every ASIC with a DMUB PSR
engine queries the caps. DCN 3.01 skips the query, but it has no PSR
engine either. Before that commit no ASIC needed dmub_caps.psr.
edp_setup_psr() already returns false when the ASIC has neither a DMCU
nor a DMUB PSR engine

This needs "drm/amd/display: Take every stream out of self-refresh
before a modeset" first. Without it, turning off or unplugging an
external display while the eDP is in PSR hangs DMUB on DCN 2.1

Fixes: 3c108046e1d6 ("drm/amd/display: Add power module on Linux")
Signed-off-by: Hugo Sales <hugo@hsal.es>
---
Depends on:

  https://lore.kernel.org/r/20261029165420.2255749-1-hugo@hsal.es

Firmware 0x0101002B answers QUERY_FEATURE_CAPS with psr = 0 but still
runs PSR 1 without trouble. Is that field just not filled in by the DCN
2.1 firmware, and is there a version from which it can be trusted? If
so, I can check the caps there as well

 .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c |  8 ++++-
 .../amdgpu_dm/tests/amdgpu_dm_psr_test.c      | 35 +++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
index dbad0a6d3a2b4..be95433624674 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
@@ -111,7 +111,13 @@ bool amdgpu_dm_set_psr_caps(struct dc_link *link, struct amdgpu_dm_connector *ac
 	/* Reset psr version first */
 	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
 
-	if (!dc->caps.dmub_caps.psr)
+	/*
+	 * Only DCN 3.0 and later ASICs with a DMUB PSR engine query the DMUB
+	 * feature caps. Older ASICs drive PSR through DMCU or DMUB without
+	 * that query, and edp_setup_psr() already bails out when neither
+	 * engine exists
+	 */
+	if (dc->ctx->dce_version >= DCN_VERSION_3_0 && !dc->caps.dmub_caps.psr)
 		return false;
 
 	if (!(link->connector_signal & SIGNAL_TYPE_EDP))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c
index 0a484ea7c0e8e..4d23b1234921c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c
@@ -239,6 +239,39 @@ static void dm_test_set_psr_caps_no_dmub_psr(struct kunit *test)
 			DC_PSR_VERSION_UNSUPPORTED);
 }
 
+/**
+ * dm_test_set_psr_caps_pre_dcn30() - DMUB caps are not required before DCN 3.0.
+ * @test: KUnit test context.
+ */
+static void dm_test_set_psr_caps_pre_dcn30(struct kunit *test)
+{
+	struct dc_link *link = alloc_test_psr_caps_link(test);
+	struct amdgpu_dm_connector *aconnector = alloc_test_aconnector(test);
+
+	link->ctx->dce_version = DCN_VERSION_2_1;
+	link->ctx->dc->caps.dmub_caps.psr = false;
+
+	KUNIT_EXPECT_TRUE(test, amdgpu_dm_set_psr_caps(link, aconnector));
+	KUNIT_EXPECT_EQ(test, link->psr_settings.psr_version, DC_PSR_VERSION_1);
+}
+
+/**
+ * dm_test_set_psr_caps_dcn30_no_dmub_psr() - DCN 3.0 requires DMUB caps.
+ * @test: KUnit test context.
+ */
+static void dm_test_set_psr_caps_dcn30_no_dmub_psr(struct kunit *test)
+{
+	struct dc_link *link = alloc_test_psr_caps_link(test);
+	struct amdgpu_dm_connector *aconnector = alloc_test_aconnector(test);
+
+	link->ctx->dce_version = DCN_VERSION_3_0;
+	link->ctx->dc->caps.dmub_caps.psr = false;
+
+	KUNIT_EXPECT_FALSE(test, amdgpu_dm_set_psr_caps(link, aconnector));
+	KUNIT_EXPECT_EQ(test, link->psr_settings.psr_version,
+			DC_PSR_VERSION_UNSUPPORTED);
+}
+
 /**
  * dm_test_set_psr_caps_non_edp() - Only eDP links can enable PSR.
  * @test: KUnit test context.
@@ -712,6 +745,8 @@ static struct kunit_case dm_psr_test_cases[] = {
 	KUNIT_CASE(dm_test_set_psr_caps_null_link),
 	KUNIT_CASE(dm_test_set_psr_caps_null_connector),
 	KUNIT_CASE(dm_test_set_psr_caps_no_dmub_psr),
+	KUNIT_CASE(dm_test_set_psr_caps_pre_dcn30),
+	KUNIT_CASE(dm_test_set_psr_caps_dcn30_no_dmub_psr),
 	KUNIT_CASE(dm_test_set_psr_caps_non_edp),
 	KUNIT_CASE(dm_test_set_psr_caps_disconnected),
 	KUNIT_CASE(dm_test_set_psr_caps_no_dpcd_psr),

base-commit: ba496bb837882eb1af58f41572fc289e46c77b8c
prerequisite-message-id: <20261029165420.2255749-1-hugo@hsal.es>
-- 
2.56.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] drm/amd/display: Don't require DMUB PSR caps before DCN 3.0
  2026-10-29 17:12 [PATCH] drm/amd/display: Don't require DMUB PSR caps before DCN 3.0 Hugo Sales
@ 2026-11-04  9:31 ` Ray Wu
  2026-11-04 10:17   ` Hugo Sales
  0 siblings, 1 reply; 3+ messages in thread
From: Ray Wu @ 2026-11-04  9:31 UTC (permalink / raw)
  To: Hugo Sales, Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher
  Cc: Chenyu Chen, Alex Hung, Christian König, David Airlie,
	Simona Vetter, amd-gfx, dri-devel, linux-kernel

We already have a similar fix internally that is planned for an upcoming DC release:

commit: drm/amd/display: Allow DC_PSR_MASK to enable PSR without DMUB PSR cap

Could you give it a try and see if it resolves the issue?

Thanks,
Ray


On 10/30/2026 1:12 AM, Hugo Sales wrote:
> Commit 3c108046e1d6 ("drm/amd/display: Add power module on Linux") made
> amdgpu_dm_set_psr_caps() return false unless dc->caps.dmub_caps.psr is
> set. DC fills dmub_caps from dc_dmub_srv_query_caps_cmd(), which only
> the DCN 3.0 and later hwseq init calls. On DCN 2.x the flag stays false,
> so DC_PSR_MASK in amdgpu.dcfeaturemask, the documented way to turn PSR
> on there, no longer does anything
>
> On a Cezanne laptop (DCN 2.1, DMUB firmware 0x0101002B) with
> amdgpu.dcfeaturemask=0xa, dmesg shows
> "eDP-1: PSR support 0, DC PSR ver -1, sink PSR ver 1 DPCD caps 0x0",
> although DC created a dmub_psr for the ASIC
>
> Sending the caps query on DCN 2.1 too doesn't help. That firmware
> answers it without error but reports psr as 0, and with the check
> skipped it runs PSR 1 fine: psr_state reaches 6 on an idle screen
>
> Keep the check only from DCN 3.0 on, where every ASIC with a DMUB PSR
> engine queries the caps. DCN 3.01 skips the query, but it has no PSR
> engine either. Before that commit no ASIC needed dmub_caps.psr.
> edp_setup_psr() already returns false when the ASIC has neither a DMCU
> nor a DMUB PSR engine
>
> This needs "drm/amd/display: Take every stream out of self-refresh
> before a modeset" first. Without it, turning off or unplugging an
> external display while the eDP is in PSR hangs DMUB on DCN 2.1
>
> Fixes: 3c108046e1d6 ("drm/amd/display: Add power module on Linux")
> Signed-off-by: Hugo Sales <hugo@hsal.es>
> ---
> Depends on:
>
>    https://lore.kernel.org/r/20261029165420.2255749-1-hugo@hsal.es
>
> Firmware 0x0101002B answers QUERY_FEATURE_CAPS with psr = 0 but still
> runs PSR 1 without trouble. Is that field just not filled in by the DCN
> 2.1 firmware, and is there a version from which it can be trusted? If
> so, I can check the caps there as well
>
>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c |  8 ++++-
>   .../amdgpu_dm/tests/amdgpu_dm_psr_test.c      | 35 +++++++++++++++++++
>   2 files changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
> index dbad0a6d3a2b4..be95433624674 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
> @@ -111,7 +111,13 @@ bool amdgpu_dm_set_psr_caps(struct dc_link *link, struct amdgpu_dm_connector *ac
>   	/* Reset psr version first */
>   	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
>   
> -	if (!dc->caps.dmub_caps.psr)
> +	/*
> +	 * Only DCN 3.0 and later ASICs with a DMUB PSR engine query the DMUB
> +	 * feature caps. Older ASICs drive PSR through DMCU or DMUB without
> +	 * that query, and edp_setup_psr() already bails out when neither
> +	 * engine exists
> +	 */
> +	if (dc->ctx->dce_version >= DCN_VERSION_3_0 && !dc->caps.dmub_caps.psr)
>   		return false;
>   
>   	if (!(link->connector_signal & SIGNAL_TYPE_EDP))
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c
> index 0a484ea7c0e8e..4d23b1234921c 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_psr_test.c
> @@ -239,6 +239,39 @@ static void dm_test_set_psr_caps_no_dmub_psr(struct kunit *test)
>   			DC_PSR_VERSION_UNSUPPORTED);
>   }
>   
> +/**
> + * dm_test_set_psr_caps_pre_dcn30() - DMUB caps are not required before DCN 3.0.
> + * @test: KUnit test context.
> + */
> +static void dm_test_set_psr_caps_pre_dcn30(struct kunit *test)
> +{
> +	struct dc_link *link = alloc_test_psr_caps_link(test);
> +	struct amdgpu_dm_connector *aconnector = alloc_test_aconnector(test);
> +
> +	link->ctx->dce_version = DCN_VERSION_2_1;
> +	link->ctx->dc->caps.dmub_caps.psr = false;
> +
> +	KUNIT_EXPECT_TRUE(test, amdgpu_dm_set_psr_caps(link, aconnector));
> +	KUNIT_EXPECT_EQ(test, link->psr_settings.psr_version, DC_PSR_VERSION_1);
> +}
> +
> +/**
> + * dm_test_set_psr_caps_dcn30_no_dmub_psr() - DCN 3.0 requires DMUB caps.
> + * @test: KUnit test context.
> + */
> +static void dm_test_set_psr_caps_dcn30_no_dmub_psr(struct kunit *test)
> +{
> +	struct dc_link *link = alloc_test_psr_caps_link(test);
> +	struct amdgpu_dm_connector *aconnector = alloc_test_aconnector(test);
> +
> +	link->ctx->dce_version = DCN_VERSION_3_0;
> +	link->ctx->dc->caps.dmub_caps.psr = false;
> +
> +	KUNIT_EXPECT_FALSE(test, amdgpu_dm_set_psr_caps(link, aconnector));
> +	KUNIT_EXPECT_EQ(test, link->psr_settings.psr_version,
> +			DC_PSR_VERSION_UNSUPPORTED);
> +}
> +
>   /**
>    * dm_test_set_psr_caps_non_edp() - Only eDP links can enable PSR.
>    * @test: KUnit test context.
> @@ -712,6 +745,8 @@ static struct kunit_case dm_psr_test_cases[] = {
>   	KUNIT_CASE(dm_test_set_psr_caps_null_link),
>   	KUNIT_CASE(dm_test_set_psr_caps_null_connector),
>   	KUNIT_CASE(dm_test_set_psr_caps_no_dmub_psr),
> +	KUNIT_CASE(dm_test_set_psr_caps_pre_dcn30),
> +	KUNIT_CASE(dm_test_set_psr_caps_dcn30_no_dmub_psr),
>   	KUNIT_CASE(dm_test_set_psr_caps_non_edp),
>   	KUNIT_CASE(dm_test_set_psr_caps_disconnected),
>   	KUNIT_CASE(dm_test_set_psr_caps_no_dpcd_psr),
>
> base-commit: ba496bb837882eb1af58f41572fc289e46c77b8c
> prerequisite-message-id: <20261029165420.2255749-1-hugo@hsal.es>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] drm/amd/display: Don't require DMUB PSR caps before DCN 3.0
  2026-11-04  9:31 ` Ray Wu
@ 2026-11-04 10:17   ` Hugo Sales
  0 siblings, 0 replies; 3+ messages in thread
From: Hugo Sales @ 2026-11-04 10:17 UTC (permalink / raw)
  To: Ray Wu, Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher
  Cc: Chenyu Chen, Alex Hung, Christian König, David Airlie,
	Simona Vetter, amd-gfx, dri-devel, linux-kernel

On 11/04/2026 9:31 AM WET Ray Wu <ray.wu@amd.com> wrote:
> We already have a similar fix internally that is planned for an upcoming DC release:
>
> commit: drm/amd/display: Allow DC_PSR_MASK to enable PSR without DMUB PSR cap
>
> Could you give it a try and see if it resolves the issue?

Hi Ray,

Happy to test it, but I can't find that commit. It isn't on amd-gfx and
it isn't in amd-staging-drm-next yet. Could you post it to the list, or
send it to me directly?

I'll try it on my ROG Flow X13 (DCN 2.1) with PSR. Since my patch reported the same problem, could the commit also carry a 
Reported-by/Tested-by for me?

Thanks,
Hugo

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-04 10:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-29 17:12 [PATCH] drm/amd/display: Don't require DMUB PSR caps before DCN 3.0 Hugo Sales
2026-11-04  9:31 ` Ray Wu
2026-11-04 10:17   ` Hugo Sales

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®