aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-01-03 04:34:43 -0500
committerDave Airlie <airlied@redhat.com>2012-01-03 04:34:43 -0500
commit2318fcd65c1fb1e842f860c1e3fe4dba7e55cd11 (patch)
tree8f2d73ee6f8be3f49ee07881a8579fa15f9e1881 /drivers/gpu
parentf9f23a77f07506a32d9dc1d925bf85c0e7507b66 (diff)
parent097354eb14fa94d31a09c64d640643f58e4a5a9a (diff)
Merge branch 'drm-intel-next' of git://people.freedesktop.org/~keithp/linux into drm-core-next
* 'drm-intel-next' of git://people.freedesktop.org/~keithp/linux: drm/i915: check ACTHD of all rings drm/i915: DisplayPort hot remove notification to audio driver drm/i915: HDMI hot remove notification to audio driver drm/i915: dont trigger hotplug events on unchanged ELD drm/i915: rename audio ELD registers drm/i915: fix ELD writing for SandyBridge
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c13
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h24
-rw-r--r--drivers/gpu/drm/i915/intel_display.c75
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c1
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c8
6 files changed, 89 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 554bef7a3b9c..505af3f64a07 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -337,6 +337,8 @@ typedef struct drm_i915_private {
337 struct timer_list hangcheck_timer; 337 struct timer_list hangcheck_timer;
338 int hangcheck_count; 338 int hangcheck_count;
339 uint32_t last_acthd; 339 uint32_t last_acthd;
340 uint32_t last_acthd_bsd;
341 uint32_t last_acthd_blt;
340 uint32_t last_instdone; 342 uint32_t last_instdone;
341 uint32_t last_instdone1; 343 uint32_t last_instdone1;
342 344
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 3700df47ad93..58493114c942 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1669,7 +1669,7 @@ void i915_hangcheck_elapsed(unsigned long data)
1669{ 1669{
1670 struct drm_device *dev = (struct drm_device *)data; 1670 struct drm_device *dev = (struct drm_device *)data;
1671 drm_i915_private_t *dev_priv = dev->dev_private; 1671 drm_i915_private_t *dev_priv = dev->dev_private;
1672 uint32_t acthd, instdone, instdone1; 1672 uint32_t acthd, instdone, instdone1, acthd_bsd, acthd_blt;
1673 bool err = false; 1673 bool err = false;
1674 1674
1675 if (!i915_enable_hangcheck) 1675 if (!i915_enable_hangcheck)
@@ -1686,16 +1686,21 @@ void i915_hangcheck_elapsed(unsigned long data)
1686 } 1686 }
1687 1687
1688 if (INTEL_INFO(dev)->gen < 4) { 1688 if (INTEL_INFO(dev)->gen < 4) {
1689 acthd = I915_READ(ACTHD);
1690 instdone = I915_READ(INSTDONE); 1689 instdone = I915_READ(INSTDONE);
1691 instdone1 = 0; 1690 instdone1 = 0;
1692 } else { 1691 } else {
1693 acthd = I915_READ(ACTHD_I965);
1694 instdone = I915_READ(INSTDONE_I965); 1692 instdone = I915_READ(INSTDONE_I965);
1695 instdone1 = I915_READ(INSTDONE1); 1693 instdone1 = I915_READ(INSTDONE1);
1696 } 1694 }
1695 acthd = intel_ring_get_active_head(&dev_priv->ring[RCS]);
1696 acthd_bsd = HAS_BSD(dev) ?
1697 intel_ring_get_active_head(&dev_priv->ring[VCS]) : 0;
1698 acthd_blt = HAS_BLT(dev) ?
1699 intel_ring_get_active_head(&dev_priv->ring[BCS]) : 0;
1697 1700
1698 if (dev_priv->last_acthd == acthd && 1701 if (dev_priv->last_acthd == acthd &&
1702 dev_priv->last_acthd_bsd == acthd_bsd &&
1703 dev_priv->last_acthd_blt == acthd_blt &&
1699 dev_priv->last_instdone == instdone && 1704 dev_priv->last_instdone == instdone &&
1700 dev_priv->last_instdone1 == instdone1) { 1705 dev_priv->last_instdone1 == instdone1) {
1701 if (dev_priv->hangcheck_count++ > 1) { 1706 if (dev_priv->hangcheck_count++ > 1) {
@@ -1727,6 +1732,8 @@ void i915_hangcheck_elapsed(unsigned long data)
1727 dev_priv->hangcheck_count = 0; 1732 dev_priv->hangcheck_count = 0;
1728 1733
1729 dev_priv->last_acthd = acthd; 1734 dev_priv->last_acthd = acthd;
1735 dev_priv->last_acthd_bsd = acthd_bsd;
1736 dev_priv->last_acthd_blt = acthd_blt;
1730 dev_priv->last_instdone = instdone; 1737 dev_priv->last_instdone = instdone;
1731 dev_priv->last_instdone1 = instdone1; 1738 dev_priv->last_instdone1 = instdone1;
1732 } 1739 }
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 853f2f0acaa2..194d9874002b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3570,17 +3570,17 @@
3570#define G4X_ELD_ACK (1 << 4) 3570#define G4X_ELD_ACK (1 << 4)
3571#define G4X_HDMIW_HDMIEDID 0x6210C 3571#define G4X_HDMIW_HDMIEDID 0x6210C
3572 3572
3573#define GEN5_HDMIW_HDMIEDID_A 0xE2050 3573#define IBX_HDMIW_HDMIEDID_A 0xE2050
3574#define GEN5_AUD_CNTL_ST_A 0xE20B4 3574#define IBX_AUD_CNTL_ST_A 0xE20B4
3575#define GEN5_ELD_BUFFER_SIZE (0x1f << 10) 3575#define IBX_ELD_BUFFER_SIZE (0x1f << 10)
3576#define GEN5_ELD_ADDRESS (0x1f << 5) 3576#define IBX_ELD_ADDRESS (0x1f << 5)
3577#define GEN5_ELD_ACK (1 << 4) 3577#define IBX_ELD_ACK (1 << 4)
3578#define GEN5_AUD_CNTL_ST2 0xE20C0 3578#define IBX_AUD_CNTL_ST2 0xE20C0
3579#define GEN5_ELD_VALIDB (1 << 0) 3579#define IBX_ELD_VALIDB (1 << 0)
3580#define GEN5_CP_READYB (1 << 1) 3580#define IBX_CP_READYB (1 << 1)
3581 3581
3582#define GEN7_HDMIW_HDMIEDID_A 0xE5050 3582#define CPT_HDMIW_HDMIEDID_A 0xE5050
3583#define GEN7_AUD_CNTRL_ST_A 0xE50B4 3583#define CPT_AUD_CNTL_ST_A 0xE50B4
3584#define GEN7_AUD_CNTRL_ST2 0xE50C0 3584#define CPT_AUD_CNTRL_ST2 0xE50C0
3585 3585
3586#endif /* _I915_REG_H_ */ 3586#endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5a3e7853003f..55a5b4c4edf1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5830,6 +5830,35 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
5830 return ret; 5830 return ret;
5831} 5831}
5832 5832
5833static bool intel_eld_uptodate(struct drm_connector *connector,
5834 int reg_eldv, uint32_t bits_eldv,
5835 int reg_elda, uint32_t bits_elda,
5836 int reg_edid)
5837{
5838 struct drm_i915_private *dev_priv = connector->dev->dev_private;
5839 uint8_t *eld = connector->eld;
5840 uint32_t i;
5841
5842 i = I915_READ(reg_eldv);
5843 i &= bits_eldv;
5844
5845 if (!eld[0])
5846 return !i;
5847
5848 if (!i)
5849 return false;
5850
5851 i = I915_READ(reg_elda);
5852 i &= ~bits_elda;
5853 I915_WRITE(reg_elda, i);
5854
5855 for (i = 0; i < eld[2]; i++)
5856 if (I915_READ(reg_edid) != *((uint32_t *)eld + i))
5857 return false;
5858
5859 return true;
5860}
5861
5833static void g4x_write_eld(struct drm_connector *connector, 5862static void g4x_write_eld(struct drm_connector *connector,
5834 struct drm_crtc *crtc) 5863 struct drm_crtc *crtc)
5835{ 5864{
@@ -5846,6 +5875,12 @@ static void g4x_write_eld(struct drm_connector *connector,
5846 else 5875 else
5847 eldv = G4X_ELDV_DEVCTG; 5876 eldv = G4X_ELDV_DEVCTG;
5848 5877
5878 if (intel_eld_uptodate(connector,
5879 G4X_AUD_CNTL_ST, eldv,
5880 G4X_AUD_CNTL_ST, G4X_ELD_ADDR,
5881 G4X_HDMIW_HDMIEDID))
5882 return;
5883
5849 i = I915_READ(G4X_AUD_CNTL_ST); 5884 i = I915_READ(G4X_AUD_CNTL_ST);
5850 i &= ~(eldv | G4X_ELD_ADDR); 5885 i &= ~(eldv | G4X_ELD_ADDR);
5851 len = (i >> 9) & 0x1f; /* ELD buffer size */ 5886 len = (i >> 9) & 0x1f; /* ELD buffer size */
@@ -5876,14 +5911,14 @@ static void ironlake_write_eld(struct drm_connector *connector,
5876 int aud_cntl_st; 5911 int aud_cntl_st;
5877 int aud_cntrl_st2; 5912 int aud_cntrl_st2;
5878 5913
5879 if (IS_IVYBRIDGE(connector->dev)) { 5914 if (HAS_PCH_IBX(connector->dev)) {
5880 hdmiw_hdmiedid = GEN7_HDMIW_HDMIEDID_A; 5915 hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A;
5881 aud_cntl_st = GEN7_AUD_CNTRL_ST_A; 5916 aud_cntl_st = IBX_AUD_CNTL_ST_A;
5882 aud_cntrl_st2 = GEN7_AUD_CNTRL_ST2; 5917 aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
5883 } else { 5918 } else {
5884 hdmiw_hdmiedid = GEN5_HDMIW_HDMIEDID_A; 5919 hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A;
5885 aud_cntl_st = GEN5_AUD_CNTL_ST_A; 5920 aud_cntl_st = CPT_AUD_CNTL_ST_A;
5886 aud_cntrl_st2 = GEN5_AUD_CNTL_ST2; 5921 aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
5887 } 5922 }
5888 5923
5889 i = to_intel_crtc(crtc)->pipe; 5924 i = to_intel_crtc(crtc)->pipe;
@@ -5897,14 +5932,25 @@ static void ironlake_write_eld(struct drm_connector *connector,
5897 if (!i) { 5932 if (!i) {
5898 DRM_DEBUG_DRIVER("Audio directed to unknown port\n"); 5933 DRM_DEBUG_DRIVER("Audio directed to unknown port\n");
5899 /* operate blindly on all ports */ 5934 /* operate blindly on all ports */
5900 eldv = GEN5_ELD_VALIDB; 5935 eldv = IBX_ELD_VALIDB;
5901 eldv |= GEN5_ELD_VALIDB << 4; 5936 eldv |= IBX_ELD_VALIDB << 4;
5902 eldv |= GEN5_ELD_VALIDB << 8; 5937 eldv |= IBX_ELD_VALIDB << 8;
5903 } else { 5938 } else {
5904 DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i); 5939 DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i);
5905 eldv = GEN5_ELD_VALIDB << ((i - 1) * 4); 5940 eldv = IBX_ELD_VALIDB << ((i - 1) * 4);
5941 }
5942
5943 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
5944 DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
5945 eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
5906 } 5946 }
5907 5947
5948 if (intel_eld_uptodate(connector,
5949 aud_cntrl_st2, eldv,
5950 aud_cntl_st, IBX_ELD_ADDRESS,
5951 hdmiw_hdmiedid))
5952 return;
5953
5908 i = I915_READ(aud_cntrl_st2); 5954 i = I915_READ(aud_cntrl_st2);
5909 i &= ~eldv; 5955 i &= ~eldv;
5910 I915_WRITE(aud_cntrl_st2, i); 5956 I915_WRITE(aud_cntrl_st2, i);
@@ -5912,13 +5958,8 @@ static void ironlake_write_eld(struct drm_connector *connector,
5912 if (!eld[0]) 5958 if (!eld[0])
5913 return; 5959 return;
5914 5960
5915 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
5916 DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
5917 eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
5918 }
5919
5920 i = I915_READ(aud_cntl_st); 5961 i = I915_READ(aud_cntl_st);
5921 i &= ~GEN5_ELD_ADDRESS; 5962 i &= ~IBX_ELD_ADDRESS;
5922 I915_WRITE(aud_cntl_st, i); 5963 I915_WRITE(aud_cntl_st, i);
5923 5964
5924 len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ 5965 len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 92b041b66e49..db3b461ad412 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1926,6 +1926,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
1926 intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); 1926 intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
1927 } 1927 }
1928 1928
1929 DP &= ~DP_AUDIO_OUTPUT_ENABLE;
1929 I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); 1930 I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
1930 POSTING_READ(intel_dp->output_reg); 1931 POSTING_READ(intel_dp->output_reg);
1931 msleep(intel_dp->panel_power_down_delay); 1932 msleep(intel_dp->panel_power_down_delay);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index d4f5a0b2120d..64541f7ef900 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -269,6 +269,10 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
269 struct drm_i915_private *dev_priv = dev->dev_private; 269 struct drm_i915_private *dev_priv = dev->dev_private;
270 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); 270 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
271 u32 temp; 271 u32 temp;
272 u32 enable_bits = SDVO_ENABLE;
273
274 if (intel_hdmi->has_audio)
275 enable_bits |= SDVO_AUDIO_ENABLE;
272 276
273 temp = I915_READ(intel_hdmi->sdvox_reg); 277 temp = I915_READ(intel_hdmi->sdvox_reg);
274 278
@@ -281,9 +285,9 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
281 } 285 }
282 286
283 if (mode != DRM_MODE_DPMS_ON) { 287 if (mode != DRM_MODE_DPMS_ON) {
284 temp &= ~SDVO_ENABLE; 288 temp &= ~enable_bits;
285 } else { 289 } else {
286 temp |= SDVO_ENABLE; 290 temp |= enable_bits;
287 } 291 }
288 292
289 I915_WRITE(intel_hdmi->sdvox_reg, temp); 293 I915_WRITE(intel_hdmi->sdvox_reg, temp);