All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai-l3A5Bk7waGM@public.gmane.org>
To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw@public.gmane.org
Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: [PATCH 4/4] drm/amdgpu: Add audio component support
Date: Mon, 23 Jul 2018 16:50:30 +0200	[thread overview]
Message-ID: <20180723145030.25133-5-tiwai@suse.de> (raw)
In-Reply-To: <20180723145030.25133-1-tiwai-l3A5Bk7waGM@public.gmane.org>

This patch introduces the HDMI audio component binding like what i915
does to amdgpu driver.  Unlike i915, we need only the hotplug
notification and the ELD query, hence the code is relatively simple,
just adding the hook at each *_audio_enable() call and giving the eld
query by copying the connector->eld contents.

This patch currently doesn't contain the component support for the new
DC codes yet.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/gpu/drm/Kconfig                   |  1 +
 drivers/gpu/drm/amd/amdgpu/Makefile       |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h       |  4 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c | 97 +++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  3 +
 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c    |  6 ++
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c    |  6 ++
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c     |  6 ++
 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c     |  6 ++
 9 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 2c7112ddfed4..fbe7216c5c56 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -193,6 +193,7 @@ config DRM_AMDGPU
 	select BACKLIGHT_LCD_SUPPORT
 	select INTERVAL_TREE
 	select CHASH
+	select SND_HDA_COMPONENT if SND_HDA_CORE
 	help
 	  Choose this option if you have a recent AMD Radeon graphics card.
 
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index bfd332c95b61..9c26facddb17 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -52,7 +52,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
 	amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
 	amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \
 	amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o \
-	amdgpu_ids.o
+	amdgpu_ids.o amdgpu_audio.o
 
 # add asic specific block
 amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index a59c07590cee..203d2584c989 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1957,5 +1957,9 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev );
 static inline int amdgpu_dm_display_resume(struct amdgpu_device *adev) { return 0; }
 #endif
 
