summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h2
-rw-r--r--shared-core/drm_pciids.txt15
-rw-r--r--shared-core/i915_dma.c43
-rw-r--r--shared-core/i915_drm.h65
-rw-r--r--shared-core/i915_drv.h339
-rw-r--r--shared-core/i915_init.c186
-rw-r--r--shared-core/i915_irq.c154
-rw-r--r--shared-core/i915_suspend.c520
-rw-r--r--shared-core/nouveau_fifo.c2
-rw-r--r--shared-core/nouveau_irq.c11
-rw-r--r--shared-core/nouveau_mem.c1
-rw-r--r--shared-core/nouveau_reg.h2
-rw-r--r--shared-core/nv04_fifo.c4
-rw-r--r--shared-core/nv40_graph.c10
-rw-r--r--shared-core/r300_cmdbuf.c215
-rw-r--r--shared-core/r300_reg.h229
-rw-r--r--shared-core/radeon_cp.c58
-rw-r--r--shared-core/radeon_cs.c4
-rw-r--r--shared-core/radeon_drv.h32
-rw-r--r--shared-core/radeon_irq.c57
-rw-r--r--shared-core/radeon_mem.c8
-rw-r--r--shared-core/xgi_drm.h4
22 files changed, 1412 insertions, 549 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index ed390885..b177dfe5 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -1012,7 +1012,7 @@ struct drm_mode_crtc_lut {
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding)
-#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, struct drm_scatter_gather)
+#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather)
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt
index b95bc8f2..0c45b4c1 100644
--- a/shared-core/drm_pciids.txt
+++ b/shared-core/drm_pciids.txt
@@ -83,7 +83,6 @@
0x1002 0x5460 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X300 M22"
0x1002 0x5462 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X600 SE M24C"
0x1002 0x5464 CHIP_RV380|RADEON_IS_MOBILITY "ATI FireGL M22 GL 5464"
-0x1002 0x5657 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV370 X550XTX"
0x1002 0x5548 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800"
0x1002 0x5549 CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800 Pro"
0x1002 0x554A CHIP_R420|RADEON_NEW_MEMMAP "ATI Radeon R423 X800 XT PE"
@@ -101,9 +100,10 @@
0x1002 0x564F CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X700 XL M26"
0x1002 0x5652 CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X700 M26"
0x1002 0x5653 CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X700 M26"
+0x1002 0x5657 CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon X550XTX"
0x1002 0x5834 CHIP_RS300|RADEON_IS_IGP "ATI Radeon RS300 9100 IGP"
0x1002 0x5835 CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY "ATI Radeon RS300 Mobility IGP"
-0x1002 0x5954 CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI RS480 XPRESS 200G"
+0x1002 0x5954 CHIP_RS480|RADEON_IS_IGP|RADEON_IS_IGPGART "ATI RS480 XPRESS 200G"
0x1002 0x5955 CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon XPRESS 200M 5955"
0x1002 0x5974 CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon RS482 XPRESS 200"
0x1002 0x5975 CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon RS485 XPRESS 1100 IGP"
@@ -113,8 +113,10 @@
0x1002 0x5964 CHIP_RV280 "ATI Radeon RV280 9200 SE"
0x1002 0x5965 CHIP_RV280 "ATI FireMV 2200 PCI"
0x1002 0x5969 CHIP_RV100 "ATI ES1000 RN50"
-0x1002 0x5a61 CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon RC410 XPRESS 200"
-0x1002 0x5a62 CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon RC410 XPRESS 200M"
+0x1002 0x5a41 CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART "ATI Radeon XPRESS 200 5A41 (PCIE)"
+0x1002 0x5a42 CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon XPRESS 200M 5A42 (PCIE)"
+0x1002 0x5a61 CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART "ATI Radeon RC410 XPRESS 200"
+0x1002 0x5a62 CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART "ATI Radeon RC410 XPRESS 200M"
0x1002 0x5b60 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV370 X300 SE"
0x1002 0x5b62 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV370 X600 Pro"
0x1002 0x5b63 CHIP_RV380|RADEON_NEW_MEMMAP "ATI Radeon RV370 X550"
@@ -396,7 +398,10 @@
0x8086 0x29C2 CHIP_I9XX|CHIP_I915 "Intel G33"
0x8086 0x29B2 CHIP_I9XX|CHIP_I915 "Intel Q35"
0x8086 0x29D2 CHIP_I9XX|CHIP_I915 "Intel Q33"
-0x8086 0x2A42 CHIP_I9XX|CHIP_I965 "Intel Integrated Graphics Device"
+0x8086 0x2A42 CHIP_I9XX|CHIP_I965 "Mobile IntelĀ® GM45 Express Chipset"
+0x8086 0x2E02 CHIP_I9XX|CHIP_I965 "Intel Integrated Graphics Device"
+0x8086 0x2E12 CHIP_I9XX|CHIP_I965 "Intel Q45/Q43"
+0x8086 0x2E22 CHIP_I9XX|CHIP_I965 "Intel G45/G43"
[imagine]
0x105d 0x2309 IMAGINE_128 "Imagine 128"
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index bd52a057..7f025e62 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -41,12 +41,12 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
- u32 acthd_reg = IS_I965G(dev) ? I965REG_ACTHD : I915REG_ACTHD;
+ u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
u32 last_acthd = I915_READ(acthd_reg);
u32 acthd;
int i;
- for (i = 0; i < 10000; i++) {
+ for (i = 0; i < 100000; i++) {
ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
acthd = I915_READ(acthd_reg);
ring->space = ring->head - (ring->tail + 8);
@@ -132,19 +132,6 @@ int i915_dma_cleanup(struct drm_device * dev)
dev_priv->ring.Size = 0;
}
- if (dev_priv->status_page_dmah) {
- drm_pci_free(dev, dev_priv->status_page_dmah);
- dev_priv->status_page_dmah = NULL;
- /* Need to rewrite hardware status page */
- I915_WRITE(0x02080, 0x1ffff000);
- }
-
- if (dev_priv->hws_agpoffset) {
- dev_priv->hws_agpoffset = 0;
- drm_core_ioremapfree(&dev_priv->hws_map, dev);
- I915_WRITE(0x02080, 0x1ffff000);
- }
-
return 0;
}
@@ -310,14 +297,14 @@ static int i915_dma_resume(struct drm_device * dev)
}
/* Program Hardware Status Page */
- if (!dev_priv->hws_vaddr) {
+ if (!dev_priv->hw_status_page) {
DRM_ERROR("Can not find hardware status page\n");
return -EINVAL;
}
- DRM_DEBUG("hw status page @ %p\n", dev_priv->hws_vaddr);
+ DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
- if (dev_priv->hws_agpoffset != 0)
- I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset);
+ if (dev_priv->status_gfx_addr != 0)
+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
else
I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
@@ -870,6 +857,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_CHIPSET_ID:
value = dev->pci_device;
break;
+ case I915_PARAM_HAS_GEM:
+ value = 1;
+ break;
default:
DRM_ERROR("Unknown parameter %d\n", param->param);
return -EINVAL;
@@ -1007,7 +997,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
- dev_priv->hws_agpoffset = hws->addr & (0x1ffff<<12);
+ dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
dev_priv->hws_map.offset = dev->agp->base + hws->addr;
dev_priv->hws_map.size = 4*1024;
@@ -1018,16 +1008,17 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
drm_core_ioremap(&dev_priv->hws_map, dev);
if (dev_priv->hws_map.handle == NULL) {
i915_dma_cleanup(dev);
- dev_priv->hws_agpoffset = 0;
+ dev_priv->status_gfx_addr = 0;
DRM_ERROR("can not ioremap virtual address for"
" G33 hw status page\n");
return -ENOMEM;
}
- dev_priv->hws_vaddr = dev_priv->hws_map.handle;
- memset(dev_priv->hws_vaddr, 0, PAGE_SIZE);
- I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset);
- DRM_DEBUG("load hws at %p\n", dev_priv->hws_vaddr);
+ dev_priv->hw_status_page = dev_priv->hws_map.handle;
+
+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
+ DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
return 0;
}
@@ -1065,6 +1056,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index 611f943a..ab13cd4a 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -190,6 +190,8 @@ typedef struct drm_i915_sarea {
#define DRM_I915_GEM_MMAP 0x1e
#define DRM_I915_GEM_SET_DOMAIN 0x1f
#define DRM_I915_GEM_SW_FINISH 0x20
+#define DRM_I915_GEM_SET_TILING 0x21
+#define DRM_I915_GEM_GET_TILING 0x22
#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)
@@ -223,6 +225,8 @@ typedef struct drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
+#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)
/* Asynchronous page flipping:
*/
@@ -276,6 +280,7 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_ALLOW_BATCHBUFFER 2
#define I915_PARAM_LAST_DISPATCH 3
#define I915_PARAM_CHIPSET_ID 4
+#define I915_PARAM_HAS_GEM 5
typedef struct drm_i915_getparam {
int param;
@@ -603,4 +608,64 @@ struct drm_i915_gem_busy {
uint32_t busy;
};
+#define I915_TILING_NONE 0
+#define I915_TILING_X 1
+#define I915_TILING_Y 2
+
+#define I915_BIT_6_SWIZZLE_NONE 0
+#define I915_BIT_6_SWIZZLE_9 1
+#define I915_BIT_6_SWIZZLE_9_10 2
+#define I915_BIT_6_SWIZZLE_9_11 3
+#define I915_BIT_6_SWIZZLE_9_10_11 4
+/* Not seen by userland */
+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
+
+struct drm_i915_gem_set_tiling {
+ /** Handle of the buffer to have its tiling state updated */
+ uint32_t handle;
+
+ /**
+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+ * I915_TILING_Y).
+ *
+ * This value is to be set on request, and will be updated by the
+ * kernel on successful return with the actual chosen tiling layout.
+ *
+ * The tiling mode may be demoted to I915_TILING_NONE when the system
+ * has bit 6 swizzling that can't be managed correctly by GEM.
+ *
+ * Buffer contents become undefined when changing tiling_mode.
+ */
+ uint32_t tiling_mode;
+
+ /**
+ * Stride in bytes for the object when in I915_TILING_X or
+ * I915_TILING_Y.
+ */
+ uint32_t stride;
+
+ /**
+ * Returned address bit 6 swizzling required for CPU access through
+ * mmap mapping.
+ */
+ uint32_t swizzle_mode;
+};
+
+struct drm_i915_gem_get_tiling {
+ /** Handle of the buffer to get tiling state for. */
+ uint32_t handle;
+
+ /**
+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+ * I915_TILING_Y).
+ */
+ uint32_t tiling_mode;
+
+ /**
+ * Returned address bit 6 swizzling required for CPU access through
+ * mmap mapping.
+ */
+ uint32_t swizzle_mode;
+};
+
#endif /* _I915_DRM_H_ */
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 17829a56..087c6d64 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -39,7 +39,7 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20080611"
+#define DRIVER_DATE "20080730"
#if defined(__linux__)
#define I915_HAVE_FENCE
@@ -63,7 +63,7 @@
*/
#define DRIVER_MAJOR 1
#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER)
-#define DRIVER_MINOR 14
+#define DRIVER_MINOR 13
#else
#define DRIVER_MINOR 6
#endif
@@ -79,6 +79,14 @@ enum pipe {
struct drm_i915_validate_buffer;
#endif
+#define WATCH_COHERENCY 0
+#define WATCH_BUF 0
+#define WATCH_EXEC 0
+#define WATCH_LRU 0
+#define WATCH_RELOC 0
+#define WATCH_INACTIVE 0
+#define WATCH_PWRITE 0
+
struct drm_i915_ring_buffer {
int tail_mask;
unsigned long Size;
@@ -107,6 +115,23 @@ struct drm_i915_vbl_swap {
struct drm_minor *minor;
};
+
+#ifdef __linux__
+struct opregion_header;
+struct opregion_acpi;
+struct opregion_swsci;
+struct opregion_asle;
+
+struct intel_opregion {
+ struct opregion_header *header;
+ struct opregion_acpi *acpi;
+ struct opregion_swsci *swsci;
+ struct opregion_asle *asle;
+
+ int enabled;
+};
+#endif
+
struct drm_i915_master_private {
drm_local_map_t *sarea;
struct drm_i915_sarea *sarea_priv;
@@ -123,12 +148,12 @@ struct drm_i915_private {
struct drm_i915_ring_buffer ring;
struct drm_dma_handle *status_page_dmah;
+ void *hw_status_page;
dma_addr_t dma_status_page;
uint32_t counter;
- uint32_t hws_agpoffset;
+ uint32_t status_gfx_addr;
drm_local_map_t hws_map;
- void *hws_vaddr;
- struct drm_memrange_node *hws;
+ struct drm_gem_object *hws_obj;
unsigned int cpp;
@@ -149,7 +174,7 @@ struct drm_i915_private {
bool cursor_needs_physical;
- struct drm_memrange vram;
+ struct drm_mm vram;
#ifdef I915_HAVE_FENCE
uint32_t flush_sequence;
@@ -187,85 +212,12 @@ struct drm_i915_private {
int lvds_vbt:1;
int int_crt_support:1;
- struct {
- struct drm_memrange gtt_space;
-
- /**
- * List of objects currently involved in rendering from the
- * ringbuffer.
- *
- * A reference is held on the buffer while on this list.
- */
- struct list_head active_list;
-
- /**
- * List of objects which are not in the ringbuffer but which
- * still have a write_domain which needs to be flushed before
- * unbinding.
- *
- * A reference is held on the buffer while on this list.
- */
- struct list_head flushing_list;
-
- /**
- * LRU list of objects which are not in the ringbuffer and
- * are ready to unbind, but are still in the GTT.
- *
- * A reference is not held on the buffer while on this list,
- * as merely being GTT-bound shouldn't prevent its being
- * freed, and we'll pull it off the list in the free path.
- */
- struct list_head inactive_list;
-
- /**
- * List of breadcrumbs associated with GPU requests currently
- * outstanding.
- */
- struct list_head request_list;
-
- /**
- * We leave the user IRQ off as much as possible,
- * but this means that requests will finish and never
- * be retired once the system goes idle. Set a timer to
- * fire periodically while the ring is running. When it
- * fires, go retire requests.
- */
- struct delayed_work retire_work;
-
- uint32_t next_gem_seqno;
-
- /**
- * Waiting sequence number, if any
- */
- uint32_t waiting_gem_seqno;
-
- /**
- * Last seq seen at irq time
- */
- uint32_t irq_gem_seqno;
-
- /**
- * Flag if the X Server, and thus DRM, is not currently in
- * control of the device.
- *
- * This is set between LeaveVT and EnterVT. It needs to be
- * replaced with a semaphore. It also needs to be
- * transitioned away from for kernel modesetting.
- */
- int suspended;
-
- /**
- * Flag if the hardware appears to be wedged.
- *
- * This is set when attempts to idle the device timeout.
- * It prevents command submission from occuring and makes
- * every pending request fail
- */
- int wedged;
- } mm;
-
struct work_struct user_interrupt_task;
+#ifdef __linux__
+ struct intel_opregion opregion;
+#endif
+
/* Register state */
u8 saveLBB;
u32 saveDSPACNTR;
@@ -354,6 +306,88 @@ struct drm_i915_private {
u8 saveDACMASK;
u8 saveDACDATA[256*3]; /* 256 3-byte colors */
u8 saveCR[37];
+
+ struct {
+ struct drm_mm gtt_space;
+
+ /**
+ * List of objects currently involved in rendering from the
+ * ringbuffer.
+ *
+ * A reference is held on the buffer while on this list.
+ */
+ struct list_head active_list;
+
+ /**
+ * List of objects which are not in the ringbuffer but which
+ * still have a write_domain which needs to be flushed before
+ * unbinding.
+ *
+ * A reference is held on the buffer while on this list.
+ */
+ struct list_head flushing_list;
+
+ /**
+ * LRU list of objects which are not in the ringbuffer and
+ * are ready to unbind, but are still in the GTT.
+ *
+ * A reference is not held on the buffer while on this list,
+ * as merely being GTT-bound shouldn't prevent its being
+ * freed, and we'll pull it off the list in the free path.
+ */
+ struct list_head inactive_list;
+
+ /**
+ * List of breadcrumbs associated with GPU requests currently
+ * outstanding.
+ */
+ struct list_head request_list;
+
+ /**
+ * We leave the user IRQ off as much as possible,
+ * but this means that requests will finish and never
+ * be retired once the system goes idle. Set a timer to
+ * fire periodically while the ring is running. When it
+ * fires, go retire requests.
+ */
+ struct delayed_work retire_work;
+
+ uint32_t next_gem_seqno;
+
+ /**
+ * Waiting sequence number, if any
+ */
+ uint32_t waiting_gem_seqno;
+
+ /**
+ * Last seq seen at irq time
+ */
+ uint32_t irq_gem_seqno;
+
+ /**
+ * Flag if the X Server, and thus DRM, is not currently in
+ * control of the device.
+ *
+ * This is set between LeaveVT and EnterVT. It needs to be
+ * replaced with a semaphore. It also needs to be
+ * transitioned away from for kernel modesetting.
+ */
+ int suspended;
+
+ /**
+ * Flag if the hardware appears to be wedged.
+ *
+ * This is set when attempts to idle the device timeout.
+ * It prevents command submission from occuring and makes
+ * every pending request fail
+ */
+ int wedged;
+
+ /** Bit 6 swizzling required for X tiling */
+ uint32_t bit_6_swizzle_x;
+ /** Bit 6 swizzling required for Y tiling */
+ uint32_t bit_6_swizzle_y;
+ } mm;
};
struct drm_i915_file_private {
@@ -375,7 +409,7 @@ struct drm_i915_gem_object {
struct drm_gem_object *obj;
/** Current space allocated to this object in the GTT, if any. */
- struct drm_memrange_node *gtt_space;
+ struct drm_mm_node *gtt_space;
/** This object's place on the active/flushing/inactive lists */
struct list_head list;
@@ -413,6 +447,15 @@ struct drm_i915_gem_object {
/** Breadcrumb of last rendering to the buffer. */
uint32_t last_rendering_seqno;
+
+ /** Current tiling mode for the object. */
+ uint32_t tiling_mode;
+
+ /**
+ * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
+ * GEM_DOMAIN_CPU is not in the object's read domain.
+ */
+ uint8_t *page_cpu_valid;
};
/**
@@ -508,6 +551,11 @@ extern void i915_mem_takedown(struct mem_block **heap);
extern void i915_mem_release(struct drm_device * dev,
struct drm_file *file_priv,
struct mem_block *heap);
+
+/* i915_suspend.c */
+extern int i915_save_state(struct drm_device *dev);
+extern int i915_restore_state(struct drm_device *dev);
+
#ifdef I915_HAVE_FENCE
/* i915_fence.c */
extern void i915_fence_handler(struct drm_device *dev);
@@ -561,6 +609,11 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int i915_gem_set_tiling(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_get_tiling(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+void i915_gem_load(struct drm_device *dev);
int i915_gem_proc_init(struct drm_minor *minor);
void i915_gem_proc_cleanup(struct drm_minor *minor);
int i915_gem_init_object(struct drm_gem_object *obj);
@@ -575,10 +628,35 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
void i915_gem_retire_work_handler(struct work_struct *work);
+void i915_gem_clflush_object(struct drm_gem_object *obj);
#endif
extern unsigned int i915_fbpercrtc;
+/* i915_gem_tiling.c */
+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
+
+/* i915_gem_debug.c */
+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
+ const char *where, uint32_t mark);
+#if WATCH_INACTIVE
+void i915_verify_inactive(struct drm_device *dev, char *file, int line);
+#else
+#define i915_verify_inactive(dev,file,line)
+#endif
+void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
+ const char *where, uint32_t mark);
+void i915_dump_lru(struct drm_device *dev, const char *where);
+
+#ifdef __linux__
+/* i915_opregion.c */
+extern int intel_opregion_init(struct drm_device *dev);
+extern void intel_opregion_free(struct drm_device *dev);
+extern void opregion_asle_intr(struct drm_device *dev);
+extern void opregion_enable_asle(struct drm_device *dev);
+#endif
+
#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
extern void intel_init_chipset_flush_compat(struct drm_device *dev);
@@ -596,12 +674,20 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
+#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg))
+#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
+
+#if defined(__FreeBSD__)
+typedef boolean_t bool;
+#endif
#define I915_VERBOSE 0
#define I915_RING_VALIDATE 0
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
+#define PRIMARY_RINGBUFFER_SIZE (128*1024)
+
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
volatile char *virt;
@@ -643,6 +729,39 @@ void i915_ring_validate(struct drm_device *dev, const char *func, int line);
extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+#define BREADCRUMB_BITS 31
+#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
+
+#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
+/**
+ * Reads a dword out of the status page, which is written to from the command
+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
+ * MI_STORE_DATA_IMM.
+ *
+ * The following dwords have a reserved meaning:
+ * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
+ * 4: ring 0 head pointer
+ * 5: ring 1 head pointer (915-class)
+ * 6: ring 2 head pointer (915-class)
+ *
+ * The area from dword 0x10 to 0x3ff is available for driver usage.
+ */
+#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
+#define I915_GEM_HWS_INDEX 0x10
+
+/* MCH MMIO space */
+/** 915-945 and GM965 MCH register controlling DRAM channel access */
+#define DCC 0x200
+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
+
+/** 965 MCH register controlling DRAM channel configuration */
+#define CHDECMISC 0x111
+#define CHDECMISC_FLEXMEMORY (1 << 1)
+
/*
* The Bridge device's PCI config space has information about the
* fb aperture size and the amount of pre-reserved memory.
@@ -740,7 +859,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
-#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) /* used to have 1<<22? */
+#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
+#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
#define MI_STORE_DWORD_INDEX_SHIFT 2
#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
@@ -749,27 +869,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define MI_BATCH_NON_SECURE_I965 (1<<8)
#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
-#define BREADCRUMB_BITS 31
-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
-
-#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hws_vaddr))[5])
-
-/**
- * Reads a dword out of the status page, which is written to from the command
- * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
- * MI_STORE_DATA_IMM.
- *
- * The following dwords have a reserved meaning:
- * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
- * 4: ring 0 head pointer
- * 5: ring 1 head pointer (915-class)
- * 6: ring 2 head pointer (915-class)
- *
- * The area from dword 0x10 to 0x3ff is available for driver usage.
- */
-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hws_vaddr))[reg])
-#define I915_GEM_HWS_INDEX 0x10
-
/*
* 3D instructions used by the kernel
*/
@@ -793,6 +892,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
@@ -805,8 +905,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define BLT_DEPTH_16_1555 (2<<24)
#define BLT_DEPTH_32 (3<<24)
#define BLT_ROP_GXCOPY (0xcc<<16)
-#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
-#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
+#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
#define ASYNC_FLIP (1<<22)
#define DISPLAY_PLANE_A (0<<20)
@@ -836,8 +936,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define PRB1_HEAD 0x02044 /* 915+ only */
#define PRB1_START 0x02048 /* 915+ only */
#define PRB1_CTL 0x0204c /* 915+ only */
-#define I965REG_ACTHD 0x02074
+#define ACTHD_I965 0x02074
#define HWS_PGA 0x02080
+#define HWS_ADDRESS_MASK 0xfffff000
+#define HWS_START_ADDRESS_SHIFT 4
#define IPEIR 0x02088
#define NOPID 0x02094
#define HWSTAM 0x02098
@@ -862,11 +964,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
#define I915_DEBUG_INTERRUPT (1<<2)
#define I915_USER_INTERRUPT (1<<1)
+#define I915_ASLE_INTERRUPT (1<<0)
#define EIR 0x020b0
#define EMR 0x020b4
#define ESR 0x020b8
#define INSTPM 0x020c0
-#define I915REG_ACTHD 0x020C8
+#define ACTHD 0x020c8
#define FW_BLC 0x020d8
#define FW_BLC_SELF 0x020e0 /* 915+ only */
#define MI_ARB_STATE 0x020e4 /* 915+ only */
@@ -916,7 +1019,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
/*
* GPIO regs
*/
-
#define GPIOA 0x5010
#define GPIOB 0x5014
#define GPIOC 0x5018
@@ -2050,11 +2152,18 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
(dev)->pci_device == 0x29A2 || \
(dev)->pci_device == 0x2A02 || \
(dev)->pci_device == 0x2A12 || \
- (dev)->pci_device == 0x2A42)
+ (dev)->pci_device == 0x2A42 || \
+ (dev)->pci_device == 0x2E02 || \
+ (dev)->pci_device == 0x2E12 || \
+ (dev)->pci_device == 0x2E22)
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
-#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
+#define IS_GM45(dev) ((dev)->pci_device == 0x2A42)
+
+#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
+ (dev)->pci_device == 0x2E12 || \
+ (dev)->pci_device == 0x2E22)
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \
@@ -2064,8 +2173,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
- IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
+ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
-#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev))
+#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
#endif
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c
index dc218688..7b88cc8d 100644
--- a/shared-core/i915_init.c
+++ b/shared-core/i915_init.c
@@ -100,92 +100,32 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size,
return 0;
}
-static int i915_init_hwstatus(struct drm_device *dev)
+static int
+i915_init_hws_phys(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_memrange_node *free_space;
int ret = 0;
- /* Program Hardware Status Page */
- if (!IS_G33(dev)) {
- dev_priv->status_page_dmah =
- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
+ dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
+ 0xffffffff);
- if (!dev_priv->status_page_dmah) {
- DRM_ERROR("Can not allocate hardware status page\n");
- ret = -ENOMEM;
- goto out;
- }
- dev_priv->hws_vaddr = dev_priv->status_page_dmah->vaddr;
- dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
-
- I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
- } else {
- free_space = drm_memrange_search_free(&dev_priv->vram,
- PAGE_SIZE,
- PAGE_SIZE, 0);
- if (!free_space) {
- DRM_ERROR("No free vram available, aborting\n");
- ret = -ENOMEM;
- goto out;
- }
-
- dev_priv->hws = drm_memrange_get_block(free_space, PAGE_SIZE,
- PAGE_SIZE);
- if (!dev_priv->hws) {
- DRM_ERROR("Unable to allocate or pin hw status page\n");
- ret = -EINVAL;
- goto out;
- }
-
- dev_priv->hws_agpoffset = dev_priv->hws->start;
- dev_priv->hws_map.offset = dev->agp->base +
- dev_priv->hws->start;
- dev_priv->hws_map.size = PAGE_SIZE;
- dev_priv->hws_map.type= 0;
- dev_priv->hws_map.flags= 0;
- dev_priv->hws_map.mtrr = 0;
-
- drm_core_ioremap(&dev_priv->hws_map, dev);
- if (dev_priv->hws_map.handle == NULL) {
- dev_priv->hws_agpoffset = 0;
- DRM_ERROR("can not ioremap virtual addr for"
- "G33 hw status page\n");
- ret = -ENOMEM;
- goto out_free;
- }
- dev_priv->hws_vaddr = dev_priv->hws_map.handle;
- I915_WRITE(HWS_PGA, dev_priv->hws_agpoffset);
+ if (!dev_priv->status_page_dmah) {
+ DRM_ERROR("Can not allocate hardware status page\n");
+ ret = -ENOMEM;
+ goto out;
}
+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
- memset(dev_priv->hws_vaddr, 0, PAGE_SIZE);
+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
- DRM_DEBUG("Enabled hardware status page\n");
+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
+ DRM_DEBUG("hws kernel virt: 0x%p\n", dev_priv->hw_status_page);
- return 0;
-
-out_free:
- /* free hws */
out:
return ret;
}
-static void i915_cleanup_hwstatus(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (!IS_G33(dev)) {
- if (dev_priv->status_page_dmah)
- drm_pci_free(dev, dev_priv->status_page_dmah);
- } else {
- if (dev_priv->hws_map.handle)
- drm_core_ioremapfree(&dev_priv->hws_map, dev);
- if (dev_priv->hws)
- drm_memrange_put_block(dev_priv->hws);
- }
- I915_WRITE(HWS_PGA, 0x1ffff000);
-}
-
static int i915_load_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -195,18 +135,17 @@ static int i915_load_modeset_init(struct drm_device *dev)
i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
/* Basic memrange allocator for stolen space (aka vram) */
- drm_memrange_init(&dev_priv->vram, 0, prealloc_size);
+ drm_mm_init(&dev_priv->vram, 0, prealloc_size);
/* Let GEM Manage from end of prealloc space to end of aperture */
i915_gem_do_init(dev, prealloc_size, agp_size);
+ if (!I915_NEED_GFX_HWS(dev))
+ i915_init_hws_phys(dev);
+
ret = i915_gem_init_ringbuffer(dev);
if (ret)
goto out;
- ret = i915_init_hwstatus(dev);
- if (ret)
- goto destroy_ringbuffer;
-
/* Allow hardware batchbuffers unless told otherwise.
*/
dev_priv->allow_batchbuffer = 1;
@@ -217,7 +156,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (dev_priv->wq == 0) {
DRM_DEBUG("Error\n");
ret = -EINVAL;
- goto destroy_hws;
+ goto destroy_ringbuffer;
}
ret = intel_init_bios(dev);
@@ -247,8 +186,6 @@ modeset_cleanup:
intel_modeset_cleanup(dev);
destroy_wq:
destroy_workqueue(dev_priv->wq);
-destroy_hws:
- i915_cleanup_hwstatus(dev);
destroy_ringbuffer:
i915_gem_cleanup_ringbuffer(dev);
out:
@@ -269,7 +206,8 @@ out:
int i915_driver_load(struct drm_device *dev, unsigned long flags)
{
struct drm_i915_private *dev_priv;
- int ret = 0;
+ int ret = 0, num_pipes = 2;
+ u32 tmp;
dev_priv = drm_alloc(sizeof(struct drm_i915_private), DRM_MEM_DRIVER);
if (dev_priv == NULL)
@@ -323,20 +261,55 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto free_priv;
}
- INIT_LIST_HEAD(&dev_priv->mm.active_list);
- INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
- INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
- INIT_LIST_HEAD(&dev_priv->mm.request_list);
- INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
- i915_gem_retire_work_handler);
- dev_priv->mm.next_gem_seqno = 1;
+ i915_gem_load(dev);
#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
- intel_init_chipset_flush_compat(dev);
+ intel_init_chipset_flush_compat(dev);
+#endif
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
+ intel_opregion_init(dev);
#endif
#endif
+ tmp = I915_READ(PIPEASTAT);
+ I915_WRITE(PIPEASTAT, tmp);
+ tmp = I915_READ(PIPEBSTAT);
+ I915_WRITE(PIPEBSTAT, tmp);
+
+ atomic_set(&dev_priv->irq_received, 0);
+ I915_WRITE(HWSTAM, 0xeffe);
+ I915_WRITE(IMR, 0x0);
+ I915_WRITE(IER, 0x0);
+
+ DRM_SPININIT(&dev_priv->swaps_lock, "swap");
+ INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
+ dev_priv->swaps_pending = 0;
+
+ DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
+ dev_priv->user_irq_refcount = 0;
+ dev_priv->irq_mask_reg = ~0;
+
+ ret = drm_vblank_init(dev, num_pipes);
+ if (ret)
+ goto out_rmmap;
+
+ ret = drm_hotplug_init(dev);
+ if (ret)
+ goto out_rmmap;
+
+ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+
+ i915_enable_interrupt(dev);
+ DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
+
+ /*
+ * Initialize the hardware status page IRQ location.
+ */
+
+ I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = i915_load_modeset_init(dev);
if (ret < 0) {
@@ -344,6 +317,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_rmmap;
}
}
+
return 0;
out_rmmap:
@@ -357,6 +331,23 @@ int i915_driver_unload(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 temp;
+
+ dev_priv->vblank_pipe = 0;
+
+ dev_priv->irq_enabled = 0;
+
+ I915_WRITE(HWSTAM, 0xffffffff);
+ I915_WRITE(IMR, 0xffffffff);
+ I915_WRITE(IER, 0x0);
+
+ temp = I915_READ(PIPEASTAT);
+ I915_WRITE(PIPEASTAT, temp);
+ temp = I915_READ(PIPEBSTAT);
+ I915_WRITE(PIPEBSTAT, temp);
+ temp = I915_READ(IIR);
+ I915_WRITE(IIR, temp);
+
I915_WRITE(PRB0_CTL, 0);
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -385,25 +376,28 @@ int i915_driver_unload(struct drm_device *dev)
dev_priv->sarea_bo = NULL;
}
#endif
- i915_cleanup_hwstatus(dev);
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
- drm_memrange_takedown(&dev_priv->vram);
+ drm_mm_takedown(&dev_priv->vram);
i915_gem_lastclose(dev);
+ if (!I915_NEED_GFX_HWS(dev))
+ drm_pci_free(dev, dev_priv->status_page_dmah);
}
+ drm_rmmap(dev, dev_priv->mmio_map);
+
#ifdef __linux__
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
+ intel_opregion_free(dev);
+#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
- intel_init_chipset_flush_compat(dev);
+ intel_fini_chipset_flush_compat(dev);
#endif
#endif
- DRM_DEBUG("%p\n", dev_priv->mmio_map);
- drm_rmmap(dev, dev_priv->mmio_map);
-
drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
dev->dev_private = NULL;
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index bad5ae29..28fa35fd 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -192,11 +192,11 @@ static void i915_vblank_tasklet(struct drm_device *dev)
u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
RING_LOCALS;
- if (sarea_priv->front_tiled) {
+ if (IS_I965G(dev) && sarea_priv->front_tiled) {
cmd |= XY_SRC_COPY_BLT_DST_TILED;
dst_pitch >>= 2;
}
- if (sarea_priv->back_tiled) {
+ if (IS_I965G(dev) && sarea_priv->back_tiled) {
cmd |= XY_SRC_COPY_BLT_SRC_TILED;
src_pitch >>= 2;
}
@@ -394,28 +394,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
}
}
-#if 0
-static int i915_in_vblank(struct drm_device *dev, int pipe)
-{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- unsigned long pipedsl, vblank, vtotal;
- unsigned long vbl_start, vbl_end, cur_line;
-
- pipedsl = pipe ? PIPEBDSL : PIPEADSL;
- vblank = pipe ? VBLANK_B : VBLANK_A;
- vtotal = pipe ? VTOTAL_B : VTOTAL_A;
-
- vbl_start = I915_READ(vblank) & VBLANK_START_MASK;
- vbl_end = (I915_READ(vblank) >> VBLANK_END_SHIFT) & VBLANK_END_MASK;
- cur_line = I915_READ(pipedsl);
-
- if (cur_line >= vbl_start)
- return 1;
-
- return 0;
-}
-#endif
u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
{
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
@@ -449,22 +428,6 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
count = (high1 << 8) | low;
- /*
- * If we're in the middle of the vblank period, the
- * above regs won't have been updated yet, so return
- * an incremented count to stay accurate
- */
-#if 0
- if (i915_in_vblank(dev, pipe))
- count++;
-#endif
- /* count may be reset by other driver(e.g. 2D driver),
- we have no way to know if it is wrapped or resetted
- when count is zero. do a rough guess.
- */
- if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2)
- dev->last_vblank[pipe] = 0;
-
return count;
}
@@ -533,20 +496,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
if (dev->pdev->msi_enabled)
I915_WRITE(IMR, ~0);
iir = I915_READ(IIR);
-#if 0
- DRM_DEBUG("flag=%08x\n", iir);
-#endif
atomic_inc(&dev_priv->irq_received);
if (iir == 0) {
- DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
- iir,
- I915_READ(IMR),
- I915_READ(IER),
- I915_READ(PIPEASTAT),
- I915_READ(PIPEBSTAT));
if (dev->pdev->msi_enabled) {
- I915_WRITE(IMR,
- dev_priv->irq_mask_reg);
+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
(void) I915_READ(IMR);
}
return IRQ_NONE;
@@ -588,6 +541,16 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
}
+#ifdef __linux__
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
+ if ((iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) &&
+ (pipeb_stats & I915_LEGACY_BLC_EVENT_ENABLE))
+ opregion_asle_intr(dev);
+ if (iir & I915_ASLE_INTERRUPT)
+ opregion_asle_intr(dev);
+#endif
+#endif
+
if (iir & I915_USER_INTERRUPT) {
dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
DRM_WAKEUP(&dev_priv->irq_queue);
@@ -602,6 +565,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
drm_handle_vblank(dev, i915_get_plane(dev, 0));
}
+ /* The vblank interrupt gets enabled even if we didn't ask for
+ it, so make sure it's shut down again */
+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
+ pipeb_stats &= ~(I915_VBLANK_INTERRUPT_ENABLE);
+
if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
PIPE_VBLANK_INTERRUPT_STATUS)) {
vblank++;
@@ -801,7 +769,6 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
PIPE_VBLANK_INTERRUPT_STATUS);
I915_WRITE(pipestat_reg, pipestat);
}
-
DRM_SPINLOCK(&dev_priv->user_irq_lock);
i915_enable_irq(dev_priv, mask_reg);
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
@@ -917,9 +884,11 @@ void i915_enable_interrupt (struct drm_device *dev)
}
}
- I915_WRITE(IMR, dev_priv->irq_mask_reg);
- I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
- (void) I915_READ (IER);
+#ifdef __linux__
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
+ opregion_enable_asle(dev);
+#endif
+#endif
dev_priv->irq_enabled = 1;
}
@@ -929,20 +898,12 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_vblank_pipe *pipe = data;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
- DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
- return -EINVAL;
- }
-
- dev_priv->vblank_pipe = pipe->pipe;
-
return 0;
}
@@ -1032,7 +993,13 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
- drm_update_vblank_count(dev, pipe);
+ /*
+ * We take the ref here and put it when the swap actually completes
+ * in the tasklet.
+ */
+ ret = drm_vblank_get(dev, pipe);
+ if (ret)
+ return ret;
curseq = drm_vblank_count(dev, pipe);
if (seqtype == _DRM_VBLANK_RELATIVE)
@@ -1043,6 +1010,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
swap->sequence = curseq + 1;
} else {
DRM_DEBUG("Missed target sequence\n");
+ drm_vblank_put(dev, pipe);
return -EINVAL;
}
}
@@ -1064,6 +1032,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
irqflags);
DRM_DEBUG("Invalid drawable ID %d\n",
swap->drawable);
+ drm_vblank_put(dev, pipe);
return -EINVAL;
}
@@ -1071,6 +1040,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
+ drm_vblank_put(dev, pipe);
return 0;
}
}
@@ -1094,6 +1064,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
if (dev_priv->swaps_pending >= 100) {
DRM_DEBUG("Too many swaps queued\n");
+ drm_vblank_put(dev, pipe);
return -EBUSY;
}
@@ -1101,17 +1072,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
if (!vbl_swap) {
DRM_ERROR("Failed to allocate memory to queue swap\n");
+ drm_vblank_put(dev, pipe);
return -ENOMEM;
}
DRM_DEBUG("\n");
- ret = drm_vblank_get(dev, pipe);
- if (ret) {
- drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
- return ret;
- }
-
vbl_swap->drw_id = swap->drawable;
vbl_swap->plane = plane;
vbl_swap->sequence = swap->sequence;
@@ -1135,25 +1101,16 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
*/
void i915_driver_irq_preinstall(struct drm_device * dev)
{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- u32 tmp;
-
- tmp = I915_READ(PIPEASTAT);
- I915_WRITE(PIPEASTAT, tmp);
- tmp = I915_READ(PIPEBSTAT);
- I915_WRITE(PIPEBSTAT, tmp);
+ struct drm_i915_private *dev_priv = dev->dev_private;
- atomic_set(&dev_priv->irq_received, 0);
- I915_WRITE(HWSTAM, 0xffff);
- I915_WRITE(IER, 0x0);
- I915_WRITE(IMR, 0xffffffff);
- I915_WRITE(IIR, 0xffffffff);
- (void) I915_READ(IIR);
+ I915_WRITE16(HWSTAM, 0xeffe);
+ I915_WRITE16(IMR, 0x0);
+ I915_WRITE16(IER, 0x0);
}
int i915_driver_irq_postinstall(struct drm_device * dev)
{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
int ret, num_pipes = 2;
DRM_SPININIT(&dev_priv->swaps_lock, "swap");
@@ -1168,10 +1125,7 @@ int i915_driver_irq_postinstall(struct drm_device * dev)
if (ret)
return ret;
- ret = drm_hotplug_init(dev);
- if (ret)
- return ret;
-
+ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
i915_enable_interrupt(dev);
@@ -1187,31 +1141,23 @@ int i915_driver_irq_postinstall(struct drm_device * dev)
void i915_driver_irq_uninstall(struct drm_device * dev)
{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp;
if (!dev_priv)
return;
- dev_priv->irq_enabled = 1;
+ dev_priv->vblank_pipe = 0;
+
+ dev_priv->irq_enabled = 0;
+ I915_WRITE(HWSTAM, 0xffffffff);
+ I915_WRITE(IMR, 0xffffffff);
+ I915_WRITE(IER, 0x0);
temp = I915_READ(PIPEASTAT);
I915_WRITE(PIPEASTAT, temp);
temp = I915_READ(PIPEBSTAT);
I915_WRITE(PIPEBSTAT, temp);
- if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
- I915_WRITE(HWSTAM, 0xffffffff);
- I915_WRITE(IMR, 0xffffffff);
- I915_WRITE(IER, 0x0);
-
- temp = I915_READ(IIR);
- I915_WRITE(IIR, temp);
- } else {
- I915_WRITE16(HWSTAM, 0xffff);
- I915_WRITE16(IMR, 0xffff);
- I915_WRITE16(IER, 0x0);
-
- temp = I915_READ16(IIR);
- I915_WRITE16(IIR, temp);
- }
+ temp = I915_READ(IIR);
+ I915_WRITE(IIR, temp);
}
diff --git a/shared-core/i915_suspend.c b/shared-core/i915_suspend.c
new file mode 100644
index 00000000..5e759b15
--- /dev/null
+++ b/shared-core/i915_suspend.c
@@ -0,0 +1,520 @@
+/* i915_suspend.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
+ */
+/*
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (pipe == PIPE_A)
+ return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
+ else
+ return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
+}
+
+static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for(i = 0; i < 256; i++)
+ array[i] = I915_READ(reg + (i << 2));
+}
+
+static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for(i = 0; i < 256; i++)
+ I915_WRITE(reg + (i << 2), array[i]);
+}
+
+static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE8(index_port, reg);
+ return I915_READ8(data_port);
+}
+
+static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
+ return I915_READ8(VGA_AR_DATA_READ);
+}
+
+static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
+ I915_WRITE8(VGA_AR_DATA_WRITE, val);
+}
+
+static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE8(index_port, reg);
+ I915_WRITE8(data_port, val);
+}
+
+static void i915_save_vga(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* VGA color palette registers */
+ dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
+ /* DACCRX automatically increments during read */
+ I915_WRITE8(VGA_DACRX, 0);
+ /* Read 3 bytes of color data from each index */
+ for (i = 0; i < 256 * 3; i++)
+ dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA);
+
+ /* MSR bits */
+ dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* CRT controller regs */
+ i915_write_indexed(dev, cr_index, cr_data, 0x11,
+ i915_read_indexed(dev, cr_index, cr_data, 0x11) &
+ (~0x80));
+ for (i = 0; i <= 0x24; i++)
+ dev_priv->saveCR[i] =
+ i915_read_indexed(dev, cr_index, cr_data, i);
+ /* Make sure we don't turn off CR group 0 writes */
+ dev_priv->saveCR[0x11] &= ~0x80;
+
+ /* Attribute controller registers */
+ I915_READ8(st01);
+ dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX);
+ for (i = 0; i <= 0x14; i++)
+ dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0);
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX);
+ I915_READ8(st01);
+
+ /* Graphics controller registers */
+ for (i = 0; i < 9; i++)
+ dev_priv->saveGR[i] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i);
+
+ dev_priv->saveGR[0x10] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
+ dev_priv->saveGR[0x11] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
+ dev_priv->saveGR[0x18] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
+
+ /* Sequencer registers */
+ for (i = 0; i < 8; i++)
+ dev_priv->saveSR[i] =
+ i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i);
+}
+
+static void i915_restore_vga(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* MSR bits */
+ I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* Sequencer registers, don't write SR07 */
+ for (i = 0; i < 7; i++)
+ i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i,
+ dev_priv->saveSR[i]);
+
+ /* CRT controller regs */
+ /* Enable CR group 0 writes */
+ i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
+ for (i = 0; i <= 0x24; i++)
+ i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]);
+
+ /* Graphics controller regs */
+ for (i = 0; i < 9; i++)
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i,
+ dev_priv->saveGR[i]);
+
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
+ dev_priv->saveGR[0x10]);
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
+ dev_priv->saveGR[0x11]);
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
+ dev_priv->saveGR[0x18]);
+
+ /* Attribute controller registers */
+ I915_READ8(st01); /* switch back to index mode */
+ for (i = 0; i <= 0x14; i++)
+ i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0);
+ I915_READ8(st01); /* switch back to index mode */
+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20);
+ I915_READ8(st01);
+
+ /* VGA color palette registers */
+ I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
+ /* DACCRX automatically increments during read */
+ I915_WRITE8(VGA_DACWX, 0);
+ /* Read 3 bytes of color data from each index */
+ for (i = 0; i < 256 * 3; i++)
+ I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]);
+
+}
+
+int i915_save_state(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+#if defined(__FreeBSD__)
+ dev_priv->saveLBB = (u8) pci_read_config(dev->device, LBB, 1);
+#else
+ pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
+#endif
+
+ /* Display arbitration control */
+ dev_priv->saveDSPARB = I915_READ(DSPARB);
+
+ /* Pipe & plane A info */
+ dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
+ dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
+ dev_priv->saveFPA0 = I915_READ(FPA0);
+ dev_priv->saveFPA1 = I915_READ(FPA1);
+ dev_priv->saveDPLL_A = I915_READ(DPLL_A);
+ if (IS_I965G(dev))
+ dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
+ dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
+ dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
+ dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
+ dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
+ dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
+ dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+
+ dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
+ dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
+ dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
+ dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
+ if (IS_I965G(dev)) {
+ dev_priv->saveDSPASURF = I915_READ(DSPASURF);
+ dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
+ }
+ i915_save_palette(dev, PIPE_A);
+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
+
+ /* Pipe & plane B info */
+ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
+ dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
+ dev_priv->saveFPB0 = I915_READ(FPB0);
+ dev_priv->saveFPB1 = I915_READ(FPB1);
+ dev_priv->saveDPLL_B = I915_READ(DPLL_B);
+ if (IS_I965G(dev))
+ dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
+ dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
+ dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
+ dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
+ dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
+ dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
+ dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+
+ dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
+ dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
+ dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
+ dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
+ if (IS_I965GM(dev) || IS_GM45(dev)) {
+ dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
+ dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
+ }
+ i915_save_palette(dev, PIPE_B);
+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
+
+ /* CRT state */
+ dev_priv->saveADPA = I915_READ(ADPA);
+
+ /* LVDS state */
+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
+ if (IS_I965G(dev))
+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ dev_priv->saveLVDS = I915_READ(LVDS);
+ if (!IS_I830(dev) && !IS_845G(dev))
+ dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
+
+ /* FIXME: save TV & SDVO state */
+
+ /* FBC state */
+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+
+ /* Interrupt state */
+ dev_priv->saveIIR = I915_READ(IIR);
+ dev_priv->saveIER = I915_READ(IER);
+ dev_priv->saveIMR = I915_READ(IMR);
+
+ /* VGA state */
+ dev_priv->saveVGA0 = I915_READ(VGA0);
+ dev_priv->saveVGA1 = I915_READ(VGA1);
+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+
+ /* Clock gating state */
+ dev_priv->saveD_STATE = I915_READ(D_STATE);
+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
+
+ /* Cache mode state */
+ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
+
+ /* Memory Arbitration state */
+ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
+
+ /* Scratch space */
+ for (i = 0; i < 16; i++) {
+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
+ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
+ }
+ for (i = 0; i < 3; i++)
+ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
+
+ i915_save_vga(dev);
+
+ return 0;
+}
+
+int i915_restore_state(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+#if defined(__FreeBSD__)
+ pci_write_config(dev->device, LBB, dev_priv->saveLBB, 1);
+#else
+ pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
+#endif
+
+ I915_WRITE(DSPARB, dev_priv->saveDSPARB);
+
+ /* Pipe & plane A info */
+ /* Prime the clock */
+ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
+ ~DPLL_VCO_ENABLE);
+ DRM_UDELAY(150);
+ }
+ I915_WRITE(FPA0, dev_priv->saveFPA0);
+ I915_WRITE(FPA1, dev_priv->saveFPA1);
+ /* Actually enable it */
+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
+ DRM_UDELAY(150);
+ if (IS_I965G(dev))
+ I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
+ DRM_UDELAY(150);
+
+ /* Restore mode */
+ I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
+ I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
+ I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
+ I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
+ I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
+ I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
+ I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
+
+ /* Restore plane info */
+ I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
+ I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
+ I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
+ I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
+ if (IS_I965G(dev)) {
+ I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
+ I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
+ }
+
+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
+
+ i915_restore_palette(dev, PIPE_A);
+ /* Enable the plane */
+ I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
+
+ /* Pipe & plane B info */
+ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
+ ~DPLL_VCO_ENABLE);
+ DRM_UDELAY(150);
+ }
+ I915_WRITE(FPB0, dev_priv->saveFPB0);
+ I915_WRITE(FPB1, dev_priv->saveFPB1);
+ /* Actually enable it */
+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
+ DRM_UDELAY(150);
+ if (IS_I965G(dev))
+ I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
+ DRM_UDELAY(150);
+
+ /* Restore mode */
+ I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
+ I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
+ I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
+ I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
+ I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
+ I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
+ I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
+
+ /* Restore plane info */
+ I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
+ I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
+ I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
+ I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
+ if (IS_I965G(dev)) {
+ I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
+ I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
+ }
+
+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
+
+ i915_restore_palette(dev, PIPE_B);
+ /* Enable the plane */
+ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
+
+ /* CRT state */
+ I915_WRITE(ADPA, dev_priv->saveADPA);
+
+ /* LVDS state */
+ if (IS_I965G(dev))
+ I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ I915_WRITE(LVDS, dev_priv->saveLVDS);
+ if (!IS_I830(dev) && !IS_845G(dev))
+ I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
+
+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
+
+ /* FIXME: restore TV & SDVO state */
+
+ /* FBC info */
+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
+
+ /* VGA state */
+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+ I915_WRITE(VGA0, dev_priv->saveVGA0);
+ I915_WRITE(VGA1, dev_priv->saveVGA1);
+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
+ DRM_UDELAY(150);
+
+ /* Clock gating state */
+ I915_WRITE (D_STATE, dev_priv->saveD_STATE);
+ I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
+
+ /* Cache mode state */
+ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
+
+ /* Memory arbitration state */
+ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
+
+ for (i = 0; i < 16; i++) {
+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
+ I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
+ }
+ for (i = 0; i < 3; i++)
+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+
+ i915_restore_vga(dev);
+
+ return 0;
+}
+
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 085336af..5ec2bc3e 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -131,7 +131,7 @@ int nouveau_fifo_init(struct drm_device *dev)
/* No cmdbuf object */
NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE, 0x00000000);
NV_WRITE(NV03_PFIFO_CACHE0_PUSH0, 0x00000000);
- NV_WRITE(NV03_PFIFO_CACHE0_PULL0, 0x00000000);
+ NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x00000000);
NV_WRITE(NV04_PFIFO_SIZE, 0x0000FFFF);
NV_WRITE(NV04_PFIFO_CACHE1_HASH, 0x0000FFFF);
NV_WRITE(NV04_PFIFO_CACHE0_PULL1, 0x00000001);
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c
index 4c46da8d..48872622 100644
--- a/shared-core/nouveau_irq.c
+++ b/shared-core/nouveau_irq.c
@@ -41,6 +41,8 @@
#include "nv50_display.h"
#include "nv50_crtc.h"
#include "nv50_output.h"
+/* needed for hotplug irq */
+#include "nv50_kms_wrapper.h"
void
nouveau_irq_preinstall(struct drm_device *dev)
@@ -510,7 +512,7 @@ nouveau_nv50_display_irq_handler(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t val = NV_READ(NV50_PDISPLAY_SUPERVISOR);
- DRM_INFO("NV50_DISPLAY_INTR - 0x%08X\n", val);
+ DRM_INFO("NV50_PDISPLAY_SUPERVISOR - 0x%08X\n", val);
/* vblank interrupts */
if (val & NV50_PDISPLAY_SUPERVISOR_CRTCn) {
@@ -591,10 +593,13 @@ nouveau_nv50_i2c_irq_handler(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- DRM_INFO("NV50_I2C_INTR - 0x%08X\n", NV_READ(NV50_I2C_CONTROLLER));
+ DRM_INFO("NV50_PCONNECTOR_HOTPLUG_CTRL - 0x%08X\n", NV_READ(NV50_PCONNECTOR_HOTPLUG_CTRL));
/* This seems to be the way to acknowledge an interrupt. */
- NV_WRITE(NV50_I2C_CONTROLLER, 0x7FFF7FFF);
+ NV_WRITE(NV50_PCONNECTOR_HOTPLUG_CTRL, 0x7FFF7FFF);
+
+ /* Do a "dumb" detect all */
+ nv50_kms_connector_detect_all(dev);
}
irqreturn_t
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index 375463b4..1078a9c5 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -36,7 +36,6 @@
#include "nouveau_drv.h"
#include "nv50_kms_wrapper.h"
-
static struct mem_block *
split_block(struct mem_block *p, uint64_t start, uint64_t size,
struct drm_file *file_priv)
diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h
index 6ed23e26..091c22c4 100644
--- a/shared-core/nouveau_reg.h
+++ b/shared-core/nouveau_reg.h
@@ -128,8 +128,6 @@
#define NV04_PTIMER_TIME_1 0x00009410
#define NV04_PTIMER_ALARM_0 0x00009420
-#define NV50_I2C_CONTROLLER 0x0000E054
-
#define NV04_PFB_CFG0 0x00100200
#define NV04_PFB_CFG1 0x00100204
#define NV40_PFB_020C 0x0010020C
diff --git a/shared-core/nv04_fifo.c b/shared-core/nv04_fifo.c
index 230c8e72..88186fe3 100644
--- a/shared-core/nv04_fifo.c
+++ b/shared-core/nv04_fifo.c
@@ -122,8 +122,8 @@ nv04_fifo_save_context(struct nouveau_channel *chan)
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t tmp;
- RAMFC_WR(DMA_PUT, NV04_PFIFO_CACHE1_DMA_PUT);
- RAMFC_WR(DMA_GET, NV04_PFIFO_CACHE1_DMA_GET);
+ RAMFC_WR(DMA_PUT, NV_READ(NV04_PFIFO_CACHE1_DMA_PUT));
+ RAMFC_WR(DMA_GET, NV_READ(NV04_PFIFO_CACHE1_DMA_GET));
tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16;
tmp |= NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE);
diff --git a/shared-core/nv40_graph.c b/shared-core/nv40_graph.c
index 2540fc5f..de178f57 100644
--- a/shared-core/nv40_graph.c
+++ b/shared-core/nv40_graph.c
@@ -1544,6 +1544,8 @@ nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX;
NV_WRITE(NV40_PGRAPH_CTXCTL_0304, tmp);
+ nouveau_wait_for_idle(dev);
+
for (i = 0; i < tv; i++) {
if (NV_READ(NV40_PGRAPH_CTXCTL_030C) == 0)
break;
@@ -1565,9 +1567,7 @@ nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
return 0;
}
-/* Save current context (from PGRAPH) into the channel's context
- *XXX: fails sometimes, not sure why..
- */
+/* Save current context (from PGRAPH) into the channel's context */
int
nv40_graph_save_context(struct nouveau_channel *chan)
{
@@ -1581,9 +1581,7 @@ nv40_graph_save_context(struct nouveau_channel *chan)
return nv40_graph_transfer_context(dev, inst, 1);
}
-/* Restore the context for a specific channel into PGRAPH
- * XXX: fails sometimes.. not sure why
- */
+/* Restore the context for a specific channel into PGRAPH */
int
nv40_graph_load_context(struct nouveau_channel *chan)
{
diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c
index f4111554..53961fc7 100644
--- a/shared-core/r300_cmdbuf.c
+++ b/shared-core/r300_cmdbuf.c
@@ -77,6 +77,9 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
return -EFAULT;
}
+ box.x2--; /* Hardware expects inclusive bottom-right corner */
+ box.y2--;
+
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
box.x1 = (box.x1) &
R300_CLIPRECT_MASK;
@@ -95,8 +98,8 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
R300_CLIPRECT_MASK;
box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) &
R300_CLIPRECT_MASK;
-
}
+
OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
(box.y1 << R300_CLIPRECT_Y_SHIFT));
OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
@@ -136,6 +139,18 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
ADVANCE_RING();
}
+ /* flus cache and wait idle clean after cliprect change */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(R300_RB3D_DC_FLUSH);
+ ADVANCE_RING();
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ ADVANCE_RING();
+ /* set flush flag */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED;
+
return 0;
}
@@ -164,13 +179,13 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(0x21DC, 1);
ADD_RANGE(R300_VAP_UNKNOWN_221C, 1);
ADD_RANGE(R300_VAP_CLIP_X_0, 4);
- ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1);
+ ADD_RANGE(R300_VAP_PVS_STATE_FLUSH_REG, 1);
ADD_RANGE(R300_VAP_UNKNOWN_2288, 1);
ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2);
ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
ADD_RANGE(R300_GB_ENABLE, 1);
ADD_RANGE(R300_GB_MSPOS0, 5);
- ADD_RANGE(R300_TX_CNTL, 1);
+ ADD_RANGE(R300_TX_INVALTAGS, 1);
ADD_RANGE(R300_TX_ENABLE, 1);
ADD_RANGE(0x4200, 4);
ADD_RANGE(0x4214, 1);
@@ -188,7 +203,7 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(0x42C0, 2);
ADD_RANGE(R300_RS_CNTL_0, 2);
- ADD_RANGE(0x43A4, 2);
+ ADD_RANGE(R300_SC_HYPERZ, 2);
ADD_RANGE(0x43E8, 1);
ADD_RANGE(0x46A4, 5);
@@ -207,14 +222,12 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(0x4E50, 9);
ADD_RANGE(0x4E88, 1);
ADD_RANGE(0x4EA0, 2);
- ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3);
- ADD_RANGE(R300_RB3D_ZSTENCIL_FORMAT, 4);
- ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
- ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
- ADD_RANGE(0x4F28, 1);
- ADD_RANGE(0x4F30, 2);
- ADD_RANGE(0x4F44, 1);
- ADD_RANGE(0x4F54, 1);
+ ADD_RANGE(R300_ZB_CNTL, 3);
+ ADD_RANGE(R300_ZB_FORMAT, 4);
+ ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
+ ADD_RANGE(R300_ZB_DEPTHPITCH, 1);
+ ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1);
+ ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13);
ADD_RANGE(R300_TX_FILTER_0, 16);
ADD_RANGE(R300_TX_FILTER1_0, 16);
@@ -227,7 +240,7 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
/* Sporadic registers used as primitives are emitted */
- ADD_RANGE(R300_RB3D_ZCACHE_CTLSTAT, 1);
+ ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1);
ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1);
ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
@@ -246,7 +259,7 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(R500_RS_INST_0, 16);
ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
-
+ ADD_RANGE(R500_ZB_FIFO_SIZE, 2);
ADD_RANGE(R500_GA_US_VECTOR_INDEX, 2);
} else {
ADD_RANGE(R300_PFS_CNTL_0, 3);
@@ -432,15 +445,28 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
if (sz * 16 > cmdbuf->bufsz)
return -EINVAL;
- BEGIN_RING(5 + sz * 4);
- /* Wait for VAP to come to senses.. */
- /* there is no need to emit it multiple times, (only once before VAP is programmed,
- but this optimization is for later */
- OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0);
+ /* VAP is very sensitive so we purge cache before we program it
+ * and we also flush its state before & after */
+ BEGIN_RING(6);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(R300_RB3D_DC_FLUSH);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
+ OUT_RING(0);
+ ADVANCE_RING();
+ /* set flush flag */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED;
+
+ BEGIN_RING(3 + sz * 4);
OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
+ ADVANCE_RING();
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
+ OUT_RING(0);
ADVANCE_RING();
cmdbuf->buf += sz * 16;
@@ -468,6 +494,15 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
OUT_RING_TABLE((int *)cmdbuf->buf, 8);
ADVANCE_RING();
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(R300_RB3D_DC_FLUSH);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ ADVANCE_RING();
+ /* set flush flag */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED;
+
cmdbuf->buf += 8 * 4;
cmdbuf->bufsz -= 8 * 4;
@@ -587,22 +622,23 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
return 0;
}
-static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
- drm_radeon_kcmd_buffer_t *cmdbuf)
+static __inline__ int r300_emit_draw_indx_2(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
- u32 *cmd = (u32 *) cmdbuf->buf;
- int count, ret;
+ u32 *cmd;
+ int count;
+ int expected_count;
RING_LOCALS;
- count=(cmd[0]>>16) & 0x3fff;
+ cmd = (u32 *) cmdbuf->buf;
+ count = (cmd[0]>>16) & 0x3fff;
+ expected_count = cmd[1] >> 16;
+ if (!(cmd[1] & R300_VAP_VF_CNTL__INDEX_SIZE_32bit))
+ expected_count = (expected_count+1)/2;
- if ((cmd[1] & 0x8000ffff) != 0x80000810) {
- DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
- return -EINVAL;
- }
- ret = !radeon_check_offset(dev_priv, cmd[2]);
- if (ret) {
- DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+ if (count && count != expected_count) {
+ DRM_ERROR("3D_DRAW_INDX_2: packet size %i, expected %i\n",
+ count, expected_count);
return -EINVAL;
}
@@ -614,6 +650,50 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
cmdbuf->buf += (count+2)*4;
cmdbuf->bufsz -= (count+2)*4;
+ if (!count) {
+ drm_r300_cmd_header_t header;
+
+ if (cmdbuf->bufsz < 4*4 + sizeof(header)) {
+ DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER, but stream is too short.\n");
+ return -EINVAL;
+ }
+
+ header.u = *(unsigned int *)cmdbuf->buf;
+
+ cmdbuf->buf += sizeof(header);
+ cmdbuf->bufsz -= sizeof(header);
+ cmd = (u32 *) cmdbuf->buf;
+
+ if (header.header.cmd_type != R300_CMD_PACKET3 ||
+ header.packet3.packet != R300_CMD_PACKET3_RAW ||
+ cmd[0] != CP_PACKET3(RADEON_CP_INDX_BUFFER, 2)) {
+ DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER.\n");
+ return -EINVAL;
+ }
+
+ if ((cmd[1] & 0x8000ffff) != 0x80000810) {
+ DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+ return -EINVAL;
+ }
+ if (!radeon_check_offset(dev_priv, cmd[2])) {
+ DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+ return -EINVAL;
+ }
+ if (cmd[3] != expected_count) {
+ DRM_ERROR("INDX_BUFFER: buffer size %i, expected %i\n",
+ cmd[3], expected_count);
+ return -EINVAL;
+ }
+
+ BEGIN_RING(4);
+ OUT_RING(cmd[0]);
+ OUT_RING_TABLE((int *)(cmdbuf->buf + 4), 3);
+ ADVANCE_RING();
+
+ cmdbuf->buf += 4*4;
+ cmdbuf->bufsz -= 4*4;
+ }
+
return 0;
}
@@ -657,11 +737,22 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
case RADEON_CNTL_BITBLT_MULTI:
return r300_emit_bitblt_multi(dev_priv, cmdbuf);
- case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
- return r300_emit_indx_buffer(dev_priv, cmdbuf);
- case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
- case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
- case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
+ case RADEON_CP_INDX_BUFFER:
+ DRM_ERROR("packet3 INDX_BUFFER without preceding 3D_DRAW_INDX_2 is illegal.\n");
+ return -EINVAL;
+ case RADEON_CP_3D_DRAW_IMMD_2:
+ /* triggers drawing using in-packet vertex data */
+ case RADEON_CP_3D_DRAW_VBUF_2:
+ /* triggers drawing of vertex buffers setup elsewhere */
+ dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED |
+ RADEON_PURGE_EMITED);
+ break;
+ case RADEON_CP_3D_DRAW_INDX_2:
+ /* triggers drawing using indices to vertex buffer */
+ /* whenever we send vertex we clear flush & purge */
+ dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED |
+ RADEON_PURGE_EMITED);
+ return r300_emit_draw_indx_2(dev_priv, cmdbuf);
case RADEON_WAIT_FOR_IDLE:
case RADEON_CP_NOP:
/* these packets are safe */
@@ -757,16 +848,53 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
*/
static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
{
+ uint32_t cache_z, cache_3d, cache_2d;
RING_LOCALS;
- BEGIN_RING(6);
+ cache_z = R300_ZC_FLUSH;
+ cache_2d = R300_DC_FLUSH_2D;
+ cache_3d = R300_DC_FLUSH_3D;
+ if (!(dev_priv->track_flush & RADEON_PURGE_EMITED)) {
+ /* we can purge, primitive where draw since last purge */
+ cache_z |= R300_ZC_FREE;
+ cache_2d |= R300_DC_FREE_2D;
+ cache_3d |= R300_DC_FREE_3D;
+ }
+
+ /* flush & purge zbuffer */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));
+ OUT_RING(cache_z);
+ ADVANCE_RING();
+ /* flush & purge 3d */
+ BEGIN_RING(2);
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
- OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
- OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0));
- OUT_RING(R300_RB3D_ZCACHE_UNKNOWN_03);
- OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
- OUT_RING(0x0);
+ OUT_RING(cache_3d);
+ ADVANCE_RING();
+ /* flush & purge texture */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_TX_INVALTAGS, 0));
+ OUT_RING(0);
+ ADVANCE_RING();
+ /* FIXME: is this one really needed ? */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_RB3D_AARESOLVE_CTL, 0));
+ OUT_RING(0);
+ ADVANCE_RING();
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ ADVANCE_RING();
+ /* flush & purge 2d through E2 as RB2D will trigger lockup */
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET0(R300_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(cache_2d);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_2D_IDLECLEAN |
+ RADEON_WAIT_HOST_IDLECLEAN);
ADVANCE_RING();
+ /* set flush & purge flags */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED;
}
/**
@@ -948,8 +1076,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
DRM_DEBUG("\n");
- /* See the comment above r300_emit_begin3d for why this call must be here,
- * and what the cleanup gotos are for. */
+ /* pacify */
r300_pacify(dev_priv);
if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) {
diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h
index 65c5606a..9e9cb526 100644
--- a/shared-core/r300_reg.h
+++ b/shared-core/r300_reg.h
@@ -311,7 +311,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
* avoids bugs caused by still running shaders reading bad data from memory.
*/
-#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
+#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284
/* Absolutely no clue what this register is about. */
#define R300_VAP_UNKNOWN_2288 0x2288
@@ -507,7 +507,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* gap */
/* Zero to flush caches. */
-#define R300_TX_CNTL 0x4100
+#define R300_TX_INVALTAGS 0x4100
#define R300_TX_FLUSH 0x0
/* The upper enable bits are guessed, based on fglrx reported limits. */
@@ -696,6 +696,27 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11)
/* END: Rasterization / Interpolators - many guesses */
+/* Hierarchical Z Enable */
+#define R300_SC_HYPERZ 0x43a4
+# define R300_SC_HYPERZ_DISABLE (0 << 0)
+# define R300_SC_HYPERZ_ENABLE (1 << 0)
+# define R300_SC_HYPERZ_MIN (0 << 1)
+# define R300_SC_HYPERZ_MAX (1 << 1)
+# define R300_SC_HYPERZ_ADJ_256 (0 << 2)
+# define R300_SC_HYPERZ_ADJ_128 (1 << 2)
+# define R300_SC_HYPERZ_ADJ_64 (2 << 2)
+# define R300_SC_HYPERZ_ADJ_32 (3 << 2)
+# define R300_SC_HYPERZ_ADJ_16 (4 << 2)
+# define R300_SC_HYPERZ_ADJ_8 (5 << 2)
+# define R300_SC_HYPERZ_ADJ_4 (6 << 2)
+# define R300_SC_HYPERZ_ADJ_2 (7 << 2)
+# define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5)
+# define R300_SC_HYPERZ_HZ_Z0MIN (1 << 5)
+# define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6)
+# define R300_SC_HYPERZ_HZ_Z0MAX (1 << 6)
+
+#define R300_SC_EDGERULE 0x43a8
+
/* BEGIN: Scissors and cliprects */
/* There are four clipping rectangles. Their corner coordinates are inclusive.
@@ -1332,6 +1353,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
+#define R300_RB3D_AARESOLVE_CTL 0x4E88
/* gap */
/* Guess by Vladimir.
@@ -1346,19 +1368,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* for this.
* Bit (1<<8) is the "test" bit. so plain write is 6 - vd
*/
-#define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00
-# define R300_RB3D_Z_DISABLED_1 0x00000010
-# define R300_RB3D_Z_DISABLED_2 0x00000014
-# define R300_RB3D_Z_TEST 0x00000012
-# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
-# define R300_RB3D_Z_WRITE_ONLY 0x00000006
-
-# define R300_RB3D_Z_TEST 0x00000012
-# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
-# define R300_RB3D_Z_WRITE_ONLY 0x00000006
-# define R300_RB3D_STENCIL_ENABLE 0x00000001
-
-#define R300_RB3D_ZSTENCIL_CNTL_1 0x4F04
+#define R300_ZB_CNTL 0x4F00
+# define R300_STENCIL_ENABLE (1 << 0)
+# define R300_Z_ENABLE (1 << 1)
+# define R300_Z_WRITE_ENABLE (1 << 2)
+# define R300_Z_SIGNED_COMPARE (1 << 3)
+# define R300_STENCIL_FRONT_BACK (1 << 4)
+
+#define R300_ZB_ZSTENCILCNTL 0x4f04
/* functions */
# define R300_ZS_NEVER 0
# define R300_ZS_LESS 1
@@ -1378,52 +1395,166 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_ZS_INVERT 5
# define R300_ZS_INCR_WRAP 6
# define R300_ZS_DECR_WRAP 7
+# define R300_Z_FUNC_SHIFT 0
/* front and back refer to operations done for front
and back faces, i.e. separate stencil function support */
-# define R300_RB3D_ZS1_DEPTH_FUNC_SHIFT 0
-# define R300_RB3D_ZS1_FRONT_FUNC_SHIFT 3
-# define R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT 6
-# define R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT 9
-# define R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT 12
-# define R300_RB3D_ZS1_BACK_FUNC_SHIFT 15
-# define R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT 18
-# define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21
-# define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24
-
-#define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08
-# define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0
-# define R300_RB3D_ZS2_STENCIL_MASK 0xFF
-# define R300_RB3D_ZS2_STENCIL_MASK_SHIFT 8
-# define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT 16
+# define R300_S_FRONT_FUNC_SHIFT 3
+# define R300_S_FRONT_SFAIL_OP_SHIFT 6
+# define R300_S_FRONT_ZPASS_OP_SHIFT 9
+# define R300_S_FRONT_ZFAIL_OP_SHIFT 12
+# define R300_S_BACK_FUNC_SHIFT 15
+# define R300_S_BACK_SFAIL_OP_SHIFT 18
+# define R300_S_BACK_ZPASS_OP_SHIFT 21
+# define R300_S_BACK_ZFAIL_OP_SHIFT 24
+
+#define R300_ZB_STENCILREFMASK 0x4f08
+# define R300_STENCILREF_SHIFT 0
+# define R300_STENCILREF_MASK 0x000000ff
+# define R300_STENCILMASK_SHIFT 8
+# define R300_STENCILMASK_MASK 0x0000ff00
+# define R300_STENCILWRITEMASK_SHIFT 16
+# define R300_STENCILWRITEMASK_MASK 0x00ff0000
/* gap */
-#define R300_RB3D_ZSTENCIL_FORMAT 0x4F10
-# define R300_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
-# define R300_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
- /* 16 bit format or some aditional bit ? */
-# define R300_DEPTH_FORMAT_UNK32 (32 << 0)
+#define R300_ZB_FORMAT 0x4f10
+# define R300_DEPTHFORMAT_16BIT_INT_Z (0 << 0)
+# define R300_DEPTHFORMAT_16BIT_13E3 (1 << 0)
+# define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL (2 << 0)
+/* reserved up to (15 << 0) */
+# define R300_INVERT_13E3_LEADING_ONES (0 << 4)
+# define R300_INVERT_13E3_LEADING_ZEROS (1 << 4)
-#define R300_RB3D_EARLY_Z 0x4F14
-# define R300_EARLY_Z_DISABLE (0 << 0)
-# define R300_EARLY_Z_ENABLE (1 << 0)
+#define R300_ZB_ZTOP 0x4F14
+# define R300_ZTOP_DISABLE (0 << 0)
+# define R300_ZTOP_ENABLE (1 << 0)
/* gap */
-#define R300_RB3D_ZCACHE_CTLSTAT 0x4F18 /* GUESS */
-# define R300_RB3D_ZCACHE_UNKNOWN_01 0x1
-# define R300_RB3D_ZCACHE_UNKNOWN_03 0x3
+#define R300_ZB_ZCACHE_CTLSTAT 0x4f18
+# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0)
+# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0)
+# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1)
+# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1)
+# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31)
+# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31)
+
+#define R300_ZB_BW_CNTL 0x4f1c
+# define R300_HIZ_DISABLE (0 << 0)
+# define R300_HIZ_ENABLE (1 << 0)
+# define R300_HIZ_MIN (0 << 1)
+# define R300_HIZ_MAX (1 << 1)
+# define R300_FAST_FILL_DISABLE (0 << 2)
+# define R300_FAST_FILL_ENABLE (1 << 2)
+# define R300_RD_COMP_DISABLE (0 << 3)
+# define R300_RD_COMP_ENABLE (1 << 3)
+# define R300_WR_COMP_DISABLE (0 << 4)
+# define R300_WR_COMP_ENABLE (1 << 4)
+# define R300_ZB_CB_CLEAR_RMW (0 << 5)
+# define R300_ZB_CB_CLEAR_CACHE_LINEAR (1 << 5)
+# define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE (0 << 6)
+# define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE (1 << 6)
+
+# define R500_ZEQUAL_OPTIMIZE_ENABLE (0 << 7)
+# define R500_ZEQUAL_OPTIMIZE_DISABLE (1 << 7)
+# define R500_SEQUAL_OPTIMIZE_ENABLE (0 << 8)
+# define R500_SEQUAL_OPTIMIZE_DISABLE (1 << 8)
+
+# define R500_BMASK_ENABLE (0 << 10)
+# define R500_BMASK_DISABLE (1 << 10)
+# define R500_HIZ_EQUAL_REJECT_DISABLE (0 << 11)
+# define R500_HIZ_EQUAL_REJECT_ENABLE (1 << 11)
+# define R500_HIZ_FP_EXP_BITS_DISABLE (0 << 12)
+# define R500_HIZ_FP_EXP_BITS_1 (1 << 12)
+# define R500_HIZ_FP_EXP_BITS_2 (2 << 12)
+# define R500_HIZ_FP_EXP_BITS_3 (3 << 12)
+# define R500_HIZ_FP_EXP_BITS_4 (4 << 12)
+# define R500_HIZ_FP_EXP_BITS_5 (5 << 12)
+# define R500_HIZ_FP_INVERT_LEADING_ONES (0 << 15)
+# define R500_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15)
+# define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16)
+# define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16)
+# define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17)
+# define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17)
+# define R500_PEQ_PACKING_DISABLE (0 << 18)
+# define R500_PEQ_PACKING_ENABLE (1 << 18)
+# define R500_COVERED_PTR_MASKING_DISABLE (0 << 18)
+# define R500_COVERED_PTR_MASKING_ENABLE (1 << 18)
+
/* gap */
-#define R300_RB3D_DEPTHOFFSET 0x4F20
-#define R300_RB3D_DEPTHPITCH 0x4F24
-# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
-# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
-# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
-# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
-# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
-# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
+/* Z Buffer Address Offset.
+ * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles.
+ */
+#define R300_ZB_DEPTHOFFSET 0x4f20
+
+/* Z Buffer Pitch and Endian Control */
+#define R300_ZB_DEPTHPITCH 0x4f24
+# define R300_DEPTHPITCH_MASK 0x00003FFC
+# define R300_DEPTHMACROTILE_DISABLE (0 << 16)
+# define R300_DEPTHMACROTILE_ENABLE (1 << 16)
+# define R300_DEPTHMICROTILE_LINEAR (0 << 17)
+# define R300_DEPTHMICROTILE_TILED (1 << 17)
+# define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17)
+# define R300_DEPTHENDIAN_NO_SWAP (0 << 18)
+# define R300_DEPTHENDIAN_WORD_SWAP (1 << 18)
+# define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18)
+# define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18)
+
+/* Z Buffer Clear Value */
+#define R300_ZB_DEPTHCLEARVALUE 0x4f28
+
+#define R300_ZB_ZMASK_OFFSET 0x4f30
+#define R300_ZB_ZMASK_PITCH 0x4f34
+#define R300_ZB_ZMASK_WRINDEX 0x4f38
+#define R300_ZB_ZMASK_DWORD 0x4f3c
+#define R300_ZB_ZMASK_RDINDEX 0x4f40
+
+/* Hierarchical Z Memory Offset */
+#define R300_ZB_HIZ_OFFSET 0x4f44
+
+/* Hierarchical Z Write Index */
+#define R300_ZB_HIZ_WRINDEX 0x4f48
+
+/* Hierarchical Z Data */
+#define R300_ZB_HIZ_DWORD 0x4f4c
+
+/* Hierarchical Z Read Index */
+#define R300_ZB_HIZ_RDINDEX 0x4f50
+
+/* Hierarchical Z Pitch */
+#define R300_ZB_HIZ_PITCH 0x4f54
+
+/* Z Buffer Z Pass Counter Data */
+#define R300_ZB_ZPASS_DATA 0x4f58
+
+/* Z Buffer Z Pass Counter Address */
+#define R300_ZB_ZPASS_ADDR 0x4f5c
+
+/* Depth buffer X and Y coordinate offset */
+#define R300_ZB_DEPTHXY_OFFSET 0x4f60
+# define R300_DEPTHX_OFFSET_SHIFT 1
+# define R300_DEPTHX_OFFSET_MASK 0x000007FE
+# define R300_DEPTHY_OFFSET_SHIFT 17
+# define R300_DEPTHY_OFFSET_MASK 0x07FE0000
+
+/* Sets the fifo sizes */
+#define R500_ZB_FIFO_SIZE 0x4fd0
+# define R500_OP_FIFO_SIZE_FULL (0 << 0)
+# define R500_OP_FIFO_SIZE_HALF (1 << 0)
+# define R500_OP_FIFO_SIZE_QUATER (2 << 0)
+# define R500_OP_FIFO_SIZE_EIGTHS (4 << 0)
+
+/* Stencil Reference Value and Mask for backfacing quads */
+/* R300_ZB_STENCILREFMASK handles front face */
+#define R500_ZB_STENCILREFMASK_BF 0x4fd4
+# define R500_STENCILREF_SHIFT 0
+# define R500_STENCILREF_MASK 0x000000ff
+# define R500_STENCILMASK_SHIFT 8
+# define R500_STENCILMASK_MASK 0x0000ff00
+# define R500_STENCILWRITEMASK_SHIFT 16
+# define R500_STENCILWRITEMASK_MASK 0x00ff0000
/* BEGIN: Vertex program instruction set */
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 53177bb0..04f4b1f8 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -40,6 +40,7 @@
#define RADEON_FIFO_DEBUG 0
static int radeon_do_cleanup_cp(struct drm_device * dev);
+static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
@@ -144,8 +145,12 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
} else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
+ RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
+ RADEON_WRITE(RS480_AGP_BASE_2, agp_base_hi);
} else {
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_base_lo);
+ RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200)
RADEON_WRITE(RADEON_AGP_BASE_2, agp_base_hi);
}
@@ -290,23 +295,8 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
DRM_UDELAY(1);
}
} else {
- /* 3D */
- tmp = RADEON_READ(R300_RB3D_DSTCACHE_CTLSTAT);
- tmp |= RADEON_RB3D_DC_FLUSH_ALL;
- RADEON_WRITE(R300_RB3D_DSTCACHE_CTLSTAT, tmp);
-
- /* 2D */
- tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT);
- tmp |= RADEON_RB3D_DC_FLUSH_ALL;
- RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);
-
- for (i = 0; i < dev_priv->usec_timeout; i++) {
- if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT)
- & RADEON_RB3D_DC_BUSY)) {
- return 0;
- }
- DRM_UDELAY(1);
- }
+ /* don't flush or purge cache here or lockup */
+ return 0;
}
#if RADEON_FIFO_DEBUG
@@ -329,6 +319,9 @@ static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
return 0;
DRM_UDELAY(1);
}
+ DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(RADEON_RBBM_STATUS),
+ RADEON_READ(R300_VAP_CNTL_STATUS));
#if RADEON_FIFO_DEBUG
DRM_ERROR("failed!\n");
@@ -355,6 +348,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
}
DRM_UDELAY(1);
}
+ DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(RADEON_RBBM_STATUS),
+ RADEON_READ(R300_VAP_CNTL_STATUS));
#if RADEON_FIFO_DEBUG
DRM_ERROR("failed!\n");
@@ -448,6 +444,7 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
DRM_INFO("Loading R300 Microcode\n");
for (i = 0; i < 256; i++) {
@@ -536,14 +533,20 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
dev_priv->cp_running = 1;
- BEGIN_RING(6);
-
+ BEGIN_RING(8);
+ /* isync can only be written through cp on r5xx write it here */
+ OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
+ OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
+ RADEON_ISYNC_ANY3D_IDLE2D |
+ RADEON_ISYNC_WAIT_IDLEGUI |
+ RADEON_ISYNC_CPSCRATCH_IDLEGUI);
RADEON_PURGE_CACHE();
RADEON_PURGE_ZCACHE();
RADEON_WAIT_UNTIL_IDLE();
-
ADVANCE_RING();
COMMIT_RING();
+
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED;
}
/* Reset the Command Processor. This will not flush any pending
@@ -864,14 +867,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) |
RS480_REQ_TYPE_SNOOP_DIS));
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
- IGP_WRITE_MCIND(RS690_MC_AGP_BASE,
- (unsigned int)dev_priv->gart_vm_start);
- IGP_WRITE_MCIND(RS690_MC_AGP_BASE_2, 0);
- } else {
- RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
- RADEON_WRITE(RS480_AGP_BASE_2, 0);
- }
+ radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start);
dev_priv->gart_size = 32*1024*1024;
temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
@@ -1070,7 +1066,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
(dev_priv->color_fmt << 10) |
(dev_priv->chip_family < CHIP_R200 ? RADEON_ZBLOCK16 : 0));
-
+
dev_priv->depth_clear.rb3d_zstencilcntl =
(dev_priv->depth_fmt |
RADEON_Z_TEST_ALWAYS |
@@ -1264,7 +1260,6 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
/* if we have an offset set from userspace */
if (dev_priv->pcigart_offset_set) {
-
/* if it came from userspace - remap it */
if (dev_priv->pcigart_offset_set == 1) {
dev_priv->gart_info.bus_addr =
@@ -1415,6 +1410,7 @@ static int radeon_do_resume_cp(struct drm_device * dev)
radeon_cp_init_ring_buffer(dev, dev_priv);
radeon_do_engine_reset(dev);
+ radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
DRM_DEBUG("radeon_do_resume_cp() complete\n");
diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c
index d961189e..b0c4abe8 100644
--- a/shared-core/radeon_cs.c
+++ b/shared-core/radeon_cs.c
@@ -140,7 +140,7 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct
val |= offset;
break;
case R300_RB3D_COLOROFFSET0:
- case R300_RB3D_DEPTHOFFSET:
+ case R300_ZB_DEPTHOFFSET:
case R300_TX_OFFSET_0:
case R300_TX_OFFSET_0+4:
ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset);
@@ -202,7 +202,7 @@ static __inline__ int radeon_cs_check_offset(struct drm_device *dev,
offset <<= 10;
break;
case R300_RB3D_COLOROFFSET0:
- case R300_RB3D_DEPTHOFFSET:
+ case R300_ZB_DEPTHOFFSET:
offset = val;
break;
case R300_TX_OFFSET_0:
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index 2b8d7f6e..a40ff6dd 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -39,7 +39,7 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20080528"
+#define DRIVER_DATE "20080613"
/* Interface history:
*
@@ -289,6 +289,9 @@ struct drm_radeon_master_private {
drm_radeon_sarea_t *sarea_priv;
};
+#define RADEON_FLUSH_EMITED (1 < 0)
+#define RADEON_PURGE_EMITED (1 < 1)
+
/* command submission struct */
struct drm_radeon_cs_priv {
uint32_t id_wcnt;
@@ -387,7 +390,6 @@ typedef struct drm_radeon_private {
struct radeon_surface surfaces[RADEON_MAX_SURFACES];
struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
-
u32 scratch_ages[5];
unsigned int crtc_last_cnt;
@@ -397,13 +399,10 @@ typedef struct drm_radeon_private {
uint32_t flags; /* see radeon_chip_flags */
unsigned long fb_aper_offset;
- int num_gb_pipes;
-
bool mm_enabled;
struct radeon_mm_info mm;
drm_local_map_t *mmio;
- uint32_t chip_family;
unsigned long pcigart_offset;
unsigned int pcigart_offset_set;
@@ -420,6 +419,10 @@ typedef struct drm_radeon_private {
u32 ram_width;
enum radeon_pll_errata pll_errata;
+
+ int num_gb_pipes;
+ int track_flush;
+ uint32_t chip_family; /* extract from flags */
struct radeon_mm_obj **ib_objs;
/* ib bitmap */
@@ -485,6 +488,7 @@ extern void radeon_mem_release(struct drm_file *file_priv,
struct mem_block *heap);
/* radeon_irq.c */
+extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state);
extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
@@ -779,11 +783,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_PP_TXFILTER_1 0x1c6c
#define RADEON_PP_TXFILTER_2 0x1c84
-#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c
-# define RADEON_RB2D_DC_FLUSH (3 << 0)
-# define RADEON_RB2D_DC_FREE (3 << 2)
-# define RADEON_RB2D_DC_FLUSH_ALL 0xf
-# define RADEON_RB2D_DC_BUSY (1 << 31)
#define RADEON_RB3D_CNTL 0x1c3c
# define RADEON_ALPHA_BLEND_ENABLE (1 << 0)
# define RADEON_PLANE_MASK_ENABLE (1 << 1)
@@ -809,9 +808,10 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define R300_ZB_ZCACHE_CTLSTAT 0x4f18
# define R300_ZC_FLUSH (1 << 0)
# define R300_ZC_FREE (1 << 1)
-# define R300_ZC_FLUSH_ALL 0x3
# define R300_ZC_BUSY (1 << 31)
#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c
+# define R300_RB3D_DC_FLUSH (2 << 0)
+# define R300_RB3D_DC_FREE (2 << 2)
# define R300_RB3D_DC_FINISH (1 << 4)
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_Z_TEST_MASK (7 << 4)
@@ -1387,10 +1387,10 @@ do { \
#define RADEON_PURGE_CACHE() do { \
if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
+ OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \
} else { \
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
+ OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \
} \
} while (0)
@@ -1407,10 +1407,10 @@ do { \
#define RADEON_PURGE_ZCACHE() do { \
if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL); \
+ OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \
} else { \
- OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); \
- OUT_RING(R300_ZC_FLUSH_ALL); \
+ OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \
+ OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \
} \
} while (0)
diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c
index f5f7f75d..dcf58e43 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -35,7 +35,7 @@
#include "radeon_drm.h"
#include "radeon_drv.h"
-static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
+void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -255,35 +255,27 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- u32 crtc_cnt_reg, crtc_status_reg;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
+ if (crtc < 0 || crtc > 1) {
+ DRM_ERROR("Invalid crtc %d\n", crtc);
+ return -EINVAL;
+ }
+
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
- if (crtc == 0) {
- crtc_cnt_reg = R500_D1CRTC_FRAME_COUNT;
- crtc_status_reg = R500_D1CRTC_STATUS;
- } else if (crtc == 1) {
- crtc_cnt_reg = R500_D2CRTC_FRAME_COUNT;
- crtc_status_reg = R500_D2CRTC_STATUS;
- } else
- return -EINVAL;
- return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1);
-
+ if (crtc == 0)
+ return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
+ else
+ return RADEON_READ(R500_D2CRTC_FRAME_COUNT);
} else {
- if (crtc == 0) {
- crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME;
- crtc_status_reg = RADEON_CRTC_STATUS;
- } else if (crtc == 1) {
- crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME;
- crtc_status_reg = RADEON_CRTC2_STATUS;
- } else {
- return -EINVAL;
- }
- return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1);
+ if (crtc == 0)
+ return RADEON_READ(RADEON_CRTC_CRNT_FRAME);
+ else
+ return RADEON_READ(RADEON_CRTC2_CRNT_FRAME);
}
}
@@ -382,27 +374,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
int radeon_vblank_crtc_get(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
- u32 flag;
- u32 value;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
- flag = RADEON_READ(R500_DxMODE_INT_MASK);
- value = 0;
- if (flag & R500_D1MODE_INT_MASK)
- value |= DRM_RADEON_VBLANK_CRTC1;
-
- if (flag & R500_D2MODE_INT_MASK)
- value |= DRM_RADEON_VBLANK_CRTC2;
- } else {
- flag = RADEON_READ(RADEON_GEN_INT_CNTL);
- value = 0;
- if (flag & RADEON_CRTC_VBLANK_MASK)
- value |= DRM_RADEON_VBLANK_CRTC1;
-
- if (flag & RADEON_CRTC2_VBLANK_MASK)
- value |= DRM_RADEON_VBLANK_CRTC2;
- }
- return value;
+ return dev_priv->vblank_crtc;
}
int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c
index 1e582ee0..dbd73c50 100644
--- a/shared-core/radeon_mem.c
+++ b/shared-core/radeon_mem.c
@@ -88,7 +88,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size,
list_for_each(p, heap) {
int start = (p->start + mask) & ~mask;
- if (p->file_priv == 0 && start + size <= p->start + p->size)
+ if (p->file_priv == NULL && start + size <= p->start + p->size)
return split_block(p, start, size, file_priv);
}
@@ -113,7 +113,7 @@ static void free_block(struct mem_block *p)
/* Assumes a single contiguous range. Needs a special file_priv in
* 'heap' to stop it being subsumed.
*/
- if (p->next->file_priv == 0) {
+ if (p->next->file_priv == NULL) {
struct mem_block *q = p->next;
p->size += q->size;
p->next = q->next;
@@ -121,7 +121,7 @@ static void free_block(struct mem_block *p)
drm_free(q, sizeof(*q), DRM_MEM_BUFS);
}
- if (p->prev->file_priv == 0) {
+ if (p->prev->file_priv == NULL) {
struct mem_block *q = p->prev;
q->size += p->size;
q->next = p->next;
@@ -174,7 +174,7 @@ void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap)
* 'heap' to stop it being subsumed.
*/
list_for_each(p, heap) {
- while (p->file_priv == 0 && p->next->file_priv == 0) {
+ while (p->file_priv == NULL && p->next->file_priv == NULL) {
struct mem_block *q = p->next;
p->size += q->size;
p->next = q->next;
diff --git a/shared-core/xgi_drm.h b/shared-core/xgi_drm.h
index ce584420..7d01065e 100644
--- a/shared-core/xgi_drm.h
+++ b/shared-core/xgi_drm.h
@@ -123,11 +123,15 @@ struct xgi_state_info {
#define DRM_XGI_FREE 2
#define DRM_XGI_SUBMIT_CMDLIST 3
#define DRM_XGI_STATE_CHANGE 4
+#define DRM_XGI_SET_FENCE 5
+#define DRM_XGI_WAIT_FENCE 6
#define XGI_IOCTL_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_BOOTSTRAP, struct xgi_bootstrap)
#define XGI_IOCTL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_ALLOC, struct xgi_mem_alloc)
#define XGI_IOCTL_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_FREE, __u32)
#define XGI_IOCTL_SUBMIT_CMDLIST DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_SUBMIT_CMDLIST, struct xgi_cmd_info)
#define XGI_IOCTL_STATE_CHANGE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_STATE_CHANGE, struct xgi_state_info)
+#define XGI_IOCTL_SET_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_SET_FENCE, u32)
+#define XGI_IOCTL_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_WAIT_FENCE, u32)
#endif /* _XGI_DRM_H_ */