[PATCH] drm/amdgpu: Fixed an issue where audio did not turn off properly after unplugging HDMI

2564278112@qq.com posted 1 patch 1 month, 2 weeks ago
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
[PATCH] drm/amdgpu: Fixed an issue where audio did not turn off properly after unplugging HDMI
Posted by 2564278112@qq.com 1 month, 2 weeks ago
From: Wang Jiang <jiangwang@kylinos.cn>

In commit 3c021931023a ("drm/amdgpu: replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi")',
the method for determining connector types has been modified.
After the modification, when disconnecting the monitor, the information from the previous connection cannot be retrieved,
because display_info.is_hdmi has been reset, resulting in the connector type returned as dvi.
On AMD Oland and other cards, the audio driver determines whether to turn off audio based on connector type
However, when the monitor is disconnected, the information from the previous connection cannot be obtained, resulting in the inability to turn off the audio.
I don't understand why this is being done, I think the right thing to do is to decide whether or not to enable audio based on whether the connector has audio.
This commit modifies the code to retrieve audio information from the connected EDID.
Now, the decision to turn audio on/off is based on the audio information in the EDID.

Signed-off-by: Wang Jiang <jiangwang@kylinos.cn>
---
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 276c025c4c03..c56b2027d53e 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -3253,17 +3253,22 @@ static void dce_v6_0_encoder_mode_set(struct drm_encoder *encoder,
 			  struct drm_display_mode *adjusted_mode)
 {
 	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
-	int em = amdgpu_atombios_encoder_get_encoder_mode(encoder);
-
+	struct drm_connector *connector;
+	struct amdgpu_connector *amdgpu_connector = NULL;
 	amdgpu_encoder->pixel_clock = adjusted_mode->clock;
 
 	/* need to call this here rather than in prepare() since we need some crtc info */
 	amdgpu_atombios_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+	connector = amdgpu_get_connector_for_encoder_init(encoder);
+	amdgpu_connector = to_amdgpu_connector(connector);
+	if (!amdgpu_connector) {
+		DRM_ERROR("Couldn't find encoder's connector\n");
+	}
 
 	/* set scaler clears this on some chips */
 	dce_v6_0_set_interleave(encoder->crtc, mode);
 
-	if (em == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(em)) {
+	if (drm_detect_monitor_audio(amdgpu_connector_edid(connector))) {
 		dce_v6_0_afmt_enable(encoder, true);
 		dce_v6_0_afmt_setmode(encoder, adjusted_mode);
 	}
@@ -3322,12 +3327,18 @@ static void dce_v6_0_encoder_disable(struct drm_encoder *encoder)
 {
 	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
 	struct amdgpu_encoder_atom_dig *dig;
-	int em = amdgpu_atombios_encoder_get_encoder_mode(encoder);
+	struct drm_connector *connector;
+	struct amdgpu_connector *amdgpu_connector = NULL;
 
 	amdgpu_atombios_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+	connector = amdgpu_get_connector_for_encoder_init(encoder);
+	amdgpu_connector = to_amdgpu_connector(connector);
+	if (!amdgpu_connector) {
+		DRM_ERROR("Couldn't find encoder's connector\n");
+	}
 
 	if (amdgpu_atombios_encoder_is_digital(encoder)) {
-		if (em == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(em))
+		if (drm_detect_monitor_audio(amdgpu_connector_edid(connector)))
 			dce_v6_0_afmt_enable(encoder, false);
 		dig = amdgpu_encoder->enc_priv;
 		dig->dig_encoder = -1;
-- 
2.25.1
Re: [PATCH] drm/amdgpu: Fixed an issue where audio did not turn off properly after unplugging HDMI
Posted by Alex Deucher 1 month, 2 weeks ago
On Fri, Aug 15, 2025 at 11:23 AM <2564278112@qq.com> wrote:
>
> From: Wang Jiang <jiangwang@kylinos.cn>
>
> In commit 3c021931023a ("drm/amdgpu: replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi")',
> the method for determining connector types has been modified.
> After the modification, when disconnecting the monitor, the information from the previous connection cannot be retrieved,
> because display_info.is_hdmi has been reset, resulting in the connector type returned as dvi.
> On AMD Oland and other cards, the audio driver determines whether to turn off audio based on connector type
> However, when the monitor is disconnected, the information from the previous connection cannot be obtained, resulting in the inability to turn off the audio.
> I don't understand why this is being done, I think the right thing to do is to decide whether or not to enable audio based on whether the connector has audio.
> This commit modifies the code to retrieve audio information from the connected EDID.
> Now, the decision to turn audio on/off is based on the audio information in the EDID.
>
> Signed-off-by: Wang Jiang <jiangwang@kylinos.cn>
> ---
>  drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 21 ++++++++++++++++-----

This only fixes up DCE6.  I would suggest one of the following to fix this:
1. Revert the changes from 3c021931023a in atombios_encoders.c
or
2. Add amdgpu_connector->is_hdmi and set it when
connector->display_info.is_hdmi is valid and use that rather than
connector->display_info.is_hdmi.

Alex

>  1 file changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> index 276c025c4c03..c56b2027d53e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
> @@ -3253,17 +3253,22 @@ static void dce_v6_0_encoder_mode_set(struct drm_encoder *encoder,
>                           struct drm_display_mode *adjusted_mode)
>  {
>         struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
> -       int em = amdgpu_atombios_encoder_get_encoder_mode(encoder);
> -
> +       struct drm_connector *connector;
> +       struct amdgpu_connector *amdgpu_connector = NULL;
>         amdgpu_encoder->pixel_clock = adjusted_mode->clock;
>
>         /* need to call this here rather than in prepare() since we need some crtc info */
>         amdgpu_atombios_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
> +       connector = amdgpu_get_connector_for_encoder_init(encoder);
> +       amdgpu_connector = to_amdgpu_connector(connector);
> +       if (!amdgpu_connector) {
> +               DRM_ERROR("Couldn't find encoder's connector\n");
> +       }
>
>         /* set scaler clears this on some chips */
>         dce_v6_0_set_interleave(encoder->crtc, mode);
>
> -       if (em == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(em)) {
> +       if (drm_detect_monitor_audio(amdgpu_connector_edid(connector))) {
>                 dce_v6_0_afmt_enable(encoder, true);
>                 dce_v6_0_afmt_setmode(encoder, adjusted_mode);
>         }
> @@ -3322,12 +3327,18 @@ static void dce_v6_0_encoder_disable(struct drm_encoder *encoder)
>  {
>         struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
>         struct amdgpu_encoder_atom_dig *dig;
> -       int em = amdgpu_atombios_encoder_get_encoder_mode(encoder);
> +       struct drm_connector *connector;
> +       struct amdgpu_connector *amdgpu_connector = NULL;
>
>         amdgpu_atombios_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
> +       connector = amdgpu_get_connector_for_encoder_init(encoder);
> +       amdgpu_connector = to_amdgpu_connector(connector);
> +       if (!amdgpu_connector) {
> +               DRM_ERROR("Couldn't find encoder's connector\n");
> +       }
>
>         if (amdgpu_atombios_encoder_is_digital(encoder)) {
> -               if (em == ATOM_ENCODER_MODE_HDMI || ENCODER_MODE_IS_DP(em))
> +               if (drm_detect_monitor_audio(amdgpu_connector_edid(connector)))
>                         dce_v6_0_afmt_enable(encoder, false);
>                 dig = amdgpu_encoder->enc_priv;
>                 dig->dig_encoder = -1;
> --
> 2.25.1
>
Re: [PATCH] drm/amdgpu: Fixed an issue where audio did not turn off properly after unplugging HDMI
Posted by kernel test robot 1 month, 2 weeks ago
Hi,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-exynos/exynos-drm-next]
[also build test ERROR on linus/master v6.17-rc1 next-20250815]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/2564278112-qq-com/drm-amdgpu-Fixed-an-issue-where-audio-did-not-turn-off-properly-after-unplugging-HDMI/20250815-164929
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
patch link:    https://lore.kernel.org/r/tencent_E5B1CAABB0320691EB730CDB19E55EA85E05%40qq.com
patch subject: [PATCH] drm/amdgpu: Fixed an issue where audio did not turn off properly after unplugging HDMI
config: x86_64-buildonly-randconfig-002-20250816 (https://download.01.org/0day-ci/archive/20250816/202508160829.jfFPh4YJ-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14+deb12u1) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250816/202508160829.jfFPh4YJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202508160829.jfFPh4YJ-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/gpu/drm/amd/amdgpu/dce_v6_0.c: In function 'dce_v6_0_encoder_mode_set':
>> drivers/gpu/drm/amd/amdgpu/dce_v6_0.c:3271:38: error: implicit declaration of function 'amdgpu_connector_edid'; did you mean 'amdgpu_connector_add'? [-Werror=implicit-function-declaration]
    3271 |         if (drm_detect_monitor_audio(amdgpu_connector_edid(connector))) {
         |                                      ^~~~~~~~~~~~~~~~~~~~~
         |                                      amdgpu_connector_add
>> drivers/gpu/drm/amd/amdgpu/dce_v6_0.c:3271:38: warning: passing argument 1 of 'drm_detect_monitor_audio' makes pointer from integer without a cast [-Wint-conversion]
    3271 |         if (drm_detect_monitor_audio(amdgpu_connector_edid(connector))) {
         |                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                      |
         |                                      int
   In file included from drivers/gpu/drm/amd/amdgpu/dce_v6_0.c:26:
   include/drm/drm_edid.h:443:50: note: expected 'const struct edid *' but argument is of type 'int'
     443 | bool drm_detect_monitor_audio(const struct edid *edid);
         |                               ~~~~~~~~~~~~~~~~~~~^~~~
   drivers/gpu/drm/amd/amdgpu/dce_v6_0.c: In function 'dce_v6_0_encoder_disable':
   drivers/gpu/drm/amd/amdgpu/dce_v6_0.c:3341:46: warning: passing argument 1 of 'drm_detect_monitor_audio' makes pointer from integer without a cast [-Wint-conversion]
    3341 |                 if (drm_detect_monitor_audio(amdgpu_connector_edid(connector)))
         |                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                              |
         |                                              int
   include/drm/drm_edid.h:443:50: note: expected 'const struct edid *' but argument is of type 'int'
     443 | bool drm_detect_monitor_audio(const struct edid *edid);
         |                               ~~~~~~~~~~~~~~~~~~~^~~~
   cc1: some warnings being treated as errors


vim +3271 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c

  3250	
  3251	static void dce_v6_0_encoder_mode_set(struct drm_encoder *encoder,
  3252				  struct drm_display_mode *mode,
  3253				  struct drm_display_mode *adjusted_mode)
  3254	{
  3255		struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
  3256		struct drm_connector *connector;
  3257		struct amdgpu_connector *amdgpu_connector = NULL;
  3258		amdgpu_encoder->pixel_clock = adjusted_mode->clock;
  3259	
  3260		/* need to call this here rather than in prepare() since we need some crtc info */
  3261		amdgpu_atombios_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
  3262		connector = amdgpu_get_connector_for_encoder_init(encoder);
  3263		amdgpu_connector = to_amdgpu_connector(connector);
  3264		if (!amdgpu_connector) {
  3265			DRM_ERROR("Couldn't find encoder's connector\n");
  3266		}
  3267	
  3268		/* set scaler clears this on some chips */
  3269		dce_v6_0_set_interleave(encoder->crtc, mode);
  3270	
> 3271		if (drm_detect_monitor_audio(amdgpu_connector_edid(connector))) {
  3272			dce_v6_0_afmt_enable(encoder, true);
  3273			dce_v6_0_afmt_setmode(encoder, adjusted_mode);
  3274		}
  3275	}
  3276	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki