All of lore.kernel.org
 help / color / mirror / Atom feed
* DP audio API changes for identifying displays connected to a port
@ 2016-08-03  2:14 Dhinakaran Pandiyan
  2016-08-03  2:14 ` [PATCH] drm/i915/dp: DP audio API changes for MST Dhinakaran Pandiyan
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Dhinakaran Pandiyan @ 2016-08-03  2:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: tiwai, libin.yang, alsa-devel


An additional parameter has been added to the API's between i915 and audio
drivers to identify display devices that can be connected to the same port.
Currently only the port identity is being shared, but this is not
sufficient as multiple displays can be driven from the same port
(E.g. DP MST). This patch makes the API changes with dummy changes in the
audio driver (Thanks Libin). Implementation to fully enable DP MST audio
will follow later.

Dhinakaran Pandiyan(1):
drm/i915/dp: DP audio API changes for MST
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03  2:14 DP audio API changes for identifying displays connected to a port Dhinakaran Pandiyan
@ 2016-08-03  2:14 ` Dhinakaran Pandiyan
  2016-08-03 13:53   ` Takashi Iwai
                     ` (2 more replies)
  2016-08-03  6:25 ` ✗ Ro.CI.BAT: failure for " Patchwork
  2016-08-03 13:47 ` DP audio API changes for identifying displays connected to a port Takashi Iwai
  2 siblings, 3 replies; 24+ messages in thread
From: Dhinakaran Pandiyan @ 2016-08-03  2:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: alsa-devel, tiwai, libin.yang, Dhinakaran Pandiyan

DP MST provides the capability to send multiple video and audio streams via
one single port. This requires the API's between i915 and audio drivers to
distinguish between audio capable displays connected to a port. This patch
adds this support via an additional parameter 'int dev_id'. The existing
parameter 'port' does not change it's meaning.

dev_id =
	MST	: pipe that the stream originates from
	Non-MST	: -1

Affected APIs:
struct i915_audio_component_ops
-       int (*sync_audio_rate)(struct device *, int port, int rate);
+	int (*sync_audio_rate)(struct device *, int port, int dev_id,
+	     int rate);

-       int (*get_eld)(struct device *, int port, bool *enabled,
-                       unsigned char *buf, int max_bytes);
+       int (*get_eld)(struct device *, int port, int dev_id,
+		       bool *enabled, unsigned char *buf, int max_bytes);

struct i915_audio_component_audio_ops
-       void (*pin_eld_notify)(void *audio_ptr, int port);
+       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);

This patch makes dummy changes in the audio drivers for build to succeed.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h    |  2 +-
 drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
 include/drm/i915_component.h       |  6 +--
 include/sound/hda_i915.h           | 11 ++---
 sound/hda/hdac_i915.c              |  9 +++--
 sound/pci/hda/patch_hdmi.c         |  7 ++--
 6 files changed, 82 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 65ada5d..8e4c8c8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2054,7 +2054,7 @@ struct drm_i915_private {
 	/* perform PHY state sanity checks? */
 	bool chv_phy_assert[2];
 
-	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
+	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
 
 	/*
 	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index 8c493de..cbe44c8 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
 	struct i915_audio_component *acomp = dev_priv->audio_component;
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	enum port port = intel_dig_port->port;
+	enum pipe pipe = crtc->pipe;
+	int dev_id = -1;
+
 
 	connector = drm_select_eld(encoder);
 	if (!connector)
@@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
 		dev_priv->display.audio_codec_enable(connector, intel_encoder,
 						     adjusted_mode);
 
+	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
+		dev_id = pipe;
+
 	mutex_lock(&dev_priv->av_mutex);
 	intel_encoder->audio_connector = connector;
+
 	/* referred in audio callbacks */
-	dev_priv->dig_port_map[port] = intel_encoder;
+	dev_priv->av_enc_map[pipe] = intel_encoder;
 	mutex_unlock(&dev_priv->av_mutex);
 
 	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
-		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
+		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
+						 (int) port, dev_id);
 }
 
 /**
@@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
 void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct i915_audio_component *acomp = dev_priv->audio_component;
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	enum port port = intel_dig_port->port;
+	enum pipe pipe = crtc->pipe;
+	int dev_id = -1;
+
+	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
+		dev_id = pipe;
 
 	if (dev_priv->display.audio_codec_disable)
 		dev_priv->display.audio_codec_disable(intel_encoder);
 
 	mutex_lock(&dev_priv->av_mutex);
 	intel_encoder->audio_connector = NULL;
-	dev_priv->dig_port_map[port] = NULL;
+	dev_priv->av_enc_map[pipe] = NULL;
 	mutex_unlock(&dev_priv->av_mutex);
 
 	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
-		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
+		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
+						 (int) port, dev_id);
 }
 
 /**
@@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
 	return dev_priv->cdclk_freq;
 }
 
-static int i915_audio_component_sync_audio_rate(struct device *dev,
-						int port, int rate)
+static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
+					       int port, int dev_id)
+{
+
+	enum pipe pipe;
+	struct drm_encoder *encoder;
+
+	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
+		return av_enc_map[dev_id];
+
+	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
+
+		if (!av_enc_map[pipe])
+			continue;
+
+		encoder = &av_enc_map[pipe]->base;
+		if (port == enc_to_dig_port(encoder)->port)
+			return av_enc_map[pipe];
+	}
+
+	return NULL;
+
+}
+
+static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
+						int dev_id, int rate)
 {
 	struct drm_i915_private *dev_priv = dev_to_i915(dev);
 	struct intel_encoder *intel_encoder;
@@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
 		return 0;
 
 	mutex_lock(&dev_priv->av_mutex);
+
 	/* 1. get the pipe */
-	intel_encoder = dev_priv->dig_port_map[port];
-	/* intel_encoder might be NULL for DP MST */
+	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
 	if (!intel_encoder || !intel_encoder->base.crtc ||
 	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
 		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
 		err = -ENODEV;
 		goto unlock;
 	}
+
 	crtc = to_intel_crtc(intel_encoder->base.crtc);
 	pipe = crtc->pipe;
 	if (pipe == INVALID_PIPE) {
@@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
 }
 
 static int i915_audio_component_get_eld(struct device *dev, int port,
-					bool *enabled,
+					int dev_id, bool *enabled,
 					unsigned char *buf, int max_bytes)
 {
 	struct drm_i915_private *dev_priv = dev_to_i915(dev);
@@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
 	const u8 *eld;
 	int ret = -EINVAL;
 
+
 	mutex_lock(&dev_priv->av_mutex);
-	intel_encoder = dev_priv->dig_port_map[port];
-	/* intel_encoder might be NULL for DP MST */
-	if (intel_encoder) {
-		ret = 0;
-		*enabled = intel_encoder->audio_connector != NULL;
-		if (*enabled) {
-			eld = intel_encoder->audio_connector->eld;
-			ret = drm_eld_size(eld);
-			memcpy(buf, eld, min(max_bytes, ret));
-		}
+
+	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
+	if (!intel_encoder) {
+		mutex_unlock(&dev_priv->av_mutex);
+		return ret;
+	}
+
+	ret = 0;
+	*enabled = intel_encoder->audio_connector != NULL;
+	if (*enabled) {
+		eld = intel_encoder->audio_connector->eld;
+		ret = drm_eld_size(eld);
+		memcpy(buf, eld, min(max_bytes, ret));
 	}
 
 	mutex_unlock(&dev_priv->av_mutex);
diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index b46fa0e..1419c98 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -64,7 +64,7 @@ struct i915_audio_component_ops {
 	 * Called from audio driver. After audio driver sets the
 	 * sample rate, it will call this function to set n/cts
 	 */
-	int (*sync_audio_rate)(struct device *, int port, int rate);
+	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
 	/**
 	 * @get_eld: fill the audio state and ELD bytes for the given port
 	 *
@@ -77,7 +77,7 @@ struct i915_audio_component_ops {
 	 * Note that the returned size may be over @max_bytes.  Then it
 	 * implies that only a part of ELD has been copied to the buffer.
 	 */
-	int (*get_eld)(struct device *, int port, bool *enabled,
+	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
 		       unsigned char *buf, int max_bytes);
 };
 
@@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
 	 * status accordingly (even when the HDA controller is in power save
 	 * mode).
 	 */
-	void (*pin_eld_notify)(void *audio_ptr, int port);
+	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
 };
 
 /**
diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
index 796cabf..5ab972e 100644
--- a/include/sound/hda_i915.h
+++ b/include/sound/hda_i915.h
@@ -10,8 +10,9 @@
 int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
 int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
 void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
-int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
-int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
+int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
+			     int dev_id, int rate);
+int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
 			   bool *audio_enabled, char *buffer, int max_bytes);
 int snd_hdac_i915_init(struct hdac_bus *bus);
 int snd_hdac_i915_exit(struct hdac_bus *bus);
@@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
 {
 }
 static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
-					   hda_nid_t nid, int rate)
+					   hda_nid_t nid, int dev_id, int rate)
 {
 	return 0;
 }
 static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
-					 bool *audio_enabled, char *buffer,
-					 int max_bytes)
+					 int dev_id, bool *audio_enabled,
+					 char *buffer, int max_bytes)
 {
 	return -ENODEV;
 }
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
index c9af022..6ea63ac 100644
--- a/sound/hda/hdac_i915.c
+++ b/sound/hda/hdac_i915.c
@@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
  * This function sets N/CTS value based on the given sample rate.
  * Returns zero for success, or a negative error code.
  */
-int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
+int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
+			     int dev_id, int rate)
 {
 	struct hdac_bus *bus = codec->bus;
 	struct i915_audio_component *acomp = bus->audio_component;
@@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
 	port = pin2port(codec, nid);
 	if (port < 0)
 		return -EINVAL;
-	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
+	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
 
@@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
  * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
  * that only a part of ELD bytes have been fetched.
  */
-int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
+int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
 			   bool *audio_enabled, char *buffer, int max_bytes)
 {
 	struct hdac_bus *bus = codec->bus;
@@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
 	port = pin2port(codec, nid);
 	if (port < 0)
 		return -EINVAL;
-	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
+	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
 				   buffer, max_bytes);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d0d5ad8..077d48a 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
 
 	mutex_lock(&per_pin->lock);
 	eld->monitor_present = false;
-	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
+	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
 				      &eld->monitor_present, eld->eld_buffer,
 				      ELD_MAX_SIZE);
 	if (size > 0) {
@@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
 	/* Todo: add DP1.2 MST audio support later */
 	if (codec_has_acomp(codec))
-		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
+		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
+					 runtime->rate);
 
 	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
 	mutex_lock(&per_pin->lock);
@@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
 	snd_hda_codec_set_power_to_all(codec, fg, power_state);
 }
 
-static void intel_pin_eld_notify(void *audio_ptr, int port)
+static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
 {
 	struct hda_codec *codec = audio_ptr;
 	int pin_nid;
-- 
2.5.0

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

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

* ✗ Ro.CI.BAT: failure for drm/i915/dp: DP audio API changes for MST
  2016-08-03  2:14 DP audio API changes for identifying displays connected to a port Dhinakaran Pandiyan
  2016-08-03  2:14 ` [PATCH] drm/i915/dp: DP audio API changes for MST Dhinakaran Pandiyan
@ 2016-08-03  6:25 ` Patchwork
  2016-08-03 13:47 ` DP audio API changes for identifying displays connected to a port Takashi Iwai
  2 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2016-08-03  6:25 UTC (permalink / raw)
  To: Pandiyan, Dhinakaran; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/dp: DP audio API changes for MST
URL   : https://patchwork.freedesktop.org/series/10571/
State : failure

== Summary ==

Applying: drm/i915/dp: DP audio API changes for MST
Using index info to reconstruct a base tree...
M	drivers/gpu/drm/i915/intel_audio.c
M	sound/pci/hda/patch_hdmi.c
Falling back to patching base and 3-way merge...
Auto-merging sound/pci/hda/patch_hdmi.c
Auto-merging drivers/gpu/drm/i915/intel_audio.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/intel_audio.c
error: Failed to merge in the changes.
Patch failed at 0001 drm/i915/dp: DP audio API changes for MST
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

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

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

* Re: DP audio API changes for identifying displays connected to a port
  2016-08-03  2:14 DP audio API changes for identifying displays connected to a port Dhinakaran Pandiyan
  2016-08-03  2:14 ` [PATCH] drm/i915/dp: DP audio API changes for MST Dhinakaran Pandiyan
  2016-08-03  6:25 ` ✗ Ro.CI.BAT: failure for " Patchwork
@ 2016-08-03 13:47 ` Takashi Iwai
  2 siblings, 0 replies; 24+ messages in thread
From: Takashi Iwai @ 2016-08-03 13:47 UTC (permalink / raw)
  To: Dhinakaran Pandiyan; +Cc: intel-gfx, alsa-devel, libin.yang

On Wed, 03 Aug 2016 04:14:29 +0200,
Dhinakaran Pandiyan wrote:
> 
> 
> An additional parameter has been added to the API's between i915 and audio
> drivers to identify display devices that can be connected to the same port.
> Currently only the port identity is being shared, but this is not
> sufficient as multiple displays can be driven from the same port
> (E.g. DP MST). This patch makes the API changes with dummy changes in the
> audio driver (Thanks Libin). Implementation to fully enable DP MST audio
> will follow later.

You should put this rather in the patch description, as it's a single
patch.


thanks,

Takashi


> 
> Dhinakaran Pandiyan(1):
> drm/i915/dp: DP audio API changes for MST
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03  2:14 ` [PATCH] drm/i915/dp: DP audio API changes for MST Dhinakaran Pandiyan
@ 2016-08-03 13:53   ` Takashi Iwai
  2016-08-03 18:52     ` Pandiyan, Dhinakaran
  2016-08-03 19:08   ` Ville Syrjälä
  2016-08-05  2:35   ` Yang, Libin
  2 siblings, 1 reply; 24+ messages in thread
From: Takashi Iwai @ 2016-08-03 13:53 UTC (permalink / raw)
  To: Dhinakaran Pandiyan; +Cc: intel-gfx, alsa-devel, libin.yang

On Wed, 03 Aug 2016 04:14:30 +0200,
Dhinakaran Pandiyan wrote:
> 
> DP MST provides the capability to send multiple video and audio streams via
> one single port. This requires the API's between i915 and audio drivers to
> distinguish between audio capable displays connected to a port. This patch
> adds this support via an additional parameter 'int dev_id'. The existing
> parameter 'port' does not change it's meaning.
> 
> dev_id =
> 	MST	: pipe that the stream originates from
> 	Non-MST	: -1
> 
> Affected APIs:
> struct i915_audio_component_ops
> -       int (*sync_audio_rate)(struct device *, int port, int rate);
> +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> +	     int rate);
> 
> -       int (*get_eld)(struct device *, int port, bool *enabled,
> -                       unsigned char *buf, int max_bytes);
> +       int (*get_eld)(struct device *, int port, int dev_id,
> +		       bool *enabled, unsigned char *buf, int max_bytes);
> 
> struct i915_audio_component_audio_ops
> -       void (*pin_eld_notify)(void *audio_ptr, int port);
> +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> 
> This patch makes dummy changes in the audio drivers for build to succeed.

OK, so the explicit dev_id will be passed in future change in the
audio side, right?  It'd be good to write up the grand plan.


> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
>  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
>  include/drm/i915_component.h       |  6 +--
>  include/sound/hda_i915.h           | 11 ++---
>  sound/hda/hdac_i915.c              |  9 +++--
>  sound/pci/hda/patch_hdmi.c         |  7 ++--
>  6 files changed, 82 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 65ada5d..8e4c8c8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2054,7 +2054,7 @@ struct drm_i915_private {
>  	/* perform PHY state sanity checks? */
>  	bool chv_phy_assert[2];
>  
> -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];

Better to have a comment for this field.


> -static int i915_audio_component_sync_audio_rate(struct device *dev,
> -						int port, int rate)
> +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> +					       int port, int dev_id)
> +{
> +
> +	enum pipe pipe;
> +	struct drm_encoder *encoder;
> +
> +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> +		return av_enc_map[dev_id];

Actually dev_id >= I915_MAX_PIPES is an invalid call, and worth to
catch with WARN_ON() and bail out.


thanks,

Takashi
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03 13:53   ` Takashi Iwai
@ 2016-08-03 18:52     ` Pandiyan, Dhinakaran
  0 siblings, 0 replies; 24+ messages in thread
From: Pandiyan, Dhinakaran @ 2016-08-03 18:52 UTC (permalink / raw)
  To: tiwai; +Cc: intel-gfx, alsa-devel, libin.yang

On Wed, 2016-08-03 at 15:53 +0200, Takashi Iwai wrote:
> On Wed, 03 Aug 2016 04:14:30 +0200,
> Dhinakaran Pandiyan wrote:
> > 
> > DP MST provides the capability to send multiple video and audio streams via
> > one single port. This requires the API's between i915 and audio drivers to
> > distinguish between audio capable displays connected to a port. This patch
> > adds this support via an additional parameter 'int dev_id'. The existing
> > parameter 'port' does not change it's meaning.
> > 
> > dev_id =
> > 	MST	: pipe that the stream originates from
> > 	Non-MST	: -1
> > 
> > Affected APIs:
> > struct i915_audio_component_ops
> > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > +	     int rate);
> > 
> > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > -                       unsigned char *buf, int max_bytes);
> > +       int (*get_eld)(struct device *, int port, int dev_id,
> > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > 
> > struct i915_audio_component_audio_ops
> > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > 
> > This patch makes dummy changes in the audio drivers for build to succeed.
> 
> OK, so the explicit dev_id will be passed in future change in the
> audio side, right?  It'd be good to write up the grand plan.
> 
Yes, that's right. I will explain that and copy the cover-letter text
here.

> 
> > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> >  include/drm/i915_component.h       |  6 +--
> >  include/sound/hda_i915.h           | 11 ++---
> >  sound/hda/hdac_i915.c              |  9 +++--
> >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> >  6 files changed, 82 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 65ada5d..8e4c8c8 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> >  	/* perform PHY state sanity checks? */
> >  	bool chv_phy_assert[2];
> >  
> > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> 
> Better to have a comment for this field.
Will add one.
> 
> 
> > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > -						int port, int rate)
> > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > +					       int port, int dev_id)
> > +{
> > +
> > +	enum pipe pipe;
> > +	struct drm_encoder *encoder;
> > +
> > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > +		return av_enc_map[dev_id];
> 
> Actually dev_id >= I915_MAX_PIPES is an invalid call, and worth to
> catch with WARN_ON() and bail out.
Sure, thanks for the review.
> 
> thanks,
> 
> Takashi
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03  2:14 ` [PATCH] drm/i915/dp: DP audio API changes for MST Dhinakaran Pandiyan
  2016-08-03 13:53   ` Takashi Iwai
@ 2016-08-03 19:08   ` Ville Syrjälä
  2016-08-03 19:43     ` Pandiyan, Dhinakaran
  2016-08-04 17:18     ` Jim Bride
  2016-08-05  2:35   ` Yang, Libin
  2 siblings, 2 replies; 24+ messages in thread
From: Ville Syrjälä @ 2016-08-03 19:08 UTC (permalink / raw)
  To: Dhinakaran Pandiyan; +Cc: tiwai, intel-gfx, alsa-devel, libin.yang

On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> DP MST provides the capability to send multiple video and audio streams via
> one single port. This requires the API's between i915 and audio drivers to
> distinguish between audio capable displays connected to a port. This patch
> adds this support via an additional parameter 'int dev_id'. The existing
> parameter 'port' does not change it's meaning.
> 
> dev_id =
> 	MST	: pipe that the stream originates from
> 	Non-MST	: -1
> 
> Affected APIs:
> struct i915_audio_component_ops
> -       int (*sync_audio_rate)(struct device *, int port, int rate);
> +	int (*sync_audio_rate)(struct device *, int port, int dev_id,

Does the term 'dev_id' have some special meaning on the audio side? On
the i915 side things would be less confusing if we just called it
'pipe'.

> +	     int rate);
> 
> -       int (*get_eld)(struct device *, int port, bool *enabled,
> -                       unsigned char *buf, int max_bytes);
> +       int (*get_eld)(struct device *, int port, int dev_id,
> +		       bool *enabled, unsigned char *buf, int max_bytes);
> 
> struct i915_audio_component_audio_ops
> -       void (*pin_eld_notify)(void *audio_ptr, int port);
> +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> 
> This patch makes dummy changes in the audio drivers for build to succeed.
> 
> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
>  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
>  include/drm/i915_component.h       |  6 +--
>  include/sound/hda_i915.h           | 11 ++---
>  sound/hda/hdac_i915.c              |  9 +++--
>  sound/pci/hda/patch_hdmi.c         |  7 ++--
>  6 files changed, 82 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 65ada5d..8e4c8c8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2054,7 +2054,7 @@ struct drm_i915_private {
>  	/* perform PHY state sanity checks? */
>  	bool chv_phy_assert[2];
>  
> -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
>  
>  	/*
>  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> index 8c493de..cbe44c8 100644
> --- a/drivers/gpu/drm/i915/intel_audio.c
> +++ b/drivers/gpu/drm/i915/intel_audio.c
> @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
>  	struct i915_audio_component *acomp = dev_priv->audio_component;
>  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
>  	enum port port = intel_dig_port->port;
> +	enum pipe pipe = crtc->pipe;
> +	int dev_id = -1;
> +
>  
>  	connector = drm_select_eld(encoder);
>  	if (!connector)
> @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
>  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
>  						     adjusted_mode);
>  
> +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> +		dev_id = pipe;
> +
>  	mutex_lock(&dev_priv->av_mutex);
>  	intel_encoder->audio_connector = connector;
> +
>  	/* referred in audio callbacks */
> -	dev_priv->dig_port_map[port] = intel_encoder;
> +	dev_priv->av_enc_map[pipe] = intel_encoder;
>  	mutex_unlock(&dev_priv->av_mutex);
>  
>  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> +						 (int) port, dev_id);
>  }
>  
>  /**
> @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
>  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
>  {
>  	struct drm_encoder *encoder = &intel_encoder->base;
> +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct i915_audio_component *acomp = dev_priv->audio_component;
>  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
>  	enum port port = intel_dig_port->port;
> +	enum pipe pipe = crtc->pipe;
> +	int dev_id = -1;
> +
> +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> +		dev_id = pipe;
>  
>  	if (dev_priv->display.audio_codec_disable)
>  		dev_priv->display.audio_codec_disable(intel_encoder);
>  
>  	mutex_lock(&dev_priv->av_mutex);
>  	intel_encoder->audio_connector = NULL;
> -	dev_priv->dig_port_map[port] = NULL;
> +	dev_priv->av_enc_map[pipe] = NULL;
>  	mutex_unlock(&dev_priv->av_mutex);
>  
>  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> +						 (int) port, dev_id);
>  }
>  
>  /**
> @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
>  	return dev_priv->cdclk_freq;
>  }
>  
> -static int i915_audio_component_sync_audio_rate(struct device *dev,
> -						int port, int rate)
> +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> +					       int port, int dev_id)
> +{
> +
> +	enum pipe pipe;
> +	struct drm_encoder *encoder;
> +
> +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> +		return av_enc_map[dev_id];
> +
> +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> +
> +		if (!av_enc_map[pipe])
> +			continue;
> +
> +		encoder = &av_enc_map[pipe]->base;
> +		if (port == enc_to_dig_port(encoder)->port)
> +			return av_enc_map[pipe];
> +	}
> +
> +	return NULL;
> +
> +}
> +
> +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> +						int dev_id, int rate)
>  {
>  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
>  	struct intel_encoder *intel_encoder;
> @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
>  		return 0;
>  
>  	mutex_lock(&dev_priv->av_mutex);
> +
>  	/* 1. get the pipe */
> -	intel_encoder = dev_priv->dig_port_map[port];
> -	/* intel_encoder might be NULL for DP MST */
> +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
>  	if (!intel_encoder || !intel_encoder->base.crtc ||
>  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
>  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
>  		err = -ENODEV;
>  		goto unlock;
>  	}
> +
>  	crtc = to_intel_crtc(intel_encoder->base.crtc);
>  	pipe = crtc->pipe;
>  	if (pipe == INVALID_PIPE) {
> @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
>  }
>  
>  static int i915_audio_component_get_eld(struct device *dev, int port,
> -					bool *enabled,
> +					int dev_id, bool *enabled,
>  					unsigned char *buf, int max_bytes)
>  {
>  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
>  	const u8 *eld;
>  	int ret = -EINVAL;
>  
> +
>  	mutex_lock(&dev_priv->av_mutex);
> -	intel_encoder = dev_priv->dig_port_map[port];
> -	/* intel_encoder might be NULL for DP MST */
> -	if (intel_encoder) {
> -		ret = 0;
> -		*enabled = intel_encoder->audio_connector != NULL;
> -		if (*enabled) {
> -			eld = intel_encoder->audio_connector->eld;
> -			ret = drm_eld_size(eld);
> -			memcpy(buf, eld, min(max_bytes, ret));
> -		}
> +
> +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> +	if (!intel_encoder) {
> +		mutex_unlock(&dev_priv->av_mutex);
> +		return ret;
> +	}
> +
> +	ret = 0;
> +	*enabled = intel_encoder->audio_connector != NULL;
> +	if (*enabled) {
> +		eld = intel_encoder->audio_connector->eld;
> +		ret = drm_eld_size(eld);
> +		memcpy(buf, eld, min(max_bytes, ret));
>  	}
>  
>  	mutex_unlock(&dev_priv->av_mutex);
> diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> index b46fa0e..1419c98 100644
> --- a/include/drm/i915_component.h
> +++ b/include/drm/i915_component.h
> @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
>  	 * Called from audio driver. After audio driver sets the
>  	 * sample rate, it will call this function to set n/cts
>  	 */
> -	int (*sync_audio_rate)(struct device *, int port, int rate);
> +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
>  	/**
>  	 * @get_eld: fill the audio state and ELD bytes for the given port
>  	 *
> @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
>  	 * Note that the returned size may be over @max_bytes.  Then it
>  	 * implies that only a part of ELD has been copied to the buffer.
>  	 */
> -	int (*get_eld)(struct device *, int port, bool *enabled,
> +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
>  		       unsigned char *buf, int max_bytes);
>  };
>  
> @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
>  	 * status accordingly (even when the HDA controller is in power save
>  	 * mode).
>  	 */
> -	void (*pin_eld_notify)(void *audio_ptr, int port);
> +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
>  };
>  
>  /**
> diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> index 796cabf..5ab972e 100644
> --- a/include/sound/hda_i915.h
> +++ b/include/sound/hda_i915.h
> @@ -10,8 +10,9 @@
>  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
>  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
>  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> +			     int dev_id, int rate);
> +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
>  			   bool *audio_enabled, char *buffer, int max_bytes);
>  int snd_hdac_i915_init(struct hdac_bus *bus);
>  int snd_hdac_i915_exit(struct hdac_bus *bus);
> @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
>  {
>  }
>  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> -					   hda_nid_t nid, int rate)
> +					   hda_nid_t nid, int dev_id, int rate)
>  {
>  	return 0;
>  }
>  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> -					 bool *audio_enabled, char *buffer,
> -					 int max_bytes)
> +					 int dev_id, bool *audio_enabled,
> +					 char *buffer, int max_bytes)
>  {
>  	return -ENODEV;
>  }
> diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> index c9af022..6ea63ac 100644
> --- a/sound/hda/hdac_i915.c
> +++ b/sound/hda/hdac_i915.c
> @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
>   * This function sets N/CTS value based on the given sample rate.
>   * Returns zero for success, or a negative error code.
>   */
> -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> +			     int dev_id, int rate)
>  {
>  	struct hdac_bus *bus = codec->bus;
>  	struct i915_audio_component *acomp = bus->audio_component;
> @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
>  	port = pin2port(codec, nid);
>  	if (port < 0)
>  		return -EINVAL;
> -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
>  }
>  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
>  
> @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
>   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
>   * that only a part of ELD bytes have been fetched.
>   */
> -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
>  			   bool *audio_enabled, char *buffer, int max_bytes)
>  {
>  	struct hdac_bus *bus = codec->bus;
> @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
>  	port = pin2port(codec, nid);
>  	if (port < 0)
>  		return -EINVAL;
> -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
>  				   buffer, max_bytes);
>  }
>  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> index d0d5ad8..077d48a 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
>  
>  	mutex_lock(&per_pin->lock);
>  	eld->monitor_present = false;
> -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
>  				      &eld->monitor_present, eld->eld_buffer,
>  				      ELD_MAX_SIZE);
>  	if (size > 0) {
> @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
>  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
>  	/* Todo: add DP1.2 MST audio support later */
>  	if (codec_has_acomp(codec))
> -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> +					 runtime->rate);
>  
>  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
>  	mutex_lock(&per_pin->lock);
> @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
>  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
>  }
>  
> -static void intel_pin_eld_notify(void *audio_ptr, int port)
> +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
>  {
>  	struct hda_codec *codec = audio_ptr;
>  	int pin_nid;
> -- 
> 2.5.0

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03 19:08   ` Ville Syrjälä
@ 2016-08-03 19:43     ` Pandiyan, Dhinakaran
  2016-08-03 20:28       ` Ville Syrjälä
  2016-08-04 17:18     ` Jim Bride
  1 sibling, 1 reply; 24+ messages in thread
From: Pandiyan, Dhinakaran @ 2016-08-03 19:43 UTC (permalink / raw)
  To: ville.syrjala; +Cc: tiwai, libin.yang, intel-gfx, alsa-devel

On Wed, 2016-08-03 at 22:08 +0300, Ville Syrjälä wrote:
> On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > DP MST provides the capability to send multiple video and audio streams via
> > one single port. This requires the API's between i915 and audio drivers to
> > distinguish between audio capable displays connected to a port. This patch
> > adds this support via an additional parameter 'int dev_id'. The existing
> > parameter 'port' does not change it's meaning.
> > 
> > dev_id =
> > 	MST	: pipe that the stream originates from
> > 	Non-MST	: -1
> > 
> > Affected APIs:
> > struct i915_audio_component_ops
> > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> 
> Does the term 'dev_id' have some special meaning on the audio side? On
> the i915 side things would be less confusing if we just called it
> 'pipe'.
> 

There was quite a bit of back and forth on this. "pipe" seemed to tie us
to the gfx hardware architecture. In case, there is no 1:1 mapping from
pipes to encoders, this will get confusing as i915 audio registers
(E.g.HSW_AUD_PIN_ELD_CP_VLD) are encoder based. Whereas, dev_id is
generic - HDA spec calls them "devices" or "device entry"


> > +	     int rate);
> > 
> > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > -                       unsigned char *buf, int max_bytes);
> > +       int (*get_eld)(struct device *, int port, int dev_id,
> > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > 
> > struct i915_audio_component_audio_ops
> > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > 
> > This patch makes dummy changes in the audio drivers for build to succeed.
> > 
> > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> >  include/drm/i915_component.h       |  6 +--
> >  include/sound/hda_i915.h           | 11 ++---
> >  sound/hda/hdac_i915.c              |  9 +++--
> >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> >  6 files changed, 82 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 65ada5d..8e4c8c8 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> >  	/* perform PHY state sanity checks? */
> >  	bool chv_phy_assert[2];
> >  
> > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> >  
> >  	/*
> >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> > index 8c493de..cbe44c8 100644
> > --- a/drivers/gpu/drm/i915/intel_audio.c
> > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> >  	enum port port = intel_dig_port->port;
> > +	enum pipe pipe = crtc->pipe;
> > +	int dev_id = -1;
> > +
> >  
> >  	connector = drm_select_eld(encoder);
> >  	if (!connector)
> > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> >  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
> >  						     adjusted_mode);
> >  
> > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > +		dev_id = pipe;
> > +
> >  	mutex_lock(&dev_priv->av_mutex);
> >  	intel_encoder->audio_connector = connector;
> > +
> >  	/* referred in audio callbacks */
> > -	dev_priv->dig_port_map[port] = intel_encoder;
> > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> >  	mutex_unlock(&dev_priv->av_mutex);
> >  
> >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > +						 (int) port, dev_id);
> >  }
> >  
> >  /**
> > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> >  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
> >  {
> >  	struct drm_encoder *encoder = &intel_encoder->base;
> > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> >  	struct drm_device *dev = encoder->dev;
> >  	struct drm_i915_private *dev_priv = to_i915(dev);
> >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> >  	enum port port = intel_dig_port->port;
> > +	enum pipe pipe = crtc->pipe;
> > +	int dev_id = -1;
> > +
> > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > +		dev_id = pipe;
> >  
> >  	if (dev_priv->display.audio_codec_disable)
> >  		dev_priv->display.audio_codec_disable(intel_encoder);
> >  
> >  	mutex_lock(&dev_priv->av_mutex);
> >  	intel_encoder->audio_connector = NULL;
> > -	dev_priv->dig_port_map[port] = NULL;
> > +	dev_priv->av_enc_map[pipe] = NULL;
> >  	mutex_unlock(&dev_priv->av_mutex);
> >  
> >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > +						 (int) port, dev_id);
> >  }
> >  
> >  /**
> > @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
> >  	return dev_priv->cdclk_freq;
> >  }
> >  
> > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > -						int port, int rate)
> > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > +					       int port, int dev_id)
> > +{
> > +
> > +	enum pipe pipe;
> > +	struct drm_encoder *encoder;
> > +
> > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > +		return av_enc_map[dev_id];
> > +
> > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > +
> > +		if (!av_enc_map[pipe])
> > +			continue;
> > +
> > +		encoder = &av_enc_map[pipe]->base;
> > +		if (port == enc_to_dig_port(encoder)->port)
> > +			return av_enc_map[pipe];
> > +	}
> > +
> > +	return NULL;
> > +
> > +}
> > +
> > +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> > +						int dev_id, int rate)
> >  {
> >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> >  	struct intel_encoder *intel_encoder;
> > @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> >  		return 0;
> >  
> >  	mutex_lock(&dev_priv->av_mutex);
> > +
> >  	/* 1. get the pipe */
> > -	intel_encoder = dev_priv->dig_port_map[port];
> > -	/* intel_encoder might be NULL for DP MST */
> > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> >  		err = -ENODEV;
> >  		goto unlock;
> >  	}
> > +
> >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> >  	pipe = crtc->pipe;
> >  	if (pipe == INVALID_PIPE) {
> > @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> >  }
> >  
> >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > -					bool *enabled,
> > +					int dev_id, bool *enabled,
> >  					unsigned char *buf, int max_bytes)
> >  {
> >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
> >  	const u8 *eld;
> >  	int ret = -EINVAL;
> >  
> > +
> >  	mutex_lock(&dev_priv->av_mutex);
> > -	intel_encoder = dev_priv->dig_port_map[port];
> > -	/* intel_encoder might be NULL for DP MST */
> > -	if (intel_encoder) {
> > -		ret = 0;
> > -		*enabled = intel_encoder->audio_connector != NULL;
> > -		if (*enabled) {
> > -			eld = intel_encoder->audio_connector->eld;
> > -			ret = drm_eld_size(eld);
> > -			memcpy(buf, eld, min(max_bytes, ret));
> > -		}
> > +
> > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > +	if (!intel_encoder) {
> > +		mutex_unlock(&dev_priv->av_mutex);
> > +		return ret;
> > +	}
> > +
> > +	ret = 0;
> > +	*enabled = intel_encoder->audio_connector != NULL;
> > +	if (*enabled) {
> > +		eld = intel_encoder->audio_connector->eld;
> > +		ret = drm_eld_size(eld);
> > +		memcpy(buf, eld, min(max_bytes, ret));
> >  	}
> >  
> >  	mutex_unlock(&dev_priv->av_mutex);
> > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > index b46fa0e..1419c98 100644
> > --- a/include/drm/i915_component.h
> > +++ b/include/drm/i915_component.h
> > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> >  	 * Called from audio driver. After audio driver sets the
> >  	 * sample rate, it will call this function to set n/cts
> >  	 */
> > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
> >  	/**
> >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> >  	 *
> > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> >  	 * Note that the returned size may be over @max_bytes.  Then it
> >  	 * implies that only a part of ELD has been copied to the buffer.
> >  	 */
> > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> >  		       unsigned char *buf, int max_bytes);
> >  };
> >  
> > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> >  	 * status accordingly (even when the HDA controller is in power save
> >  	 * mode).
> >  	 */
> > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> >  };
> >  
> >  /**
> > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > index 796cabf..5ab972e 100644
> > --- a/include/sound/hda_i915.h
> > +++ b/include/sound/hda_i915.h
> > @@ -10,8 +10,9 @@
> >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> >  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
> >  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > +			     int dev_id, int rate);
> > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> >  			   bool *audio_enabled, char *buffer, int max_bytes);
> >  int snd_hdac_i915_init(struct hdac_bus *bus);
> >  int snd_hdac_i915_exit(struct hdac_bus *bus);
> > @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> >  {
> >  }
> >  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > -					   hda_nid_t nid, int rate)
> > +					   hda_nid_t nid, int dev_id, int rate)
> >  {
> >  	return 0;
> >  }
> >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > -					 bool *audio_enabled, char *buffer,
> > -					 int max_bytes)
> > +					 int dev_id, bool *audio_enabled,
> > +					 char *buffer, int max_bytes)
> >  {
> >  	return -ENODEV;
> >  }
> > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> > index c9af022..6ea63ac 100644
> > --- a/sound/hda/hdac_i915.c
> > +++ b/sound/hda/hdac_i915.c
> > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
> >   * This function sets N/CTS value based on the given sample rate.
> >   * Returns zero for success, or a negative error code.
> >   */
> > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > +			     int dev_id, int rate)
> >  {
> >  	struct hdac_bus *bus = codec->bus;
> >  	struct i915_audio_component *acomp = bus->audio_component;
> > @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> >  	port = pin2port(codec, nid);
> >  	if (port < 0)
> >  		return -EINVAL;
> > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> >  }
> >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> >  
> > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> >   * that only a part of ELD bytes have been fetched.
> >   */
> > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> >  			   bool *audio_enabled, char *buffer, int max_bytes)
> >  {
> >  	struct hdac_bus *bus = codec->bus;
> > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> >  	port = pin2port(codec, nid);
> >  	if (port < 0)
> >  		return -EINVAL;
> > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
> >  				   buffer, max_bytes);
> >  }
> >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > index d0d5ad8..077d48a 100644
> > --- a/sound/pci/hda/patch_hdmi.c
> > +++ b/sound/pci/hda/patch_hdmi.c
> > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
> >  
> >  	mutex_lock(&per_pin->lock);
> >  	eld->monitor_present = false;
> > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> >  				      &eld->monitor_present, eld->eld_buffer,
> >  				      ELD_MAX_SIZE);
> >  	if (size > 0) {
> > @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> >  	/* Todo: add DP1.2 MST audio support later */
> >  	if (codec_has_acomp(codec))
> > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > +					 runtime->rate);
> >  
> >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> >  	mutex_lock(&per_pin->lock);
> > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
> >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
> >  }
> >  
> > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> >  {
> >  	struct hda_codec *codec = audio_ptr;
> >  	int pin_nid;
> > -- 
> > 2.5.0
> 

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03 19:43     ` Pandiyan, Dhinakaran
@ 2016-08-03 20:28       ` Ville Syrjälä
  2016-08-03 21:42         ` Pandiyan, Dhinakaran
  0 siblings, 1 reply; 24+ messages in thread
From: Ville Syrjälä @ 2016-08-03 20:28 UTC (permalink / raw)
  To: Pandiyan, Dhinakaran; +Cc: tiwai, libin.yang, intel-gfx, alsa-devel

On Wed, Aug 03, 2016 at 07:43:06PM +0000, Pandiyan, Dhinakaran wrote:
> On Wed, 2016-08-03 at 22:08 +0300, Ville Syrjälä wrote:
> > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > DP MST provides the capability to send multiple video and audio streams via
> > > one single port. This requires the API's between i915 and audio drivers to
> > > distinguish between audio capable displays connected to a port. This patch
> > > adds this support via an additional parameter 'int dev_id'. The existing
> > > parameter 'port' does not change it's meaning.
> > > 
> > > dev_id =
> > > 	MST	: pipe that the stream originates from
> > > 	Non-MST	: -1
> > > 
> > > Affected APIs:
> > > struct i915_audio_component_ops
> > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > 
> > Does the term 'dev_id' have some special meaning on the audio side? On
> > the i915 side things would be less confusing if we just called it
> > 'pipe'.
> > 
> 
> There was quite a bit of back and forth on this. "pipe" seemed to tie us
> to the gfx hardware architecture. In case, there is no 1:1 mapping from
> pipes to encoders, this will get confusing as i915 audio registers
> (E.g.HSW_AUD_PIN_ELD_CP_VLD) are encoder based.

I'm not following. Looking at the current i915 audio code, on HSW+
everything is pipe based.

> Whereas, dev_id is
> generic - HDA spec calls them "devices" or "device entry"

Generic and totally unclear what it means from graphics side.

pipe and port are the only things we really have in i915. If those aren't
good enough for the audio side, then I think we should have some decent
code to remap between the pipe+port vs. whatever audio side id is needed.
I don't really care on which side of the border such code would live, as
long as it's clear what it's doing.

> 
> > > +	     int rate);
> > > 
> > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > -                       unsigned char *buf, int max_bytes);
> > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > > 
> > > struct i915_audio_component_audio_ops
> > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > 
> > > This patch makes dummy changes in the audio drivers for build to succeed.
> > > 
> > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> > >  include/drm/i915_component.h       |  6 +--
> > >  include/sound/hda_i915.h           | 11 ++---
> > >  sound/hda/hdac_i915.c              |  9 +++--
> > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index 65ada5d..8e4c8c8 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > >  	/* perform PHY state sanity checks? */
> > >  	bool chv_phy_assert[2];
> > >  
> > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> > >  
> > >  	/*
> > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> > > index 8c493de..cbe44c8 100644
> > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > >  	enum port port = intel_dig_port->port;
> > > +	enum pipe pipe = crtc->pipe;
> > > +	int dev_id = -1;
> > > +
> > >  
> > >  	connector = drm_select_eld(encoder);
> > >  	if (!connector)
> > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > >  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
> > >  						     adjusted_mode);
> > >  
> > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > +		dev_id = pipe;
> > > +
> > >  	mutex_lock(&dev_priv->av_mutex);
> > >  	intel_encoder->audio_connector = connector;
> > > +
> > >  	/* referred in audio callbacks */
> > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > >  
> > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > +						 (int) port, dev_id);
> > >  }
> > >  
> > >  /**
> > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > >  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
> > >  {
> > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > >  	struct drm_device *dev = encoder->dev;
> > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > >  	enum port port = intel_dig_port->port;
> > > +	enum pipe pipe = crtc->pipe;
> > > +	int dev_id = -1;
> > > +
> > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > +		dev_id = pipe;
> > >  
> > >  	if (dev_priv->display.audio_codec_disable)
> > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > >  
> > >  	mutex_lock(&dev_priv->av_mutex);
> > >  	intel_encoder->audio_connector = NULL;
> > > -	dev_priv->dig_port_map[port] = NULL;
> > > +	dev_priv->av_enc_map[pipe] = NULL;
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > >  
> > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > +						 (int) port, dev_id);
> > >  }
> > >  
> > >  /**
> > > @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
> > >  	return dev_priv->cdclk_freq;
> > >  }
> > >  
> > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > -						int port, int rate)
> > > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > > +					       int port, int dev_id)
> > > +{
> > > +
> > > +	enum pipe pipe;
> > > +	struct drm_encoder *encoder;
> > > +
> > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > +		return av_enc_map[dev_id];
> > > +
> > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > +
> > > +		if (!av_enc_map[pipe])
> > > +			continue;
> > > +
> > > +		encoder = &av_enc_map[pipe]->base;
> > > +		if (port == enc_to_dig_port(encoder)->port)
> > > +			return av_enc_map[pipe];
> > > +	}
> > > +
> > > +	return NULL;
> > > +
> > > +}
> > > +
> > > +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> > > +						int dev_id, int rate)
> > >  {
> > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > >  	struct intel_encoder *intel_encoder;
> > > @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > >  		return 0;
> > >  
> > >  	mutex_lock(&dev_priv->av_mutex);
> > > +
> > >  	/* 1. get the pipe */
> > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > -	/* intel_encoder might be NULL for DP MST */
> > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > >  		err = -ENODEV;
> > >  		goto unlock;
> > >  	}
> > > +
> > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > >  	pipe = crtc->pipe;
> > >  	if (pipe == INVALID_PIPE) {
> > > @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > >  }
> > >  
> > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > -					bool *enabled,
> > > +					int dev_id, bool *enabled,
> > >  					unsigned char *buf, int max_bytes)
> > >  {
> > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
> > >  	const u8 *eld;
> > >  	int ret = -EINVAL;
> > >  
> > > +
> > >  	mutex_lock(&dev_priv->av_mutex);
> > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > -	/* intel_encoder might be NULL for DP MST */
> > > -	if (intel_encoder) {
> > > -		ret = 0;
> > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > -		if (*enabled) {
> > > -			eld = intel_encoder->audio_connector->eld;
> > > -			ret = drm_eld_size(eld);
> > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > -		}
> > > +
> > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > +	if (!intel_encoder) {
> > > +		mutex_unlock(&dev_priv->av_mutex);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = 0;
> > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > +	if (*enabled) {
> > > +		eld = intel_encoder->audio_connector->eld;
> > > +		ret = drm_eld_size(eld);
> > > +		memcpy(buf, eld, min(max_bytes, ret));
> > >  	}
> > >  
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > > index b46fa0e..1419c98 100644
> > > --- a/include/drm/i915_component.h
> > > +++ b/include/drm/i915_component.h
> > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > >  	 * Called from audio driver. After audio driver sets the
> > >  	 * sample rate, it will call this function to set n/cts
> > >  	 */
> > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
> > >  	/**
> > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > >  	 *
> > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > >  	 * implies that only a part of ELD has been copied to the buffer.
> > >  	 */
> > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> > >  		       unsigned char *buf, int max_bytes);
> > >  };
> > >  
> > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > >  	 * status accordingly (even when the HDA controller is in power save
> > >  	 * mode).
> > >  	 */
> > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > >  };
> > >  
> > >  /**
> > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > index 796cabf..5ab972e 100644
> > > --- a/include/sound/hda_i915.h
> > > +++ b/include/sound/hda_i915.h
> > > @@ -10,8 +10,9 @@
> > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> > >  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
> > >  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > +			     int dev_id, int rate);
> > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > >  int snd_hdac_i915_init(struct hdac_bus *bus);
> > >  int snd_hdac_i915_exit(struct hdac_bus *bus);
> > > @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> > >  {
> > >  }
> > >  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > -					   hda_nid_t nid, int rate)
> > > +					   hda_nid_t nid, int dev_id, int rate)
> > >  {
> > >  	return 0;
> > >  }
> > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > -					 bool *audio_enabled, char *buffer,
> > > -					 int max_bytes)
> > > +					 int dev_id, bool *audio_enabled,
> > > +					 char *buffer, int max_bytes)
> > >  {
> > >  	return -ENODEV;
> > >  }
> > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> > > index c9af022..6ea63ac 100644
> > > --- a/sound/hda/hdac_i915.c
> > > +++ b/sound/hda/hdac_i915.c
> > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
> > >   * This function sets N/CTS value based on the given sample rate.
> > >   * Returns zero for success, or a negative error code.
> > >   */
> > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > +			     int dev_id, int rate)
> > >  {
> > >  	struct hdac_bus *bus = codec->bus;
> > >  	struct i915_audio_component *acomp = bus->audio_component;
> > > @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > >  	port = pin2port(codec, nid);
> > >  	if (port < 0)
> > >  		return -EINVAL;
> > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> > >  }
> > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > >  
> > > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > >   * that only a part of ELD bytes have been fetched.
> > >   */
> > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > >  			   bool *audio_enabled, char *buffer, int max_bytes)
> > >  {
> > >  	struct hdac_bus *bus = codec->bus;
> > > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > >  	port = pin2port(codec, nid);
> > >  	if (port < 0)
> > >  		return -EINVAL;
> > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
> > >  				   buffer, max_bytes);
> > >  }
> > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > > index d0d5ad8..077d48a 100644
> > > --- a/sound/pci/hda/patch_hdmi.c
> > > +++ b/sound/pci/hda/patch_hdmi.c
> > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
> > >  
> > >  	mutex_lock(&per_pin->lock);
> > >  	eld->monitor_present = false;
> > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> > >  				      &eld->monitor_present, eld->eld_buffer,
> > >  				      ELD_MAX_SIZE);
> > >  	if (size > 0) {
> > > @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > >  	/* Todo: add DP1.2 MST audio support later */
> > >  	if (codec_has_acomp(codec))
> > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > +					 runtime->rate);
> > >  
> > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > >  	mutex_lock(&per_pin->lock);
> > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
> > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
> > >  }
> > >  
> > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> > >  {
> > >  	struct hda_codec *codec = audio_ptr;
> > >  	int pin_nid;
> > > -- 
> > > 2.5.0
> > 
> 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03 20:28       ` Ville Syrjälä
@ 2016-08-03 21:42         ` Pandiyan, Dhinakaran
  2016-08-04 12:49           ` Ville Syrjälä
  0 siblings, 1 reply; 24+ messages in thread
From: Pandiyan, Dhinakaran @ 2016-08-03 21:42 UTC (permalink / raw)
  To: ville.syrjala; +Cc: tiwai, Kp, Jeeja, alsa-devel, intel-gfx, libin.yang

On Wed, 2016-08-03 at 23:28 +0300, Ville Syrjälä wrote:
> On Wed, Aug 03, 2016 at 07:43:06PM +0000, Pandiyan, Dhinakaran wrote:
> > On Wed, 2016-08-03 at 22:08 +0300, Ville Syrjälä wrote:
> > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > DP MST provides the capability to send multiple video and audio streams via
> > > > one single port. This requires the API's between i915 and audio drivers to
> > > > distinguish between audio capable displays connected to a port. This patch
> > > > adds this support via an additional parameter 'int dev_id'. The existing
> > > > parameter 'port' does not change it's meaning.
> > > > 
> > > > dev_id =
> > > > 	MST	: pipe that the stream originates from
> > > > 	Non-MST	: -1
> > > > 
> > > > Affected APIs:
> > > > struct i915_audio_component_ops
> > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > 
> > > Does the term 'dev_id' have some special meaning on the audio side? On
> > > the i915 side things would be less confusing if we just called it
> > > 'pipe'.
> > > 
> > 
> > There was quite a bit of back and forth on this. "pipe" seemed to tie us
> > to the gfx hardware architecture. In case, there is no 1:1 mapping from
> > pipes to encoders, this will get confusing as i915 audio registers
> > (E.g.HSW_AUD_PIN_ELD_CP_VLD) are encoder based.
> 
> I'm not following. Looking at the current i915 audio code, on HSW+
> everything is pipe based.
> 
Although we pass "pipe" to these macros, the definition here and in the
BSpec seem to indicate they are based on the encoder.

Eg: #define HSW_AUD_PIN_ELD_CP_VLD          _MMIO(0x650c0)
#define   AUDIO_INACTIVE(trans)         ((1 << 3) << ((trans) * 4))
#define   AUDIO_OUTPUT_ENABLE(trans)    ((1 << 2) << ((trans) * 4))
#define   AUDIO_CP_READY(trans)         ((1 << 1) << ((trans) * 4))
#define   AUDIO_ELD_VALID(trans)        ((1 << 0) << ((trans) * 4))


> > Whereas, dev_id is
> > generic - HDA spec calls them "devices" or "device entry"
> 
> Generic and totally unclear what it means from graphics side.
> 
> pipe and port are the only things we really have in i915. If those aren't
> good enough for the audio side, then I think we should have some decent
> code to remap between the pipe+port vs. whatever audio side id is needed.
> I don't really care on which side of the border such code would live, as
> long as it's clear what it's doing.
> 

I agree, dev_id can be misleading within i915.
> > 
> > > > +	     int rate);
> > > > 
> > > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > > -                       unsigned char *buf, int max_bytes);
> > > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > > > 
> > > > struct i915_audio_component_audio_ops
> > > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > > 
> > > > This patch makes dummy changes in the audio drivers for build to succeed.
> > > > 
> > > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > > >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> > > >  include/drm/i915_component.h       |  6 +--
> > > >  include/sound/hda_i915.h           | 11 ++---
> > > >  sound/hda/hdac_i915.c              |  9 +++--
> > > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > > index 65ada5d..8e4c8c8 100644
> > > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > > >  	/* perform PHY state sanity checks? */
> > > >  	bool chv_phy_assert[2];
> > > >  
> > > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> > > >  
> > > >  	/*
> > > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > > > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> > > > index 8c493de..cbe44c8 100644
> > > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > >  	enum port port = intel_dig_port->port;
> > > > +	enum pipe pipe = crtc->pipe;
> > > > +	int dev_id = -1;
> > > > +
> > > >  
> > > >  	connector = drm_select_eld(encoder);
> > > >  	if (!connector)
> > > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > >  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
> > > >  						     adjusted_mode);
> > > >  
> > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > +		dev_id = pipe;
> > > > +
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > >  	intel_encoder->audio_connector = connector;
> > > > +
> > > >  	/* referred in audio callbacks */
> > > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > >  
> > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > > +						 (int) port, dev_id);
> > > >  }
> > > >  
> > > >  /**
> > > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > >  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
> > > >  {
> > > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > > >  	struct drm_device *dev = encoder->dev;
> > > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > >  	enum port port = intel_dig_port->port;
> > > > +	enum pipe pipe = crtc->pipe;
> > > > +	int dev_id = -1;
> > > > +
> > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > +		dev_id = pipe;
> > > >  
> > > >  	if (dev_priv->display.audio_codec_disable)
> > > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > > >  
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > >  	intel_encoder->audio_connector = NULL;
> > > > -	dev_priv->dig_port_map[port] = NULL;
> > > > +	dev_priv->av_enc_map[pipe] = NULL;
> > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > >  
> > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > > +						 (int) port, dev_id);
> > > >  }
> > > >  
> > > >  /**
> > > > @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
> > > >  	return dev_priv->cdclk_freq;
> > > >  }
> > > >  
> > > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > -						int port, int rate)
> > > > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > > > +					       int port, int dev_id)
> > > > +{
> > > > +
> > > > +	enum pipe pipe;
> > > > +	struct drm_encoder *encoder;
> > > > +
> > > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > > +		return av_enc_map[dev_id];
> > > > +
> > > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > > +
> > > > +		if (!av_enc_map[pipe])
> > > > +			continue;
> > > > +
> > > > +		encoder = &av_enc_map[pipe]->base;
> > > > +		if (port == enc_to_dig_port(encoder)->port)
> > > > +			return av_enc_map[pipe];
> > > > +	}
> > > > +
> > > > +	return NULL;
> > > > +
> > > > +}
> > > > +
> > > > +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> > > > +						int dev_id, int rate)
> > > >  {
> > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > >  	struct intel_encoder *intel_encoder;
> > > > @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > >  		return 0;
> > > >  
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > +
> > > >  	/* 1. get the pipe */
> > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > -	/* intel_encoder might be NULL for DP MST */
> > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > > >  		err = -ENODEV;
> > > >  		goto unlock;
> > > >  	}
> > > > +
> > > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > > >  	pipe = crtc->pipe;
> > > >  	if (pipe == INVALID_PIPE) {
> > > > @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > >  }
> > > >  
> > > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > > -					bool *enabled,
> > > > +					int dev_id, bool *enabled,
> > > >  					unsigned char *buf, int max_bytes)
> > > >  {
> > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > > @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
> > > >  	const u8 *eld;
> > > >  	int ret = -EINVAL;
> > > >  
> > > > +
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > -	/* intel_encoder might be NULL for DP MST */
> > > > -	if (intel_encoder) {
> > > > -		ret = 0;
> > > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > > -		if (*enabled) {
> > > > -			eld = intel_encoder->audio_connector->eld;
> > > > -			ret = drm_eld_size(eld);
> > > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > > -		}
> > > > +
> > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > > +	if (!intel_encoder) {
> > > > +		mutex_unlock(&dev_priv->av_mutex);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	ret = 0;
> > > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > > +	if (*enabled) {
> > > > +		eld = intel_encoder->audio_connector->eld;
> > > > +		ret = drm_eld_size(eld);
> > > > +		memcpy(buf, eld, min(max_bytes, ret));
> > > >  	}
> > > >  
> > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > > > index b46fa0e..1419c98 100644
> > > > --- a/include/drm/i915_component.h
> > > > +++ b/include/drm/i915_component.h
> > > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > > >  	 * Called from audio driver. After audio driver sets the
> > > >  	 * sample rate, it will call this function to set n/cts
> > > >  	 */
> > > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
> > > >  	/**
> > > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > > >  	 *
> > > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > > >  	 * implies that only a part of ELD has been copied to the buffer.
> > > >  	 */
> > > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> > > >  		       unsigned char *buf, int max_bytes);
> > > >  };
> > > >  
> > > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > > >  	 * status accordingly (even when the HDA controller is in power save
> > > >  	 * mode).
> > > >  	 */
> > > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > >  };
> > > >  
> > > >  /**
> > > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > > index 796cabf..5ab972e 100644
> > > > --- a/include/sound/hda_i915.h
> > > > +++ b/include/sound/hda_i915.h
> > > > @@ -10,8 +10,9 @@
> > > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> > > >  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
> > > >  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > +			     int dev_id, int rate);
> > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > > >  int snd_hdac_i915_init(struct hdac_bus *bus);
> > > >  int snd_hdac_i915_exit(struct hdac_bus *bus);
> > > > @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> > > >  {
> > > >  }
> > > >  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > > -					   hda_nid_t nid, int rate)
> > > > +					   hda_nid_t nid, int dev_id, int rate)
> > > >  {
> > > >  	return 0;
> > > >  }
> > > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > -					 bool *audio_enabled, char *buffer,
> > > > -					 int max_bytes)
> > > > +					 int dev_id, bool *audio_enabled,
> > > > +					 char *buffer, int max_bytes)
> > > >  {
> > > >  	return -ENODEV;
> > > >  }
> > > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> > > > index c9af022..6ea63ac 100644
> > > > --- a/sound/hda/hdac_i915.c
> > > > +++ b/sound/hda/hdac_i915.c
> > > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
> > > >   * This function sets N/CTS value based on the given sample rate.
> > > >   * Returns zero for success, or a negative error code.
> > > >   */
> > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > +			     int dev_id, int rate)
> > > >  {
> > > >  	struct hdac_bus *bus = codec->bus;
> > > >  	struct i915_audio_component *acomp = bus->audio_component;
> > > > @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > >  	port = pin2port(codec, nid);
> > > >  	if (port < 0)
> > > >  		return -EINVAL;
> > > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > >  
> > > > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > > >   * that only a part of ELD bytes have been fetched.
> > > >   */
> > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > > >  			   bool *audio_enabled, char *buffer, int max_bytes)
> > > >  {
> > > >  	struct hdac_bus *bus = codec->bus;
> > > > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > >  	port = pin2port(codec, nid);
> > > >  	if (port < 0)
> > > >  		return -EINVAL;
> > > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
> > > >  				   buffer, max_bytes);
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > > > index d0d5ad8..077d48a 100644
> > > > --- a/sound/pci/hda/patch_hdmi.c
> > > > +++ b/sound/pci/hda/patch_hdmi.c
> > > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
> > > >  
> > > >  	mutex_lock(&per_pin->lock);
> > > >  	eld->monitor_present = false;
> > > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> > > >  				      &eld->monitor_present, eld->eld_buffer,
> > > >  				      ELD_MAX_SIZE);
> > > >  	if (size > 0) {
> > > > @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > > >  	/* Todo: add DP1.2 MST audio support later */
> > > >  	if (codec_has_acomp(codec))
> > > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> > > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > > +					 runtime->rate);
> > > >  
> > > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > > >  	mutex_lock(&per_pin->lock);
> > > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
> > > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
> > > >  }
> > > >  
> > > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> > > >  {
> > > >  	struct hda_codec *codec = audio_ptr;
> > > >  	int pin_nid;
> > > > -- 
> > > > 2.5.0
> > > 
> > 
> 

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03 21:42         ` Pandiyan, Dhinakaran
@ 2016-08-04 12:49           ` Ville Syrjälä
  2016-08-04 16:44             ` Pandiyan, Dhinakaran
  0 siblings, 1 reply; 24+ messages in thread
From: Ville Syrjälä @ 2016-08-04 12:49 UTC (permalink / raw)
  To: Pandiyan, Dhinakaran; +Cc: tiwai, Kp, Jeeja, alsa-devel, intel-gfx, libin.yang

On Wed, Aug 03, 2016 at 09:42:53PM +0000, Pandiyan, Dhinakaran wrote:
> On Wed, 2016-08-03 at 23:28 +0300, Ville Syrjälä wrote:
> > On Wed, Aug 03, 2016 at 07:43:06PM +0000, Pandiyan, Dhinakaran wrote:
> > > On Wed, 2016-08-03 at 22:08 +0300, Ville Syrjälä wrote:
> > > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > > DP MST provides the capability to send multiple video and audio streams via
> > > > > one single port. This requires the API's between i915 and audio drivers to
> > > > > distinguish between audio capable displays connected to a port. This patch
> > > > > adds this support via an additional parameter 'int dev_id'. The existing
> > > > > parameter 'port' does not change it's meaning.
> > > > > 
> > > > > dev_id =
> > > > > 	MST	: pipe that the stream originates from
> > > > > 	Non-MST	: -1
> > > > > 
> > > > > Affected APIs:
> > > > > struct i915_audio_component_ops
> > > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > > 
> > > > Does the term 'dev_id' have some special meaning on the audio side? On
> > > > the i915 side things would be less confusing if we just called it
> > > > 'pipe'.
> > > > 
> > > 
> > > There was quite a bit of back and forth on this. "pipe" seemed to tie us
> > > to the gfx hardware architecture. In case, there is no 1:1 mapping from
> > > pipes to encoders, this will get confusing as i915 audio registers
> > > (E.g.HSW_AUD_PIN_ELD_CP_VLD) are encoder based.
> > 
> > I'm not following. Looking at the current i915 audio code, on HSW+
> > everything is pipe based.
> > 
> Although we pass "pipe" to these macros, the definition here and in the
> BSpec seem to indicate they are based on the encoder.
> 
> Eg: #define HSW_AUD_PIN_ELD_CP_VLD          _MMIO(0x650c0)
> #define   AUDIO_INACTIVE(trans)         ((1 << 3) << ((trans) * 4))
> #define   AUDIO_OUTPUT_ENABLE(trans)    ((1 << 2) << ((trans) * 4))
> #define   AUDIO_CP_READY(trans)         ((1 << 1) << ((trans) * 4))
> #define   AUDIO_ELD_VALID(trans)        ((1 << 0) << ((trans) * 4))

That's transcoder, not encoder. transcoder is the tail end of the pipe.
For all the external ports transcoder==pipe, and for port A there is the
special edp transcoder which can be fed by any pipe. The edp transcoder
doesn't support audio though, and I can't see anything in the spec to
suggest that it would gain audio capabilities, in the near future at
least. So from that point of view passing around the pipe would seem
like a safe approach.

We could of course pass around transcoder instead of pipe. Since we
don't ever need to enable audio on the edp transcoder, we don't even
have to worry about what number we assign to it. And hence it is
actually the same as passing the pipe, except in name.

> 
> 
> > > Whereas, dev_id is
> > > generic - HDA spec calls them "devices" or "device entry"
> > 
> > Generic and totally unclear what it means from graphics side.
> > 
> > pipe and port are the only things we really have in i915. If those aren't
> > good enough for the audio side, then I think we should have some decent
> > code to remap between the pipe+port vs. whatever audio side id is needed.
> > I don't really care on which side of the border such code would live, as
> > long as it's clear what it's doing.
> > 
> 
> I agree, dev_id can be misleading within i915.
> > > 
> > > > > +	     int rate);
> > > > > 
> > > > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > > > -                       unsigned char *buf, int max_bytes);
> > > > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > > > > 
> > > > > struct i915_audio_component_audio_ops
> > > > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > > > 
> > > > > This patch makes dummy changes in the audio drivers for build to succeed.
> > > > > 
> > > > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > > > >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> > > > >  include/drm/i915_component.h       |  6 +--
> > > > >  include/sound/hda_i915.h           | 11 ++---
> > > > >  sound/hda/hdac_i915.c              |  9 +++--
> > > > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > > > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > > > index 65ada5d..8e4c8c8 100644
> > > > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > > > >  	/* perform PHY state sanity checks? */
> > > > >  	bool chv_phy_assert[2];
> > > > >  
> > > > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> > > > >  
> > > > >  	/*
> > > > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > > > > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> > > > > index 8c493de..cbe44c8 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > > >  	enum port port = intel_dig_port->port;
> > > > > +	enum pipe pipe = crtc->pipe;
> > > > > +	int dev_id = -1;
> > > > > +
> > > > >  
> > > > >  	connector = drm_select_eld(encoder);
> > > > >  	if (!connector)
> > > > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > > >  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
> > > > >  						     adjusted_mode);
> > > > >  
> > > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > > +		dev_id = pipe;
> > > > > +
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > >  	intel_encoder->audio_connector = connector;
> > > > > +
> > > > >  	/* referred in audio callbacks */
> > > > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > >  
> > > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > > > +						 (int) port, dev_id);
> > > > >  }
> > > > >  
> > > > >  /**
> > > > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > > >  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
> > > > >  {
> > > > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > > > >  	struct drm_device *dev = encoder->dev;
> > > > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > > >  	enum port port = intel_dig_port->port;
> > > > > +	enum pipe pipe = crtc->pipe;
> > > > > +	int dev_id = -1;
> > > > > +
> > > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > > +		dev_id = pipe;
> > > > >  
> > > > >  	if (dev_priv->display.audio_codec_disable)
> > > > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > > > >  
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > >  	intel_encoder->audio_connector = NULL;
> > > > > -	dev_priv->dig_port_map[port] = NULL;
> > > > > +	dev_priv->av_enc_map[pipe] = NULL;
> > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > >  
> > > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > > > +						 (int) port, dev_id);
> > > > >  }
> > > > >  
> > > > >  /**
> > > > > @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
> > > > >  	return dev_priv->cdclk_freq;
> > > > >  }
> > > > >  
> > > > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > > -						int port, int rate)
> > > > > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > > > > +					       int port, int dev_id)
> > > > > +{
> > > > > +
> > > > > +	enum pipe pipe;
> > > > > +	struct drm_encoder *encoder;
> > > > > +
> > > > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > > > +		return av_enc_map[dev_id];
> > > > > +
> > > > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > > > +
> > > > > +		if (!av_enc_map[pipe])
> > > > > +			continue;
> > > > > +
> > > > > +		encoder = &av_enc_map[pipe]->base;
> > > > > +		if (port == enc_to_dig_port(encoder)->port)
> > > > > +			return av_enc_map[pipe];
> > > > > +	}
> > > > > +
> > > > > +	return NULL;
> > > > > +
> > > > > +}
> > > > > +
> > > > > +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> > > > > +						int dev_id, int rate)
> > > > >  {
> > > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > > >  	struct intel_encoder *intel_encoder;
> > > > > @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > >  		return 0;
> > > > >  
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > +
> > > > >  	/* 1. get the pipe */
> > > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > > -	/* intel_encoder might be NULL for DP MST */
> > > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > > > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > > > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > > > >  		err = -ENODEV;
> > > > >  		goto unlock;
> > > > >  	}
> > > > > +
> > > > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > > > >  	pipe = crtc->pipe;
> > > > >  	if (pipe == INVALID_PIPE) {
> > > > > @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > >  }
> > > > >  
> > > > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > > > -					bool *enabled,
> > > > > +					int dev_id, bool *enabled,
> > > > >  					unsigned char *buf, int max_bytes)
> > > > >  {
> > > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > > > @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
> > > > >  	const u8 *eld;
> > > > >  	int ret = -EINVAL;
> > > > >  
> > > > > +
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > > -	/* intel_encoder might be NULL for DP MST */
> > > > > -	if (intel_encoder) {
> > > > > -		ret = 0;
> > > > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > > > -		if (*enabled) {
> > > > > -			eld = intel_encoder->audio_connector->eld;
> > > > > -			ret = drm_eld_size(eld);
> > > > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > > > -		}
> > > > > +
> > > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > > > +	if (!intel_encoder) {
> > > > > +		mutex_unlock(&dev_priv->av_mutex);
> > > > > +		return ret;
> > > > > +	}
> > > > > +
> > > > > +	ret = 0;
> > > > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > > > +	if (*enabled) {
> > > > > +		eld = intel_encoder->audio_connector->eld;
> > > > > +		ret = drm_eld_size(eld);
> > > > > +		memcpy(buf, eld, min(max_bytes, ret));
> > > > >  	}
> > > > >  
> > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > > > > index b46fa0e..1419c98 100644
> > > > > --- a/include/drm/i915_component.h
> > > > > +++ b/include/drm/i915_component.h
> > > > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > > > >  	 * Called from audio driver. After audio driver sets the
> > > > >  	 * sample rate, it will call this function to set n/cts
> > > > >  	 */
> > > > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
> > > > >  	/**
> > > > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > > > >  	 *
> > > > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > > > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > > > >  	 * implies that only a part of ELD has been copied to the buffer.
> > > > >  	 */
> > > > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > > > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> > > > >  		       unsigned char *buf, int max_bytes);
> > > > >  };
> > > > >  
> > > > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > > > >  	 * status accordingly (even when the HDA controller is in power save
> > > > >  	 * mode).
> > > > >  	 */
> > > > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > > >  };
> > > > >  
> > > > >  /**
> > > > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > > > index 796cabf..5ab972e 100644
> > > > > --- a/include/sound/hda_i915.h
> > > > > +++ b/include/sound/hda_i915.h
> > > > > @@ -10,8 +10,9 @@
> > > > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> > > > >  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
> > > > >  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> > > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > > +			     int dev_id, int rate);
> > > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > > > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > > > >  int snd_hdac_i915_init(struct hdac_bus *bus);
> > > > >  int snd_hdac_i915_exit(struct hdac_bus *bus);
> > > > > @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> > > > >  {
> > > > >  }
> > > > >  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > > > -					   hda_nid_t nid, int rate)
> > > > > +					   hda_nid_t nid, int dev_id, int rate)
> > > > >  {
> > > > >  	return 0;
> > > > >  }
> > > > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > > -					 bool *audio_enabled, char *buffer,
> > > > > -					 int max_bytes)
> > > > > +					 int dev_id, bool *audio_enabled,
> > > > > +					 char *buffer, int max_bytes)
> > > > >  {
> > > > >  	return -ENODEV;
> > > > >  }
> > > > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> > > > > index c9af022..6ea63ac 100644
> > > > > --- a/sound/hda/hdac_i915.c
> > > > > +++ b/sound/hda/hdac_i915.c
> > > > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
> > > > >   * This function sets N/CTS value based on the given sample rate.
> > > > >   * Returns zero for success, or a negative error code.
> > > > >   */
> > > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > > +			     int dev_id, int rate)
> > > > >  {
> > > > >  	struct hdac_bus *bus = codec->bus;
> > > > >  	struct i915_audio_component *acomp = bus->audio_component;
> > > > > @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > > >  	port = pin2port(codec, nid);
> > > > >  	if (port < 0)
> > > > >  		return -EINVAL;
> > > > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > > > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> > > > >  }
> > > > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > > >  
> > > > > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > > > >   * that only a part of ELD bytes have been fetched.
> > > > >   */
> > > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > > > >  			   bool *audio_enabled, char *buffer, int max_bytes)
> > > > >  {
> > > > >  	struct hdac_bus *bus = codec->bus;
> > > > > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > >  	port = pin2port(codec, nid);
> > > > >  	if (port < 0)
> > > > >  		return -EINVAL;
> > > > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
> > > > >  				   buffer, max_bytes);
> > > > >  }
> > > > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > > > > index d0d5ad8..077d48a 100644
> > > > > --- a/sound/pci/hda/patch_hdmi.c
> > > > > +++ b/sound/pci/hda/patch_hdmi.c
> > > > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
> > > > >  
> > > > >  	mutex_lock(&per_pin->lock);
> > > > >  	eld->monitor_present = false;
> > > > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> > > > >  				      &eld->monitor_present, eld->eld_buffer,
> > > > >  				      ELD_MAX_SIZE);
> > > > >  	if (size > 0) {
> > > > > @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > > > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > > > >  	/* Todo: add DP1.2 MST audio support later */
> > > > >  	if (codec_has_acomp(codec))
> > > > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> > > > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > > > +					 runtime->rate);
> > > > >  
> > > > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > > > >  	mutex_lock(&per_pin->lock);
> > > > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
> > > > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
> > > > >  }
> > > > >  
> > > > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> > > > >  {
> > > > >  	struct hda_codec *codec = audio_ptr;
> > > > >  	int pin_nid;
> > > > > -- 
> > > > > 2.5.0
> > > > 
> > > 
> > 
> 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-04 12:49           ` Ville Syrjälä
@ 2016-08-04 16:44             ` Pandiyan, Dhinakaran
  0 siblings, 0 replies; 24+ messages in thread
From: Pandiyan, Dhinakaran @ 2016-08-04 16:44 UTC (permalink / raw)
  To: ville.syrjala; +Cc: tiwai, Kp, Jeeja, alsa-devel, intel-gfx, libin.yang

On Thu, 2016-08-04 at 15:49 +0300, Ville Syrjälä wrote:
> On Wed, Aug 03, 2016 at 09:42:53PM +0000, Pandiyan, Dhinakaran wrote:
> > On Wed, 2016-08-03 at 23:28 +0300, Ville Syrjälä wrote:
> > > On Wed, Aug 03, 2016 at 07:43:06PM +0000, Pandiyan, Dhinakaran wrote:
> > > > On Wed, 2016-08-03 at 22:08 +0300, Ville Syrjälä wrote:
> > > > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > > > DP MST provides the capability to send multiple video and audio streams via
> > > > > > one single port. This requires the API's between i915 and audio drivers to
> > > > > > distinguish between audio capable displays connected to a port. This patch
> > > > > > adds this support via an additional parameter 'int dev_id'. The existing
> > > > > > parameter 'port' does not change it's meaning.
> > > > > > 
> > > > > > dev_id =
> > > > > > 	MST	: pipe that the stream originates from
> > > > > > 	Non-MST	: -1
> > > > > > 
> > > > > > Affected APIs:
> > > > > > struct i915_audio_component_ops
> > > > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > > > 
> > > > > Does the term 'dev_id' have some special meaning on the audio side? On
> > > > > the i915 side things would be less confusing if we just called it
> > > > > 'pipe'.
> > > > > 
> > > > 
> > > > There was quite a bit of back and forth on this. "pipe" seemed to tie us
> > > > to the gfx hardware architecture. In case, there is no 1:1 mapping from
> > > > pipes to encoders, this will get confusing as i915 audio registers
> > > > (E.g.HSW_AUD_PIN_ELD_CP_VLD) are encoder based.
> > > 
> > > I'm not following. Looking at the current i915 audio code, on HSW+
> > > everything is pipe based.
> > > 
> > Although we pass "pipe" to these macros, the definition here and in the
> > BSpec seem to indicate they are based on the encoder.
> > 
> > Eg: #define HSW_AUD_PIN_ELD_CP_VLD          _MMIO(0x650c0)
> > #define   AUDIO_INACTIVE(trans)         ((1 << 3) << ((trans) * 4))
> > #define   AUDIO_OUTPUT_ENABLE(trans)    ((1 << 2) << ((trans) * 4))
> > #define   AUDIO_CP_READY(trans)         ((1 << 1) << ((trans) * 4))
> > #define   AUDIO_ELD_VALID(trans)        ((1 << 0) << ((trans) * 4))
> 
> That's transcoder, not encoder. transcoder is the tail end of the pipe.
> For all the external ports transcoder==pipe, and for port A there is the
> special edp transcoder which can be fed by any pipe. The edp transcoder
> doesn't support audio though, and I can't see anything in the spec to
> suggest that it would gain audio capabilities, in the near future at
> least. So from that point of view passing around the pipe would seem
> like a safe approach.
> 
> We could of course pass around transcoder instead of pipe. Since we
> don't ever need to enable audio on the edp transcoder, we don't even
> have to worry about what number we assign to it. And hence it is
> actually the same as passing the pipe, except in name.
> 

Thanks for the detailed explanation, makes sense to change it to "pipe".
I will send out a new version. Do you recommend I send this patch with 
"Prep. for DP audio MST support" series
(https://lists.freedesktop.org/archives/intel-gfx/2016-August/102399.html)? This patch depends on the some of the patches in that. I had separated this patch out because of the audio driver changes in this.
> > 
> > 
> > > > Whereas, dev_id is
> > > > generic - HDA spec calls them "devices" or "device entry"
> > > 
> > > Generic and totally unclear what it means from graphics side.
> > > 
> > > pipe and port are the only things we really have in i915. If those aren't
> > > good enough for the audio side, then I think we should have some decent
> > > code to remap between the pipe+port vs. whatever audio side id is needed.
> > > I don't really care on which side of the border such code would live, as
> > > long as it's clear what it's doing.
> > > 
> > 
> > I agree, dev_id can be misleading within i915.
> > > > 
> > > > > > +	     int rate);
> > > > > > 
> > > > > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > > > > -                       unsigned char *buf, int max_bytes);
> > > > > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > > > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > > > > > 
> > > > > > struct i915_audio_component_audio_ops
> > > > > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > > > > 
> > > > > > This patch makes dummy changes in the audio drivers for build to succeed.
> > > > > > 
> > > > > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > > > > >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> > > > > >  include/drm/i915_component.h       |  6 +--
> > > > > >  include/sound/hda_i915.h           | 11 ++---
> > > > > >  sound/hda/hdac_i915.c              |  9 +++--
> > > > > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > > > > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > > > > index 65ada5d..8e4c8c8 100644
> > > > > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > > > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > > > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > > > > >  	/* perform PHY state sanity checks? */
> > > > > >  	bool chv_phy_assert[2];
> > > > > >  
> > > > > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > > > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> > > > > >  
> > > > > >  	/*
> > > > > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > > > > > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> > > > > > index 8c493de..cbe44c8 100644
> > > > > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > > > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > > > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > > > >  	enum port port = intel_dig_port->port;
> > > > > > +	enum pipe pipe = crtc->pipe;
> > > > > > +	int dev_id = -1;
> > > > > > +
> > > > > >  
> > > > > >  	connector = drm_select_eld(encoder);
> > > > > >  	if (!connector)
> > > > > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > > > >  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
> > > > > >  						     adjusted_mode);
> > > > > >  
> > > > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > > > +		dev_id = pipe;
> > > > > > +
> > > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > >  	intel_encoder->audio_connector = connector;
> > > > > > +
> > > > > >  	/* referred in audio callbacks */
> > > > > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > > > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > > >  
> > > > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > > > > +						 (int) port, dev_id);
> > > > > >  }
> > > > > >  
> > > > > >  /**
> > > > > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > > > > >  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
> > > > > >  {
> > > > > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > > > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > > > > >  	struct drm_device *dev = encoder->dev;
> > > > > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > > > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > > > >  	enum port port = intel_dig_port->port;
> > > > > > +	enum pipe pipe = crtc->pipe;
> > > > > > +	int dev_id = -1;
> > > > > > +
> > > > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > > > +		dev_id = pipe;
> > > > > >  
> > > > > >  	if (dev_priv->display.audio_codec_disable)
> > > > > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > > > > >  
> > > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > >  	intel_encoder->audio_connector = NULL;
> > > > > > -	dev_priv->dig_port_map[port] = NULL;
> > > > > > +	dev_priv->av_enc_map[pipe] = NULL;
> > > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > > >  
> > > > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > > > > +						 (int) port, dev_id);
> > > > > >  }
> > > > > >  
> > > > > >  /**
> > > > > > @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
> > > > > >  	return dev_priv->cdclk_freq;
> > > > > >  }
> > > > > >  
> > > > > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > > > -						int port, int rate)
> > > > > > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > > > > > +					       int port, int dev_id)
> > > > > > +{
> > > > > > +
> > > > > > +	enum pipe pipe;
> > > > > > +	struct drm_encoder *encoder;
> > > > > > +
> > > > > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > > > > +		return av_enc_map[dev_id];
> > > > > > +
> > > > > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > > > > +
> > > > > > +		if (!av_enc_map[pipe])
> > > > > > +			continue;
> > > > > > +
> > > > > > +		encoder = &av_enc_map[pipe]->base;
> > > > > > +		if (port == enc_to_dig_port(encoder)->port)
> > > > > > +			return av_enc_map[pipe];
> > > > > > +	}
> > > > > > +
> > > > > > +	return NULL;
> > > > > > +
> > > > > > +}
> > > > > > +
> > > > > > +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> > > > > > +						int dev_id, int rate)
> > > > > >  {
> > > > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > > > >  	struct intel_encoder *intel_encoder;
> > > > > > @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > > >  		return 0;
> > > > > >  
> > > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > > +
> > > > > >  	/* 1. get the pipe */
> > > > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > > > -	/* intel_encoder might be NULL for DP MST */
> > > > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > > > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > > > > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > > > > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > > > > >  		err = -ENODEV;
> > > > > >  		goto unlock;
> > > > > >  	}
> > > > > > +
> > > > > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > > > > >  	pipe = crtc->pipe;
> > > > > >  	if (pipe == INVALID_PIPE) {
> > > > > > @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > > >  }
> > > > > >  
> > > > > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > > > > -					bool *enabled,
> > > > > > +					int dev_id, bool *enabled,
> > > > > >  					unsigned char *buf, int max_bytes)
> > > > > >  {
> > > > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > > > > @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
> > > > > >  	const u8 *eld;
> > > > > >  	int ret = -EINVAL;
> > > > > >  
> > > > > > +
> > > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > > > -	/* intel_encoder might be NULL for DP MST */
> > > > > > -	if (intel_encoder) {
> > > > > > -		ret = 0;
> > > > > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > > > > -		if (*enabled) {
> > > > > > -			eld = intel_encoder->audio_connector->eld;
> > > > > > -			ret = drm_eld_size(eld);
> > > > > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > > > > -		}
> > > > > > +
> > > > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > > > > +	if (!intel_encoder) {
> > > > > > +		mutex_unlock(&dev_priv->av_mutex);
> > > > > > +		return ret;
> > > > > > +	}
> > > > > > +
> > > > > > +	ret = 0;
> > > > > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > > > > +	if (*enabled) {
> > > > > > +		eld = intel_encoder->audio_connector->eld;
> > > > > > +		ret = drm_eld_size(eld);
> > > > > > +		memcpy(buf, eld, min(max_bytes, ret));
> > > > > >  	}
> > > > > >  
> > > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > > > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > > > > > index b46fa0e..1419c98 100644
> > > > > > --- a/include/drm/i915_component.h
> > > > > > +++ b/include/drm/i915_component.h
> > > > > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > > > > >  	 * Called from audio driver. After audio driver sets the
> > > > > >  	 * sample rate, it will call this function to set n/cts
> > > > > >  	 */
> > > > > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
> > > > > >  	/**
> > > > > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > > > > >  	 *
> > > > > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > > > > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > > > > >  	 * implies that only a part of ELD has been copied to the buffer.
> > > > > >  	 */
> > > > > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > > > > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> > > > > >  		       unsigned char *buf, int max_bytes);
> > > > > >  };
> > > > > >  
> > > > > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > > > > >  	 * status accordingly (even when the HDA controller is in power save
> > > > > >  	 * mode).
> > > > > >  	 */
> > > > > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > > > >  };
> > > > > >  
> > > > > >  /**
> > > > > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > > > > index 796cabf..5ab972e 100644
> > > > > > --- a/include/sound/hda_i915.h
> > > > > > +++ b/include/sound/hda_i915.h
> > > > > > @@ -10,8 +10,9 @@
> > > > > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> > > > > >  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
> > > > > >  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > > > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> > > > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > > > +			     int dev_id, int rate);
> > > > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > > > > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > > > > >  int snd_hdac_i915_init(struct hdac_bus *bus);
> > > > > >  int snd_hdac_i915_exit(struct hdac_bus *bus);
> > > > > > @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> > > > > >  {
> > > > > >  }
> > > > > >  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > > > > -					   hda_nid_t nid, int rate)
> > > > > > +					   hda_nid_t nid, int dev_id, int rate)
> > > > > >  {
> > > > > >  	return 0;
> > > > > >  }
> > > > > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > > > -					 bool *audio_enabled, char *buffer,
> > > > > > -					 int max_bytes)
> > > > > > +					 int dev_id, bool *audio_enabled,
> > > > > > +					 char *buffer, int max_bytes)
> > > > > >  {
> > > > > >  	return -ENODEV;
> > > > > >  }
> > > > > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> > > > > > index c9af022..6ea63ac 100644
> > > > > > --- a/sound/hda/hdac_i915.c
> > > > > > +++ b/sound/hda/hdac_i915.c
> > > > > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
> > > > > >   * This function sets N/CTS value based on the given sample rate.
> > > > > >   * Returns zero for success, or a negative error code.
> > > > > >   */
> > > > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > > > +			     int dev_id, int rate)
> > > > > >  {
> > > > > >  	struct hdac_bus *bus = codec->bus;
> > > > > >  	struct i915_audio_component *acomp = bus->audio_component;
> > > > > > @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > > > >  	port = pin2port(codec, nid);
> > > > > >  	if (port < 0)
> > > > > >  		return -EINVAL;
> > > > > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > > > > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> > > > > >  }
> > > > > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > > > >  
> > > > > > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > > > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > > > > >   * that only a part of ELD bytes have been fetched.
> > > > > >   */
> > > > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > > > > >  			   bool *audio_enabled, char *buffer, int max_bytes)
> > > > > >  {
> > > > > >  	struct hdac_bus *bus = codec->bus;
> > > > > > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > > >  	port = pin2port(codec, nid);
> > > > > >  	if (port < 0)
> > > > > >  		return -EINVAL;
> > > > > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > > > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
> > > > > >  				   buffer, max_bytes);
> > > > > >  }
> > > > > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > > > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > > > > > index d0d5ad8..077d48a 100644
> > > > > > --- a/sound/pci/hda/patch_hdmi.c
> > > > > > +++ b/sound/pci/hda/patch_hdmi.c
> > > > > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
> > > > > >  
> > > > > >  	mutex_lock(&per_pin->lock);
> > > > > >  	eld->monitor_present = false;
> > > > > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > > > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> > > > > >  				      &eld->monitor_present, eld->eld_buffer,
> > > > > >  				      ELD_MAX_SIZE);
> > > > > >  	if (size > 0) {
> > > > > > @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > > > > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > > > > >  	/* Todo: add DP1.2 MST audio support later */
> > > > > >  	if (codec_has_acomp(codec))
> > > > > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> > > > > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > > > > +					 runtime->rate);
> > > > > >  
> > > > > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > > > > >  	mutex_lock(&per_pin->lock);
> > > > > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
> > > > > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
> > > > > >  }
> > > > > >  
> > > > > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > > > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> > > > > >  {
> > > > > >  	struct hda_codec *codec = audio_ptr;
> > > > > >  	int pin_nid;
> > > > > > -- 
> > > > > > 2.5.0
> > > > > 
> > > > 
> > > 
> > 
> 

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03 19:08   ` Ville Syrjälä
  2016-08-03 19:43     ` Pandiyan, Dhinakaran
@ 2016-08-04 17:18     ` Jim Bride
  2016-08-04 17:35       ` Ville Syrjälä
  1 sibling, 1 reply; 24+ messages in thread
From: Jim Bride @ 2016-08-04 17:18 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: tiwai, intel-gfx, alsa-devel, Dhinakaran Pandiyan, libin.yang

On Wed, Aug 03, 2016 at 10:08:12PM +0300, Ville Syrjälä wrote:
> On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > DP MST provides the capability to send multiple video and audio streams via
> > one single port. This requires the API's between i915 and audio drivers to
> > distinguish between audio capable displays connected to a port. This patch
> > adds this support via an additional parameter 'int dev_id'. The existing
> > parameter 'port' does not change it's meaning.
> > 
> > dev_id =
> > 	MST	: pipe that the stream originates from
> > 	Non-MST	: -1
> > 
> > Affected APIs:
> > struct i915_audio_component_ops
> > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> 
> Does the term 'dev_id' have some special meaning on the audio side? On
> the i915 side things would be less confusing if we just called it
> 'pipe'.

Yeah, it does.  All of the documentation on the audio side is written
in terms of device ID, so they asked for that nomenclature.

Jim


> > +	     int rate);
> > 
> > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > -                       unsigned char *buf, int max_bytes);
> > +       int (*get_eld)(struct device *, int port, int dev_id,
> > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > 
> > struct i915_audio_component_audio_ops
> > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > 
> > This patch makes dummy changes in the audio drivers for build to succeed.
> > 
> > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> >  include/drm/i915_component.h       |  6 +--
> >  include/sound/hda_i915.h           | 11 ++---
> >  sound/hda/hdac_i915.c              |  9 +++--
> >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> >  6 files changed, 82 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 65ada5d..8e4c8c8 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> >  	/* perform PHY state sanity checks? */
> >  	bool chv_phy_assert[2];
> >  
> > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> >  
> >  	/*
> >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> > index 8c493de..cbe44c8 100644
> > --- a/drivers/gpu/drm/i915/intel_audio.c
> > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> >  	enum port port = intel_dig_port->port;
> > +	enum pipe pipe = crtc->pipe;
> > +	int dev_id = -1;
> > +
> >  
> >  	connector = drm_select_eld(encoder);
> >  	if (!connector)
> > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> >  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
> >  						     adjusted_mode);
> >  
> > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > +		dev_id = pipe;
> > +
> >  	mutex_lock(&dev_priv->av_mutex);
> >  	intel_encoder->audio_connector = connector;
> > +
> >  	/* referred in audio callbacks */
> > -	dev_priv->dig_port_map[port] = intel_encoder;
> > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> >  	mutex_unlock(&dev_priv->av_mutex);
> >  
> >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > +						 (int) port, dev_id);
> >  }
> >  
> >  /**
> > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> >  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
> >  {
> >  	struct drm_encoder *encoder = &intel_encoder->base;
> > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> >  	struct drm_device *dev = encoder->dev;
> >  	struct drm_i915_private *dev_priv = to_i915(dev);
> >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> >  	enum port port = intel_dig_port->port;
> > +	enum pipe pipe = crtc->pipe;
> > +	int dev_id = -1;
> > +
> > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > +		dev_id = pipe;
> >  
> >  	if (dev_priv->display.audio_codec_disable)
> >  		dev_priv->display.audio_codec_disable(intel_encoder);
> >  
> >  	mutex_lock(&dev_priv->av_mutex);
> >  	intel_encoder->audio_connector = NULL;
> > -	dev_priv->dig_port_map[port] = NULL;
> > +	dev_priv->av_enc_map[pipe] = NULL;
> >  	mutex_unlock(&dev_priv->av_mutex);
> >  
> >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > +						 (int) port, dev_id);
> >  }
> >  
> >  /**
> > @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
> >  	return dev_priv->cdclk_freq;
> >  }
> >  
> > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > -						int port, int rate)
> > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > +					       int port, int dev_id)
> > +{
> > +
> > +	enum pipe pipe;
> > +	struct drm_encoder *encoder;
> > +
> > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > +		return av_enc_map[dev_id];
> > +
> > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > +
> > +		if (!av_enc_map[pipe])
> > +			continue;
> > +
> > +		encoder = &av_enc_map[pipe]->base;
> > +		if (port == enc_to_dig_port(encoder)->port)
> > +			return av_enc_map[pipe];
> > +	}
> > +
> > +	return NULL;
> > +
> > +}
> > +
> > +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> > +						int dev_id, int rate)
> >  {
> >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> >  	struct intel_encoder *intel_encoder;
> > @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> >  		return 0;
> >  
> >  	mutex_lock(&dev_priv->av_mutex);
> > +
> >  	/* 1. get the pipe */
> > -	intel_encoder = dev_priv->dig_port_map[port];
> > -	/* intel_encoder might be NULL for DP MST */
> > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> >  		err = -ENODEV;
> >  		goto unlock;
> >  	}
> > +
> >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> >  	pipe = crtc->pipe;
> >  	if (pipe == INVALID_PIPE) {
> > @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> >  }
> >  
> >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > -					bool *enabled,
> > +					int dev_id, bool *enabled,
> >  					unsigned char *buf, int max_bytes)
> >  {
> >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
> >  	const u8 *eld;
> >  	int ret = -EINVAL;
> >  
> > +
> >  	mutex_lock(&dev_priv->av_mutex);
> > -	intel_encoder = dev_priv->dig_port_map[port];
> > -	/* intel_encoder might be NULL for DP MST */
> > -	if (intel_encoder) {
> > -		ret = 0;
> > -		*enabled = intel_encoder->audio_connector != NULL;
> > -		if (*enabled) {
> > -			eld = intel_encoder->audio_connector->eld;
> > -			ret = drm_eld_size(eld);
> > -			memcpy(buf, eld, min(max_bytes, ret));
> > -		}
> > +
> > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > +	if (!intel_encoder) {
> > +		mutex_unlock(&dev_priv->av_mutex);
> > +		return ret;
> > +	}
> > +
> > +	ret = 0;
> > +	*enabled = intel_encoder->audio_connector != NULL;
> > +	if (*enabled) {
> > +		eld = intel_encoder->audio_connector->eld;
> > +		ret = drm_eld_size(eld);
> > +		memcpy(buf, eld, min(max_bytes, ret));
> >  	}
> >  
> >  	mutex_unlock(&dev_priv->av_mutex);
> > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > index b46fa0e..1419c98 100644
> > --- a/include/drm/i915_component.h
> > +++ b/include/drm/i915_component.h
> > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> >  	 * Called from audio driver. After audio driver sets the
> >  	 * sample rate, it will call this function to set n/cts
> >  	 */
> > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
> >  	/**
> >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> >  	 *
> > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> >  	 * Note that the returned size may be over @max_bytes.  Then it
> >  	 * implies that only a part of ELD has been copied to the buffer.
> >  	 */
> > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> >  		       unsigned char *buf, int max_bytes);
> >  };
> >  
> > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> >  	 * status accordingly (even when the HDA controller is in power save
> >  	 * mode).
> >  	 */
> > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> >  };
> >  
> >  /**
> > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > index 796cabf..5ab972e 100644
> > --- a/include/sound/hda_i915.h
> > +++ b/include/sound/hda_i915.h
> > @@ -10,8 +10,9 @@
> >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> >  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
> >  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > +			     int dev_id, int rate);
> > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> >  			   bool *audio_enabled, char *buffer, int max_bytes);
> >  int snd_hdac_i915_init(struct hdac_bus *bus);
> >  int snd_hdac_i915_exit(struct hdac_bus *bus);
> > @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> >  {
> >  }
> >  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > -					   hda_nid_t nid, int rate)
> > +					   hda_nid_t nid, int dev_id, int rate)
> >  {
> >  	return 0;
> >  }
> >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > -					 bool *audio_enabled, char *buffer,
> > -					 int max_bytes)
> > +					 int dev_id, bool *audio_enabled,
> > +					 char *buffer, int max_bytes)
> >  {
> >  	return -ENODEV;
> >  }
> > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> > index c9af022..6ea63ac 100644
> > --- a/sound/hda/hdac_i915.c
> > +++ b/sound/hda/hdac_i915.c
> > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
> >   * This function sets N/CTS value based on the given sample rate.
> >   * Returns zero for success, or a negative error code.
> >   */
> > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > +			     int dev_id, int rate)
> >  {
> >  	struct hdac_bus *bus = codec->bus;
> >  	struct i915_audio_component *acomp = bus->audio_component;
> > @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> >  	port = pin2port(codec, nid);
> >  	if (port < 0)
> >  		return -EINVAL;
> > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> >  }
> >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> >  
> > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> >   * that only a part of ELD bytes have been fetched.
> >   */
> > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> >  			   bool *audio_enabled, char *buffer, int max_bytes)
> >  {
> >  	struct hdac_bus *bus = codec->bus;
> > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> >  	port = pin2port(codec, nid);
> >  	if (port < 0)
> >  		return -EINVAL;
> > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
> >  				   buffer, max_bytes);
> >  }
> >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > index d0d5ad8..077d48a 100644
> > --- a/sound/pci/hda/patch_hdmi.c
> > +++ b/sound/pci/hda/patch_hdmi.c
> > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
> >  
> >  	mutex_lock(&per_pin->lock);
> >  	eld->monitor_present = false;
> > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> >  				      &eld->monitor_present, eld->eld_buffer,
> >  				      ELD_MAX_SIZE);
> >  	if (size > 0) {
> > @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> >  	/* Todo: add DP1.2 MST audio support later */
> >  	if (codec_has_acomp(codec))
> > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > +					 runtime->rate);
> >  
> >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> >  	mutex_lock(&per_pin->lock);
> > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
> >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
> >  }
> >  
> > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> >  {
> >  	struct hda_codec *codec = audio_ptr;
> >  	int pin_nid;
> > -- 
> > 2.5.0
> 
> -- 
> Ville Syrjälä
> Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-04 17:18     ` Jim Bride
@ 2016-08-04 17:35       ` Ville Syrjälä
  2016-08-04 17:55         ` Takashi Iwai
  0 siblings, 1 reply; 24+ messages in thread
From: Ville Syrjälä @ 2016-08-04 17:35 UTC (permalink / raw)
  To: Jim Bride; +Cc: tiwai, intel-gfx, alsa-devel, Dhinakaran Pandiyan, libin.yang

On Thu, Aug 04, 2016 at 10:18:52AM -0700, Jim Bride wrote:
> On Wed, Aug 03, 2016 at 10:08:12PM +0300, Ville Syrjälä wrote:
> > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > DP MST provides the capability to send multiple video and audio streams via
> > > one single port. This requires the API's between i915 and audio drivers to
> > > distinguish between audio capable displays connected to a port. This patch
> > > adds this support via an additional parameter 'int dev_id'. The existing
> > > parameter 'port' does not change it's meaning.
> > > 
> > > dev_id =
> > > 	MST	: pipe that the stream originates from
> > > 	Non-MST	: -1
> > > 
> > > Affected APIs:
> > > struct i915_audio_component_ops
> > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > 
> > Does the term 'dev_id' have some special meaning on the audio side? On
> > the i915 side things would be less confusing if we just called it
> > 'pipe'.
> 
> Yeah, it does.  All of the documentation on the audio side is written
> in terms of device ID, so they asked for that nomenclature.

And is the device ID always the same as the pipe? Until now we've made
due with passing the port instead of the pipe, so either the audio side
didn't use the device ID, or its meaning changes based on how we drive
things, or they dug it out from somewhere else based on the port?

> 
> Jim
> 
> 
> > > +	     int rate);
> > > 
> > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > -                       unsigned char *buf, int max_bytes);
> > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > > 
> > > struct i915_audio_component_audio_ops
> > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > 
> > > This patch makes dummy changes in the audio drivers for build to succeed.
> > > 
> > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++---------
> > >  include/drm/i915_component.h       |  6 +--
> > >  include/sound/hda_i915.h           | 11 ++---
> > >  sound/hda/hdac_i915.c              |  9 +++--
> > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index 65ada5d..8e4c8c8 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > >  	/* perform PHY state sanity checks? */
> > >  	bool chv_phy_assert[2];
> > >  
> > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> > >  
> > >  	/*
> > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
> > > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
> > > index 8c493de..cbe44c8 100644
> > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > >  	enum port port = intel_dig_port->port;
> > > +	enum pipe pipe = crtc->pipe;
> > > +	int dev_id = -1;
> > > +
> > >  
> > >  	connector = drm_select_eld(encoder);
> > >  	if (!connector)
> > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > >  		dev_priv->display.audio_codec_enable(connector, intel_encoder,
> > >  						     adjusted_mode);
> > >  
> > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > +		dev_id = pipe;
> > > +
> > >  	mutex_lock(&dev_priv->av_mutex);
> > >  	intel_encoder->audio_connector = connector;
> > > +
> > >  	/* referred in audio callbacks */
> > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > >  
> > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > +						 (int) port, dev_id);
> > >  }
> > >  
> > >  /**
> > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
> > >  void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
> > >  {
> > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > >  	struct drm_device *dev = encoder->dev;
> > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > >  	enum port port = intel_dig_port->port;
> > > +	enum pipe pipe = crtc->pipe;
> > > +	int dev_id = -1;
> > > +
> > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > +		dev_id = pipe;
> > >  
> > >  	if (dev_priv->display.audio_codec_disable)
> > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > >  
> > >  	mutex_lock(&dev_priv->av_mutex);
> > >  	intel_encoder->audio_connector = NULL;
> > > -	dev_priv->dig_port_map[port] = NULL;
> > > +	dev_priv->av_enc_map[pipe] = NULL;
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > >  
> > >  	if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
> > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr, (int) port);
> > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
> > > +						 (int) port, dev_id);
> > >  }
> > >  
> > >  /**
> > > @@ -628,8 +643,32 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
> > >  	return dev_priv->cdclk_freq;
> > >  }
> > >  
> > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > -						int port, int rate)
> > > +static struct intel_encoder *get_saved_encoder(struct intel_encoder *av_enc_map[],
> > > +					       int port, int dev_id)
> > > +{
> > > +
> > > +	enum pipe pipe;
> > > +	struct drm_encoder *encoder;
> > > +
> > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > +		return av_enc_map[dev_id];
> > > +
> > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > +
> > > +		if (!av_enc_map[pipe])
> > > +			continue;
> > > +
> > > +		encoder = &av_enc_map[pipe]->base;
> > > +		if (port == enc_to_dig_port(encoder)->port)
> > > +			return av_enc_map[pipe];
> > > +	}
> > > +
> > > +	return NULL;
> > > +
> > > +}
> > > +
> > > +static int i915_audio_component_sync_audio_rate(struct device *dev, int port,
> > > +						int dev_id, int rate)
> > >  {
> > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > >  	struct intel_encoder *intel_encoder;
> > > @@ -649,15 +688,16 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > >  		return 0;
> > >  
> > >  	mutex_lock(&dev_priv->av_mutex);
> > > +
> > >  	/* 1. get the pipe */
> > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > -	/* intel_encoder might be NULL for DP MST */
> > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > >  		err = -ENODEV;
> > >  		goto unlock;
> > >  	}
> > > +
> > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > >  	pipe = crtc->pipe;
> > >  	if (pipe == INVALID_PIPE) {
> > > @@ -702,7 +742,7 @@ static int i915_audio_component_sync_audio_rate(struct device *dev,
> > >  }
> > >  
> > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > -					bool *enabled,
> > > +					int dev_id, bool *enabled,
> > >  					unsigned char *buf, int max_bytes)
> > >  {
> > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > @@ -710,17 +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int port,
> > >  	const u8 *eld;
> > >  	int ret = -EINVAL;
> > >  
> > > +
> > >  	mutex_lock(&dev_priv->av_mutex);
> > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > -	/* intel_encoder might be NULL for DP MST */
> > > -	if (intel_encoder) {
> > > -		ret = 0;
> > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > -		if (*enabled) {
> > > -			eld = intel_encoder->audio_connector->eld;
> > > -			ret = drm_eld_size(eld);
> > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > -		}
> > > +
> > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port, dev_id);
> > > +	if (!intel_encoder) {
> > > +		mutex_unlock(&dev_priv->av_mutex);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = 0;
> > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > +	if (*enabled) {
> > > +		eld = intel_encoder->audio_connector->eld;
> > > +		ret = drm_eld_size(eld);
> > > +		memcpy(buf, eld, min(max_bytes, ret));
> > >  	}
> > >  
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > > index b46fa0e..1419c98 100644
> > > --- a/include/drm/i915_component.h
> > > +++ b/include/drm/i915_component.h
> > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > >  	 * Called from audio driver. After audio driver sets the
> > >  	 * sample rate, it will call this function to set n/cts
> > >  	 */
> > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int rate);
> > >  	/**
> > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > >  	 *
> > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > >  	 * implies that only a part of ELD has been copied to the buffer.
> > >  	 */
> > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> > >  		       unsigned char *buf, int max_bytes);
> > >  };
> > >  
> > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > >  	 * status accordingly (even when the HDA controller is in power save
> > >  	 * mode).
> > >  	 */
> > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > >  };
> > >  
> > >  /**
> > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > index 796cabf..5ab972e 100644
> > > --- a/include/sound/hda_i915.h
> > > +++ b/include/sound/hda_i915.h
> > > @@ -10,8 +10,9 @@
> > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> > >  int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
> > >  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate);
> > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > +			     int dev_id, int rate);
> > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > >  int snd_hdac_i915_init(struct hdac_bus *bus);
> > >  int snd_hdac_i915_exit(struct hdac_bus *bus);
> > > @@ -29,13 +30,13 @@ static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> > >  {
> > >  }
> > >  static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > -					   hda_nid_t nid, int rate)
> > > +					   hda_nid_t nid, int dev_id, int rate)
> > >  {
> > >  	return 0;
> > >  }
> > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > -					 bool *audio_enabled, char *buffer,
> > > -					 int max_bytes)
> > > +					 int dev_id, bool *audio_enabled,
> > > +					 char *buffer, int max_bytes)
> > >  {
> > >  	return -ENODEV;
> > >  }
> > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
> > > index c9af022..6ea63ac 100644
> > > --- a/sound/hda/hdac_i915.c
> > > +++ b/sound/hda/hdac_i915.c
> > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec, hda_nid_t pin_nid)
> > >   * This function sets N/CTS value based on the given sample rate.
> > >   * Returns zero for success, or a negative error code.
> > >   */
> > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > +			     int dev_id, int rate)
> > >  {
> > >  	struct hdac_bus *bus = codec->bus;
> > >  	struct i915_audio_component *acomp = bus->audio_component;
> > > @@ -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int rate)
> > >  	port = pin2port(codec, nid);
> > >  	if (port < 0)
> > >  		return -EINVAL;
> > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> > >  }
> > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > >  
> > > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > >   * that only a part of ELD bytes have been fetched.
> > >   */
> > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
> > >  			   bool *audio_enabled, char *buffer, int max_bytes)
> > >  {
> > >  	struct hdac_bus *bus = codec->bus;
> > > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > >  	port = pin2port(codec, nid);
> > >  	if (port < 0)
> > >  		return -EINVAL;
> > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id, audio_enabled,
> > >  				   buffer, max_bytes);
> > >  }
> > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > > index d0d5ad8..077d48a 100644
> > > --- a/sound/pci/hda/patch_hdmi.c
> > > +++ b/sound/pci/hda/patch_hdmi.c
> > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
> > >  
> > >  	mutex_lock(&per_pin->lock);
> > >  	eld->monitor_present = false;
> > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> > >  				      &eld->monitor_present, eld->eld_buffer,
> > >  				      ELD_MAX_SIZE);
> > >  	if (size > 0) {
> > > @@ -1739,7 +1739,8 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > >  	/* Todo: add DP1.2 MST audio support later */
> > >  	if (codec_has_acomp(codec))
> > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime->rate);
> > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > +					 runtime->rate);
> > >  
> > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > >  	mutex_lock(&per_pin->lock);
> > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
> > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);
> > >  }
> > >  
> > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> > >  {
> > >  	struct hda_codec *codec = audio_ptr;
> > >  	int pin_nid;
> > > -- 
> > > 2.5.0
> > 
> > -- 
> > Ville Syrjälä
> > Intel OTC

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-04 17:35       ` Ville Syrjälä
@ 2016-08-04 17:55         ` Takashi Iwai
  2016-08-04 20:48           ` Ville Syrjälä
  0 siblings, 1 reply; 24+ messages in thread
From: Takashi Iwai @ 2016-08-04 17:55 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: libin.yang, intel-gfx, alsa-devel, Dhinakaran Pandiyan

On Thu, 04 Aug 2016 19:35:16 +0200,
Ville Syrjälä wrote:
> 
> On Thu, Aug 04, 2016 at 10:18:52AM -0700, Jim Bride wrote:
> > On Wed, Aug 03, 2016 at 10:08:12PM +0300, Ville Syrjälä wrote:
> > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > DP MST provides the capability to send multiple video and audio streams via
> > > > one single port. This requires the API's between i915 and audio drivers to
> > > > distinguish between audio capable displays connected to a port. This patch
> > > > adds this support via an additional parameter 'int dev_id'. The existing
> > > > parameter 'port' does not change it's meaning.
> > > > 
> > > > dev_id =
> > > > 	MST	: pipe that the stream originates from
> > > > 	Non-MST	: -1
> > > > 
> > > > Affected APIs:
> > > > struct i915_audio_component_ops
> > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > 
> > > Does the term 'dev_id' have some special meaning on the audio side? On
> > > the i915 side things would be less confusing if we just called it
> > > 'pipe'.
> > 
> > Yeah, it does.  All of the documentation on the audio side is written
> > in terms of device ID, so they asked for that nomenclature.
> 
> And is the device ID always the same as the pipe? Until now we've made
> due with passing the port instead of the pipe, so either the audio side
> didn't use the device ID, or its meaning changes based on how we drive
> things, or they dug it out from somewhere else based on the port?

This is my concern, too.  Currently we have a very wild assumption
even for the port mapping.  In the audio side, there is neither port
nor pipe.  There are only the widget node id and the device id.  The
former is supposedly corresponding to the port, and the latter to the
pipe.  But the audio side has absolutely no clue about how these are
connected.


Takashi
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-04 17:55         ` Takashi Iwai
@ 2016-08-04 20:48           ` Ville Syrjälä
  2016-08-05  2:31             ` Yang, Libin
  0 siblings, 1 reply; 24+ messages in thread
From: Ville Syrjälä @ 2016-08-04 20:48 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: libin.yang, intel-gfx, alsa-devel, Dhinakaran Pandiyan

On Thu, Aug 04, 2016 at 07:55:09PM +0200, Takashi Iwai wrote:
> On Thu, 04 Aug 2016 19:35:16 +0200,
> Ville Syrjälä wrote:
> > 
> > On Thu, Aug 04, 2016 at 10:18:52AM -0700, Jim Bride wrote:
> > > On Wed, Aug 03, 2016 at 10:08:12PM +0300, Ville Syrjälä wrote:
> > > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > > DP MST provides the capability to send multiple video and audio streams via
> > > > > one single port. This requires the API's between i915 and audio drivers to
> > > > > distinguish between audio capable displays connected to a port. This patch
> > > > > adds this support via an additional parameter 'int dev_id'. The existing
> > > > > parameter 'port' does not change it's meaning.
> > > > > 
> > > > > dev_id =
> > > > > 	MST	: pipe that the stream originates from
> > > > > 	Non-MST	: -1
> > > > > 
> > > > > Affected APIs:
> > > > > struct i915_audio_component_ops
> > > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > > 
> > > > Does the term 'dev_id' have some special meaning on the audio side? On
> > > > the i915 side things would be less confusing if we just called it
> > > > 'pipe'.
> > > 
> > > Yeah, it does.  All of the documentation on the audio side is written
> > > in terms of device ID, so they asked for that nomenclature.
> > 
> > And is the device ID always the same as the pipe? Until now we've made
> > due with passing the port instead of the pipe, so either the audio side
> > didn't use the device ID, or its meaning changes based on how we drive
> > things, or they dug it out from somewhere else based on the port?
> 
> This is my concern, too.  Currently we have a very wild assumption
> even for the port mapping.  In the audio side, there is neither port
> nor pipe.  There are only the widget node id and the device id.  The
> former is supposedly corresponding to the port, and the latter to the
> pipe.  But the audio side has absolutely no clue about how these are
> connected.

So I tried to study this a bit, and MST and device<n> are mentioned a few
times in the description of some audio registers in the GPU docs. Looks
like a bunch of bits overlap somehow with pin vs. device usage. I don't
understand how that's supposed to work. Eg:
 AUD_PWRSTAUD_PWRST
 1:0 	 PinB Widget PwrSt Set
 PinB Widget power state that was setFor DP MST this represents Device1
 power state

It's anyone's guees what those bits are suppoosed to reflect when you're
doing MST with device1/pipe A, and at the same time you're driving
port B in HDMI/SST mode.

Anyways, it doesn't help that this whole device widget aspect of hda
seems to be undocumented. No spec I've found seems to know anything
about any device widgets, and yet those are how MST rolls apparently.

In conclusion, I'd say that consistency's sake we should use either
dev+pin or pipe+port in the interface, not mix both. In case of
dev+pin I don't think we should use the NID (I'm assuming device
widgets have one too), but rather the index. i915 could then do
the mapping somethign like dev=pipe and pin=port-1, and then
snd-hda can do the idx<->nid conversion however it sees fit
(just use base_nid, or walk some per-type widget lists, or whatever).

That's assuming the widgets really are somehow ordered consistently so
we can index them like that. I also might have understtod everyhing I
read abou hda.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-04 20:48           ` Ville Syrjälä
@ 2016-08-05  2:31             ` Yang, Libin
  2016-08-05  7:46               ` Pandiyan, Dhinakaran
  0 siblings, 1 reply; 24+ messages in thread
From: Yang, Libin @ 2016-08-05  2:31 UTC (permalink / raw)
  To: Ville Syrjälä, Takashi Iwai
  Cc: libin.yang, intel-gfx, alsa-devel, Pandiyan, Dhinakaran


> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
> Ville Syrjälä
> Sent: Friday, August 5, 2016 4:48 AM
> To: Takashi Iwai <tiwai@suse.de>
> Cc: libin.yang@linux.intel.com; intel-gfx@lists.freedesktop.org; alsa-
> devel@alsa-project.org; Pandiyan, Dhinakaran
> <dhinakaran.pandiyan@intel.com>
> Subject: Re: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> 
> On Thu, Aug 04, 2016 at 07:55:09PM +0200, Takashi Iwai wrote:
> > On Thu, 04 Aug 2016 19:35:16 +0200,
> > Ville Syrjälä wrote:
> > >
> > > On Thu, Aug 04, 2016 at 10:18:52AM -0700, Jim Bride wrote:
> > > > On Wed, Aug 03, 2016 at 10:08:12PM +0300, Ville Syrjälä wrote:
> > > > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > > > DP MST provides the capability to send multiple video and
> > > > > > audio streams via one single port. This requires the API's
> > > > > > between i915 and audio drivers to distinguish between audio
> > > > > > capable displays connected to a port. This patch adds this
> > > > > > support via an additional parameter 'int dev_id'. The existing
> parameter 'port' does not change it's meaning.
> > > > > >
> > > > > > dev_id =
> > > > > > 	MST	: pipe that the stream originates from
> > > > > > 	Non-MST	: -1
> > > > > >
> > > > > > Affected APIs:
> > > > > > struct i915_audio_component_ops
> > > > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > > +	int (*sync_audio_rate)(struct device *, int port, int
> > > > > > +dev_id,
> > > > >
> > > > > Does the term 'dev_id' have some special meaning on the audio
> > > > > side? On the i915 side things would be less confusing if we just
> > > > > called it 'pipe'.
> > > >
> > > > Yeah, it does.  All of the documentation on the audio side is
> > > > written in terms of device ID, so they asked for that nomenclature.
> > >
> > > And is the device ID always the same as the pipe? Until now we've
> > > made due with passing the port instead of the pipe, so either the
> > > audio side didn't use the device ID, or its meaning changes based on
> > > how we drive things, or they dug it out from somewhere else based on the
> port?
> >
> > This is my concern, too.  Currently we have a very wild assumption
> > even for the port mapping.  In the audio side, there is neither port
> > nor pipe.  There are only the widget node id and the device id.  The
> > former is supposedly corresponding to the port, and the latter to the
> > pipe.  But the audio side has absolutely no clue about how these are
> > connected.
> 
> So I tried to study this a bit, and MST and device<n> are mentioned a few
> times in the description of some audio registers in the GPU docs. Looks like a
> bunch of bits overlap somehow with pin vs. device usage. I don't understand
> how that's supposed to work. Eg:

For SST & HDMI, port is mapping to pin.

For MST, in audio, each pin has several device entries. Each device entry
can transfer audio stream. And we confirmed with silicon team,
device entry is related to pipe.

Device entry is always the right concept in audio driver. We are not sure
the relationship will be always right between pipe and device entry.

We are worry that the relationship may be changed in the future between
pipe and device entry. I mean maybe the pipe is not related to device
entry in the new platforms, but some other conception, such as transcoder.
If so, if we are using pipe now, maybe we need change the API again.
For the stability, we are thinking device entry is suitable.

I think your concern is right. It is not good to use audio conception 
in gfx driver, which will cause confusion. If we can confirm that
pipe will always be the fixed mapping to device entry, it will be
better to use pipe.

>  AUD_PWRSTAUD_PWRST
>  1:0 	 PinB Widget PwrSt Set
>  PinB Widget power state that was setFor DP MST this represents Device1
> power state

For this register, it means different in different scenario:
In DP SST & HDMI, it is for PinB
In DP MST, it is for device entry 1 (on whichever pin). 

> 
> It's anyone's guees what those bits are suppoosed to reflect when you're doing
> MST with device1/pipe A, and at the same time you're driving port B in
> HDMI/SST mode.

I did the similar test before. I remember (but I didn't remember clearly now)
If one pin is used as DP MST, all the pins are used as DP MST. This means if
PinB is used as DP MST, 1:0 represents Device 1 and 5:4 represents Device 2.
Let's say PinC is connected to HDMI audio, it is now looked as Device 2 (or
other device id) not as PinC audio.

Regards,
Libin

> 
> Anyways, it doesn't help that this whole device widget aspect of hda seems to
> be undocumented. No spec I've found seems to know anything about any
> device widgets, and yet those are how MST rolls apparently.
> 
> In conclusion, I'd say that consistency's sake we should use either
> dev+pin or pipe+port in the interface, not mix both. In case of pin I
> dev+don't think we should use the NID (I'm assuming device
> widgets have one too), but rather the index. i915 could then do the mapping
> somethign like dev=pipe and pin=port-1, and then snd-hda can do the idx<-
> >nid conversion however it sees fit (just use base_nid, or walk some per-type
> widget lists, or whatever).
> 
> That's assuming the widgets really are somehow ordered consistently so we
> can index them like that. I also might have understtod everyhing I read abou
> hda.
> 
> --
> Ville Syrjälä
> Intel OTC
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-03  2:14 ` [PATCH] drm/i915/dp: DP audio API changes for MST Dhinakaran Pandiyan
  2016-08-03 13:53   ` Takashi Iwai
  2016-08-03 19:08   ` Ville Syrjälä
@ 2016-08-05  2:35   ` Yang, Libin
  2016-08-05  5:57     ` Pandiyan, Dhinakaran
  2 siblings, 1 reply; 24+ messages in thread
From: Yang, Libin @ 2016-08-05  2:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: tiwai, alsa-devel, libin.yang, Pandiyan, Dhinakaran


> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
> Dhinakaran Pandiyan
> Sent: Wednesday, August 3, 2016 10:15 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: alsa-devel@alsa-project.org; tiwai@suse.de; libin.yang@linux.intel.com;
> Pandiyan, Dhinakaran <dhinakaran.pandiyan@intel.com>
> Subject: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> 
> DP MST provides the capability to send multiple video and audio streams via
> one single port. This requires the API's between i915 and audio drivers to
> distinguish between audio capable displays connected to a port. This patch
> adds this support via an additional parameter 'int dev_id'. The existing
> parameter 'port' does not change it's meaning.
> 
> dev_id =
> 	MST	: pipe that the stream originates from
> 	Non-MST	: -1
> 
> Affected APIs:
> struct i915_audio_component_ops
> -       int (*sync_audio_rate)(struct device *, int port, int rate);
> +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> +	     int rate);
> 
> -       int (*get_eld)(struct device *, int port, bool *enabled,
> -                       unsigned char *buf, int max_bytes);
> +       int (*get_eld)(struct device *, int port, int dev_id,
> +		       bool *enabled, unsigned char *buf, int max_bytes);
> 
> struct i915_audio_component_audio_ops
> -       void (*pin_eld_notify)(void *audio_ptr, int port);
> +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> 
> This patch makes dummy changes in the audio drivers for build to succeed.
> 
> Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
>  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++--
> -------
>  include/drm/i915_component.h       |  6 +--
>  include/sound/hda_i915.h           | 11 ++---
>  sound/hda/hdac_i915.c              |  9 +++--
>  sound/pci/hda/patch_hdmi.c         |  7 ++--
>  6 files changed, 82 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h index 65ada5d..8e4c8c8 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2054,7 +2054,7 @@ struct drm_i915_private {
>  	/* perform PHY state sanity checks? */
>  	bool chv_phy_assert[2];
> 
> -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];

We may still need save the port number info.
In non-MST mode, device entry means nothing. This means
av_enc_map[pipe] may not get the right intel_encoder

Regards,
Libin

> 
>  	/*
>  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your
> patch diff --git a/drivers/gpu/drm/i915/intel_audio.c
> b/drivers/gpu/drm/i915/intel_audio.c
> index 8c493de..cbe44c8 100644
> --- a/drivers/gpu/drm/i915/intel_audio.c
> +++ b/drivers/gpu/drm/i915/intel_audio.c
> @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder
> *intel_encoder)
>  	struct i915_audio_component *acomp = dev_priv->audio_component;
>  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
>  	enum port port = intel_dig_port->port;
> +	enum pipe pipe = crtc->pipe;
> +	int dev_id = -1;
> +
> 
>  	connector = drm_select_eld(encoder);
>  	if (!connector)
> @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder
> *intel_encoder)
>  		dev_priv->display.audio_codec_enable(connector,
> intel_encoder,
>  						     adjusted_mode);
> 
> +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> +		dev_id = pipe;
> +
>  	mutex_lock(&dev_priv->av_mutex);
>  	intel_encoder->audio_connector = connector;
> +
>  	/* referred in audio callbacks */
> -	dev_priv->dig_port_map[port] = intel_encoder;
> +	dev_priv->av_enc_map[pipe] = intel_encoder;
>  	mutex_unlock(&dev_priv->av_mutex);
> 
>  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> >pin_eld_notify)
> -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> >audio_ptr, (int) port);
> +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> >audio_ptr,
> +						 (int) port, dev_id);
>  }
> 
>  /**
> @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder
> *intel_encoder)  void intel_audio_codec_disable(struct intel_encoder
> *intel_encoder)  {
>  	struct drm_encoder *encoder = &intel_encoder->base;
> +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct i915_audio_component *acomp = dev_priv->audio_component;
>  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
>  	enum port port = intel_dig_port->port;
> +	enum pipe pipe = crtc->pipe;
> +	int dev_id = -1;
> +
> +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> +		dev_id = pipe;
> 
>  	if (dev_priv->display.audio_codec_disable)
>  		dev_priv->display.audio_codec_disable(intel_encoder);
> 
>  	mutex_lock(&dev_priv->av_mutex);
>  	intel_encoder->audio_connector = NULL;
> -	dev_priv->dig_port_map[port] = NULL;
> +	dev_priv->av_enc_map[pipe] = NULL;
>  	mutex_unlock(&dev_priv->av_mutex);
> 
>  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> >pin_eld_notify)
> -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> >audio_ptr, (int) port);
> +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> >audio_ptr,
> +						 (int) port, dev_id);
>  }
> 
>  /**
> @@ -628,8 +643,32 @@ static int
> i915_audio_component_get_cdclk_freq(struct device *dev)
>  	return dev_priv->cdclk_freq;
>  }
> 
> -static int i915_audio_component_sync_audio_rate(struct device *dev,
> -						int port, int rate)
> +static struct intel_encoder *get_saved_encoder(struct intel_encoder
> *av_enc_map[],
> +					       int port, int dev_id)
> +{
> +
> +	enum pipe pipe;
> +	struct drm_encoder *encoder;
> +
> +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> +		return av_enc_map[dev_id];
> +
> +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> +
> +		if (!av_enc_map[pipe])
> +			continue;
> +
> +		encoder = &av_enc_map[pipe]->base;
> +		if (port == enc_to_dig_port(encoder)->port)
> +			return av_enc_map[pipe];
> +	}
> +
> +	return NULL;
> +
> +}
> +
> +static int i915_audio_component_sync_audio_rate(struct device *dev, int
> port,
> +						int dev_id, int rate)
>  {
>  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
>  	struct intel_encoder *intel_encoder;
> @@ -649,15 +688,16 @@ static int
> i915_audio_component_sync_audio_rate(struct device *dev,
>  		return 0;
> 
>  	mutex_lock(&dev_priv->av_mutex);
> +
>  	/* 1. get the pipe */
> -	intel_encoder = dev_priv->dig_port_map[port];
> -	/* intel_encoder might be NULL for DP MST */
> +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> dev_id);
>  	if (!intel_encoder || !intel_encoder->base.crtc ||
>  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
>  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
>  		err = -ENODEV;
>  		goto unlock;
>  	}
> +
>  	crtc = to_intel_crtc(intel_encoder->base.crtc);
>  	pipe = crtc->pipe;
>  	if (pipe == INVALID_PIPE) {
> @@ -702,7 +742,7 @@ static int
> i915_audio_component_sync_audio_rate(struct device *dev,  }
> 
>  static int i915_audio_component_get_eld(struct device *dev, int port,
> -					bool *enabled,
> +					int dev_id, bool *enabled,
>  					unsigned char *buf, int max_bytes)  {
>  	struct drm_i915_private *dev_priv = dev_to_i915(dev); @@ -710,17
> +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int
> port,
>  	const u8 *eld;
>  	int ret = -EINVAL;
> 
> +
>  	mutex_lock(&dev_priv->av_mutex);
> -	intel_encoder = dev_priv->dig_port_map[port];
> -	/* intel_encoder might be NULL for DP MST */
> -	if (intel_encoder) {
> -		ret = 0;
> -		*enabled = intel_encoder->audio_connector != NULL;
> -		if (*enabled) {
> -			eld = intel_encoder->audio_connector->eld;
> -			ret = drm_eld_size(eld);
> -			memcpy(buf, eld, min(max_bytes, ret));
> -		}
> +
> +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> dev_id);
> +	if (!intel_encoder) {
> +		mutex_unlock(&dev_priv->av_mutex);
> +		return ret;
> +	}
> +
> +	ret = 0;
> +	*enabled = intel_encoder->audio_connector != NULL;
> +	if (*enabled) {
> +		eld = intel_encoder->audio_connector->eld;
> +		ret = drm_eld_size(eld);
> +		memcpy(buf, eld, min(max_bytes, ret));
>  	}
> 
>  	mutex_unlock(&dev_priv->av_mutex);
> diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> index b46fa0e..1419c98 100644
> --- a/include/drm/i915_component.h
> +++ b/include/drm/i915_component.h
> @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
>  	 * Called from audio driver. After audio driver sets the
>  	 * sample rate, it will call this function to set n/cts
>  	 */
> -	int (*sync_audio_rate)(struct device *, int port, int rate);
> +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int
> +rate);
>  	/**
>  	 * @get_eld: fill the audio state and ELD bytes for the given port
>  	 *
> @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
>  	 * Note that the returned size may be over @max_bytes.  Then it
>  	 * implies that only a part of ELD has been copied to the buffer.
>  	 */
> -	int (*get_eld)(struct device *, int port, bool *enabled,
> +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
>  		       unsigned char *buf, int max_bytes);  };
> 
> @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
>  	 * status accordingly (even when the HDA controller is in power save
>  	 * mode).
>  	 */
> -	void (*pin_eld_notify)(void *audio_ptr, int port);
> +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
>  };
> 
>  /**
> diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h index
> 796cabf..5ab972e 100644
> --- a/include/sound/hda_i915.h
> +++ b/include/sound/hda_i915.h
> @@ -10,8 +10,9 @@
>  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);  int
> snd_hdac_display_power(struct hdac_bus *bus, bool enable);  void
> snd_hdac_i915_set_bclk(struct hdac_bus *bus); -int
> snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int
> rate); -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> +			     int dev_id, int rate);
> +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> +int dev_id,
>  			   bool *audio_enabled, char *buffer, int max_bytes);
> int snd_hdac_i915_init(struct hdac_bus *bus);  int snd_hdac_i915_exit(struct
> hdac_bus *bus); @@ -29,13 +30,13 @@ static inline void
> snd_hdac_i915_set_bclk(struct hdac_bus *bus)  {  }  static inline int
> snd_hdac_sync_audio_rate(struct hdac_device *codec,
> -					   hda_nid_t nid, int rate)
> +					   hda_nid_t nid, int dev_id, int rate)
>  {
>  	return 0;
>  }
>  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec,
> hda_nid_t nid,
> -					 bool *audio_enabled, char *buffer,
> -					 int max_bytes)
> +					 int dev_id, bool *audio_enabled,
> +					 char *buffer, int max_bytes)
>  {
>  	return -ENODEV;
>  }
> diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index
> c9af022..6ea63ac 100644
> --- a/sound/hda/hdac_i915.c
> +++ b/sound/hda/hdac_i915.c
> @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec,
> hda_nid_t pin_nid)
>   * This function sets N/CTS value based on the given sample rate.
>   * Returns zero for success, or a negative error code.
>   */
> -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int
> rate)
> +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> +			     int dev_id, int rate)
>  {
>  	struct hdac_bus *bus = codec->bus;
>  	struct i915_audio_component *acomp = bus->audio_component; @@
> -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> hda_nid_t nid, int rate)
>  	port = pin2port(codec, nid);
>  	if (port < 0)
>  		return -EINVAL;
> -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
>  }
>  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> 
> @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
>   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
>   * that only a part of ELD bytes have been fetched.
>   */
> -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> +int dev_id,
>  			   bool *audio_enabled, char *buffer, int max_bytes)  {
>  	struct hdac_bus *bus = codec->bus;
> @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device
> *codec, hda_nid_t nid,
>  	port = pin2port(codec, nid);
>  	if (port < 0)
>  		return -EINVAL;
> -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> +	return acomp->ops->get_eld(acomp->dev, port, dev_id,
> audio_enabled,
>  				   buffer, max_bytes);
>  }
>  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index
> d0d5ad8..077d48a 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec
> *codec,
> 
>  	mutex_lock(&per_pin->lock);
>  	eld->monitor_present = false;
> -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
>  				      &eld->monitor_present, eld->eld_buffer,
>  				      ELD_MAX_SIZE);
>  	if (size > 0) {
> @@ -1739,7 +1739,8 @@ static int
> generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
>  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
>  	/* Todo: add DP1.2 MST audio support later */
>  	if (codec_has_acomp(codec))
> -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime-
> >rate);
> +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> +					 runtime->rate);
> 
>  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
>  	mutex_lock(&per_pin->lock);
> @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct
> hda_codec *codec, hda_nid_t fg,
>  	snd_hda_codec_set_power_to_all(codec, fg, power_state);  }
> 
> -static void intel_pin_eld_notify(void *audio_ptr, int port)
> +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
>  {
>  	struct hda_codec *codec = audio_ptr;
>  	int pin_nid;
> --
> 2.5.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-05  2:35   ` Yang, Libin
@ 2016-08-05  5:57     ` Pandiyan, Dhinakaran
  2016-08-05  6:21       ` Yang, Libin
  0 siblings, 1 reply; 24+ messages in thread
From: Pandiyan, Dhinakaran @ 2016-08-05  5:57 UTC (permalink / raw)
  To: Yang, Libin; +Cc: tiwai, intel-gfx, alsa-devel, libin.yang

On Fri, 2016-08-05 at 02:35 +0000, Yang, Libin wrote:
> > -----Original Message-----
> > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
> > Dhinakaran Pandiyan
> > Sent: Wednesday, August 3, 2016 10:15 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: alsa-devel@alsa-project.org; tiwai@suse.de; libin.yang@linux.intel.com;
> > Pandiyan, Dhinakaran <dhinakaran.pandiyan@intel.com>
> > Subject: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> > 
> > DP MST provides the capability to send multiple video and audio streams via
> > one single port. This requires the API's between i915 and audio drivers to
> > distinguish between audio capable displays connected to a port. This patch
> > adds this support via an additional parameter 'int dev_id'. The existing
> > parameter 'port' does not change it's meaning.
> > 
> > dev_id =
> > 	MST	: pipe that the stream originates from
> > 	Non-MST	: -1
> > 
> > Affected APIs:
> > struct i915_audio_component_ops
> > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > +	     int rate);
> > 
> > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > -                       unsigned char *buf, int max_bytes);
> > +       int (*get_eld)(struct device *, int port, int dev_id,
> > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > 
> > struct i915_audio_component_audio_ops
> > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > +       void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > 
> > This patch makes dummy changes in the audio drivers for build to succeed.
> > 
> > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> >  drivers/gpu/drm/i915/intel_audio.c | 82 +++++++++++++++++++++++++++++--
> > -------
> >  include/drm/i915_component.h       |  6 +--
> >  include/sound/hda_i915.h           | 11 ++---
> >  sound/hda/hdac_i915.c              |  9 +++--
> >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> >  6 files changed, 82 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h index 65ada5d..8e4c8c8 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> >  	/* perform PHY state sanity checks? */
> >  	bool chv_phy_assert[2];
> > 
> > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> 
> We may still need save the port number info.
> In non-MST mode, device entry means nothing. This means
> av_enc_map[pipe] may not get the right intel_encoder
> 
> Regards,
> Libin
> 
We find the encoder using port in get_saved_encoder()
> > 
> >  	/*
> >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your
> > patch diff --git a/drivers/gpu/drm/i915/intel_audio.c
> > b/drivers/gpu/drm/i915/intel_audio.c
> > index 8c493de..cbe44c8 100644
> > --- a/drivers/gpu/drm/i915/intel_audio.c
> > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct intel_encoder
> > *intel_encoder)
> >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> >  	enum port port = intel_dig_port->port;
> > +	enum pipe pipe = crtc->pipe;
> > +	int dev_id = -1;
> > +
> > 
> >  	connector = drm_select_eld(encoder);
> >  	if (!connector)
> > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct intel_encoder
> > *intel_encoder)
> >  		dev_priv->display.audio_codec_enable(connector,
> > intel_encoder,
> >  						     adjusted_mode);
> > 
> > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > +		dev_id = pipe;
> > +
> >  	mutex_lock(&dev_priv->av_mutex);
> >  	intel_encoder->audio_connector = connector;
> > +
> >  	/* referred in audio callbacks */
> > -	dev_priv->dig_port_map[port] = intel_encoder;
> > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> >  	mutex_unlock(&dev_priv->av_mutex);
> > 
> >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > >pin_eld_notify)
> > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > >audio_ptr, (int) port);
> > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > >audio_ptr,
> > +						 (int) port, dev_id);
> >  }
> > 
> >  /**
> > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct intel_encoder
> > *intel_encoder)  void intel_audio_codec_disable(struct intel_encoder
> > *intel_encoder)  {
> >  	struct drm_encoder *encoder = &intel_encoder->base;
> > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> >  	struct drm_device *dev = encoder->dev;
> >  	struct drm_i915_private *dev_priv = to_i915(dev);
> >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> >  	enum port port = intel_dig_port->port;
> > +	enum pipe pipe = crtc->pipe;
> > +	int dev_id = -1;
> > +
> > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > +		dev_id = pipe;
> > 
> >  	if (dev_priv->display.audio_codec_disable)
> >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > 
> >  	mutex_lock(&dev_priv->av_mutex);
> >  	intel_encoder->audio_connector = NULL;
> > -	dev_priv->dig_port_map[port] = NULL;
> > +	dev_priv->av_enc_map[pipe] = NULL;
> >  	mutex_unlock(&dev_priv->av_mutex);
> > 
> >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > >pin_eld_notify)
> > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > >audio_ptr, (int) port);
> > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > >audio_ptr,
> > +						 (int) port, dev_id);
> >  }
> > 
> >  /**
> > @@ -628,8 +643,32 @@ static int
> > i915_audio_component_get_cdclk_freq(struct device *dev)
> >  	return dev_priv->cdclk_freq;
> >  }
> > 
> > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > -						int port, int rate)
> > +static struct intel_encoder *get_saved_encoder(struct intel_encoder
> > *av_enc_map[],
> > +					       int port, int dev_id)
> > +{
> > +
> > +	enum pipe pipe;
> > +	struct drm_encoder *encoder;
> > +
> > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > +		return av_enc_map[dev_id];
> > +
> > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > +
> > +		if (!av_enc_map[pipe])
> > +			continue;
> > +
> > +		encoder = &av_enc_map[pipe]->base;
> > +		if (port == enc_to_dig_port(encoder)->port)
> > +			return av_enc_map[pipe];
> > +	}
> > +
> > +	return NULL;
> > +
> > +}
> > +
> > +static int i915_audio_component_sync_audio_rate(struct device *dev, int
> > port,
> > +						int dev_id, int rate)
> >  {
> >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> >  	struct intel_encoder *intel_encoder;
> > @@ -649,15 +688,16 @@ static int
> > i915_audio_component_sync_audio_rate(struct device *dev,
> >  		return 0;
> > 
> >  	mutex_lock(&dev_priv->av_mutex);
> > +
> >  	/* 1. get the pipe */
> > -	intel_encoder = dev_priv->dig_port_map[port];
> > -	/* intel_encoder might be NULL for DP MST */
> > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> > dev_id);
> >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> >  		err = -ENODEV;
> >  		goto unlock;
> >  	}
> > +
> >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> >  	pipe = crtc->pipe;
> >  	if (pipe == INVALID_PIPE) {
> > @@ -702,7 +742,7 @@ static int
> > i915_audio_component_sync_audio_rate(struct device *dev,  }
> > 
> >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > -					bool *enabled,
> > +					int dev_id, bool *enabled,
> >  					unsigned char *buf, int max_bytes)  {
> >  	struct drm_i915_private *dev_priv = dev_to_i915(dev); @@ -710,17
> > +750,21 @@ static int i915_audio_component_get_eld(struct device *dev, int
> > port,
> >  	const u8 *eld;
> >  	int ret = -EINVAL;
> > 
> > +
> >  	mutex_lock(&dev_priv->av_mutex);
> > -	intel_encoder = dev_priv->dig_port_map[port];
> > -	/* intel_encoder might be NULL for DP MST */
> > -	if (intel_encoder) {
> > -		ret = 0;
> > -		*enabled = intel_encoder->audio_connector != NULL;
> > -		if (*enabled) {
> > -			eld = intel_encoder->audio_connector->eld;
> > -			ret = drm_eld_size(eld);
> > -			memcpy(buf, eld, min(max_bytes, ret));
> > -		}
> > +
> > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> > dev_id);
> > +	if (!intel_encoder) {
> > +		mutex_unlock(&dev_priv->av_mutex);
> > +		return ret;
> > +	}
> > +
> > +	ret = 0;
> > +	*enabled = intel_encoder->audio_connector != NULL;
> > +	if (*enabled) {
> > +		eld = intel_encoder->audio_connector->eld;
> > +		ret = drm_eld_size(eld);
> > +		memcpy(buf, eld, min(max_bytes, ret));
> >  	}
> > 
> >  	mutex_unlock(&dev_priv->av_mutex);
> > diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> > index b46fa0e..1419c98 100644
> > --- a/include/drm/i915_component.h
> > +++ b/include/drm/i915_component.h
> > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> >  	 * Called from audio driver. After audio driver sets the
> >  	 * sample rate, it will call this function to set n/cts
> >  	 */
> > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int
> > +rate);
> >  	/**
> >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> >  	 *
> > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> >  	 * Note that the returned size may be over @max_bytes.  Then it
> >  	 * implies that only a part of ELD has been copied to the buffer.
> >  	 */
> > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > +	int (*get_eld)(struct device *, int port, int dev_id, bool *enabled,
> >  		       unsigned char *buf, int max_bytes);  };
> > 
> > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> >  	 * status accordingly (even when the HDA controller is in power save
> >  	 * mode).
> >  	 */
> > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> >  };
> > 
> >  /**
> > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h index
> > 796cabf..5ab972e 100644
> > --- a/include/sound/hda_i915.h
> > +++ b/include/sound/hda_i915.h
> > @@ -10,8 +10,9 @@
> >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);  int
> > snd_hdac_display_power(struct hdac_bus *bus, bool enable);  void
> > snd_hdac_i915_set_bclk(struct hdac_bus *bus); -int
> > snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int
> > rate); -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > +			     int dev_id, int rate);
> > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int dev_id,
> >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > int snd_hdac_i915_init(struct hdac_bus *bus);  int snd_hdac_i915_exit(struct
> > hdac_bus *bus); @@ -29,13 +30,13 @@ static inline void
> > snd_hdac_i915_set_bclk(struct hdac_bus *bus)  {  }  static inline int
> > snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > -					   hda_nid_t nid, int rate)
> > +					   hda_nid_t nid, int dev_id, int rate)
> >  {
> >  	return 0;
> >  }
> >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec,
> > hda_nid_t nid,
> > -					 bool *audio_enabled, char *buffer,
> > -					 int max_bytes)
> > +					 int dev_id, bool *audio_enabled,
> > +					 char *buffer, int max_bytes)
> >  {
> >  	return -ENODEV;
> >  }
> > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index
> > c9af022..6ea63ac 100644
> > --- a/sound/hda/hdac_i915.c
> > +++ b/sound/hda/hdac_i915.c
> > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec,
> > hda_nid_t pin_nid)
> >   * This function sets N/CTS value based on the given sample rate.
> >   * Returns zero for success, or a negative error code.
> >   */
> > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int
> > rate)
> > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > +			     int dev_id, int rate)
> >  {
> >  	struct hdac_bus *bus = codec->bus;
> >  	struct i915_audio_component *acomp = bus->audio_component; @@
> > -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > hda_nid_t nid, int rate)
> >  	port = pin2port(codec, nid);
> >  	if (port < 0)
> >  		return -EINVAL;
> > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id, rate);
> >  }
> >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > 
> > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> >   * that only a part of ELD bytes have been fetched.
> >   */
> > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > +int dev_id,
> >  			   bool *audio_enabled, char *buffer, int max_bytes)  {
> >  	struct hdac_bus *bus = codec->bus;
> > @@ -249,7 +250,7 @@ int snd_hdac_acomp_get_eld(struct hdac_device
> > *codec, hda_nid_t nid,
> >  	port = pin2port(codec, nid);
> >  	if (port < 0)
> >  		return -EINVAL;
> > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > +	return acomp->ops->get_eld(acomp->dev, port, dev_id,
> > audio_enabled,
> >  				   buffer, max_bytes);
> >  }
> >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index
> > d0d5ad8..077d48a 100644
> > --- a/sound/pci/hda/patch_hdmi.c
> > +++ b/sound/pci/hda/patch_hdmi.c
> > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct hda_codec
> > *codec,
> > 
> >  	mutex_lock(&per_pin->lock);
> >  	eld->monitor_present = false;
> > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> >  				      &eld->monitor_present, eld->eld_buffer,
> >  				      ELD_MAX_SIZE);
> >  	if (size > 0) {
> > @@ -1739,7 +1739,8 @@ static int
> > generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> >  	/* Todo: add DP1.2 MST audio support later */
> >  	if (codec_has_acomp(codec))
> > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime-
> > >rate);
> > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > +					 runtime->rate);
> > 
> >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> >  	mutex_lock(&per_pin->lock);
> > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct
> > hda_codec *codec, hda_nid_t fg,
> >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);  }
> > 
> > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > +static void intel_pin_eld_notify(void *audio_ptr, int port, int dev_id)
> >  {
> >  	struct hda_codec *codec = audio_ptr;
> >  	int pin_nid;
> > --
> > 2.5.0
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-05  5:57     ` Pandiyan, Dhinakaran
@ 2016-08-05  6:21       ` Yang, Libin
  2016-08-05  6:41         ` Pandiyan, Dhinakaran
  0 siblings, 1 reply; 24+ messages in thread
From: Yang, Libin @ 2016-08-05  6:21 UTC (permalink / raw)
  To: Pandiyan, Dhinakaran; +Cc: tiwai, intel-gfx, alsa-devel, libin.yang


> -----Original Message-----
> From: Pandiyan, Dhinakaran
> Sent: Friday, August 5, 2016 1:57 PM
> To: Yang, Libin <libin.yang@intel.com>
> Cc: intel-gfx@lists.freedesktop.org; tiwai@suse.de; alsa-devel@alsa-
> project.org; libin.yang@linux.intel.com
> Subject: Re: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> 
> On Fri, 2016-08-05 at 02:35 +0000, Yang, Libin wrote:
> > > -----Original Message-----
> > > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On
> > > Behalf Of Dhinakaran Pandiyan
> > > Sent: Wednesday, August 3, 2016 10:15 AM
> > > To: intel-gfx@lists.freedesktop.org
> > > Cc: alsa-devel@alsa-project.org; tiwai@suse.de;
> > > libin.yang@linux.intel.com; Pandiyan, Dhinakaran
> > > <dhinakaran.pandiyan@intel.com>
> > > Subject: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for
> > > MST
> > >
> > > DP MST provides the capability to send multiple video and audio
> > > streams via one single port. This requires the API's between i915
> > > and audio drivers to distinguish between audio capable displays
> > > connected to a port. This patch adds this support via an additional
> > > parameter 'int dev_id'. The existing parameter 'port' does not change it's
> meaning.
> > >
> > > dev_id =
> > > 	MST	: pipe that the stream originates from
> > > 	Non-MST	: -1
> > >
> > > Affected APIs:
> > > struct i915_audio_component_ops
> > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > +	     int rate);
> > >
> > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > -                       unsigned char *buf, int max_bytes);
> > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > >
> > > struct i915_audio_component_audio_ops
> > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int
> > > + dev_id);
> > >
> > > This patch makes dummy changes in the audio drivers for build to succeed.
> > >
> > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > >  drivers/gpu/drm/i915/intel_audio.c | 82
> > > +++++++++++++++++++++++++++++--
> > > -------
> > >  include/drm/i915_component.h       |  6 +--
> > >  include/sound/hda_i915.h           | 11 ++---
> > >  sound/hda/hdac_i915.c              |  9 +++--
> > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > > b/drivers/gpu/drm/i915/i915_drv.h index 65ada5d..8e4c8c8 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > >  	/* perform PHY state sanity checks? */
> > >  	bool chv_phy_assert[2];
> > >
> > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> >
> > We may still need save the port number info.
> > In non-MST mode, device entry means nothing. This means
> > av_enc_map[pipe] may not get the right intel_encoder
> >
> > Regards,
> > Libin
> >
> We find the encoder using port in get_saved_encoder()

It seems it still can't get the encoder for SST/HDMI as
pipe may always be -1 or 0 for SST/HDMI?

Regards,
Libin

> > >
> > >  	/*
> > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your
> > > patch diff --git a/drivers/gpu/drm/i915/intel_audio.c
> > > b/drivers/gpu/drm/i915/intel_audio.c
> > > index 8c493de..cbe44c8 100644
> > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct
> > > intel_encoder
> > > *intel_encoder)
> > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > >  	enum port port = intel_dig_port->port;
> > > +	enum pipe pipe = crtc->pipe;
> > > +	int dev_id = -1;
> > > +
> > >
> > >  	connector = drm_select_eld(encoder);
> > >  	if (!connector)
> > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct
> > > intel_encoder
> > > *intel_encoder)
> > >  		dev_priv->display.audio_codec_enable(connector,
> > > intel_encoder,
> > >  						     adjusted_mode);
> > >
> > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > +		dev_id = pipe;
> > > +
> > >  	mutex_lock(&dev_priv->av_mutex);
> > >  	intel_encoder->audio_connector = connector;
> > > +
> > >  	/* referred in audio callbacks */
> > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > >
> > >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > > >pin_eld_notify)
> > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > >audio_ptr, (int) port);
> > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > >audio_ptr,
> > > +						 (int) port, dev_id);
> > >  }
> > >
> > >  /**
> > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct
> > > intel_encoder
> > > *intel_encoder)  void intel_audio_codec_disable(struct intel_encoder
> > > *intel_encoder)  {
> > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > >  	struct drm_device *dev = encoder->dev;
> > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > >  	enum port port = intel_dig_port->port;
> > > +	enum pipe pipe = crtc->pipe;
> > > +	int dev_id = -1;
> > > +
> > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > +		dev_id = pipe;
> > >
> > >  	if (dev_priv->display.audio_codec_disable)
> > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > >
> > >  	mutex_lock(&dev_priv->av_mutex);
> > >  	intel_encoder->audio_connector = NULL;
> > > -	dev_priv->dig_port_map[port] = NULL;
> > > +	dev_priv->av_enc_map[pipe] = NULL;
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > >
> > >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > > >pin_eld_notify)
> > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > >audio_ptr, (int) port);
> > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > >audio_ptr,
> > > +						 (int) port, dev_id);
> > >  }
> > >
> > >  /**
> > > @@ -628,8 +643,32 @@ static int
> > > i915_audio_component_get_cdclk_freq(struct device *dev)
> > >  	return dev_priv->cdclk_freq;
> > >  }
> > >
> > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > -						int port, int rate)
> > > +static struct intel_encoder *get_saved_encoder(struct intel_encoder
> > > *av_enc_map[],
> > > +					       int port, int dev_id)
> > > +{
> > > +
> > > +	enum pipe pipe;
> > > +	struct drm_encoder *encoder;
> > > +
> > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > +		return av_enc_map[dev_id];
> > > +
> > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > +
> > > +		if (!av_enc_map[pipe])
> > > +			continue;
> > > +
> > > +		encoder = &av_enc_map[pipe]->base;
> > > +		if (port == enc_to_dig_port(encoder)->port)
> > > +			return av_enc_map[pipe];
> > > +	}
> > > +
> > > +	return NULL;
> > > +
> > > +}
> > > +
> > > +static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > +int
> > > port,
> > > +						int dev_id, int rate)
> > >  {
> > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > >  	struct intel_encoder *intel_encoder; @@ -649,15 +688,16 @@ static
> > > int i915_audio_component_sync_audio_rate(struct device *dev,
> > >  		return 0;
> > >
> > >  	mutex_lock(&dev_priv->av_mutex);
> > > +
> > >  	/* 1. get the pipe */
> > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > -	/* intel_encoder might be NULL for DP MST */
> > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> > > dev_id);
> > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > >  		err = -ENODEV;
> > >  		goto unlock;
> > >  	}
> > > +
> > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > >  	pipe = crtc->pipe;
> > >  	if (pipe == INVALID_PIPE) {
> > > @@ -702,7 +742,7 @@ static int
> > > i915_audio_component_sync_audio_rate(struct device *dev,  }
> > >
> > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > -					bool *enabled,
> > > +					int dev_id, bool *enabled,
> > >  					unsigned char *buf, int max_bytes)  {
> > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev); @@ -710,17
> > > +750,21 @@ static int i915_audio_component_get_eld(struct device
> > > +*dev, int
> > > port,
> > >  	const u8 *eld;
> > >  	int ret = -EINVAL;
> > >
> > > +
> > >  	mutex_lock(&dev_priv->av_mutex);
> > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > -	/* intel_encoder might be NULL for DP MST */
> > > -	if (intel_encoder) {
> > > -		ret = 0;
> > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > -		if (*enabled) {
> > > -			eld = intel_encoder->audio_connector->eld;
> > > -			ret = drm_eld_size(eld);
> > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > -		}
> > > +
> > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> > > dev_id);
> > > +	if (!intel_encoder) {
> > > +		mutex_unlock(&dev_priv->av_mutex);
> > > +		return ret;
> > > +	}
> > > +
> > > +	ret = 0;
> > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > +	if (*enabled) {
> > > +		eld = intel_encoder->audio_connector->eld;
> > > +		ret = drm_eld_size(eld);
> > > +		memcpy(buf, eld, min(max_bytes, ret));
> > >  	}
> > >
> > >  	mutex_unlock(&dev_priv->av_mutex);
> > > diff --git a/include/drm/i915_component.h
> > > b/include/drm/i915_component.h index b46fa0e..1419c98 100644
> > > --- a/include/drm/i915_component.h
> > > +++ b/include/drm/i915_component.h
> > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > >  	 * Called from audio driver. After audio driver sets the
> > >  	 * sample rate, it will call this function to set n/cts
> > >  	 */
> > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int
> > > +rate);
> > >  	/**
> > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > >  	 *
> > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > >  	 * implies that only a part of ELD has been copied to the buffer.
> > >  	 */
> > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > +	int (*get_eld)(struct device *, int port, int dev_id, bool
> > > +*enabled,
> > >  		       unsigned char *buf, int max_bytes);  };
> > >
> > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > >  	 * status accordingly (even when the HDA controller is in power save
> > >  	 * mode).
> > >  	 */
> > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > >  };
> > >
> > >  /**
> > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > index 796cabf..5ab972e 100644
> > > --- a/include/sound/hda_i915.h
> > > +++ b/include/sound/hda_i915.h
> > > @@ -10,8 +10,9 @@
> > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> > > int snd_hdac_display_power(struct hdac_bus *bus, bool enable);  void
> > > snd_hdac_i915_set_bclk(struct hdac_bus *bus); -int
> > > snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > int rate); -int snd_hdac_acomp_get_eld(struct hdac_device *codec,
> > > hda_nid_t nid,
> > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > +			     int dev_id, int rate);
> > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > +nid, int dev_id,
> > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> int
> > > snd_hdac_i915_init(struct hdac_bus *bus);  int
> > > snd_hdac_i915_exit(struct hdac_bus *bus); @@ -29,13 +30,13 @@ static
> > > inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)  {  }
> > > static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > -					   hda_nid_t nid, int rate)
> > > +					   hda_nid_t nid, int dev_id, int rate)
> > >  {
> > >  	return 0;
> > >  }
> > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec,
> > > hda_nid_t nid,
> > > -					 bool *audio_enabled, char *buffer,
> > > -					 int max_bytes)
> > > +					 int dev_id, bool *audio_enabled,
> > > +					 char *buffer, int max_bytes)
> > >  {
> > >  	return -ENODEV;
> > >  }
> > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index
> > > c9af022..6ea63ac 100644
> > > --- a/sound/hda/hdac_i915.c
> > > +++ b/sound/hda/hdac_i915.c
> > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec,
> > > hda_nid_t pin_nid)
> > >   * This function sets N/CTS value based on the given sample rate.
> > >   * Returns zero for success, or a negative error code.
> > >   */
> > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t
> > > nid, int
> > > rate)
> > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > +			     int dev_id, int rate)
> > >  {
> > >  	struct hdac_bus *bus = codec->bus;
> > >  	struct i915_audio_component *acomp = bus->audio_component; @@
> > > -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device
> > > *codec, hda_nid_t nid, int rate)
> > >  	port = pin2port(codec, nid);
> > >  	if (port < 0)
> > >  		return -EINVAL;
> > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id,
> > > +rate);
> > >  }
> > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > >
> > > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > >   * that only a part of ELD bytes have been fetched.
> > >   */
> > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > nid,
> > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > +nid, int dev_id,
> > >  			   bool *audio_enabled, char *buffer, int max_bytes)  {
> > >  	struct hdac_bus *bus = codec->bus; @@ -249,7 +250,7 @@ int
> > > snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > >  	port = pin2port(codec, nid);
> > >  	if (port < 0)
> > >  		return -EINVAL;
> > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id,
> > > audio_enabled,
> > >  				   buffer, max_bytes);
> > >  }
> > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > > index d0d5ad8..077d48a 100644
> > > --- a/sound/pci/hda/patch_hdmi.c
> > > +++ b/sound/pci/hda/patch_hdmi.c
> > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct
> > > hda_codec *codec,
> > >
> > >  	mutex_lock(&per_pin->lock);
> > >  	eld->monitor_present = false;
> > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> > >  				      &eld->monitor_present, eld->eld_buffer,
> > >  				      ELD_MAX_SIZE);
> > >  	if (size > 0) {
> > > @@ -1739,7 +1739,8 @@ static int
> > > generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > >  	/* Todo: add DP1.2 MST audio support later */
> > >  	if (codec_has_acomp(codec))
> > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime-
> > > >rate);
> > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > +					 runtime->rate);
> > >
> > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > >  	mutex_lock(&per_pin->lock);
> > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct
> > > hda_codec *codec, hda_nid_t fg,
> > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);  }
> > >
> > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int
> > > +dev_id)
> > >  {
> > >  	struct hda_codec *codec = audio_ptr;
> > >  	int pin_nid;
> > > --
> > > 2.5.0
> > >
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-05  6:21       ` Yang, Libin
@ 2016-08-05  6:41         ` Pandiyan, Dhinakaran
  2016-08-05  6:43           ` Yang, Libin
  0 siblings, 1 reply; 24+ messages in thread
From: Pandiyan, Dhinakaran @ 2016-08-05  6:41 UTC (permalink / raw)
  To: Yang, Libin; +Cc: tiwai, intel-gfx, alsa-devel, libin.yang

On Fri, 2016-08-05 at 06:21 +0000, Yang, Libin wrote:
> > -----Original Message-----
> > From: Pandiyan, Dhinakaran
> > Sent: Friday, August 5, 2016 1:57 PM
> > To: Yang, Libin <libin.yang@intel.com>
> > Cc: intel-gfx@lists.freedesktop.org; tiwai@suse.de; alsa-devel@alsa-
> > project.org; libin.yang@linux.intel.com
> > Subject: Re: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> > 
> > On Fri, 2016-08-05 at 02:35 +0000, Yang, Libin wrote:
> > > > -----Original Message-----
> > > > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On
> > > > Behalf Of Dhinakaran Pandiyan
> > > > Sent: Wednesday, August 3, 2016 10:15 AM
> > > > To: intel-gfx@lists.freedesktop.org
> > > > Cc: alsa-devel@alsa-project.org; tiwai@suse.de;
> > > > libin.yang@linux.intel.com; Pandiyan, Dhinakaran
> > > > <dhinakaran.pandiyan@intel.com>
> > > > Subject: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for
> > > > MST
> > > >
> > > > DP MST provides the capability to send multiple video and audio
> > > > streams via one single port. This requires the API's between i915
> > > > and audio drivers to distinguish between audio capable displays
> > > > connected to a port. This patch adds this support via an additional
> > > > parameter 'int dev_id'. The existing parameter 'port' does not change it's
> > meaning.
> > > >
> > > > dev_id =
> > > > 	MST	: pipe that the stream originates from
> > > > 	Non-MST	: -1
> > > >
> > > > Affected APIs:
> > > > struct i915_audio_component_ops
> > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > > +	     int rate);
> > > >
> > > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > > -                       unsigned char *buf, int max_bytes);
> > > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > > >
> > > > struct i915_audio_component_audio_ops
> > > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int
> > > > + dev_id);
> > > >
> > > > This patch makes dummy changes in the audio drivers for build to succeed.
> > > >
> > > > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > > >  drivers/gpu/drm/i915/intel_audio.c | 82
> > > > +++++++++++++++++++++++++++++--
> > > > -------
> > > >  include/drm/i915_component.h       |  6 +--
> > > >  include/sound/hda_i915.h           | 11 ++---
> > > >  sound/hda/hdac_i915.c              |  9 +++--
> > > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > > > b/drivers/gpu/drm/i915/i915_drv.h index 65ada5d..8e4c8c8 100644
> > > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > > >  	/* perform PHY state sanity checks? */
> > > >  	bool chv_phy_assert[2];
> > > >
> > > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> > >
> > > We may still need save the port number info.
> > > In non-MST mode, device entry means nothing. This means
> > > av_enc_map[pipe] may not get the right intel_encoder
> > >
> > > Regards,
> > > Libin
> > >
> > We find the encoder using port in get_saved_encoder()
> 
> It seems it still can't get the encoder for SST/HDMI as
> pipe may always be -1 or 0 for SST/HDMI?
> 
> Regards,
> Libin
> 

