Merge remote branch 'anholt/drm-intel-next' into drm-linus

This merges the upstream Intel tree and fixes up numerous conflicts
due to patches merged into Linus tree later in -rc cycle.

Conflicts:
	drivers/char/agp/intel-agp.c
	drivers/gpu/drm/drm_dp_i2c_helper.c
	drivers/gpu/drm/i915/i915_irq.c
	drivers/gpu/drm/i915/i915_suspend.c
This commit is contained in:
Dave Airlie 2009-12-08 14:03:47 +10:00
commit 3ff99164f6
38 changed files with 3406 additions and 830 deletions

View file

@ -36,10 +36,10 @@
#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 #define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC #define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE #define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
#define PCI_DEVICE_ID_INTEL_IGDGM_HB 0xA010 #define PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB 0xA010
#define PCI_DEVICE_ID_INTEL_IGDGM_IG 0xA011 #define PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG 0xA011
#define PCI_DEVICE_ID_INTEL_IGDG_HB 0xA000 #define PCI_DEVICE_ID_INTEL_PINEVIEW_HB 0xA000
#define PCI_DEVICE_ID_INTEL_IGDG_IG 0xA001 #define PCI_DEVICE_ID_INTEL_PINEVIEW_IG 0xA001
#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 #define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 #define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0 #define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0
@ -50,20 +50,20 @@
#define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 #define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42
#define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40
#define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42
#define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00 #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00
#define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02 #define PCI_DEVICE_ID_INTEL_EAGLELAKE_IG 0x2E02
#define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10 #define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10
#define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12 #define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12
#define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20 #define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20
#define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22 #define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22
#define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30
#define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32
#define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040 #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040
#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042
#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044
#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062
#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a
#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046
/* cover 915 and 945 variants */ /* cover 915 and 945 variants */
#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
@ -83,22 +83,22 @@
#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB) agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
#define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \ #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB) agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB)
#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB) agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB)
extern int agp_memory_reserved; extern int agp_memory_reserved;
@ -653,7 +653,7 @@ static void intel_i830_init_gtt_entries(void)
size = 512; size = 512;
} }
size += 4; /* add in BIOS popup space */ size += 4; /* add in BIOS popup space */
} else if (IS_G33 && !IS_IGD) { } else if (IS_G33 && !IS_PINEVIEW) {
/* G33's GTT size defined in gmch_ctrl */ /* G33's GTT size defined in gmch_ctrl */
switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
case G33_PGETBL_SIZE_1M: case G33_PGETBL_SIZE_1M:
@ -669,7 +669,7 @@ static void intel_i830_init_gtt_entries(void)
size = 512; size = 512;
} }
size += 4; size += 4;
} else if (IS_G4X || IS_IGD) { } else if (IS_G4X || IS_PINEVIEW) {
/* On 4 series hardware, GTT stolen is separate from graphics /* On 4 series hardware, GTT stolen is separate from graphics
* stolen, ignore it in stolen gtt entries counting. However, * stolen, ignore it in stolen gtt entries counting. However,
* 4KB of the stolen memory doesn't get mapped to the GTT. * 4KB of the stolen memory doesn't get mapped to the GTT.
@ -1352,15 +1352,15 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
{ {
switch (agp_bridge->dev->device) { switch (agp_bridge->dev->device) {
case PCI_DEVICE_ID_INTEL_GM45_HB: case PCI_DEVICE_ID_INTEL_GM45_HB:
case PCI_DEVICE_ID_INTEL_IGD_E_HB: case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB:
case PCI_DEVICE_ID_INTEL_Q45_HB: case PCI_DEVICE_ID_INTEL_Q45_HB:
case PCI_DEVICE_ID_INTEL_G45_HB: case PCI_DEVICE_ID_INTEL_G45_HB:
case PCI_DEVICE_ID_INTEL_G41_HB: case PCI_DEVICE_ID_INTEL_G41_HB:
case PCI_DEVICE_ID_INTEL_B43_HB: case PCI_DEVICE_ID_INTEL_B43_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: case PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB: case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB:
*gtt_offset = *gtt_size = MB(2); *gtt_offset = *gtt_size = MB(2);
break; break;
default: default:
@ -2340,14 +2340,14 @@ static const struct intel_driver_description {
NULL, &intel_g33_driver }, NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
NULL, &intel_g33_driver }, NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD", { PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "Pineview",
NULL, &intel_g33_driver }, NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD", { PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "Pineview",
NULL, &intel_g33_driver }, NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
"Mobile Intel® GM45 Express", NULL, &intel_i965_driver }, "GM45", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0, { PCI_DEVICE_ID_INTEL_EAGLELAKE_HB, PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, 0,
"Intel Integrated Graphics Device", NULL, &intel_i965_driver }, "Eaglelake", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0, { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0,
"Q45/Q43", NULL, &intel_i965_driver }, "Q45/Q43", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0, { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0,
@ -2356,14 +2356,14 @@ static const struct intel_driver_description {
"B43", NULL, &intel_i965_driver }, "B43", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0,
"G41", NULL, &intel_i965_driver }, "G41", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_D_HB, PCI_DEVICE_ID_INTEL_IGDNG_D_IG, 0, { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0,
"IGDNG/D", NULL, &intel_i965_driver }, "Ironlake/D", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, { PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
"IGDNG/M", NULL, &intel_i965_driver }, "Ironlake/M", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, { PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
"IGDNG/MA", NULL, &intel_i965_driver }, "Ironlake/MA", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0,
"IGDNG/MC2", NULL, &intel_i965_driver }, "Ironlake/MC2", NULL, &intel_i965_driver },
{ 0, 0, 0, NULL, NULL, NULL } { 0, 0, 0, NULL, NULL, NULL }
}; };
@ -2545,8 +2545,8 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82945G_HB), ID(PCI_DEVICE_ID_INTEL_82945G_HB),
ID(PCI_DEVICE_ID_INTEL_82945GM_HB), ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
ID(PCI_DEVICE_ID_INTEL_82945GME_HB), ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
ID(PCI_DEVICE_ID_INTEL_IGDGM_HB), ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
ID(PCI_DEVICE_ID_INTEL_IGDG_HB), ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
ID(PCI_DEVICE_ID_INTEL_82G35_HB), ID(PCI_DEVICE_ID_INTEL_82G35_HB),
ID(PCI_DEVICE_ID_INTEL_82965Q_HB), ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
@ -2557,15 +2557,15 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_Q35_HB), ID(PCI_DEVICE_ID_INTEL_Q35_HB),
ID(PCI_DEVICE_ID_INTEL_Q33_HB), ID(PCI_DEVICE_ID_INTEL_Q33_HB),
ID(PCI_DEVICE_ID_INTEL_GM45_HB), ID(PCI_DEVICE_ID_INTEL_GM45_HB),
ID(PCI_DEVICE_ID_INTEL_IGD_E_HB), ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
ID(PCI_DEVICE_ID_INTEL_Q45_HB), ID(PCI_DEVICE_ID_INTEL_Q45_HB),
ID(PCI_DEVICE_ID_INTEL_G45_HB), ID(PCI_DEVICE_ID_INTEL_G45_HB),
ID(PCI_DEVICE_ID_INTEL_G41_HB), ID(PCI_DEVICE_ID_INTEL_G41_HB),
ID(PCI_DEVICE_ID_INTEL_B43_HB), ID(PCI_DEVICE_ID_INTEL_B43_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
{ } { }
}; };

View file

@ -256,7 +256,8 @@ static void drm_mode_object_put(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex); mutex_unlock(&dev->mode_config.idr_mutex);
} }
void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
uint32_t id, uint32_t type)
{ {
struct drm_mode_object *obj = NULL; struct drm_mode_object *obj = NULL;
@ -2630,7 +2631,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out; goto out;
} }
e->event.base.type = DRM_EVENT_VBLANK; e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
e->event.base.length = sizeof e->event; e->event.base.length = sizeof e->event;
e->event.user_data = page_flip->user_data; e->event.user_data = page_flip->user_data;
e->base.event = &e->event.base; e->base.event = &e->event.base;

View file

@ -160,7 +160,7 @@ i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
if (ret >= 0) if (ret >= 0)
ret = num; ret = num;
i2c_algo_dp_aux_stop(adapter, reading); i2c_algo_dp_aux_stop(adapter, reading);
DRM_DEBUG("dp_aux_xfer return %d\n", ret); DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
return ret; return ret;
} }

View file

@ -429,15 +429,21 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */ /* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
!dev->vblank_enabled[crtc]) { if (!dev->vblank_enabled[crtc]) {
ret = dev->driver->enable_vblank(dev, crtc); ret = dev->driver->enable_vblank(dev, crtc);
DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
if (ret) if (ret)
atomic_dec(&dev->vblank_refcount[crtc]);
else {
dev->vblank_enabled[crtc] = 1;
drm_update_vblank_count(dev, crtc);
}
}
} else {
if (!dev->vblank_enabled[crtc]) {
atomic_dec(&dev->vblank_refcount[crtc]); atomic_dec(&dev->vblank_refcount[crtc]);
else { ret = -EINVAL;
dev->vblank_enabled[crtc] = 1;
drm_update_vblank_count(dev, crtc);
} }
} }
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@ -464,6 +470,18 @@ void drm_vblank_put(struct drm_device *dev, int crtc)
} }
EXPORT_SYMBOL(drm_vblank_put); EXPORT_SYMBOL(drm_vblank_put);
void drm_vblank_off(struct drm_device *dev, int crtc)
{
unsigned long irqflags;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
DRM_WAKEUP(&dev->vbl_queue[crtc]);
dev->vblank_enabled[crtc] = 0;
dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
EXPORT_SYMBOL(drm_vblank_off);
/** /**
* drm_vblank_pre_modeset - account for vblanks across mode sets * drm_vblank_pre_modeset - account for vblanks across mode sets
* @dev: DRM device * @dev: DRM device

View file

@ -22,6 +22,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
intel_fb.o \ intel_fb.o \
intel_tv.o \ intel_tv.o \
intel_dvo.o \ intel_dvo.o \
intel_overlay.o \
dvo_ch7xxx.o \ dvo_ch7xxx.o \
dvo_ch7017.o \ dvo_ch7017.o \
dvo_ivch.o \ dvo_ivch.o \

View file

@ -249,7 +249,8 @@ static bool ch7017_init(struct intel_dvo_device *dvo,
if (val != CH7017_DEVICE_ID_VALUE && if (val != CH7017_DEVICE_ID_VALUE &&
val != CH7018_DEVICE_ID_VALUE && val != CH7018_DEVICE_ID_VALUE &&
val != CH7019_DEVICE_ID_VALUE) { val != CH7019_DEVICE_ID_VALUE) {
DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n", DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
"Slave %d.\n",
val, i2cbus->adapter.name,dvo->slave_addr); val, i2cbus->adapter.name,dvo->slave_addr);
goto fail; goto fail;
} }
@ -284,7 +285,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
uint8_t horizontal_active_pixel_output, vertical_active_line_output; uint8_t horizontal_active_pixel_output, vertical_active_line_output;
uint8_t active_input_line_output; uint8_t active_input_line_output;
DRM_DEBUG("Registers before mode setting\n"); DRM_DEBUG_KMS("Registers before mode setting\n");
ch7017_dump_regs(dvo); ch7017_dump_regs(dvo);
/* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/ /* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/
@ -346,7 +347,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
/* Turn the LVDS back on with new settings. */ /* Turn the LVDS back on with new settings. */
ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down); ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down);
DRM_DEBUG("Registers after mode setting\n"); DRM_DEBUG_KMS("Registers after mode setting\n");
ch7017_dump_regs(dvo); ch7017_dump_regs(dvo);
} }
@ -386,7 +387,7 @@ static void ch7017_dump_regs(struct intel_dvo_device *dvo)
#define DUMP(reg) \ #define DUMP(reg) \
do { \ do { \
ch7017_read(dvo, reg, &val); \ ch7017_read(dvo, reg, &val); \
DRM_DEBUG(#reg ": %02x\n", val); \ DRM_DEBUG_KMS(#reg ": %02x\n", val); \
} while (0) } while (0)
DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT); DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT);

View file

@ -152,7 +152,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
}; };
if (!ch7xxx->quiet) { if (!ch7xxx->quiet) {
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
return false; return false;
@ -179,7 +179,7 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
return true; return true;
if (!ch7xxx->quiet) { if (!ch7xxx->quiet) {
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
@ -207,7 +207,8 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo,
name = ch7xxx_get_id(vendor); name = ch7xxx_get_id(vendor);
if (!name) { if (!name) {
DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
"slave %d.\n",
vendor, adapter->name, dvo->slave_addr); vendor, adapter->name, dvo->slave_addr);
goto out; goto out;
} }
@ -217,13 +218,14 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo,
goto out; goto out;
if (device != CH7xxx_DID) { if (device != CH7xxx_DID) {
DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
"slave %d.\n",
vendor, adapter->name, dvo->slave_addr); vendor, adapter->name, dvo->slave_addr);
goto out; goto out;
} }
ch7xxx->quiet = false; ch7xxx->quiet = false;
DRM_DEBUG("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n", DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
name, vendor, device); name, vendor, device);
return true; return true;
out: out:
@ -315,8 +317,8 @@ static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
for (i = 0; i < CH7xxx_NUM_REGS; i++) { for (i = 0; i < CH7xxx_NUM_REGS; i++) {
if ((i % 8) == 0 ) if ((i % 8) == 0 )
DRM_DEBUG("\n %02X: ", i); DRM_LOG_KMS("\n %02X: ", i);
DRM_DEBUG("%02X ", ch7xxx->mode_reg.regs[i]); DRM_LOG_KMS("%02X ", ch7xxx->mode_reg.regs[i]);
} }
} }

View file

