drm/i915: pass ELD to HDMI/DP audio driver

Add ELD support for Intel Eaglelake, IbexPeak/Ironlake,
SandyBridge/CougarPoint and IvyBridge/PantherPoint chips.

ELD (EDID-Like Data) describes to the HDMI/DP audio driver the audio
capabilities of the plugged monitor. It's built and passed to audio
driver in 2 steps:

(1) at get_modes time, parse EDID and save ELD to drm_connector.eld[]

(2) at mode_set time, write drm_connector.eld[] to the Transcoder's hw
    ELD buffer and set the ELD_valid bit to inform HDMI/DP audio driver

This patch is tested OK on G45/HDMI, IbexPeak/HDMI and IvyBridge/HDMI+DP.
Test scheme: plug in the HDMI/DP monitor, and run

        cat /proc/asound/card0/eld*

to check if the monitor name, HDMI/DP type, etc. show up correctly.

Minor imperfection: the GEN5_AUD_CNTL_ST/DIP_Port_Select field always
reads 0 (reserved). Without knowing the port number, I worked it around
by setting the ELD_valid bit for ALL the three ports. It's tested to not
be a problem, because the audio driver will find invalid ELD data and
hence rightfully abort, even when it sees the ELD_valid indicator.

Thanks to Zhenyu and Pierre-Louis for a lot of valuable help and testing.

CC: Zhao Yakui <yakui.zhao@intel.com>
CC: Wang Zhenyu <zhenyu.z.wang@intel.com>
CC: Jeremy Bush <contractfrombelow@gmail.com>
CC: Christopher White <c.white@pulseforce.com>
CC: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
CC: Paul Menzel <paulepanter@users.sourceforge.net>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 4091f21..6cbde9f 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -773,8 +773,12 @@
 		intel_dp->DP |= DP_PORT_WIDTH_4;
 		break;
 	}
-	if (intel_dp->has_audio)
+	if (intel_dp->has_audio) {
+		DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
+				 pipe_name(intel_crtc->pipe));
 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
+		intel_write_eld(encoder, adjusted_mode);
+	}
 
 	memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
 	intel_dp->link_configuration[0] = intel_dp->link_bw;