@@ -810,11 +810,22 @@ void intel_init_audio_hooks(struct drm_i915_private *dev_priv)
}
}
+int intel_get_audio_bclk(struct drm_i915_private *dev_priv)
+{
+ if (INTEL_GEN(dev_priv) >= 9 &&
+ (dev_priv->audio_freq_cntrl & AUD_FREQ_48M_BCLK))
+ return 48000;
+
+ return 96000;
+}
+
static int glk_force_audio_cdclk_commit(struct intel_atomic_state *state,
struct intel_crtc *crtc,
bool enable)
{
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_cdclk_state *cdclk_state;
+ int bclk = intel_get_audio_bclk(dev_priv);
int ret;
/* need to hold at least one crtc lock for the global state */
@@ -827,7 +838,7 @@ static int glk_force_audio_cdclk_commit(struct intel_atomic_state *state,
return PTR_ERR(cdclk_state);
cdclk_state->force_min_cdclk_changed = true;
- cdclk_state->force_min_cdclk = enable ? 2 * 96000 : 0;
+ cdclk_state->force_min_cdclk = enable ? 2 * bclk : 0;
ret = intel_atomic_lock_global_state(&cdclk_state->base);
if (ret)
@@ -20,5 +20,6 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
const struct drm_connector_state *old_conn_state);
void intel_audio_init(struct drm_i915_private *dev_priv);
void intel_audio_deinit(struct drm_i915_private *dev_priv);
+int intel_get_audio_bclk(struct drm_i915_private *dev_priv);
#endif /* __INTEL_AUDIO_H__ */
@@ -23,6 +23,7 @@
#include "intel_atomic.h"
#include "intel_cdclk.h"
+#include "intel_audio.h"
#include "intel_display_types.h"
#include "intel_sideband.h"
@@ -2001,6 +2002,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv =
to_i915(crtc_state->uapi.crtc->dev);
+ int bclk = intel_get_audio_bclk(dev_priv);
int min_cdclk;
if (!crtc_state->hw.enable)
@@ -2032,10 +2034,10 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
/*
* According to BSpec, "The CD clock frequency must be at least twice
- * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
+ * the frequency of the Azalia BCLK.".
*/
if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
- min_cdclk = max(2 * 96000, min_cdclk);
+ min_cdclk = max(2 * bclk, min_cdclk);
/*
* "For DP audio configuration, cdclk frequency shall be set to
@@ -9294,6 +9294,8 @@ enum {
#define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15)
#define AUD_FREQ_CNTRL _MMIO(0x65900)
+#define AUD_FREQ_48M_BCLK REG_BIT(3)
+#define AUD_FREQ_96M_BCLK REG_BIT(4)
#define AUD_PIN_BUF_CTL _MMIO(0x48414)
#define AUD_PIN_BUF_ENABLE REG_BIT(31)
Instead of assuming maximum value of BCLK (96Mhz), use the actual value as configured by BIOS. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> --- drivers/gpu/drm/i915/display/intel_audio.c | 13 ++++++++++++- drivers/gpu/drm/i915/display/intel_audio.h | 1 + drivers/gpu/drm/i915/display/intel_cdclk.c | 6 ++++-- drivers/gpu/drm/i915/i915_reg.h | 2 ++ 4 files changed, 19 insertions(+), 3 deletions(-)