@ -202,7 +202,8 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
}; };
if (!priv->quiet) { if (!priv->quiet) {
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", DRM_DEBUG_KMS("Unable to read register 0x%02x from "
"%s:%02x.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
return false; return false;
@ -230,7 +231,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
return true; return true;
if (!priv->quiet) { if (!priv->quiet) {
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
@ -261,7 +262,7 @@ static bool ivch_init(struct intel_dvo_device *dvo,
* the address it's responding on. * the address it's responding on.
*/ */
if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->slave_addr) { if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->slave_addr) {
DRM_DEBUG("ivch detect failed due to address mismatch " DRM_DEBUG_KMS("ivch detect failed due to address mismatch "
"(%d vs %d)\n", "(%d vs %d)\n",
(temp & VR00_BASE_ADDRESS_MASK), dvo->slave_addr); (temp & VR00_BASE_ADDRESS_MASK), dvo->slave_addr);
goto out; goto out;
@ -367,41 +368,41 @@ static void ivch_dump_regs(struct intel_dvo_device *dvo)
uint16_t val; uint16_t val;
ivch_read(dvo, VR00, &val); ivch_read(dvo, VR00, &val);
DRM_DEBUG("VR00: 0x%04x\n", val); DRM_LOG_KMS("VR00: 0x%04x\n", val);
ivch_read(dvo, VR01, &val); ivch_read(dvo, VR01, &val);
DRM_DEBUG("VR01: 0x%04x\n", val); DRM_LOG_KMS("VR01: 0x%04x\n", val);
ivch_read(dvo, VR30, &val); ivch_read(dvo, VR30, &val);
DRM_DEBUG("VR30: 0x%04x\n", val); DRM_LOG_KMS("VR30: 0x%04x\n", val);
ivch_read(dvo, VR40, &val); ivch_read(dvo, VR40, &val);
DRM_DEBUG("VR40: 0x%04x\n", val); DRM_LOG_KMS("VR40: 0x%04x\n", val);
/* GPIO registers */ /* GPIO registers */
ivch_read(dvo, VR80, &val); ivch_read(dvo, VR80, &val);
DRM_DEBUG("VR80: 0x%04x\n", val); DRM_LOG_KMS("VR80: 0x%04x\n", val);
ivch_read(dvo, VR81, &val); ivch_read(dvo, VR81, &val);
DRM_DEBUG("VR81: 0x%04x\n", val); DRM_LOG_KMS("VR81: 0x%04x\n", val);
ivch_read(dvo, VR82, &val); ivch_read(dvo, VR82, &val);
DRM_DEBUG("VR82: 0x%04x\n", val); DRM_LOG_KMS("VR82: 0x%04x\n", val);
ivch_read(dvo, VR83, &val); ivch_read(dvo, VR83, &val);
DRM_DEBUG("VR83: 0x%04x\n", val); DRM_LOG_KMS("VR83: 0x%04x\n", val);
ivch_read(dvo, VR84, &val); ivch_read(dvo, VR84, &val);
DRM_DEBUG("VR84: 0x%04x\n", val); DRM_LOG_KMS("VR84: 0x%04x\n", val);
ivch_read(dvo, VR85, &val); ivch_read(dvo, VR85, &val);
DRM_DEBUG("VR85: 0x%04x\n", val); DRM_LOG_KMS("VR85: 0x%04x\n", val);
ivch_read(dvo, VR86, &val); ivch_read(dvo, VR86, &val);
DRM_DEBUG("VR86: 0x%04x\n", val); DRM_LOG_KMS("VR86: 0x%04x\n", val);
ivch_read(dvo, VR87, &val); ivch_read(dvo, VR87, &val);
DRM_DEBUG("VR87: 0x%04x\n", val); DRM_LOG_KMS("VR87: 0x%04x\n", val);
ivch_read(dvo, VR88, &val); ivch_read(dvo, VR88, &val);
DRM_DEBUG("VR88: 0x%04x\n", val); DRM_LOG_KMS("VR88: 0x%04x\n", val);
/* Scratch register 0 - AIM Panel type */ /* Scratch register 0 - AIM Panel type */
ivch_read(dvo, VR8E, &val); ivch_read(dvo, VR8E, &val);
DRM_DEBUG("VR8E: 0x%04x\n", val); DRM_LOG_KMS("VR8E: 0x%04x\n", val);
/* Scratch register 1 - Status register */ /* Scratch register 1 - Status register */
ivch_read(dvo, VR8F, &val); ivch_read(dvo, VR8F, &val);
DRM_DEBUG("VR8F: 0x%04x\n", val); DRM_LOG_KMS("VR8F: 0x%04x\n", val);
} }
static void ivch_save(struct intel_dvo_device *dvo) static void ivch_save(struct intel_dvo_device *dvo)

View file

@ -105,7 +105,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
}; };
if (!sil->quiet) { if (!sil->quiet) {
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
return false; return false;
@ -131,7 +131,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
return true; return true;
if (!sil->quiet) { if (!sil->quiet) {
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
@ -158,7 +158,7 @@ static bool sil164_init(struct intel_dvo_device *dvo,
goto out; goto out;
if (ch != (SIL164_VID & 0xff)) { if (ch != (SIL164_VID & 0xff)) {
DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
ch, adapter->name, dvo->slave_addr); ch, adapter->name, dvo->slave_addr);
goto out; goto out;
} }
@ -167,13 +167,13 @@ static bool sil164_init(struct intel_dvo_device *dvo,
goto out; goto out;
if (ch != (SIL164_DID & 0xff)) { if (ch != (SIL164_DID & 0xff)) {
DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n",
ch, adapter->name, dvo->slave_addr); ch, adapter->name, dvo->slave_addr);
goto out; goto out;
} }
sil->quiet = false; sil->quiet = false;
DRM_DEBUG("init sil164 dvo controller successfully!\n"); DRM_DEBUG_KMS("init sil164 dvo controller successfully!\n");
return true; return true;
out: out:
@ -241,15 +241,15 @@ static void sil164_dump_regs(struct intel_dvo_device *dvo)
uint8_t val; uint8_t val;
sil164_readb(dvo, SIL164_FREQ_LO, &val); sil164_readb(dvo, SIL164_FREQ_LO, &val);
DRM_DEBUG("SIL164_FREQ_LO: 0x%02x\n", val); DRM_LOG_KMS("SIL164_FREQ_LO: 0x%02x\n", val);
sil164_readb(dvo, SIL164_FREQ_HI, &val); sil164_readb(dvo, SIL164_FREQ_HI, &val);
DRM_DEBUG("SIL164_FREQ_HI: 0x%02x\n", val); DRM_LOG_KMS("SIL164_FREQ_HI: 0x%02x\n", val);
sil164_readb(dvo, SIL164_REG8, &val); sil164_readb(dvo, SIL164_REG8, &val);
DRM_DEBUG("SIL164_REG8: 0x%02x\n", val); DRM_LOG_KMS("SIL164_REG8: 0x%02x\n", val);
sil164_readb(dvo, SIL164_REG9, &val); sil164_readb(dvo, SIL164_REG9, &val);
DRM_DEBUG("SIL164_REG9: 0x%02x\n", val); DRM_LOG_KMS("SIL164_REG9: 0x%02x\n", val);
sil164_readb(dvo, SIL164_REGC, &val); sil164_readb(dvo, SIL164_REGC, &val);
DRM_DEBUG("SIL164_REGC: 0x%02x\n", val); DRM_LOG_KMS("SIL164_REGC: 0x%02x\n", val);
} }
static void sil164_save(struct intel_dvo_device *dvo) static void sil164_save(struct intel_dvo_device *dvo)

View file

@ -130,7 +130,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
}; };
if (!tfp->quiet) { if (!tfp->quiet) {
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
return false; return false;
@ -156,7 +156,7 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
return true; return true;
if (!tfp->quiet) { if (!tfp->quiet) {
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
addr, i2cbus->adapter.name, dvo->slave_addr); addr, i2cbus->adapter.name, dvo->slave_addr);
} }
@ -191,13 +191,15 @@ static bool tfp410_init(struct intel_dvo_device *dvo,
tfp->quiet = true; tfp->quiet = true;
if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n", DRM_DEBUG_KMS("tfp410 not detected got VID %X: from %s "
"Slave %d.\n",
id, adapter->name, dvo->slave_addr); id, adapter->name, dvo->slave_addr);
goto out; goto out;
} }
if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n", DRM_DEBUG_KMS("tfp410 not detected got DID %X: from %s "
"Slave %d.\n",
id, adapter->name, dvo->slave_addr); id, adapter->name, dvo->slave_addr);
goto out; goto out;
} }
@ -262,33 +264,33 @@ static void tfp410_dump_regs(struct intel_dvo_device *dvo)
uint8_t val, val2; uint8_t val, val2;
tfp410_readb(dvo, TFP410_REV, &val); tfp410_readb(dvo, TFP410_REV, &val);
DRM_DEBUG("TFP410_REV: 0x%02X\n", val); DRM_LOG_KMS("TFP410_REV: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_CTL_1, &val); tfp410_readb(dvo, TFP410_CTL_1, &val);
DRM_DEBUG("TFP410_CTL1: 0x%02X\n", val); DRM_LOG_KMS("TFP410_CTL1: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_CTL_2, &val); tfp410_readb(dvo, TFP410_CTL_2, &val);
DRM_DEBUG("TFP410_CTL2: 0x%02X\n", val); DRM_LOG_KMS("TFP410_CTL2: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_CTL_3, &val); tfp410_readb(dvo, TFP410_CTL_3, &val);
DRM_DEBUG("TFP410_CTL3: 0x%02X\n", val); DRM_LOG_KMS("TFP410_CTL3: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_USERCFG, &val); tfp410_readb(dvo, TFP410_USERCFG, &val);
DRM_DEBUG("TFP410_USERCFG: 0x%02X\n", val); DRM_LOG_KMS("TFP410_USERCFG: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_DE_DLY, &val); tfp410_readb(dvo, TFP410_DE_DLY, &val);
DRM_DEBUG("TFP410_DE_DLY: 0x%02X\n", val); DRM_LOG_KMS("TFP410_DE_DLY: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_DE_CTL, &val); tfp410_readb(dvo, TFP410_DE_CTL, &val);
DRM_DEBUG("TFP410_DE_CTL: 0x%02X\n", val); DRM_LOG_KMS("TFP410_DE_CTL: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_DE_TOP, &val); tfp410_readb(dvo, TFP410_DE_TOP, &val);
DRM_DEBUG("TFP410_DE_TOP: 0x%02X\n", val); DRM_LOG_KMS("TFP410_DE_TOP: 0x%02X\n", val);
tfp410_readb(dvo, TFP410_DE_CNT_LO, &val); tfp410_readb(dvo, TFP410_DE_CNT_LO, &val);
tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2); tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2);
DRM_DEBUG("TFP410_DE_CNT: 0x%02X%02X\n", val2, val); DRM_LOG_KMS("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
tfp410_readb(dvo, TFP410_DE_LIN_LO, &val); tfp410_readb(dvo, TFP410_DE_LIN_LO, &val);
tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2); tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2);
DRM_DEBUG("TFP410_DE_LIN: 0x%02X%02X\n", val2, val); DRM_LOG_KMS("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
tfp410_readb(dvo, TFP410_H_RES_LO, &val); tfp410_readb(dvo, TFP410_H_RES_LO, &val);
tfp410_readb(dvo, TFP410_H_RES_HI, &val2); tfp410_readb(dvo, TFP410_H_RES_HI, &val2);
DRM_DEBUG("TFP410_H_RES: 0x%02X%02X\n", val2, val); DRM_LOG_KMS("TFP410_H_RES: 0x%02X%02X\n", val2, val);
tfp410_readb(dvo, TFP410_V_RES_LO, &val); tfp410_readb(dvo, TFP410_V_RES_LO, &val);
tfp410_readb(dvo, TFP410_V_RES_HI, &val2); tfp410_readb(dvo, TFP410_V_RES_HI, &val2);
DRM_DEBUG("TFP410_V_RES: 0x%02X%02X\n", val2, val); DRM_LOG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val);
} }
static void tfp410_save(struct intel_dvo_device *dvo) static void tfp410_save(struct intel_dvo_device *dvo)

View file

@ -27,6 +27,7 @@
*/ */
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/debugfs.h>
#include "drmP.h" #include "drmP.h"
#include "drm.h" #include "drm.h"
#include "i915_drm.h" #include "i915_drm.h"
@ -160,7 +161,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
if (!IS_IGDNG(dev)) { if (!IS_IRONLAKE(dev)) {
seq_printf(m, "Interrupt enable: %08x\n", seq_printf(m, "Interrupt enable: %08x\n",
I915_READ(IER)); I915_READ(IER));
seq_printf(m, "Interrupt identity: %08x\n", seq_printf(m, "Interrupt identity: %08x\n",
@ -412,6 +413,109 @@ static int i915_registers_info(struct seq_file *m, void *data) {
return 0; return 0;
} }
static int
i915_wedged_open(struct inode *inode,
struct file *filp)
{
filp->private_data = inode->i_private;
return 0;
}
static ssize_t
i915_wedged_read(struct file *filp,
char __user *ubuf,
size_t max,
loff_t *ppos)
{
struct drm_device *dev = filp->private_data;
drm_i915_private_t *dev_priv = dev->dev_private;
char buf[80];
int len;
len = snprintf(buf, sizeof (buf),
"wedged : %d\n",
atomic_read(&dev_priv->mm.wedged));
return simple_read_from_buffer(ubuf, max, ppos, buf, len);
}
static ssize_t
i915_wedged_write(struct file *filp,
const char __user *ubuf,
size_t cnt,
loff_t *ppos)
{
struct drm_device *dev = filp->private_data;
drm_i915_private_t *dev_priv = dev->dev_private;
char buf[20];
int val = 1;
if (cnt > 0) {
if (cnt > sizeof (buf) - 1)
return -EINVAL;
if (copy_from_user(buf, ubuf, cnt))
return -EFAULT;
buf[cnt] = 0;
val = simple_strtoul(buf, NULL, 0);
}
DRM_INFO("Manually setting wedged to %d\n", val);
atomic_set(&dev_priv->mm.wedged, val);
if (val) {
DRM_WAKEUP(&dev_priv->irq_queue);
queue_work(dev_priv->wq, &dev_priv->error_work);
}
return cnt;
}
static const struct file_operations i915_wedged_fops = {
.owner = THIS_MODULE,
.open = i915_wedged_open,
.read = i915_wedged_read,
.write = i915_wedged_write,
};
/* As the drm_debugfs_init() routines are called before dev->dev_private is
* allocated we need to hook into the minor for release. */
static int
drm_add_fake_info_node(struct drm_minor *minor,
struct dentry *ent,
const void *key)
{
struct drm_info_node *node;
node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
if (node == NULL) {
debugfs_remove(ent);
return -ENOMEM;
}
node->minor = minor;
node->dent = ent;
node->info_ent = (void *) key;
list_add(&node->list, &minor->debugfs_nodes.list);
return 0;
}
static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
{
struct drm_device *dev = minor->dev;
struct dentry *ent;
ent = debugfs_create_file("i915_wedged",
S_IRUGO | S_IWUSR,
root, dev,
&i915_wedged_fops);
if (IS_ERR(ent))
return PTR_ERR(ent);
return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
}
static struct drm_info_list i915_debugfs_list[] = { static struct drm_info_list i915_debugfs_list[] = {
{"i915_regs", i915_registers_info, 0}, {"i915_regs", i915_registers_info, 0},
@ -432,6 +536,12 @@ static struct drm_info_list i915_debugfs_list[] = {
int i915_debugfs_init(struct drm_minor *minor) int i915_debugfs_init(struct drm_minor *minor)
{ {
int ret;
ret = i915_wedged_create(minor->debugfs_root, minor);
if (ret)
return ret;
return drm_debugfs_create_files(i915_debugfs_list, return drm_debugfs_create_files(i915_debugfs_list,
I915_DEBUGFS_ENTRIES, I915_DEBUGFS_ENTRIES,
minor->debugfs_root, minor); minor->debugfs_root, minor);
@ -441,7 +551,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
{ {
drm_debugfs_remove_files(i915_debugfs_list, drm_debugfs_remove_files(i915_debugfs_list,
I915_DEBUGFS_ENTRIES, minor); I915_DEBUGFS_ENTRIES, minor);
drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
1, minor);
} }
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */

View file

@ -807,6 +807,12 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_NUM_FENCES_AVAIL: case I915_PARAM_NUM_FENCES_AVAIL:
value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
break; break;
case I915_PARAM_HAS_OVERLAY:
value = dev_priv->overlay ? 1 : 0;
break;
case I915_PARAM_HAS_PAGEFLIPPING:
value = 1;
break;
default: default:
DRM_DEBUG_DRIVER("Unknown parameter %d\n", DRM_DEBUG_DRIVER("Unknown parameter %d\n",
param->param); param->param);
@ -962,7 +968,7 @@ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
* Some of the preallocated space is taken by the GTT * Some of the preallocated space is taken by the GTT
* and popup. GTT is 1K per MB of aperture size, and popup is 4K. * and popup. GTT is 1K per MB of aperture size, and popup is 4K.
*/ */
if (IS_G4X(dev) || IS_IGD(dev) || IS_IGDNG(dev)) if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev))
overhead = 4096; overhead = 4096;
else else
overhead = (*aperture_size / 1024) + 4096; overhead = (*aperture_size / 1024) + 4096;
@ -1048,7 +1054,7 @@ static unsigned long i915_gtt_to_phys(struct drm_device *dev,
int gtt_offset, gtt_size; int gtt_offset, gtt_size;
if (IS_I965G(dev)) { if (IS_I965G(dev)) {
if (IS_G4X(dev) || IS_IGDNG(dev)) { if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
gtt_offset = 2*1024*1024; gtt_offset = 2*1024*1024;
gtt_size = 2*1024*1024; gtt_size = 2*1024*1024;
} else { } else {
@ -1070,7 +1076,7 @@ static unsigned long i915_gtt_to_phys(struct drm_device *dev,
entry = *(volatile u32 *)(gtt + (gtt_addr / 1024)); entry = *(volatile u32 *)(gtt + (gtt_addr / 1024));
DRM_DEBUG("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry); DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry);
/* Mask out these reserved bits on this hardware. */ /* Mask out these reserved bits on this hardware. */
if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev) || if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev) ||
@ -1096,7 +1102,7 @@ static unsigned long i915_gtt_to_phys(struct drm_device *dev,
phys =(entry & PTE_ADDRESS_MASK) | phys =(entry & PTE_ADDRESS_MASK) |
((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4)); ((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4));
DRM_DEBUG("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys); DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys);
return phys; return phys;
} }
@ -1306,7 +1312,7 @@ static void i915_get_mem_freq(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
u32 tmp; u32 tmp;
if (!IS_IGD(dev)) if (!IS_PINEVIEW(dev))
return; return;
tmp = I915_READ(CLKCFG); tmp = I915_READ(CLKCFG);
@ -1413,7 +1419,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (ret) if (ret)
goto out_iomapfree; goto out_iomapfree;
dev_priv->wq = create_workqueue("i915"); dev_priv->wq = create_singlethread_workqueue("i915");
if (dev_priv->wq == NULL) { if (dev_priv->wq == NULL) {
DRM_ERROR("Failed to create our workqueue.\n"); DRM_ERROR("Failed to create our workqueue.\n");
ret = -ENOMEM; ret = -ENOMEM;
@ -1434,7 +1440,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev->driver->get_vblank_counter = i915_get_vblank_counter; dev->driver->get_vblank_counter = i915_get_vblank_counter;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
if (IS_G4X(dev) || IS_IGDNG(dev)) { if (IS_G4X(dev) || IS_IRONLAKE(dev)) {
dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
dev->driver->get_vblank_counter = gm45_get_vblank_counter; dev->driver->get_vblank_counter = gm45_get_vblank_counter;
} }
@ -1489,9 +1495,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
} }
/* Must be done after probing outputs */ /* Must be done after probing outputs */
/* FIXME: verify on IGDNG */ intel_opregion_init(dev, 0);
if (!IS_IGDNG(dev))
intel_opregion_init(dev, 0);
setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
(unsigned long) dev); (unsigned long) dev);
@ -1525,6 +1529,15 @@ int i915_driver_unload(struct drm_device *dev)
} }
if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (drm_core_check_feature(dev, DRIVER_MODESET)) {
/*
* free the memory space allocated for the child device
* config parsed from VBT
*/
if (dev_priv->child_dev && dev_priv->child_dev_num) {
kfree(dev_priv->child_dev);
dev_priv->child_dev = NULL;
dev_priv->child_dev_num = 0;
}
drm_irq_uninstall(dev); drm_irq_uninstall(dev);
vga_client_register(dev->pdev, NULL, NULL, NULL); vga_client_register(dev->pdev, NULL, NULL, NULL);
} }
@ -1535,8 +1548,7 @@ int i915_driver_unload(struct drm_device *dev)
if (dev_priv->regs != NULL) if (dev_priv->regs != NULL)
iounmap(dev_priv->regs); iounmap(dev_priv->regs);
if (!IS_IGDNG(dev)) intel_opregion_free(dev, 0);
intel_opregion_free(dev, 0);
if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (drm_core_check_feature(dev, DRIVER_MODESET)) {
intel_modeset_cleanup(dev); intel_modeset_cleanup(dev);
@ -1548,6 +1560,8 @@ int i915_driver_unload(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
drm_mm_takedown(&dev_priv->vram); drm_mm_takedown(&dev_priv->vram);
i915_gem_lastclose(dev); i915_gem_lastclose(dev);
intel_cleanup_overlay(dev);
} }
pci_dev_put(dev_priv->bridge_dev); pci_dev_put(dev_priv->bridge_dev);
@ -1656,6 +1670,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0),
DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0), DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0), DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0),
DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW),
}; };
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);

View file