+int amdgpu_audio_component_init(struct amdgpu_device *adev);
+void amdgpu_audio_component_fini(struct amdgpu_device *adev);
+void amdgpu_audio_eld_notify(struct amdgpu_device *adev, int pin);
+
 #include "amdgpu_object.h"
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c
new file mode 100644
index 000000000000..39256e2f84b3
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: MIT
+
+#include <linux/component.h>
+#include "amdgpu.h"
+
+static int amdgpu_audio_component_get_eld(struct device *kdev, int port,
+					  int pipe, bool *enabled,
+					  unsigned char *buf, int max_bytes)
+{
+	struct drm_device *dev = dev_get_drvdata(kdev);
+	struct drm_encoder *encoder;
+	struct amdgpu_encoder *amdgpu_encoder;
+	struct amdgpu_encoder_atom_dig *dig;
+	struct drm_connector *connector;
+	int ret = 0;
+
+	*enabled = 0;
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		amdgpu_encoder = to_amdgpu_encoder(encoder);
+		dig = amdgpu_encoder->enc_priv;
+		if (!dig || !dig->afmt || !dig->afmt->enabled)
+			continue;
+		if (!dig->afmt->pin || dig->afmt->pin->id != port)
+			continue;
+		connector = amdgpu_get_connector_for_encoder(encoder);
+		*enabled = !!connector;
+		if (connector) {
+			ret = drm_eld_size(connector->eld);
+			memcpy(buf, connector->eld, min(max_bytes, ret));
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static const struct drm_audio_component_ops amdgpu_audio_component_ops = {
+	.get_eld = amdgpu_audio_component_get_eld,
+};
+
+static int amdgpu_audio_component_bind(struct device *kdev,
+				       struct device *hda_kdev, void *data)
+{
+	struct drm_device *dev = dev_get_drvdata(kdev);
+	struct amdgpu_device *adev = dev->dev_private;
+	struct drm_audio_component *acomp = data;
+
+	acomp->ops = &amdgpu_audio_component_ops;
+	acomp->dev = kdev;
+	adev->mode_info.audio.component = acomp;
+	return 0;
+}
+
+static void amdgpu_audio_component_unbind(struct device *kdev,
+					  struct device *hda_kdev, void *data)
+{
+	struct drm_device *dev = dev_get_drvdata(kdev);
+	struct amdgpu_device *adev = dev->dev_private;
+	struct drm_audio_component *acomp = data;
+
+	acomp->ops = NULL;
+	acomp->dev = NULL;
+	adev->mode_info.audio.component = NULL;
+}
+
+static const struct component_ops amdgpu_audio_component_bind_ops = {
+	.bind	= amdgpu_audio_component_bind,
+	.unbind	= amdgpu_audio_component_unbind,
+};
+
+int amdgpu_audio_component_init(struct amdgpu_device *adev)
+{
+	int err;
+
+	err = component_add(adev->dev, &amdgpu_audio_component_bind_ops);
+	if (err < 0)
+		return err;
+	adev->mode_info.audio.component_registered = true;
+	return 0;
+}
+
+void amdgpu_audio_component_fini(struct amdgpu_device *adev)
+{
+	if (adev->mode_info.audio.component_registered) {
+		component_del(adev->dev, &amdgpu_audio_component_bind_ops);
+		adev->mode_info.audio.component_registered = false;
+	}
+}
+
+void amdgpu_audio_eld_notify(struct amdgpu_device *adev, int pin)
+{
+	struct drm_audio_component *acomp = adev->mode_info.audio.component;
+
+	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
+		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
+						 pin, -1);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b9e9e8b02fb7..7cb1aa97e522 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -39,6 +39,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_audio_component.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/hrtimer.h>
@@ -260,6 +261,8 @@ struct amdgpu_audio {
 	bool enabled;
 	struct amdgpu_audio_pin pin[AMDGPU_MAX_AFMT_BLOCKS];
 	int num_pins;
+	bool component_registered;
+	struct drm_audio_component *component;
 };
 
 struct amdgpu_display_funcs {
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index ada241bfeee9..c8471a59930f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1392,6 +1392,8 @@ static void dce_v10_0_audio_enable(struct amdgpu_device *adev,
 
 	WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 			   enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+	amdgpu_audio_eld_notify(adev, pin->id);
 }
 
 static const u32 pin_offsets[] =
@@ -1430,6 +1432,8 @@ static int dce_v10_0_audio_init(struct amdgpu_device *adev)
 		dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 	}
 
+	amdgpu_audio_component_init(adev);
+
 	return 0;
 }
 
@@ -1443,6 +1447,8 @@ static void dce_v10_0_audio_fini(struct amdgpu_device *adev)
 	if (!adev->mode_info.audio.enabled)
 		return;
 
+	amdgpu_audio_component_fini(adev);
+
 	for (i = 0; i < adev->mode_info.audio.num_pins; i++)
 		dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index a5b96eac3033..49edb74725a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -1418,6 +1418,8 @@ static void dce_v11_0_audio_enable(struct amdgpu_device *adev,
 
 	WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 			   enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+	amdgpu_audio_eld_notify(adev, pin->id);
 }
 
 static const u32 pin_offsets[] =
@@ -1472,6 +1474,8 @@ static int dce_v11_0_audio_init(struct amdgpu_device *adev)
 		dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 	}
 
+	amdgpu_audio_component_init(adev);
+
 	return 0;
 }
 
@@ -1485,6 +1489,8 @@ static void dce_v11_0_audio_fini(struct amdgpu_device *adev)
 	if (!adev->mode_info.audio.enabled)
 		return;
 
+	amdgpu_audio_component_fini(adev);
+
 	for (i = 0; i < adev->mode_info.audio.num_pins; i++)
 		dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 394cc1e8fe20..2b7468eaacca 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1297,6 +1297,8 @@ static void dce_v6_0_audio_enable(struct amdgpu_device *adev,
 
 	WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 			enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+	amdgpu_audio_eld_notify(adev, pin->id);
 }
 
 static const u32 pin_offsets[7] =
