mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
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
This commit is contained in:
commit
2318fcd65c
@ -337,6 +337,8 @@ typedef struct drm_i915_private {
|
||||
struct timer_list hangcheck_timer;
|
||||
int hangcheck_count;
|
||||
uint32_t last_acthd;
|
||||
uint32_t last_acthd_bsd;
|
||||
uint32_t last_acthd_blt;
|
||||
uint32_t last_instdone;
|
||||
uint32_t last_instdone1;
|
||||
|
||||
|
@ -1669,7 +1669,7 @@ void i915_hangcheck_elapsed(unsigned long data)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *)data;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t acthd, instdone, instdone1;
|
||||
uint32_t acthd, instdone, instdone1, acthd_bsd, acthd_blt;
|
||||
bool err = false;
|
||||
|
||||
if (!i915_enable_hangcheck)
|
||||
@ -1686,16 +1686,21 @@ void i915_hangcheck_elapsed(unsigned long data)
|
||||
}
|
||||
|
||||
if (INTEL_INFO(dev)->gen < 4) {
|
||||
acthd = I915_READ(ACTHD);
|
||||
instdone = I915_READ(INSTDONE);
|
||||
instdone1 = 0;
|
||||
} else {
|
||||
acthd = I915_READ(ACTHD_I965);
|
||||
instdone = I915_READ(INSTDONE_I965);
|
||||
instdone1 = I915_READ(INSTDONE1);
|
||||
}
|
||||
acthd = intel_ring_get_active_head(&dev_priv->ring[RCS]);
|
||||
acthd_bsd = HAS_BSD(dev) ?
|
||||
intel_ring_get_active_head(&dev_priv->ring[VCS]) : 0;
|
||||
acthd_blt = HAS_BLT(dev) ?
|
||||
intel_ring_get_active_head(&dev_priv->ring[BCS]) : 0;
|
||||
|
||||
if (dev_priv->last_acthd == acthd &&
|
||||
dev_priv->last_acthd_bsd == acthd_bsd &&
|
||||
dev_priv->last_acthd_blt == acthd_blt &&
|
||||
dev_priv->last_instdone == instdone &&
|
||||
dev_priv->last_instdone1 == instdone1) {
|
||||
if (dev_priv->hangcheck_count++ > 1) {
|
||||
@ -1727,6 +1732,8 @@ void i915_hangcheck_elapsed(unsigned long data)
|
||||
dev_priv->hangcheck_count = 0;
|
||||
|
||||
dev_priv->last_acthd = acthd;
|
||||
dev_priv->last_acthd_bsd = acthd_bsd;
|
||||
dev_priv->last_acthd_blt = acthd_blt;
|
||||
dev_priv->last_instdone = instdone;
|
||||
dev_priv->last_instdone1 = instdone1;
|
||||
}
|
||||
|
@ -3570,17 +3570,17 @@
|
||||
#define G4X_ELD_ACK (1 << 4)
|
||||
#define G4X_HDMIW_HDMIEDID 0x6210C
|
||||
|
||||
#define GEN5_HDMIW_HDMIEDID_A 0xE2050
|
||||
#define GEN5_AUD_CNTL_ST_A 0xE20B4
|
||||
#define GEN5_ELD_BUFFER_SIZE (0x1f << 10)
|
||||
#define GEN5_ELD_ADDRESS (0x1f << 5)
|
||||
#define GEN5_ELD_ACK (1 << 4)
|
||||
#define GEN5_AUD_CNTL_ST2 0xE20C0
|
||||
#define GEN5_ELD_VALIDB (1 << 0)
|
||||
#define GEN5_CP_READYB (1 << 1)
|
||||
#define IBX_HDMIW_HDMIEDID_A 0xE2050
|
||||
#define IBX_AUD_CNTL_ST_A 0xE20B4
|
||||
#define IBX_ELD_BUFFER_SIZE (0x1f << 10)
|
||||
#define IBX_ELD_ADDRESS (0x1f << 5)
|
||||
#define IBX_ELD_ACK (1 << 4)
|
||||
#define IBX_AUD_CNTL_ST2 0xE20C0
|
||||
#define IBX_ELD_VALIDB (1 << 0)
|
||||
#define IBX_CP_READYB (1 << 1)
|
||||
|
||||
#define GEN7_HDMIW_HDMIEDID_A 0xE5050
|
||||
#define GEN7_AUD_CNTRL_ST_A 0xE50B4
|
||||
#define GEN7_AUD_CNTRL_ST2 0xE50C0
|
||||
#define CPT_HDMIW_HDMIEDID_A 0xE5050
|
||||
#define CPT_AUD_CNTL_ST_A 0xE50B4
|
||||
#define CPT_AUD_CNTRL_ST2 0xE50C0
|
||||
|
||||
#endif /* _I915_REG_H_ */
|
||||
|
@ -5830,6 +5830,35 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool intel_eld_uptodate(struct drm_connector *connector,
|
||||
int reg_eldv, uint32_t bits_eldv,
|
||||
int reg_elda, uint32_t bits_elda,
|
||||
int reg_edid)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = connector->dev->dev_private;
|
||||
uint8_t *eld = connector->eld;
|
||||
uint32_t i;
|
||||
|
||||
i = I915_READ(reg_eldv);
|
||||
i &= bits_eldv;
|
||||
|
||||
if (!eld[0])
|
||||
return !i;
|
||||
|
||||
if (!i)
|
||||
return false;
|
||||
|
||||
i = I915_READ(reg_elda);
|
||||
i &= ~bits_elda;
|
||||
I915_WRITE(reg_elda, i);
|
||||
|
||||
for (i = 0; i < eld[2]; i++)
|
||||
if (I915_READ(reg_edid) != *((uint32_t *)eld + i))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void g4x_write_eld(struct drm_connector *connector,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
@ -5846,6 +5875,12 @@ static void g4x_write_eld(struct drm_connector *connector,
|
||||
else
|
||||
eldv = G4X_ELDV_DEVCTG;
|
||||
|
||||
if (intel_eld_uptodate(connector,
|
||||
G4X_AUD_CNTL_ST, eldv,
|
||||
G4X_AUD_CNTL_ST, G4X_ELD_ADDR,
|
||||
G4X_HDMIW_HDMIEDID))
|
||||
return;
|
||||
|
||||
i = I915_READ(G4X_AUD_CNTL_ST);
|
||||
i &= ~(eldv | G4X_ELD_ADDR);
|
||||
len = (i >> 9) & 0x1f; /* ELD buffer size */
|
||||
@ -5876,14 +5911,14 @@ static void ironlake_write_eld(struct drm_connector *connector,
|
||||
int aud_cntl_st;
|
||||
int aud_cntrl_st2;
|
||||
|
||||
if (IS_IVYBRIDGE(connector->dev)) {
|
||||
hdmiw_hdmiedid = GEN7_HDMIW_HDMIEDID_A;
|
||||
aud_cntl_st = GEN7_AUD_CNTRL_ST_A;
|
||||
aud_cntrl_st2 = GEN7_AUD_CNTRL_ST2;
|
||||
if (HAS_PCH_IBX(connector->dev)) {
|
||||
hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A;
|
||||
aud_cntl_st = IBX_AUD_CNTL_ST_A;
|
||||
aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
|
||||
} else {
|
||||
hdmiw_hdmiedid = GEN5_HDMIW_HDMIEDID_A;
|
||||
aud_cntl_st = GEN5_AUD_CNTL_ST_A;
|
||||
aud_cntrl_st2 = GEN5_AUD_CNTL_ST2;
|
||||
hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A;
|
||||
aud_cntl_st = CPT_AUD_CNTL_ST_A;
|
||||
aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
|
||||
}
|
||||
|
||||
i = to_intel_crtc(crtc)->pipe;
|
||||
@ -5897,14 +5932,25 @@ static void ironlake_write_eld(struct drm_connector *connector,
|
||||
if (!i) {
|
||||
DRM_DEBUG_DRIVER("Audio directed to unknown port\n");
|
||||
/* operate blindly on all ports */
|
||||
eldv = GEN5_ELD_VALIDB;
|
||||
eldv |= GEN5_ELD_VALIDB << 4;
|
||||
eldv |= GEN5_ELD_VALIDB << 8;
|
||||
eldv = IBX_ELD_VALIDB;
|
||||
eldv |= IBX_ELD_VALIDB << 4;
|
||||
eldv |= IBX_ELD_VALIDB << 8;
|
||||
} else {
|
||||
DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i);
|
||||
eldv = GEN5_ELD_VALIDB << ((i - 1) * 4);
|
||||
eldv = IBX_ELD_VALIDB << ((i - 1) * 4);
|
||||
}
|
||||
|
||||
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
|
||||
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
|
||||
eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
|
||||
}
|
||||
|
||||
if (intel_eld_uptodate(connector,
|
||||
aud_cntrl_st2, eldv,
|
||||
aud_cntl_st, IBX_ELD_ADDRESS,
|
||||
hdmiw_hdmiedid))
|
||||
return;
|
||||
|
||||
i = I915_READ(aud_cntrl_st2);
|
||||
i &= ~eldv;
|
||||
I915_WRITE(aud_cntrl_st2, i);
|
||||
@ -5912,13 +5958,8 @@ static void ironlake_write_eld(struct drm_connector *connector,
|
||||
if (!eld[0])
|
||||
return;
|
||||
|
||||
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
|
||||
DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
|
||||
eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */
|
||||
}
|
||||
|
||||
i = I915_READ(aud_cntl_st);
|
||||
i &= ~GEN5_ELD_ADDRESS;
|
||||
i &= ~IBX_ELD_ADDRESS;
|
||||
I915_WRITE(aud_cntl_st, i);
|
||||
|
||||
len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */
|
||||
|
@ -1926,6 +1926,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
|
||||
intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
|
||||
}
|
||||
|
||||
DP &= ~DP_AUDIO_OUTPUT_ENABLE;
|
||||
I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
|
||||
POSTING_READ(intel_dp->output_reg);
|
||||
msleep(intel_dp->panel_power_down_delay);
|
||||
|
@ -269,6 +269,10 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
u32 temp;
|
||||
u32 enable_bits = SDVO_ENABLE;
|
||||
|
||||
if (intel_hdmi->has_audio)
|
||||
enable_bits |= SDVO_AUDIO_ENABLE;
|
||||
|
||||
temp = I915_READ(intel_hdmi->sdvox_reg);
|
||||
|
||||
@ -281,9 +285,9 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
|
||||
}
|
||||
|
||||
if (mode != DRM_MODE_DPMS_ON) {
|
||||
temp &= ~SDVO_ENABLE;
|
||||
temp &= ~enable_bits;
|
||||
} else {
|
||||
temp |= SDVO_ENABLE;
|
||||
temp |= enable_bits;
|
||||
}
|
||||
|
||||
I915_WRITE(intel_hdmi->sdvox_reg, temp);
|
||||
|
Loading…
Reference in New Issue
Block a user