@ -170,6 +170,8 @@ struct drm_i915_display_funcs {
/* clock gating init */ /* clock gating init */
}; };
struct intel_overlay;
typedef struct drm_i915_private { typedef struct drm_i915_private {
struct drm_device *dev; struct drm_device *dev;
@ -187,6 +189,7 @@ typedef struct drm_i915_private {
unsigned int status_gfx_addr; unsigned int status_gfx_addr;
drm_local_map_t hws_map; drm_local_map_t hws_map;
struct drm_gem_object *hws_obj; struct drm_gem_object *hws_obj;
struct drm_gem_object *pwrctx;
struct resource mch_res; struct resource mch_res;
@ -206,11 +209,13 @@ typedef struct drm_i915_private {
/** Cached value of IMR to avoid reads in updating the bitfield */ /** Cached value of IMR to avoid reads in updating the bitfield */
u32 irq_mask_reg; u32 irq_mask_reg;
u32 pipestat[2]; u32 pipestat[2];
/** splitted irq regs for graphics and display engine on IGDNG, /** splitted irq regs for graphics and display engine on Ironlake,
irq_mask_reg is still used for display irq. */ irq_mask_reg is still used for display irq. */
u32 gt_irq_mask_reg; u32 gt_irq_mask_reg;
u32 gt_irq_enable_reg; u32 gt_irq_enable_reg;
u32 de_irq_enable_reg; u32 de_irq_enable_reg;
u32 pch_irq_mask_reg;
u32 pch_irq_enable_reg;
u32 hotplug_supported_mask; u32 hotplug_supported_mask;
struct work_struct hotplug_work; struct work_struct hotplug_work;
@ -240,6 +245,9 @@ typedef struct drm_i915_private {
struct intel_opregion opregion; struct intel_opregion opregion;
/* overlay */
struct intel_overlay *overlay;
/* LVDS info */ /* LVDS info */
int backlight_duty_cycle; /* restore backlight to this value */ int backlight_duty_cycle; /* restore backlight to this value */
bool panel_wants_dither; bool panel_wants_dither;
@ -258,7 +266,7 @@ typedef struct drm_i915_private {
struct notifier_block lid_notifier; struct notifier_block lid_notifier;
int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ int crt_ddc_bus; /* 0 = unknown, else GPIO to use for CRT DDC */
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */
@ -280,6 +288,7 @@ typedef struct drm_i915_private {
u32 saveDSPBCNTR; u32 saveDSPBCNTR;
u32 saveDSPARB; u32 saveDSPARB;
u32 saveRENDERSTANDBY; u32 saveRENDERSTANDBY;
u32 savePWRCTXA;
u32 saveHWS; u32 saveHWS;
u32 savePIPEACONF; u32 savePIPEACONF;
u32 savePIPEBCONF; u32 savePIPEBCONF;
@ -539,13 +548,21 @@ typedef struct drm_i915_private {
/* indicate whether the LVDS_BORDER should be enabled or not */ /* indicate whether the LVDS_BORDER should be enabled or not */
unsigned int lvds_border_bits; unsigned int lvds_border_bits;
struct drm_crtc *plane_to_crtc_mapping[2];
struct drm_crtc *pipe_to_crtc_mapping[2];
wait_queue_head_t pending_flip_queue;
/* Reclocking support */ /* Reclocking support */
bool render_reclock_avail; bool render_reclock_avail;
bool lvds_downclock_avail; bool lvds_downclock_avail;
/* indicates the reduced downclock for LVDS*/
int lvds_downclock;
struct work_struct idle_work; struct work_struct idle_work;
struct timer_list idle_timer; struct timer_list idle_timer;
bool busy; bool busy;
u16 orig_clock; u16 orig_clock;
int child_dev_num;
struct child_device_config *child_dev;
} drm_i915_private_t; } drm_i915_private_t;
/** driver private structure attached to each drm_gem_object */ /** driver private structure attached to each drm_gem_object */
@ -638,6 +655,13 @@ struct drm_i915_gem_object {
* Advice: are the backing pages purgeable? * Advice: are the backing pages purgeable?
*/ */
int madv; int madv;
/**
* Number of crtcs where this object is currently the fb, but
* will be page flipped away on the next vblank. When it
* reaches 0, dev_priv->pending_flip_queue will be woken up.
*/
atomic_t pending_flip;
}; };
/** /**
@ -738,6 +762,8 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
void void
i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
void intel_enable_asle (struct drm_device *dev);
/* i915_mem.c */ /* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data, extern int i915_mem_alloc(struct drm_device *dev, void *data,
@ -813,6 +839,9 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start, int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end); unsigned long end);
int i915_gem_idle(struct drm_device *dev); int i915_gem_idle(struct drm_device *dev);
uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
uint32_t flush_domains);
int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write); int write);
@ -824,6 +853,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev);
int i915_gem_object_get_pages(struct drm_gem_object *obj); int i915_gem_object_get_pages(struct drm_gem_object *obj);
void i915_gem_object_put_pages(struct drm_gem_object *obj); void i915_gem_object_put_pages(struct drm_gem_object *obj);
void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
void i915_gem_shrinker_init(void); void i915_gem_shrinker_init(void);
void i915_gem_shrinker_exit(void); void i915_gem_shrinker_exit(void);
@ -863,11 +893,13 @@ extern int i915_restore_state(struct drm_device *dev);
extern int intel_opregion_init(struct drm_device *dev, int resume); extern int intel_opregion_init(struct drm_device *dev, int resume);
extern void intel_opregion_free(struct drm_device *dev, int suspend); extern void intel_opregion_free(struct drm_device *dev, int suspend);
extern void opregion_asle_intr(struct drm_device *dev); extern void opregion_asle_intr(struct drm_device *dev);
extern void ironlake_opregion_gse_intr(struct drm_device *dev);
extern void opregion_enable_asle(struct drm_device *dev); extern void opregion_enable_asle(struct drm_device *dev);
#else #else
static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; } static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; } static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; }
static inline void opregion_asle_intr(struct drm_device *dev) { return; } static inline void opregion_asle_intr(struct drm_device *dev) { return; }
static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; }
static inline void opregion_enable_asle(struct drm_device *dev) { return; } static inline void opregion_enable_asle(struct drm_device *dev) { return; }
#endif #endif
@ -955,8 +987,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I830(dev) ((dev)->pci_device == 0x3577) #define IS_I830(dev) ((dev)->pci_device == 0x3577)
#define IS_845G(dev) ((dev)->pci_device == 0x2562) #define IS_845G(dev) ((dev)->pci_device == 0x2562)
#define IS_I85X(dev) ((dev)->pci_device == 0x3582) #define IS_I85X(dev) ((dev)->pci_device == 0x3582)
#define IS_I855(dev) ((dev)->pci_device == 0x3582)
#define IS_I865G(dev) ((dev)->pci_device == 0x2572) #define IS_I865G(dev) ((dev)->pci_device == 0x2572)
#define IS_I8XX(dev) (IS_I830(dev) || IS_845G(dev) || IS_I85X(dev) || IS_I865G(dev))
#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a) #define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) #define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
@ -990,47 +1022,51 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
(dev)->pci_device == 0x2E42 || \ (dev)->pci_device == 0x2E42 || \
IS_GM45(dev)) IS_GM45(dev))
#define IS_IGDG(dev) ((dev)->pci_device == 0xa001) #define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001)
#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011) #define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011)
#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev)) #define IS_PINEVIEW(dev) (IS_PINEVIEW_G(dev) || IS_PINEVIEW_M(dev))
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ #define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \ (dev)->pci_device == 0x29B2 || \
(dev)->pci_device == 0x29D2 || \ (dev)->pci_device == 0x29D2 || \
(IS_IGD(dev))) (IS_PINEVIEW(dev)))
#define IS_IGDNG_D(dev) ((dev)->pci_device == 0x0042) #define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042)
#define IS_IGDNG_M(dev) ((dev)->pci_device == 0x0046) #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046)
#define IS_IGDNG(dev) (IS_IGDNG_D(dev) || IS_IGDNG_M(dev)) #define IS_IRONLAKE(dev) (IS_IRONLAKE_D(dev) || IS_IRONLAKE_M(dev))
#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ #define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \ IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev) || \
IS_IGDNG(dev)) IS_IRONLAKE(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
IS_IGD(dev) || IS_IGDNG_M(dev)) IS_PINEVIEW(dev) || IS_IRONLAKE_M(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \ #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev) || \
IS_IGDNG(dev)) IS_IRONLAKE(dev))
/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
* rows, which changed the alignment requirements and fence programming. * rows, which changed the alignment requirements and fence programming.
*/ */
#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
IS_I915GM(dev))) IS_I915GM(dev)))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define SUPPORTS_DIGITAL_OUTPUTS(dev) (IS_I9XX(dev) && !IS_PINEVIEW(dev))
#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
#define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev)) #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
#define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev))
#define SUPPORTS_TV(dev) (IS_I9XX(dev) && IS_MOBILE(dev) && \
!IS_IRONLAKE(dev) && !IS_PINEVIEW(dev))
#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev)) #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev))
/* dsparb controlled by hw only */ /* dsparb controlled by hw only */
#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev)) #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IRONLAKE(dev))
#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IRONLAKE(dev))
#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \ #define I915_HAS_FBC(dev) (IS_MOBILE(dev) && \
(IS_I9XX(dev) || IS_GM45(dev)) && \ (IS_I9XX(dev) || IS_GM45(dev)) && \
!IS_IGD(dev) && \ !IS_PINEVIEW(dev) && \
!IS_IGDNG(dev)) !IS_IRONLAKE(dev))
#define I915_HAS_RC6(dev) (IS_I965GM(dev) || IS_GM45(dev) || IS_IRONLAKE_M(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024) #define PRIMARY_RINGBUFFER_SIZE (128*1024)

View file

@ -1583,7 +1583,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
* *
* Returned sequence numbers are nonzero on success. * Returned sequence numbers are nonzero on success.
*/ */
static uint32_t uint32_t
i915_add_request(struct drm_device *dev, struct drm_file *file_priv, i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
uint32_t flush_domains) uint32_t flush_domains)
{ {
@ -1617,7 +1617,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
OUT_RING(MI_USER_INTERRUPT); OUT_RING(MI_USER_INTERRUPT);
ADVANCE_LP_RING(); ADVANCE_LP_RING();
DRM_DEBUG("%d\n", seqno); DRM_DEBUG_DRIVER("%d\n", seqno);
request->seqno = seqno; request->seqno = seqno;
request->emitted_jiffies = jiffies; request->emitted_jiffies = jiffies;
@ -1820,12 +1820,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
} }
/** int
* Waits for a sequence number to be signaled, and cleans up the i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
* request and object lists appropriately for that event.
*/
static int
i915_wait_request(struct drm_device *dev, uint32_t seqno)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
u32 ier; u32 ier;
@ -1837,7 +1833,7 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
return -EIO; return -EIO;
if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
ier = I915_READ(DEIER) | I915_READ(GTIER); ier = I915_READ(DEIER) | I915_READ(GTIER);
else else
ier = I915_READ(IER); ier = I915_READ(IER);
@ -1852,10 +1848,15 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
dev_priv->mm.waiting_gem_seqno = seqno; dev_priv->mm.waiting_gem_seqno = seqno;
i915_user_irq_get(dev); i915_user_irq_get(dev);
ret = wait_event_interruptible(dev_priv->irq_queue, if (interruptible)
i915_seqno_passed(i915_get_gem_seqno(dev), ret = wait_event_interruptible(dev_priv->irq_queue,
seqno) || i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
atomic_read(&dev_priv->mm.wedged)); atomic_read(&dev_priv->mm.wedged));
else
wait_event(dev_priv->irq_queue,
i915_seqno_passed(i915_get_gem_seqno(dev), seqno) ||
atomic_read(&dev_priv->mm.wedged));
i915_user_irq_put(dev); i915_user_irq_put(dev);
dev_priv->mm.waiting_gem_seqno = 0; dev_priv->mm.waiting_gem_seqno = 0;
@ -1879,6 +1880,16 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
return ret; return ret;
} }
/**
* Waits for a sequence number to be signaled, and cleans up the
* request and object lists appropriately for that event.
*/
static int
i915_wait_request(struct drm_device *dev, uint32_t seqno)
{
return i915_do_wait_request(dev, seqno, 1);
}
static void static void
i915_gem_flush(struct drm_device *dev, i915_gem_flush(struct drm_device *dev,
uint32_t invalidate_domains, uint32_t invalidate_domains,
@ -1947,7 +1958,7 @@ i915_gem_flush(struct drm_device *dev,
#endif #endif
BEGIN_LP_RING(2); BEGIN_LP_RING(2);
OUT_RING(cmd); OUT_RING(cmd);
OUT_RING(0); /* noop */ OUT_RING(MI_NOOP);
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
} }
@ -2760,6 +2771,22 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
old_write_domain); old_write_domain);
} }
void
i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
{
switch (obj->write_domain) {
case I915_GEM_DOMAIN_GTT:
i915_gem_object_flush_gtt_write_domain(obj);
break;
case I915_GEM_DOMAIN_CPU:
i915_gem_object_flush_cpu_write_domain(obj);
break;
default:
i915_gem_object_flush_gpu_write_domain(obj);
break;
}
}
/** /**
* Moves a single object to the GTT read, and possibly write domain. * Moves a single object to the GTT read, and possibly write domain.
* *
@ -3525,6 +3552,41 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec,
return 0; return 0;
} }
static int
i915_gem_wait_for_pending_flip(struct drm_device *dev,
struct drm_gem_object **object_list,
int count)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv;
DEFINE_WAIT(wait);
int i, ret = 0;
for (;;) {
prepare_to_wait(&dev_priv->pending_flip_queue,
&wait, TASK_INTERRUPTIBLE);
for (i = 0; i < count; i++) {
obj_priv = object_list[i]->driver_private;
if (atomic_read(&obj_priv->pending_flip) > 0)
break;
}
if (i == count)
break;
if (!signal_pending(current)) {
mutex_unlock(&dev->struct_mutex);
schedule();
mutex_lock(&dev->struct_mutex);
continue;
}
ret = -ERESTARTSYS;
break;
}
finish_wait(&dev_priv->pending_flip_queue, &wait);
return ret;
}
int int
i915_gem_execbuffer(struct drm_device *dev, void *data, i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
@ -3540,7 +3602,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
int ret, ret2, i, pinned = 0; int ret, ret2, i, pinned = 0;
uint64_t exec_offset; uint64_t exec_offset;
uint32_t seqno, flush_domains, reloc_index; uint32_t seqno, flush_domains, reloc_index;
int pin_tries; int pin_tries, flips;
#if WATCH_EXEC #if WATCH_EXEC
DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
@ -3552,8 +3614,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
return -EINVAL; return -EINVAL;
} }
/* Copy in the exec list from userland */ /* Copy in the exec list from userland */
exec_list = drm_calloc_large(sizeof(*exec_list), args->buffer_count); exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
object_list = drm_calloc_large(sizeof(*object_list), args->buffer_count); object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count);
if (exec_list == NULL || object_list == NULL) { if (exec_list == NULL || object_list == NULL) {
DRM_ERROR("Failed to allocate exec or object list " DRM_ERROR("Failed to allocate exec or object list "
"for %d buffers\n", "for %d buffers\n",
@ -3598,20 +3660,19 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
i915_verify_inactive(dev, __FILE__, __LINE__); i915_verify_inactive(dev, __FILE__, __LINE__);
if (atomic_read(&dev_priv->mm.wedged)) { if (atomic_read(&dev_priv->mm.wedged)) {
DRM_ERROR("Execbuf while wedged\n");
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
ret = -EIO; ret = -EIO;
goto pre_mutex_err; goto pre_mutex_err;
} }
if (dev_priv->mm.suspended) { if (dev_priv->mm.suspended) {
DRM_ERROR("Execbuf while VT-switched.\n");
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
ret = -EBUSY; ret = -EBUSY;
goto pre_mutex_err; goto pre_mutex_err;
} }
/* Look up object handles */ /* Look up object handles */
flips = 0;
for (i = 0; i < args->buffer_count; i++) { for (i = 0; i < args->buffer_count; i++) {
object_list[i] = drm_gem_object_lookup(dev, file_priv, object_list[i] = drm_gem_object_lookup(dev, file_priv,
exec_list[i].handle); exec_list[i].handle);
@ -3630,6 +3691,14 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
goto err; goto err;
} }
obj_priv->in_execbuffer = true; obj_priv->in_execbuffer = true;
flips += atomic_read(&obj_priv->pending_flip);
}
if (flips > 0) {
ret = i915_gem_wait_for_pending_flip(dev, object_list,
args->buffer_count);
if (ret)
goto err;
} }
/* Pin and relocate */ /* Pin and relocate */
@ -4356,7 +4425,7 @@ i915_gem_init_hws(struct drm_device *dev)
memset(dev_priv->hw_status_page, 0, PAGE_SIZE); memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
I915_READ(HWS_PGA); /* posting read */ I915_READ(HWS_PGA); /* posting read */
DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
return 0; return 0;
} }
@ -4614,8 +4683,8 @@ i915_gem_load(struct drm_device *dev)
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
I915_WRITE(FENCE_REG_945_8 + (i * 4), 0); I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
} }
i915_gem_detect_bit_6_swizzle(dev); i915_gem_detect_bit_6_swizzle(dev);
init_waitqueue_head(&dev_priv->pending_flip_queue);
} }
/* /*
@ -4790,7 +4859,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
user_data = (char __user *) (uintptr_t) args->data_ptr; user_data = (char __user *) (uintptr_t) args->data_ptr;
obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size); DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size);
ret = copy_from_user(obj_addr, user_data, args->size); ret = copy_from_user(obj_addr, user_data, args->size);
if (ret) if (ret)
return -EFAULT; return -EFAULT;

View file

@ -121,7 +121,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
0, pcibios_align_resource, 0, pcibios_align_resource,
dev_priv->bridge_dev); dev_priv->bridge_dev);
if (ret) { if (ret) {
DRM_DEBUG("failed bus alloc: %d\n", ret); DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
dev_priv->mch_res.start = 0; dev_priv->mch_res.start = 0;
goto out; goto out;
} }
@ -209,8 +209,8 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
bool need_disable; bool need_disable;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
/* On IGDNG whatever DRAM config, GPU always do /* On Ironlake whatever DRAM config, GPU always do
* same swizzling setup. * same swizzling setup.
*/ */
swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_x = I915_BIT_6_SWIZZLE_9_10;

View file

