@@ -7359,6 +7359,13 @@ enum {
#define _HSW_AUD_MISC_CTRL_B 0x65110
#define HSW_AUD_MISC_CTRL(pipe) _MMIO_PIPE(pipe, _HSW_AUD_MISC_CTRL_A, _HSW_AUD_MISC_CTRL_B)
+#define _HSW_AUD_M_CTS_ENABLE_A 0x65028
+#define _HSW_AUD_M_CTS_ENABLE_B 0x65128
+#define HSW_AUD_M_CTS_ENABLE(pipe) _MMIO_PIPE(pipe, _HSW_AUD_M_CTS_ENABLE_A, _HSW_AUD_M_CTS_ENABLE_B)
+#define AUD_M_CTS_M_VALUE_INDEX (1 << 21)
+#define AUD_M_CTS_M_PROG_ENABLE (1 << 20)
+#define AUD_CONFIG_M_MASK 0xfffff
+
#define _HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4
#define _HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4
#define HSW_AUD_DIP_ELD_CTRL(pipe) _MMIO_PIPE(pipe, _HSW_AUD_DIP_ELD_CTRL_ST_A, _HSW_AUD_DIP_ELD_CTRL_ST_B)
@@ -57,6 +57,70 @@
* struct &i915_audio_component_audio_ops @audio_ops is called from i915 driver.
*/
+/* DP N/M table */
+#define LC_540M 540000
+#define LC_270M 270000
+#define LC_162M 162000
+
+struct dp_aud_n_m {
+ int sample_rate;
+ int clock;
+ u16 n;
+ u16 m;
+};
+
+static const struct dp_aud_n_m dp_aud_n_m[] = {
+ { 192000, LC_540M, 5625, 1024 },
+ { 176400, LC_540M, 9375, 1568 },
+ { 96000, LC_540M, 5625, 512 },
+ { 88200, LC_540M, 9375, 784 },
+ { 48000, LC_540M, 5625, 256 },
+ { 44100, LC_540M, 9375, 392 },
+ { 32000, LC_540M, 16875, 512 },
+ { 192000, LC_270M, 5625, 2048 },
+ { 176400, LC_270M, 9375, 3136 },
+ { 96000, LC_270M, 5625, 1024 },
+ { 88200, LC_270M, 9375, 1568 },
+ { 48000, LC_270M, 5625, 512 },
+ { 44100, LC_270M, 9375, 784 },
+ { 32000, LC_270M, 16875, 1024 },
+ { 192000, LC_162M, 3375, 2048 },
+ { 176400, LC_162M, 5625, 3136 },
+ { 96000, LC_162M, 3375, 1024 },
+ { 88200, LC_162M, 5625, 1568 },
+ { 48000, LC_162M, 3375, 512 },
+ { 44100, LC_162M, 5625, 784 },
+ { 32000, LC_162M, 10125, 1024 },
+};
+
+static const struct dp_aud_n_m *
+audio_config_dp_get_n_m(struct intel_crtc *intel_crtc, int rate) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) {
+ if (rate == dp_aud_n_m[i].sample_rate &&
+ intel_crtc->config->port_clock == dp_aud_n_m[i].clock)
+ return &dp_aud_n_m[i];
+ }
+
+ return NULL;
+}
+
+static int audio_config_dp_get_m(struct intel_crtc *intel_crtc, int
+rate) {
+ const struct dp_aud_n_m *nm = audio_config_dp_get_n_m(intel_crtc,
+rate);
+
+ return nm ? nm->m : 0;
+}
+
+static int audio_config_dp_get_n(struct intel_crtc *intel_crtc, int
+rate) {
+ const struct dp_aud_n_m *nm = audio_config_dp_get_n_m(intel_crtc,
+rate);
+
+ return nm ? nm->n : 0;
+}
+
static const struct {
int clock;
u32 config;
@@ -225,8 +289,10 @@ hsw_dp_audio_config_update(struct intel_crtc *intel_crtc, enum port port,
const struct drm_display_mode *adjusted_mode) {
struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+ struct i915_audio_component *acomp = dev_priv->audio_component;
+ int rate = acomp ? acomp->aud_sample_rate[port] : 0;
enum pipe pipe = intel_crtc->pipe;
- u32 tmp;
+ u32 tmp, n, m;
tmp = I915_READ(HSW_AUD_CFG(pipe));
tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
@@ -234,7 +300,30 @@ hsw_dp_audio_config_update(struct intel_crtc *intel_crtc, enum port port,