The audio driver sends dev_id=-1, but the correct "port" for SST. So, we
loop through all the saved encoders and choose the one that is tied to
"port"

for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {

		if (!av_enc_map[pipe])
			continue;

		encoder = &av_enc_map[pipe]->base;
		if (port == enc_to_dig_port(encoder)->port)
			return av_enc_map[pipe];
	}



> > > >
> > > >  	/*
> > > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your
> > > > patch diff --git a/drivers/gpu/drm/i915/intel_audio.c
> > > > b/drivers/gpu/drm/i915/intel_audio.c
> > > > index 8c493de..cbe44c8 100644
> > > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct
> > > > intel_encoder
> > > > *intel_encoder)
> > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > >  	enum port port = intel_dig_port->port;
> > > > +	enum pipe pipe = crtc->pipe;
> > > > +	int dev_id = -1;
> > > > +
> > > >
> > > >  	connector = drm_select_eld(encoder);
> > > >  	if (!connector)
> > > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct
> > > > intel_encoder
> > > > *intel_encoder)
> > > >  		dev_priv->display.audio_codec_enable(connector,
> > > > intel_encoder,
> > > >  						     adjusted_mode);
> > > >
> > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > +		dev_id = pipe;
> > > > +
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > >  	intel_encoder->audio_connector = connector;
> > > > +
> > > >  	/* referred in audio callbacks */
> > > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > >
> > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > > > >pin_eld_notify)
> > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > > >audio_ptr, (int) port);
> > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > > >audio_ptr,
> > > > +						 (int) port, dev_id);
> > > >  }
> > > >
> > > >  /**
> > > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct
> > > > intel_encoder
> > > > *intel_encoder)  void intel_audio_codec_disable(struct intel_encoder
> > > > *intel_encoder)  {
> > > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > > >  	struct drm_device *dev = encoder->dev;
> > > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > >  	enum port port = intel_dig_port->port;
> > > > +	enum pipe pipe = crtc->pipe;
> > > > +	int dev_id = -1;
> > > > +
> > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > +		dev_id = pipe;
> > > >
> > > >  	if (dev_priv->display.audio_codec_disable)
> > > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > > >
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > >  	intel_encoder->audio_connector = NULL;
> > > > -	dev_priv->dig_port_map[port] = NULL;
> > > > +	dev_priv->av_enc_map[pipe] = NULL;
> > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > >
> > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > > > >pin_eld_notify)
> > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > > >audio_ptr, (int) port);
> > > > +		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > > >audio_ptr,
> > > > +						 (int) port, dev_id);
> > > >  }
> > > >
> > > >  /**
> > > > @@ -628,8 +643,32 @@ static int
> > > > i915_audio_component_get_cdclk_freq(struct device *dev)
> > > >  	return dev_priv->cdclk_freq;
> > > >  }
> > > >
> > > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > -						int port, int rate)
> > > > +static struct intel_encoder *get_saved_encoder(struct intel_encoder
> > > > *av_enc_map[],
> > > > +					       int port, int dev_id)
> > > > +{
> > > > +
> > > > +	enum pipe pipe;
> > > > +	struct drm_encoder *encoder;
> > > > +
> > > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > > +		return av_enc_map[dev_id];
> > > > +
> > > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > > +
> > > > +		if (!av_enc_map[pipe])
> > > > +			continue;
> > > > +
> > > > +		encoder = &av_enc_map[pipe]->base;
> > > > +		if (port == enc_to_dig_port(encoder)->port)
> > > > +			return av_enc_map[pipe];
> > > > +	}
> > > > +
> > > > +	return NULL;
> > > > +
> > > > +}
> > > > +
> > > > +static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > +int
> > > > port,
> > > > +						int dev_id, int rate)
> > > >  {
> > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > >  	struct intel_encoder *intel_encoder; @@ -649,15 +688,16 @@ static
> > > > int i915_audio_component_sync_audio_rate(struct device *dev,
> > > >  		return 0;
> > > >
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > +
> > > >  	/* 1. get the pipe */
> > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > -	/* intel_encoder might be NULL for DP MST */
> > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> > > > dev_id);
> > > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > > >  		err = -ENODEV;
> > > >  		goto unlock;
> > > >  	}
> > > > +
> > > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > > >  	pipe = crtc->pipe;
> > > >  	if (pipe == INVALID_PIPE) {
> > > > @@ -702,7 +742,7 @@ static int
> > > > i915_audio_component_sync_audio_rate(struct device *dev,  }
> > > >
> > > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > > -					bool *enabled,
> > > > +					int dev_id, bool *enabled,
> > > >  					unsigned char *buf, int max_bytes)  {
> > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev); @@ -710,17
> > > > +750,21 @@ static int i915_audio_component_get_eld(struct device
> > > > +*dev, int
> > > > port,
> > > >  	const u8 *eld;
> > > >  	int ret = -EINVAL;
> > > >
> > > > +
> > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > -	/* intel_encoder might be NULL for DP MST */
> > > > -	if (intel_encoder) {
> > > > -		ret = 0;
> > > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > > -		if (*enabled) {
> > > > -			eld = intel_encoder->audio_connector->eld;
> > > > -			ret = drm_eld_size(eld);
> > > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > > -		}
> > > > +
> > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map, port,
> > > > dev_id);
> > > > +	if (!intel_encoder) {
> > > > +		mutex_unlock(&dev_priv->av_mutex);
> > > > +		return ret;
> > > > +	}
> > > > +
> > > > +	ret = 0;
> > > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > > +	if (*enabled) {
> > > > +		eld = intel_encoder->audio_connector->eld;
> > > > +		ret = drm_eld_size(eld);
> > > > +		memcpy(buf, eld, min(max_bytes, ret));
> > > >  	}
> > > >
> > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > diff --git a/include/drm/i915_component.h
> > > > b/include/drm/i915_component.h index b46fa0e..1419c98 100644
> > > > --- a/include/drm/i915_component.h
> > > > +++ b/include/drm/i915_component.h
> > > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > > >  	 * Called from audio driver. After audio driver sets the
> > > >  	 * sample rate, it will call this function to set n/cts
> > > >  	 */
> > > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id, int
> > > > +rate);
> > > >  	/**
> > > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > > >  	 *
> > > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > > >  	 * implies that only a part of ELD has been copied to the buffer.
> > > >  	 */
> > > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > > +	int (*get_eld)(struct device *, int port, int dev_id, bool
> > > > +*enabled,
> > > >  		       unsigned char *buf, int max_bytes);  };
> > > >
> > > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > > >  	 * status accordingly (even when the HDA controller is in power save
> > > >  	 * mode).
> > > >  	 */
> > > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > >  };
> > > >
> > > >  /**
> > > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > > index 796cabf..5ab972e 100644
> > > > --- a/include/sound/hda_i915.h
> > > > +++ b/include/sound/hda_i915.h
> > > > @@ -10,8 +10,9 @@
> > > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
> > > > int snd_hdac_display_power(struct hdac_bus *bus, bool enable);  void
> > > > snd_hdac_i915_set_bclk(struct hdac_bus *bus); -int
> > > > snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > int rate); -int snd_hdac_acomp_get_eld(struct hdac_device *codec,
> > > > hda_nid_t nid,
> > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > +			     int dev_id, int rate);
> > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > > +nid, int dev_id,
> > > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > int
> > > > snd_hdac_i915_init(struct hdac_bus *bus);  int
> > > > snd_hdac_i915_exit(struct hdac_bus *bus); @@ -29,13 +30,13 @@ static
> > > > inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)  {  }
> > > > static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > > -					   hda_nid_t nid, int rate)
> > > > +					   hda_nid_t nid, int dev_id, int rate)
> > > >  {
> > > >  	return 0;
> > > >  }
> > > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec,
> > > > hda_nid_t nid,
> > > > -					 bool *audio_enabled, char *buffer,
> > > > -					 int max_bytes)
> > > > +					 int dev_id, bool *audio_enabled,
> > > > +					 char *buffer, int max_bytes)
> > > >  {
> > > >  	return -ENODEV;
> > > >  }
> > > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index
> > > > c9af022..6ea63ac 100644
> > > > --- a/sound/hda/hdac_i915.c
> > > > +++ b/sound/hda/hdac_i915.c
> > > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device *codec,
> > > > hda_nid_t pin_nid)
> > > >   * This function sets N/CTS value based on the given sample rate.
> > > >   * Returns zero for success, or a negative error code.
> > > >   */
> > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t
> > > > nid, int
> > > > rate)
> > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid,
> > > > +			     int dev_id, int rate)
> > > >  {
> > > >  	struct hdac_bus *bus = codec->bus;
> > > >  	struct i915_audio_component *acomp = bus->audio_component; @@
> > > > -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device
> > > > *codec, hda_nid_t nid, int rate)
> > > >  	port = pin2port(codec, nid);
> > > >  	if (port < 0)
> > > >  		return -EINVAL;
> > > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > > +	return acomp->ops->sync_audio_rate(acomp->dev, port, dev_id,
> > > > +rate);
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > >
> > > > @@ -236,7 +237,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > > >   * that only a part of ELD bytes have been fetched.
> > > >   */
> > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > > nid,
> > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > > +nid, int dev_id,
> > > >  			   bool *audio_enabled, char *buffer, int max_bytes)  {
> > > >  	struct hdac_bus *bus = codec->bus; @@ -249,7 +250,7 @@ int
> > > > snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > >  	port = pin2port(codec, nid);
> > > >  	if (port < 0)
> > > >  		return -EINVAL;
> > > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id,
> > > > audio_enabled,
> > > >  				   buffer, max_bytes);
> > > >  }
> > > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > > > index d0d5ad8..077d48a 100644
> > > > --- a/sound/pci/hda/patch_hdmi.c
> > > > +++ b/sound/pci/hda/patch_hdmi.c
> > > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct
> > > > hda_codec *codec,
> > > >
> > > >  	mutex_lock(&per_pin->lock);
> > > >  	eld->monitor_present = false;
> > > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid, -1,
> > > >  				      &eld->monitor_present, eld->eld_buffer,
> > > >  				      ELD_MAX_SIZE);
> > > >  	if (size > 0) {
> > > > @@ -1739,7 +1739,8 @@ static int
> > > > generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > > >  	/* Todo: add DP1.2 MST audio support later */
> > > >  	if (codec_has_acomp(codec))
> > > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime-
> > > > >rate);
> > > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > > +					 runtime->rate);
> > > >
> > > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > > >  	mutex_lock(&per_pin->lock);
> > > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct
> > > > hda_codec *codec, hda_nid_t fg,
> > > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);  }
> > > >
> > > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int
> > > > +dev_id)
> > > >  {
> > > >  	struct hda_codec *codec = audio_ptr;
> > > >  	int pin_nid;
> > > > --
> > > > 2.5.0
> > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-05  6:41         ` Pandiyan, Dhinakaran
@ 2016-08-05  6:43           ` Yang, Libin
  0 siblings, 0 replies; 24+ messages in thread
From: Yang, Libin @ 2016-08-05  6:43 UTC (permalink / raw)
  To: Pandiyan, Dhinakaran; +Cc: tiwai, intel-gfx, alsa-devel, libin.yang



> -----Original Message-----
> From: Pandiyan, Dhinakaran
> Sent: Friday, August 5, 2016 2:42 PM
> To: Yang, Libin <libin.yang@intel.com>
> Cc: intel-gfx@lists.freedesktop.org; tiwai@suse.de; alsa-devel@alsa-
> project.org; libin.yang@linux.intel.com
> Subject: Re: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> 
> On Fri, 2016-08-05 at 06:21 +0000, Yang, Libin wrote:
> > > -----Original Message-----
> > > From: Pandiyan, Dhinakaran
> > > Sent: Friday, August 5, 2016 1:57 PM
> > > To: Yang, Libin <libin.yang@intel.com>
> > > Cc: intel-gfx@lists.freedesktop.org; tiwai@suse.de; alsa-devel@alsa-
> > > project.org; libin.yang@linux.intel.com
> > > Subject: Re: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes
> > > for MST
> > >
> > > On Fri, 2016-08-05 at 02:35 +0000, Yang, Libin wrote:
> > > > > -----Original Message-----
> > > > > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org]
> > > > > On Behalf Of Dhinakaran Pandiyan
> > > > > Sent: Wednesday, August 3, 2016 10:15 AM
> > > > > To: intel-gfx@lists.freedesktop.org
> > > > > Cc: alsa-devel@alsa-project.org; tiwai@suse.de;
> > > > > libin.yang@linux.intel.com; Pandiyan, Dhinakaran
> > > > > <dhinakaran.pandiyan@intel.com>
> > > > > Subject: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes
> > > > > for MST
> > > > >
> > > > > DP MST provides the capability to send multiple video and audio
> > > > > streams via one single port. This requires the API's between
> > > > > i915 and audio drivers to distinguish between audio capable
> > > > > displays connected to a port. This patch adds this support via
> > > > > an additional parameter 'int dev_id'. The existing parameter
> > > > > 'port' does not change it's
> > > meaning.
> > > > >
> > > > > dev_id =
> > > > > 	MST	: pipe that the stream originates from
> > > > > 	Non-MST	: -1
> > > > >
> > > > > Affected APIs:
> > > > > struct i915_audio_component_ops
> > > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > > > +	     int rate);
> > > > >
> > > > > -       int (*get_eld)(struct device *, int port, bool *enabled,
> > > > > -                       unsigned char *buf, int max_bytes);
> > > > > +       int (*get_eld)(struct device *, int port, int dev_id,
> > > > > +		       bool *enabled, unsigned char *buf, int max_bytes);
> > > > >
> > > > > struct i915_audio_component_audio_ops
> > > > > -       void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > > +       void (*pin_eld_notify)(void *audio_ptr, int port, int
> > > > > + dev_id);
> > > > >
> > > > > This patch makes dummy changes in the audio drivers for build to
> succeed.
> > > > >
> > > > > Signed-off-by: Dhinakaran Pandiyan
> > > > > <dhinakaran.pandiyan@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/i915_drv.h    |  2 +-
> > > > >  drivers/gpu/drm/i915/intel_audio.c | 82
> > > > > +++++++++++++++++++++++++++++--
> > > > > -------
> > > > >  include/drm/i915_component.h       |  6 +--
> > > > >  include/sound/hda_i915.h           | 11 ++---
> > > > >  sound/hda/hdac_i915.c              |  9 +++--
> > > > >  sound/pci/hda/patch_hdmi.c         |  7 ++--
> > > > >  6 files changed, 82 insertions(+), 35 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > > > > b/drivers/gpu/drm/i915/i915_drv.h index 65ada5d..8e4c8c8 100644
> > > > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > > > @@ -2054,7 +2054,7 @@ struct drm_i915_private {
> > > > >  	/* perform PHY state sanity checks? */
> > > > >  	bool chv_phy_assert[2];
> > > > >
> > > > > -	struct intel_encoder *dig_port_map[I915_MAX_PORTS];
> > > > > +	struct intel_encoder *av_enc_map[I915_MAX_PIPES];
> > > >
> > > > We may still need save the port number info.
> > > > In non-MST mode, device entry means nothing. This means
> > > > av_enc_map[pipe] may not get the right intel_encoder
> > > >
> > > > Regards,
> > > > Libin
> > > >
> > > We find the encoder using port in get_saved_encoder()
> >
> > It seems it still can't get the encoder for SST/HDMI as pipe may
> > always be -1 or 0 for SST/HDMI?
> >
> > Regards,
> > Libin
> >
> 
> The audio driver sends dev_id=-1, but the correct "port" for SST. So, we loop
> through all the saved encoders and choose the one that is tied to "port"
> 
> for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> 
> 		if (!av_enc_map[pipe])
> 			continue;
> 
> 		encoder = &av_enc_map[pipe]->base;
> 		if (port == enc_to_dig_port(encoder)->port)
> 			return av_enc_map[pipe];
> 	}