@ -43,10 +43,13 @@
* we leave them always unmasked in IMR and then control enabling them through * we leave them always unmasked in IMR and then control enabling them through
* PIPESTAT alone. * PIPESTAT alone.
*/ */
#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ #define I915_INTERRUPT_ENABLE_FIX \
I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ (I915_ASLE_INTERRUPT | \
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | \
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | \
I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
/** Interrupts that we mask and unmask at runtime. */ /** Interrupts that we mask and unmask at runtime. */
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
@ -61,7 +64,7 @@
DRM_I915_VBLANK_PIPE_B) DRM_I915_VBLANK_PIPE_B)
void void
igdng_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
{ {
if ((dev_priv->gt_irq_mask_reg & mask) != 0) { if ((dev_priv->gt_irq_mask_reg & mask) != 0) {
dev_priv->gt_irq_mask_reg &= ~mask; dev_priv->gt_irq_mask_reg &= ~mask;
@ -71,7 +74,7 @@ igdng_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
} }
static inline void static inline void
igdng_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
{ {
if ((dev_priv->gt_irq_mask_reg & mask) != mask) { if ((dev_priv->gt_irq_mask_reg & mask) != mask) {
dev_priv->gt_irq_mask_reg |= mask; dev_priv->gt_irq_mask_reg |= mask;
@ -82,7 +85,7 @@ igdng_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask)
/* For display hotplug interrupt */ /* For display hotplug interrupt */
void void
igdng_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
{ {
if ((dev_priv->irq_mask_reg & mask) != 0) { if ((dev_priv->irq_mask_reg & mask) != 0) {
dev_priv->irq_mask_reg &= ~mask; dev_priv->irq_mask_reg &= ~mask;
@ -92,7 +95,7 @@ igdng_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
} }
static inline void static inline void
igdng_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
{ {
if ((dev_priv->irq_mask_reg & mask) != mask) { if ((dev_priv->irq_mask_reg & mask) != mask) {
dev_priv->irq_mask_reg |= mask; dev_priv->irq_mask_reg |= mask;
@ -156,6 +159,20 @@ i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
} }
} }
/**
* intel_enable_asle - enable ASLE interrupt for OpRegion
*/
void intel_enable_asle (struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
if (IS_IRONLAKE(dev))
ironlake_enable_display_irq(dev_priv, DE_GSE);
else
i915_enable_pipestat(dev_priv, 1,
I915_LEGACY_BLC_EVENT_ENABLE);
}
/** /**
* i915_pipe_enabled - check if a pipe is enabled * i915_pipe_enabled - check if a pipe is enabled
* @dev: DRM device * @dev: DRM device
@ -191,7 +208,8 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
if (!i915_pipe_enabled(dev, pipe)) { if (!i915_pipe_enabled(dev, pipe)) {
DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
"pipe %d\n", pipe);
return 0; return 0;
} }
@ -220,7 +238,8 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
if (!i915_pipe_enabled(dev, pipe)) { if (!i915_pipe_enabled(dev, pipe)) {
DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
"pipe %d\n", pipe);
return 0; return 0;
} }
@ -250,12 +269,12 @@ static void i915_hotplug_work_func(struct work_struct *work)
drm_sysfs_hotplug_event(dev); drm_sysfs_hotplug_event(dev);
} }
irqreturn_t igdng_irq_handler(struct drm_device *dev) irqreturn_t ironlake_irq_handler(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE; int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier; u32 de_iir, gt_iir, de_ier, pch_iir;
u32 new_de_iir, new_gt_iir; u32 new_de_iir, new_gt_iir, new_pch_iir;
struct drm_i915_master_private *master_priv; struct drm_i915_master_private *master_priv;
/* disable master interrupt before clearing iir */ /* disable master interrupt before clearing iir */
@ -265,13 +284,18 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
de_iir = I915_READ(DEIIR); de_iir = I915_READ(DEIIR);
gt_iir = I915_READ(GTIIR); gt_iir = I915_READ(GTIIR);
pch_iir = I915_READ(SDEIIR);
for (;;) { for (;;) {
if (de_iir == 0 && gt_iir == 0) if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
break; break;
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
/* should clear PCH hotplug event before clear CPU irq */
I915_WRITE(SDEIIR, pch_iir);
new_pch_iir = I915_READ(SDEIIR);
I915_WRITE(DEIIR, de_iir); I915_WRITE(DEIIR, de_iir);
new_de_iir = I915_READ(DEIIR); new_de_iir = I915_READ(DEIIR);
I915_WRITE(GTIIR, gt_iir); I915_WRITE(GTIIR, gt_iir);
@ -291,8 +315,18 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
DRM_WAKEUP(&dev_priv->irq_queue); DRM_WAKEUP(&dev_priv->irq_queue);
} }
if (de_iir & DE_GSE)
ironlake_opregion_gse_intr(dev);
/* check event from PCH */
if ((de_iir & DE_PCH_EVENT) &&
(pch_iir & SDE_HOTPLUG_MASK)) {
queue_work(dev_priv->wq, &dev_priv->hotplug_work);
}
de_iir = new_de_iir; de_iir = new_de_iir;
gt_iir = new_gt_iir; gt_iir = new_gt_iir;
pch_iir = new_pch_iir;
} }
I915_WRITE(DEIER, de_ier); I915_WRITE(DEIER, de_ier);
@ -317,19 +351,19 @@ static void i915_error_work_func(struct work_struct *work)
char *reset_event[] = { "RESET=1", NULL }; char *reset_event[] = { "RESET=1", NULL };
char *reset_done_event[] = { "ERROR=0", NULL }; char *reset_done_event[] = { "ERROR=0", NULL };
DRM_DEBUG("generating error event\n"); DRM_DEBUG_DRIVER("generating error event\n");
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
if (atomic_read(&dev_priv->mm.wedged)) { if (atomic_read(&dev_priv->mm.wedged)) {
if (IS_I965G(dev)) { if (IS_I965G(dev)) {
DRM_DEBUG("resetting chip\n"); DRM_DEBUG_DRIVER("resetting chip\n");
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
if (!i965_reset(dev, GDRST_RENDER)) { if (!i965_reset(dev, GDRST_RENDER)) {
atomic_set(&dev_priv->mm.wedged, 0); atomic_set(&dev_priv->mm.wedged, 0);
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
} }
} else { } else {
printk("reboot required\n"); DRM_DEBUG_DRIVER("reboot required\n");
} }
} }
} }
@ -355,7 +389,7 @@ static void i915_capture_error_state(struct drm_device *dev)
error = kmalloc(sizeof(*error), GFP_ATOMIC); error = kmalloc(sizeof(*error), GFP_ATOMIC);
if (!error) { if (!error) {
DRM_DEBUG("out ot memory, not capturing error state\n"); DRM_DEBUG_DRIVER("out ot memory, not capturing error state\n");
goto out; goto out;
} }
@ -535,8 +569,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
atomic_inc(&dev_priv->irq_received); atomic_inc(&dev_priv->irq_received);
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
return igdng_irq_handler(dev); return ironlake_irq_handler(dev);
iir = I915_READ(IIR); iir = I915_READ(IIR);
@ -568,14 +602,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
*/ */
if (pipea_stats & 0x8000ffff) { if (pipea_stats & 0x8000ffff) {
if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS) if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS)
DRM_DEBUG("pipe a underrun\n"); DRM_DEBUG_DRIVER("pipe a underrun\n");
I915_WRITE(PIPEASTAT, pipea_stats); I915_WRITE(PIPEASTAT, pipea_stats);
irq_received = 1; irq_received = 1;
} }
if (pipeb_stats & 0x8000ffff) { if (pipeb_stats & 0x8000ffff) {
if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS) if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS)
DRM_DEBUG("pipe b underrun\n"); DRM_DEBUG_DRIVER("pipe b underrun\n");
I915_WRITE(PIPEBSTAT, pipeb_stats); I915_WRITE(PIPEBSTAT, pipeb_stats);
irq_received = 1; irq_received = 1;
} }
@ -591,7 +625,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
(iir & I915_DISPLAY_PORT_INTERRUPT)) { (iir & I915_DISPLAY_PORT_INTERRUPT)) {
u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
DRM_DEBUG("hotplug event received, stat 0x%08x\n", DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
hotplug_status); hotplug_status);
if (hotplug_status & dev_priv->hotplug_supported_mask) if (hotplug_status & dev_priv->hotplug_supported_mask)
queue_work(dev_priv->wq, queue_work(dev_priv->wq,
@ -599,27 +633,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
I915_READ(PORT_HOTPLUG_STAT); I915_READ(PORT_HOTPLUG_STAT);
/* EOS interrupts occurs */
if (IS_IGD(dev) &&
(hotplug_status & CRT_EOS_INT_STATUS)) {
u32 temp;
DRM_DEBUG("EOS interrupt occurs\n");
/* status is already cleared */
temp = I915_READ(ADPA);
temp &= ~ADPA_DAC_ENABLE;
I915_WRITE(ADPA, temp);
temp = I915_READ(PORT_HOTPLUG_EN);
temp &= ~CRT_EOS_INT_EN;
I915_WRITE(PORT_HOTPLUG_EN, temp);
temp = I915_READ(PORT_HOTPLUG_STAT);
if (temp & CRT_EOS_INT_STATUS)
I915_WRITE(PORT_HOTPLUG_STAT,
CRT_EOS_INT_STATUS);
}
} }
I915_WRITE(IIR, iir); I915_WRITE(IIR, iir);
@ -641,14 +654,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
} }
if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
intel_prepare_page_flip(dev, 0);
if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT)
intel_prepare_page_flip(dev, 1);
if (pipea_stats & vblank_status) { if (pipea_stats & vblank_status) {
vblank++; vblank++;
drm_handle_vblank(dev, 0); drm_handle_vblank(dev, 0);
intel_finish_page_flip(dev, 0);
} }
if (pipeb_stats & vblank_status) { if (pipeb_stats & vblank_status) {
vblank++; vblank++;
drm_handle_vblank(dev, 1); drm_handle_vblank(dev, 1);
intel_finish_page_flip(dev, 1);
} }
if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) || if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
@ -684,7 +705,7 @@ static int i915_emit_irq(struct drm_device * dev)
i915_kernel_lost_context(dev); i915_kernel_lost_context(dev);
DRM_DEBUG("\n"); DRM_DEBUG_DRIVER("\n");
dev_priv->counter++; dev_priv->counter++;
if (dev_priv->counter > 0x7FFFFFFFUL) if (dev_priv->counter > 0x7FFFFFFFUL)
@ -709,8 +730,8 @@ void i915_user_irq_get(struct drm_device *dev)
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
igdng_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
else else
i915_enable_irq(dev_priv, I915_USER_INTERRUPT); i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
} }
@ -725,8 +746,8 @@ void i915_user_irq_put(struct drm_device *dev)
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
igdng_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
else else
i915_disable_irq(dev_priv, I915_USER_INTERRUPT); i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
} }
@ -749,7 +770,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
int ret = 0; int ret = 0;
DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv)); READ_BREADCRUMB(dev_priv));
if (READ_BREADCRUMB(dev_priv) >= irq_nr) { if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
@ -832,7 +853,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
if (!(pipeconf & PIPEACONF_ENABLE)) if (!(pipeconf & PIPEACONF_ENABLE))
return -EINVAL; return -EINVAL;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
return 0; return 0;
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
@ -854,7 +875,7 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags; unsigned long irqflags;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
return; return;
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
@ -868,7 +889,7 @@ void i915_enable_interrupt (struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
if (!IS_IGDNG(dev)) if (!IS_IRONLAKE(dev))
opregion_enable_asle(dev); opregion_enable_asle(dev);
dev_priv->irq_enabled = 1; dev_priv->irq_enabled = 1;
} }
@ -976,7 +997,7 @@ void i915_hangcheck_elapsed(unsigned long data)
/* drm_dma.h hooks /* drm_dma.h hooks
*/ */
static void igdng_irq_preinstall(struct drm_device *dev) static void ironlake_irq_preinstall(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@ -992,14 +1013,21 @@ static void igdng_irq_preinstall(struct drm_device *dev)
I915_WRITE(GTIMR, 0xffffffff); I915_WRITE(GTIMR, 0xffffffff);
I915_WRITE(GTIER, 0x0); I915_WRITE(GTIER, 0x0);
(void) I915_READ(GTIER); (void) I915_READ(GTIER);
/* south display irq */
I915_WRITE(SDEIMR, 0xffffffff);
I915_WRITE(SDEIER, 0x0);
(void) I915_READ(SDEIER);
} }
static int igdng_irq_postinstall(struct drm_device *dev) static int ironlake_irq_postinstall(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
/* enable kind of interrupts always enabled */ /* enable kind of interrupts always enabled */
u32 display_mask = DE_MASTER_IRQ_CONTROL /*| DE_PCH_EVENT */; u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT;
u32 render_mask = GT_USER_INTERRUPT; u32 render_mask = GT_USER_INTERRUPT;
u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
dev_priv->irq_mask_reg = ~display_mask; dev_priv->irq_mask_reg = ~display_mask;
dev_priv->de_irq_enable_reg = display_mask; dev_priv->de_irq_enable_reg = display_mask;
@ -1019,6 +1047,14 @@ static int igdng_irq_postinstall(struct drm_device *dev)
I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
(void) I915_READ(GTIER); (void) I915_READ(GTIER);
dev_priv->pch_irq_mask_reg = ~hotplug_mask;
dev_priv->pch_irq_enable_reg = hotplug_mask;
I915_WRITE(SDEIIR, I915_READ(SDEIIR));
I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg);
I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg);
(void) I915_READ(SDEIER);
return 0; return 0;
} }
@ -1031,8 +1067,8 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
INIT_WORK(&dev_priv->error_work, i915_error_work_func); INIT_WORK(&dev_priv->error_work, i915_error_work_func);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
igdng_irq_preinstall(dev); ironlake_irq_preinstall(dev);
return; return;
} }
@ -1059,8 +1095,8 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
return igdng_irq_postinstall(dev); return ironlake_irq_postinstall(dev);
/* Unmask the interrupts that we always want on. */ /* Unmask the interrupts that we always want on. */
dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX; dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
@ -1120,7 +1156,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
return 0; return 0;
} }
static void igdng_irq_uninstall(struct drm_device *dev) static void ironlake_irq_uninstall(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
I915_WRITE(HWSTAM, 0xffffffff); I915_WRITE(HWSTAM, 0xffffffff);
@ -1143,8 +1179,8 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
dev_priv->vblank_pipe = 0; dev_priv->vblank_pipe = 0;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
igdng_irq_uninstall(dev); ironlake_irq_uninstall(dev);
return; return;
} }

View file

@ -118,6 +118,10 @@ struct opregion_asle {
#define ASLE_BACKLIGHT_FAIL (2<<12) #define ASLE_BACKLIGHT_FAIL (2<<12)
#define ASLE_PFIT_FAIL (2<<14) #define ASLE_PFIT_FAIL (2<<14)
#define ASLE_PWM_FREQ_FAIL (2<<16) #define ASLE_PWM_FREQ_FAIL (2<<16)
#define ASLE_ALS_ILLUM_FAILED (1<<10)
#define ASLE_BACKLIGHT_FAILED (1<<12)
#define ASLE_PFIT_FAILED (1<<14)
#define ASLE_PWM_FREQ_FAILED (1<<16)
/* ASLE backlight brightness to set */ /* ASLE backlight brightness to set */
#define ASLE_BCLP_VALID (1<<31) #define ASLE_BCLP_VALID (1<<31)
@ -163,7 +167,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE)) if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE))
pci_write_config_dword(dev->pdev, PCI_LBPC, bclp); pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
else { else {
if (IS_IGD(dev)) { if (IS_PINEVIEW(dev)) {
blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1);
max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >>
BACKLIGHT_MODULATION_FREQ_SHIFT; BACKLIGHT_MODULATION_FREQ_SHIFT;
@ -224,7 +228,7 @@ void opregion_asle_intr(struct drm_device *dev)
asle_req = asle->aslc & ASLE_REQ_MSK; asle_req = asle->aslc & ASLE_REQ_MSK;
if (!asle_req) { if (!asle_req) {
DRM_DEBUG("non asle set request??\n"); DRM_DEBUG_DRIVER("non asle set request??\n");
return; return;
} }
@ -243,6 +247,73 @@ void opregion_asle_intr(struct drm_device *dev)
asle->aslc = asle_stat; asle->aslc = asle_stat;
} }
static u32 asle_set_backlight_ironlake(struct drm_device *dev, u32 bclp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct opregion_asle *asle = dev_priv->opregion.asle;
u32 cpu_pwm_ctl, pch_pwm_ctl2;
u32 max_backlight, level;
if (!(bclp & ASLE_BCLP_VALID))
return ASLE_BACKLIGHT_FAILED;
bclp &= ASLE_BCLP_MSK;
if (bclp < 0 || bclp > 255)
return ASLE_BACKLIGHT_FAILED;
cpu_pwm_ctl = I915_READ(BLC_PWM_CPU_CTL);
pch_pwm_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
/* get the max PWM frequency */
max_backlight = (pch_pwm_ctl2 >> 16) & BACKLIGHT_DUTY_CYCLE_MASK;
/* calculate the expected PMW frequency */
level = (bclp * max_backlight) / 255;
/* reserve the high 16 bits */
cpu_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK);
/* write the updated PWM frequency */
I915_WRITE(BLC_PWM_CPU_CTL, cpu_pwm_ctl | level);
asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
return 0;
}
void ironlake_opregion_gse_intr(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct opregion_asle *asle = dev_priv->opregion.asle;
u32 asle_stat = 0;
u32 asle_req;
if (!asle)
return;
asle_req = asle->aslc & ASLE_REQ_MSK;
if (!asle_req) {
DRM_DEBUG_DRIVER("non asle set request??\n");
return;
}
if (asle_req & ASLE_SET_ALS_ILLUM) {
DRM_DEBUG_DRIVER("Illum is not supported\n");
asle_stat |= ASLE_ALS_ILLUM_FAILED;
}
if (asle_req & ASLE_SET_BACKLIGHT)
asle_stat |= asle_set_backlight_ironlake(dev, asle->bclp);
if (asle_req & ASLE_SET_PFIT) {
DRM_DEBUG_DRIVER("Pfit is not supported\n");
asle_stat |= ASLE_PFIT_FAILED;
}
if (asle_req & ASLE_SET_PWM_FREQ) {
DRM_DEBUG_DRIVER("PWM freq is not supported\n");
asle_stat |= ASLE_PWM_FREQ_FAILED;
}
asle->aslc = asle_stat;
}
#define ASLE_ALS_EN (1<<0) #define ASLE_ALS_EN (1<<0)
#define ASLE_BLC_EN (1<<1) #define ASLE_BLC_EN (1<<1)
#define ASLE_PFIT_EN (1<<2) #define ASLE_PFIT_EN (1<<2)
@ -258,8 +329,7 @@ void opregion_enable_asle(struct drm_device *dev)
unsigned long irqflags; unsigned long irqflags;
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
i915_enable_pipestat(dev_priv, 1, intel_enable_asle(dev);
I915_LEGACY_BLC_EVENT_ENABLE);
spin_unlock_irqrestore(&dev_priv->user_irq_lock, spin_unlock_irqrestore(&dev_priv->user_irq_lock,
irqflags); irqflags);
} }
@ -361,9 +431,9 @@ int intel_opregion_init(struct drm_device *dev, int resume)
int err = 0; int err = 0;
pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls); DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
if (asls == 0) { if (asls == 0) {
DRM_DEBUG("ACPI OpRegion not supported!\n"); DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
return -ENOTSUPP; return -ENOTSUPP;
} }
@ -373,30 +443,30 @@ int intel_opregion_init(struct drm_device *dev, int resume)
opregion->header = base; opregion->header = base;
if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) { if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
DRM_DEBUG("opregion signature mismatch\n"); DRM_DEBUG_DRIVER("opregion signature mismatch\n");
err = -EINVAL; err = -EINVAL;
goto err_out; goto err_out;
} }
mboxes = opregion->header->mboxes; mboxes = opregion->header->mboxes;
if (mboxes & MBOX_ACPI) { if (mboxes & MBOX_ACPI) {
DRM_DEBUG("Public ACPI methods supported\n"); DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
opregion->acpi = base + OPREGION_ACPI_OFFSET; opregion->acpi = base + OPREGION_ACPI_OFFSET;
if (drm_core_check_feature(dev, DRIVER_MODESET)) if (drm_core_check_feature(dev, DRIVER_MODESET))
intel_didl_outputs(dev); intel_didl_outputs(dev);
} else { } else {
DRM_DEBUG("Public ACPI methods not supported\n"); DRM_DEBUG_DRIVER("Public ACPI methods not supported\n");
err = -ENOTSUPP; err = -ENOTSUPP;
goto err_out; goto err_out;
} }
opregion->enabled = 1; opregion->enabled = 1;
if (mboxes & MBOX_SWSCI) { if (mboxes & MBOX_SWSCI) {
DRM_DEBUG("SWSCI supported\n"); DRM_DEBUG_DRIVER("SWSCI supported\n");
opregion->swsci = base + OPREGION_SWSCI_OFFSET; opregion->swsci = base + OPREGION_SWSCI_OFFSET;
} }
if (mboxes & MBOX_ASLE) { if (mboxes & MBOX_ASLE) {
DRM_DEBUG("ASLE supported\n"); DRM_DEBUG_DRIVER("ASLE supported\n");
opregion->asle = base + OPREGION_ASLE_OFFSET; opregion->asle = base + OPREGION_ASLE_OFFSET;
opregion_enable_asle(dev); opregion_enable_asle(dev);
} }

View file

