drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
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
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 >
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
© 2016 - 2025 Red Hat, Inc.