Get your mean. Thanks.

> 
> 
> 
> > > > >
> > > > >  	/*
> > > > >  	 * NOTE: This is the dri1/ums dungeon, don't add stuff here.
> > > > > Your patch diff --git a/drivers/gpu/drm/i915/intel_audio.c
> > > > > b/drivers/gpu/drm/i915/intel_audio.c
> > > > > index 8c493de..cbe44c8 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_audio.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_audio.c
> > > > > @@ -500,6 +500,9 @@ void intel_audio_codec_enable(struct
> > > > > intel_encoder
> > > > > *intel_encoder)
> > > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > > >  	enum port port = intel_dig_port->port;
> > > > > +	enum pipe pipe = crtc->pipe;
> > > > > +	int dev_id = -1;
> > > > > +
> > > > >
> > > > >  	connector = drm_select_eld(encoder);
> > > > >  	if (!connector)
> > > > > @@ -522,14 +525,19 @@ void intel_audio_codec_enable(struct
> > > > > intel_encoder
> > > > > *intel_encoder)
> > > > >  		dev_priv->display.audio_codec_enable(connector,
> > > > > intel_encoder,
> > > > >  						     adjusted_mode);
> > > > >
> > > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > > +		dev_id = pipe;
> > > > > +
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > >  	intel_encoder->audio_connector = connector;
> > > > > +
> > > > >  	/* referred in audio callbacks */
> > > > > -	dev_priv->dig_port_map[port] = intel_encoder;
> > > > > +	dev_priv->av_enc_map[pipe] = intel_encoder;
> > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > >
> > > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > > > > >pin_eld_notify)
> > > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > > > >audio_ptr, (int) port);
> > > > > +		acomp->audio_ops->pin_eld_notify(acomp-
> >audio_ops-
> > > > > >audio_ptr,
> > > > > +						 (int) port, dev_id);
> > > > >  }
> > > > >
> > > > >  /**
> > > > > @@ -542,22 +550,29 @@ void intel_audio_codec_enable(struct
> > > > > intel_encoder
> > > > > *intel_encoder)  void intel_audio_codec_disable(struct
> > > > > intel_encoder
> > > > > *intel_encoder)  {
> > > > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > > > > +	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
> > > > >  	struct drm_device *dev = encoder->dev;
> > > > >  	struct drm_i915_private *dev_priv = to_i915(dev);
> > > > >  	struct i915_audio_component *acomp = dev_priv->audio_component;
> > > > >  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
> > > > >  	enum port port = intel_dig_port->port;
> > > > > +	enum pipe pipe = crtc->pipe;
> > > > > +	int dev_id = -1;
> > > > > +
> > > > > +	if (intel_encoder->type == INTEL_OUTPUT_DP_MST)
> > > > > +		dev_id = pipe;
> > > > >
> > > > >  	if (dev_priv->display.audio_codec_disable)
> > > > >  		dev_priv->display.audio_codec_disable(intel_encoder);
> > > > >
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > >  	intel_encoder->audio_connector = NULL;
> > > > > -	dev_priv->dig_port_map[port] = NULL;
> > > > > +	dev_priv->av_enc_map[pipe] = NULL;
> > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > >
> > > > >  	if (acomp && acomp->audio_ops && acomp->audio_ops-
> > > > > >pin_eld_notify)
> > > > > -		acomp->audio_ops->pin_eld_notify(acomp->audio_ops-
> > > > > >audio_ptr, (int) port);
> > > > > +		acomp->audio_ops->pin_eld_notify(acomp-
> >audio_ops-
> > > > > >audio_ptr,
> > > > > +						 (int) port, dev_id);
> > > > >  }
> > > > >
> > > > >  /**
> > > > > @@ -628,8 +643,32 @@ static int
> > > > > i915_audio_component_get_cdclk_freq(struct device *dev)
> > > > >  	return dev_priv->cdclk_freq;
> > > > >  }
> > > > >
> > > > > -static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > > -						int port, int rate)
> > > > > +static struct intel_encoder *get_saved_encoder(struct
> > > > > +intel_encoder
> > > > > *av_enc_map[],
> > > > > +					       int port, int dev_id) {
> > > > > +
> > > > > +	enum pipe pipe;
> > > > > +	struct drm_encoder *encoder;
> > > > > +
> > > > > +	if (dev_id >= 0 && dev_id < I915_MAX_PIPES)
> > > > > +		return av_enc_map[dev_id];
> > > > > +
> > > > > +	for (pipe = PIPE_A; pipe < I915_MAX_PIPES; pipe++) {
> > > > > +
> > > > > +		if (!av_enc_map[pipe])
> > > > > +			continue;
> > > > > +
> > > > > +		encoder = &av_enc_map[pipe]->base;
> > > > > +		if (port == enc_to_dig_port(encoder)->port)
> > > > > +			return av_enc_map[pipe];
> > > > > +	}
> > > > > +
> > > > > +	return NULL;
> > > > > +
> > > > > +}
> > > > > +
> > > > > +static int i915_audio_component_sync_audio_rate(struct device
> > > > > +*dev, int
> > > > > port,
> > > > > +						int dev_id, int rate)
> > > > >  {
> > > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev);
> > > > >  	struct intel_encoder *intel_encoder; @@ -649,15 +688,16 @@
> > > > > static int i915_audio_component_sync_audio_rate(struct device *dev,
> > > > >  		return 0;
> > > > >
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > +
> > > > >  	/* 1. get the pipe */
> > > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > > -	/* intel_encoder might be NULL for DP MST */
> > > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map,
> port,
> > > > > dev_id);
> > > > >  	if (!intel_encoder || !intel_encoder->base.crtc ||
> > > > >  	    intel_encoder->type != INTEL_OUTPUT_HDMI) {
> > > > >  		DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
> > > > >  		err = -ENODEV;
> > > > >  		goto unlock;
> > > > >  	}
> > > > > +
> > > > >  	crtc = to_intel_crtc(intel_encoder->base.crtc);
> > > > >  	pipe = crtc->pipe;
> > > > >  	if (pipe == INVALID_PIPE) {
> > > > > @@ -702,7 +742,7 @@ static int
> > > > > i915_audio_component_sync_audio_rate(struct device *dev,  }
> > > > >
> > > > >  static int i915_audio_component_get_eld(struct device *dev, int port,
> > > > > -					bool *enabled,
> > > > > +					int dev_id, bool *enabled,
> > > > >  					unsigned char *buf, int max_bytes)  {
> > > > >  	struct drm_i915_private *dev_priv = dev_to_i915(dev); @@
> > > > > -710,17
> > > > > +750,21 @@ static int i915_audio_component_get_eld(struct device
> > > > > +*dev, int
> > > > > port,
> > > > >  	const u8 *eld;
> > > > >  	int ret = -EINVAL;
> > > > >
> > > > > +
> > > > >  	mutex_lock(&dev_priv->av_mutex);
> > > > > -	intel_encoder = dev_priv->dig_port_map[port];
> > > > > -	/* intel_encoder might be NULL for DP MST */
> > > > > -	if (intel_encoder) {
> > > > > -		ret = 0;
> > > > > -		*enabled = intel_encoder->audio_connector != NULL;
> > > > > -		if (*enabled) {
> > > > > -			eld = intel_encoder->audio_connector->eld;
> > > > > -			ret = drm_eld_size(eld);
> > > > > -			memcpy(buf, eld, min(max_bytes, ret));
> > > > > -		}
> > > > > +
> > > > > +	intel_encoder = get_saved_encoder(dev_priv->av_enc_map,
> port,
> > > > > dev_id);
> > > > > +	if (!intel_encoder) {
> > > > > +		mutex_unlock(&dev_priv->av_mutex);
> > > > > +		return ret;
> > > > > +	}
> > > > > +
> > > > > +	ret = 0;
> > > > > +	*enabled = intel_encoder->audio_connector != NULL;
> > > > > +	if (*enabled) {
> > > > > +		eld = intel_encoder->audio_connector->eld;
> > > > > +		ret = drm_eld_size(eld);
> > > > > +		memcpy(buf, eld, min(max_bytes, ret));
> > > > >  	}
> > > > >
> > > > >  	mutex_unlock(&dev_priv->av_mutex);
> > > > > diff --git a/include/drm/i915_component.h
> > > > > b/include/drm/i915_component.h index b46fa0e..1419c98 100644
> > > > > --- a/include/drm/i915_component.h
> > > > > +++ b/include/drm/i915_component.h
> > > > > @@ -64,7 +64,7 @@ struct i915_audio_component_ops {
> > > > >  	 * Called from audio driver. After audio driver sets the
> > > > >  	 * sample rate, it will call this function to set n/cts
> > > > >  	 */
> > > > > -	int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > +	int (*sync_audio_rate)(struct device *, int port, int dev_id,
> > > > > +int rate);
> > > > >  	/**
> > > > >  	 * @get_eld: fill the audio state and ELD bytes for the given port
> > > > >  	 *
> > > > > @@ -77,7 +77,7 @@ struct i915_audio_component_ops {
> > > > >  	 * Note that the returned size may be over @max_bytes.  Then it
> > > > >  	 * implies that only a part of ELD has been copied to the buffer.
> > > > >  	 */
> > > > > -	int (*get_eld)(struct device *, int port, bool *enabled,
> > > > > +	int (*get_eld)(struct device *, int port, int dev_id, bool
> > > > > +*enabled,
> > > > >  		       unsigned char *buf, int max_bytes);  };
> > > > >
> > > > > @@ -97,7 +97,7 @@ struct i915_audio_component_audio_ops {
> > > > >  	 * status accordingly (even when the HDA controller is in power save
> > > > >  	 * mode).
> > > > >  	 */
> > > > > -	void (*pin_eld_notify)(void *audio_ptr, int port);
> > > > > +	void (*pin_eld_notify)(void *audio_ptr, int port, int dev_id);
> > > > >  };
> > > > >
> > > > >  /**
> > > > > diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
> > > > > index 796cabf..5ab972e 100644
> > > > > --- a/include/sound/hda_i915.h
> > > > > +++ b/include/sound/hda_i915.h
> > > > > @@ -10,8 +10,9 @@
> > > > >  int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool
> > > > > enable); int snd_hdac_display_power(struct hdac_bus *bus, bool
> > > > > enable);  void snd_hdac_i915_set_bclk(struct hdac_bus *bus);
> > > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > > > hda_nid_t nid, int rate); -int snd_hdac_acomp_get_eld(struct
> > > > > hdac_device *codec, hda_nid_t nid,
> > > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t
> nid,
> > > > > +			     int dev_id, int rate);
> > > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > > > +nid, int dev_id,
> > > > >  			   bool *audio_enabled, char *buffer, int max_bytes);
> > > int
> > > > > snd_hdac_i915_init(struct hdac_bus *bus);  int
> > > > > snd_hdac_i915_exit(struct hdac_bus *bus); @@ -29,13 +30,13 @@
> > > > > static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
> > > > > {  } static inline int snd_hdac_sync_audio_rate(struct hdac_device
> *codec,
> > > > > -					   hda_nid_t nid, int rate)
> > > > > +					   hda_nid_t nid, int dev_id,
> int rate)
> > > > >  {
> > > > >  	return 0;
> > > > >  }
> > > > >  static inline int snd_hdac_acomp_get_eld(struct hdac_device
> > > > > *codec, hda_nid_t nid,
> > > > > -					 bool *audio_enabled, char *buffer,
> > > > > -					 int max_bytes)
> > > > > +					 int dev_id, bool
> *audio_enabled,
> > > > > +					 char *buffer, int max_bytes)
> > > > >  {
> > > > >  	return -ENODEV;
> > > > >  }
> > > > > diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index
> > > > > c9af022..6ea63ac 100644
> > > > > --- a/sound/hda/hdac_i915.c
> > > > > +++ b/sound/hda/hdac_i915.c
> > > > > @@ -201,7 +201,8 @@ static int pin2port(struct hdac_device
> > > > > *codec, hda_nid_t pin_nid)
> > > > >   * This function sets N/CTS value based on the given sample rate.
> > > > >   * Returns zero for success, or a negative error code.
> > > > >   */
> > > > > -int snd_hdac_sync_audio_rate(struct hdac_device *codec,
> > > > > hda_nid_t nid, int
> > > > > rate)
> > > > > +int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t
> nid,
> > > > > +			     int dev_id, int rate)
> > > > >  {
> > > > >  	struct hdac_bus *bus = codec->bus;
> > > > >  	struct i915_audio_component *acomp = bus->audio_component; @@
> > > > > -212,7 +213,7 @@ int snd_hdac_sync_audio_rate(struct hdac_device
> > > > > *codec, hda_nid_t nid, int rate)
> > > > >  	port = pin2port(codec, nid);
> > > > >  	if (port < 0)
> > > > >  		return -EINVAL;
> > > > > -	return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
> > > > > +	return acomp->ops->sync_audio_rate(acomp->dev, port,
> dev_id,
> > > > > +rate);
> > > > >  }
> > > > >  EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > > >
> > > > > @@ -236,7 +237,7 @@
> EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
> > > > >   * thus it may be over @max_bytes.  If it's over @max_bytes, it implies
> > > > >   * that only a part of ELD bytes have been fetched.
> > > > >   */
> > > > > -int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > > > nid,
> > > > > +int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t
> > > > > +nid, int dev_id,
> > > > >  			   bool *audio_enabled, char *buffer, int max_bytes)  {
> > > > >  	struct hdac_bus *bus = codec->bus; @@ -249,7 +250,7 @@ int
> > > > > snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid,
> > > > >  	port = pin2port(codec, nid);
> > > > >  	if (port < 0)
> > > > >  		return -EINVAL;
> > > > > -	return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
> > > > > +	return acomp->ops->get_eld(acomp->dev, port, dev_id,
> > > > > audio_enabled,
> > > > >  				   buffer, max_bytes);
> > > > >  }
> > > > >  EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
> > > > > diff --git a/sound/pci/hda/patch_hdmi.c
> > > > > b/sound/pci/hda/patch_hdmi.c index d0d5ad8..077d48a 100644
> > > > > --- a/sound/pci/hda/patch_hdmi.c
> > > > > +++ b/sound/pci/hda/patch_hdmi.c
> > > > > @@ -1485,7 +1485,7 @@ static void sync_eld_via_acomp(struct
> > > > > hda_codec *codec,
> > > > >
> > > > >  	mutex_lock(&per_pin->lock);
> > > > >  	eld->monitor_present = false;
> > > > > -	size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
> > > > > +	size = snd_hdac_acomp_get_eld(&codec->core, per_pin-
> >pin_nid,
> > > > > +-1,
> > > > >  				      &eld->monitor_present, eld->eld_buffer,
> > > > >  				      ELD_MAX_SIZE);
> > > > >  	if (size > 0) {
> > > > > @@ -1739,7 +1739,8 @@ static int
> > > > > generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
> > > > >  	/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
> > > > >  	/* Todo: add DP1.2 MST audio support later */
> > > > >  	if (codec_has_acomp(codec))
> > > > > -		snd_hdac_sync_audio_rate(&codec->core, pin_nid, runtime-
> > > > > >rate);
> > > > > +		snd_hdac_sync_audio_rate(&codec->core, pin_nid, -1,
> > > > > +					 runtime->rate);
> > > > >
> > > > >  	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
> > > > >  	mutex_lock(&per_pin->lock);
> > > > > @@ -2285,7 +2286,7 @@ static void haswell_set_power_state(struct
> > > > > hda_codec *codec, hda_nid_t fg,
> > > > >  	snd_hda_codec_set_power_to_all(codec, fg, power_state);  }
> > > > >
> > > > > -static void intel_pin_eld_notify(void *audio_ptr, int port)
> > > > > +static void intel_pin_eld_notify(void *audio_ptr, int port, int
> > > > > +dev_id)
> > > > >  {
> > > > >  	struct hda_codec *codec = audio_ptr;
> > > > >  	int pin_nid;
> > > > > --
> > > > > 2.5.0
> > > > >
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-05  2:31             ` Yang, Libin
@ 2016-08-05  7:46               ` Pandiyan, Dhinakaran
  2016-08-05  8:51                 ` Ville Syrjälä
  0 siblings, 1 reply; 24+ messages in thread
From: Pandiyan, Dhinakaran @ 2016-08-05  7:46 UTC (permalink / raw)
  To: Yang, Libin; +Cc: tiwai, libin.yang, intel-gfx, alsa-devel

On Fri, 2016-08-05 at 02:31 +0000, Yang, Libin wrote:
> > -----Original Message-----
> > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
> > Ville Syrjälä
> > Sent: Friday, August 5, 2016 4:48 AM
> > To: Takashi Iwai <tiwai@suse.de>
> > Cc: libin.yang@linux.intel.com; intel-gfx@lists.freedesktop.org; alsa-
> > devel@alsa-project.org; Pandiyan, Dhinakaran
> > <dhinakaran.pandiyan@intel.com>
> > Subject: Re: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> > 
> > On Thu, Aug 04, 2016 at 07:55:09PM +0200, Takashi Iwai wrote:
> > > On Thu, 04 Aug 2016 19:35:16 +0200,
> > > Ville Syrjälä wrote:
> > > >
> > > > On Thu, Aug 04, 2016 at 10:18:52AM -0700, Jim Bride wrote:
> > > > > On Wed, Aug 03, 2016 at 10:08:12PM +0300, Ville Syrjälä wrote:
> > > > > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > > > > DP MST provides the capability to send multiple video and
> > > > > > > audio streams via one single port. This requires the API's
> > > > > > > between i915 and audio drivers to distinguish between audio
> > > > > > > capable displays connected to a port. This patch adds this
> > > > > > > support via an additional parameter 'int dev_id'. The existing
> > parameter 'port' does not change it's meaning.
> > > > > > >
> > > > > > > dev_id =
> > > > > > > 	MST	: pipe that the stream originates from
> > > > > > > 	Non-MST	: -1
> > > > > > >
> > > > > > > Affected APIs:
> > > > > > > struct i915_audio_component_ops
> > > > > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > > > +	int (*sync_audio_rate)(struct device *, int port, int
> > > > > > > +dev_id,
> > > > > >
> > > > > > Does the term 'dev_id' have some special meaning on the audio
> > > > > > side? On the i915 side things would be less confusing if we just
> > > > > > called it 'pipe'.
> > > > >
> > > > > Yeah, it does.  All of the documentation on the audio side is
> > > > > written in terms of device ID, so they asked for that nomenclature.
> > > >
> > > > And is the device ID always the same as the pipe? Until now we've
> > > > made due with passing the port instead of the pipe, so either the
> > > > audio side didn't use the device ID, or its meaning changes based on
> > > > how we drive things, or they dug it out from somewhere else based on the
> > port?
> > >
> > > This is my concern, too.  Currently we have a very wild assumption
> > > even for the port mapping.  In the audio side, there is neither port
> > > nor pipe.  There are only the widget node id and the device id.  The
> > > former is supposedly corresponding to the port, and the latter to the
> > > pipe.  But the audio side has absolutely no clue about how these are
> > > connected.
> > 
> > So I tried to study this a bit, and MST and device<n> are mentioned a few
> > times in the description of some audio registers in the GPU docs. Looks like a
> > bunch of bits overlap somehow with pin vs. device usage. I don't understand
> > how that's supposed to work. Eg:
> 
> For SST & HDMI, port is mapping to pin.
> 
> For MST, in audio, each pin has several device entries. Each device entry
> can transfer audio stream. And we confirmed with silicon team,
> device entry is related to pipe.
> 
> Device entry is always the right concept in audio driver. We are not sure
> the relationship will be always right between pipe and device entry.
> 
> We are worry that the relationship may be changed in the future between
> pipe and device entry. I mean maybe the pipe is not related to device
> entry in the new platforms, but some other conception, such as transcoder.
> If so, if we are using pipe now, maybe we need change the API again.
> For the stability, we are thinking device entry is suitable.
> 
> I think your concern is right. It is not good to use audio conception 
> in gfx driver, which will cause confusion. If we can confirm that
> pipe will always be the fixed mapping to device entry, it will be
> better to use pipe.
> >  AUD_PWRSTAUD_PWRST
> >  1:0 	 PinB Widget PwrSt Set
> >  PinB Widget power state that was setFor DP MST this represents Device1
> > power state
> 
> For this register, it means different in different scenario:
> In DP SST & HDMI, it is for PinB
> In DP MST, it is for device entry 1 (on whichever pin). 
> 
> > 
> > It's anyone's guees what those bits are suppoosed to reflect when you're doing
> > MST with device1/pipe A, and at the same time you're driving port B in
> > HDMI/SST mode.
> 
> I did the similar test before. I remember (but I didn't remember clearly now)
> If one pin is used as DP MST, all the pins are used as DP MST. This means if
> PinB is used as DP MST, 1:0 represents Device 1 and 5:4 represents Device 2.
> Let's say PinC is connected to HDMI audio, it is now looked as Device 2 (or
> other device id) not as PinC audio.
> 
> Regards,
> Libin
> 

Here's what I found after digging through the specs. 

1. Firstly, "device 1" is not same as "device entry at index=1".
a) Device
"Get Device Select" (source: Bspec)
------------------------------------------------------------------------
11:06 Sink Device ID: Sink Device ID in the multi stream topology of the
DP hierarchy.
Device attached to Pipe A will have ID of "00000", Pipe B will have
"00001" and Pipe C will have "00010".
------------------------------------------------------------------------

b) Device entry
Device entry is an audio device attached to a pin(port). Each entry has
an index in a per pin list of devices.
  
2. The "device(pipe)" and the device entry(index in a per pin list)
mapping can be figured out with a sequence of "Get Device List Entry"
and "Get Device Select" verbs in the audio driver.(source:HDA spec)

i915 is not aware of "device entry" or it's mapping to device(pipe). So,
we should be sending the "pin(port)" and "device(pipe)" via
pin_eld_notify(). The audio driver can use this information to get  the
right device entry for "Get Pin Sense" verb. 

3. Confirming what Ville already said. All we need to do now is, as
Ville pointed out, rename the variables

(port and pipe) or (pin and device_id)

Since dev_id is a horrible name for a new variable in i915, let's use
port and pipe.

I will send out a patch renaming dev_id to pipe.

-DK

> > 
> > Anyways, it doesn't help that this whole device widget aspect of hda seems to
> > be undocumented. No spec I've found seems to know anything about any
> > device widgets, and yet those are how MST rolls apparently.
> > 
> > In conclusion, I'd say that consistency's sake we should use either
> > dev+pin or pipe+port in the interface, not mix both. In case of pin I
> > dev+don't think we should use the NID (I'm assuming device
> > widgets have one too), but rather the index. i915 could then do the mapping
> > somethign like dev=pipe and pin=port-1, and then snd-hda can do the idx<-
> > >nid conversion however it sees fit (just use base_nid, or walk some per-type
> > widget lists, or whatever).
> > 
> > That's assuming the widgets really are somehow ordered consistently so we
> > can index them like that. I also might have understtod everyhing I read abou
> > hda.
> > 
> > --
> > Ville Syrjälä
> > Intel OTC
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH] drm/i915/dp: DP audio API changes for MST
  2016-08-05  7:46               ` Pandiyan, Dhinakaran
@ 2016-08-05  8:51                 ` Ville Syrjälä
  0 siblings, 0 replies; 24+ messages in thread
From: Ville Syrjälä @ 2016-08-05  8:51 UTC (permalink / raw)
  To: Pandiyan, Dhinakaran; +Cc: tiwai, intel-gfx, alsa-devel, libin.yang

On Fri, Aug 05, 2016 at 07:46:54AM +0000, Pandiyan, Dhinakaran wrote:
> On Fri, 2016-08-05 at 02:31 +0000, Yang, Libin wrote:
> > > -----Original Message-----
> > > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
> > > Ville Syrjälä
> > > Sent: Friday, August 5, 2016 4:48 AM
> > > To: Takashi Iwai <tiwai@suse.de>
> > > Cc: libin.yang@linux.intel.com; intel-gfx@lists.freedesktop.org; alsa-
> > > devel@alsa-project.org; Pandiyan, Dhinakaran
> > > <dhinakaran.pandiyan@intel.com>
> > > Subject: Re: [Intel-gfx] [PATCH] drm/i915/dp: DP audio API changes for MST
> > > 
> > > On Thu, Aug 04, 2016 at 07:55:09PM +0200, Takashi Iwai wrote:
> > > > On Thu, 04 Aug 2016 19:35:16 +0200,
> > > > Ville Syrjälä wrote:
> > > > >
> > > > > On Thu, Aug 04, 2016 at 10:18:52AM -0700, Jim Bride wrote:
> > > > > > On Wed, Aug 03, 2016 at 10:08:12PM +0300, Ville Syrjälä wrote:
> > > > > > > On Tue, Aug 02, 2016 at 07:14:30PM -0700, Dhinakaran Pandiyan wrote:
> > > > > > > > DP MST provides the capability to send multiple video and
> > > > > > > > audio streams via one single port. This requires the API's
> > > > > > > > between i915 and audio drivers to distinguish between audio
> > > > > > > > capable displays connected to a port. This patch adds this
> > > > > > > > support via an additional parameter 'int dev_id'. The existing
> > > parameter 'port' does not change it's meaning.
> > > > > > > >
> > > > > > > > dev_id =
> > > > > > > > 	MST	: pipe that the stream originates from
> > > > > > > > 	Non-MST	: -1
> > > > > > > >
> > > > > > > > Affected APIs:
> > > > > > > > struct i915_audio_component_ops
> > > > > > > > -       int (*sync_audio_rate)(struct device *, int port, int rate);
> > > > > > > > +	int (*sync_audio_rate)(struct device *, int port, int
> > > > > > > > +dev_id,
> > > > > > >
> > > > > > > Does the term 'dev_id' have some special meaning on the audio
> > > > > > > side? On the i915 side things would be less confusing if we just
> > > > > > > called it 'pipe'.
> > > > > >
> > > > > > Yeah, it does.  All of the documentation on the audio side is
> > > > > > written in terms of device ID, so they asked for that nomenclature.
> > > > >
> > > > > And is the device ID always the same as the pipe? Until now we've
> > > > > made due with passing the port instead of the pipe, so either the
> > > > > audio side didn't use the device ID, or its meaning changes based on
> > > > > how we drive things, or they dug it out from somewhere else based on the
> > > port?
> > > >
> > > > This is my concern, too.  Currently we have a very wild assumption
> > > > even for the port mapping.  In the audio side, there is neither port
> > > > nor pipe.  There are only the widget node id and the device id.  The
> > > > former is supposedly corresponding to the port, and the latter to the
> > > > pipe.  But the audio side has absolutely no clue about how these are
> > > > connected.
> > > 
> > > So I tried to study this a bit, and MST and device<n> are mentioned a few
> > > times in the description of some audio registers in the GPU docs. Looks like a
> > > bunch of bits overlap somehow with pin vs. device usage. I don't understand
> > > how that's supposed to work. Eg:
> > 
> > For SST & HDMI, port is mapping to pin.
> > 
> > For MST, in audio, each pin has several device entries. Each device entry
> > can transfer audio stream. And we confirmed with silicon team,
> > device entry is related to pipe.
> > 
> > Device entry is always the right concept in audio driver. We are not sure
> > the relationship will be always right between pipe and device entry.
> > 
> > We are worry that the relationship may be changed in the future between
> > pipe and device entry. I mean maybe the pipe is not related to device
> > entry in the new platforms, but some other conception, such as transcoder.
> > If so, if we are using pipe now, maybe we need change the API again.
> > For the stability, we are thinking device entry is suitable.
> > 
> > I think your concern is right. It is not good to use audio conception 
> > in gfx driver, which will cause confusion. If we can confirm that
> > pipe will always be the fixed mapping to device entry, it will be
> > better to use pipe.
> > >  AUD_PWRSTAUD_PWRST
> > >  1:0 	 PinB Widget PwrSt Set
> > >  PinB Widget power state that was setFor DP MST this represents Device1
> > > power state
> > 
> > For this register, it means different in different scenario:
> > In DP SST & HDMI, it is for PinB
> > In DP MST, it is for device entry 1 (on whichever pin). 
> > 
> > > 
> > > It's anyone's guees what those bits are suppoosed to reflect when you're doing
> > > MST with device1/pipe A, and at the same time you're driving port B in
> > > HDMI/SST mode.
> > 
> > I did the similar test before. I remember (but I didn't remember clearly now)
> > If one pin is used as DP MST, all the pins are used as DP MST. This means if
> > PinB is used as DP MST, 1:0 represents Device 1 and 5:4 represents Device 2.
> > Let's say PinC is connected to HDMI audio, it is now looked as Device 2 (or
> > other device id) not as PinC audio.
> > 
> > Regards,
> > Libin
> > 
> 
> Here's what I found after digging through the specs. 
> 
> 1. Firstly, "device 1" is not same as "device entry at index=1".
> a) Device
> "Get Device Select" (source: Bspec)
> ------------------------------------------------------------------------
> 11:06 Sink Device ID: Sink Device ID in the multi stream topology of the
> DP hierarchy.
> Device attached to Pipe A will have ID of "00000", Pipe B will have
> "00001" and Pipe C will have "00010".
> ------------------------------------------------------------------------
> 
> b) Device entry
> Device entry is an audio device attached to a pin(port). Each entry has
> an index in a per pin list of devices.
>   
> 2. The "device(pipe)" and the device entry(index in a per pin list)
> mapping can be figured out with a sequence of "Get Device List Entry"
> and "Get Device Select" verbs in the audio driver.(source:HDA spec)
> 
> i915 is not aware of "device entry" or it's mapping to device(pipe). So,
> we should be sending the "pin(port)" and "device(pipe)" via
> pin_eld_notify(). The audio driver can use this information to get  the
> right device entry for "Get Pin Sense" verb. 

OK, so sounds like the hda side is the only one that can really figure
this stuff out. i915 just doesn't have enough information.

> 
> 3. Confirming what Ville already said. All we need to do now is, as
> Ville pointed out, rename the variables
> 
> (port and pipe) or (pin and device_id)
> 
> Since dev_id is a horrible name for a new variable in i915, let's use
> port and pipe.
> 
> I will send out a patch renaming dev_id to pipe.

Sounds good. Thanks.

> 
> -DK
> 
> > > 
> > > Anyways, it doesn't help that this whole device widget aspect of hda seems to
> > > be undocumented. No spec I've found seems to know anything about any
> > > device widgets, and yet those are how MST rolls apparently.
> > > 
> > > In conclusion, I'd say that consistency's sake we should use either
> > > dev+pin or pipe+port in the interface, not mix both. In case of pin I
> > > dev+don't think we should use the NID (I'm assuming device
> > > widgets have one too), but rather the index. i915 could then do the mapping
> > > somethign like dev=pipe and pin=port-1, and then snd-hda can do the idx<-
> > > >nid conversion however it sees fit (just use base_nid, or walk some per-type
> > > widget lists, or whatever).
> > > 
> > > That's assuming the widgets really are somehow ordered consistently so we
> > > can index them like that. I also might have understtod everyhing I read abou
> > > hda.
> > > 
> > > --
> > > Ville Syrjälä
> > > Intel OTC
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2016-08-05  8:51 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-03  2:14 DP audio API changes for identifying displays connected to a port Dhinakaran Pandiyan
2016-08-03  2:14 ` [PATCH] drm/i915/dp: DP audio API changes for MST Dhinakaran Pandiyan
2016-08-03 13:53   ` Takashi Iwai
2016-08-03 18:52     ` Pandiyan, Dhinakaran
2016-08-03 19:08   ` Ville Syrjälä
2016-08-03 19:43     ` Pandiyan, Dhinakaran
2016-08-03 20:28       ` Ville Syrjälä
2016-08-03 21:42         ` Pandiyan, Dhinakaran
2016-08-04 12:49           ` Ville Syrjälä
2016-08-04 16:44             ` Pandiyan, Dhinakaran
2016-08-04 17:18     ` Jim Bride
2016-08-04 17:35       ` Ville Syrjälä
2016-08-04 17:55         ` Takashi Iwai
2016-08-04 20:48           ` Ville Syrjälä
2016-08-05  2:31             ` Yang, Libin
2016-08-05  7:46               ` Pandiyan, Dhinakaran
2016-08-05  8:51                 ` Ville Syrjälä
2016-08-05  2:35   ` Yang, Libin
2016-08-05  5:57     ` Pandiyan, Dhinakaran
2016-08-05  6:21       ` Yang, Libin
2016-08-05  6:41         ` Pandiyan, Dhinakaran
2016-08-05  6:43           ` Yang, Libin
2016-08-03  6:25 ` ✗ Ro.CI.BAT: failure for " Patchwork
2016-08-03 13:47 ` DP audio API changes for identifying displays connected to a port Takashi Iwai

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.