@ -140,6 +140,7 @@
#define MI_NOOP MI_INSTR(0, 0) #define MI_NOOP MI_INSTR(0, 0)
#define MI_USER_INTERRUPT MI_INSTR(0x02, 0) #define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0) #define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) #define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) #define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
@ -151,7 +152,13 @@
#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
#define MI_REPORT_HEAD MI_INSTR(0x07, 0) #define MI_REPORT_HEAD MI_INSTR(0x07, 0)
#define MI_OVERLAY_FLIP MI_INSTR(0x11,0)
#define MI_OVERLAY_CONTINUE (0x0<<21)
#define MI_OVERLAY_ON (0x1<<21)
#define MI_OVERLAY_OFF (0x2<<21)
#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
@ -260,6 +267,8 @@
#define HWS_PGA 0x02080 #define HWS_PGA 0x02080
#define HWS_ADDRESS_MASK 0xfffff000 #define HWS_ADDRESS_MASK 0xfffff000
#define HWS_START_ADDRESS_SHIFT 4 #define HWS_START_ADDRESS_SHIFT 4
#define PWRCTXA 0x2088 /* 965GM+ only */
#define PWRCTX_EN (1<<0)
#define IPEIR 0x02088 #define IPEIR 0x02088
#define IPEHR 0x0208c #define IPEHR 0x0208c
#define INSTDONE 0x02090 #define INSTDONE 0x02090
@ -405,6 +414,13 @@
# define GPIO_DATA_VAL_IN (1 << 12) # define GPIO_DATA_VAL_IN (1 << 12)
# define GPIO_DATA_PULLUP_DISABLE (1 << 13) # define GPIO_DATA_PULLUP_DISABLE (1 << 13)
#define GMBUS0 0x5100
#define GMBUS1 0x5104
#define GMBUS2 0x5108
#define GMBUS3 0x510c
#define GMBUS4 0x5110
#define GMBUS5 0x5120
/* /*
* Clock control & power management * Clock control & power management
*/ */
@ -435,7 +451,7 @@
#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ #define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
#define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */ #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */
#define I915_FIFO_UNDERRUN_STATUS (1UL<<31) #define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
#define I915_CRC_ERROR_ENABLE (1UL<<29) #define I915_CRC_ERROR_ENABLE (1UL<<29)
@ -512,7 +528,7 @@
*/ */
#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 #define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
#define DPLL_FPA01_P1_POST_DIV_SHIFT 16 #define DPLL_FPA01_P1_POST_DIV_SHIFT 16
#define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15 #define DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW 15
/* i830, required in DVO non-gang */ /* i830, required in DVO non-gang */
#define PLL_P2_DIVIDE_BY_4 (1 << 23) #define PLL_P2_DIVIDE_BY_4 (1 << 23)
#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ #define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
@ -522,7 +538,7 @@
#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) #define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
#define PLL_REF_INPUT_MASK (3 << 13) #define PLL_REF_INPUT_MASK (3 << 13)
#define PLL_LOAD_PULSE_PHASE_SHIFT 9 #define PLL_LOAD_PULSE_PHASE_SHIFT 9
/* IGDNG */ /* Ironlake */
# define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT 9 # define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT 9
# define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK (7 << 9) # define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK (7 << 9)
# define PLL_REF_SDVO_HDMI_MULTIPLIER(x) (((x)-1) << 9) # define PLL_REF_SDVO_HDMI_MULTIPLIER(x) (((x)-1) << 9)
@ -586,12 +602,12 @@
#define FPB0 0x06048 #define FPB0 0x06048
#define FPB1 0x0604c #define FPB1 0x0604c
#define FP_N_DIV_MASK 0x003f0000 #define FP_N_DIV_MASK 0x003f0000
#define FP_N_IGD_DIV_MASK 0x00ff0000 #define FP_N_PINEVIEW_DIV_MASK 0x00ff0000
#define FP_N_DIV_SHIFT 16 #define FP_N_DIV_SHIFT 16
#define FP_M1_DIV_MASK 0x00003f00 #define FP_M1_DIV_MASK 0x00003f00
#define FP_M1_DIV_SHIFT 8 #define FP_M1_DIV_SHIFT 8
#define FP_M2_DIV_MASK 0x0000003f #define FP_M2_DIV_MASK 0x0000003f
#define FP_M2_IGD_DIV_MASK 0x000000ff #define FP_M2_PINEVIEW_DIV_MASK 0x000000ff
#define FP_M2_DIV_SHIFT 0 #define FP_M2_DIV_SHIFT 0
#define DPLL_TEST 0x606c #define DPLL_TEST 0x606c
#define DPLLB_TEST_SDVO_DIV_1 (0 << 22) #define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
@ -769,7 +785,8 @@
/** GM965 GM45 render standby register */ /** GM965 GM45 render standby register */
#define MCHBAR_RENDER_STANDBY 0x111B8 #define MCHBAR_RENDER_STANDBY 0x111B8
#define RCX_SW_EXIT (1<<23)
#define RSX_STATUS_MASK 0x00700000
#define PEG_BAND_GAP_DATA 0x14d68 #define PEG_BAND_GAP_DATA 0x14d68
/* /*
@ -844,7 +861,6 @@
#define SDVOB_HOTPLUG_INT_EN (1 << 26) #define SDVOB_HOTPLUG_INT_EN (1 << 26)
#define SDVOC_HOTPLUG_INT_EN (1 << 25) #define SDVOC_HOTPLUG_INT_EN (1 << 25)
#define TV_HOTPLUG_INT_EN (1 << 18) #define TV_HOTPLUG_INT_EN (1 << 18)
#define CRT_EOS_INT_EN (1 << 10)
#define CRT_HOTPLUG_INT_EN (1 << 9) #define CRT_HOTPLUG_INT_EN (1 << 9)
#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) #define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) #define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8)
@ -868,7 +884,6 @@
HDMID_HOTPLUG_INT_EN | \ HDMID_HOTPLUG_INT_EN | \
SDVOB_HOTPLUG_INT_EN | \ SDVOB_HOTPLUG_INT_EN | \
SDVOC_HOTPLUG_INT_EN | \ SDVOC_HOTPLUG_INT_EN | \
TV_HOTPLUG_INT_EN | \
CRT_HOTPLUG_INT_EN) CRT_HOTPLUG_INT_EN)
@ -879,7 +894,6 @@
#define DPC_HOTPLUG_INT_STATUS (1 << 28) #define DPC_HOTPLUG_INT_STATUS (1 << 28)
#define HDMID_HOTPLUG_INT_STATUS (1 << 27) #define HDMID_HOTPLUG_INT_STATUS (1 << 27)
#define DPD_HOTPLUG_INT_STATUS (1 << 27) #define DPD_HOTPLUG_INT_STATUS (1 << 27)
#define CRT_EOS_INT_STATUS (1 << 12)
#define CRT_HOTPLUG_INT_STATUS (1 << 11) #define CRT_HOTPLUG_INT_STATUS (1 << 11)
#define TV_HOTPLUG_INT_STATUS (1 << 10) #define TV_HOTPLUG_INT_STATUS (1 << 10)
#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) #define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
@ -1620,7 +1634,7 @@
#define DP_CLOCK_OUTPUT_ENABLE (1 << 13) #define DP_CLOCK_OUTPUT_ENABLE (1 << 13)
#define DP_SCRAMBLING_DISABLE (1 << 12) #define DP_SCRAMBLING_DISABLE (1 << 12)
#define DP_SCRAMBLING_DISABLE_IGDNG (1 << 7) #define DP_SCRAMBLING_DISABLE_IRONLAKE (1 << 7)
/** limit RGB values to avoid confusing TVs */ /** limit RGB values to avoid confusing TVs */
#define DP_COLOR_RANGE_16_235 (1 << 8) #define DP_COLOR_RANGE_16_235 (1 << 8)
@ -1808,7 +1822,7 @@
#define DSPFW3 0x7003c #define DSPFW3 0x7003c
#define DSPFW_HPLL_SR_EN (1<<31) #define DSPFW_HPLL_SR_EN (1<<31)
#define DSPFW_CURSOR_SR_SHIFT 24 #define DSPFW_CURSOR_SR_SHIFT 24
#define IGD_SELF_REFRESH_EN (1<<30) #define PINEVIEW_SELF_REFRESH_EN (1<<30)
/* FIFO watermark sizes etc */ /* FIFO watermark sizes etc */
#define G4X_FIFO_LINE_SIZE 64 #define G4X_FIFO_LINE_SIZE 64
@ -1824,16 +1838,16 @@
#define G4X_MAX_WM 0x3f #define G4X_MAX_WM 0x3f
#define I915_MAX_WM 0x3f #define I915_MAX_WM 0x3f
#define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ #define PINEVIEW_DISPLAY_FIFO 512 /* in 64byte unit */
#define IGD_FIFO_LINE_SIZE 64 #define PINEVIEW_FIFO_LINE_SIZE 64
#define IGD_MAX_WM 0x1ff #define PINEVIEW_MAX_WM 0x1ff
#define IGD_DFT_WM 0x3f #define PINEVIEW_DFT_WM 0x3f
#define IGD_DFT_HPLLOFF_WM 0 #define PINEVIEW_DFT_HPLLOFF_WM 0
#define IGD_GUARD_WM 10 #define PINEVIEW_GUARD_WM 10
#define IGD_CURSOR_FIFO 64 #define PINEVIEW_CURSOR_FIFO 64
#define IGD_CURSOR_MAX_WM 0x3f #define PINEVIEW_CURSOR_MAX_WM 0x3f
#define IGD_CURSOR_DFT_WM 0 #define PINEVIEW_CURSOR_DFT_WM 0
#define IGD_CURSOR_GUARD_WM 5 #define PINEVIEW_CURSOR_GUARD_WM 5
/* /*
* The two pipe frame counter registers are not synchronized, so * The two pipe frame counter registers are not synchronized, so
@ -1907,6 +1921,7 @@
#define DISPPLANE_16BPP (0x5<<26) #define DISPPLANE_16BPP (0x5<<26)
#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) #define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
#define DISPPLANE_32BPP (0x7<<26) #define DISPPLANE_32BPP (0x7<<26)
#define DISPPLANE_32BPP_30BIT_NO_ALPHA (0xa<<26)
#define DISPPLANE_STEREO_ENABLE (1<<25) #define DISPPLANE_STEREO_ENABLE (1<<25)
#define DISPPLANE_STEREO_DISABLE 0 #define DISPPLANE_STEREO_DISABLE 0
#define DISPPLANE_SEL_PIPE_MASK (1<<24) #define DISPPLANE_SEL_PIPE_MASK (1<<24)
@ -1918,7 +1933,7 @@
#define DISPPLANE_NO_LINE_DOUBLE 0 #define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0 #define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* IGDNG */ #define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* Ironlake */
#define DISPPLANE_TILED (1<<10) #define DISPPLANE_TILED (1<<10)
#define DSPAADDR 0x70184 #define DSPAADDR 0x70184
#define DSPASTRIDE 0x70188 #define DSPASTRIDE 0x70188
@ -1971,7 +1986,7 @@
# define VGA_2X_MODE (1 << 30) # define VGA_2X_MODE (1 << 30)
# define VGA_PIPE_B_SELECT (1 << 29) # define VGA_PIPE_B_SELECT (1 << 29)
/* IGDNG */ /* Ironlake */
#define CPU_VGACNTRL 0x41000 #define CPU_VGACNTRL 0x41000
@ -2117,6 +2132,7 @@
#define SDE_PORTC_HOTPLUG (1 << 9) #define SDE_PORTC_HOTPLUG (1 << 9)
#define SDE_PORTB_HOTPLUG (1 << 8) #define SDE_PORTB_HOTPLUG (1 << 8)
#define SDE_SDVOB_HOTPLUG (1 << 6) #define SDE_SDVOB_HOTPLUG (1 << 6)
#define SDE_HOTPLUG_MASK (0xf << 8)
#define SDEISR 0xc4000 #define SDEISR 0xc4000
#define SDEIMR 0xc4004 #define SDEIMR 0xc4004
@ -2157,6 +2173,13 @@
#define PCH_GPIOE 0xc5020 #define PCH_GPIOE 0xc5020
#define PCH_GPIOF 0xc5024 #define PCH_GPIOF 0xc5024
#define PCH_GMBUS0 0xc5100
#define PCH_GMBUS1 0xc5104
#define PCH_GMBUS2 0xc5108
#define PCH_GMBUS3 0xc510c
#define PCH_GMBUS4 0xc5110
#define PCH_GMBUS5 0xc5120
#define PCH_DPLL_A 0xc6014 #define PCH_DPLL_A 0xc6014
#define PCH_DPLL_B 0xc6018 #define PCH_DPLL_B 0xc6018
@ -2292,7 +2315,7 @@
#define FDI_DP_PORT_WIDTH_X3 (2<<19) #define FDI_DP_PORT_WIDTH_X3 (2<<19)
#define FDI_DP_PORT_WIDTH_X4 (3<<19) #define FDI_DP_PORT_WIDTH_X4 (3<<19)
#define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18) #define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18)
/* IGDNG: hardwired to 1 */ /* Ironlake: hardwired to 1 */
#define FDI_TX_PLL_ENABLE (1<<14) #define FDI_TX_PLL_ENABLE (1<<14)
/* both Tx and Rx */ /* both Tx and Rx */
#define FDI_SCRAMBLING_ENABLE (0<<7) #define FDI_SCRAMBLING_ENABLE (0<<7)

View file

@ -27,14 +27,14 @@
#include "drmP.h" #include "drmP.h"
#include "drm.h" #include "drm.h"
#include "i915_drm.h" #include "i915_drm.h"
#include "i915_drv.h" #include "intel_drv.h"
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll_reg; u32 dpll_reg;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B;
} else { } else {
dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B;
@ -53,7 +53,7 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
if (!i915_pipe_enabled(dev, pipe)) if (!i915_pipe_enabled(dev, pipe))
return; return;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
if (pipe == PIPE_A) if (pipe == PIPE_A)
@ -75,7 +75,7 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
if (!i915_pipe_enabled(dev, pipe)) if (!i915_pipe_enabled(dev, pipe))
return; return;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B;
if (pipe == PIPE_A) if (pipe == PIPE_A)
@ -239,7 +239,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET)) if (drm_core_check_feature(dev, DRIVER_MODESET))
return; return;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
} }
@ -247,7 +247,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
/* Pipe & plane A info */ /* Pipe & plane A info */
dev_priv->savePIPEACONF = I915_READ(PIPEACONF); dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
dev_priv->savePIPEASRC = I915_READ(PIPEASRC); dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->saveFPA0 = I915_READ(PCH_FPA0); dev_priv->saveFPA0 = I915_READ(PCH_FPA0);
dev_priv->saveFPA1 = I915_READ(PCH_FPA1); dev_priv->saveFPA1 = I915_READ(PCH_FPA1);
dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A);
@ -256,7 +256,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveFPA1 = I915_READ(FPA1); dev_priv->saveFPA1 = I915_READ(FPA1);
dev_priv->saveDPLL_A = I915_READ(DPLL_A); dev_priv->saveDPLL_A = I915_READ(DPLL_A);
} }
if (IS_I965G(dev) && !IS_IGDNG(dev)) if (IS_I965G(dev) && !IS_IRONLAKE(dev))
dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
@ -264,10 +264,10 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
if (!IS_IGDNG(dev)) if (!IS_IRONLAKE(dev))
dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
@ -304,7 +304,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
/* Pipe & plane B info */ /* Pipe & plane B info */
dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->saveFPB0 = I915_READ(PCH_FPB0); dev_priv->saveFPB0 = I915_READ(PCH_FPB0);
dev_priv->saveFPB1 = I915_READ(PCH_FPB1); dev_priv->saveFPB1 = I915_READ(PCH_FPB1);
dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B);
@ -313,7 +313,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveFPB1 = I915_READ(FPB1); dev_priv->saveFPB1 = I915_READ(FPB1);
dev_priv->saveDPLL_B = I915_READ(DPLL_B); dev_priv->saveDPLL_B = I915_READ(DPLL_B);
} }
if (IS_I965G(dev) && !IS_IGDNG(dev)) if (IS_I965G(dev) && !IS_IRONLAKE(dev))
dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
@ -321,10 +321,10 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
if (!IS_IGDNG(dev)) if (!IS_IRONLAKE(dev))
dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
@ -369,7 +369,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET)) if (drm_core_check_feature(dev, DRIVER_MODESET))
return; return;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dpll_a_reg = PCH_DPLL_A; dpll_a_reg = PCH_DPLL_A;
dpll_b_reg = PCH_DPLL_B; dpll_b_reg = PCH_DPLL_B;
fpa0_reg = PCH_FPA0; fpa0_reg = PCH_FPA0;
@ -385,7 +385,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
fpb1_reg = FPB1; fpb1_reg = FPB1;
} }
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
} }
@ -402,7 +402,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
/* Actually enable it */ /* Actually enable it */
I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A);
DRM_UDELAY(150); DRM_UDELAY(150);
if (IS_I965G(dev) && !IS_IGDNG(dev)) if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
DRM_UDELAY(150); DRM_UDELAY(150);
@ -413,10 +413,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
if (!IS_IGDNG(dev)) if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
@ -467,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
/* Actually enable it */ /* Actually enable it */
I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
DRM_UDELAY(150); DRM_UDELAY(150);
if (IS_I965G(dev) && !IS_IGDNG(dev)) if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
DRM_UDELAY(150); DRM_UDELAY(150);
@ -478,10 +478,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
if (!IS_IGDNG(dev)) if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
@ -546,14 +546,14 @@ void i915_save_display(struct drm_device *dev)
dev_priv->saveCURSIZE = I915_READ(CURSIZE); dev_priv->saveCURSIZE = I915_READ(CURSIZE);
/* CRT state */ /* CRT state */
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->saveADPA = I915_READ(PCH_ADPA); dev_priv->saveADPA = I915_READ(PCH_ADPA);
} else { } else {
dev_priv->saveADPA = I915_READ(ADPA); dev_priv->saveADPA = I915_READ(ADPA);
} }
/* LVDS state */ /* LVDS state */
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
@ -571,10 +571,10 @@ void i915_save_display(struct drm_device *dev)
dev_priv->saveLVDS = I915_READ(LVDS); dev_priv->saveLVDS = I915_READ(LVDS);
} }
if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev)) if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS);
dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS);
dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR);
@ -614,7 +614,7 @@ void i915_save_display(struct drm_device *dev)
dev_priv->saveVGA0 = I915_READ(VGA0); dev_priv->saveVGA0 = I915_READ(VGA0);
dev_priv->saveVGA1 = I915_READ(VGA1); dev_priv->saveVGA1 = I915_READ(VGA1);
dev_priv->saveVGA_PD = I915_READ(VGA_PD); dev_priv->saveVGA_PD = I915_READ(VGA_PD);
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL);
else else
dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
@ -656,24 +656,24 @@ void i915_restore_display(struct drm_device *dev)
I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
/* CRT state */ /* CRT state */
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
I915_WRITE(PCH_ADPA, dev_priv->saveADPA); I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
else else
I915_WRITE(ADPA, dev_priv->saveADPA); I915_WRITE(ADPA, dev_priv->saveADPA);
/* LVDS state */ /* LVDS state */
if (IS_I965G(dev) && !IS_IGDNG(dev)) if (IS_I965G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); I915_WRITE(PCH_LVDS, dev_priv->saveLVDS);
} else if (IS_MOBILE(dev) && !IS_I830(dev)) } else if (IS_MOBILE(dev) && !IS_I830(dev))
I915_WRITE(LVDS, dev_priv->saveLVDS); I915_WRITE(LVDS, dev_priv->saveLVDS);
if (!IS_I830(dev) && !IS_845G(dev) && !IS_IGDNG(dev)) if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev))
I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL);
I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2);
I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL);
@ -713,7 +713,7 @@ void i915_restore_display(struct drm_device *dev)
} }
/* VGA state */ /* VGA state */
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
else else
I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
@ -733,8 +733,10 @@ int i915_save_state(struct drm_device *dev)
pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
/* Render Standby */ /* Render Standby */
if (IS_I965G(dev) && IS_MOBILE(dev)) if (I915_HAS_RC6(dev)) {
dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY);
dev_priv->savePWRCTXA = I915_READ(PWRCTXA);
}
/* Hardware status page */ /* Hardware status page */
dev_priv->saveHWS = I915_READ(HWS_PGA); dev_priv->saveHWS = I915_READ(HWS_PGA);
@ -742,7 +744,7 @@ int i915_save_state(struct drm_device *dev)
i915_save_display(dev); i915_save_display(dev);
/* Interrupt state */ /* Interrupt state */
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
dev_priv->saveDEIER = I915_READ(DEIER); dev_priv->saveDEIER = I915_READ(DEIER);
dev_priv->saveDEIMR = I915_READ(DEIMR); dev_priv->saveDEIMR = I915_READ(DEIMR);
dev_priv->saveGTIER = I915_READ(GTIER); dev_priv->saveGTIER = I915_READ(GTIER);
@ -796,8 +798,10 @@ int i915_restore_state(struct drm_device *dev)
pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
/* Render Standby */ /* Render Standby */
if (IS_I965G(dev) && IS_MOBILE(dev)) if (I915_HAS_RC6(dev)) {
I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY);
I915_WRITE(PWRCTXA, dev_priv->savePWRCTXA);
}
/* Hardware status page */ /* Hardware status page */
I915_WRITE(HWS_PGA, dev_priv->saveHWS); I915_WRITE(HWS_PGA, dev_priv->saveHWS);
@ -817,7 +821,7 @@ int i915_restore_state(struct drm_device *dev)
i915_restore_display(dev); i915_restore_display(dev);
/* Interrupt state */ /* Interrupt state */
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(DEIER, dev_priv->saveDEIER); I915_WRITE(DEIER, dev_priv->saveDEIER);
I915_WRITE(DEIMR, dev_priv->saveDEIMR); I915_WRITE(DEIMR, dev_priv->saveDEIMR);
I915_WRITE(GTIER, dev_priv->saveGTIER); I915_WRITE(GTIER, dev_priv->saveGTIER);
@ -846,6 +850,9 @@ int i915_restore_state(struct drm_device *dev)
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
/* I2C state */
intel_i2c_reset_gmbus(dev);
return 0; return 0;
} }