@@ -1343,6 +1345,8 @@ static int dce_v6_0_audio_init(struct amdgpu_device *adev)
 		dce_v6_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 	}
 
+	amdgpu_audio_component_init(adev);
+
 	return 0;
 }
 
@@ -1356,6 +1360,8 @@ static void dce_v6_0_audio_fini(struct amdgpu_device *adev)
 	if (!adev->mode_info.audio.enabled)
 		return;
 
+	amdgpu_audio_component_fini(adev);
+
 	for (i = 0; i < adev->mode_info.audio.num_pins; i++)
 		dce_v6_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index c9b9ab8f1b05..c2370ea1f64f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1348,6 +1348,8 @@ static void dce_v8_0_audio_enable(struct amdgpu_device *adev,
 
 	WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 		enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+	amdgpu_audio_eld_notify(adev, pin->id);
 }
 
 static const u32 pin_offsets[7] =
@@ -1395,6 +1397,8 @@ static int dce_v8_0_audio_init(struct amdgpu_device *adev)
 		dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 	}
 
+	amdgpu_audio_component_init(adev);
+
 	return 0;
 }
 
@@ -1408,6 +1412,8 @@ static void dce_v8_0_audio_fini(struct amdgpu_device *adev)
 	if (!adev->mode_info.audio.enabled)
 		return;
 
+	amdgpu_audio_component_fini(adev);
+
 	for (i = 0; i < adev->mode_info.audio.num_pins; i++)
 		dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
 
-- 
2.18.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2018-07-23 14:50 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-23 14:50 [PATCH 0/4] drm_audio_component support for AMD/ATI HDMI codecs Takashi Iwai
     [not found] ` <20180723145030.25133-1-tiwai-l3A5Bk7waGM@public.gmane.org>
2018-07-23 14:50   ` [PATCH 1/4] ALSA: hda/hdmi: Use single mutex unlock in error paths Takashi Iwai
2018-07-23 14:50   ` [PATCH 2/4] ALSA: hda/hdmi: Allow audio component for AMD/ATI HDMI Takashi Iwai
2018-07-23 14:50   ` [PATCH 3/4] drm/radeon: Add audio component support Takashi Iwai
     [not found]     ` <20180723145030.25133-4-tiwai-l3A5Bk7waGM@public.gmane.org>
2018-07-25  3:32       ` 答复: " Qu, Jim
2018-07-23 14:50   ` Takashi Iwai [this message]
2018-07-25  5:38     ` 答复: [PATCH 4/4] drm/amdgpu: " Qu, Jim
2018-07-23 20:53 ` [PATCH 0/4] drm_audio_component support for AMD/ATI HDMI codecs Alex Deucher
     [not found]   ` <CADnq5_MJf-+Xp5177oTf1M2z1ytrGXM1CYG_fyoh7+WQ5bPAPQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-07-24  5:19     ` Takashi Iwai
     [not found] ` <DM3PR12MB0873B23B1B964A05FD647AF599540-4hRkV8tDpBiYEITDcfEJ8AdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2018-07-25  5:28   ` 答复: [PATCH 3/4] drm/radeon: Add audio component support Takashi Iwai
     [not found]     ` <s5h8t5zyjch.wl-tiwai-l3A5Bk7waGM@public.gmane.org>
2018-07-25  5:40       ` jimqu
     [not found] ` <DM3PR12MB087322334203C27EB7C151E499540-4hRkV8tDpBiYEITDcfEJ8AdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2018-07-25  5:46   ` 答复: [PATCH 4/4] drm/amdgpu: " Takashi Iwai
2018-07-25  8:02     ` jimqu
     [not found]       ` <16a47d85-4d09-2087-1959-fd9a039140c9-5C7GfCeVMHo@public.gmane.org>
2018-07-25  8:20         ` y4T�TCH " Takashi Iwai
2018-07-27  4:55           ` jimqu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180723145030.25133-5-tiwai@suse.de \
    --to=tiwai-l3a5bk7wagm@public.gmane.org \
    --cc=alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.