forked from Minki/linux
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes
* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel: drm/i915: pch_irq_handler -> {ibx, cpt}_irq_handler char/agp: add another Ironlake host bridge drm/i915: fix up ivb plane 3 pageflips drm/i915: hold forcewake around ring hw init drm/i915: Mark the ringbuffers as being in the GTT domain drm/i915/crt: Do not rely upon the HPD presence pin drm/i915: Reset last_retired_head when resetting ring
This commit is contained in:
commit
6cf98d6ebb
@ -898,6 +898,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
|
||||
ID(PCI_DEVICE_ID_INTEL_B43_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_B43_1_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
|
||||
|
@ -212,6 +212,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30
|
||||
#define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32
|
||||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040
|
||||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB 0x0069
|
||||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042
|
||||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044
|
||||
#define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062
|
||||
|
@ -233,6 +233,7 @@ static const struct intel_device_info intel_sandybridge_d_info = {
|
||||
.has_blt_ring = 1,
|
||||
.has_llc = 1,
|
||||
.has_pch_split = 1,
|
||||
.has_force_wake = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_sandybridge_m_info = {
|
||||
@ -243,6 +244,7 @@ static const struct intel_device_info intel_sandybridge_m_info = {
|
||||
.has_blt_ring = 1,
|
||||
.has_llc = 1,
|
||||
.has_pch_split = 1,
|
||||
.has_force_wake = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ivybridge_d_info = {
|
||||
@ -252,6 +254,7 @@ static const struct intel_device_info intel_ivybridge_d_info = {
|
||||
.has_blt_ring = 1,
|
||||
.has_llc = 1,
|
||||
.has_pch_split = 1,
|
||||
.has_force_wake = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_ivybridge_m_info = {
|
||||
@ -262,6 +265,7 @@ static const struct intel_device_info intel_ivybridge_m_info = {
|
||||
.has_blt_ring = 1,
|
||||
.has_llc = 1,
|
||||
.has_pch_split = 1,
|
||||
.has_force_wake = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_valleyview_m_info = {
|
||||
@ -289,6 +293,7 @@ static const struct intel_device_info intel_haswell_d_info = {
|
||||
.has_blt_ring = 1,
|
||||
.has_llc = 1,
|
||||
.has_pch_split = 1,
|
||||
.has_force_wake = 1,
|
||||
};
|
||||
|
||||
static const struct intel_device_info intel_haswell_m_info = {
|
||||
@ -298,6 +303,7 @@ static const struct intel_device_info intel_haswell_m_info = {
|
||||
.has_blt_ring = 1,
|
||||
.has_llc = 1,
|
||||
.has_pch_split = 1,
|
||||
.has_force_wake = 1,
|
||||
};
|
||||
|
||||
static const struct pci_device_id pciidlist[] = { /* aka */
|
||||
@ -1139,10 +1145,9 @@ MODULE_LICENSE("GPL and additional rights");
|
||||
|
||||
/* We give fast paths for the really cool registers */
|
||||
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
|
||||
(((dev_priv)->info->gen >= 6) && \
|
||||
((reg) < 0x40000) && \
|
||||
((reg) != FORCEWAKE)) && \
|
||||
(!IS_VALLEYVIEW((dev_priv)->dev))
|
||||
((HAS_FORCE_WAKE((dev_priv)->dev)) && \
|
||||
((reg) < 0x40000) && \
|
||||
((reg) != FORCEWAKE))
|
||||
|
||||
#define __i915_read(x, y) \
|
||||
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
|
||||
|
@ -285,6 +285,7 @@ struct intel_device_info {
|
||||
u8 is_ivybridge:1;
|
||||
u8 is_valleyview:1;
|
||||
u8 has_pch_split:1;
|
||||
u8 has_force_wake:1;
|
||||
u8 is_haswell:1;
|
||||
u8 has_fbc:1;
|
||||
u8 has_pipe_cxsr:1;
|
||||
@ -1101,6 +1102,8 @@ struct drm_i915_file_private {
|
||||
#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
|
||||
#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
|
||||
|
||||
#define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)
|
||||
|
||||
#include "i915_trace.h"
|
||||
|
||||
/**
|
||||
|
@ -510,7 +510,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pch_irq_handler(struct drm_device *dev, u32 pch_iir)
|
||||
static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
int pipe;
|
||||
@ -550,6 +550,35 @@ static void pch_irq_handler(struct drm_device *dev, u32 pch_iir)
|
||||
DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
|
||||
}
|
||||
|
||||
static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
if (pch_iir & SDE_AUDIO_POWER_MASK_CPT)
|
||||
DRM_DEBUG_DRIVER("PCH audio power change on port %d\n",
|
||||
(pch_iir & SDE_AUDIO_POWER_MASK_CPT) >>
|
||||
SDE_AUDIO_POWER_SHIFT_CPT);
|
||||
|
||||
if (pch_iir & SDE_AUX_MASK_CPT)
|
||||
DRM_DEBUG_DRIVER("AUX channel interrupt\n");
|
||||
|
||||
if (pch_iir & SDE_GMBUS_CPT)
|
||||
DRM_DEBUG_DRIVER("PCH GMBUS interrupt\n");
|
||||
|
||||
if (pch_iir & SDE_AUDIO_CP_REQ_CPT)
|
||||
DRM_DEBUG_DRIVER("Audio CP request interrupt\n");
|
||||
|
||||
if (pch_iir & SDE_AUDIO_CP_CHG_CPT)
|
||||
DRM_DEBUG_DRIVER("Audio CP change interrupt\n");
|
||||
|
||||
if (pch_iir & SDE_FDI_MASK_CPT)
|
||||
for_each_pipe(pipe)
|
||||
DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n",
|
||||
pipe_name(pipe),
|
||||
I915_READ(FDI_RX_IIR(pipe)));
|
||||
}
|
||||
|
||||
static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *) arg;
|
||||
@ -591,7 +620,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
|
||||
|
||||
if (pch_iir & SDE_HOTPLUG_MASK_CPT)
|
||||
queue_work(dev_priv->wq, &dev_priv->hotplug_work);
|
||||
pch_irq_handler(dev, pch_iir);
|
||||
cpt_irq_handler(dev, pch_iir);
|
||||
|
||||
/* clear PCH hotplug event before clear CPU irq */
|
||||
I915_WRITE(SDEIIR, pch_iir);
|
||||
@ -684,7 +713,10 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
|
||||
if (de_iir & DE_PCH_EVENT) {
|
||||
if (pch_iir & hotplug_mask)
|
||||
queue_work(dev_priv->wq, &dev_priv->hotplug_work);
|
||||
pch_irq_handler(dev, pch_iir);
|
||||
if (HAS_PCH_CPT(dev))
|
||||
cpt_irq_handler(dev, pch_iir);
|
||||
else
|
||||
ibx_irq_handler(dev, pch_iir);
|
||||
}
|
||||
|
||||
if (de_iir & DE_PCU_EVENT) {
|
||||
|
@ -210,6 +210,14 @@
|
||||
#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
|
||||
#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1)
|
||||
#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
|
||||
/* IVB has funny definitions for which plane to flip. */
|
||||
#define MI_DISPLAY_FLIP_IVB_PLANE_A (0 << 19)
|
||||
#define MI_DISPLAY_FLIP_IVB_PLANE_B (1 << 19)
|
||||
#define MI_DISPLAY_FLIP_IVB_SPRITE_A (2 << 19)
|
||||
#define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
|
||||
#define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19)
|
||||
#define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
|
||||
|
||||
#define MI_SET_CONTEXT MI_INSTR(0x18, 0)
|
||||
#define MI_MM_SPACE_GTT (1<<8)
|
||||
#define MI_MM_SPACE_PHYSICAL (0<<8)
|
||||
@ -3313,7 +3321,7 @@
|
||||
|
||||
/* PCH */
|
||||
|
||||
/* south display engine interrupt */
|
||||
/* south display engine interrupt: IBX */
|
||||
#define SDE_AUDIO_POWER_D (1 << 27)
|
||||
#define SDE_AUDIO_POWER_C (1 << 26)
|
||||
#define SDE_AUDIO_POWER_B (1 << 25)
|
||||
@ -3349,15 +3357,44 @@
|
||||
#define SDE_TRANSA_CRC_ERR (1 << 1)
|
||||
#define SDE_TRANSA_FIFO_UNDER (1 << 0)
|
||||
#define SDE_TRANS_MASK (0x3f)
|
||||
/* CPT */
|
||||
#define SDE_CRT_HOTPLUG_CPT (1 << 19)
|
||||
|
||||
/* south display engine interrupt: CPT/PPT */
|
||||
#define SDE_AUDIO_POWER_D_CPT (1 << 31)
|
||||
#define SDE_AUDIO_POWER_C_CPT (1 << 30)
|
||||
#define SDE_AUDIO_POWER_B_CPT (1 << 29)
|
||||
#define SDE_AUDIO_POWER_SHIFT_CPT 29
|
||||
#define SDE_AUDIO_POWER_MASK_CPT (7 << 29)
|
||||
#define SDE_AUXD_CPT (1 << 27)
|
||||
#define SDE_AUXC_CPT (1 << 26)
|
||||
#define SDE_AUXB_CPT (1 << 25)
|
||||
#define SDE_AUX_MASK_CPT (7 << 25)
|
||||
#define SDE_PORTD_HOTPLUG_CPT (1 << 23)
|
||||
#define SDE_PORTC_HOTPLUG_CPT (1 << 22)
|
||||
#define SDE_PORTB_HOTPLUG_CPT (1 << 21)
|
||||
#define SDE_CRT_HOTPLUG_CPT (1 << 19)
|
||||
#define SDE_HOTPLUG_MASK_CPT (SDE_CRT_HOTPLUG_CPT | \
|
||||
SDE_PORTD_HOTPLUG_CPT | \
|
||||
SDE_PORTC_HOTPLUG_CPT | \
|
||||
SDE_PORTB_HOTPLUG_CPT)
|
||||
#define SDE_GMBUS_CPT (1 << 17)
|
||||
#define SDE_AUDIO_CP_REQ_C_CPT (1 << 10)
|
||||
#define SDE_AUDIO_CP_CHG_C_CPT (1 << 9)
|
||||
#define SDE_FDI_RXC_CPT (1 << 8)
|
||||
#define SDE_AUDIO_CP_REQ_B_CPT (1 << 6)
|
||||
#define SDE_AUDIO_CP_CHG_B_CPT (1 << 5)
|
||||
#define SDE_FDI_RXB_CPT (1 << 4)
|
||||
#define SDE_AUDIO_CP_REQ_A_CPT (1 << 2)
|
||||
#define SDE_AUDIO_CP_CHG_A_CPT (1 << 1)
|
||||
#define SDE_FDI_RXA_CPT (1 << 0)
|
||||
#define SDE_AUDIO_CP_REQ_CPT (SDE_AUDIO_CP_REQ_C_CPT | \
|
||||
SDE_AUDIO_CP_REQ_B_CPT | \
|
||||
SDE_AUDIO_CP_REQ_A_CPT)
|
||||
#define SDE_AUDIO_CP_CHG_CPT (SDE_AUDIO_CP_CHG_C_CPT | \
|
||||
SDE_AUDIO_CP_CHG_B_CPT | \
|
||||
SDE_AUDIO_CP_CHG_A_CPT)
|
||||
#define SDE_FDI_MASK_CPT (SDE_FDI_RXC_CPT | \
|
||||
SDE_FDI_RXB_CPT | \
|
||||
SDE_FDI_RXA_CPT)
|
||||
|
||||
#define SDEISR 0xc4000
|
||||
#define SDEIMR 0xc4004
|
||||
|
@ -453,13 +453,15 @@ intel_crt_detect(struct drm_connector *connector, bool force)
|
||||
struct intel_load_detect_pipe tmp;
|
||||
|
||||
if (I915_HAS_HOTPLUG(dev)) {
|
||||
/* We can not rely on the HPD pin always being correctly wired
|
||||
* up, for example many KVM do not pass it through, and so
|
||||
* only trust an assertion that the monitor is connected.
|
||||
*/
|
||||
if (intel_crt_detect_hotplug(connector)) {
|
||||
DRM_DEBUG_KMS("CRT detected via hotplug\n");
|
||||
return connector_status_connected;
|
||||
} else {
|
||||
} else
|
||||
DRM_DEBUG_KMS("CRT not detected via hotplug\n");
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
}
|
||||
|
||||
if (intel_crt_detect_ddc(connector))
|
||||
|
@ -6158,17 +6158,34 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_ring_buffer *ring = &dev_priv->ring[BCS];
|
||||
uint32_t plane_bit = 0;
|
||||
int ret;
|
||||
|
||||
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
switch(intel_crtc->plane) {
|
||||
case PLANE_A:
|
||||
plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
|
||||
break;
|
||||
case PLANE_B:
|
||||
plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
|
||||
break;
|
||||
case PLANE_C:
|
||||
plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "unknown plane in flip command\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = intel_ring_begin(ring, 4);
|
||||
if (ret)
|
||||
goto err_unpin;
|
||||
|
||||
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19));
|
||||
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
|
||||
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
|
||||
intel_ring_emit(ring, (obj->gtt_offset));
|
||||
intel_ring_emit(ring, (MI_NOOP));
|
||||
|
@ -266,10 +266,15 @@ u32 intel_ring_get_active_head(struct intel_ring_buffer *ring)
|
||||
|
||||
static int init_ring_common(struct intel_ring_buffer *ring)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = ring->dev->dev_private;
|
||||
struct drm_device *dev = ring->dev;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_object *obj = ring->obj;
|
||||
int ret = 0;
|
||||
u32 head;
|
||||
|
||||
if (HAS_FORCE_WAKE(dev))
|
||||
gen6_gt_force_wake_get(dev_priv);
|
||||
|
||||
/* Stop the ring if it's running. */
|
||||
I915_WRITE_CTL(ring, 0);
|
||||
I915_WRITE_HEAD(ring, 0);
|
||||
@ -317,7 +322,8 @@ static int init_ring_common(struct intel_ring_buffer *ring)
|
||||
I915_READ_HEAD(ring),
|
||||
I915_READ_TAIL(ring),
|
||||
I915_READ_START(ring));
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!drm_core_check_feature(ring->dev, DRIVER_MODESET))
|
||||
@ -326,9 +332,14 @@ static int init_ring_common(struct intel_ring_buffer *ring)
|
||||
ring->head = I915_READ_HEAD(ring);
|
||||
ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
|
||||
ring->space = ring_space(ring);
|
||||
ring->last_retired_head = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (HAS_FORCE_WAKE(dev))
|
||||
gen6_gt_force_wake_put(dev_priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -987,6 +998,10 @@ static int intel_init_ring_buffer(struct drm_device *dev,
|
||||
if (ret)
|
||||
goto err_unref;
|
||||
|
||||
ret = i915_gem_object_set_to_gtt_domain(obj, true);
|
||||
if (ret)
|
||||
goto err_unpin;
|
||||
|
||||
ring->virtual_start = ioremap_wc(dev->agp->base + obj->gtt_offset,
|
||||
ring->size);
|
||||
if (ring->virtual_start == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user