View file

@ -114,6 +114,8 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
struct lvds_dvo_timing *dvo_timing; struct lvds_dvo_timing *dvo_timing;
struct drm_display_mode *panel_fixed_mode; struct drm_display_mode *panel_fixed_mode;
int lfp_data_size, dvo_timing_offset; int lfp_data_size, dvo_timing_offset;
int i, temp_downclock;
struct drm_display_mode *temp_mode;
/* Defaults if we can't find VBT info */ /* Defaults if we can't find VBT info */
dev_priv->lvds_dither = 0; dev_priv->lvds_dither = 0;
@ -159,9 +161,49 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
DRM_DEBUG("Found panel mode in BIOS VBT tables:\n"); DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
drm_mode_debug_printmodeline(panel_fixed_mode); drm_mode_debug_printmodeline(panel_fixed_mode);
temp_mode = kzalloc(sizeof(*temp_mode), GFP_KERNEL);
temp_downclock = panel_fixed_mode->clock;
/*
* enumerate the LVDS panel timing info entry in VBT to check whether
* the LVDS downclock is found.
*/
for (i = 0; i < 16; i++) {
entry = (struct bdb_lvds_lfp_data_entry *)
((uint8_t *)lvds_lfp_data->data + (lfp_data_size * i));
dvo_timing = (struct lvds_dvo_timing *)
((unsigned char *)entry + dvo_timing_offset);
fill_detail_timing_data(temp_mode, dvo_timing);
if (temp_mode->hdisplay == panel_fixed_mode->hdisplay &&
temp_mode->hsync_start == panel_fixed_mode->hsync_start &&
temp_mode->hsync_end == panel_fixed_mode->hsync_end &&
temp_mode->htotal == panel_fixed_mode->htotal &&
temp_mode->vdisplay == panel_fixed_mode->vdisplay &&
temp_mode->vsync_start == panel_fixed_mode->vsync_start &&
temp_mode->vsync_end == panel_fixed_mode->vsync_end &&
temp_mode->vtotal == panel_fixed_mode->vtotal &&
temp_mode->clock < temp_downclock) {
/*
* downclock is already found. But we expect
* to find the lower downclock.
*/
temp_downclock = temp_mode->clock;
}
/* clear it to zero */
memset(temp_mode, 0, sizeof(*temp_mode));
}
kfree(temp_mode);
if (temp_downclock < panel_fixed_mode->clock) {
dev_priv->lvds_downclock_avail = 1;
dev_priv->lvds_downclock = temp_downclock;
DRM_DEBUG_KMS("LVDS downclock is found in VBT. ",
"Normal Clock %dKHz, downclock %dKHz\n",
temp_downclock, panel_fixed_mode->clock);
}
return; return;
} }
@ -217,7 +259,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
if (IS_I85X(dev_priv->dev)) if (IS_I85X(dev_priv->dev))
dev_priv->lvds_ssc_freq = dev_priv->lvds_ssc_freq =
general->ssc_freq ? 66 : 48; general->ssc_freq ? 66 : 48;
else if (IS_IGDNG(dev_priv->dev)) else if (IS_IRONLAKE(dev_priv->dev))
dev_priv->lvds_ssc_freq = dev_priv->lvds_ssc_freq =
general->ssc_freq ? 100 : 120; general->ssc_freq ? 100 : 120;
else else
@ -241,22 +283,18 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
GPIOF, GPIOF,
}; };
/* Set sensible defaults in case we can't find the general block
or it is the wrong chipset */
dev_priv->crt_ddc_bus = -1;
general = find_section(bdb, BDB_GENERAL_DEFINITIONS); general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
if (general) { if (general) {
u16 block_size = get_blocksize(general); u16 block_size = get_blocksize(general);
if (block_size >= sizeof(*general)) { if (block_size >= sizeof(*general)) {
int bus_pin = general->crt_ddc_gmbus_pin; int bus_pin = general->crt_ddc_gmbus_pin;
DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin); DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
if ((bus_pin >= 1) && (bus_pin <= 6)) { if ((bus_pin >= 1) && (bus_pin <= 6)) {
dev_priv->crt_ddc_bus = dev_priv->crt_ddc_bus =
crt_bus_map_table[bus_pin-1]; crt_bus_map_table[bus_pin-1];
} }
} else { } else {
DRM_DEBUG("BDB_GD too small (%d). Invalid.\n", DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
block_size); block_size);
} }
} }
@ -274,7 +312,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
if (!p_defs) { if (!p_defs) {
DRM_DEBUG("No general definition block is found\n"); DRM_DEBUG_KMS("No general definition block is found\n");
return; return;
} }
/* judge whether the size of child device meets the requirements. /* judge whether the size of child device meets the requirements.
@ -284,7 +322,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
*/ */
if (p_defs->child_dev_size != sizeof(*p_child)) { if (p_defs->child_dev_size != sizeof(*p_child)) {
/* different child dev size . Ignore it */ /* different child dev size . Ignore it */
DRM_DEBUG("different child size is found. Invalid.\n"); DRM_DEBUG_KMS("different child size is found. Invalid.\n");
return; return;
} }
/* get the block size of general definitions */ /* get the block size of general definitions */
@ -310,11 +348,11 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
if (p_child->dvo_port != DEVICE_PORT_DVOB && if (p_child->dvo_port != DEVICE_PORT_DVOB &&
p_child->dvo_port != DEVICE_PORT_DVOC) { p_child->dvo_port != DEVICE_PORT_DVOC) {
/* skip the incorrect SDVO port */ /* skip the incorrect SDVO port */
DRM_DEBUG("Incorrect SDVO port. Skip it \n"); DRM_DEBUG_KMS("Incorrect SDVO port. Skip it \n");
continue; continue;
} }
DRM_DEBUG("the SDVO device with slave addr %2x is found on " DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
"%s port\n", " %s port\n",
p_child->slave_addr, p_child->slave_addr,
(p_child->dvo_port == DEVICE_PORT_DVOB) ? (p_child->dvo_port == DEVICE_PORT_DVOB) ?
"SDVOB" : "SDVOC"); "SDVOB" : "SDVOC");
@ -325,21 +363,21 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
p_mapping->dvo_wiring = p_child->dvo_wiring; p_mapping->dvo_wiring = p_child->dvo_wiring;
p_mapping->initialized = 1; p_mapping->initialized = 1;
} else { } else {
DRM_DEBUG("Maybe one SDVO port is shared by " DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
"two SDVO device.\n"); "two SDVO device.\n");
} }
if (p_child->slave2_addr) { if (p_child->slave2_addr) {
/* Maybe this is a SDVO device with multiple inputs */ /* Maybe this is a SDVO device with multiple inputs */
/* And the mapping info is not added */ /* And the mapping info is not added */
DRM_DEBUG("there exists the slave2_addr. Maybe this " DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
"is a SDVO device with multiple inputs.\n"); " is a SDVO device with multiple inputs.\n");
} }
count++; count++;
} }
if (!count) { if (!count) {
/* No SDVO device info is found */ /* No SDVO device info is found */
DRM_DEBUG("No SDVO device info is found in VBT\n"); DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
} }
return; return;
} }
@ -366,6 +404,70 @@ parse_driver_features(struct drm_i915_private *dev_priv,
dev_priv->render_reclock_avail = true; dev_priv->render_reclock_avail = true;
} }
static void
parse_device_mapping(struct drm_i915_private *dev_priv,
struct bdb_header *bdb)
{
struct bdb_general_definitions *p_defs;
struct child_device_config *p_child, *child_dev_ptr;
int i, child_device_num, count;
u16 block_size;
p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
if (!p_defs) {
DRM_DEBUG_KMS("No general definition block is found\n");
return;
}
/* judge whether the size of child device meets the requirements.
* If the child device size obtained from general definition block
* is different with sizeof(struct child_device_config), skip the
* parsing of sdvo device info
*/
if (p_defs->child_dev_size != sizeof(*p_child)) {
/* different child dev size . Ignore it */
DRM_DEBUG_KMS("different child size is found. Invalid.\n");
return;
}
/* get the block size of general definitions */
block_size = get_blocksize(p_defs);
/* get the number of child device */
child_device_num = (block_size - sizeof(*p_defs)) /
sizeof(*p_child);
count = 0;
/* get the number of child device that is present */
for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]);
if (!p_child->device_type) {
/* skip the device block if device type is invalid */
continue;
}
count++;
}
if (!count) {
DRM_DEBUG_KMS("no child dev is parsed from VBT \n");
return;
}
dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
if (!dev_priv->child_dev) {
DRM_DEBUG_KMS("No memory space for child device\n");
return;
}
dev_priv->child_dev_num = count;
count = 0;
for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]);
if (!p_child->device_type) {
/* skip the device block if device type is invalid */
continue;
}
child_dev_ptr = dev_priv->child_dev + count;
count++;
memcpy((void *)child_dev_ptr, (void *)p_child,
sizeof(*p_child));
}
return;
}
/** /**
* intel_init_bios - initialize VBIOS settings & find VBT * intel_init_bios - initialize VBIOS settings & find VBT
* @dev: DRM device * @dev: DRM device
@ -417,6 +519,7 @@ intel_init_bios(struct drm_device *dev)
parse_lfp_panel_data(dev_priv, bdb); parse_lfp_panel_data(dev_priv, bdb);
parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb);
parse_sdvo_device_mapping(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb);
parse_device_mapping(dev_priv, bdb);
parse_driver_features(dev_priv, bdb); parse_driver_features(dev_priv, bdb);
pci_unmap_rom(pdev, bios); pci_unmap_rom(pdev, bios);

View file

@ -549,4 +549,21 @@ bool intel_init_bios(struct drm_device *dev);
#define SWF14_APM_STANDBY 0x1 #define SWF14_APM_STANDBY 0x1
#define SWF14_APM_RESTORE 0x0 #define SWF14_APM_RESTORE 0x0
/* Add the device class for LFP, TV, HDMI */
#define DEVICE_TYPE_INT_LFP 0x1022
#define DEVICE_TYPE_INT_TV 0x1009
#define DEVICE_TYPE_HDMI 0x60D2
#define DEVICE_TYPE_DP 0x68C6
#define DEVICE_TYPE_eDP 0x78C6
/* define the DVO port for HDMI output type */
#define DVO_B 1
#define DVO_C 2
#define DVO_D 3
/* define the PORT for DP output type */
#define PORT_IDPB 7
#define PORT_IDPC 8
#define PORT_IDPD 9
#endif /* _I830_BIOS_H_ */ #endif /* _I830_BIOS_H_ */

View file

