--- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -84,6 +84,8 @@ } aud_ncts[] = { { 44100, TMDS_296M, 4459, 234375 }, { 44100, TMDS_297M, 4704, 247500 }, + { 44100, 148352*3/2, 5733, 148352 }, + { 44100, 148500*3/2, 4704, 148500 }, { 48000, TMDS_296M, 5824, 281250 }, { 48000, TMDS_297M, 5120, 247500 }, { 32000, TMDS_296M, 5824, 421875 }, @@ -121,14 +123,22 @@ return hdmi_audio_clock[i].config; } -static int audio_config_get_n(const struct drm_display_mode *mode, int rate) +static int audio_config_get_n(struct intel_crtc *crtc, + const struct drm_display_mode *adjusted_mode, + int rate) { int i; + int crtc_clock = adjusted_mode->crtc_clock; - for (i = 0; i < ARRAY_SIZE(aud_ncts); i++) { - if ((rate == aud_ncts[i].sample_rate) && - (mode->clock == aud_ncts[i].clock)) { - return aud_ncts[i].n; + if (crtc->config->pipe_bpp > 24) + crtc_clock = crtc_clock * 3 / 2; //36-bit mode uses 50% faster TMDS clock. + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { + for (i = 0; i < ARRAY_SIZE(aud_ncts); i++) { + if ((rate == aud_ncts[i].sample_rate) && + (crtc_clock == aud_ncts[i].clock)) { + return aud_ncts[i].n; + } } } return 0; @@ -150,10 +160,11 @@ /* check whether N/CTS/M need be set manually */ static bool audio_rate_need_prog(struct intel_crtc *crtc, - const struct drm_display_mode *mode) + const struct drm_display_mode *adjusted_mode) { - if (((mode->clock == TMDS_297M) || - (mode->clock == TMDS_296M)) && + if (((adjusted_mode->crtc_clock == TMDS_297M) || + (adjusted_mode->crtc_clock == TMDS_296M) || + (crtc->config->pipe_bpp > 24 && adjusted_mode->crtc_clock >= 148352 )) && intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) return true; else @@ -343,7 +354,7 @@ DRM_ERROR("invalid port: %d\n", port); rate = 0; } - n = audio_config_get_n(adjusted_mode, rate); + n = audio_config_get_n(intel_crtc, adjusted_mode, rate); if (n != 0) tmp = audio_config_setup_n_reg(n, tmp); else @@ -687,7 +698,7 @@ goto unlock; } - n = audio_config_get_n(mode, rate); + n = audio_config_get_n(crtc, mode, rate); if (n == 0) { DRM_DEBUG_KMS("Using automatic mode for N value on port %c\n", port_name(port));