aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_audio.c')
-rw-r--r--drivers/gpu/drm/i915/intel_audio.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index 2396cc702d18..3da9b8409f20 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -28,7 +28,6 @@
28 28
29#include <drm/drmP.h> 29#include <drm/drmP.h>
30#include <drm/drm_edid.h> 30#include <drm/drm_edid.h>
31#include "intel_drv.h"
32#include "i915_drv.h" 31#include "i915_drv.h"
33 32
34/** 33/**
@@ -270,6 +269,9 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder)
270 DRM_DEBUG_KMS("Disable audio codec on port %c, pipe %c\n", 269 DRM_DEBUG_KMS("Disable audio codec on port %c, pipe %c\n",
271 port_name(port), pipe_name(pipe)); 270 port_name(port), pipe_name(pipe));
272 271
272 if (WARN_ON(port == PORT_A))
273 return;
274
273 if (HAS_PCH_IBX(dev_priv->dev)) { 275 if (HAS_PCH_IBX(dev_priv->dev)) {
274 aud_config = IBX_AUD_CFG(pipe); 276 aud_config = IBX_AUD_CFG(pipe);
275 aud_cntrl_st2 = IBX_AUD_CNTL_ST2; 277 aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
@@ -291,12 +293,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder)
291 tmp |= AUD_CONFIG_N_VALUE_INDEX; 293 tmp |= AUD_CONFIG_N_VALUE_INDEX;
292 I915_WRITE(aud_config, tmp); 294 I915_WRITE(aud_config, tmp);
293 295
294 if (WARN_ON(!port)) { 296 eldv = IBX_ELD_VALID(port);
295 eldv = IBX_ELD_VALID(PORT_B) | IBX_ELD_VALID(PORT_C) |
296 IBX_ELD_VALID(PORT_D);
297 } else {
298 eldv = IBX_ELD_VALID(port);
299 }
300 297
301 /* Invalidate ELD */ 298 /* Invalidate ELD */
302 tmp = I915_READ(aud_cntrl_st2); 299 tmp = I915_READ(aud_cntrl_st2);
@@ -326,6 +323,9 @@ static void ilk_audio_codec_enable(struct drm_connector *connector,
326 DRM_DEBUG_KMS("Enable audio codec on port %c, pipe %c, %u bytes ELD\n", 323 DRM_DEBUG_KMS("Enable audio codec on port %c, pipe %c, %u bytes ELD\n",
327 port_name(port), pipe_name(pipe), drm_eld_size(eld)); 324 port_name(port), pipe_name(pipe), drm_eld_size(eld));
328 325
326 if (WARN_ON(port == PORT_A))
327 return;
328
329 /* 329 /*
330 * FIXME: We're supposed to wait for vblank here, but we have vblanks 330 * FIXME: We're supposed to wait for vblank here, but we have vblanks
331 * disabled during the mode set. The proper fix would be to push the 331 * disabled during the mode set. The proper fix would be to push the
@@ -350,12 +350,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector,
350 aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; 350 aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
351 } 351 }
352 352
353 if (WARN_ON(!port)) { 353 eldv = IBX_ELD_VALID(port);
354 eldv = IBX_ELD_VALID(PORT_B) | IBX_ELD_VALID(PORT_C) |
355 IBX_ELD_VALID(PORT_D);
356 } else {
357 eldv = IBX_ELD_VALID(port);
358 }
359 354
360 /* Invalidate ELD */ 355 /* Invalidate ELD */
361 tmp = I915_READ(aud_cntrl_st2); 356 tmp = I915_READ(aud_cntrl_st2);
@@ -475,6 +470,32 @@ static void i915_audio_component_put_power(struct device *dev)
475 intel_display_power_put(dev_to_i915(dev), POWER_DOMAIN_AUDIO); 470 intel_display_power_put(dev_to_i915(dev), POWER_DOMAIN_AUDIO);
476} 471}
477 472
473static void i915_audio_component_codec_wake_override(struct device *dev,
474 bool enable)
475{
476 struct drm_i915_private *dev_priv = dev_to_i915(dev);
477 u32 tmp;
478
479 if (!IS_SKYLAKE(dev_priv))
480 return;
481
482 /*
483 * Enable/disable generating the codec wake signal, overriding the
484 * internal logic to generate the codec wake to controller.
485 */
486 tmp = I915_READ(HSW_AUD_CHICKENBIT);
487 tmp &= ~SKL_AUD_CODEC_WAKE_SIGNAL;
488 I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
489 usleep_range(1000, 1500);
490
491 if (enable) {
492 tmp = I915_READ(HSW_AUD_CHICKENBIT);
493 tmp |= SKL_AUD_CODEC_WAKE_SIGNAL;
494 I915_WRITE(HSW_AUD_CHICKENBIT, tmp);
495 usleep_range(1000, 1500);
496 }
497}
498
478/* Get CDCLK in kHz */ 499/* Get CDCLK in kHz */
479static int i915_audio_component_get_cdclk_freq(struct device *dev) 500static int i915_audio_component_get_cdclk_freq(struct device *dev)
480{ 501{
@@ -485,7 +506,8 @@ static int i915_audio_component_get_cdclk_freq(struct device *dev)
485 return -ENODEV; 506 return -ENODEV;
486 507
487 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); 508 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
488 ret = intel_ddi_get_cdclk_freq(dev_priv); 509 ret = dev_priv->display.get_display_clock_speed(dev_priv->dev);
510
489 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); 511 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
490 512
491 return ret; 513 return ret;
@@ -495,6 +517,7 @@ static const struct i915_audio_component_ops i915_audio_component_ops = {
495 .owner = THIS_MODULE, 517 .owner = THIS_MODULE,
496 .get_power = i915_audio_component_get_power, 518 .get_power = i915_audio_component_get_power,
497 .put_power = i915_audio_component_put_power, 519 .put_power = i915_audio_component_put_power,
520 .codec_wake_override = i915_audio_component_codec_wake_override,
498 .get_cdclk_freq = i915_audio_component_get_cdclk_freq, 521 .get_cdclk_freq = i915_audio_component_get_cdclk_freq,
499}; 522};
500 523