@ -39,7 +39,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp, reg; u32 temp, reg;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
reg = PCH_ADPA; reg = PCH_ADPA;
else else
reg = ADPA; reg = ADPA;
@ -64,34 +64,6 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
} }
I915_WRITE(reg, temp); I915_WRITE(reg, temp);
if (IS_IGD(dev)) {
if (mode == DRM_MODE_DPMS_OFF) {
/* turn off DAC */
temp = I915_READ(PORT_HOTPLUG_EN);
temp &= ~CRT_EOS_INT_EN;
I915_WRITE(PORT_HOTPLUG_EN, temp);
temp = I915_READ(PORT_HOTPLUG_STAT);
if (temp & CRT_EOS_INT_STATUS)
I915_WRITE(PORT_HOTPLUG_STAT,
CRT_EOS_INT_STATUS);
} else {
/* turn on DAC. EOS interrupt must be enabled after DAC
* is enabled, so it sounds not good to enable it in
* i915_driver_irq_postinstall()
* wait 12.5ms after DAC is enabled
*/
msleep(13);
temp = I915_READ(PORT_HOTPLUG_STAT);
if (temp & CRT_EOS_INT_STATUS)
I915_WRITE(PORT_HOTPLUG_STAT,
CRT_EOS_INT_STATUS);
temp = I915_READ(PORT_HOTPLUG_EN);
temp |= CRT_EOS_INT_EN;
I915_WRITE(PORT_HOTPLUG_EN, temp);
}
}
} }
static int intel_crt_mode_valid(struct drm_connector *connector, static int intel_crt_mode_valid(struct drm_connector *connector,
@ -141,7 +113,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
else else
dpll_md_reg = DPLL_B_MD; dpll_md_reg = DPLL_B_MD;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
adpa_reg = PCH_ADPA; adpa_reg = PCH_ADPA;
else else
adpa_reg = ADPA; adpa_reg = ADPA;
@ -150,7 +122,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
* Disable separate mode multiplier used when cloning SDVO to CRT * Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning * XXX this needs to be adjusted when we really are cloning
*/ */
if (IS_I965G(dev) && !IS_IGDNG(dev)) { if (IS_I965G(dev) && !IS_IRONLAKE(dev)) {
dpll_md = I915_READ(dpll_md_reg); dpll_md = I915_READ(dpll_md_reg);
I915_WRITE(dpll_md_reg, I915_WRITE(dpll_md_reg,
dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@ -164,18 +136,18 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
if (intel_crtc->pipe == 0) { if (intel_crtc->pipe == 0) {
adpa |= ADPA_PIPE_A_SELECT; adpa |= ADPA_PIPE_A_SELECT;
if (!IS_IGDNG(dev)) if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_A, 0); I915_WRITE(BCLRPAT_A, 0);
} else { } else {
adpa |= ADPA_PIPE_B_SELECT; adpa |= ADPA_PIPE_B_SELECT;
if (!IS_IGDNG(dev)) if (!IS_IRONLAKE(dev))
I915_WRITE(BCLRPAT_B, 0); I915_WRITE(BCLRPAT_B, 0);
} }
I915_WRITE(adpa_reg, adpa); I915_WRITE(adpa_reg, adpa);
} }
static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
@ -194,7 +166,7 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
ADPA_CRT_HOTPLUG_ENABLE | ADPA_CRT_HOTPLUG_ENABLE |
ADPA_CRT_HOTPLUG_FORCE_TRIGGER); ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
DRM_DEBUG("pch crt adpa 0x%x", adpa); DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
I915_WRITE(PCH_ADPA, adpa); I915_WRITE(PCH_ADPA, adpa);
while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0)
@ -227,8 +199,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
u32 hotplug_en; u32 hotplug_en;
int i, tries = 0; int i, tries = 0;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
return intel_igdng_crt_detect_hotplug(connector); return intel_ironlake_crt_detect_hotplug(connector);
/* /*
* On 4 series desktop, CRT detect sequence need to be done twice * On 4 series desktop, CRT detect sequence need to be done twice
@ -549,12 +521,12 @@ void intel_crt_init(struct drm_device *dev)
&intel_output->enc); &intel_output->enc);
/* Set up the DDC bus. */ /* Set up the DDC bus. */
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
i2c_reg = PCH_GPIOA; i2c_reg = PCH_GPIOA;
else { else {
i2c_reg = GPIOA; i2c_reg = GPIOA;
/* Use VBT information for CRT DDC if available */ /* Use VBT information for CRT DDC if available */
if (dev_priv->crt_ddc_bus != -1) if (dev_priv->crt_ddc_bus != 0)
i2c_reg = dev_priv->crt_ddc_bus; i2c_reg = dev_priv->crt_ddc_bus;
} }
intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");

File diff suppressed because it is too large Load diff

View file

@ -35,6 +35,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "drm_dp_helper.h" #include "drm_dp_helper.h"
#define DP_LINK_STATUS_SIZE 6 #define DP_LINK_STATUS_SIZE 6
#define DP_LINK_CHECK_TIMEOUT (10 * 1000) #define DP_LINK_CHECK_TIMEOUT (10 * 1000)
@ -223,8 +224,8 @@ intel_dp_aux_ch(struct intel_output *intel_output,
*/ */
if (IS_eDP(intel_output)) if (IS_eDP(intel_output))
aux_clock_divider = 225; /* eDP input clock at 450Mhz */ aux_clock_divider = 225; /* eDP input clock at 450Mhz */
else if (IS_IGDNG(dev)) else if (IS_IRONLAKE(dev))
aux_clock_divider = 62; /* IGDNG: input clock fixed at 125Mhz */ aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
else else
aux_clock_divider = intel_hrawclk(dev) / 2; aux_clock_divider = intel_hrawclk(dev) / 2;
@ -282,7 +283,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
/* Timeouts occur when the device isn't connected, so they're /* Timeouts occur when the device isn't connected, so they're
* "normal" -- don't fill the kernel log with these */ * "normal" -- don't fill the kernel log with these */
if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) {
DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status); DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
@ -432,7 +433,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
msg, msg_bytes, msg, msg_bytes,
reply, reply_bytes); reply, reply_bytes);
if (ret < 0) { if (ret < 0) {
DRM_DEBUG("aux_ch failed %d\n", ret); DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
return ret; return ret;
} }
switch (reply[0] & AUX_I2C_REPLY_MASK) { switch (reply[0] & AUX_I2C_REPLY_MASK) {
@ -442,10 +443,10 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
} }
return reply_bytes - 1; return reply_bytes - 1;
case AUX_I2C_REPLY_NACK: case AUX_I2C_REPLY_NACK:
DRM_DEBUG("aux_ch nack\n"); DRM_DEBUG_KMS("aux_ch nack\n");
return -EREMOTEIO; return -EREMOTEIO;
case AUX_I2C_REPLY_DEFER: case AUX_I2C_REPLY_DEFER:
DRM_DEBUG("aux_ch defer\n"); DRM_DEBUG_KMS("aux_ch defer\n");
udelay(100); udelay(100);
break; break;
default: default:
@ -495,7 +496,8 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
dp_priv->link_bw = bws[clock]; dp_priv->link_bw = bws[clock];
dp_priv->lane_count = lane_count; dp_priv->lane_count = lane_count;
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n", DRM_DEBUG_KMS("Display port link bw %02x lane "
"count %d clock %d\n",
dp_priv->link_bw, dp_priv->lane_count, dp_priv->link_bw, dp_priv->lane_count,
adjusted_mode->clock); adjusted_mode->clock);
return true; return true;
@ -574,7 +576,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
intel_dp_compute_m_n(3, lane_count, intel_dp_compute_m_n(3, lane_count,
mode->clock, adjusted_mode->clock, &m_n); mode->clock, adjusted_mode->clock, &m_n);
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
if (intel_crtc->pipe == 0) { if (intel_crtc->pipe == 0) {
I915_WRITE(TRANSA_DATA_M1, I915_WRITE(TRANSA_DATA_M1,
((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
@ -666,23 +668,23 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
} }
} }
static void igdng_edp_backlight_on (struct drm_device *dev) static void ironlake_edp_backlight_on (struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp; u32 pp;
DRM_DEBUG("\n"); DRM_DEBUG_KMS("\n");
pp = I915_READ(PCH_PP_CONTROL); pp = I915_READ(PCH_PP_CONTROL);
pp |= EDP_BLC_ENABLE; pp |= EDP_BLC_ENABLE;
I915_WRITE(PCH_PP_CONTROL, pp); I915_WRITE(PCH_PP_CONTROL, pp);
} }
static void igdng_edp_backlight_off (struct drm_device *dev) static void ironlake_edp_backlight_off (struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp; u32 pp;
DRM_DEBUG("\n"); DRM_DEBUG_KMS("\n");
pp = I915_READ(PCH_PP_CONTROL); pp = I915_READ(PCH_PP_CONTROL);
pp &= ~EDP_BLC_ENABLE; pp &= ~EDP_BLC_ENABLE;
I915_WRITE(PCH_PP_CONTROL, pp); I915_WRITE(PCH_PP_CONTROL, pp);
@ -701,13 +703,13 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
if (dp_reg & DP_PORT_EN) { if (dp_reg & DP_PORT_EN) {
intel_dp_link_down(intel_output, dp_priv->DP); intel_dp_link_down(intel_output, dp_priv->DP);
if (IS_eDP(intel_output)) if (IS_eDP(intel_output))
igdng_edp_backlight_off(dev); ironlake_edp_backlight_off(dev);
} }
} else { } else {
if (!(dp_reg & DP_PORT_EN)) { if (!(dp_reg & DP_PORT_EN)) {
intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
if (IS_eDP(intel_output)) if (IS_eDP(intel_output))
igdng_edp_backlight_on(dev); ironlake_edp_backlight_on(dev);
} }
} }
dp_priv->dpms_mode = mode; dp_priv->dpms_mode = mode;
@ -1070,7 +1072,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_output->dev_priv; struct intel_dp_priv *dp_priv = intel_output->dev_priv;
DRM_DEBUG("\n"); DRM_DEBUG_KMS("\n");
if (IS_eDP(intel_output)) { if (IS_eDP(intel_output)) {
DP &= ~DP_PLL_ENABLE; DP &= ~DP_PLL_ENABLE;
@ -1131,7 +1133,7 @@ intel_dp_check_link_status(struct intel_output *intel_output)
} }
static enum drm_connector_status static enum drm_connector_status
igdng_dp_detect(struct drm_connector *connector) ironlake_dp_detect(struct drm_connector *connector)
{ {
struct intel_output *intel_output = to_intel_output(connector); struct intel_output *intel_output = to_intel_output(connector);
struct intel_dp_priv *dp_priv = intel_output->dev_priv; struct intel_dp_priv *dp_priv = intel_output->dev_priv;
@ -1166,8 +1168,8 @@ intel_dp_detect(struct drm_connector *connector)
dp_priv->has_audio = false; dp_priv->has_audio = false;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
return igdng_dp_detect(connector); return ironlake_dp_detect(connector);
temp = I915_READ(PORT_HOTPLUG_EN); temp = I915_READ(PORT_HOTPLUG_EN);
@ -1287,7 +1289,53 @@ intel_dp_hot_plug(struct intel_output *intel_output)
if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
intel_dp_check_link_status(intel_output); intel_dp_check_link_status(intel_output);
} }
/*
* Enumerate the child dev array parsed from VBT to check whether
* the given DP is present.
* If it is present, return 1.
* If it is not present, return false.
* If no child dev is parsed from VBT, it is assumed that the given
* DP is present.
*/
static int dp_is_present_in_vbt(struct drm_device *dev, int dp_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct child_device_config *p_child;
int i, dp_port, ret;
if (!dev_priv->child_dev_num)
return 1;
dp_port = 0;
if (dp_reg == DP_B || dp_reg == PCH_DP_B)
dp_port = PORT_IDPB;
else if (dp_reg == DP_C || dp_reg == PCH_DP_C)
dp_port = PORT_IDPC;
else if (dp_reg == DP_D || dp_reg == PCH_DP_D)
dp_port = PORT_IDPD;
ret = 0;
for (i = 0; i < dev_priv->child_dev_num; i++) {
p_child = dev_priv->child_dev + i;
/*
* If the device type is not DP, continue.
*/
if (p_child->device_type != DEVICE_TYPE_DP &&
p_child->device_type != DEVICE_TYPE_eDP)
continue;
/* Find the eDP port */
if (dp_reg == DP_A && p_child->device_type == DEVICE_TYPE_eDP) {
ret = 1;
break;
}
/* Find the DP port */
if (p_child->dvo_port == dp_port) {
ret = 1;
break;
}
}
return ret;
}
void void
intel_dp_init(struct drm_device *dev, int output_reg) intel_dp_init(struct drm_device *dev, int output_reg)
{ {
@ -1297,6 +1345,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
struct intel_dp_priv *dp_priv; struct intel_dp_priv *dp_priv;
const char *name = NULL; const char *name = NULL;
if (!dp_is_present_in_vbt(dev, output_reg)) {
DRM_DEBUG_KMS("DP is not present. Ignore it\n");
return;
}
intel_output = kcalloc(sizeof(struct intel_output) + intel_output = kcalloc(sizeof(struct intel_output) +
sizeof(struct intel_dp_priv), 1, GFP_KERNEL); sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
if (!intel_output) if (!intel_output)
@ -1314,11 +1366,11 @@ intel_dp_init(struct drm_device *dev, int output_reg)
else else
intel_output->type = INTEL_OUTPUT_DISPLAYPORT; intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
if (output_reg == DP_B) if (output_reg == DP_B || output_reg == PCH_DP_B)
intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
else if (output_reg == DP_C) else if (output_reg == DP_C || output_reg == PCH_DP_C)
intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
else if (output_reg == DP_D) else if (output_reg == DP_D || output_reg == PCH_DP_D)
intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
if (IS_eDP(intel_output)) { if (IS_eDP(intel_output)) {

View file

@ -110,6 +110,32 @@ struct intel_output {
int clone_mask; int clone_mask;
}; };
struct intel_crtc;
struct intel_overlay {
struct drm_device *dev;
struct intel_crtc *crtc;
struct drm_i915_gem_object *vid_bo;
struct drm_i915_gem_object *old_vid_bo;
int active;
int pfit_active;
u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
u32 color_key;
u32 brightness, contrast, saturation;
u32 old_xscale, old_yscale;
/* register access */
u32 flip_addr;
struct drm_i915_gem_object *reg_bo;
void *virt_addr;
/* flip handling */
uint32_t last_flip_req;
int hw_wedged;
#define HW_WEDGED 1
#define NEEDS_WAIT_FOR_FLIP 2
#define RELEASE_OLD_VID 3
#define SWITCH_OFF_STAGE_1 4
#define SWITCH_OFF_STAGE_2 5
};
struct intel_crtc { struct intel_crtc {
struct drm_crtc base; struct drm_crtc base;
enum pipe pipe; enum pipe pipe;
@ -121,6 +147,8 @@ struct intel_crtc {
bool busy; /* is scanout buffer being updated frequently? */ bool busy; /* is scanout buffer being updated frequently? */
struct timer_list idle_timer; struct timer_list idle_timer;
bool lowfreq_avail; bool lowfreq_avail;
struct intel_overlay *overlay;
struct intel_unpin_work *unpin_work;
}; };
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@ -134,6 +162,8 @@ void intel_i2c_destroy(struct i2c_adapter *adapter);
int intel_ddc_get_modes(struct intel_output *intel_output); int intel_ddc_get_modes(struct intel_output *intel_output);
extern bool intel_ddc_probe(struct intel_output *intel_output); extern bool intel_ddc_probe(struct intel_output *intel_output);
void intel_i2c_quirk_set(struct drm_device *dev, bool enable); void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
void intel_i2c_reset_gmbus(struct drm_device *dev);
extern void intel_crt_init(struct drm_device *dev); extern void intel_crt_init(struct drm_device *dev);
extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
extern bool intel_sdvo_init(struct drm_device *dev, int output_device); extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
@ -148,6 +178,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
extern void intel_edp_link_config (struct intel_output *, int *, int *); extern void intel_edp_link_config (struct intel_output *, int *, int *);
extern int intel_panel_fitter_pipe (struct drm_device *dev);
extern void intel_crtc_load_lut(struct drm_crtc *crtc); extern void intel_crtc_load_lut(struct drm_crtc *crtc);
extern void intel_encoder_prepare (struct drm_encoder *encoder); extern void intel_encoder_prepare (struct drm_encoder *encoder);
extern void intel_encoder_commit (struct drm_encoder *encoder); extern void intel_encoder_commit (struct drm_encoder *encoder);
@ -183,4 +214,16 @@ extern int intel_framebuffer_create(struct drm_device *dev,
struct drm_framebuffer **fb, struct drm_framebuffer **fb,
struct drm_gem_object *obj); struct drm_gem_object *obj);
extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
extern void intel_setup_overlay(struct drm_device *dev);
extern void intel_cleanup_overlay(struct drm_device *dev);
extern int intel_overlay_switch_off(struct intel_overlay *overlay);
extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
int interruptible);
extern int intel_overlay_put_image(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int intel_overlay_attrs(struct drm_device *dev, void *data,
struct drm_file *file_priv);
#endif /* __INTEL_DRV_H__ */ #endif /* __INTEL_DRV_H__ */

View file

@ -230,8 +230,9 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
par->intel_fb = intel_fb; par->intel_fb = intel_fb;
/* To allow resizeing without swapping buffers */ /* To allow resizeing without swapping buffers */
DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
intel_fb->base.height, obj_priv->gtt_offset, fbo); intel_fb->base.width, intel_fb->base.height,
obj_priv->gtt_offset, fbo);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return 0; return 0;
@ -249,7 +250,7 @@ int intelfb_probe(struct drm_device *dev)
{ {
int ret; int ret;
DRM_DEBUG("\n"); DRM_DEBUG_KMS("\n");
ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create); ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create);
return ret; return ret;
} }

View file

@ -82,7 +82,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
/* HW workaround, need to toggle enable bit off and on for 12bpc, but /* HW workaround, need to toggle enable bit off and on for 12bpc, but
* we do this anyway which shows more stable in testing. * we do this anyway which shows more stable in testing.
*/ */
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
POSTING_READ(hdmi_priv->sdvox_reg); POSTING_READ(hdmi_priv->sdvox_reg);
} }
@ -99,7 +99,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
/* HW workaround, need to write this twice for issue that may result /* HW workaround, need to write this twice for issue that may result
* in first write getting masked. * in first write getting masked.
*/ */
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
I915_WRITE(hdmi_priv->sdvox_reg, temp); I915_WRITE(hdmi_priv->sdvox_reg, temp);
POSTING_READ(hdmi_priv->sdvox_reg); POSTING_READ(hdmi_priv->sdvox_reg);
} }
@ -225,7 +225,52 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
.destroy = intel_hdmi_enc_destroy, .destroy = intel_hdmi_enc_destroy,
}; };
/*
* Enumerate the child dev array parsed from VBT to check whether
* the given HDMI is present.
* If it is present, return 1.
* If it is not present, return false.
* If no child dev is parsed from VBT, it assumes that the given
* HDMI is present.
*/
static int hdmi_is_present_in_vbt(struct drm_device *dev, int hdmi_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct child_device_config *p_child;
int i, hdmi_port, ret;
if (!dev_priv->child_dev_num)
return 1;
if (hdmi_reg == SDVOB)
hdmi_port = DVO_B;
else if (hdmi_reg == SDVOC)
hdmi_port = DVO_C;
else if (hdmi_reg == HDMIB)
hdmi_port = DVO_B;
else if (hdmi_reg == HDMIC)
hdmi_port = DVO_C;
else if (hdmi_reg == HDMID)
hdmi_port = DVO_D;
else
return 0;
ret = 0;
for (i = 0; i < dev_priv->child_dev_num; i++) {
p_child = dev_priv->child_dev + i;
/*
* If the device type is not HDMI, continue.
*/
if (p_child->device_type != DEVICE_TYPE_HDMI)
continue;
/* Find the HDMI port */
if (p_child->dvo_port == hdmi_port) {
ret = 1;
break;
}
}
return ret;
}
void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
@ -233,6 +278,10 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
struct intel_output *intel_output; struct intel_output *intel_output;
struct intel_hdmi_priv *hdmi_priv; struct intel_hdmi_priv *hdmi_priv;
if (!hdmi_is_present_in_vbt(dev, sdvox_reg)) {
DRM_DEBUG_KMS("HDMI is not present. Ignored it \n");
return;
}
intel_output = kcalloc(sizeof(struct intel_output) + intel_output = kcalloc(sizeof(struct intel_output) +
sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
if (!intel_output) if (!intel_output)

View file

@ -39,7 +39,7 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
/* When using bit bashing for I2C, this bit needs to be set to 1 */ /* When using bit bashing for I2C, this bit needs to be set to 1 */
if (!IS_IGD(dev)) if (!IS_PINEVIEW(dev))
return; return;
if (enable) if (enable)
I915_WRITE(DSPCLK_GATE_D, I915_WRITE(DSPCLK_GATE_D,
@ -118,6 +118,23 @@ static void set_data(void *data, int state_high)
udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
} }
/* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C
* engine, but if the BIOS leaves it enabled, then that can break our use
* of the bit-banging I2C interfaces. This is notably the case with the
* Mac Mini in EFI mode.
*/
void
intel_i2c_reset_gmbus(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
if (IS_IRONLAKE(dev)) {
I915_WRITE(PCH_GMBUS0, 0);
} else {
I915_WRITE(GMBUS0, 0);
}
}
/** /**
* intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
* @dev: DRM device * @dev: DRM device
@ -168,6 +185,8 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
if(i2c_bit_add_bus(&chan->adapter)) if(i2c_bit_add_bus(&chan->adapter))
goto out_free; goto out_free;
intel_i2c_reset_gmbus(dev);
/* JJJ: raise SCL and SDA? */ /* JJJ: raise SCL and SDA? */
intel_i2c_quirk_set(dev, true); intel_i2c_quirk_set(dev, true);
set_data(chan, 1); set_data(chan, 1);

View file

@ -56,7 +56,7 @@ static void intel_lvds_set_backlight(struct drm_device *dev, int level)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 blc_pwm_ctl, reg; u32 blc_pwm_ctl, reg;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
reg = BLC_PWM_CPU_CTL; reg = BLC_PWM_CPU_CTL;
else else
reg = BLC_PWM_CTL; reg = BLC_PWM_CTL;
@ -74,7 +74,7 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg; u32 reg;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
reg = BLC_PWM_PCH_CTL2; reg = BLC_PWM_PCH_CTL2;
else else
reg = BLC_PWM_CTL; reg = BLC_PWM_CTL;
@ -91,7 +91,7 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp_status, ctl_reg, status_reg; u32 pp_status, ctl_reg, status_reg;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
ctl_reg = PCH_PP_CONTROL; ctl_reg = PCH_PP_CONTROL;
status_reg = PCH_PP_STATUS; status_reg = PCH_PP_STATUS;
} else { } else {
@ -137,7 +137,7 @@ static void intel_lvds_save(struct drm_connector *connector)
u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg; u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
u32 pwm_ctl_reg; u32 pwm_ctl_reg;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
pp_on_reg = PCH_PP_ON_DELAYS; pp_on_reg = PCH_PP_ON_DELAYS;
pp_off_reg = PCH_PP_OFF_DELAYS; pp_off_reg = PCH_PP_OFF_DELAYS;
pp_ctl_reg = PCH_PP_CONTROL; pp_ctl_reg = PCH_PP_CONTROL;
@ -174,7 +174,7 @@ static void intel_lvds_restore(struct drm_connector *connector)
u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg; u32 pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg;
u32 pwm_ctl_reg; u32 pwm_ctl_reg;
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
pp_on_reg = PCH_PP_ON_DELAYS; pp_on_reg = PCH_PP_ON_DELAYS;
pp_off_reg = PCH_PP_OFF_DELAYS; pp_off_reg = PCH_PP_OFF_DELAYS;
pp_ctl_reg = PCH_PP_CONTROL; pp_ctl_reg = PCH_PP_CONTROL;
@ -297,7 +297,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
} }
/* full screen scale for now */ /* full screen scale for now */
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
goto out; goto out;
/* 965+ wants fuzzy fitting */ /* 965+ wants fuzzy fitting */
@ -327,7 +327,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
* to register description and PRM. * to register description and PRM.
* Change the value here to see the borders for debugging * Change the value here to see the borders for debugging
*/ */
if (!IS_IGDNG(dev)) { if (!IS_IRONLAKE(dev)) {
I915_WRITE(BCLRPAT_A, 0); I915_WRITE(BCLRPAT_A, 0);
I915_WRITE(BCLRPAT_B, 0); I915_WRITE(BCLRPAT_B, 0);
} }
@ -548,7 +548,7 @@ static void intel_lvds_prepare(struct drm_encoder *encoder)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg; u32 reg;
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
reg = BLC_PWM_CPU_CTL; reg = BLC_PWM_CPU_CTL;
else else
reg = BLC_PWM_CTL; reg = BLC_PWM_CTL;
@ -587,7 +587,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
* settings. * settings.
*/ */
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
return; return;
/* /*
@ -913,6 +913,101 @@ static int intel_lid_present(void)
} }
#endif #endif
/**
* intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID
* @dev: drm device
* @connector: LVDS connector
*
* Find the reduced downclock for LVDS in EDID.
*/
static void intel_find_lvds_downclock(struct drm_device *dev,
struct drm_connector *connector)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_display_mode *scan, *panel_fixed_mode;
int temp_downclock;
panel_fixed_mode = dev_priv->panel_fixed_mode;
temp_downclock = panel_fixed_mode->clock;
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(scan, &connector->probed_modes, head) {
/*
* If one mode has the same resolution with the fixed_panel
* mode while they have the different refresh rate, it means
* that the reduced downclock is found for the LVDS. In such
* case we can set the different FPx0/1 to dynamically select
* between low and high frequency.
*/
if (scan->hdisplay == panel_fixed_mode->hdisplay &&
scan->hsync_start == panel_fixed_mode->hsync_start &&
scan->hsync_end == panel_fixed_mode->hsync_end &&
scan->htotal == panel_fixed_mode->htotal &&
scan->vdisplay == panel_fixed_mode->vdisplay &&
scan->vsync_start == panel_fixed_mode->vsync_start &&
scan->vsync_end == panel_fixed_mode->vsync_end &&
scan->vtotal == panel_fixed_mode->vtotal) {
if (scan->clock < temp_downclock) {
/*
* The downclock is already found. But we
* expect to find the lower downclock.
*/
temp_downclock = scan->clock;
}
}
}
mutex_unlock(&dev->mode_config.mutex);
if (temp_downclock < panel_fixed_mode->clock) {
/* We found the downclock for LVDS. */
dev_priv->lvds_downclock_avail = 1;
dev_priv->lvds_downclock = temp_downclock;
DRM_DEBUG_KMS("LVDS downclock is found in EDID. "
"Normal clock %dKhz, downclock %dKhz\n",
panel_fixed_mode->clock, temp_downclock);
}
return;
}
/*
* Enumerate the child dev array parsed from VBT to check whether
* the LVDS is present.
* If it is present, return 1.
* If it is not present, return false.
* If no child dev is parsed from VBT, it assumes that the LVDS is present.
* Note: The addin_offset should also be checked for LVDS panel.
* Only when it is non-zero, it is assumed that it is present.
*/
static int lvds_is_present_in_vbt(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct child_device_config *p_child;
int i, ret;
if (!dev_priv->child_dev_num)
return 1;
ret = 0;
for (i = 0; i < dev_priv->child_dev_num; i++) {
p_child = dev_priv->child_dev + i;
/*
* If the device type is not LFP, continue.
* If the device type is 0x22, it is also regarded as LFP.
*/
if (p_child->device_type != DEVICE_TYPE_INT_LFP &&
p_child->device_type != DEVICE_TYPE_LFP)
continue;
/* The addin_offset should be checked. Only when it is
* non-zero, it is regarded as present.
*/
if (p_child->addin_offset) {
ret = 1;
break;
}
}
return ret;
}
/** /**
* intel_lvds_init - setup LVDS connectors on this device * intel_lvds_init - setup LVDS connectors on this device
* @dev: drm device * @dev: drm device
@ -936,21 +1031,20 @@ void intel_lvds_init(struct drm_device *dev)
if (dmi_check_system(intel_no_lvds)) if (dmi_check_system(intel_no_lvds))
return; return;
/* Assume that any device without an ACPI LID device also doesn't /*
* have an integrated LVDS. We would be better off parsing the BIOS * Assume LVDS is present if there's an ACPI lid device or if the
* to get a reliable indicator, but that code isn't written yet. * device is present in the VBT.
*
* In the case of all-in-one desktops using LVDS that we've seen,
* they're using SDVO LVDS.
*/ */
if (!intel_lid_present()) if (!lvds_is_present_in_vbt(dev) && !intel_lid_present()) {
DRM_DEBUG_KMS("LVDS is not present in VBT and no lid detected\n");
return; return;
}
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
return; return;
if (dev_priv->edp_support) { if (dev_priv->edp_support) {
DRM_DEBUG("disable LVDS for eDP support\n"); DRM_DEBUG_KMS("disable LVDS for eDP support\n");
return; return;
} }
gpio = PCH_GPIOC; gpio = PCH_GPIOC;
@ -1023,6 +1117,7 @@ void intel_lvds_init(struct drm_device *dev)
dev_priv->panel_fixed_mode = dev_priv->panel_fixed_mode =
drm_mode_duplicate(dev, scan); drm_mode_duplicate(dev, scan);
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
intel_find_lvds_downclock(dev, connector);
goto out; goto out;
} }
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
@ -1047,8 +1142,8 @@ void intel_lvds_init(struct drm_device *dev)
* correct mode. * correct mode.
*/ */
/* IGDNG: FIXME if still fail, not try pipe mode now */ /* Ironlake: FIXME if still fail, not try pipe mode now */
if (IS_IGDNG(dev)) if (IS_IRONLAKE(dev))
goto failed; goto failed;
lvds = I915_READ(LVDS); lvds = I915_READ(LVDS);
@ -1069,7 +1164,7 @@ void intel_lvds_init(struct drm_device *dev)
goto failed; goto failed;
out: out:
if (IS_IGDNG(dev)) { if (IS_IRONLAKE(dev)) {
u32 pwm; u32 pwm;
/* make sure PWM is enabled */ /* make sure PWM is enabled */
pwm = I915_READ(BLC_PWM_CPU_CTL2); pwm = I915_READ(BLC_PWM_CPU_CTL2);
@ -1082,7 +1177,7 @@ out:
} }
dev_priv->lid_notifier.notifier_call = intel_lid_notify; dev_priv->lid_notifier.notifier_call = intel_lid_notify;
if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) {
DRM_DEBUG("lid notifier registration failed\n"); DRM_DEBUG_KMS("lid notifier registration failed\n");
dev_priv->lid_notifier.notifier_call = NULL; dev_priv->lid_notifier.notifier_call = NULL;
} }
drm_sysfs_connector_add(connector); drm_sysfs_connector_add(connector);
@ -1093,5 +1188,6 @@ failed:
if (intel_output->ddc_bus) if (intel_output->ddc_bus)
intel_i2c_destroy(intel_output->ddc_bus); intel_i2c_destroy(intel_output->ddc_bus);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
drm_encoder_cleanup(encoder);
kfree(intel_output); kfree(intel_output);
} }

