|
@@ -491,6 +491,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
|
|
|
struct drm_i915_private *dev_priv = to_i915(encoder->dev);
|
|
|
struct i915_audio_component *acomp = dev_priv->audio_component;
|
|
|
enum port port = intel_encoder->port;
|
|
|
+ enum pipe pipe = crtc->pipe;
|
|
|
|
|
|
connector = drm_select_eld(encoder);
|
|
|
if (!connector)
|
|
@@ -515,12 +516,18 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
|
|
|
|
|
|
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);
|
|
|
|
|
|
+ /* audio drivers expect pipe = -1 to indicate Non-MST cases */
|
|
|
+ if (intel_encoder->type != INTEL_OUTPUT_DP_MST)
|
|
|
+ pipe = -1;
|
|
|
+
|
|
|
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, (int) pipe);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -536,17 +543,24 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder)
|
|
|
struct drm_i915_private *dev_priv = to_i915(encoder->dev);
|
|
|
struct i915_audio_component *acomp = dev_priv->audio_component;
|
|
|
enum port port = intel_encoder->port;
|
|
|
+ struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
|
|
|
+ enum pipe pipe = crtc->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);
|
|
|
|
|
|
+ /* audio drivers expect pipe = -1 to indicate Non-MST cases */
|
|
|
+ if (intel_encoder->type != INTEL_OUTPUT_DP_MST)
|
|
|
+ pipe = -1;
|
|
|
+
|
|
|
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, (int) pipe);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -621,15 +635,40 @@ static int i915_audio_component_get_cdclk_freq(struct device *kdev)
|
|
|
return dev_priv->cdclk_freq;
|
|
|
}
|
|
|
|
|
|
-static int i915_audio_component_sync_audio_rate(struct device *kdev,
|
|
|
- int port, int rate)
|
|
|
+static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv,
|
|
|
+ int port, int pipe)
|
|
|
+{
|
|
|
+
|
|
|
+ if (WARN_ON(pipe >= I915_MAX_PIPES))
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ /* MST */
|
|
|
+ if (pipe >= 0)
|
|
|
+ return dev_priv->av_enc_map[pipe];
|
|
|
+
|
|
|
+ /* Non-MST */
|
|
|
+ for_each_pipe(dev_priv, pipe) {
|
|
|
+ struct intel_encoder *encoder;
|
|
|
+
|
|
|
+ encoder = dev_priv->av_enc_map[pipe];
|
|
|
+ if (encoder == NULL)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (port == encoder->port)
|
|
|
+ return encoder;
|
|
|
+ }
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static int i915_audio_component_sync_audio_rate(struct device *kdev, int port,
|
|
|
+ int pipe, int rate)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
|
|
|
struct intel_encoder *intel_encoder;
|
|
|
struct intel_crtc *crtc;
|
|
|
struct drm_display_mode *mode;
|
|
|
struct i915_audio_component *acomp = dev_priv->audio_component;
|
|
|
- enum pipe pipe = INVALID_PIPE;
|
|
|
u32 tmp;
|
|
|
int n;
|
|
|
int err = 0;
|
|
@@ -643,25 +682,20 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev,
|
|
|
|
|
|
i915_audio_component_get_power(kdev);
|
|
|
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_enc(dev_priv, port, pipe);
|
|
|
if (!intel_encoder || !intel_encoder->base.crtc ||
|
|
|
intel_encoder->type != INTEL_OUTPUT_HDMI) {
|
|
|
- DRM_DEBUG_KMS("no valid port %c\n", port_name(port));
|
|
|
+ DRM_DEBUG_KMS("Not valid for port %c\n", port_name(port));
|
|
|
err = -ENODEV;
|
|
|
goto unlock;
|
|
|
}
|
|
|
+
|
|
|
+ /* pipe passed from the audio driver will be -1 for Non-MST case */
|
|
|
crtc = to_intel_crtc(intel_encoder->base.crtc);
|
|
|
pipe = crtc->pipe;
|
|
|
- if (pipe == INVALID_PIPE) {
|
|
|
- DRM_DEBUG_KMS("no pipe for the port %c\n", port_name(port));
|
|
|
- err = -ENODEV;
|
|
|
- goto unlock;
|
|
|
- }
|
|
|
|
|
|
- DRM_DEBUG_KMS("pipe %c connects port %c\n",
|
|
|
- pipe_name(pipe), port_name(port));
|
|
|
mode = &crtc->config->base.adjusted_mode;
|
|
|
|
|
|
/* port must be valid now, otherwise the pipe will be invalid */
|
|
@@ -697,7 +731,7 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev,
|
|
|
}
|
|
|
|
|
|
static int i915_audio_component_get_eld(struct device *kdev, int port,
|
|
|
- bool *enabled,
|
|
|
+ int pipe, bool *enabled,
|
|
|
unsigned char *buf, int max_bytes)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
|
|
@@ -706,16 +740,20 @@ static int i915_audio_component_get_eld(struct device *kdev, int port,
|
|
|
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_enc(dev_priv, port, pipe);
|
|
|
+ if (!intel_encoder) {
|
|
|
+ DRM_DEBUG_KMS("Not valid for port %c\n", port_name(port));
|
|
|
+ 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);
|