File diff suppressed because it is too large Load diff

View file

@ -36,8 +36,6 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_sdvo_regs.h" #include "intel_sdvo_regs.h"
#undef SDVO_DEBUG
static char *tv_format_names[] = { static char *tv_format_names[] = {
"NTSC_M" , "NTSC_J" , "NTSC_443", "NTSC_M" , "NTSC_J" , "NTSC_443",
"PAL_B" , "PAL_D" , "PAL_G" , "PAL_B" , "PAL_D" , "PAL_G" ,
@ -356,7 +354,6 @@ static const struct _sdvo_cmd_name {
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
#define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv) #define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv)
#ifdef SDVO_DEBUG
static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
void *args, int args_len) void *args, int args_len)
{ {
@ -379,9 +376,6 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
DRM_LOG_KMS("(%02X)", cmd); DRM_LOG_KMS("(%02X)", cmd);
DRM_LOG_KMS("\n"); DRM_LOG_KMS("\n");
} }
#else
#define intel_sdvo_debug_write(o, c, a, l)
#endif
static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd, static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
void *args, int args_len) void *args, int args_len)
@ -398,7 +392,6 @@ static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd); intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
} }
#ifdef SDVO_DEBUG
static const char *cmd_status_names[] = { static const char *cmd_status_names[] = {
"Power on", "Power on",
"Success", "Success",
@ -427,9 +420,6 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
DRM_LOG_KMS("(??? %d)", status); DRM_LOG_KMS("(??? %d)", status);
DRM_LOG_KMS("\n"); DRM_LOG_KMS("\n");
} }
#else
#define intel_sdvo_debug_response(o, r, l, s)
#endif
static u8 intel_sdvo_read_response(struct intel_output *intel_output, static u8 intel_sdvo_read_response(struct intel_output *intel_output,
void *response, int response_len) void *response, int response_len)
@ -1627,6 +1617,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
intel_sdvo_write_cmd(intel_output, intel_sdvo_write_cmd(intel_output,
SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
if (sdvo_priv->is_tv) {
/* add 30ms delay when the output type is SDVO-TV */
mdelay(30);
}
status = intel_sdvo_read_response(intel_output, &response, 2); status = intel_sdvo_read_response(intel_output, &response, 2);
DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);

View file

@ -1213,20 +1213,17 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
tv_ctl |= TV_TRILEVEL_SYNC; tv_ctl |= TV_TRILEVEL_SYNC;
if (tv_mode->pal_burst) if (tv_mode->pal_burst)
tv_ctl |= TV_PAL_BURST; tv_ctl |= TV_PAL_BURST;
scctl1 = 0;
/* dda1 implies valid video levels */
if (tv_mode->dda1_inc) {
scctl1 |= TV_SC_DDA1_EN;
}
scctl1 = 0;
if (tv_mode->dda1_inc)
scctl1 |= TV_SC_DDA1_EN;
if (tv_mode->dda2_inc) if (tv_mode->dda2_inc)
scctl1 |= TV_SC_DDA2_EN; scctl1 |= TV_SC_DDA2_EN;
if (tv_mode->dda3_inc) if (tv_mode->dda3_inc)
scctl1 |= TV_SC_DDA3_EN; scctl1 |= TV_SC_DDA3_EN;
scctl1 |= tv_mode->sc_reset; scctl1 |= tv_mode->sc_reset;
scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; if (video_levels)
scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
@ -1416,16 +1413,16 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
* 0 0 0 Component * 0 0 0 Component
*/ */
if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
DRM_DEBUG("Detected Composite TV connection\n"); DRM_DEBUG_KMS("Detected Composite TV connection\n");
type = DRM_MODE_CONNECTOR_Composite; type = DRM_MODE_CONNECTOR_Composite;
} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
DRM_DEBUG("Detected S-Video TV connection\n"); DRM_DEBUG_KMS("Detected S-Video TV connection\n");
type = DRM_MODE_CONNECTOR_SVIDEO; type = DRM_MODE_CONNECTOR_SVIDEO;
} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
DRM_DEBUG("Detected Component TV connection\n"); DRM_DEBUG_KMS("Detected Component TV connection\n");
type = DRM_MODE_CONNECTOR_Component; type = DRM_MODE_CONNECTOR_Component;
} else { } else {
DRM_DEBUG("No TV connection detected\n"); DRM_DEBUG_KMS("No TV connection detected\n");
type = -1; type = -1;
} }
@ -1702,6 +1699,41 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs = {
.destroy = intel_tv_enc_destroy, .destroy = intel_tv_enc_destroy,
}; };
/*
* Enumerate the child dev array parsed from VBT to check whether
* the integrated TV is present.
* If it is present, return 1.
* If it is not present, return false.
* If no child dev is parsed from VBT, it assumes that the TV is present.
*/
static int tv_is_present_in_vbt(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct child_device_config *p_child;
int i, ret;
if (!dev_priv->child_dev_num)
return 1;
ret = 0;
for (i = 0; i < dev_priv->child_dev_num; i++) {
p_child = dev_priv->child_dev + i;
/*
* If the device type is not TV, continue.
*/
if (p_child->device_type != DEVICE_TYPE_INT_TV &&
p_child->device_type != DEVICE_TYPE_TV)
continue;
/* Only when the addin_offset is non-zero, it is regarded
* as present.
*/
if (p_child->addin_offset) {
ret = 1;
break;
}
}
return ret;
}
void void
intel_tv_init(struct drm_device *dev) intel_tv_init(struct drm_device *dev)
@ -1717,6 +1749,10 @@ intel_tv_init(struct drm_device *dev)
if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
return; return;
if (!tv_is_present_in_vbt(dev)) {
DRM_DEBUG_KMS("Integrated TV is not present.\n");
return;
}
/* Even if we have an encoder we may not have a connector */ /* Even if we have an encoder we may not have a connector */
if (!dev_priv->int_tv_support) if (!dev_priv->int_tv_support)
return; return;

View file

@ -1941,8 +1941,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
for (t = 0; t < dev_priv->usec_timeout; t++) { for (t = 0; t < dev_priv->usec_timeout; t++) {
u32 done_age = GET_SCRATCH(dev_priv, 1); u32 done_age = GET_SCRATCH(dev_priv, 1);
DRM_DEBUG("done_age = %d\n", done_age); DRM_DEBUG("done_age = %d\n", done_age);
for (i = start; i < dma->buf_count; i++) { for (i = 0; i < dma->buf_count; i++) {
buf = dma->buflist[i]; buf = dma->buflist[start];
buf_priv = buf->dev_private; buf_priv = buf->dev_private;
if (buf->file_priv == NULL || (buf->pending && if (buf->file_priv == NULL || (buf->pending &&
buf_priv->age <= buf_priv->age <=
@ -1951,7 +1951,8 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
buf->pending = 0; buf->pending = 0;
return buf; return buf;
} }
start = 0; if (++start >= dma->buf_count)
start = 0;
} }
if (t) { if (t) {
@ -1960,47 +1961,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
} }
} }
DRM_DEBUG("returning NULL!\n");
return NULL; return NULL;
} }
#if 0
struct drm_buf *radeon_freelist_get(struct drm_device * dev)
{
struct drm_device_dma *dma = dev->dma;
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_buf_priv_t *buf_priv;
struct drm_buf *buf;
int i, t;
int start;
u32 done_age;
done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
if (++dev_priv->last_buf >= dma->buf_count)
dev_priv->last_buf = 0;
start = dev_priv->last_buf;
dev_priv->stats.freelist_loops++;
for (t = 0; t < 2; t++) {
for (i = start; i < dma->buf_count; i++) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
if (buf->file_priv == 0 || (buf->pending &&
buf_priv->age <=
done_age)) {
dev_priv->stats.requested_bufs++;
buf->pending = 0;
return buf;
}
}
start = 0;
}
return NULL;
}
#endif
void radeon_freelist_reset(struct drm_device * dev) void radeon_freelist_reset(struct drm_device * dev)
{ {
struct drm_device_dma *dma = dev->dma; struct drm_device_dma *dma = dev->dma;

View file

@ -728,6 +728,7 @@ struct drm_event {
}; };
#define DRM_EVENT_VBLANK 0x01 #define DRM_EVENT_VBLANK 0x01
#define DRM_EVENT_FLIP_COMPLETE 0x02
struct drm_event_vblank { struct drm_event_vblank {
struct drm_event base; struct drm_event base;

View file

@ -1300,6 +1300,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
extern void drm_handle_vblank(struct drm_device *dev, int crtc); extern void drm_handle_vblank(struct drm_device *dev, int crtc);
extern int drm_vblank_get(struct drm_device *dev, int crtc); extern int drm_vblank_get(struct drm_device *dev, int crtc);
extern void drm_vblank_put(struct drm_device *dev, int crtc); extern void drm_vblank_put(struct drm_device *dev, int crtc);
extern void drm_vblank_off(struct drm_device *dev, int crtc);
extern void drm_vblank_cleanup(struct drm_device *dev); extern void drm_vblank_cleanup(struct drm_device *dev);
/* Modesetting support */ /* Modesetting support */
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
@ -1524,16 +1525,29 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
{ {
if (size * nmemb <= PAGE_SIZE)
return kcalloc(nmemb, size, GFP_KERNEL);
if (size != 0 && nmemb > ULONG_MAX / size) if (size != 0 && nmemb > ULONG_MAX / size)
return NULL; return NULL;
if (size * nmemb <= PAGE_SIZE)
return kcalloc(nmemb, size, GFP_KERNEL);
return __vmalloc(size * nmemb, return __vmalloc(size * nmemb,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
} }
/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
{
if (size != 0 && nmemb > ULONG_MAX / size)
return NULL;
if (size * nmemb <= PAGE_SIZE)
return kmalloc(nmemb * size, GFP_KERNEL);
return __vmalloc(size * nmemb,
GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
}
static __inline void drm_free_large(void *ptr) static __inline void drm_free_large(void *ptr)
{ {
if (!is_vmalloc_addr(ptr)) if (!is_vmalloc_addr(ptr))

View file

@ -743,7 +743,8 @@ extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder); struct drm_encoder *encoder);
extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size); int gamma_size);
extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
uint32_t id, uint32_t type);
/* IOCTLs */ /* IOCTLs */
extern int drm_mode_getresources(struct drm_device *dev, extern int drm_mode_getresources(struct drm_device *dev,
void *data, struct drm_file *file_priv); void *data, struct drm_file *file_priv);

View file

@ -123,5 +123,5 @@ do { \
remove_wait_queue(&(queue), &entry); \ remove_wait_queue(&(queue), &entry); \
} while (0) } while (0)
#define DRM_WAKEUP( queue ) wake_up_interruptible( queue ) #define DRM_WAKEUP( queue ) wake_up( queue )
#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )

View file

@ -186,6 +186,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_GEM_MMAP_GTT 0x24 #define DRM_I915_GEM_MMAP_GTT 0x24
#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 #define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25
#define DRM_I915_GEM_MADVISE 0x26 #define DRM_I915_GEM_MADVISE 0x26
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
#define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@ -221,8 +223,10 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling) #define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id) #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image)
#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
/* Allow drivers to submit batchbuffers directly to hardware, relying /* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware. * on the security mechanisms provided by hardware.
@ -266,6 +270,8 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_CHIPSET_ID 4 #define I915_PARAM_CHIPSET_ID 4
#define I915_PARAM_HAS_GEM 5 #define I915_PARAM_HAS_GEM 5
#define I915_PARAM_NUM_FENCES_AVAIL 6 #define I915_PARAM_NUM_FENCES_AVAIL 6
#define I915_PARAM_HAS_OVERLAY 7
#define I915_PARAM_HAS_PAGEFLIPPING 8
typedef struct drm_i915_getparam { typedef struct drm_i915_getparam {
int param; int param;
@ -686,4 +692,70 @@ struct drm_i915_gem_madvise {
__u32 retained; __u32 retained;
}; };
/* flags */
#define I915_OVERLAY_TYPE_MASK 0xff
#define I915_OVERLAY_YUV_PLANAR 0x01
#define I915_OVERLAY_YUV_PACKED 0x02
#define I915_OVERLAY_RGB 0x03
#define I915_OVERLAY_DEPTH_MASK 0xff00
#define I915_OVERLAY_RGB24 0x1000
#define I915_OVERLAY_RGB16 0x2000
#define I915_OVERLAY_RGB15 0x3000
#define I915_OVERLAY_YUV422 0x0100
#define I915_OVERLAY_YUV411 0x0200
#define I915_OVERLAY_YUV420 0x0300
#define I915_OVERLAY_YUV410 0x0400
#define I915_OVERLAY_SWAP_MASK 0xff0000
#define I915_OVERLAY_NO_SWAP 0x000000
#define I915_OVERLAY_UV_SWAP 0x010000
#define I915_OVERLAY_Y_SWAP 0x020000
#define I915_OVERLAY_Y_AND_UV_SWAP 0x030000
#define I915_OVERLAY_FLAGS_MASK 0xff000000
#define I915_OVERLAY_ENABLE 0x01000000
struct drm_intel_overlay_put_image {
/* various flags and src format description */
__u32 flags;
/* source picture description */
__u32 bo_handle;
/* stride values and offsets are in bytes, buffer relative */
__u16 stride_Y; /* stride for packed formats */
__u16 stride_UV;
__u32 offset_Y; /* offset for packet formats */
__u32 offset_U;
__u32 offset_V;
/* in pixels */
__u16 src_width;
__u16 src_height;
/* to compensate the scaling factors for partially covered surfaces */
__u16 src_scan_width;
__u16 src_scan_height;
/* output crtc description */
__u32 crtc_id;
__u16 dst_x;
__u16 dst_y;
__u16 dst_width;
__u16 dst_height;
};
/* flags */
#define I915_OVERLAY_UPDATE_ATTRS (1<<0)
#define I915_OVERLAY_UPDATE_GAMMA (1<<1)
struct drm_intel_overlay_attrs {
__u32 flags;
__u32 color_key;
__s32 brightness;
__u32 contrast;
__u32 saturation;
__u32 gamma0;
__u32 gamma1;
__u32 gamma2;
__u32 gamma3;
__u32 gamma4;
__u32 gamma5;
};
#endif /* _I915_DRM_H_ */ #endif /* _I915_DRM_H_ */