summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/drm')
-rw-r--r--sys/dev/pci/drm/ati_pcigart.c6
-rw-r--r--sys/dev/pci/drm/drm.h98
-rw-r--r--sys/dev/pci/drm/drmP.h70
-rw-r--r--sys/dev/pci/drm/drm_bufs.c34
-rw-r--r--sys/dev/pci/drm/drm_drv.c13
-rw-r--r--sys/dev/pci/drm/drm_internal.h40
-rw-r--r--sys/dev/pci/drm/drm_irq.c300
-rw-r--r--sys/dev/pci/drm/drm_pciids.h115
-rw-r--r--sys/dev/pci/drm/drm_vm.c3
-rw-r--r--sys/dev/pci/drm/i915_dma.c627
-rw-r--r--sys/dev/pci/drm/i915_drm.h55
-rw-r--r--sys/dev/pci/drm/i915_drv.c6
-rw-r--r--sys/dev/pci/drm/i915_drv.h219
-rw-r--r--sys/dev/pci/drm/i915_irq.c469
-rw-r--r--sys/dev/pci/drm/i915_mem.c8
-rw-r--r--sys/dev/pci/drm/mach64_dma.c358
-rw-r--r--sys/dev/pci/drm/mach64_drv.c4
-rw-r--r--sys/dev/pci/drm/mach64_drv.h453
-rw-r--r--sys/dev/pci/drm/mach64_irq.c101
-rw-r--r--sys/dev/pci/drm/mach64_state.c59
-rw-r--r--sys/dev/pci/drm/mga_dma.c89
-rw-r--r--sys/dev/pci/drm/mga_drv.c4
-rw-r--r--sys/dev/pci/drm/mga_drv.h21
-rw-r--r--sys/dev/pci/drm/mga_irq.c78
-rw-r--r--sys/dev/pci/drm/mga_state.c26
-rw-r--r--sys/dev/pci/drm/mga_warp.c1
-rw-r--r--sys/dev/pci/drm/r128_cce.c5
-rw-r--r--sys/dev/pci/drm/r128_drv.c4
-rw-r--r--sys/dev/pci/drm/r128_drv.h14
-rw-r--r--sys/dev/pci/drm/r128_irq.c55
-rw-r--r--sys/dev/pci/drm/r128_state.c43
-rw-r--r--sys/dev/pci/drm/r300_cmdbuf.c186
-rw-r--r--sys/dev/pci/drm/r300_reg.h18
-rw-r--r--sys/dev/pci/drm/radeon_cp.c1176
-rw-r--r--sys/dev/pci/drm/radeon_drm.h21
-rw-r--r--sys/dev/pci/drm/radeon_drv.c4
-rw-r--r--sys/dev/pci/drm/radeon_drv.h268
-rw-r--r--sys/dev/pci/drm/radeon_irq.c300
-rw-r--r--sys/dev/pci/drm/radeon_mem.c6
-rw-r--r--sys/dev/pci/drm/radeon_microcode.h1844
-rw-r--r--sys/dev/pci/drm/radeon_state.c67
-rw-r--r--sys/dev/pci/drm/savage_bci.c20
-rw-r--r--sys/dev/pci/drm/savage_state.c184
-rw-r--r--sys/dev/pci/drm/sis_drv.h2
-rw-r--r--sys/dev/pci/drm/via_3d_reg.h1
-rw-r--r--sys/dev/pci/drm/via_dma.c124
-rw-r--r--sys/dev/pci/drm/via_drm.h8
-rw-r--r--sys/dev/pci/drm/via_drv.c4
-rw-r--r--sys/dev/pci/drm/via_drv.h20
-rw-r--r--sys/dev/pci/drm/via_irq.c120
-rw-r--r--sys/dev/pci/drm/via_map.c7
-rw-r--r--sys/dev/pci/drm/via_verifier.c4
-rw-r--r--sys/dev/pci/drm/via_verifier.h8
-rw-r--r--sys/dev/pci/drm/via_video.c4
54 files changed, 5138 insertions, 2636 deletions
diff --git a/sys/dev/pci/drm/ati_pcigart.c b/sys/dev/pci/drm/ati_pcigart.c
index ca50fce5685..ddcb1a7126c 100644
--- a/sys/dev/pci/drm/ati_pcigart.c
+++ b/sys/dev/pci/drm/ati_pcigart.c
@@ -35,7 +35,7 @@
#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
-int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
+int drm_ati_pcigart_init(drm_device_t *dev, struct drm_ati_pcigart_info *gart_info)
{
unsigned long pages;
u32 *pci_gart = NULL, page_base;
@@ -69,7 +69,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
#if defined(__FreeBSD__)
KASSERT(PAGE_SIZE >= ATI_PCIGART_PAGE_SIZE, ("page size too small"));
-#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#else
KASSERT(PAGE_SIZE >= ATI_PCIGART_PAGE_SIZE);
#endif
@@ -98,7 +98,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
return 1;
}
-int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
+int drm_ati_pcigart_cleanup(drm_device_t *dev, struct drm_ati_pcigart_info *gart_info)
{
if (dev->sg == NULL) {
DRM_ERROR( "no scatter/gather memory!\n" );
diff --git a/sys/dev/pci/drm/drm.h b/sys/dev/pci/drm/drm.h
index d8a6bbd0849..ae1da174395 100644
--- a/sys/dev/pci/drm/drm.h
+++ b/sys/dev/pci/drm/drm.h
@@ -249,7 +249,8 @@ enum drm_map_flags {
_DRM_KERNEL = 0x08, /**< kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
- _DRM_REMOVABLE = 0x40 /**< Removable mapping */
+ _DRM_REMOVABLE = 0x40, /**< Removable mapping */
+ _DRM_DRIVER = 0x80 /**< Managed by driver */
};
struct drm_ctx_priv_map {
@@ -554,6 +555,20 @@ union drm_wait_vblank {
struct drm_wait_vblank_reply reply;
};
+
+#define _DRM_PRE_MODESET 1
+#define _DRM_POST_MODESET 2
+
+/**
+ * DRM_IOCTL_MODESET_CTL ioctl argument type
+ *
+ * \sa drmModesetCtl().
+ */
+struct drm_modeset_ctl {
+ uint32_t crtc;
+ uint32_t cmd;
+};
+
/**
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
@@ -629,8 +644,14 @@ struct drm_set_version {
#define DRM_FENCE_FLAG_EMIT 0x00000001
#define DRM_FENCE_FLAG_SHAREABLE 0x00000002
+/**
+ * On hardware with no interrupt events for operation completion,
+ * indicates that the kernel should sleep while waiting for any blocking
+ * operation to complete rather than spinning.
+ *
+ * Has no effect otherwise.
+ */
#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004
-#define DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS 0x00000008
#define DRM_FENCE_FLAG_NO_USER 0x00000010
/* Reserved for driver use */
@@ -646,7 +667,7 @@ struct drm_fence_arg {
unsigned int signaled;
unsigned int error;
unsigned int sequence;
- unsigned int pad64;
+ unsigned int pad64;
uint64_t expand_pad[2]; /*Future expansion */
};
@@ -661,6 +682,10 @@ struct drm_fence_arg {
#define DRM_BO_FLAG_EXE (1ULL << 2)
/*
+ * All of the bits related to access mode
+ */
+#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE)
+/*
* Status flags. Can be read to determine the actual state of a buffer.
* Can also be set in the buffer mask before validation.
*/
@@ -700,7 +725,14 @@ struct drm_fence_arg {
*/
#define DRM_BO_FLAG_NO_MOVE (1ULL << 8)
-/* Mask: Make sure the buffer is in cached memory when mapped
+/* Mask: Make sure the buffer is in cached memory when mapped. In conjunction
+ * with DRM_BO_FLAG_CACHED it also allows the buffer to be bound into the GART
+ * with unsnooped PTEs instead of snooped, by using chipset-specific cache
+ * flushing at bind time. A better name might be DRM_BO_FLAG_TT_UNSNOOPED,
+ * as the eviction to local memory (TTM unbind) on map is just a side effect
+ * to prevent aggressive cache prefetch from the GPU disturbing the cache
+ * management that the DRM is doing.
+ *
* Flags: Acknowledge.
* Buffers allocated with this flag should not be used for suballocators
* This type may have issues on CPUs with over-aggressive caching
@@ -740,18 +772,49 @@ struct drm_fence_arg {
#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31)
/* We can add more of these now with a 64-bit flag type */
-/* Memory flag mask */
+/*
+ * This is a mask covering all of the memory type flags; easier to just
+ * use a single constant than a bunch of | values. It covers
+ * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4
+ */
#define DRM_BO_MASK_MEM 0x00000000FF000000ULL
-#define DRM_BO_MASK_MEMTYPE 0x00000000FF0800A0ULL
-
+/*
+ * This adds all of the CPU-mapping options in with the memory
+ * type to label all bits which change how the page gets mapped
+ */
+#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \
+ DRM_BO_FLAG_CACHED_MAPPED | \
+ DRM_BO_FLAG_CACHED | \
+ DRM_BO_FLAG_MAPPABLE)
+
/* Driver-private flags */
#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL
-/* Don't block on validate and map */
+/*
+ * Don't block on validate and map. Instead, return EBUSY.
+ */
#define DRM_BO_HINT_DONT_BLOCK 0x00000002
-/* Don't place this buffer on the unfenced list.*/
+/*
+ * Don't place this buffer on the unfenced list. This means
+ * that the buffer will not end up having a fence associated
+ * with it as a result of this operation
+ */
#define DRM_BO_HINT_DONT_FENCE 0x00000004
+/**
+ * On hardware with no interrupt events for operation completion,
+ * indicates that the kernel should sleep while waiting for any blocking
+ * operation to complete rather than spinning.
+ *
+ * Has no effect otherwise.
+ */
#define DRM_BO_HINT_WAIT_LAZY 0x00000008
+/*
+ * The client has compute relocations refering to this buffer using the
+ * offset in the presumed_offset field. If that offset ends up matching
+ * where this buffer lands, the kernel is free to skip executing those
+ * relocations
+ */
+#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010
#define DRM_BO_INIT_MAGIC 0xfe769812
#define DRM_BO_INIT_MAJOR 1
@@ -768,10 +831,11 @@ struct drm_bo_info_req {
unsigned int desired_tile_stride;
unsigned int tile_info;
unsigned int pad64;
+ uint64_t presumed_offset;
};
struct drm_bo_create_req {
- uint64_t mask;
+ uint64_t flags;
uint64_t size;
uint64_t buffer_start;
unsigned int hint;
@@ -787,7 +851,7 @@ struct drm_bo_create_req {
struct drm_bo_info_rep {
uint64_t flags;
- uint64_t mask;
+ uint64_t proposed_flags;
uint64_t size;
uint64_t offset;
uint64_t arg_handle;
@@ -878,7 +942,7 @@ struct drm_bo_version_arg {
struct drm_mm_type_arg {
unsigned int mem_type;
- unsigned int lock_flags;
+ unsigned int lock_flags;
};
struct drm_mm_init_arg {
@@ -890,6 +954,11 @@ struct drm_mm_init_arg {
uint64_t p_size;
};
+struct drm_mm_info_arg {
+ unsigned int mem_type;
+ uint64_t p_size;
+};
+
/**
* \name Ioctls Definitions
*/
@@ -909,6 +978,7 @@ struct drm_mm_init_arg {
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
@@ -950,7 +1020,7 @@ struct drm_mm_init_arg {
#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)
@@ -980,7 +1050,7 @@ struct drm_mm_init_arg {
#define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg)
#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
-
+#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg)
/*@}*/
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h
index 6248fedfaec..c9ffa6c4bfa 100644
--- a/sys/dev/pci/drm/drmP.h
+++ b/sys/dev/pci/drm/drmP.h
@@ -129,6 +129,7 @@ typedef struct drm_file drm_file_t;
#include "drm.h"
#include "drm_linux_list.h"
#include "drm_atomic.h"
+#include "drm_internal.h"
#ifdef __amd64__
#define DRM_NO_MTRR
@@ -494,12 +495,16 @@ do { \
#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD_version > 500000)
/* Returns -errno to shared code */
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
-for ( ret = 0 ; !ret && !(condition) ; ) { \
+ret = 0; \
+while ( ret == 0 ) { \
DRM_UNLOCK(); \
DRM_SPINLOCK(&dev->irq_lock); \
- if (!(condition)) \
- ret = -msleep(&(queue), &dev->irq_lock, \
- PZERO | PCATCH, "drmwtq", (timeout)); \
+ if (condition) { \
+ DRM_SPINUNLOCK(&dev->irq_lock); \
+ break; \
+ } \
+ ret = -msleep(&(queue), &dev->irq_lock, \
+ PZERO | PCATCH, "drmwtq", (timeout)); \
DRM_SPINUNLOCK(&dev->irq_lock); \
DRM_LOCK(); \
}
@@ -733,11 +738,6 @@ typedef struct drm_vbl_sig {
int pid;
} drm_vbl_sig_t;
-struct drm_drawable_info {
- unsigned int num_rects;
- struct drm_clip_rect *rects;
-};
-
/* location of GART table */
#define DRM_ATI_GART_MAIN 1
#define DRM_ATI_GART_FB 2
@@ -746,14 +746,18 @@ struct drm_drawable_info {
#define DRM_ATI_GART_PCIE 2
#define DRM_ATI_GART_IGP 3
-typedef struct ati_pcigart_info {
+#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : (1ULL<<(n)) -1)
+#define upper_32_bits(_val) (((u64)(_val)) >> 32)
+
+struct drm_ati_pcigart_info {
int gart_table_location;
int gart_reg_if;
void *addr;
dma_addr_t bus_addr;
+ dma_addr_t table_mask;
drm_local_map_t mapping;
int table_size;
-} drm_ati_pcigart_info;
+};
struct drm_driver_info {
int (*load)(struct drm_device *, unsigned long flags);
@@ -778,10 +782,12 @@ struct drm_driver_info {
int new);
int (*kernel_context_switch_unlock)(struct drm_device *dev);
void (*irq_preinstall)(drm_device_t *dev);
- void (*irq_postinstall)(drm_device_t *dev);
+ int (*irq_postinstall)(drm_device_t *dev);
void (*irq_uninstall)(drm_device_t *dev);
irqreturn_t (*irq_handler)(DRM_IRQ_ARGS);
- int (*vblank_wait)(drm_device_t *dev, unsigned int *sequence);
+ u_int32_t (*get_vblank_counter)(struct drm_device *, int);
+ int (*enable_vblank)(struct drm_device *, int);
+ void (*disable_vblank)(struct drm_device *, int);
drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */
@@ -912,9 +918,24 @@ struct drm_device {
atomic_t context_flag; /* Context swapping flag */
int last_context; /* Last current context */
- int vbl_queue; /* vbl wait channel */
- atomic_t vbl_received;
- atomic_t vbl_received2;
+
+ /* VBLANK support */
+ int *vbl_queue; /* vbl wait channel */
+ atomic_t *_vblank_count; /* no vblank interrupts */
+ DRM_SPINTYPE vbl_lock; /* locking for vblank operations */
+#if 0 /* unneeded for now */
+ TAILQ_HEAD(vbl_sigs);
+#endif
+ atomic_t vbl_signal_pending; /* sigs pending on all crtcs */
+ atomic_t *vblank_refcount; /* no. users for vlank interrupts */
+ u_int32_t *last_vblank; /* locked, used for overflow handling*/
+ int *vblank_enabled; /* make sure we only disable once */
+ u_int32_t *vblank_premodeset; /* compensation for wraparounds */
+ int *vblank_suspend; /* Don't wait while crtc is disabled */
+ struct timeout vblank_disable_timer;
+ int num_crtcs; /* number of crtcs on device */
+
+ u_int32_t max_vblank_count; /* size of counter reg */
#ifdef __FreeBSD__
struct sigio *buf_sigio; /* Processes waiting for SIGIO */
@@ -1040,8 +1061,15 @@ irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
void drm_driver_irq_preinstall(drm_device_t *dev);
void drm_driver_irq_postinstall(drm_device_t *dev);
void drm_driver_irq_uninstall(drm_device_t *dev);
-int drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
-void drm_vbl_send_signals(drm_device_t *dev);
+void drm_vbl_send_signals(drm_device_t *dev, int crtc);
+void drm_vblank_cleanup(struct drm_device *);
+int drm_vblank_init(struct drm_device *, int);
+u_int32_t drm_vblank_count(struct drm_device *, int);
+void drm_update_vblank_count(struct drm_device *, int);
+int drm_vblank_get(struct drm_device *, int);
+void drm_vblank_put(struct drm_device *, int);
+int drm_modeset_ctl(struct drm_device *dev, void *, struct drm_file *);
+void drm_handle_vblank(struct drm_device *, int);
/* AGP/PCI Express/GART support (drm_agpsupport.c) */
int drm_device_is_agp(drm_device_t *dev);
@@ -1071,10 +1099,8 @@ extern int drm_sysctl_cleanup(drm_device_t *dev);
#endif /* __FreeBSD__ */
/* ATI PCIGART support (ati_pcigart.c) */
-int drm_ati_pcigart_init(drm_device_t *dev,
- drm_ati_pcigart_info *gart_info);
-int drm_ati_pcigart_cleanup(drm_device_t *dev,
- drm_ati_pcigart_info *gart_info);
+int drm_ati_pcigart_init(drm_device_t *, struct drm_ati_pcigart_info *);
+int drm_ati_pcigart_cleanup(drm_device_t *, struct drm_ati_pcigart_info *);
/* Locking IOCTL support (drm_drv.c) */
int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv);
diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c
index 0102327beee..83e0c71f1ae 100644
--- a/sys/dev/pci/drm/drm_bufs.c
+++ b/sys/dev/pci/drm/drm_bufs.c
@@ -903,18 +903,15 @@ drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
{
int order, ret;
- DRM_SPINLOCK(&dev->dma_lock);
- if (request->count < 0 || request->count > 4096) {
- DRM_SPINUNLOCK(&dev->dma_lock);
+ if (request->count < 0 || request->count > 4096)
return EINVAL;
- }
order = drm_order(request->size);
- if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) {
- DRM_SPINUNLOCK(&dev->dma_lock);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return EINVAL;
- }
+
+ DRM_SPINLOCK(&dev->dma_lock);
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
@@ -939,18 +936,15 @@ drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
{
int order, ret;
- DRM_SPINLOCK(&dev->dma_lock);
- if (request->count < 0 || request->count > 4096) {
- DRM_SPINUNLOCK(&dev->dma_lock);
+ if (request->count < 0 || request->count > 4096)
return EINVAL;
- }
order = drm_order(request->size);
- if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) {
- DRM_SPINUNLOCK(&dev->dma_lock);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return EINVAL;
- }
+
+ DRM_SPINLOCK(&dev->dma_lock);
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
@@ -975,18 +969,14 @@ drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
{
int order, ret;
- DRM_SPINLOCK(&dev->dma_lock);
-
- if (request->count < 0 || request->count > 4096) {
- DRM_SPINUNLOCK(&dev->dma_lock);
+ if (request->count < 0 || request->count > 4096)
return EINVAL;
- }
order = drm_order(request->size);
- if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER){
- DRM_SPINUNLOCK(&dev->dma_lock);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return EINVAL;
- }
+
+ DRM_SPINLOCK(&dev->dma_lock);
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index a7c8f2ba48a..efb5e16b695 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -121,6 +121,7 @@ static drm_ioctl_desc_t drm_ioctls[256] = {
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
};
@@ -405,10 +406,7 @@ int
drm_lastclose(drm_device_t *dev)
{
struct drm_magic_entry *pt;
- drm_local_map_t *map;
-#ifdef __FreeBSD__
- drm_local_map_t *mapsave;
-#endif
+ drm_local_map_t *map, *mapsave;
DRM_SPINLOCK_ASSERT(&dev->dev_lock);
@@ -462,9 +460,12 @@ drm_lastclose(drm_device_t *dev)
#ifdef __FreeBSD__
TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) {
#else
- while ((map = TAILQ_FIRST(&dev->maplist)) != NULL) {
+ for (map = TAILQ_FIRST(&dev->maplist); map != TAILQ_END(&dev->maplist);
+ map = mapsave) {
+ mapsave = TAILQ_NEXT(map, link);
#endif
- drm_rmmap(dev, map);
+ if (!(map->flags & _DRM_DRIVER))
+ drm_rmmap(dev, map);
}
drm_dma_takedown(dev);
diff --git a/sys/dev/pci/drm/drm_internal.h b/sys/dev/pci/drm/drm_internal.h
new file mode 100644
index 00000000000..b82a189d38d
--- /dev/null
+++ b/sys/dev/pci/drm/drm_internal.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2007 Red Hat, Inc
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS 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.
+ */
+
+/* This header file holds function prototypes and data types that are
+ * internal to the drm (not exported to user space) but shared across
+ * drivers and platforms */
+
+#ifndef __DRM_INTERNAL_H__
+#define __DRM_INTERNAL_H__
+
+/**
+ * Drawable information.
+ */
+struct drm_drawable_info {
+ unsigned int num_rects;
+ struct drm_clip_rect *rects;
+};
+
+#endif
diff --git a/sys/dev/pci/drm/drm_irq.c b/sys/dev/pci/drm/drm_irq.c
index 251c67af4c1..3f9b0ac4c71 100644
--- a/sys/dev/pci/drm/drm_irq.c
+++ b/sys/dev/pci/drm/drm_irq.c
@@ -36,11 +36,12 @@
#include "drm.h"
irqreturn_t drm_irq_handler_wrap(DRM_IRQ_ARGS);
+void vblank_disable(void *);
#ifdef __OpenBSD__
-void drm_locked_task(void *context, void *pending);
+void drm_locked_task(void *context, void *pending);
#else
-void drm_locked_task(void *context, int pending __unused);
+void drm_locked_task(void *context, int pending __unused);
#endif
int
@@ -129,7 +130,7 @@ drm_irq_install(drm_device_t *dev)
dev->context_flag = 0;
-#ifdef __OpenBSD__
+#ifdef __OpenBSD__
mtx_init(&dev->irq_lock, IPL_BIO);
#else
DRM_SPININIT(&dev->irq_lock, "DRM IRQ lock");
@@ -170,7 +171,7 @@ drm_irq_install(drm_device_t *dev)
drm_irq_handler_wrap, dev,
dev->device.dv_xname);
#else
- dev->irqh = pci_intr_establish(dev->pa.pa_pc, ih, IPL_TTY,
+ dev->irqh = pci_intr_establish(dev->pa.pa_pc, ih, IPL_BIO,
drm_irq_handler_wrap, dev);
#endif
if (!dev->irqh) {
@@ -232,6 +233,7 @@ drm_irq_uninstall(drm_device_t *dev)
#elif defined(__NetBSD__) || defined(__OpenBSD__)
pci_intr_disestablish(dev->pa.pa_pc, dev->irqh);
#endif
+ drm_vblank_cleanup(dev);
DRM_SPINUNINIT(&dev->irq_lock);
return 0;
@@ -266,24 +268,252 @@ drm_control(drm_device_t *dev, void *data, struct drm_file *file_priv)
}
}
+void
+vblank_disable(void *arg)
+{
+ struct drm_device *dev = (struct drm_device*)arg;
+ int i;
+
+ for (i=0; i < dev->num_crtcs; i++){
+ DRM_SPINLOCK(&dev->vbl_lock);
+ if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
+ dev->vblank_enabled[i]) {
+ dev->driver.disable_vblank(dev, i);
+ dev->vblank_enabled[i] = 0;
+ }
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+ }
+}
+
+void
+drm_vblank_cleanup(struct drm_device *dev)
+{
+ if (dev->num_crtcs == 0)
+ return; /* not initialised */
+
+ timeout_del(&dev->vblank_disable_timer);
+
+ vblank_disable(dev);
+
+ if (dev->vbl_queue)
+ drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) *
+ dev->num_crtcs, M_DRM);
+#if 0 /* disabled for now */
+ if (dev-vbl_sigs)
+ drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
+ M_DRM);
+#endif
+ if (dev->_vblank_count)
+ drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
+ dev->num_crtcs, M_DRM);
+ if (dev->vblank_refcount)
+ drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
+ dev->num_crtcs, M_DRM);
+ if (dev->vblank_enabled)
+ drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
+ dev->num_crtcs, M_DRM);
+ if (dev->last_vblank)
+ drm_free(dev->last_vblank, sizeof(*dev->last_vblank) *
+ dev->num_crtcs, M_DRM);
+ if (dev->vblank_premodeset)
+ drm_free(dev->vblank_premodeset,
+ sizeof(*dev->vblank_premodeset) * dev->num_crtcs, M_DRM);
+ if (dev->vblank_suspend)
+ drm_free(dev->vblank_suspend,
+ sizeof(*dev->vblank_suspend) * dev->num_crtcs, M_DRM);
+
+ dev->num_crtcs = 0;
+ DRM_SPINUNINIT(&dev->vbl_lock);
+}
+
+int
+drm_vblank_init(struct drm_device *dev, int num_crtcs)
+{
+ int i;
+
+ timeout_set(&dev->vblank_disable_timer, vblank_disable, dev);
+ mtx_init(&dev->vbl_lock, IPL_BIO);
+ atomic_set(&dev->vbl_signal_pending, 0);
+ dev->num_crtcs = num_crtcs;
+
+ if ((dev->vbl_queue = drm_calloc(num_crtcs, sizeof(*dev->vbl_queue),
+ M_DRM)) == NULL)
+ goto err;
+
+ if ((dev->_vblank_count = drm_calloc(num_crtcs,
+ sizeof(*dev->_vblank_count), M_DRM)) == NULL)
+ goto err;
+
+ if ((dev->vblank_refcount = drm_calloc(num_crtcs,
+ sizeof(*dev->vblank_refcount), M_DRM)) == NULL)
+ goto err;
+ if ((dev->vblank_enabled = drm_calloc(num_crtcs,
+ sizeof(*dev->vblank_enabled), M_DRM)) == NULL)
+ goto err;
+ if ((dev->last_vblank = drm_calloc(num_crtcs, sizeof(*dev->last_vblank),
+ M_DRM)) == NULL)
+ goto err;
+ if ((dev->vblank_premodeset = drm_calloc(num_crtcs,
+ sizeof(*dev->vblank_premodeset), M_DRM)) == NULL)
+ goto err;
+ if ((dev->vblank_suspend = drm_calloc(num_crtcs,
+ sizeof(*dev->vblank_suspend), M_DRM)) == NULL)
+ goto err;
+
+
+ /* Zero everything */
+ for (i = 0; i < num_crtcs; i++) {
+ atomic_set(&dev->_vblank_count[i], 0);
+ atomic_set(&dev->vblank_refcount[i], 0);
+ }
+
+ return (0);
+
+err:
+ drm_vblank_cleanup(dev);
+ return ENOMEM;
+}
+
+u_int32_t
+drm_vblank_count(struct drm_device *dev, int crtc)
+{
+ return atomic_read(&dev->_vblank_count[crtc]);
+}
+
+void
+drm_update_vblank_count(struct drm_device *dev, int crtc)
+{
+ u_int32_t cur_vblank, diff;
+
+ if (dev->vblank_suspend[crtc])
+ return;
+
+ /*
+ * Deal with the possibility of lost vblanks due to disabled interrupts
+ * counter overflow may have happened.
+ */
+ cur_vblank = dev->driver.get_vblank_counter(dev, crtc);
+ DRM_SPINLOCK(&dev->vbl_lock);
+ if (cur_vblank < dev->last_vblank[crtc]) {
+ if (cur_vblank == dev->last_vblank[crtc] -1)
+ diff = 0;
+ else {
+ diff = dev->max_vblank_count - dev->last_vblank[crtc];
+ diff += cur_vblank;
+ }
+ } else {
+ diff = cur_vblank - dev->last_vblank[crtc];
+ }
+ dev->last_vblank[crtc] = cur_vblank;
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+
+ atomic_add(diff, &dev->_vblank_count[crtc]);
+}
+
+int
+drm_vblank_get(struct drm_device *dev, int crtc)
+{
+ int ret = 0;
+
+ DRM_SPINLOCK(&dev->vbl_lock);
+
+ atomic_add(1, &dev->vblank_refcount[crtc]);
+ if (dev->vblank_refcount[crtc] == 1 &&
+ dev->vblank_enabled[crtc] == 0) {
+ ret = dev->driver.enable_vblank(dev, crtc);
+ if (ret)
+ atomic_dec(&dev->vblank_refcount[crtc]);
+ else
+ dev->vblank_enabled[crtc] = 1;
+ }
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+
+ return ret;
+}
+
+void
+drm_vblank_put(struct drm_device *dev, int crtc)
+{
+ DRM_SPINLOCK(&dev->vbl_lock);
+ /* Last user schedules interrupt disable */
+ atomic_dec(&dev->vblank_refcount[crtc]);
+ if (&dev->vblank_refcount[crtc] == 0)
+ timeout_add(&dev->vblank_disable_timer, 5*DRM_HZ);
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+}
+
+int
+drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_modeset_ctl *modeset = data;
+ int crtc, ret = 0;
+
+ crtc = modeset->crtc;
+ if (crtc >= dev->num_crtcs) {
+ ret = EINVAL;
+ goto out;
+ }
+
+ switch (modeset->cmd) {
+ case _DRM_PRE_MODESET:
+ dev->vblank_premodeset[crtc] =
+ dev->driver.get_vblank_counter(dev, crtc);
+ dev->vblank_suspend[crtc] = 1;
+ break;
+ case _DRM_POST_MODESET:
+ if (dev->vblank_suspend[crtc]) {
+ uint32_t new =
+ dev->driver.get_vblank_counter(dev, crtc);
+ /* Compensate for spurious wraparound */
+ if (new < dev->vblank_premodeset[crtc])
+ atomic_sub(dev->max_vblank_count + new -
+ dev->vblank_premodeset[crtc],
+ &dev->_vblank_count[crtc]);
+ }
+ dev->vblank_suspend[crtc] = 0;
+ break;
+ default:
+ ret = EINVAL;
+ }
+
+out:
+ return ret;
+}
+
int
drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
drm_wait_vblank_t *vblwait = data;
- struct timeval now;
- int ret, flags;
+ int ret, flags, crtc, seq;
if (!dev->irq_enabled)
return EINVAL;
+ flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
+ crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
+
+ if (crtc >= dev->num_crtcs)
+ return EINVAL;
+
+ drm_update_vblank_count(dev, crtc);
+ seq = drm_vblank_count(dev,crtc);
+
if (vblwait->request.type & _DRM_VBLANK_RELATIVE) {
- vblwait->request.sequence += atomic_read(&dev->vbl_received);
+ vblwait->request.sequence += seq;
vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
}
flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
+ if ((flags & _DRM_VBLANK_NEXTONMISS) &&
+ (seq - vblwait->request.sequence) <= (1<<23)) {
+ vblwait->request.sequence = seq + 1;
+ }
+
if (flags & _DRM_VBLANK_SIGNAL) {
#if 0 /* disabled */
+ if (dev->vblank_suspend[crtc])
+ return (EBUSY);
+
drm_vbl_sig_t *vbl_sig = malloc(sizeof(drm_vbl_sig_t), M_DRM,
M_NOWAIT | M_ZERO);
if (vbl_sig == NULL)
@@ -294,36 +524,56 @@ drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv)
vbl_sig->pid = DRM_CURRENTPID;
vblwait->reply.sequence = atomic_read(&dev->vbl_received);
+
- DRM_SPINLOCK(&dev->irq_lock);
+ DRM_SPINLOCK(&dev->vbl_lock);
TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
- DRM_SPINUNLOCK(&dev->irq_lock);
+ DRM_SPINUNLOCK(&dev->vbl_lock);
ret = 0;
#endif
ret = EINVAL;
} else {
- DRM_LOCK();
- /* shared code returns -errno */
- ret = -dev->driver.vblank_wait(dev,
- &vblwait->request.sequence);
- DRM_UNLOCK();
-
- microtime(&now);
- vblwait->reply.tval_sec = now.tv_sec;
- vblwait->reply.tval_usec = now.tv_usec;
+ if (!dev->vblank_suspend[crtc]) {
+ unsigned long cur_vblank;
+
+ ret = drm_vblank_get(dev, crtc);
+ if (ret)
+ return ret;
+ while (ret == 0) {
+ DRM_SPINLOCK(&dev->vbl_lock);
+ if (((cur_vblank = drm_vblank_count(dev, crtc))
+ - vblwait->request.sequence) <= (1 << 23)) {
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+ break;
+ }
+ ret = msleep(&dev->vbl_queue[crtc],
+ &dev->vbl_lock, PZERO | PCATCH,
+ "drmvblq", 3 * DRM_HZ);
+ DRM_SPINUNLOCK(&dev->vbl_lock);
+ }
+ }
+ drm_vblank_put(dev, crtc);
+
+ if (ret != EINTR) {
+ struct timeval now;
+ microtime(&now);
+ vblwait->reply.tval_sec = now.tv_sec;
+ vblwait->reply.tval_usec = now.tv_usec;
+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
+ }
}
- return ret;
+ return (ret);
}
void
-drm_vbl_send_signals(drm_device_t *dev)
+drm_vbl_send_signals(drm_device_t *dev, int crtc)
{
}
#if 0 /* disabled */
void
-drm_vbl_send_signals( drm_device_t *dev )
+drm_vbl_send_signals(drm_device_t *dev, int crtc)
{
drm_vbl_sig_t *vbl_sig;
unsigned int vbl_seq = atomic_read( &dev->vbl_received );
@@ -347,6 +597,14 @@ drm_vbl_send_signals( drm_device_t *dev )
#endif
void
+drm_handle_vblank(struct drm_device *dev, int crtc)
+{
+ drm_update_vblank_count(dev, crtc);
+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
+ drm_vbl_send_signals(dev, crtc);
+}
+
+void
#ifdef __OpenBSD__
drm_locked_task(void *context, void *pending)
#else
diff --git a/sys/dev/pci/drm/drm_pciids.h b/sys/dev/pci/drm/drm_pciids.h
index 39927eb1b60..fa3fdbd99ba 100644
--- a/sys/dev/pci/drm/drm_pciids.h
+++ b/sys/dev/pci/drm/drm_pciids.h
@@ -83,6 +83,7 @@
{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"}, \
@@ -102,20 +103,18 @@
{0x1002, 0x5653, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon Mobility X700 M26"}, \
{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_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI RS480 XPRESS 200G"}, \
- {0x1002, 0x5955, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon XPRESS 200M 5955"}, \
- {0x1002, 0x5974, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon RS482 XPRESS 200"}, \
- {0x1002, 0x5975, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon RS485 XPRESS 1100 IGP"}, \
+ {0x1002, 0x5954, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|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"}, \
{0x1002, 0x5960, CHIP_RV280, "ATI Radeon RV280 9250"}, \
{0x1002, 0x5961, CHIP_RV280, "ATI Radeon RV280 9200"}, \
{0x1002, 0x5962, CHIP_RV280, "ATI Radeon RV280 9200"}, \
{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, 0x5a41, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon RS400 XPRESS 200"}, \
- {0x1002, 0x5a42, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART, "ATI Radeon RS400 XPRESS 200M"}, \
- {0x1002, 0x5a61, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|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, 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, 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"}, \
@@ -139,8 +138,105 @@
{0x1002, 0x5e4c, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700 SE"}, \
{0x1002, 0x5e4d, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700"}, \
{0x1002, 0x5e4f, CHIP_RV410|RADEON_NEW_MEMMAP, "ATI Radeon RV410 X700 SE"}, \
+ {0x1002, 0x7100, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \
+ {0x1002, 0x7101, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1800 XT"}, \
+ {0x1002, 0x7102, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1800"}, \
+ {0x1002, 0x7103, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V7200"}, \
+ {0x1002, 0x7104, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V7200"}, \
+ {0x1002, 0x7105, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V5300"}, \
+ {0x1002, 0x7106, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V7100"}, \
+ {0x1002, 0x7108, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \
+ {0x1002, 0x7109, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \
+ {0x1002, 0x710A, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \
+ {0x1002, 0x710B, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \
+ {0x1002, 0x710C, CHIP_R520|RADEON_NEW_MEMMAP, "ATI Radeon X1800"}, \
+ {0x1002, 0x710E, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V7300"}, \
+ {0x1002, 0x710F, CHIP_R520|RADEON_NEW_MEMMAP, "ATI FireGL V7350"}, \
+ {0x1002, 0x7140, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \
+ {0x1002, 0x7141, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI RV505"}, \
+ {0x1002, 0x7142, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \
+ {0x1002, 0x7143, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550"}, \
+ {0x1002, 0x7144, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI M54-GL"}, \
+ {0x1002, 0x7145, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1400"}, \
+ {0x1002, 0x7146, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \
+ {0x1002, 0x7147, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550 64-bit"}, \
+ {0x1002, 0x7149, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \
+ {0x1002, 0x714A, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \
+ {0x1002, 0x714B, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \
+ {0x1002, 0x714C, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1300"}, \
+ {0x1002, 0x714D, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \
+ {0x1002, 0x714E, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \
+ {0x1002, 0x714F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI RV505"}, \
+ {0x1002, 0x7151, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI RV505"}, \
+ {0x1002, 0x7152, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI FireGL V3300"}, \
+ {0x1002, 0x7153, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI FireGL V3350"}, \
+ {0x1002, 0x715E, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \
+ {0x1002, 0x715F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550 64-bit"}, \
+ {0x1002, 0x7180, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \
+ {0x1002, 0x7181, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \
+ {0x1002, 0x7183, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \
+ {0x1002, 0x7186, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1450"}, \
+ {0x1002, 0x7187, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300/X1550"}, \
+ {0x1002, 0x7188, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X2300"}, \
+ {0x1002, 0x718A, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X2300"}, \
+ {0x1002, 0x718B, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1350"}, \
+ {0x1002, 0x718C, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1350"}, \
+ {0x1002, 0x718D, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1450"}, \
+ {0x1002, 0x718F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1300"}, \
+ {0x1002, 0x7193, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550"}, \
+ {0x1002, 0x7196, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1350"}, \
+ {0x1002, 0x719B, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI FireMV 2250"}, \
+ {0x1002, 0x719F, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X1550 64-bit"}, \
+ {0x1002, 0x71C0, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \
+ {0x1002, 0x71C1, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \
+ {0x1002, 0x71C2, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \
+ {0x1002, 0x71C3, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \
+ {0x1002, 0x71C4, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5200"}, \
+ {0x1002, 0x71C5, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1600"}, \
+ {0x1002, 0x71C6, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \
+ {0x1002, 0x71C7, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \
+ {0x1002, 0x71CD, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1600"}, \
+ {0x1002, 0x71CE, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI Radeon X1300 XT/X1600 Pro"}, \
+ {0x1002, 0x71D2, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI FireGL V3400"}, \
+ {0x1002, 0x71D4, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility FireGL V5250"}, \
+ {0x1002, 0x71D5, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1700"}, \
+ {0x1002, 0x71D6, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1700 XT"}, \
+ {0x1002, 0x71DA, CHIP_RV530|RADEON_NEW_MEMMAP, "ATI FireGL V5200"}, \
+ {0x1002, 0x71DE, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1700"}, \
+ {0x1002, 0x7200, CHIP_RV515|RADEON_NEW_MEMMAP, "ATI Radeon X2300HD"}, \
+ {0x1002, 0x7210, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2300"}, \
+ {0x1002, 0x7211, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon HD 2300"}, \
+ {0x1002, 0x7240, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1950"}, \
+ {0x1002, 0x7243, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x7244, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1950"}, \
+ {0x1002, 0x7245, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x7246, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x7247, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x7248, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x7249, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x724A, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x724B, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x724C, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x724D, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x724E, CHIP_R580|RADEON_NEW_MEMMAP, "ATI AMD Stream Processor"}, \
+ {0x1002, 0x724F, CHIP_R580|RADEON_NEW_MEMMAP, "ATI Radeon X1900"}, \
+ {0x1002, 0x7280, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI Radeon X1950"}, \
+ {0x1002, 0x7281, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \
+ {0x1002, 0x7283, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \
+ {0x1002, 0x7284, CHIP_R580|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Mobility Radeon X1900"}, \
+ {0x1002, 0x7287, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \
+ {0x1002, 0x7288, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI Radeon X1950 GT"}, \
+ {0x1002, 0x7289, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI RV570"}, \
+ {0x1002, 0x728B, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI RV570"}, \
+ {0x1002, 0x728C, CHIP_RV570|RADEON_NEW_MEMMAP, "ATI ATI FireGL V7400"}, \
+ {0x1002, 0x7290, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \
+ {0x1002, 0x7291, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \
+ {0x1002, 0x7293, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI Radeon X1650"}, \
+ {0x1002, 0x7297, CHIP_RV560|RADEON_NEW_MEMMAP, "ATI RV560"}, \
{0x1002, 0x7834, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP, "ATI Radeon RS350 9000/9100 IGP"}, \
{0x1002, 0x7835, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP, "ATI Radeon RS350 Mobility IGP"}, \
+ {0x1002, 0x791e, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1250 IGP"}, \
+ {0x1002, 0x791f, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART, "ATI Radeon RS690 X1270 IGP"}, \
{0, 0, 0, NULL}
#define r128_PCI_IDS \
@@ -242,6 +338,7 @@
{0x1106, 0x3343, 0, "VIA P4M890"}, \
{0x1106, 0x3230, VIA_DX9_0, "VIA K8M890"}, \
{0x1106, 0x3157, VIA_PRO_GROUP_A, "VIA CX700"}, \
+ {0x1106, 0x3371, VIA_DX9_0, "VIA P4M900 / VN896"}, \
{0, 0, 0, NULL}
#define i810_PCI_IDS \
@@ -297,6 +394,7 @@
{0x8086, 0x3582, CHIP_I8XX, "Intel i852GM/i855GM GMCH"}, \
{0x8086, 0x2572, CHIP_I8XX, "Intel i865G GMCH"}, \
{0x8086, 0x2582, CHIP_I9XX|CHIP_I915, "Intel i915G"}, \
+ {0x8086, 0x258a, CHIP_I9XX|CHIP_I915, "Intel E7221 (i915)"}, \
{0x8086, 0x2592, CHIP_I9XX|CHIP_I915, "Intel i915GM"}, \
{0x8086, 0x2772, CHIP_I9XX|CHIP_I915, "Intel i945G"}, \
{0x8086, 0x27A2, CHIP_I9XX|CHIP_I915, "Intel i945GM"}, \
@@ -310,6 +408,7 @@
{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"}, \
{0, 0, 0, NULL}
#define imagine_PCI_IDS \
diff --git a/sys/dev/pci/drm/drm_vm.c b/sys/dev/pci/drm/drm_vm.c
index 09a4879a647..427a549fb5b 100644
--- a/sys/dev/pci/drm/drm_vm.c
+++ b/sys/dev/pci/drm/drm_vm.c
@@ -74,12 +74,11 @@ drm_mmap(dev_t kdev, off_t offset, int prot)
unsigned long page = offset >> PAGE_SHIFT;
unsigned long phys = dma->pagelist[page];
+ DRM_SPINUNLOCK(&dev->dma_lock);
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
*paddr = phys;
- DRM_SPINUNLOCK(&dev->dma_lock);
return 0;
#else
- DRM_SPINUNLOCK(&dev->dma_lock);
return atop(phys);
#endif
} else {
diff --git a/sys/dev/pci/drm/i915_dma.c b/sys/dev/pci/drm/i915_dma.c
index fa5e9458545..60b405d471a 100644
--- a/sys/dev/pci/drm/i915_dma.c
+++ b/sys/dev/pci/drm/i915_dma.c
@@ -51,8 +51,6 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
if (ring->space >= n)
return 0;
- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
-
if (ring->head != last_head)
i = 0;
@@ -73,9 +71,6 @@ void i915_kernel_lost_context(struct drm_device * dev)
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->Size;
-
- if (ring->head == ring->tail)
- dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
}
static int i915_dma_cleanup(struct drm_device * dev)
@@ -111,10 +106,75 @@ static int i915_dma_cleanup(struct drm_device * dev)
return 0;
}
-static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
+#if defined(I915_HAVE_BUFFER)
+#define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16)
+#define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff)
+#define DRI2_SAREA_BLOCK_NEXT(p) \
+ ((void *) ((unsigned char *) (p) + \
+ DRI2_SAREA_BLOCK_SIZE(*(unsigned int *) p)))
+
+#define DRI2_SAREA_BLOCK_END 0x0000
+#define DRI2_SAREA_BLOCK_LOCK 0x0001
+#define DRI2_SAREA_BLOCK_EVENT_BUFFER 0x0002
+
+static int
+setup_dri2_sarea(struct drm_device * dev,
+ struct drm_file *file_priv,
+ drm_i915_init_t * init)
{
drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret;
+ unsigned int *p, *end, *next;
+
+ mutex_lock(&dev->struct_mutex);
+ dev_priv->sarea_bo =
+ drm_lookup_buffer_object(file_priv,
+ init->sarea_handle, 1);
+ mutex_unlock(&dev->struct_mutex);
+
+ if (!dev_priv->sarea_bo) {
+ DRM_ERROR("did not find sarea bo\n");
+ return -EINVAL;
+ }
+
+ ret = drm_bo_kmap(dev_priv->sarea_bo, 0,
+ dev_priv->sarea_bo->num_pages,
+ &dev_priv->sarea_kmap);
+ if (ret) {
+ DRM_ERROR("could not map sarea bo\n");
+ return ret;
+ }
+
+ p = dev_priv->sarea_kmap.virtual;
+ end = (void *) p + (dev_priv->sarea_bo->num_pages << PAGE_SHIFT);
+ while (p < end && DRI2_SAREA_BLOCK_TYPE(*p) != DRI2_SAREA_BLOCK_END) {
+ switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
+ case DRI2_SAREA_BLOCK_LOCK:
+ dev->lock.hw_lock = (void *) (p + 1);
+ dev->sigdata.lock = dev->lock.hw_lock;
+ break;
+ }
+ next = DRI2_SAREA_BLOCK_NEXT(p);
+ if (next <= p || end < next) {
+ DRM_ERROR("malformed dri2 sarea: next is %p should be within %p-%p\n",
+ next, p, end);
+ return -EINVAL;
+ }
+ p = next;
+ }
+
+ return 0;
+}
+#endif
+static int i915_initialize(struct drm_device * dev,
+ struct drm_file *file_priv,
+ drm_i915_init_t * init)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+#if defined(I915_HAVE_BUFFER)
+ int ret;
+#endif
dev_priv->sarea = drm_getsarea(dev);
if (!dev_priv->sarea) {
DRM_ERROR("can not find sarea!\n");
@@ -122,7 +182,8 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
return -EINVAL;
}
- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
+ if (init->mmio_offset != 0)
+ dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
if (!dev_priv->mmio_map) {
i915_dma_cleanup(dev);
DRM_ERROR("can not find mmio map!\n");
@@ -133,8 +194,14 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS;
#endif
- dev_priv->sarea_priv = (drm_i915_sarea_t *)
- ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
+ if (init->sarea_priv_offset)
+ dev_priv->sarea_priv = (drm_i915_sarea_t *)
+ ((u8 *) dev_priv->sarea->handle +
+ init->sarea_priv_offset);
+ else {
+ /* No sarea_priv for you! */
+ dev_priv->sarea_priv = NULL;
+ }
dev_priv->ring.Start = init->ring_start;
dev_priv->ring.End = init->ring_end;
@@ -159,12 +226,16 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
dev_priv->cpp = init->cpp;
- dev_priv->sarea_priv->pf_current_page = 0;
+
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->pf_current_page = 0;
/* We are using separate values as placeholders for mechanisms for
* private backbuffer/depthbuffer usage.
*/
dev_priv->use_mi_batchbuffer_start = 0;
+ if (IS_I965G(dev)) /* 965 doesn't support older method */
+ dev_priv->use_mi_batchbuffer_start = 1;
/* Allow hardware batchbuffers unless told otherwise.
*/
@@ -175,7 +246,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
/* Program Hardware Status Page */
- if (!IS_G33(dev)) {
+ if (!I915_NEED_GFX_HWS(dev)) {
dev_priv->status_page_dmah =
drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
@@ -193,8 +264,19 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
}
DRM_DEBUG("Enabled hardware status page\n");
#ifdef I915_HAVE_BUFFER
- DRM_SPININIT(&dev_priv->cmdbuf_mutex, "915_cmdbuf");
+ mutex_init(&dev_priv->cmdbuf_mutex);
+#endif
+#if defined(I915_HAVE_BUFFER)
+ if (init->func == I915_INIT_DMA2) {
+ ret = setup_dri2_sarea(dev, file_priv, init);
+ if (ret) {
+ i915_dma_cleanup(dev);
+ DRM_ERROR("could not set up dri2 sarea\n");
+ return ret;
+ }
+ }
#endif
+
return 0;
}
@@ -202,7 +284,7 @@ static int i915_dma_resume(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (!dev_priv->sarea) {
DRM_ERROR("can not find sarea!\n");
@@ -244,7 +326,8 @@ static int i915_dma_init(struct drm_device *dev, void *data,
switch (init->func) {
case I915_INIT_DMA:
- retcode = i915_initialize(dev, init);
+ case I915_INIT_DMA2:
+ retcode = i915_initialize(dev, file_priv, init);
break;
case I915_CLEANUP_DMA:
retcode = i915_dma_cleanup(dev);
@@ -336,7 +419,7 @@ static int validate_cmd(int cmd)
return ret;
}
-static int i915_emit_cmds(struct drm_device * dev, int __user * buffer,
+static int i915_emit_cmds(struct drm_device *dev, int __user *buffer,
int dwords)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -416,7 +499,7 @@ static int i915_emit_box(struct drm_device * dev,
}
/* XXX: Emitting the counter should really be moved to part of the IRQ
- * emit. For now, do it in both places:
+ * emit. For now, do it in both places:
*/
void i915_emit_breadcrumb(struct drm_device *dev)
@@ -429,7 +512,8 @@ void i915_emit_breadcrumb(struct drm_device *dev)
DRM_DEBUG("Breadcrumb counter wrapped around\n");
}
- dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
BEGIN_LP_RING(4);
OUT_RING(CMD_STORE_DWORD_IDX);
@@ -492,15 +576,16 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
return ret;
}
- i915_emit_breadcrumb( dev );
+ i915_emit_breadcrumb(dev);
#ifdef I915_HAVE_FENCE
- drm_fence_flush_old(dev, 0, dev_priv->counter);
+ if (unlikely((dev_priv->counter & 0xFF) == 0))
+ drm_fence_flush_old(dev, 0, dev_priv->counter);
#endif
return 0;
}
-static int i915_dispatch_batchbuffer(struct drm_device * dev,
- drm_i915_batchbuffer_t * batch)
+int i915_dispatch_batchbuffer(struct drm_device * dev,
+ drm_i915_batchbuffer_t * batch)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_clip_rect __user *boxes = batch->cliprects;
@@ -546,9 +631,10 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
}
}
- i915_emit_breadcrumb( dev );
+ i915_emit_breadcrumb(dev);
#ifdef I915_HAVE_FENCE
- drm_fence_flush_old(dev, 0, dev_priv->counter);
+ if (unlikely((dev_priv->counter & 0xFF) == 0))
+ drm_fence_flush_old(dev, 0, dev_priv->counter);
#endif
return 0;
}
@@ -610,8 +696,7 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
drm_i915_private_t *dev_priv = dev->dev_private;
int i;
- DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n",
- __FUNCTION__,
+ DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
planes, dev_priv->sarea_priv->pf_current_page);
i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
@@ -622,12 +707,12 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
i915_emit_breadcrumb(dev);
#ifdef I915_HAVE_FENCE
- if (!sync)
+ if (unlikely(!sync && ((dev_priv->counter & 0xFF) == 0)))
drm_fence_flush_old(dev, 0, dev_priv->counter);
#endif
}
-static int i915_quiescent(struct drm_device * dev)
+int i915_quiescent(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -706,388 +791,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
return 0;
}
-#ifdef I915_HAVE_BUFFER
-struct i915_relocatee_info {
- struct drm_buffer_object *buf;
- unsigned long offset;
- u32 *data_page;
- unsigned page_offset;
- struct drm_bo_kmap_obj kmap;
- int is_iomem;
-};
-
-static void i915_dereference_buffers_locked(struct drm_buffer_object **buffers,
- unsigned num_buffers)
-{
- while (num_buffers--)
- drm_bo_usage_deref_locked(&buffers[num_buffers]);
-}
-
-int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
- struct drm_buffer_object **buffers,
- struct i915_relocatee_info *relocatee,
- uint32_t *reloc)
-{
- unsigned index;
- unsigned long new_cmd_offset;
- u32 val;
- int ret;
-
- if (reloc[2] >= num_buffers) {
- DRM_ERROR("Illegal relocation buffer %08X\n", reloc[2]);
- return -EINVAL;
- }
-
- new_cmd_offset = reloc[0];
- if (!relocatee->data_page ||
- !drm_bo_same_page(relocatee->offset, new_cmd_offset)) {
- drm_bo_kunmap(&relocatee->kmap);
- relocatee->offset = new_cmd_offset;
- ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT,
- 1, &relocatee->kmap);
- if (ret) {
- DRM_ERROR("Could not map command buffer to apply relocs\n %08lx", new_cmd_offset);
- return ret;
- }
-
- relocatee->data_page = drm_bmo_virtual(&relocatee->kmap,
- &relocatee->is_iomem);
- relocatee->page_offset = (relocatee->offset & PAGE_MASK);
- }
-
- val = buffers[reloc[2]]->offset;
- index = (reloc[0] - relocatee->page_offset) >> 2;
-
- /* add in validate */
- val = val + reloc[1];
-
- relocatee->data_page[index] = val;
- return 0;
-}
-
-int i915_process_relocs(struct drm_file *file_priv,
- uint32_t buf_handle,
- uint32_t *reloc_buf_handle,
- struct i915_relocatee_info *relocatee,
- struct drm_buffer_object **buffers,
- uint32_t num_buffers)
-{
- struct drm_device *dev = file_priv->head->dev;
- struct drm_buffer_object *reloc_list_object;
- uint32_t cur_handle = *reloc_buf_handle;
- uint32_t *reloc_page;
- int ret, reloc_is_iomem, reloc_stride;
- uint32_t num_relocs, reloc_offset, reloc_end, reloc_page_offset, next_offset, cur_offset;
- struct drm_bo_kmap_obj reloc_kmap;
-
- memset(&reloc_kmap, 0, sizeof(reloc_kmap));
-
- mutex_lock(&dev->struct_mutex);
- reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1);
- mutex_unlock(&dev->struct_mutex);
- if (!reloc_list_object)
- return -EINVAL;
-
- ret = drm_bo_kmap(reloc_list_object, 0, 1, &reloc_kmap);
- if (ret) {
- DRM_ERROR("Could not map relocation buffer.\n");
- goto out;
- }
-
- reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem);
- num_relocs = reloc_page[0] & 0xffff;
-
- if ((reloc_page[0] >> 16) & 0xffff) {
- DRM_ERROR("Unsupported relocation type requested\n");
- goto out;
- }
-
- /* get next relocate buffer handle */
- *reloc_buf_handle = reloc_page[1];
- reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t); /* may be different for other types of relocs */
-
- DRM_DEBUG("num relocs is %d, next is %08X\n", num_relocs, reloc_page[1]);
-
- reloc_page_offset = 0;
- reloc_offset = I915_RELOC_HEADER * sizeof(uint32_t);
- reloc_end = reloc_offset + (num_relocs * reloc_stride);
-
- do {
- next_offset = drm_bo_offset_end(reloc_offset, reloc_end);
-
- do {
- cur_offset = ((reloc_offset + reloc_page_offset) & ~PAGE_MASK) / sizeof(uint32_t);
- ret = i915_apply_reloc(file_priv, num_buffers,
- buffers, relocatee, &reloc_page[cur_offset]);
- if (ret)
- goto out;
-
- reloc_offset += reloc_stride;
- } while (reloc_offset < next_offset);
-
- drm_bo_kunmap(&reloc_kmap);
-
- reloc_offset = next_offset;
- if (reloc_offset != reloc_end) {
- ret = drm_bo_kmap(reloc_list_object, reloc_offset >> PAGE_SHIFT, 1, &reloc_kmap);
- if (ret) {
- DRM_ERROR("Could not map relocation buffer.\n");
- goto out;
- }
-
- reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem);
- reloc_page_offset = reloc_offset & ~PAGE_MASK;
- }
-
- } while (reloc_offset != reloc_end);
-out:
- drm_bo_kunmap(&relocatee->kmap);
- relocatee->data_page = NULL;
-
- drm_bo_kunmap(&reloc_kmap);
-
- mutex_lock(&dev->struct_mutex);
- drm_bo_usage_deref_locked(&reloc_list_object);
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
-
-static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
- drm_handle_t buf_reloc_handle,
- struct drm_buffer_object **buffers,
- uint32_t buf_count)
-{
- struct drm_device *dev = file_priv->head->dev;
- struct i915_relocatee_info relocatee;
- int ret = 0;
-
- memset(&relocatee, 0, sizeof(relocatee));
-
- mutex_lock(&dev->struct_mutex);
- relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1);
- mutex_unlock(&dev->struct_mutex);
- if (!relocatee.buf) {
- DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle);
- ret = -EINVAL;
- goto out_err;
- }
-
- while (buf_reloc_handle) {
- ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count);
- if (ret) {
- DRM_ERROR("process relocs failed\n");
- break;
- }
- }
-
- mutex_lock(&dev->struct_mutex);
- drm_bo_usage_deref_locked(&relocatee.buf);
- mutex_unlock(&dev->struct_mutex);
-
-out_err:
- return ret;
-}
-
-/*
- * Validate, add fence and relocate a block of bos from a userspace list
- */
-int i915_validate_buffer_list(struct drm_file *file_priv,
- unsigned int fence_class, uint64_t data,
- struct drm_buffer_object **buffers,
- uint32_t *num_buffers)
-{
- struct drm_i915_op_arg arg;
- struct drm_bo_op_req *req = &arg.d.req;
- struct drm_bo_arg_rep rep;
- unsigned long next = 0;
- int ret = 0;
- unsigned buf_count = 0;
- struct drm_device *dev = file_priv->head->dev;
- uint32_t buf_reloc_handle, buf_handle;
-
-
- do {
- if (buf_count >= *num_buffers) {
- DRM_ERROR("Buffer count exceeded %d\n.", *num_buffers);
- ret = -EINVAL;
- goto out_err;
- }
-
- buffers[buf_count] = NULL;
-
- if (copy_from_user(&arg, (void __user *)(unsigned)data, sizeof(arg))) {
- ret = -EFAULT;
- goto out_err;
- }
-
- if (arg.handled) {
- data = arg.next;
- mutex_lock(&dev->struct_mutex);
- buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1);
- mutex_unlock(&dev->struct_mutex);
- buf_count++;
- continue;
- }
-
- rep.ret = 0;
- if (req->op != drm_bo_validate) {
- DRM_ERROR
- ("Buffer object operation wasn't \"validate\".\n");
- rep.ret = -EINVAL;
- goto out_err;
- }
-
- buf_handle = req->bo_req.handle;
- buf_reloc_handle = arg.reloc_handle;
-
- if (buf_reloc_handle) {
- ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count);
- if (ret)
- goto out_err;
- DRM_MEMORYBARRIER();
- }
-
- rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
- req->bo_req.fence_class,
- req->bo_req.flags,
- req->bo_req.mask,
- req->bo_req.hint,
- 0,
- &rep.bo_info,
- &buffers[buf_count]);
-
- if (rep.ret) {
- DRM_ERROR("error on handle validate %d\n", rep.ret);
- goto out_err;
- }
-
-
- next = arg.next;
- arg.handled = 1;
- arg.d.rep = rep;
-
- if (copy_to_user((void __user *)(unsigned)data, &arg, sizeof(arg)))
- return -EFAULT;
-
- data = next;
- buf_count++;
-
- } while (next != 0);
- *num_buffers = buf_count;
- return 0;
-out_err:
- mutex_lock(&dev->struct_mutex);
- i915_dereference_buffers_locked(buffers, buf_count);
- mutex_unlock(&dev->struct_mutex);
- *num_buffers = 0;
- return (ret) ? ret : rep.ret;
-}
-
-static int i915_execbuffer(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
- dev_priv->sarea_priv;
- struct drm_i915_execbuffer *exec_buf = data;
- struct _drm_i915_batchbuffer *batch = &exec_buf->batch;
- struct drm_fence_arg *fence_arg = &exec_buf->fence_arg;
- int num_buffers;
- int ret;
- struct drm_buffer_object **buffers;
- struct drm_fence_object *fence;
-
- if (!dev_priv->allow_batchbuffer) {
- DRM_ERROR("Batchbuffer ioctl disabled\n");
- return -EINVAL;
- }
-
-
- if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
- batch->num_cliprects *
- sizeof(struct drm_clip_rect)))
- return -EFAULT;
-
- if (exec_buf->num_buffers > dev_priv->max_validate_buffers)
- return -EINVAL;
-
-
- ret = drm_bo_read_lock(&dev->bm.bm_lock);
- if (ret)
- return ret;
-
- /*
- * The cmdbuf_mutex makes sure the validate-submit-fence
- * operation is atomic.
- */
-
- ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
- if (ret) {
- drm_bo_read_unlock(&dev->bm.bm_lock);
- return -EAGAIN;
- }
-
- num_buffers = exec_buf->num_buffers;
-
- buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER);
- if (!buffers) {
- drm_bo_read_unlock(&dev->bm.bm_lock);
- mutex_unlock(&dev_priv->cmdbuf_mutex);
- return -ENOMEM;
- }
-
- /* validate buffer list + fixup relocations */
- ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list,
- buffers, &num_buffers);
- if (ret)
- goto out_free;
-
- /* make sure all previous memory operations have passed */
- DRM_MEMORYBARRIER();
- drm_agp_chipset_flush(dev);
-
- /* submit buffer */
- batch->start = buffers[num_buffers-1]->offset;
-
- DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n",
- batch->start, batch->used, batch->num_cliprects);
-
- ret = i915_dispatch_batchbuffer(dev, batch);
- if (ret)
- goto out_err0;
-
- sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
-
- /* fence */
- ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence);
- if (ret)
- goto out_err0;
-
- if (!(fence_arg->flags & DRM_FENCE_FLAG_NO_USER)) {
- ret = drm_fence_add_user_object(file_priv, fence, fence_arg->flags & DRM_FENCE_FLAG_SHAREABLE);
- if (!ret) {
- fence_arg->handle = fence->base.hash.key;
- fence_arg->fence_class = fence->fence_class;
- fence_arg->type = fence->type;
- fence_arg->signaled = fence->signaled;
- }
- }
- drm_fence_usage_deref_unlocked(&fence);
-out_err0:
-
- /* handle errors */
- mutex_lock(&dev->struct_mutex);
- i915_dereference_buffers_locked(buffers, num_buffers);
- mutex_unlock(&dev->struct_mutex);
-
-out_free:
- drm_free(buffers, (exec_buf->num_buffers * sizeof(struct drm_buffer_object *)), DRM_MEM_DRIVER);
-
- mutex_unlock(&dev_priv->cmdbuf_mutex);
- drm_bo_read_unlock(&dev->bm.bm_lock);
- return ret;
-}
+#if defined(DRM_DEBUG_CODE)
+#define DRM_DEBUG_RELOCATION (drm_debug != 0)
+#else
+#define DRM_DEBUG_RELOCATION 0
#endif
static int i915_do_cleanup_pageflip(struct drm_device * dev)
@@ -1095,13 +802,13 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev)
drm_i915_private_t *dev_priv = dev->dev_private;
int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
for (i = 0, planes = 0; i < 2; i++)
if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
dev_priv->sarea_priv->pf_current_page =
(dev_priv->sarea_priv->pf_current_page &
- ~(0x3 << (2 * i))) | (num_pages - 1) << (2 * i);
+ ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i));
planes |= 1 << i;
}
@@ -1116,7 +823,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *f
{
drm_i915_flip_t *param = data;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1141,7 +848,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1155,6 +862,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_LAST_DISPATCH:
value = READ_BREADCRUMB(dev_priv);
break;
+ case I915_PARAM_CHIPSET_ID:
+ value = dev->pci_device;
+ break;
default:
DRM_ERROR("Unknown parameter %d\n", param->param);
return -EINVAL;
@@ -1175,13 +885,14 @@ static int i915_setparam(struct drm_device *dev, void *data,
drm_i915_setparam_t *param = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
switch (param->param) {
case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
- dev_priv->use_mi_batchbuffer_start = param->value;
+ if (!IS_I965G(dev))
+ dev_priv->use_mi_batchbuffer_start = param->value;
break;
case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
dev_priv->tex_lru_log_granularity = param->value;
@@ -1218,7 +929,7 @@ static int i915_mmio(struct drm_device *dev, void *data,
int i;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1229,27 +940,27 @@ static int i915_mmio(struct drm_device *dev, void *data,
base = (u8 *) dev_priv->mmio_map->handle + e->offset;
switch (mmio->read_write) {
- case I915_MMIO_READ:
- if (!(e->flag & I915_MMIO_MAY_READ))
- return -EINVAL;
- for (i = 0; i < e->size / 4; i++)
- buf[i] = I915_READ(e->offset + i * 4);
- if (DRM_COPY_TO_USER(mmio->data, buf, e->size)) {
- DRM_ERROR("DRM_COPY_TO_USER failed\n");
- return -EFAULT;
- }
- break;
-
- case I915_MMIO_WRITE:
- if (!(e->flag & I915_MMIO_MAY_WRITE))
- return -EINVAL;
- if(DRM_COPY_FROM_USER(buf, mmio->data, e->size)) {
- DRM_ERROR("DRM_COPY_TO_USER failed\n");
- return -EFAULT;
- }
- for (i = 0; i < e->size / 4; i++)
- I915_WRITE(e->offset + i * 4, buf[i]);
- break;
+ case I915_MMIO_READ:
+ if (!(e->flag & I915_MMIO_MAY_READ))
+ return -EINVAL;
+ for (i = 0; i < e->size / 4; i++)
+ buf[i] = I915_READ(e->offset + i * 4);
+ if (DRM_COPY_TO_USER(mmio->data, buf, e->size)) {
+ DRM_ERROR("DRM_COPY_TO_USER failed\n");
+ return -EFAULT;
+ }
+ break;
+
+ case I915_MMIO_WRITE:
+ if (!(e->flag & I915_MMIO_MAY_WRITE))
+ return -EINVAL;
+ if (DRM_COPY_FROM_USER(buf, mmio->data, e->size)) {
+ DRM_ERROR("DRM_COPY_TO_USER failed\n");
+ return -EFAULT;
+ }
+ for (i = 0; i < e->size / 4; i++)
+ I915_WRITE(e->offset + i * 4, buf[i]);
+ break;
}
return 0;
}
@@ -1260,8 +971,11 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_hws_addr_t *hws = data;
+ if (!I915_NEED_GFX_HWS(dev))
+ return -EINVAL;
+
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
@@ -1317,12 +1031,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
base = drm_get_resource_start(dev, mmio_bar);
size = drm_get_resource_len(dev, mmio_bar);
- ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL,
- &dev_priv->mmio_map);
+ ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
+ _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map);
+#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
intel_init_chipset_flush_compat(dev);
#endif
+#endif
+
return ret;
}
@@ -1335,9 +1052,11 @@ int i915_driver_unload(struct drm_device *dev)
drm_free(dev->dev_private, sizeof(drm_i915_private_t),
DRM_MEM_DRIVER);
+#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
intel_fini_chipset_flush_compat(dev);
#endif
+#endif
return 0;
}
@@ -1345,11 +1064,36 @@ void i915_driver_lastclose(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
+ /* agp off can use this to get called before dev_priv */
+ if (!dev_priv)
+ return;
+
+#ifdef I915_HAVE_BUFFER
+ if (dev_priv->val_bufs) {
+ vfree(dev_priv->val_bufs);
+ dev_priv->val_bufs = NULL;
+ }
+#endif
+
if (drm_getsarea(dev) && dev_priv->sarea_priv)
i915_do_cleanup_pageflip(dev);
if (dev_priv->agp_heap)
i915_mem_takedown(&(dev_priv->agp_heap));
+#if defined(I915_HAVE_BUFFER)
+ if (dev_priv->sarea_kmap.virtual) {
+ drm_bo_kunmap(&dev_priv->sarea_kmap);
+ dev_priv->sarea_kmap.virtual = NULL;
+ dev->lock.hw_lock = NULL;
+ dev->sigdata.lock = NULL;
+ }
+ if (dev_priv->sarea_bo) {
+ mutex_lock(&dev->struct_mutex);
+ drm_bo_usage_deref_locked(&dev_priv->sarea_bo);
+ mutex_unlock(&dev->struct_mutex);
+ dev_priv->sarea_bo = NULL;
+ }
+#endif
i915_dma_cleanup(dev);
}
@@ -1404,8 +1148,7 @@ int i915_driver_device_is_agp(struct drm_device * dev)
int i915_driver_firstopen(struct drm_device *dev)
{
#ifdef I915_HAVE_BUFFER
- if (IS_I9XX(dev))
- drm_bo_driver_init(dev);
+ drm_bo_driver_init(dev);
#endif
return 0;
}
diff --git a/sys/dev/pci/drm/i915_drm.h b/sys/dev/pci/drm/i915_drm.h
index 56977ff318d..97e77428692 100644
--- a/sys/dev/pci/drm/i915_drm.h
+++ b/sys/dev/pci/drm/i915_drm.h
@@ -43,7 +43,12 @@ typedef struct _drm_i915_init {
enum {
I915_INIT_DMA = 0x01,
I915_CLEANUP_DMA = 0x02,
- I915_RESUME_DMA = 0x03
+ I915_RESUME_DMA = 0x03,
+
+ /* Since this struct isn't versioned, just used a new
+ * 'func' code to indicate the presence of dri2 sarea
+ * info. */
+ I915_INIT_DMA2 = 0x04
} func;
unsigned int mmio_offset;
int sarea_priv_offset;
@@ -61,9 +66,10 @@ typedef struct _drm_i915_init {
unsigned int depth_pitch;
unsigned int cpp;
unsigned int chipset;
+ unsigned int sarea_handle;
} drm_i915_init_t;
-typedef struct _drm_i915_sarea {
+typedef struct drm_i915_sarea {
struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
int last_upload; /* last time texture was uploaded */
int last_enqueue; /* last time a buffer was enqueued */
@@ -119,6 +125,15 @@ typedef struct _drm_i915_sarea {
int third_offset;
int third_size;
unsigned int third_tiled;
+
+ /* buffer object handles for the static buffers. May change
+ * over the lifetime of the client, though it doesn't in our current
+ * implementation.
+ */
+ unsigned int front_bo_handle;
+ unsigned int back_bo_handle;
+ unsigned int third_bo_handle;
+ unsigned int depth_bo_handle;
} drm_i915_sarea_t;
/* Driver specific fence types and classes.
@@ -178,6 +193,7 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
+#define DRM_IOCTL_I915_MMIO DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_MMIO, drm_i915_mmio)
#define DRM_IOCTL_I915_EXECBUFFER DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_EXECBUFFER, struct drm_i915_execbuffer)
/* Asynchronous page flipping:
@@ -195,7 +211,7 @@ typedef struct drm_i915_flip {
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
*/
-typedef struct _drm_i915_batchbuffer {
+typedef struct drm_i915_batchbuffer {
int start; /* agp offset */
int used; /* nr bytes in use */
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
@@ -231,6 +247,7 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_IRQ_ACTIVE 1
#define I915_PARAM_ALLOW_BATCHBUFFER 2
#define I915_PARAM_LAST_DISPATCH 3
+#define I915_PARAM_CHIPSET_ID 4
typedef struct drm_i915_getparam {
int param;
@@ -274,7 +291,7 @@ typedef struct drm_i915_mem_init_heap {
* rotate):
*/
typedef struct drm_i915_mem_destroy_heap {
- int region;
+ int region;
} drm_i915_mem_destroy_heap_t;
/* Allow X server to configure which pipes to monitor for vblank signals
@@ -314,7 +331,7 @@ typedef struct drm_i915_mmio_entry {
unsigned int flag;
unsigned int offset;
unsigned int size;
-}drm_i915_mmio_entry_t;
+} drm_i915_mmio_entry_t;
typedef struct drm_i915_mmio {
unsigned int read_write:1;
@@ -328,9 +345,9 @@ typedef struct drm_i915_hws_addr {
/*
* Relocation header is 4 uint32_ts
- * 0 - (16-bit relocation type << 16)| 16 bit reloc count
- * 1 - buffer handle for another list of relocs
- * 2-3 - spare.
+ * 0 - 32 bit reloc count
+ * 1 - 32-bit relocation type
+ * 2-3 - 64-bit user buffer handle ptr for another list of relocs.
*/
#define I915_RELOC_HEADER 4
@@ -338,16 +355,31 @@ typedef struct drm_i915_hws_addr {
* type 0 relocation has 4-uint32_t stride
* 0 - offset into buffer
* 1 - delta to add in
- * 2 - index into buffer list
+ * 2 - buffer handle
* 3 - reserved (for optimisations later).
*/
+/*
+ * type 1 relocation has 4-uint32_t stride.
+ * Hangs off the first item in the op list.
+ * Performed after all valiations are done.
+ * Try to group relocs into the same relocatee together for
+ * performance reasons.
+ * 0 - offset into buffer
+ * 1 - delta to add in
+ * 2 - buffer index in op list.
+ * 3 - relocatee index in op list.
+ */
#define I915_RELOC_TYPE_0 0
#define I915_RELOC0_STRIDE 4
+#define I915_RELOC_TYPE_1 1
+#define I915_RELOC1_STRIDE 4
+
struct drm_i915_op_arg {
uint64_t next;
- uint32_t reloc_handle;
+ uint64_t reloc_ptr;
int handled;
+ unsigned int pad64;
union {
struct drm_bo_op_req req;
struct drm_bo_arg_rep rep;
@@ -358,7 +390,8 @@ struct drm_i915_op_arg {
struct drm_i915_execbuffer {
uint64_t ops_list;
uint32_t num_buffers;
- struct _drm_i915_batchbuffer batch;
+ struct drm_i915_batchbuffer batch;
+ drm_context_t context; /* for lockless use in the future */
struct drm_fence_arg fence_arg;
};
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c
index 6b9be6b8200..2943a860e6d 100644
--- a/sys/dev/pci/drm/i915_drv.c
+++ b/sys/dev/pci/drm/i915_drv.c
@@ -49,8 +49,10 @@ i915_configure(drm_device_t *dev)
dev->driver.load = i915_driver_load;
dev->driver.preclose = i915_driver_preclose;
dev->driver.lastclose = i915_driver_lastclose;
- dev->driver.device_is_agp = i915_driver_device_is_agp,
- dev->driver.vblank_wait = i915_driver_vblank_wait;
+ dev->driver.device_is_agp = i915_driver_device_is_agp;
+ dev->driver.get_vblank_counter = i915_get_vblank_counter;
+ dev->driver.enable_vblank = i915_enable_vblank;
+ dev->driver.disable_vblank = i915_disable_vblank;
dev->driver.irq_preinstall = i915_driver_irq_preinstall;
dev->driver.irq_postinstall = i915_driver_irq_postinstall;
dev->driver.irq_uninstall = i915_driver_irq_uninstall;
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 99a16492abe..6421f689c46 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -37,7 +37,7 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20070209"
+#define DRIVER_DATE "20080312"
#if defined(__linux__)
#define I915_HAVE_FENCE
@@ -57,10 +57,11 @@
* 1.9: Usable page flipping and triple buffering
* 1.10: Plane/pipe disentangling
* 1.11: TTM superioctl
+ * 1.12: TTM relocation optimization
*/
#define DRIVER_MAJOR 1
#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER)
-#define DRIVER_MINOR 11
+#define DRIVER_MINOR 13
#else
#define DRIVER_MINOR 6
#endif
@@ -68,6 +69,7 @@
#ifdef I915_HAVE_BUFFER
#define I915_MAX_VALIDATE_BUFFERS 4096
+struct drm_i915_validate_buffer;
#endif
typedef struct _drm_i915_ring_buffer {
@@ -140,16 +142,22 @@ typedef struct drm_i915_private {
void *agp_iomap;
unsigned int max_validate_buffers;
struct mutex cmdbuf_mutex;
+ struct drm_i915_validate_buffer *val_bufs;
#endif
DRM_SPINTYPE swaps_lock;
drm_i915_vbl_swap_t vbl_swaps;
unsigned int swaps_pending;
-
+#if defined(I915_HAVE_BUFFER)
+ /* DRI2 sarea */
+ struct drm_buffer_object *sarea_bo;
+ struct drm_bo_kmap_obj sarea_kmap;
+#endif
/* Register state */
u8 saveLBB;
u32 saveDSPACNTR;
u32 saveDSPBCNTR;
+ u32 saveDSPARB;
u32 savePIPEACONF;
u32 savePIPEBCONF;
u32 savePIPEASRC;
@@ -165,6 +173,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_A;
u32 saveVSYNC_A;
u32 saveBCLRPAT_A;
+ u32 savePIPEASTAT;
u32 saveDSPASTRIDE;
u32 saveDSPASIZE;
u32 saveDSPAPOS;
@@ -185,6 +194,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_B;
u32 saveVSYNC_B;
u32 saveBCLRPAT_B;
+ u32 savePIPEBSTAT;
u32 saveDSPBSTRIDE;
u32 saveDSPBSIZE;
u32 saveDSPBPOS;
@@ -213,17 +223,24 @@ typedef struct drm_i915_private {
u32 saveFBC_LL_BASE;
u32 saveFBC_CONTROL;
u32 saveFBC_CONTROL2;
+ u32 saveIER;
+ u32 saveIIR;
+ u32 saveIMR;
+ u32 saveCACHE_MODE_0;
+ u32 saveD_STATE;
+ u32 saveDSPCLK_GATE_D;
+ u32 saveMI_ARB_STATE;
u32 saveSWF0[16];
u32 saveSWF1[16];
u32 saveSWF2[3];
u8 saveMSR;
u8 saveSR[8];
- u8 saveGR[24];
+ u8 saveGR[25];
u8 saveAR_INDEX;
- u8 saveAR[20];
+ u8 saveAR[21];
u8 saveDACMASK;
u8 saveDACDATA[256*3]; /* 256 3-byte colors */
- u8 saveCR[36];
+ u8 saveCR[37];
} drm_i915_private_t;
enum intel_chip_family {
@@ -250,6 +267,9 @@ extern void i915_emit_breadcrumb(struct drm_device *dev);
extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync);
extern int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush);
extern int i915_driver_firstopen(struct drm_device *dev);
+extern int i915_dispatch_batchbuffer(struct drm_device * dev,
+ drm_i915_batchbuffer_t * batch);
+extern int i915_quiescent(struct drm_device *dev);
/* i915_irq.c */
extern int i915_irq_emit(struct drm_device *dev, void *data,
@@ -257,21 +277,22 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
extern int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern void i915_driver_irq_postinstall(struct drm_device * dev);
+extern int i915_driver_irq_postinstall(struct drm_device * dev);
extern void i915_driver_irq_uninstall(struct drm_device * dev);
extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern int i915_emit_irq(struct drm_device *dev);
-extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
-extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
+extern int i915_emit_irq(struct drm_device * dev);
+extern int i915_enable_vblank(struct drm_device *dev, int crtc);
+extern void i915_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
+extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
/* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -288,35 +309,35 @@ extern void i915_mem_release(struct drm_device * dev,
struct mem_block *heap);
#ifdef I915_HAVE_FENCE
/* i915_fence.c */
-
-
extern void i915_fence_handler(struct drm_device *dev);
-extern int i915_fence_emit_sequence(struct drm_device *dev, uint32_t class,
- uint32_t flags,
- uint32_t *sequence,
- uint32_t *native_type);
-extern void i915_poke_flush(struct drm_device *dev, uint32_t class);
-extern int i915_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags);
+extern void i915_invalidate_reported_sequence(struct drm_device *dev);
+
#endif
#ifdef I915_HAVE_BUFFER
/* i915_buffer.c */
extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev);
-extern int i915_fence_types(struct drm_buffer_object *bo, uint32_t *fclass,
- uint32_t *type);
+extern int i915_fence_type(struct drm_buffer_object *bo, uint32_t *fclass,
+ uint32_t *type);
extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
extern int i915_init_mem_type(struct drm_device *dev, uint32_t type,
struct drm_mem_type_manager *man);
-extern uint32_t i915_evict_mask(struct drm_buffer_object *bo);
+extern uint64_t i915_evict_flags(struct drm_buffer_object *bo);
extern int i915_move(struct drm_buffer_object *bo, int evict,
int no_wait, struct drm_bo_mem_reg *new_mem);
void i915_flush_ttm(struct drm_ttm *ttm);
+/* i915_execbuf.c */
+int i915_execbuffer(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
#endif
+#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
extern void intel_init_chipset_flush_compat(struct drm_device *dev);
extern void intel_fini_chipset_flush_compat(struct drm_device *dev);
#endif
+#endif
#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
@@ -330,8 +351,8 @@ extern void intel_fini_chipset_flush_compat(struct drm_device *dev);
#define BEGIN_LP_RING(n) do { \
if (I915_VERBOSE) \
- DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
- (n), __FUNCTION__); \
+ DRM_DEBUG("BEGIN_LP_RING(%d)\n", \
+ (n)); \
if (dev_priv->ring.space < (n)*4) \
i915_wait_ring(dev, (n)*4, __FUNCTION__); \
outcount = 0; \
@@ -404,6 +425,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
#define CMD_REPORT_HEAD (7<<23)
+#define CMD_STORE_DWORD_IMM ((0x20<<23) | (0x1 << 22) | 0x1)
#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
@@ -456,10 +478,23 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
/* Interrupt bits:
*/
-#define USER_INT_FLAG (1<<1)
-#define VSYNC_PIPEB_FLAG (1<<5)
-#define VSYNC_PIPEA_FLAG (1<<7)
-#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
+#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
+#define I915_HWB_OOM_INTERRUPT (1<<13) /* binner out of memory */
+#define I915_SYNC_STATUS_INTERRUPT (1<<12)
+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
+#define I915_DEBUG_INTERRUPT (1<<2)
+#define I915_USER_INTERRUPT (1<<1)
+
#define I915REG_HWSTAM 0x02098
#define I915REG_INT_IDENTITY_R 0x020a4
@@ -467,11 +502,67 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define I915REG_INT_ENABLE_R 0x020a0
#define I915REG_INSTPM 0x020c0
+#define PIPEADSL 0x70000
+#define PIPEBDSL 0x71000
+
#define I915REG_PIPEASTAT 0x70024
#define I915REG_PIPEBSTAT 0x71024
+/*
+ * The two pipe frame counter registers are not synchronized, so
+ * reading a stable value is somewhat tricky. The following code
+ * should work:
+ *
+ * do {
+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ * PIPE_FRAME_HIGH_SHIFT;
+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
+ * PIPE_FRAME_LOW_SHIFT);
+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ * PIPE_FRAME_HIGH_SHIFT);
+ * } while (high1 != high2);
+ * frame = (high1 << 8) | low1;
+ */
+#define PIPEAFRAMEHIGH 0x70040
+#define PIPEBFRAMEHIGH 0x71040
+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
+#define PIPE_FRAME_HIGH_SHIFT 0
+#define PIPEAFRAMEPIXEL 0x70044
+#define PIPEBFRAMEPIXEL 0x71044
-#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
-#define I915_VBLANK_CLEAR (1UL<<1)
+#define PIPE_FRAME_LOW_MASK 0xff000000
+#define PIPE_FRAME_LOW_SHIFT 24
+/*
+ * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register
+ * and is 24 bits wide.
+ */
+#define PIPE_PIXEL_MASK 0x00ffffff
+#define PIPE_PIXEL_SHIFT 0
+
+#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
+#define I915_CRC_ERROR_ENABLE (1UL<<29)
+#define I915_CRC_DONE_ENABLE (1UL<<28)
+#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
+#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
+#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
+#define I915_DPST_EVENT_ENABLE (1UL<<23)
+#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
+#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
+#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
+#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
+#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
+#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
+#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
+#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
+#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
+#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
+#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
+#define I915_DPST_EVENT_STATUS (1UL<<7)
+#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
+#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
+#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
+#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
+#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
+#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
#define SRX_INDEX 0x3c4
#define SRX_DATA 0x3c5
@@ -509,7 +600,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define HEAD_WRAP_ONE 0x00200000
#define HEAD_ADDR 0x001FFFFC
#define RING_START 0x08
-#define START_ADDR 0x0xFFFFF000
+#define START_ADDR 0xFFFFF000
#define RING_LEN 0x0C
#define RING_NR_PAGES 0x001FF000
#define RING_REPORT_MASK 0x00000006
@@ -536,6 +627,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
*/
#define DMA_FADD_S 0x20d4
+/* Memory Interface Arbitration State
+ */
+#define MI_ARB_STATE 0x20e4
+
/* Cache mode 0 reg.
* - Manipulating render cache behaviour is central
* to the concept of zone rendering, tuning this reg can help avoid
@@ -546,6 +641,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
* bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
*/
#define Cache_Mode_0 0x2120
+#define CACHE_MODE_0 0x2120
#define CM0_MASK_SHIFT 16
#define CM0_IZ_OPT_DISABLE (1<<6)
#define CM0_ZR_OPT_DISABLE (1<<5)
@@ -639,6 +735,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
+#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
+
#define MI_BATCH_BUFFER ((0x30<<23)|1)
#define MI_BATCH_BUFFER_START (0x31<<23)
@@ -735,6 +834,10 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
/** P1 value is 2 greater than this field */
# define VGA0_PD_P1_MASK (0x1f << 0)
+/* PCI D state control register */
+#define D_STATE 0x6104
+#define DSPCLK_GATE_D 0x6200
+
/* I830 CRTC registers */
#define HTOTAL_A 0x60000
#define HBLANK_A 0x60004
@@ -756,6 +859,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define BCLRPAT_B 0x61020
#define VSYNCSHIFT_B 0x61028
+#define HACTIVE_MASK 0x00000fff
+#define VTOTAL_MASK 0x00001fff
+#define VTOTAL_SHIFT 16
+#define VACTIVE_MASK 0x00000fff
+#define VBLANK_END_MASK 0x00001fff
+#define VBLANK_END_SHIFT 16
+#define VBLANK_START_MASK 0x00001fff
+
#define PP_STATUS 0x61200
# define PP_ON (1 << 31)
/**
@@ -1043,6 +1154,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
+#define DSPARB 0x70030
+#define DSPARB_CSTART_MASK (0x7f << 7)
+#define DSPARB_CSTART_SHIFT 7
+#define DSPARB_BSTART_MASK (0x7f)
+#define DSPARB_BSTART_SHIFT 0
+
#define PIPEBCONF 0x71008
#define PIPEBCONF_ENABLE (1<<31)
#define PIPEBCONF_DISABLE 0
@@ -1148,33 +1265,29 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define PALETTE_A 0x0a000
#define PALETTE_B 0x0a800
-#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC)
-#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG)
-#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
-#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG)
-#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG)
-
-#ifdef __OpenBSD__
-#define IS_I915G(dev) (dev->pci_device == PCI_PRODUCT_INTEL_82915G_IGD_1)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/
-#define IS_I915GM(dev) ((dev)->pci_device == PCI_PRODUCT_INTEL_82915GM_IGD_1)
-#define IS_I945G(dev) ((dev)->pci_device == PCI_PRODUCT_INTEL_82945G_IGD_1)
-#define IS_I945GM(dev) ((dev)->pci_device == PCI_PRODUCT_INTEL_82945GM_IGD_1)
-#else
-#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/
-#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG)
-#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG)
-#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG)
-#endif
-
+#define IS_I830(dev) ((dev)->pci_device == 0x3577)
+#define IS_845G(dev) ((dev)->pci_device == 0x2562)
+#define IS_I85X(dev) ((dev)->pci_device == 0x3582)
+#define IS_I855(dev) ((dev)->pci_device == 0x3582)
+#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
+
+#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
+#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
+#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
+#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\
+ (dev)->pci_device == 0x27AE)
#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \
(dev)->pci_device == 0x2982 || \
(dev)->pci_device == 0x2992 || \
(dev)->pci_device == 0x29A2 || \
(dev)->pci_device == 0x2A02 || \
- (dev)->pci_device == 0x2A12)
+ (dev)->pci_device == 0x2A12 || \
+ (dev)->pci_device == 0x2A42)
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
+#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
+
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \
(dev)->pci_device == 0x29D2)
@@ -1183,7 +1296,9 @@ 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_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
+
+#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/sys/dev/pci/drm/i915_irq.c b/sys/dev/pci/drm/i915_irq.c
index 2c699ecd34c..da87dbcc45c 100644
--- a/sys/dev/pci/drm/i915_irq.c
+++ b/sys/dev/pci/drm/i915_irq.c
@@ -31,10 +31,6 @@
#include "i915_drm.h"
#include "i915_drv.h"
-#define USER_INT_FLAG (1<<1)
-#define VSYNC_PIPEB_FLAG (1<<5)
-#define VSYNC_PIPEA_FLAG (1<<7)
-
#define MAX_NOPID ((u32)~0)
/**
@@ -42,9 +38,9 @@
* @dev: DRM device
* @plane: plane to look for
*
- * We need to get the pipe associated with a given plane to correctly perform
- * vblank driven swapping, and they may not always be equal. So look up the
- * pipe associated with @plane here.
+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
+ * rather than a pipe number, since they may not always be equal. This routine
+ * maps the given @plane back to a pipe number.
*/
static int
i915_get_pipe(struct drm_device *dev, int plane)
@@ -58,6 +54,44 @@ i915_get_pipe(struct drm_device *dev, int plane)
}
/**
+ * i915_get_plane - return the the plane associated with a given pipe
+ * @dev: DRM device
+ * @pipe: pipe to look for
+ *
+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
+ * rather than a plane number, since they may not always be equal. This routine
+ * maps the given @pipe back to a plane number.
+ */
+static int
+i915_get_plane(struct drm_device *dev, int pipe)
+{
+ if (i915_get_pipe(dev, 0) == pipe)
+ return 0;
+ return 1;
+}
+
+/**
+ * i915_pipe_enabled - check if a pipe is enabled
+ * @dev: DRM device
+ * @pipe: pipe to check
+ *
+ * Reading certain registers when the pipe is disabled can hang the chip.
+ * Use this routine to make sure the PLL is running and the pipe is active
+ * before reading such registers if unsure.
+ */
+static int
+i915_pipe_enabled(struct drm_device *dev, int pipe)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
+
+ if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
+ return 1;
+
+ return 0;
+}
+
+/**
* Emit a synchronous flip.
*
* This function must be called with the drawable spinlock held.
@@ -114,8 +148,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
struct list_head *list, *tmp, hits, *hit;
int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
- unsigned counter[2] = { atomic_read(&dev->vbl_received),
- atomic_read(&dev->vbl_received2) };
+ unsigned counter[2];
struct drm_drawable_info *drw;
drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
u32 cpp = dev_priv->cpp, offsets[3];
@@ -123,9 +156,23 @@ static void i915_vblank_tasklet(struct drm_device *dev)
XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB)
: XY_SRC_COPY_BLT_CMD;
- u32 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
- (cpp << 23) | (1 << 24);
+ u32 src_pitch = sarea_priv->pitch * cpp;
+ u32 dst_pitch = sarea_priv->pitch * cpp;
+ /* COPY rop (0xcc), map cpp to magic color depth constants */
+ u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
RING_LOCALS;
+
+ if (sarea_priv->front_tiled) {
+ cmd |= XY_SRC_COPY_BLT_DST_TILED;
+ dst_pitch >>= 2;
+ }
+ if (sarea_priv->back_tiled) {
+ cmd |= XY_SRC_COPY_BLT_SRC_TILED;
+ src_pitch >>= 2;
+ }
+
+ counter[0] = drm_vblank_count(dev, 0);
+ counter[1] = drm_vblank_count(dev, 1);
DRM_DEBUG("\n");
@@ -151,6 +198,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
list_del(list);
dev_priv->swaps_pending--;
+ drm_vblank_put(dev, pipe);
DRM_SPINUNLOCK(&dev_priv->swaps_lock);
DRM_SPINLOCK(&dev->drw_lock);
@@ -242,16 +290,29 @@ static void i915_vblank_tasklet(struct drm_device *dev)
}
if (init_drawrect) {
- BEGIN_LP_RING(6);
-
- OUT_RING(GFX_OP_DRAWRECT_INFO);
- OUT_RING(0);
- OUT_RING(0);
- OUT_RING(sarea_priv->width | sarea_priv->height << 16);
- OUT_RING(sarea_priv->width | sarea_priv->height << 16);
- OUT_RING(0);
-
- ADVANCE_LP_RING();
+ int width = sarea_priv->width;
+ int height = sarea_priv->height;
+ if (IS_I965G(dev)) {
+ BEGIN_LP_RING(4);
+
+ OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
+ OUT_RING(0);
+ OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
+ OUT_RING(0);
+
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(6);
+
+ OUT_RING(GFX_OP_DRAWRECT_INFO);
+ OUT_RING(0);
+ OUT_RING(0);
+ OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
+ OUT_RING(0);
+ OUT_RING(0);
+
+ ADVANCE_LP_RING();
+ }
sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
@@ -276,12 +337,12 @@ static void i915_vblank_tasklet(struct drm_device *dev)
BEGIN_LP_RING(8);
OUT_RING(cmd);
- OUT_RING(pitchropcpp);
+ OUT_RING(ropcpp | dst_pitch);
OUT_RING((y1 << 16) | rect->x1);
OUT_RING((y2 << 16) | rect->x2);
OUT_RING(offsets[front]);
OUT_RING((y1 << 16) | rect->x1);
- OUT_RING(pitchropcpp & 0xffff);
+ OUT_RING(src_pitch);
OUT_RING(offsets[back]);
ADVANCE_LP_RING();
@@ -300,66 +361,143 @@ 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)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) 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)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ unsigned long high_frame;
+ unsigned long low_frame;
+ u32 high1, high2, low, count;
+ int pipe;
+
+ pipe = i915_get_pipe(dev, plane);
+ high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
+ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
+
+ if (!i915_pipe_enabled(dev, pipe)) {
+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+ return 0;
+ }
+
+ /*
+ * High & low register fields aren't synchronized, so make sure
+ * we get a low value that's stable across two reads of the high
+ * register.
+ */
+ do {
+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
+ PIPE_FRAME_LOW_SHIFT);
+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ } while (high1 != high2);
+
+ 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;
+}
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- u16 temp;
+ u32 iir;
u32 pipea_stats, pipeb_stats;
+ int vblank = 0;
- pipea_stats = I915_READ(I915REG_PIPEASTAT);
- pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
-
- temp = I915_READ16(I915REG_INT_IDENTITY_R);
- temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
-
+ iir = I915_READ(I915REG_INT_IDENTITY_R);
#if 0
- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
+ DRM_DEBUG("flag=%08x\n", iir);
#endif
- if (temp == 0)
+ if (iir == 0) {
+ DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
+ iir,
+ I915_READ(I915REG_INT_MASK_R),
+ I915_READ(I915REG_INT_ENABLE_R),
+ I915_READ(I915REG_PIPEASTAT),
+ I915_READ(I915REG_PIPEBSTAT));
return IRQ_NONE;
+ }
- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
- (void) I915_READ16(I915REG_INT_IDENTITY_R);
- DRM_READMEMORYBARRIER();
+ /*
+ * Clear the PIPE(A|B)STAT regs before the IIR otherwise
+ * we may get extra interrupts.
+ */
+ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
+ pipea_stats = I915_READ(I915REG_PIPEASTAT);
+ if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
+ I915_VBLANK_INTERRUPT_STATUS))
+ {
+ vblank++;
+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
+ }
+ I915_WRITE(I915REG_PIPEASTAT, pipea_stats);
+ }
+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
+ pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
+ if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
+ I915_VBLANK_INTERRUPT_STATUS))
+ {
+ vblank++;
+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
+ }
+ I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats);
+ }
- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
- if (temp & USER_INT_FLAG) {
+ I915_WRITE(I915REG_INT_IDENTITY_R, iir);
+ (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */
+
+ if (iir & I915_USER_INTERRUPT) {
DRM_WAKEUP(&dev_priv->irq_queue);
#ifdef I915_HAVE_FENCE
i915_fence_handler(dev);
#endif
}
- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
- int vblank_pipe = dev_priv->vblank_pipe;
-
- if ((vblank_pipe &
- (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
- == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
- if (temp & VSYNC_PIPEA_FLAG)
- atomic_inc(&dev->vbl_received);
- if (temp & VSYNC_PIPEB_FLAG)
- atomic_inc(&dev->vbl_received2);
- } else if (((temp & VSYNC_PIPEA_FLAG) &&
- (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
- ((temp & VSYNC_PIPEB_FLAG) &&
- (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
- atomic_inc(&dev->vbl_received);
-
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
-
+ if (vblank) {
if (dev_priv->swaps_pending > 0)
drm_locked_tasklet(dev, i915_vblank_tasklet);
- I915_WRITE(I915REG_PIPEASTAT,
- pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
- I915_VBLANK_CLEAR);
- I915_WRITE(I915REG_PIPEBSTAT,
- pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
- I915_VBLANK_CLEAR);
}
return IRQ_HANDLED;
@@ -372,7 +510,7 @@ int i915_emit_irq(struct drm_device *dev)
i915_kernel_lost_context(dev);
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
i915_emit_breadcrumb(dev);
@@ -388,8 +526,8 @@ void i915_user_irq_on(drm_i915_private_t *dev_priv)
{
DRM_SPINLOCK(&dev_priv->user_irq_lock);
if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){
- dev_priv->irq_enable_reg |= USER_INT_FLAG;
- I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ dev_priv->irq_enable_reg |= I915_USER_INTERRUPT;
+ I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
}
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
@@ -400,7 +538,7 @@ void i915_user_irq_off(drm_i915_private_t *dev_priv)
DRM_SPINLOCK(&dev_priv->user_irq_lock);
if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
// dev_priv->irq_enable_reg &= ~USER_INT_FLAG;
- // I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ // I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
}
DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
}
@@ -411,61 +549,28 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = 0;
- DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr,
+ DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));
if (READ_BREADCRUMB(dev_priv) >= irq_nr)
return 0;
- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
-
i915_user_irq_on(dev_priv);
DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
READ_BREADCRUMB(dev_priv) >= irq_nr);
i915_user_irq_off(dev_priv);
if (ret == -EBUSY) {
- DRM_ERROR("%s: EBUSY -- rec: %d emitted: %d\n",
- __FUNCTION__,
+ DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
}
- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->last_dispatch =
+ READ_BREADCRUMB(dev_priv);
return ret;
}
-static int i915_driver_vblank_do_wait(struct drm_device *dev,
- unsigned int *sequence,
- atomic_t *counter)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
-
- if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
- return -EINVAL;
- }
-
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1<<23)));
-
- *sequence = cur_vblank;
-
- return ret;
-}
-
-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
-}
-
-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
-}
-
/* Needs the lock as it touches the ring.
*/
int i915_irq_emit(struct drm_device *dev, void *data,
@@ -478,7 +583,7 @@ int i915_irq_emit(struct drm_device *dev, void *data,
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -501,24 +606,102 @@ int i915_irq_wait(struct drm_device *dev, void *data,
drm_i915_irq_wait_t *irqwait = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
return i915_wait_irq(dev, irqwait->irq_seq);
}
-static void i915_enable_interrupt (struct drm_device *dev)
+int i915_enable_vblank(struct drm_device *dev, int plane)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int pipe = i915_get_pipe(dev, plane);
+ u32 pipestat_reg = 0;
+ u32 pipestat;
+
+ switch (pipe) {
+ case 0:
+ pipestat_reg = I915REG_PIPEASTAT;
+ dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
+ break;
+ case 1:
+ pipestat_reg = I915REG_PIPEBSTAT;
+ dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
+ pipe);
+ break;
+ }
+
+ if (pipestat_reg)
+ {
+ pipestat = I915_READ (pipestat_reg);
+ /*
+ * Older chips didn't have the start vblank interrupt,
+ * but
+ */
+ if (IS_I965G (dev))
+ pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE;
+ else
+ pipestat |= I915_VBLANK_INTERRUPT_ENABLE;
+ /*
+ * Clear any pending status
+ */
+ pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
+ I915_VBLANK_INTERRUPT_STATUS);
+ I915_WRITE(pipestat_reg, pipestat);
+ }
+ I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+
+ return 0;
+}
+
+void i915_disable_vblank(struct drm_device *dev, int plane)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int pipe = i915_get_pipe(dev, plane);
+ u32 pipestat_reg = 0;
+ u32 pipestat;
+
+ switch (pipe) {
+ case 0:
+ pipestat_reg = I915REG_PIPEASTAT;
+ dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
+ break;
+ case 1:
+ pipestat_reg = I915REG_PIPEBSTAT;
+ dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
+ break;
+ default:
+ DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
+ pipe);
+ break;
+ }
+
+ I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ if (pipestat_reg)
+ {
+ pipestat = I915_READ (pipestat_reg);
+ pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE |
+ I915_VBLANK_INTERRUPT_ENABLE);
+ /*
+ * Clear any pending status
+ */
+ pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
+ I915_VBLANK_INTERRUPT_STATUS);
+ I915_WRITE(pipestat_reg, pipestat);
+ }
+}
- dev_priv->irq_enable_reg = USER_INT_FLAG;
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
- dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
- dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
+static void i915_enable_interrupt (struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ dev_priv->irq_enable_reg |= I915_USER_INTERRUPT;
- I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+ I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
dev_priv->irq_enabled = 1;
}
@@ -531,20 +714,17 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
drm_i915_vblank_pipe_t *pipe = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
- DRM_ERROR("%s called with invalid pipe 0x%x\n",
- __FUNCTION__, pipe->pipe);
+ DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
return -EINVAL;
}
dev_priv->vblank_pipe = pipe->pipe;
- i915_enable_interrupt (dev);
-
return 0;
}
@@ -556,15 +736,15 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
u16 flag;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
flag = I915_READ(I915REG_INT_ENABLE_R);
pipe->pipe = 0;
- if (flag & VSYNC_PIPEA_FLAG)
+ if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)
pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
- if (flag & VSYNC_PIPEB_FLAG)
+ if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
return 0;
@@ -582,13 +762,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
unsigned int pipe, seqtype, curseq, plane;
unsigned long irqflags;
struct list_head *list;
+ int ret;
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __func__);
return -EINVAL;
}
- if (dev_priv->sarea_priv->rotation) {
+ if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) {
DRM_DEBUG("Rotation not supported\n");
return -EINVAL;
}
@@ -625,7 +806,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
+ drm_update_vblank_count(dev, pipe);
+ curseq = drm_vblank_count(dev, pipe);
if (seqtype == _DRM_VBLANK_RELATIVE)
swap->sequence += curseq;
@@ -698,6 +880,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
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;
@@ -708,7 +896,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
- list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head);
+ list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head);
dev_priv->swaps_pending++;
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
@@ -727,16 +915,28 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
}
-void i915_driver_irq_postinstall(struct drm_device * dev)
+int i915_driver_irq_postinstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int ret, num_pipes = 2;
DRM_SPININIT(&dev_priv->swaps_lock, "swap");
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
dev_priv->swaps_pending = 0;
+#ifdef __OpenBSD__
+ mtx_init(&dev_priv->user_irq_lock, IPL_NONE);
+#else
DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
+#endif
dev_priv->user_irq_refcount = 0;
+ dev_priv->irq_enable_reg = 0;
+
+ ret = drm_vblank_init(dev, num_pipes);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
i915_enable_interrupt(dev);
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
@@ -746,21 +946,26 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
*/
I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
+ return 0;
}
void i915_driver_irq_uninstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- u16 temp;
+ u32 temp;
if (!dev_priv)
return;
dev_priv->irq_enabled = 0;
- I915_WRITE16(I915REG_HWSTAM, 0xffff);
- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
-
- temp = I915_READ16(I915REG_INT_IDENTITY_R);
- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+ I915_WRITE(I915REG_HWSTAM, 0xffffffff);
+ I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
+ I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
+
+ temp = I915_READ(I915REG_PIPEASTAT);
+ I915_WRITE(I915REG_PIPEASTAT, temp);
+ temp = I915_READ(I915REG_PIPEBSTAT);
+ I915_WRITE(I915REG_PIPEBSTAT, temp);
+ temp = I915_READ(I915REG_INT_IDENTITY_R);
+ I915_WRITE(I915REG_INT_IDENTITY_R, temp);
}
diff --git a/sys/dev/pci/drm/i915_mem.c b/sys/dev/pci/drm/i915_mem.c
index d360896f38a..6126a60dc9c 100644
--- a/sys/dev/pci/drm/i915_mem.c
+++ b/sys/dev/pci/drm/i915_mem.c
@@ -276,7 +276,7 @@ int i915_mem_alloc(struct drm_device *dev, void *data,
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -314,7 +314,7 @@ int i915_mem_free(struct drm_device *dev, void *data,
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -342,7 +342,7 @@ int i915_mem_init_heap(struct drm_device *dev, void *data,
struct mem_block **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -366,7 +366,7 @@ int i915_mem_destroy_heap( struct drm_device *dev, void *data,
struct mem_block **heap;
if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ DRM_ERROR( "called with no initialization\n" );
return -EINVAL;
}
diff --git a/sys/dev/pci/drm/mach64_dma.c b/sys/dev/pci/drm/mach64_dma.c
index 13fa044650f..339234fa830 100644
--- a/sys/dev/pci/drm/mach64_dma.c
+++ b/sys/dev/pci/drm/mach64_dma.c
@@ -6,7 +6,7 @@
* \author Gareth Hughes <gareth@valinux.com>
* \author Frank C. Earl <fearl@airmail.net>
* \author Leif Delgass <ldelgass@retinalburn.net>
- * \author Jose Fonseca <j_r_fonseca@yahoo.co.uk>
+ * \author José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
/*
@@ -57,7 +57,7 @@
* \returns zero on success, or -EBUSY if the timeout (specificed by
* drm_mach64_private::usec_timeout) occurs.
*/
-int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, int entries)
+int mach64_do_wait_for_fifo(drm_mach64_private_t *dev_priv, int entries)
{
int slots = 0, i;
@@ -68,15 +68,14 @@ int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, int entries)
DRM_UDELAY(1);
}
- DRM_INFO("%s failed! slots=%d entries=%d\n", __FUNCTION__, slots,
- entries);
+ DRM_INFO("failed! slots=%d entries=%d\n", slots, entries);
return -EBUSY;
}
/**
* Wait for the draw engine to be idle.
*/
-int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv)
+int mach64_do_wait_for_idle(drm_mach64_private_t *dev_priv)
{
int i, ret;
@@ -85,14 +84,12 @@ int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv)
return ret;
for (i = 0; i < dev_priv->usec_timeout; i++) {
- if (!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE)) {
+ if (!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE))
return 0;
- }
DRM_UDELAY(1);
}
- DRM_INFO("%s failed! GUI_STAT=0x%08x\n", __FUNCTION__,
- MACH64_READ(MACH64_GUI_STAT));
+ DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT));
mach64_dump_ring_info(dev_priv);
return -EBUSY;
}
@@ -116,7 +113,7 @@ int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv)
*
* \sa mach64_dump_ring_info()
*/
-int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n)
+int mach64_wait_ring(drm_mach64_private_t *dev_priv, int n)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
int i;
@@ -124,9 +121,8 @@ int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n)
for (i = 0; i < dev_priv->usec_timeout; i++) {
mach64_update_ring_snapshot(dev_priv);
if (ring->space >= n) {
- if (i > 0) {
- DRM_DEBUG("%s: %d usecs\n", __FUNCTION__, i);
- }
+ if (i > 0)
+ DRM_DEBUG("%d usecs\n", i);
return 0;
}
DRM_UDELAY(1);
@@ -143,7 +139,7 @@ int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n)
*
* \sa mach64_wait_ring()
*/
-static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
+static int mach64_ring_idle(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
u32 head;
@@ -155,9 +151,8 @@ static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
mach64_update_ring_snapshot(dev_priv);
if (ring->head == ring->tail &&
!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE)) {
- if (i > 0) {
- DRM_DEBUG("%s: %d usecs\n", __FUNCTION__, i);
- }
+ if (i > 0)
+ DRM_DEBUG("%d usecs\n", i);
return 0;
}
if (ring->head == head) {
@@ -169,8 +164,7 @@ static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
DRM_UDELAY(1);
}
- DRM_INFO("%s failed! GUI_STAT=0x%08x\n", __FUNCTION__,
- MACH64_READ(MACH64_GUI_STAT));
+ DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT));
mach64_dump_ring_info(dev_priv);
return -EBUSY;
}
@@ -180,7 +174,7 @@ static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
*
* \sa mach64_do_engine_reset()
*/
-static void mach64_ring_reset(drm_mach64_private_t * dev_priv)
+static void mach64_ring_reset(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
@@ -198,7 +192,7 @@ static void mach64_ring_reset(drm_mach64_private_t * dev_priv)
/**
* Ensure the all the queued commands will be processed.
*/
-int mach64_do_dma_flush(drm_mach64_private_t * dev_priv)
+int mach64_do_dma_flush(drm_mach64_private_t *dev_priv)
{
/* FIXME: It's not necessary to wait for idle when flushing
* we just need to ensure the ring will be completely processed
@@ -210,14 +204,14 @@ int mach64_do_dma_flush(drm_mach64_private_t * dev_priv)
/**
* Stop all DMA activity.
*/
-int mach64_do_dma_idle(drm_mach64_private_t * dev_priv)
+int mach64_do_dma_idle(drm_mach64_private_t *dev_priv)
{
int ret;
/* wait for completion */
if ((ret = mach64_ring_idle(dev_priv)) < 0) {
- DRM_ERROR("%s failed BM_GUI_TABLE=0x%08x tail: %u\n",
- __FUNCTION__, MACH64_READ(MACH64_BM_GUI_TABLE),
+ DRM_ERROR("failed BM_GUI_TABLE=0x%08x tail: %u\n",
+ MACH64_READ(MACH64_BM_GUI_TABLE),
dev_priv->ring.tail);
return ret;
}
@@ -232,11 +226,11 @@ int mach64_do_dma_idle(drm_mach64_private_t * dev_priv)
/**
* Reset the engine. This will stop the DMA if it is running.
*/
-int mach64_do_engine_reset(drm_mach64_private_t * dev_priv)
+int mach64_do_engine_reset(drm_mach64_private_t *dev_priv)
{
u32 tmp;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
/* Kill off any outstanding DMA transfers.
*/
@@ -276,7 +270,7 @@ int mach64_do_engine_reset(drm_mach64_private_t * dev_priv)
/**
* Dump engine registers values.
*/
-void mach64_dump_engine_info(drm_mach64_private_t * dev_priv)
+void mach64_dump_engine_info(drm_mach64_private_t *dev_priv)
{
DRM_INFO("\n");
if (!dev_priv->is_pci) {
@@ -417,8 +411,8 @@ void mach64_dump_engine_info(drm_mach64_private_t * dev_priv)
* Used by mach64_dump_ring_info() to dump the contents of the current buffer
* pointed by the ring head.
*/
-static void mach64_dump_buf_info(drm_mach64_private_t * dev_priv,
- struct drm_buf * buf)
+static void mach64_dump_buf_info(drm_mach64_private_t *dev_priv,
+ struct drm_buf *buf)
{
u32 addr = GETBUFADDR(buf);
u32 used = buf->used >> 2;
@@ -477,7 +471,7 @@ static void mach64_dump_buf_info(drm_mach64_private_t * dev_priv,
* Dump the ring state and contents, including the contents of the buffer being
* processed by the graphics engine.
*/
-void mach64_dump_ring_info(drm_mach64_private_t * dev_priv)
+void mach64_dump_ring_info(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
int i, skipped;
@@ -526,9 +520,8 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv)
u32 buf_addr = GETBUFADDR(buf);
- if (buf_addr <= addr && addr < buf_addr + buf->used) {
+ if (buf_addr <= addr && addr < buf_addr + buf->used)
mach64_dump_buf_info(dev_priv, buf);
- }
}
}
@@ -559,6 +552,259 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv)
/*******************************************************************/
+/** \name DMA descriptor ring macros */
+/*@{*/
+
+/**
+ * Add the end mark to the ring's new tail position.
+ *
+ * The bus master engine will keep processing the DMA buffers listed in the ring
+ * until it finds this mark, making it stop.
+ *
+ * \sa mach64_clear_dma_eol
+ */
+static __inline__ void mach64_set_dma_eol(volatile u32 *addr)
+{
+#if defined(__i386__)
+ int nr = 31;
+
+ /* Taken from include/asm-i386/bitops.h linux header */
+ __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr)
+ :"Ir"(nr));
+#elif defined(__powerpc__)
+ u32 old;
+ u32 mask = cpu_to_le32(MACH64_DMA_EOL);
+
+ /* Taken from the include/asm-ppc/bitops.h linux header */
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%3 \n\
+ or %0,%0,%2 \n\
+ stwcx. %0,0,%3 \n\
+ bne- 1b":"=&r"(old), "=m"(*addr)
+ :"r"(mask), "r"(addr), "m"(*addr)
+ :"cc");
+#elif defined(__alpha__)
+ u32 temp;
+ u32 mask = MACH64_DMA_EOL;
+
+ /* Taken from the include/asm-alpha/bitops.h linux header */
+ __asm__ __volatile__("1: ldl_l %0,%3\n"
+ " bis %0,%2,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous":"=&r"(temp), "=m"(*addr)
+ :"Ir"(mask), "m"(*addr));
+#else
+ u32 mask = cpu_to_le32(MACH64_DMA_EOL);
+
+ *addr |= mask;
+#endif
+}
+
+/**
+ * Remove the end mark from the ring's old tail position.
+ *
+ * It should be called after calling mach64_set_dma_eol to mark the ring's new
+ * tail position.
+ *
+ * We update the end marks while the bus master engine is in operation. Since
+ * the bus master engine may potentially be reading from the same position
+ * that we write, we must change atomically to avoid having intermediary bad
+ * data.
+ */
+static __inline__ void mach64_clear_dma_eol(volatile u32 *addr)
+{
+#if defined(__i386__)
+ int nr = 31;
+
+ /* Taken from include/asm-i386/bitops.h linux header */
+ __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr)
+ :"Ir"(nr));
+#elif defined(__powerpc__)
+ u32 old;
+ u32 mask = cpu_to_le32(MACH64_DMA_EOL);
+
+ /* Taken from the include/asm-ppc/bitops.h linux header */
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%3 \n\
+ andc %0,%0,%2 \n\
+ stwcx. %0,0,%3 \n\
+ bne- 1b":"=&r"(old), "=m"(*addr)
+ :"r"(mask), "r"(addr), "m"(*addr)
+ :"cc");
+#elif defined(__alpha__)
+ u32 temp;
+ u32 mask = ~MACH64_DMA_EOL;
+
+ /* Taken from the include/asm-alpha/bitops.h linux header */
+ __asm__ __volatile__("1: ldl_l %0,%3\n"
+ " and %0,%2,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous":"=&r"(temp), "=m"(*addr)
+ :"Ir"(mask), "m"(*addr));
+#else
+ u32 mask = cpu_to_le32(~MACH64_DMA_EOL);
+
+ *addr &= mask;
+#endif
+}
+
+#define RING_LOCALS \
+ int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring
+
+#define RING_WRITE_OFS _ring_write
+
+#define BEGIN_RING(n) \
+ do { \
+ if (MACH64_VERBOSE) { \
+ DRM_INFO( "BEGIN_RING( %d ) \n", \
+ (n) ); \
+ } \
+ if (dev_priv->ring.space <= (n) * sizeof(u32)) { \
+ int ret; \
+ if ((ret = mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \
+ DRM_ERROR( "wait_ring failed, resetting engine\n"); \
+ mach64_dump_engine_info( dev_priv ); \
+ mach64_do_engine_reset( dev_priv ); \
+ return ret; \
+ } \
+ } \
+ dev_priv->ring.space -= (n) * sizeof(u32); \
+ _ring = (u32 *) dev_priv->ring.start; \
+ _ring_tail = _ring_write = dev_priv->ring.tail; \
+ _ring_mask = dev_priv->ring.tail_mask; \
+ } while (0)
+
+#define OUT_RING( x ) \
+do { \
+ if (MACH64_VERBOSE) { \
+ DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
+ (unsigned int)(x), _ring_write ); \
+ } \
+ _ring[_ring_write++] = cpu_to_le32( x ); \
+ _ring_write &= _ring_mask; \
+} while (0)
+
+#define ADVANCE_RING() \
+do { \
+ if (MACH64_VERBOSE) { \
+ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
+ _ring_write, _ring_tail ); \
+ } \
+ DRM_MEMORYBARRIER(); \
+ mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \
+ DRM_MEMORYBARRIER(); \
+ dev_priv->ring.tail = _ring_write; \
+ mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \
+} while (0)
+
+/**
+ * Queue a DMA buffer of registers writes into the ring buffer.
+ */
+int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv,
+ drm_mach64_freelist_t *entry)
+{
+ int bytes, pages, remainder;
+ u32 address, page;
+ int i;
+ struct drm_buf *buf = entry->buf;
+ RING_LOCALS;
+
+ bytes = buf->used;
+ address = GETBUFADDR( buf );
+ pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;
+
+ BEGIN_RING( pages * 4 );
+
+ for ( i = 0 ; i < pages-1 ; i++ ) {
+ page = address + i * MACH64_DMA_CHUNKSIZE;
+ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
+ OUT_RING( page );
+ OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );
+ OUT_RING( 0 );
+ }
+
+ /* generate the final descriptor for any remaining commands in this buffer */
+ page = address + i * MACH64_DMA_CHUNKSIZE;
+ remainder = bytes - i * MACH64_DMA_CHUNKSIZE;
+
+ /* Save dword offset of last descriptor for this buffer.
+ * This is needed to check for completion of the buffer in freelist_get
+ */
+ entry->ring_ofs = RING_WRITE_OFS;
+
+ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
+ OUT_RING( page );
+ OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );
+ OUT_RING( 0 );
+
+ ADVANCE_RING();
+
+ return 0;
+}
+
+/**
+ * Queue DMA buffer controlling host data tranfers (e.g., blit).
+ *
+ * Almost identical to mach64_add_buf_to_ring.
+ */
+int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv,
+ drm_mach64_freelist_t *entry)
+{
+ int bytes, pages, remainder;
+ u32 address, page;
+ int i;
+ struct drm_buf *buf = entry->buf;
+ RING_LOCALS;
+
+ bytes = buf->used - MACH64_HOSTDATA_BLIT_OFFSET;
+ pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;
+ address = GETBUFADDR( buf );
+
+ BEGIN_RING( 4 + pages * 4 );
+
+ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
+ OUT_RING( address );
+ OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET );
+ OUT_RING( 0 );
+ address += MACH64_HOSTDATA_BLIT_OFFSET;
+
+ for ( i = 0 ; i < pages-1 ; i++ ) {
+ page = address + i * MACH64_DMA_CHUNKSIZE;
+ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );
+ OUT_RING( page );
+ OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );
+ OUT_RING( 0 );
+ }
+
+ /* generate the final descriptor for any remaining commands in this buffer */
+ page = address + i * MACH64_DMA_CHUNKSIZE;
+ remainder = bytes - i * MACH64_DMA_CHUNKSIZE;
+
+ /* Save dword offset of last descriptor for this buffer.
+ * This is needed to check for completion of the buffer in freelist_get
+ */
+ entry->ring_ofs = RING_WRITE_OFS;
+
+ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );
+ OUT_RING( page );
+ OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );
+ OUT_RING( 0 );
+
+ ADVANCE_RING();
+
+ return 0;
+}
+
+/*@}*/
+
+
+/*******************************************************************/
/** \name DMA test and initialization */
/*@{*/
@@ -582,7 +828,7 @@ static int mach64_bm_dma_test(struct drm_device * dev)
u32 src_cntl, pat_reg0, pat_reg1;
int i, count, failed;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
table = (u32 *) dev_priv->ring.start;
@@ -758,7 +1004,7 @@ static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
u32 tmp;
int i, ret;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
dev_priv = drm_alloc(sizeof(drm_mach64_private_t), DRM_MEM_DRIVER);
if (dev_priv == NULL)
@@ -968,7 +1214,7 @@ static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
/** MMIO Pseudo-DMA (intended primarily for debugging, not performance)
*/
-int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
+int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
volatile u32 *ring_read;
@@ -983,9 +1229,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
target = MACH64_BM_ADDR;
if ((ret = mach64_do_wait_for_idle(dev_priv)) < 0) {
- DRM_INFO
- ("%s: idle failed before pseudo-dma dispatch, resetting engine\n",
- __FUNCTION__);
+ DRM_INFO("idle failed before pseudo-dma dispatch, resetting engine\n");
mach64_dump_engine_info(dev_priv);
mach64_do_engine_reset(dev_priv);
return ret;
@@ -1106,7 +1350,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
- DRM_DEBUG("%s completed\n", __FUNCTION__);
+ DRM_DEBUG("completed\n");
return 0;
}
@@ -1119,7 +1363,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
int mach64_do_cleanup_dma(struct drm_device * dev)
{
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
@@ -1163,7 +1407,7 @@ int mach64_dma_init(struct drm_device *dev, void *data,
{
drm_mach64_init_t *init = data;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1182,7 +1426,7 @@ int mach64_dma_idle(struct drm_device *dev, void *data,
{
drm_mach64_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1194,7 +1438,7 @@ int mach64_dma_flush(struct drm_device *dev, void *data,
{
drm_mach64_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1206,7 +1450,7 @@ int mach64_engine_reset(struct drm_device *dev, void *data,
{
drm_mach64_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1228,8 +1472,7 @@ int mach64_init_freelist(struct drm_device * dev)
struct list_head *ptr;
int i;
- DRM_DEBUG("%s: adding %d buffers to freelist\n", __FUNCTION__,
- dma->buf_count);
+ DRM_DEBUG("adding %d buffers to freelist\n", dma->buf_count);
for (i = 0; i < dma->buf_count; i++) {
if ((entry =
@@ -1253,7 +1496,7 @@ void mach64_destroy_freelist(struct drm_device * dev)
struct list_head *ptr;
struct list_head *tmp;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
list_for_each_safe(ptr, tmp, &dev_priv->pending) {
list_del(ptr);
@@ -1276,7 +1519,7 @@ void mach64_destroy_freelist(struct drm_device * dev)
/* IMPORTANT: This function should only be called when the engine is idle or locked up,
* as it assumes all buffers in the pending list have been completed by the hardware.
*/
-int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv)
+int mach64_do_release_used_buffers(drm_mach64_private_t *dev_priv)
{
struct list_head *ptr;
struct list_head *tmp;
@@ -1298,13 +1541,12 @@ int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv)
}
}
- DRM_DEBUG("%s: released %d buffers from pending list\n", __FUNCTION__,
- i);
+ DRM_DEBUG("released %d buffers from pending list\n", i);
return 0;
}
-static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
+static int mach64_do_reclaim_completed(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
struct list_head *ptr;
@@ -1326,8 +1568,7 @@ static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
#endif
/* last pass is complete, so release everything */
mach64_do_release_used_buffers(dev_priv);
- DRM_DEBUG("%s: idle engine, freed all buffers.\n",
- __FUNCTION__);
+ DRM_DEBUG("idle engine, freed all buffers.\n");
if (list_empty(&dev_priv->free_list)) {
DRM_ERROR("Freelist empty with idle engine\n");
return -1;
@@ -1368,9 +1609,9 @@ static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
list_del(ptr);
list_add_tail(ptr, &dev_priv->free_list);
DRM_DEBUG
- ("%s: freed processed buffer (head=%d tail=%d "
+ ("freed processed buffer (head=%d tail=%d "
"buf ring ofs=%d).\n",
- __FUNCTION__, head, tail, ofs);
+ head, tail, ofs);
return 0;
}
}
@@ -1378,7 +1619,7 @@ static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
return 1;
}
-struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv)
+struct drm_buf *mach64_freelist_get(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
drm_mach64_freelist_t *entry;
@@ -1424,7 +1665,7 @@ struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv)
return entry->buf;
}
-int mach64_freelist_put(drm_mach64_private_t * dev_priv, struct drm_buf * copy_buf)
+int mach64_freelist_put(drm_mach64_private_t *dev_priv, struct drm_buf *copy_buf)
{
struct list_head *ptr;
drm_mach64_freelist_t *entry;
@@ -1433,8 +1674,7 @@ int mach64_freelist_put(drm_mach64_private_t * dev_priv, struct drm_buf * copy_b
list_for_each(ptr, &dev_priv->pending) {
entry = list_entry(ptr, drm_mach64_freelist_t, list);
if (copy_buf == entry->buf) {
- DRM_ERROR("%s: Trying to release a pending buf\n",
- __FUNCTION__);
+ DRM_ERROR("Trying to release a pending buf\n");
return -EFAULT;
}
}
diff --git a/sys/dev/pci/drm/mach64_drv.c b/sys/dev/pci/drm/mach64_drv.c
index 9065840850f..ef2ed7a21ef 100644
--- a/sys/dev/pci/drm/mach64_drv.c
+++ b/sys/dev/pci/drm/mach64_drv.c
@@ -51,7 +51,9 @@ mach64_configure(drm_device_t *dev)
{
dev->driver.buf_priv_size = 1; /* No dev_priv */
dev->driver.lastclose = mach64_driver_lastclose;
- dev->driver.vblank_wait = mach64_driver_vblank_wait;
+ dev->driver.get_vblank_counter = mach64_get_vblank_counter;
+ dev->driver.enable_vblank = mach64_enable_vblank;
+ dev->driver.disable_vblank = mach64_disable_vblank;
dev->driver.irq_preinstall = mach64_driver_irq_preinstall;
dev->driver.irq_postinstall = mach64_driver_irq_postinstall;
dev->driver.irq_uninstall = mach64_driver_irq_uninstall;
diff --git a/sys/dev/pci/drm/mach64_drv.h b/sys/dev/pci/drm/mach64_drv.h
index 79c2c61d87c..fb8a772454d 100644
--- a/sys/dev/pci/drm/mach64_drv.h
+++ b/sys/dev/pci/drm/mach64_drv.h
@@ -29,7 +29,7 @@
* Gareth Hughes <gareth@valinux.com>
* Frank C. Earl <fearl@airmail.net>
* Leif Delgass <ldelgass@retinalburn.net>
- * Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
+ * José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
#ifndef __MACH64_DRV_H__
@@ -96,6 +96,8 @@ typedef struct drm_mach64_private {
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
+ atomic_t vbl_received; /**< Number of vblanks received. */
+
u32 front_offset_pitch;
u32 back_offset_pitch;
u32 depth_offset_pitch;
@@ -140,6 +142,11 @@ extern void mach64_dump_engine_info(drm_mach64_private_t * dev_priv);
extern void mach64_dump_ring_info(drm_mach64_private_t * dev_priv);
extern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv);
+extern int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv,
+ drm_mach64_freelist_t *_entry);
+extern int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv,
+ drm_mach64_freelist_t *_entry);
+
extern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv);
extern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv);
extern int mach64_do_cleanup_dma(struct drm_device * dev);
@@ -155,13 +162,14 @@ extern int mach64_dma_blit(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int mach64_get_param(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern int mach64_driver_vblank_wait(struct drm_device * dev,
- unsigned int *sequence);
+extern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc);
+extern int mach64_enable_vblank(struct drm_device *dev, int crtc);
+extern void mach64_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS);
-extern void mach64_driver_irq_preinstall(struct drm_device * dev);
-extern void mach64_driver_irq_postinstall(struct drm_device * dev);
-extern void mach64_driver_irq_uninstall(struct drm_device * dev);
+extern void mach64_driver_irq_preinstall(struct drm_device *dev);
+extern int mach64_driver_irq_postinstall(struct drm_device *dev);
+extern void mach64_driver_irq_uninstall(struct drm_device *dev);
/* ================================================================
* Registers
@@ -521,95 +529,17 @@ extern void mach64_driver_irq_uninstall(struct drm_device * dev);
#define MACH64_APERTURE_OFFSET 0x7ff800 /* frame-buffer offset for gui-masters */
/* ================================================================
- * Misc helper macros
+ * Ring operations
+ *
+ * Since the Mach64 bus master engine requires polling, these functions end
+ * up being called frequently, hence being inline.
*/
-static __inline__ void mach64_set_dma_eol(volatile u32 * addr)
-{
-#if defined(__i386__)
- int nr = 31;
-
- /* Taken from include/asm-i386/bitops.h linux header */
- __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr)
- :"Ir"(nr));
-#elif defined(__powerpc__)
- u32 old;
- u32 mask = cpu_to_le32(MACH64_DMA_EOL);
-
- /* Taken from the include/asm-ppc/bitops.h linux header */
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3 \n\
- or %0,%0,%2 \n\
- stwcx. %0,0,%3 \n\
- bne- 1b":"=&r"(old), "=m"(*addr)
- :"r"(mask), "r"(addr), "m"(*addr)
- :"cc");
-#elif defined(__alpha__)
- u32 temp;
- u32 mask = MACH64_DMA_EOL;
-
- /* Taken from the include/asm-alpha/bitops.h linux header */
- __asm__ __volatile__("1: ldl_l %0,%3\n"
- " bis %0,%2,%0\n"
- " stl_c %0,%1\n"
- " beq %0,2f\n"
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous":"=&r"(temp), "=m"(*addr)
- :"Ir"(mask), "m"(*addr));
-#else
- u32 mask = cpu_to_le32(MACH64_DMA_EOL);
-
- *addr |= mask;
-#endif
-}
-
-static __inline__ void mach64_clear_dma_eol(volatile u32 * addr)
-{
-#if defined(__i386__)
- int nr = 31;
-
- /* Taken from include/asm-i386/bitops.h linux header */
- __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr)
- :"Ir"(nr));
-#elif defined(__powerpc__)
- u32 old;
- u32 mask = cpu_to_le32(MACH64_DMA_EOL);
-
- /* Taken from the include/asm-ppc/bitops.h linux header */
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3 \n\
- andc %0,%0,%2 \n\
- stwcx. %0,0,%3 \n\
- bne- 1b":"=&r"(old), "=m"(*addr)
- :"r"(mask), "r"(addr), "m"(*addr)
- :"cc");
-#elif defined(__alpha__)
- u32 temp;
- u32 mask = ~MACH64_DMA_EOL;
-
- /* Taken from the include/asm-alpha/bitops.h linux header */
- __asm__ __volatile__("1: ldl_l %0,%3\n"
- " and %0,%2,%0\n"
- " stl_c %0,%1\n"
- " beq %0,2f\n"
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous":"=&r"(temp), "=m"(*addr)
- :"Ir"(mask), "m"(*addr));
-#else
- u32 mask = cpu_to_le32(~MACH64_DMA_EOL);
-
- *addr &= mask;
-#endif
-}
-
static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
ring->head_addr, ring->head, ring->tail, ring->space);
if (mach64_do_wait_for_idle(dev_priv) < 0) {
@@ -635,8 +565,7 @@ static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv)
static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
drm_mach64_descriptor_ring_t * ring)
{
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
ring->head_addr, ring->head, ring->tail, ring->space);
/* reset descriptor table ring head */
@@ -655,8 +584,7 @@ static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0);
if (dev_priv->driver_mode == MACH64_MODE_DMA_SYNC) {
if ((mach64_do_wait_for_idle(dev_priv)) < 0) {
- DRM_ERROR("%s: idle failed, resetting engine\n",
- __FUNCTION__);
+ DRM_ERROR("idle failed, resetting engine\n");
mach64_dump_engine_info(dev_priv);
mach64_do_engine_reset(dev_priv);
return;
@@ -666,11 +594,22 @@ static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
}
}
+/**
+ * Poll the ring head and make sure the bus master is alive.
+ *
+ * Mach64's bus master engine will stop if there are no more entries to process.
+ * This function polls the engine for the last processed entry and calls
+ * mach64_ring_resume if there is an unprocessed entry.
+ *
+ * Note also that, since we update the ring tail while the bus master engine is
+ * in operation, it is possible that the last tail update was too late to be
+ * processed, and the bus master engine stops at the previous tail position.
+ * Therefore it is important to call this function frequently.
+ */
static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv,
drm_mach64_descriptor_ring_t * ring)
{
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
ring->head_addr, ring->head, ring->tail, ring->space);
if (!dev_priv->ring_running) {
@@ -717,8 +656,7 @@ static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv,
static __inline__ void mach64_ring_stop(drm_mach64_private_t * dev_priv)
{
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
dev_priv->ring.head_addr, dev_priv->ring.head,
dev_priv->ring.tail, dev_priv->ring.space);
@@ -739,7 +677,7 @@ mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
mach64_ring_tick(dev_priv, ring);
@@ -750,60 +688,12 @@ mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv)
}
/* ================================================================
- * DMA descriptor ring macros
- */
-
-#define RING_LOCALS \
- int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring
-
-#define RING_WRITE_OFS _ring_write
-
-#define BEGIN_RING( n ) \
-do { \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
- (n), __FUNCTION__ ); \
- } \
- if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
- int ret; \
- if ((ret=mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \
- DRM_ERROR( "wait_ring failed, resetting engine\n"); \
- mach64_dump_engine_info( dev_priv ); \
- mach64_do_engine_reset( dev_priv ); \
- return ret; \
- } \
- } \
- dev_priv->ring.space -= (n) * sizeof(u32); \
- _ring = (u32 *) dev_priv->ring.start; \
- _ring_tail = _ring_write = dev_priv->ring.tail; \
- _ring_mask = dev_priv->ring.tail_mask; \
-} while (0)
-
-#define OUT_RING( x ) \
-do { \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
- (unsigned int)(x), _ring_write ); \
- } \
- _ring[_ring_write++] = cpu_to_le32( x ); \
- _ring_write &= _ring_mask; \
-} while (0)
-
-#define ADVANCE_RING() \
-do { \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
- _ring_write, _ring_tail ); \
- } \
- DRM_MEMORYBARRIER(); \
- mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \
- DRM_MEMORYBARRIER(); \
- dev_priv->ring.tail = _ring_write; \
- mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \
-} while (0)
-
-/* ================================================================
* DMA macros
+ *
+ * Mach64's ring buffer doesn't take register writes directly. These
+ * have to be written indirectly in DMA buffers. These macros simplify
+ * the task of setting up a buffer, writing commands to it, and
+ * queuing the buffer in the ring.
*/
#define DMALOCALS \
@@ -828,7 +718,7 @@ static __inline__ int mach64_find_pending_buf_entry(drm_mach64_private_t *
struct list_head *ptr;
#if MACH64_EXTRA_CHECKING
if (list_empty(&dev_priv->pending)) {
- DRM_ERROR("Empty pending list in %s\n", __FUNCTION__);
+ DRM_ERROR("Empty pending list in \n");
return -EINVAL;
}
#endif
@@ -855,18 +745,15 @@ do { \
#define DMAGETPTR( file_priv, dev_priv, n ) \
do { \
if ( MACH64_VERBOSE ) { \
- DRM_INFO( "DMAGETPTR( %d ) in %s\n", \
- n, __FUNCTION__ ); \
+ DRM_INFO( "DMAGETPTR( %d )\n", (n) ); \
} \
_buf = mach64_freelist_get( dev_priv ); \
if (_buf == NULL) { \
- DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", \
- __FUNCTION__ ); \
+ DRM_ERROR("couldn't get buffer in DMAGETPTR\n"); \
return -EAGAIN; \
} \
if (_buf->pending) { \
- DRM_ERROR("%s: pending buf in DMAGETPTR\n", \
- __FUNCTION__ ); \
+ DRM_ERROR("pending buf in DMAGETPTR\n"); \
return -EFAULT; \
} \
_buf->file_priv = file_priv; \
@@ -886,173 +773,87 @@ do { \
_buf->used += 8; \
} while (0)
-#define DMAADVANCE( dev_priv, _discard ) \
-do { \
- struct list_head *ptr; \
- RING_LOCALS; \
- \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( "DMAADVANCE() in %s\n", __FUNCTION__ ); \
- } \
- \
- if (_buf->used <= 0) { \
- DRM_ERROR( "DMAADVANCE() in %s: sending empty buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return -EFAULT; \
- } \
- if (_buf->pending) { \
- /* This is a resued buffer, so we need to find it in the pending list */ \
- int ret; \
- if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) { \
- DRM_ERROR( "DMAADVANCE() in %s: couldn't find pending buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return ret; \
- } \
- if (_entry->discard) { \
- DRM_ERROR( "DMAADVANCE() in %s: sending discarded pending buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return -EFAULT; \
- } \
- } else { \
- if (list_empty(&dev_priv->placeholders)) { \
- DRM_ERROR( "DMAADVANCE() in %s: empty placeholder list\n", \
- __FUNCTION__ ); \
- return -EFAULT; \
- } \
- ptr = dev_priv->placeholders.next; \
- list_del(ptr); \
- _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
- _buf->pending = 1; \
- _entry->buf = _buf; \
- list_add_tail(ptr, &dev_priv->pending); \
- } \
- _entry->discard = (_discard); \
- ADD_BUF_TO_RING( dev_priv ); \
-} while (0)
-
-#define DMADISCARDBUF() \
-do { \
- if (_entry == NULL) { \
- int ret; \
- if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) { \
- DRM_ERROR( "%s: couldn't find pending buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return ret; \
- } \
- } \
- _entry->discard = 1; \
-} while(0)
-
-#define ADD_BUF_TO_RING( dev_priv ) \
-do { \
- int bytes, pages, remainder; \
- u32 address, page; \
- int i; \
- \
- bytes = _buf->used; \
- address = GETBUFADDR( _buf ); \
- \
- pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; \
- \
- BEGIN_RING( pages * 4 ); \
- \
- for ( i = 0 ; i < pages-1 ; i++ ) { \
- page = address + i * MACH64_DMA_CHUNKSIZE; \
- OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); \
- OUT_RING( page ); \
- OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); \
- OUT_RING( 0 ); \
- } \
- \
- /* generate the final descriptor for any remaining commands in this buffer */ \
- page = address + i * MACH64_DMA_CHUNKSIZE; \
- remainder = bytes - i * MACH64_DMA_CHUNKSIZE; \
- \
- /* Save dword offset of last descriptor for this buffer. \
- * This is needed to check for completion of the buffer in freelist_get \
- */ \
- _entry->ring_ofs = RING_WRITE_OFS; \
- \
- OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); \
- OUT_RING( page ); \
- OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); \
- OUT_RING( 0 ); \
- \
- ADVANCE_RING(); \
-} while(0)
-
-#define DMAADVANCEHOSTDATA( dev_priv ) \
-do { \
- struct list_head *ptr; \
- RING_LOCALS; \
- \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( "DMAADVANCEHOSTDATA() in %s\n", __FUNCTION__ ); \
- } \
- \
- if (_buf->used <= 0) { \
- DRM_ERROR( "DMAADVANCEHOSTDATA() in %s: sending empty buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return -EFAULT; \
- } \
- if (list_empty(&dev_priv->placeholders)) { \
- DRM_ERROR( "%s: empty placeholder list in DMAADVANCEHOSTDATA()\n", \
- __FUNCTION__ ); \
- return -EFAULT; \
- } \
- \
- ptr = dev_priv->placeholders.next; \
- list_del(ptr); \
- _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
- _entry->buf = _buf; \
- _entry->buf->pending = 1; \
- list_add_tail(ptr, &dev_priv->pending); \
- _entry->discard = 1; \
- ADD_HOSTDATA_BUF_TO_RING( dev_priv ); \
-} while (0)
-
-#define ADD_HOSTDATA_BUF_TO_RING( dev_priv ) \
-do { \
- int bytes, pages, remainder; \
- u32 address, page; \
- int i; \
- \
- bytes = _buf->used - MACH64_HOSTDATA_BLIT_OFFSET; \
- pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; \
- address = GETBUFADDR( _buf ); \
- \
- BEGIN_RING( 4 + pages * 4 ); \
- \
- OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); \
- OUT_RING( address ); \
- OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET ); \
- OUT_RING( 0 ); \
- \
- address += MACH64_HOSTDATA_BLIT_OFFSET; \
- \
- for ( i = 0 ; i < pages-1 ; i++ ) { \
- page = address + i * MACH64_DMA_CHUNKSIZE; \
- OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); \
- OUT_RING( page ); \
- OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); \
- OUT_RING( 0 ); \
- } \
- \
- /* generate the final descriptor for any remaining commands in this buffer */ \
- page = address + i * MACH64_DMA_CHUNKSIZE; \
- remainder = bytes - i * MACH64_DMA_CHUNKSIZE; \
- \
- /* Save dword offset of last descriptor for this buffer. \
- * This is needed to check for completion of the buffer in freelist_get \
- */ \
- _entry->ring_ofs = RING_WRITE_OFS; \
- \
- OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); \
- OUT_RING( page ); \
- OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); \
- OUT_RING( 0 ); \
- \
- ADVANCE_RING(); \
-} while(0)
+#define DMAADVANCE( dev_priv, _discard ) \
+ do { \
+ struct list_head *ptr; \
+ int ret; \
+ \
+ if ( MACH64_VERBOSE ) { \
+ DRM_INFO( "DMAADVANCE() in \n" ); \
+ } \
+ \
+ if (_buf->used <= 0) { \
+ DRM_ERROR( "DMAADVANCE(): sending empty buf %d\n", \
+ _buf->idx ); \
+ return -EFAULT; \
+ } \
+ if (_buf->pending) { \
+ /* This is a resued buffer, so we need to find it in the pending list */ \
+ if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \
+ DRM_ERROR( "DMAADVANCE(): couldn't find pending buf %d\n", _buf->idx ); \
+ return ret; \
+ } \
+ if (_entry->discard) { \
+ DRM_ERROR( "DMAADVANCE(): sending discarded pending buf %d\n", _buf->idx ); \
+ return -EFAULT; \
+ } \
+ } else { \
+ if (list_empty(&dev_priv->placeholders)) { \
+ DRM_ERROR( "DMAADVANCE(): empty placeholder list\n"); \
+ return -EFAULT; \
+ } \
+ ptr = dev_priv->placeholders.next; \
+ list_del(ptr); \
+ _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
+ _buf->pending = 1; \
+ _entry->buf = _buf; \
+ list_add_tail(ptr, &dev_priv->pending); \
+ } \
+ _entry->discard = (_discard); \
+ if ((ret = mach64_add_buf_to_ring( dev_priv, _entry ))) \
+ return ret; \
+ } while (0)
+
+#define DMADISCARDBUF() \
+ do { \
+ if (_entry == NULL) { \
+ int ret; \
+ if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \
+ DRM_ERROR( "couldn't find pending buf %d\n", \
+ _buf->idx ); \
+ return ret; \
+ } \
+ } \
+ _entry->discard = 1; \
+ } while(0)
+
+#define DMAADVANCEHOSTDATA( dev_priv ) \
+ do { \
+ struct list_head *ptr; \
+ int ret; \
+ \
+ if ( MACH64_VERBOSE ) { \
+ DRM_INFO( "DMAADVANCEHOSTDATA() in \n" ); \
+ } \
+ \
+ if (_buf->used <= 0) { \
+ DRM_ERROR( "DMAADVANCEHOSTDATA(): sending empty buf %d\n", _buf->idx ); \
+ return -EFAULT; \
+ } \
+ if (list_empty(&dev_priv->placeholders)) { \
+ DRM_ERROR( "empty placeholder list in DMAADVANCEHOSTDATA()\n" ); \
+ return -EFAULT; \
+ } \
+ \
+ ptr = dev_priv->placeholders.next; \
+ list_del(ptr); \
+ _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
+ _entry->buf = _buf; \
+ _entry->buf->pending = 1; \
+ list_add_tail(ptr, &dev_priv->pending); \
+ _entry->discard = 1; \
+ if ((ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry ))) \
+ return ret; \
+ } while (0)
#endif /* __MACH64_DRV_H__ */
diff --git a/sys/dev/pci/drm/mach64_irq.c b/sys/dev/pci/drm/mach64_irq.c
index 4122dd9109d..57879e8d74c 100644
--- a/sys/dev/pci/drm/mach64_irq.c
+++ b/sys/dev/pci/drm/mach64_irq.c
@@ -42,9 +42,8 @@
irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS)
{
- struct drm_device *dev = (struct drm_device *) arg;
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+ struct drm_device *dev = arg;
+ drm_mach64_private_t *dev_priv = dev->dev_private;
int status;
status = MACH64_READ(MACH64_CRTC_INT_CNTL);
@@ -62,74 +61,98 @@ irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS)
(status & ~MACH64_CRTC_INT_ACKS)
| MACH64_CRTC_VBLANK_INT);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
-int mach64_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+u32 mach64_get_vblank_counter(struct drm_device * dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ const drm_mach64_private_t *const dev_priv = dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
+int mach64_enable_vblank(struct drm_device * dev, int crtc)
+{
+ drm_mach64_private_t *dev_priv = dev->dev_private;
+ u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL);
+
+ if (crtc != 0) {
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("before enable vblank CRTC_INT_CTNL: 0x%08x\n", status);
- *sequence = cur_vblank;
+ /* Turn on VBLANK interrupt */
+ MACH64_WRITE(MACH64_CRTC_INT_CNTL, MACH64_READ(MACH64_CRTC_INT_CNTL)
+ | MACH64_CRTC_VBLANK_INT_EN);
- return ret;
+ return 0;
}
-/* drm_dma.h hooks
-*/
-void mach64_driver_irq_preinstall(struct drm_device * dev)
+void mach64_disable_vblank(struct drm_device * dev, int crtc)
{
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+ if (crtc != 0) {
+ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
+ crtc);
+ return;
+ }
+
+ /*
+ * FIXME: implement proper interrupt disable by using the vblank
+ * counter register (if available).
+ */
+}
+static void mach64_disable_vblank_local(struct drm_device * dev, int crtc)
+{
+ drm_mach64_private_t *dev_priv = dev->dev_private;
u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL);
- DRM_DEBUG("before install CRTC_INT_CTNL: 0x%08x\n", status);
+ if (crtc != 0) {
+ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
+ crtc);
+ return;
+ }
+
+ DRM_DEBUG("before disable vblank CRTC_INT_CTNL: 0x%08x\n", status);
/* Disable and clear VBLANK interrupt */
MACH64_WRITE(MACH64_CRTC_INT_CNTL, (status & ~MACH64_CRTC_VBLANK_INT_EN)
| MACH64_CRTC_VBLANK_INT);
}
-void mach64_driver_irq_postinstall(struct drm_device * dev)
+void mach64_driver_irq_preinstall(struct drm_device * dev)
{
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+ drm_mach64_private_t *dev_priv = dev->dev_private;
- /* Turn on VBLANK interrupt */
- MACH64_WRITE(MACH64_CRTC_INT_CNTL, MACH64_READ(MACH64_CRTC_INT_CNTL)
- | MACH64_CRTC_VBLANK_INT_EN);
+ u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL);
- DRM_DEBUG("after install CRTC_INT_CTNL: 0x%08x\n",
- MACH64_READ(MACH64_CRTC_INT_CNTL));
+ DRM_DEBUG("before install CRTC_INT_CTNL: 0x%08x\n", status);
+
+ mach64_disable_vblank_local(dev, 0);
+}
+int mach64_driver_irq_postinstall(struct drm_device * dev)
+{
+ return drm_vblank_init(dev, 1);
}
void mach64_driver_irq_uninstall(struct drm_device * dev)
{
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+ drm_mach64_private_t *dev_priv = dev->dev_private;
if (!dev_priv)
return;
- /* Disable and clear VBLANK interrupt */
- MACH64_WRITE(MACH64_CRTC_INT_CNTL,
- (MACH64_READ(MACH64_CRTC_INT_CNTL) &
- ~MACH64_CRTC_VBLANK_INT_EN)
- | MACH64_CRTC_VBLANK_INT);
+ mach64_disable_vblank_local(dev, 0);
DRM_DEBUG("after uninstall CRTC_INT_CTNL: 0x%08x\n",
MACH64_READ(MACH64_CRTC_INT_CNTL));
diff --git a/sys/dev/pci/drm/mach64_state.c b/sys/dev/pci/drm/mach64_state.c
index 89b6c6cee0c..c82f38bb2a5 100644
--- a/sys/dev/pci/drm/mach64_state.c
+++ b/sys/dev/pci/drm/mach64_state.c
@@ -27,7 +27,7 @@
* Authors:
* Gareth Hughes <gareth@valinux.com>
* Leif Delgass <ldelgass@retinalburn.net>
- * Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
+ * José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
#include "drmP.h"
@@ -95,7 +95,7 @@ static int mach64_emit_cliprect(struct drm_file *file_priv,
drm_mach64_context_regs_t *regs = &sarea_priv->context_state;
DMALOCALS;
- DRM_DEBUG("%s: box=%p\n", __FUNCTION__, box);
+ DRM_DEBUG("box=%p\n", box);
/* Get GL scissor */
/* FIXME: store scissor in SAREA as a cliprect instead of in
@@ -146,7 +146,7 @@ static __inline__ int mach64_emit_state(struct drm_file *file_priv,
if (MACH64_VERBOSE) {
mach64_print_dirty(__FUNCTION__, dirty);
} else {
- DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty);
+ DRM_DEBUG("dirty=0x%08x\n", dirty);
}
DMAGETPTR(file_priv, dev_priv, 17); /* returns on failure to get buffer */
@@ -229,7 +229,7 @@ static int mach64_dma_dispatch_clear(struct drm_device * dev,
int i;
DMALOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
switch (dev_priv->fb_bpp) {
case 16:
@@ -368,7 +368,7 @@ static int mach64_dma_dispatch_swap(struct drm_device * dev,
int i;
DMALOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
switch (dev_priv->fb_bpp) {
case 16:
@@ -445,7 +445,7 @@ static int mach64_do_get_frames_queued(drm_mach64_private_t * dev_priv)
int i, start;
u32 head, tail, ofs;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (sarea_priv->frames_queued == 0)
return 0;
@@ -525,15 +525,14 @@ static __inline__ int copy_from_user_vertex(u32 *to,
from += count;
to += count;
} else {
- DRM_ERROR("%s: Got bad command: 0x%04x\n",
- __FUNCTION__, reg);
+ DRM_ERROR("Got bad command: 0x%04x\n", reg);
drm_free(orig_from, bytes, DRM_MEM_DRIVER);
return -EACCES;
}
} else {
DRM_ERROR
- ("%s: Got bad command count(=%u) dwords remaining=%lu\n",
- __FUNCTION__, count, n);
+ ("Got bad command count(=%u) dwords remaining=%lu\n",
+ count, n);
drm_free(orig_from, bytes, DRM_MEM_DRIVER);
return -EINVAL;
}
@@ -543,7 +542,7 @@ static __inline__ int copy_from_user_vertex(u32 *to,
if (n == 0)
return 0;
else {
- DRM_ERROR("%s: Bad buf->used(=%lu)\n", __FUNCTION__, bytes);
+ DRM_ERROR("Bad buf->used(=%lu)\n", bytes);
return -EINVAL;
}
}
@@ -563,18 +562,22 @@ static int mach64_dma_dispatch_vertex(struct drm_device * dev,
int verify_ret = 0;
DMALOCALS;
- DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n",
- __FUNCTION__, buf, used, sarea_priv->nbox);
+ DRM_DEBUG("buf=%p used=%lu nbox=%d\n",
+ buf, used, sarea_priv->nbox);
if (!used)
goto _vertex_done;
copy_buf = mach64_freelist_get(dev_priv);
if (copy_buf == NULL) {
- DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__);
+ DRM_ERROR("couldn't get buffer\n");
return -EAGAIN;
}
+ /* Mach64's vertex data is actually register writes. To avoid security
+ * compromises these register writes have to be verified and copied from
+ * user space into a private DMA buffer.
+ */
verify_ret = copy_from_user_vertex(GETBUFPTR(copy_buf), buf, used);
if (verify_ret != 0) {
@@ -694,10 +697,20 @@ static int mach64_dma_dispatch_blit(struct drm_device * dev,
copy_buf = mach64_freelist_get(dev_priv);
if (copy_buf == NULL) {
- DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__);
+ DRM_ERROR("couldn't get buffer\n");
return -EAGAIN;
}
+ /* Copy the blit data from userspace.
+ *
+ * XXX: This is overkill. The most efficient solution would be having
+ * two sets of buffers (one set private for vertex data, the other set
+ * client-writable for blits). However that would bring more complexity
+ * and would break backward compatability. The solution currently
+ * implemented is keeping all buffers private, allowing to secure the
+ * driver, without increasing complexity at the expense of some speed
+ * transfering data.
+ */
verify_ret = copy_from_user_blit(GETBUFPTR(copy_buf), blit->buf, used);
if (verify_ret != 0) {
@@ -745,7 +758,7 @@ static int mach64_dma_dispatch_blit(struct drm_device * dev,
DMAOUTREG(MACH64_DST_X_Y, (blit->y << 16) | blit->x);
DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (blit->height << 16) | blit->width);
- DRM_DEBUG("%s: %lu bytes\n", __FUNCTION__, used);
+ DRM_DEBUG("%lu bytes\n", used);
/* Add the buffer to the queue */
DMAADVANCEHOSTDATA(dev_priv);
@@ -766,7 +779,7 @@ int mach64_dma_clear(struct drm_device *dev, void *data,
drm_mach64_clear_t *clear = data;
int ret;
- DRM_DEBUG("%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID);
+ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -791,7 +804,7 @@ int mach64_dma_swap(struct drm_device *dev, void *data,
drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv;
int ret;
- DRM_DEBUG("%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID);
+ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -816,12 +829,12 @@ int mach64_dma_vertex(struct drm_device *dev, void *data,
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- DRM_DEBUG("%s: pid=%d buf=%p used=%lu discard=%d\n",
- __FUNCTION__, DRM_CURRENTPID,
+ DRM_DEBUG("pid=%d buf=%p used=%lu discard=%d\n",
+ DRM_CURRENTPID,
vertex->buf, vertex->used, vertex->discard);
if (vertex->prim < 0 || vertex->prim > MACH64_PRIM_POLYGON) {
@@ -868,10 +881,10 @@ int mach64_get_param(struct drm_device *dev, void *data,
drm_mach64_getparam_t *param = data;
int value;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/sys/dev/pci/drm/mga_dma.c b/sys/dev/pci/drm/mga_dma.c
index 44b14945b28..d56f4d7a7e4 100644
--- a/sys/dev/pci/drm/mga_dma.c
+++ b/sys/dev/pci/drm/mga_dma.c
@@ -46,7 +46,7 @@
#define MINIMAL_CLEANUP 0
#define FULL_CLEANUP 1
-static int mga_do_cleanup_dma(struct drm_device * dev, int full_cleanup);
+static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup);
/* ================================================================
* Engine control
@@ -395,7 +395,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
int mga_driver_load(struct drm_device *dev, unsigned long flags)
{
- drm_mga_private_t * dev_priv;
+ drm_mga_private_t *dev_priv;
dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
if (!dev_priv)
@@ -436,10 +436,11 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags)
static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
drm_mga_dma_bootstrap_t * dma_bs)
{
- drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
+ drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *)dev->dev_private;
unsigned int warp_size = mga_warp_microcode_size(dev_priv);
int err;
- unsigned offset;
+ unsigned offset;
const unsigned secondary_size = dma_bs->secondary_bin_count
* dma_bs->secondary_bin_size;
const unsigned agp_size = (dma_bs->agp_size << 20);
@@ -481,11 +482,10 @@ static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
}
}
-
/* Allocate and bind AGP memory. */
agp_req.size = agp_size;
agp_req.type = 0;
- err = drm_agp_alloc( dev, & agp_req );
+ err = drm_agp_alloc(dev, &agp_req);
if (err) {
dev_priv->agp_size = 0;
DRM_ERROR("Unable to allocate %uMB AGP memory\n",
@@ -511,36 +511,36 @@ static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
warp_size = PAGE_SIZE;
offset = 0;
- err = drm_addmap( dev, offset, warp_size,
- _DRM_AGP, _DRM_READ_ONLY, & dev_priv->warp );
+ err = drm_addmap(dev, offset, warp_size,
+ _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
if (err) {
DRM_ERROR("Unable to map WARP microcode: %d\n", err);
return err;
}
offset += warp_size;
- err = drm_addmap( dev, offset, dma_bs->primary_size,
- _DRM_AGP, _DRM_READ_ONLY, & dev_priv->primary );
+ err = drm_addmap(dev, offset, dma_bs->primary_size,
+ _DRM_AGP, _DRM_READ_ONLY, & dev_priv->primary);
if (err) {
DRM_ERROR("Unable to map primary DMA region: %d\n", err);
return err;
}
offset += dma_bs->primary_size;
- err = drm_addmap( dev, offset, secondary_size,
- _DRM_AGP, 0, & dev->agp_buffer_map );
+ err = drm_addmap(dev, offset, secondary_size,
+ _DRM_AGP, 0, & dev->agp_buffer_map);
if (err) {
DRM_ERROR("Unable to map secondary DMA region: %d\n", err);
return err;
}
- (void) memset( &req, 0, sizeof(req) );
+ (void)memset( &req, 0, sizeof(req) );
req.count = dma_bs->secondary_bin_count;
req.size = dma_bs->secondary_bin_size;
req.flags = _DRM_AGP_BUFFER;
req.agp_start = offset;
- err = drm_addbufs_agp( dev, & req );
+ err = drm_addbufs_agp(dev, &req);
if (err) {
DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
return err;
@@ -563,8 +563,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
#endif
offset += secondary_size;
- err = drm_addmap( dev, offset, agp_size - offset,
- _DRM_AGP, 0, & dev_priv->agp_textures );
+ err = drm_addmap(dev, offset, agp_size - offset,
+ _DRM_AGP, 0, & dev_priv->agp_textures);
if (err) {
DRM_ERROR("Unable to map AGP texture region: %d\n", err);
return err;
@@ -606,7 +606,8 @@ static int mga_do_agp_dma_bootstrap(struct drm_device *dev,
static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
drm_mga_dma_bootstrap_t * dma_bs)
{
- drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private;
+ drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
unsigned int warp_size = mga_warp_microcode_size(dev_priv);
unsigned int primary_size;
unsigned int bin_count;
@@ -639,9 +640,8 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
* alignment of the primary or secondary DMA buffers.
*/
- for ( primary_size = dma_bs->primary_size
- ; primary_size != 0
- ; primary_size >>= 1 ) {
+ for (primary_size = dma_bs->primary_size; primary_size != 0;
+ primary_size >>= 1 ) {
/* The proper alignment for this mapping is 0x04 */
err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
_DRM_READ_ONLY, &dev_priv->primary);
@@ -657,18 +657,17 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
if (dev_priv->primary->size != dma_bs->primary_size) {
DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
dma_bs->primary_size,
- (unsigned) dev_priv->primary->size);
+ (unsigned)dev_priv->primary->size);
dma_bs->primary_size = dev_priv->primary->size;
}
- for ( bin_count = dma_bs->secondary_bin_count
- ; bin_count > 0
- ; bin_count-- ) {
- (void) memset( &req, 0, sizeof(req) );
+ for (bin_count = dma_bs->secondary_bin_count; bin_count > 0;
+ bin_count-- ) {
+ (void)memset(&req, 0, sizeof(req));
req.count = bin_count;
req.size = dma_bs->secondary_bin_size;
- err = drm_addbufs_pci( dev, & req );
+ err = drm_addbufs_pci(dev, &req);
if (!err) {
break;
}
@@ -696,12 +695,12 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
}
-static int mga_do_dma_bootstrap(struct drm_device * dev,
- drm_mga_dma_bootstrap_t * dma_bs)
+static int mga_do_dma_bootstrap(struct drm_device *dev,
+ drm_mga_dma_bootstrap_t *dma_bs)
{
const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev);
int err;
- drm_mga_private_t * const dev_priv =
+ drm_mga_private_t *const dev_priv =
(drm_mga_private_t *) dev->dev_private;
@@ -710,17 +709,17 @@ static int mga_do_dma_bootstrap(struct drm_device * dev,
/* The first steps are the same for both PCI and AGP based DMA. Map
* the cards MMIO registers and map a status page.
*/
- err = drm_addmap( dev, dev_priv->mmio_base, dev_priv->mmio_size,
- _DRM_REGISTERS, _DRM_READ_ONLY, & dev_priv->mmio );
+ err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
+ _DRM_REGISTERS, _DRM_READ_ONLY, & dev_priv->mmio);
if (err) {
DRM_ERROR("Unable to map MMIO region: %d\n", err);
return err;
}
- err = drm_addmap( dev, 0, SAREA_MAX, _DRM_SHM,
- _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
- & dev_priv->status );
+ err = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
+ _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
+ & dev_priv->status);
if (err) {
DRM_ERROR("Unable to map status region: %d\n", err);
return err;
@@ -768,7 +767,7 @@ int mga_dma_bootstrap(struct drm_device *dev, void *data,
drm_mga_dma_bootstrap_t *bootstrap = data;
int err;
static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
- const drm_mga_private_t * const dev_priv =
+ const drm_mga_private_t *const dev_priv =
(drm_mga_private_t *) dev->dev_private;
@@ -829,7 +828,7 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
return -EINVAL;
}
- if (! dev_priv->used_new_dma_init) {
+ if (!dev_priv->used_new_dma_init) {
dev_priv->dma_access = MGA_PAGPXFER;
dev_priv->wagp_enable = MGA_WAGP_ENABLE;
@@ -855,7 +854,8 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
return -EINVAL;
}
dev->agp_buffer_token = init->buffers_offset;
- dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ dev->agp_buffer_map =
+ drm_core_findmap(dev, init->buffers_offset);
if (!dev->agp_buffer_map) {
DRM_ERROR("failed to find dma buffer region!\n");
return -EINVAL;
@@ -898,10 +898,6 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
/* Init the primary DMA registers.
*/
MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL);
-#if 0
- MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */
- MGA_PRIMPTREN1); /* DWGSYNC */
-#endif
dev_priv->prim.start = (u8 *) dev_priv->primary->handle;
dev_priv->prim.end = ((u8 *) dev_priv->primary->handle
@@ -932,7 +928,7 @@ static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
return 0;
}
-static int mga_do_cleanup_dma(struct drm_device * dev, int full_cleanup)
+static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
{
int err = 0;
DRM_DEBUG("\n");
@@ -993,14 +989,15 @@ static int mga_do_cleanup_dma(struct drm_device * dev, int full_cleanup)
memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
dev_priv->warp_pipe = 0;
- memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
+ memset(dev_priv->warp_pipe_phys, 0,
+ sizeof(dev_priv->warp_pipe_phys));
if (dev_priv->head != NULL) {
mga_freelist_cleanup(dev);
}
}
- return 0;
+ return err;
}
int mga_dma_init(struct drm_device *dev, void *data,
@@ -1015,7 +1012,7 @@ int mga_dma_init(struct drm_device *dev, void *data,
case MGA_INIT_DMA:
err = mga_do_init_dma(dev, init);
if (err) {
- (void) mga_do_cleanup_dma(dev, FULL_CLEANUP);
+ (void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
}
return err;
case MGA_CLEANUP_DMA:
@@ -1052,7 +1049,7 @@ int mga_dma_flush(struct drm_device *dev, void *data,
#if MGA_DMA_DEBUG
int ret = mga_do_wait_for_idle(dev_priv);
if (ret < 0)
- DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
+ DRM_INFO("-EBUSY\n");
return ret;
#else
return mga_do_wait_for_idle(dev_priv);
diff --git a/sys/dev/pci/drm/mga_drv.c b/sys/dev/pci/drm/mga_drv.c
index d18a7845063..c3029c1ea19 100644
--- a/sys/dev/pci/drm/mga_drv.c
+++ b/sys/dev/pci/drm/mga_drv.c
@@ -98,7 +98,9 @@ mga_configure(drm_device_t *dev)
dev->driver.load = mga_driver_load;
dev->driver.unload = mga_driver_unload;
dev->driver.lastclose = mga_driver_lastclose;
- dev->driver.vblank_wait = mga_driver_vblank_wait;
+ dev->driver.enable_vblank = mga_enable_vblank;
+ dev->driver.disable_vblank = mga_disable_vblank;
+ dev->driver.get_vblank_counter = mga_get_vblank_counter;
dev->driver.irq_preinstall = mga_driver_irq_preinstall;
dev->driver.irq_postinstall = mga_driver_irq_postinstall;
dev->driver.irq_uninstall = mga_driver_irq_uninstall;
diff --git a/sys/dev/pci/drm/mga_drv.h b/sys/dev/pci/drm/mga_drv.h
index 0c7fab5b516..bf3be808297 100644
--- a/sys/dev/pci/drm/mga_drv.h
+++ b/sys/dev/pci/drm/mga_drv.h
@@ -113,13 +113,14 @@ typedef struct drm_mga_private {
* \sa drm_mga_private_t::mmio
*/
/*@{*/
- u32 mmio_base; /**< Bus address of base of MMIO. */
- u32 mmio_size; /**< Size of the MMIO region. */
+ u32 mmio_base; /**< Bus address of base of MMIO. */
+ u32 mmio_size; /**< Size of the MMIO region. */
/*@}*/
u32 clear_cmd;
u32 maccess;
+ atomic_t vbl_received; /**< Number of vblanks received. */
wait_queue_head_t fence_queue;
atomic_t last_fence_retired;
u32 next_fence_to_post;
@@ -181,11 +182,14 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
extern int mga_warp_init(drm_mga_private_t * dev_priv);
/* mga_irq.c */
+extern int mga_enable_vblank(struct drm_device *dev, int crtc);
+extern void mga_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
extern void mga_driver_irq_preinstall(struct drm_device * dev);
-extern void mga_driver_irq_postinstall(struct drm_device * dev);
+extern int mga_driver_irq_postinstall(struct drm_device * dev);
extern void mga_driver_irq_uninstall(struct drm_device * dev);
extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
@@ -249,7 +253,7 @@ do { \
} else if ( dev_priv->prim.space < \
dev_priv->prim.high_mark ) { \
if ( MGA_DMA_DEBUG ) \
- DRM_INFO( "%s: wrap...\n", __FUNCTION__ ); \
+ DRM_INFO( "wrap...\n"); \
return -EBUSY; \
} \
} \
@@ -260,7 +264,7 @@ do { \
if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \
if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \
if ( MGA_DMA_DEBUG ) \
- DRM_INFO( "%s: wrap...\n", __FUNCTION__ ); \
+ DRM_INFO( "wrap...\n"); \
return -EBUSY; \
} \
mga_do_dma_wrap_end( dev_priv ); \
@@ -280,8 +284,7 @@ do { \
#define BEGIN_DMA( n ) \
do { \
if ( MGA_VERBOSE ) { \
- DRM_INFO( "BEGIN_DMA( %d ) in %s\n", \
- (n), __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_DMA( %d )\n", (n) ); \
DRM_INFO( " space=0x%x req=0x%Zx\n", \
dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
} \
@@ -292,7 +295,7 @@ do { \
#define BEGIN_DMA_WRAP() \
do { \
if ( MGA_VERBOSE ) { \
- DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_DMA()\n" ); \
DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \
} \
prim = dev_priv->prim.start; \
@@ -311,7 +314,7 @@ do { \
#define FLUSH_DMA() \
do { \
if ( 0 ) { \
- DRM_INFO( "%s:\n", __FUNCTION__ ); \
+ DRM_INFO( "\n" ); \
DRM_INFO( " tail=0x%06x head=0x%06lx\n", \
dev_priv->prim.tail, \
MGA_READ( MGA_PRIMADDRESS ) - \
diff --git a/sys/dev/pci/drm/mga_irq.c b/sys/dev/pci/drm/mga_irq.c
index c18bae9f2db..4fe86322672 100644
--- a/sys/dev/pci/drm/mga_irq.c
+++ b/sys/dev/pci/drm/mga_irq.c
@@ -36,6 +36,20 @@
#include "mga_drm.h"
#include "mga_drv.h"
+u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ const drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
+
+ if (crtc != 0) {
+ return 0;
+ }
+
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
+
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -48,16 +62,15 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
/* VBLANK interrupt */
if (status & MGA_VLINEPEN) {
MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
handled = 1;
}
/* SOFTRAP interrupt */
if (status & MGA_SOFTRAPEN) {
const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
- const u32 prim_end = MGA_READ(MGA_PRIMEND);
+ const u32 prim_end = MGA_READ(MGA_PRIMEND);
MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
@@ -65,7 +78,7 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
/* In addition to clearing the interrupt-pending bit, we
* have to write to MGA_PRIMEND to re-start the DMA operation.
*/
- if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) {
+ if ((prim_start & ~0x03) != (prim_end & ~0x03)) {
MGA_WRITE(MGA_PRIMEND, prim_end);
}
@@ -74,28 +87,39 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
handled = 1;
}
- if ( handled ) {
+ if (handled)
return IRQ_HANDLED;
- }
return IRQ_NONE;
}
-int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int mga_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0) {
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return 0;
+ }
- *sequence = cur_vblank;
+ MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ return 0;
+}
- return ret;
+
+void mga_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0) {
+ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
+ crtc);
+ }
+
+ /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have
+ * a nice hardware counter that tracks the number of refreshes when
+ * the interrupt is disabled, and the kernel doesn't know the refresh
+ * rate to calculate an estimate.
+ */
+ /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
}
int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
@@ -127,14 +151,22 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
MGA_WRITE(MGA_ICLEAR, ~0);
}
-void mga_driver_irq_postinstall(struct drm_device * dev)
+int mga_driver_irq_postinstall(struct drm_device * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ int ret;
- DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
+ ret = drm_vblank_init(dev, 1);
+ if (ret)
+ return ret;
- /* Turn on vertical blank interrupt and soft trap interrupt. */
- MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
+
+ /* Turn on soft trap interrupt. Vertical blank interrupts are enabled
+ * in mga_enable_vblank.
+ */
+ MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
+ return 0;
}
void mga_driver_irq_uninstall(struct drm_device * dev)
diff --git a/sys/dev/pci/drm/mga_state.c b/sys/dev/pci/drm/mga_state.c
index 0b8ba048d33..2da108beefd 100644
--- a/sys/dev/pci/drm/mga_state.c
+++ b/sys/dev/pci/drm/mga_state.c
@@ -62,8 +62,7 @@ static void mga_emit_clip_rect(drm_mga_private_t * dev_priv,
}
DMA_BLOCK(MGA_DMAPAD, 0x00000000,
MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1,
- MGA_YTOP, box->y1 * pitch,
- MGA_YBOT, (box->y2 - 1) * pitch);
+ MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch);
ADVANCE_DMA();
}
@@ -78,18 +77,15 @@ static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv)
DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
MGA_MACCESS, ctx->maccess,
- MGA_PLNWT, ctx->plnwt,
- MGA_DWGCTL, ctx->dwgctl);
+ MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
MGA_FOGCOL, ctx->fogcolor,
- MGA_WFLAG, ctx->wflag,
- MGA_ZORG, dev_priv->depth_offset);
+ MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
DMA_BLOCK(MGA_FCOL, ctx->fcol,
MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000);
+ MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
ADVANCE_DMA();
}
@@ -648,7 +644,7 @@ static void mga_dma_dispatch_swap(struct drm_device * dev)
FLUSH_DMA();
- DRM_DEBUG("%s... done.\n", __FUNCTION__);
+ DRM_DEBUG("... done.\n");
}
static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf)
@@ -660,7 +656,7 @@ static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * bu
u32 length = (u32) buf->used;
int i = 0;
DMA_LOCALS;
- DRM_DEBUG("vertex: buf=%d used=%d\n", buf->idx, buf->used);
+ DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
if (buf->used) {
buf_priv->dispatched = 1;
@@ -707,7 +703,7 @@ static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * b
u32 address = (u32) buf->bus_address;
int i = 0;
DMA_LOCALS;
- DRM_DEBUG("indices: buf=%d start=%d end=%d\n", buf->idx, start, end);
+ DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end);
if (start != end) {
buf_priv->dispatched = 1;
@@ -992,7 +988,7 @@ static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *fi
#if 0
if (mga_do_wait_for_idle(dev_priv) < 0) {
if (MGA_DMA_DEBUG)
- DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
+ DRM_INFO("-EBUSY\n");
return -EBUSY;
}
#endif
@@ -1051,7 +1047,7 @@ static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *fil
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1083,7 +1079,7 @@ static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *fi
DMA_LOCALS;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1112,7 +1108,7 @@ static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file *f
u32 *fence = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/sys/dev/pci/drm/mga_warp.c b/sys/dev/pci/drm/mga_warp.c
index d10e0b9c37c..9a44bddbdd2 100644
--- a/sys/dev/pci/drm/mga_warp.c
+++ b/sys/dev/pci/drm/mga_warp.c
@@ -35,6 +35,7 @@
#include "mga_ucode.h"
#define MGA_WARP_CODE_ALIGN 256 /* in bytes */
+
#define WARP_UCODE_SIZE( which ) \
((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)
diff --git a/sys/dev/pci/drm/r128_cce.c b/sys/dev/pci/drm/r128_cce.c
index 8ce128bd9d4..995c6f2e676 100644
--- a/sys/dev/pci/drm/r128_cce.c
+++ b/sys/dev/pci/drm/r128_cce.c
@@ -558,6 +558,7 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
#if __OS_HAS_AGP
if (dev_priv->is_pci) {
#endif
+ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
dev_priv->gart_info.addr = NULL;
@@ -649,7 +650,7 @@ int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
- DRM_DEBUG("%s while CCE running\n", __FUNCTION__);
+ DRM_DEBUG("while CCE running\n");
return 0;
}
@@ -708,7 +709,7 @@ int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_DEBUG("%s called before init done\n", __FUNCTION__);
+ DRM_DEBUG("called before init done\n");
return -EINVAL;
}
diff --git a/sys/dev/pci/drm/r128_drv.c b/sys/dev/pci/drm/r128_drv.c
index 9c16396f383..6f431f2a4c0 100644
--- a/sys/dev/pci/drm/r128_drv.c
+++ b/sys/dev/pci/drm/r128_drv.c
@@ -50,7 +50,9 @@ r128_configure(drm_device_t *dev)
dev->driver.buf_priv_size = sizeof(drm_r128_buf_priv_t);
dev->driver.preclose = r128_driver_preclose;
dev->driver.lastclose = r128_driver_lastclose;
- dev->driver.vblank_wait = r128_driver_vblank_wait;
+ dev->driver.get_vblank_counter = r128_get_vblank_counter;
+ dev->driver.enable_vblank = r128_enable_vblank;
+ dev->driver.disable_vblank = r128_disable_vblank;
dev->driver.irq_preinstall = r128_driver_irq_preinstall;
dev->driver.irq_postinstall = r128_driver_irq_postinstall;
dev->driver.irq_uninstall = r128_driver_irq_uninstall;
diff --git a/sys/dev/pci/drm/r128_drv.h b/sys/dev/pci/drm/r128_drv.h
index 4d27f549b65..ab8b6297ce9 100644
--- a/sys/dev/pci/drm/r128_drv.h
+++ b/sys/dev/pci/drm/r128_drv.h
@@ -97,6 +97,8 @@ typedef struct drm_r128_private {
u32 crtc_offset;
u32 crtc_offset_cntl;
+ atomic_t vbl_received;
+
u32 color_fmt;
unsigned int front_offset;
unsigned int front_pitch;
@@ -118,7 +120,7 @@ typedef struct drm_r128_private {
drm_local_map_t *cce_ring;
drm_local_map_t *ring_rptr;
drm_local_map_t *agp_textures;
- struct ati_pcigart_info gart_info;
+ struct drm_ati_pcigart_info gart_info;
} drm_r128_private_t;
typedef struct drm_r128_buf_priv {
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
extern int r128_do_cleanup_cce(struct drm_device * dev);
-extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
-
+extern int r128_enable_vblank(struct drm_device *dev, int crtc);
+extern void r128_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
extern void r128_driver_irq_preinstall(struct drm_device * dev);
-extern void r128_driver_irq_postinstall(struct drm_device * dev);
+extern int r128_driver_irq_postinstall(struct drm_device * dev);
extern void r128_driver_irq_uninstall(struct drm_device * dev);
extern void r128_driver_lastclose(struct drm_device * dev);
extern void r128_driver_preclose(struct drm_device * dev,
@@ -462,8 +465,7 @@ do { \
#define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \
- DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
- (n), __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
COMMIT_RING(); \
diff --git a/sys/dev/pci/drm/r128_irq.c b/sys/dev/pci/drm/r128_irq.c
index c76fdca7662..5b95bd898f9 100644
--- a/sys/dev/pci/drm/r128_irq.c
+++ b/sys/dev/pci/drm/r128_irq.c
@@ -35,6 +35,16 @@
#include "r128_drm.h"
#include "r128_drv.h"
+u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ const drm_r128_private_t *dev_priv = dev->dev_private;
+
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
/* VBLANK interrupt */
if (status & R128_CRTC_VBLANK_INT) {
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
-int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int r128_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_r128_private_t *dev_priv = dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0) {
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
+ return -EINVAL;
+ }
- *sequence = cur_vblank;
+ R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ return 0;
+}
+
+void r128_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0)
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
- return ret;
+ /*
+ * FIXME: implement proper interrupt disable by using the vblank
+ * counter register (if available)
+ *
+ * R128_WRITE(R128_GEN_INT_CNTL,
+ * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
+ */
}
void r128_driver_irq_preinstall(struct drm_device * dev)
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
}
-void r128_driver_irq_postinstall(struct drm_device * dev)
+int r128_driver_irq_postinstall(struct drm_device * dev)
{
- drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
-
- /* Turn on VBL interrupt */
- R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ return drm_vblank_init(dev, 1);
}
void r128_driver_irq_uninstall(struct drm_device * dev)
diff --git a/sys/dev/pci/drm/r128_state.c b/sys/dev/pci/drm/r128_state.c
index b7f483cac6d..51a9afce7b9 100644
--- a/sys/dev/pci/drm/r128_state.c
+++ b/sys/dev/pci/drm/r128_state.c
@@ -42,7 +42,7 @@ static void r128_emit_clip_rects(drm_r128_private_t * dev_priv,
{
u32 aux_sc_cntl = 0x00000000;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING((count < 3 ? count : 3) * 5 + 2);
@@ -85,7 +85,7 @@ static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(2);
@@ -100,7 +100,7 @@ static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(13);
@@ -126,7 +126,7 @@ static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(3);
@@ -142,7 +142,7 @@ static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(5);
@@ -161,7 +161,7 @@ static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(2);
@@ -178,7 +178,7 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
int i;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS);
@@ -204,7 +204,7 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
int i;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS);
@@ -226,7 +226,7 @@ static void r128_emit_state(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
- DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty);
+ DRM_DEBUG("dirty=0x%08x\n", dirty);
if (dirty & R128_UPLOAD_CORE) {
r128_emit_core(dev_priv);
@@ -362,7 +362,7 @@ static void r128_cce_dispatch_clear(struct drm_device * dev,
unsigned int flags = clear->flags;
int i;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (dev_priv->page_flipping && dev_priv->current_page == 1) {
unsigned int tmp = flags;
@@ -466,7 +466,7 @@ static void r128_cce_dispatch_swap(struct drm_device * dev)
struct drm_clip_rect *pbox = sarea_priv->boxes;
int i;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
#if R128_PERFORMANCE_BOXES
/* Do some trivial performance monitoring...
@@ -528,8 +528,7 @@ static void r128_cce_dispatch_flip(struct drm_device * dev)
{
drm_r128_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
+ DRM_DEBUG("page=%d pfCurrentPage=%d\n",
dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
#if R128_PERFORMANCE_BOXES
@@ -1156,7 +1155,7 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev,
int count, *x, *y;
int i, xbuf_size, ybuf_size;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
count = depth->n;
if (count > 4096 || count <= 0)
@@ -1226,7 +1225,7 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple)
drm_r128_private_t *dev_priv = dev->dev_private;
int i;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(33);
@@ -1309,7 +1308,7 @@ static int r128_do_cleanup_pageflip(struct drm_device * dev)
static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1328,7 +1327,7 @@ static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *fi
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1356,7 +1355,7 @@ static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1412,7 +1411,7 @@ static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1557,11 +1556,11 @@ static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
+ DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
indirect->idx, indirect->start, indirect->end,
indirect->discard);
@@ -1622,7 +1621,7 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/sys/dev/pci/drm/r300_cmdbuf.c b/sys/dev/pci/drm/r300_cmdbuf.c
index 6ab907c69a4..bff6378fb27 100644
--- a/sys/dev/pci/drm/r300_cmdbuf.c
+++ b/sys/dev/pci/drm/r300_cmdbuf.c
@@ -77,23 +77,31 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
return -EFAULT;
}
- box.x1 =
- (box.x1 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.y1 =
- (box.y1 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.x2 =
- (box.x2 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.y2 =
- (box.y2 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
+ box.x1 = (box.x1) &
+ R300_CLIPRECT_MASK;
+ box.y1 = (box.y1) &
+ R300_CLIPRECT_MASK;
+ box.x2 = (box.x2) &
+ R300_CLIPRECT_MASK;
+ box.y2 = (box.y2) &
+ R300_CLIPRECT_MASK;
+ } else {
+ box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) &
+ R300_CLIPRECT_MASK;
+ box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) &
+ R300_CLIPRECT_MASK;
+ box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) &
+ 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) |
(box.y2 << R300_CLIPRECT_Y_SHIFT));
+
}
OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]);
@@ -133,9 +141,11 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
static u8 r300_reg_flags[0x10000 >> 2];
-void r300_init_reg_flags(void)
+void r300_init_reg_flags(struct drm_device *dev)
{
int i;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
memset(r300_reg_flags, 0, 0x10000 >> 2);
#define ADD_RANGE_MARK(reg, count,mark) \
for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
@@ -179,18 +189,12 @@ void r300_init_reg_flags(void)
ADD_RANGE(R300_RE_CULL_CNTL, 1);
ADD_RANGE(0x42C0, 2);
ADD_RANGE(R300_RS_CNTL_0, 2);
- ADD_RANGE(R300_RS_INTERP_0, 8);
- ADD_RANGE(R300_RS_ROUTE_0, 8);
+
ADD_RANGE(0x43A4, 2);
ADD_RANGE(0x43E8, 1);
- ADD_RANGE(R300_PFS_CNTL_0, 3);
- ADD_RANGE(R300_PFS_NODE_0, 4);
- ADD_RANGE(R300_PFS_TEXI_0, 64);
+
ADD_RANGE(0x46A4, 5);
- ADD_RANGE(R300_PFS_INSTR0_0, 64);
- ADD_RANGE(R300_PFS_INSTR1_0, 64);
- ADD_RANGE(R300_PFS_INSTR2_0, 64);
- ADD_RANGE(R300_PFS_INSTR3_0, 64);
+
ADD_RANGE(R300_RE_FOG_STATE, 1);
ADD_RANGE(R300_FOG_COLOR_R, 3);
ADD_RANGE(R300_PP_ALPHA_TEST, 2);
@@ -230,6 +234,27 @@ void r300_init_reg_flags(void)
ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
+ ADD_RANGE(R500_VAP_INDEX_OFFSET, 1);
+ ADD_RANGE(R500_US_CONFIG, 2);
+ ADD_RANGE(R500_US_CODE_ADDR, 3);
+ ADD_RANGE(R500_US_FC_CTRL, 1);
+ ADD_RANGE(R500_RS_IP_0, 16);
+ ADD_RANGE(R500_RS_INST_0, 16);
+ ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
+ ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
+ } else {
+ ADD_RANGE(R300_PFS_CNTL_0, 3);
+ ADD_RANGE(R300_PFS_NODE_0, 4);
+ ADD_RANGE(R300_PFS_TEXI_0, 64);
+ ADD_RANGE(R300_PFS_INSTR0_0, 64);
+ ADD_RANGE(R300_PFS_INSTR1_0, 64);
+ ADD_RANGE(R300_PFS_INSTR2_0, 64);
+ ADD_RANGE(R300_PFS_INSTR3_0, 64);
+ ADD_RANGE(R300_RS_INTERP_0, 8);
+ ADD_RANGE(R300_RS_ROUTE_0, 8);
+
+ }
}
static __inline__ int r300_check_range(unsigned reg, int count)
@@ -313,6 +338,7 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv,
sz = header.packet0.count;
reg = (header.packet0.reghi << 8) | header.packet0.reglo;
+ DRM_DEBUG("R300_CMD_PACKET0: reg %04x, sz %d\n", reg, sz);
if (!sz)
return 0;
@@ -716,6 +742,47 @@ static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
buf->used = 0;
}
+static void r300_cmd_wait(drm_radeon_private_t * dev_priv,
+ drm_r300_cmd_header_t header)
+{
+ u32 wait_until;
+ RING_LOCALS;
+
+ if (!header.wait.flags)
+ return;
+
+ wait_until = 0;
+
+ switch(header.wait.flags) {
+ case R300_WAIT_2D:
+ wait_until = RADEON_WAIT_2D_IDLE;
+ break;
+ case R300_WAIT_3D:
+ wait_until = RADEON_WAIT_3D_IDLE;
+ break;
+ case R300_NEW_WAIT_2D_3D:
+ wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE;
+ break;
+ case R300_NEW_WAIT_2D_2D_CLEAN:
+ wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
+ break;
+ case R300_NEW_WAIT_3D_3D_CLEAN:
+ wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
+ break;
+ case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN:
+ wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
+ wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
+ break;
+ default:
+ return;
+ }
+
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(wait_until);
+ ADVANCE_RING();
+}
+
static int r300_scratch(drm_radeon_private_t *dev_priv,
drm_radeon_kcmd_buffer_t *cmdbuf,
drm_r300_cmd_header_t header)
@@ -774,6 +841,54 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
}
/**
+ * Uploads user-supplied vertex program instructions or parameters onto
+ * the graphics card.
+ * Called by r300_do_cp_cmdbuf.
+ */
+static __inline__ int r300_emit_r500fp(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf,
+ drm_r300_cmd_header_t header)
+{
+ int sz;
+ int addr;
+ int type;
+ int clamp;
+ int stride;
+ RING_LOCALS;
+
+ sz = header.r500fp.count;
+ /* address is 9 bits 0 - 8, bit 1 of flags is part of address */
+ addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo;
+
+ type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
+ clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
+
+ addr |= (type << 16);
+ addr |= (clamp << 17);
+
+ stride = type ? 4 : 6;
+
+ DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type);
+ if (!sz)
+ return 0;
+ if (sz * stride * 4 > cmdbuf->bufsz)
+ return -EINVAL;
+
+ BEGIN_RING(3 + sz * stride);
+ OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr);
+ OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1));
+ OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride);
+
+ ADVANCE_RING();
+
+ cmdbuf->buf += sz * stride * 4;
+ cmdbuf->bufsz -= sz * stride * 4;
+
+ return 0;
+}
+
+
+/**
* Parses and validates a user-supplied command buffer and emits appropriate
* commands on the DMA ring buffer.
* Called by the ioctl handler function radeon_cp_cmdbuf.
@@ -811,7 +926,6 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
switch (header.header.cmd_type) {
case R300_CMD_PACKET0:
- DRM_DEBUG("R300_CMD_PACKET0\n");
ret = r300_emit_packet0(dev_priv, cmdbuf, header);
if (ret) {
DRM_ERROR("r300_emit_packet0 failed\n");
@@ -895,19 +1009,8 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
break;
case R300_CMD_WAIT:
- /* simple enough, we can do it here */
DRM_DEBUG("R300_CMD_WAIT\n");
- if (header.wait.flags == 0)
- break; /* nothing to do */
-
- {
- RING_LOCALS;
-
- BEGIN_RING(2);
- OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
- OUT_RING((header.wait.flags & 0xf) << 14);
- ADVANCE_RING();
- }
+ r300_cmd_wait(dev_priv, header);
break;
case R300_CMD_SCRATCH:
@@ -919,6 +1022,19 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
}
break;
+ case R300_CMD_R500FP:
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
+ DRM_ERROR("Calling r500 command on r300 card\n");
+ ret = -EINVAL;
+ goto cleanup;
+ }
+ DRM_DEBUG("R300_CMD_R500FP\n");
+ ret = r300_emit_r500fp(dev_priv, cmdbuf, header);
+ if (ret) {
+ DRM_ERROR("r300_emit_r500fp failed\n");
+ goto cleanup;
+ }
+ break;
default:
DRM_ERROR("bad cmd_type %i at %p\n",
header.header.cmd_type,
diff --git a/sys/dev/pci/drm/r300_reg.h b/sys/dev/pci/drm/r300_reg.h
index 29198c8a240..0be01fc7451 100644
--- a/sys/dev/pci/drm/r300_reg.h
+++ b/sys/dev/pci/drm/r300_reg.h
@@ -1349,7 +1349,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Guess by Vladimir.
* Set to 0A before 3D operations, set to 02 afterwards.
*/
-#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C
+/*#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C*/
# define R300_RB3D_DSTCACHE_UNKNOWN_02 0x00000002
# define R300_RB3D_DSTCACHE_UNKNOWN_0A 0x0000000A
@@ -1626,6 +1626,22 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define R300_CP_CMD_BITBLT_MULTI 0xC0009B00
+#define R500_VAP_INDEX_OFFSET 0x208c
+
+#define R500_GA_US_VECTOR_INDEX 0x4250
+#define R500_GA_US_VECTOR_DATA 0x4254
+
+#define R500_RS_IP_0 0x4074
+#define R500_RS_INST_0 0x4320
+
+#define R500_US_CONFIG 0x4600
+
+#define R500_US_FC_CTRL 0x4624
+#define R500_US_CODE_ADDR 0x4630
+
+#define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0
+#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8
+
#endif /* _R300_REG_H */
/* *INDENT-ON* */
diff --git a/sys/dev/pci/drm/radeon_cp.c b/sys/dev/pci/drm/radeon_cp.c
index 7bdf8c37a87..5675fda6f3e 100644
--- a/sys/dev/pci/drm/radeon_cp.c
+++ b/sys/dev/pci/drm/radeon_cp.c
@@ -2,6 +2,7 @@
/*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Fremont, California.
+ * Copyright 2007 Advanced Micro Devices, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -34,787 +35,103 @@
#include "radeon_drv.h"
#include "r300_reg.h"
-#define RADEON_FIFO_DEBUG 1
+#include "radeon_microcode.h"
+#define RADEON_FIFO_DEBUG 0
static int radeon_do_cleanup_cp(struct drm_device * dev);
-/* CP microcode (from ATI) */
-static const u32 R200_cp_microcode[][2] = {
- {0x21007000, 0000000000},
- {0x20007000, 0000000000},
- {0x000000ab, 0x00000004},
- {0x000000af, 0x00000004},
- {0x66544a49, 0000000000},
- {0x49494174, 0000000000},
- {0x54517d83, 0000000000},
- {0x498d8b64, 0000000000},
- {0x49494949, 0000000000},
- {0x49da493c, 0000000000},
- {0x49989898, 0000000000},
- {0xd34949d5, 0000000000},
- {0x9dc90e11, 0000000000},
- {0xce9b9b9b, 0000000000},
- {0x000f0000, 0x00000016},
- {0x352e232c, 0000000000},
- {0x00000013, 0x00000004},
- {0x000f0000, 0x00000016},
- {0x352e272c, 0000000000},
- {0x000f0001, 0x00000016},
- {0x3239362f, 0000000000},
- {0x000077ef, 0x00000002},
- {0x00061000, 0x00000002},
- {0x00000020, 0x0000001a},
- {0x00004000, 0x0000001e},
- {0x00061000, 0x00000002},
- {0x00000020, 0x0000001a},
- {0x00004000, 0x0000001e},
- {0x00061000, 0x00000002},
- {0x00000020, 0x0000001a},
- {0x00004000, 0x0000001e},
- {0x00000016, 0x00000004},
- {0x0003802a, 0x00000002},
- {0x040067e0, 0x00000002},
- {0x00000016, 0x00000004},
- {0x000077e0, 0x00000002},
- {0x00065000, 0x00000002},
- {0x000037e1, 0x00000002},
- {0x040067e1, 0x00000006},
- {0x000077e0, 0x00000002},
- {0x000077e1, 0x00000002},
- {0x000077e1, 0x00000006},
- {0xffffffff, 0000000000},
- {0x10000000, 0000000000},
- {0x0003802a, 0x00000002},
- {0x040067e0, 0x00000006},
- {0x00007675, 0x00000002},
- {0x00007676, 0x00000002},
- {0x00007677, 0x00000002},
- {0x00007678, 0x00000006},
- {0x0003802b, 0x00000002},
- {0x04002676, 0x00000002},
- {0x00007677, 0x00000002},
- {0x00007678, 0x00000006},
- {0x0000002e, 0x00000018},
- {0x0000002e, 0x00000018},
- {0000000000, 0x00000006},
- {0x0000002f, 0x00000018},
- {0x0000002f, 0x00000018},
- {0000000000, 0x00000006},
- {0x01605000, 0x00000002},
- {0x00065000, 0x00000002},
- {0x00098000, 0x00000002},
- {0x00061000, 0x00000002},
- {0x64c0603d, 0x00000004},
- {0x00080000, 0x00000016},
- {0000000000, 0000000000},
- {0x0400251d, 0x00000002},
- {0x00007580, 0x00000002},
- {0x00067581, 0x00000002},
- {0x04002580, 0x00000002},
- {0x00067581, 0x00000002},
- {0x00000046, 0x00000004},
- {0x00005000, 0000000000},
- {0x00061000, 0x00000002},
- {0x0000750e, 0x00000002},
- {0x00019000, 0x00000002},
- {0x00011055, 0x00000014},
- {0x00000055, 0x00000012},
- {0x0400250f, 0x00000002},
- {0x0000504a, 0x00000004},
- {0x00007565, 0x00000002},
- {0x00007566, 0x00000002},
- {0x00000051, 0x00000004},
- {0x01e655b4, 0x00000002},
- {0x4401b0dc, 0x00000002},
- {0x01c110dc, 0x00000002},
- {0x2666705d, 0x00000018},
- {0x040c2565, 0x00000002},
- {0x0000005d, 0x00000018},
- {0x04002564, 0x00000002},
- {0x00007566, 0x00000002},
- {0x00000054, 0x00000004},
- {0x00401060, 0x00000008},
- {0x00101000, 0x00000002},
- {0x000d80ff, 0x00000002},
- {0x00800063, 0x00000008},
- {0x000f9000, 0x00000002},
- {0x000e00ff, 0x00000002},
- {0000000000, 0x00000006},
- {0x00000080, 0x00000018},
- {0x00000054, 0x00000004},
- {0x00007576, 0x00000002},
- {0x00065000, 0x00000002},
- {0x00009000, 0x00000002},
- {0x00041000, 0x00000002},
- {0x0c00350e, 0x00000002},
- {0x00049000, 0x00000002},
- {0x00051000, 0x00000002},
- {0x01e785f8, 0x00000002},
- {0x00200000, 0x00000002},
- {0x00600073, 0x0000000c},
- {0x00007563, 0x00000002},
- {0x006075f0, 0x00000021},
- {0x20007068, 0x00000004},
- {0x00005068, 0x00000004},
- {0x00007576, 0x00000002},
- {0x00007577, 0x00000002},
- {0x0000750e, 0x00000002},
- {0x0000750f, 0x00000002},
- {0x00a05000, 0x00000002},
- {0x00600076, 0x0000000c},
- {0x006075f0, 0x00000021},
- {0x000075f8, 0x00000002},
- {0x00000076, 0x00000004},
- {0x000a750e, 0x00000002},
- {0x0020750f, 0x00000002},
- {0x00600079, 0x00000004},
- {0x00007570, 0x00000002},
- {0x00007571, 0x00000002},
- {0x00007572, 0x00000006},
- {0x00005000, 0x00000002},
- {0x00a05000, 0x00000002},
- {0x00007568, 0x00000002},
- {0x00061000, 0x00000002},
- {0x00000084, 0x0000000c},
- {0x00058000, 0x00000002},
- {0x0c607562, 0x00000002},
- {0x00000086, 0x00000004},
- {0x00600085, 0x00000004},
- {0x400070dd, 0000000000},
- {0x000380dd, 0x00000002},
- {0x00000093, 0x0000001c},
- {0x00065095, 0x00000018},
- {0x040025bb, 0x00000002},
- {0x00061096, 0x00000018},
- {0x040075bc, 0000000000},
- {0x000075bb, 0x00000002},
- {0x000075bc, 0000000000},
- {0x00090000, 0x00000006},
- {0x00090000, 0x00000002},
- {0x000d8002, 0x00000006},
- {0x00005000, 0x00000002},
- {0x00007821, 0x00000002},
- {0x00007800, 0000000000},
- {0x00007821, 0x00000002},
- {0x00007800, 0000000000},
- {0x01665000, 0x00000002},
- {0x000a0000, 0x00000002},
- {0x000671cc, 0x00000002},
- {0x0286f1cd, 0x00000002},
- {0x000000a3, 0x00000010},
- {0x21007000, 0000000000},
- {0x000000aa, 0x0000001c},
- {0x00065000, 0x00000002},
- {0x000a0000, 0x00000002},
- {0x00061000, 0x00000002},
- {0x000b0000, 0x00000002},
- {0x38067000, 0x00000002},
- {0x000a00a6, 0x00000004},
- {0x20007000, 0000000000},
- {0x01200000, 0x00000002},
- {0x20077000, 0x00000002},
- {0x01200000, 0x00000002},
- {0x20007000, 0000000000},
- {0x00061000, 0x00000002},
- {0x0120751b, 0x00000002},
- {0x8040750a, 0x00000002},
- {0x8040750b, 0x00000002},
- {0x00110000, 0x00000002},
- {0x000380dd, 0x00000002},
- {0x000000bd, 0x0000001c},
- {0x00061096, 0x00000018},
- {0x844075bd, 0x00000002},
- {0x00061095, 0x00000018},
- {0x840075bb, 0x00000002},
- {0x00061096, 0x00000018},
- {0x844075bc, 0x00000002},
- {0x000000c0, 0x00000004},
- {0x804075bd, 0x00000002},
- {0x800075bb, 0x00000002},
- {0x804075bc, 0x00000002},
- {0x00108000, 0x00000002},
- {0x01400000, 0x00000002},
- {0x006000c4, 0x0000000c},
- {0x20c07000, 0x00000020},
- {0x000000c6, 0x00000012},
- {0x00800000, 0x00000006},
- {0x0080751d, 0x00000006},
- {0x000025bb, 0x00000002},
- {0x000040c0, 0x00000004},
- {0x0000775c, 0x00000002},
- {0x00a05000, 0x00000002},
- {0x00661000, 0x00000002},
- {0x0460275d, 0x00000020},
- {0x00004000, 0000000000},
- {0x00007999, 0x00000002},
- {0x00a05000, 0x00000002},
- {0x00661000, 0x00000002},
- {0x0460299b, 0x00000020},
- {0x00004000, 0000000000},
- {0x01e00830, 0x00000002},
- {0x21007000, 0000000000},
- {0x00005000, 0x00000002},
- {0x00038042, 0x00000002},
- {0x040025e0, 0x00000002},
- {0x000075e1, 0000000000},
- {0x00000001, 0000000000},
- {0x000380d9, 0x00000002},
- {0x04007394, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
-};
-
-static const u32 radeon_cp_microcode[][2] = {
- {0x21007000, 0000000000},
- {0x20007000, 0000000000},
- {0x000000b4, 0x00000004},
- {0x000000b8, 0x00000004},
- {0x6f5b4d4c, 0000000000},
- {0x4c4c427f, 0000000000},
- {0x5b568a92, 0000000000},
- {0x4ca09c6d, 0000000000},
- {0xad4c4c4c, 0000000000},
- {0x4ce1af3d, 0000000000},
- {0xd8afafaf, 0000000000},
- {0xd64c4cdc, 0000000000},
- {0x4cd10d10, 0000000000},
- {0x000f0000, 0x00000016},
- {0x362f242d, 0000000000},
- {0x00000012, 0x00000004},
- {0x000f0000, 0x00000016},
- {0x362f282d, 0000000000},
- {0x000380e7, 0x00000002},
- {0x04002c97, 0x00000002},
- {0x000f0001, 0x00000016},
- {0x333a3730, 0000000000},
- {0x000077ef, 0x00000002},
- {0x00061000, 0x00000002},
- {0x00000021, 0x0000001a},
- {0x00004000, 0x0000001e},
- {0x00061000, 0x00000002},
- {0x00000021, 0x0000001a},
- {0x00004000, 0x0000001e},
- {0x00061000, 0x00000002},
- {0x00000021, 0x0000001a},
- {0x00004000, 0x0000001e},
- {0x00000017, 0x00000004},
- {0x0003802b, 0x00000002},
- {0x040067e0, 0x00000002},
- {0x00000017, 0x00000004},
- {0x000077e0, 0x00000002},
- {0x00065000, 0x00000002},
- {0x000037e1, 0x00000002},
- {0x040067e1, 0x00000006},
- {0x000077e0, 0x00000002},
- {0x000077e1, 0x00000002},
- {0x000077e1, 0x00000006},
- {0xffffffff, 0000000000},
- {0x10000000, 0000000000},
- {0x0003802b, 0x00000002},
- {0x040067e0, 0x00000006},
- {0x00007675, 0x00000002},
- {0x00007676, 0x00000002},
- {0x00007677, 0x00000002},
- {0x00007678, 0x00000006},
- {0x0003802c, 0x00000002},
- {0x04002676, 0x00000002},
- {0x00007677, 0x00000002},
- {0x00007678, 0x00000006},
- {0x0000002f, 0x00000018},
- {0x0000002f, 0x00000018},
- {0000000000, 0x00000006},
- {0x00000030, 0x00000018},
- {0x00000030, 0x00000018},
- {0000000000, 0x00000006},
- {0x01605000, 0x00000002},
- {0x00065000, 0x00000002},
- {0x00098000, 0x00000002},
- {0x00061000, 0x00000002},
- {0x64c0603e, 0x00000004},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x00080000, 0x00000016},
- {0000000000, 0000000000},
- {0x0400251d, 0x00000002},
- {0x00007580, 0x00000002},
- {0x00067581, 0x00000002},
- {0x04002580, 0x00000002},
- {0x00067581, 0x00000002},
- {0x00000049, 0x00000004},
- {0x00005000, 0000000000},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x00061000, 0x00000002},
- {0x0000750e, 0x00000002},
- {0x00019000, 0x00000002},
- {0x00011055, 0x00000014},
- {0x00000055, 0x00000012},
- {0x0400250f, 0x00000002},
- {0x0000504f, 0x00000004},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x00007565, 0x00000002},
- {0x00007566, 0x00000002},
- {0x00000058, 0x00000004},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x01e655b4, 0x00000002},
- {0x4401b0e4, 0x00000002},
- {0x01c110e4, 0x00000002},
- {0x26667066, 0x00000018},
- {0x040c2565, 0x00000002},
- {0x00000066, 0x00000018},
- {0x04002564, 0x00000002},
- {0x00007566, 0x00000002},
- {0x0000005d, 0x00000004},
- {0x00401069, 0x00000008},
- {0x00101000, 0x00000002},
- {0x000d80ff, 0x00000002},
- {0x0080006c, 0x00000008},
- {0x000f9000, 0x00000002},
- {0x000e00ff, 0x00000002},
- {0000000000, 0x00000006},
- {0x0000008f, 0x00000018},
- {0x0000005b, 0x00000004},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x00007576, 0x00000002},
- {0x00065000, 0x00000002},
- {0x00009000, 0x00000002},
- {0x00041000, 0x00000002},
- {0x0c00350e, 0x00000002},
- {0x00049000, 0x00000002},
- {0x00051000, 0x00000002},
- {0x01e785f8, 0x00000002},
- {0x00200000, 0x00000002},
- {0x0060007e, 0x0000000c},
- {0x00007563, 0x00000002},
- {0x006075f0, 0x00000021},
- {0x20007073, 0x00000004},
- {0x00005073, 0x00000004},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x00007576, 0x00000002},
- {0x00007577, 0x00000002},
- {0x0000750e, 0x00000002},
- {0x0000750f, 0x00000002},
- {0x00a05000, 0x00000002},
- {0x00600083, 0x0000000c},
- {0x006075f0, 0x00000021},
- {0x000075f8, 0x00000002},
- {0x00000083, 0x00000004},
- {0x000a750e, 0x00000002},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x0020750f, 0x00000002},
- {0x00600086, 0x00000004},
- {0x00007570, 0x00000002},
- {0x00007571, 0x00000002},
- {0x00007572, 0x00000006},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x00005000, 0x00000002},
- {0x00a05000, 0x00000002},
- {0x00007568, 0x00000002},
- {0x00061000, 0x00000002},
- {0x00000095, 0x0000000c},
- {0x00058000, 0x00000002},
- {0x0c607562, 0x00000002},
- {0x00000097, 0x00000004},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x00600096, 0x00000004},
- {0x400070e5, 0000000000},
- {0x000380e6, 0x00000002},
- {0x040025c5, 0x00000002},
- {0x000380e5, 0x00000002},
- {0x000000a8, 0x0000001c},
- {0x000650aa, 0x00000018},
- {0x040025bb, 0x00000002},
- {0x000610ab, 0x00000018},
- {0x040075bc, 0000000000},
- {0x000075bb, 0x00000002},
- {0x000075bc, 0000000000},
- {0x00090000, 0x00000006},
- {0x00090000, 0x00000002},
- {0x000d8002, 0x00000006},
- {0x00007832, 0x00000002},
- {0x00005000, 0x00000002},
- {0x000380e7, 0x00000002},
- {0x04002c97, 0x00000002},
- {0x00007820, 0x00000002},
- {0x00007821, 0x00000002},
- {0x00007800, 0000000000},
- {0x01200000, 0x00000002},
- {0x20077000, 0x00000002},
- {0x01200000, 0x00000002},
- {0x20007000, 0x00000002},
- {0x00061000, 0x00000002},
- {0x0120751b, 0x00000002},
- {0x8040750a, 0x00000002},
- {0x8040750b, 0x00000002},
- {0x00110000, 0x00000002},
- {0x000380e5, 0x00000002},
- {0x000000c6, 0x0000001c},
- {0x000610ab, 0x00000018},
- {0x844075bd, 0x00000002},
- {0x000610aa, 0x00000018},
- {0x840075bb, 0x00000002},
- {0x000610ab, 0x00000018},
- {0x844075bc, 0x00000002},
- {0x000000c9, 0x00000004},
- {0x804075bd, 0x00000002},
- {0x800075bb, 0x00000002},
- {0x804075bc, 0x00000002},
- {0x00108000, 0x00000002},
- {0x01400000, 0x00000002},
- {0x006000cd, 0x0000000c},
- {0x20c07000, 0x00000020},
- {0x000000cf, 0x00000012},
- {0x00800000, 0x00000006},
- {0x0080751d, 0x00000006},
- {0000000000, 0000000000},
- {0x0000775c, 0x00000002},
- {0x00a05000, 0x00000002},
- {0x00661000, 0x00000002},
- {0x0460275d, 0x00000020},
- {0x00004000, 0000000000},
- {0x01e00830, 0x00000002},
- {0x21007000, 0000000000},
- {0x6464614d, 0000000000},
- {0x69687420, 0000000000},
- {0x00000073, 0000000000},
- {0000000000, 0000000000},
- {0x00005000, 0x00000002},
- {0x000380d0, 0x00000002},
- {0x040025e0, 0x00000002},
- {0x000075e1, 0000000000},
- {0x00000001, 0000000000},
- {0x000380e0, 0x00000002},
- {0x04002394, 0x00000002},
- {0x00005000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0x00000008, 0000000000},
- {0x00000004, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
- {0000000000, 0000000000},
-};
-
-static const u32 R300_cp_microcode[][2] = {
- { 0x4200e000, 0000000000 },
- { 0x4000e000, 0000000000 },
- { 0x000000af, 0x00000008 },
- { 0x000000b3, 0x00000008 },
- { 0x6c5a504f, 0000000000 },
- { 0x4f4f497a, 0000000000 },
- { 0x5a578288, 0000000000 },
- { 0x4f91906a, 0000000000 },
- { 0x4f4f4f4f, 0000000000 },
- { 0x4fe24f44, 0000000000 },
- { 0x4f9c9c9c, 0000000000 },
- { 0xdc4f4fde, 0000000000 },
- { 0xa1cd4f4f, 0000000000 },
- { 0xd29d9d9d, 0000000000 },
- { 0x4f0f9fd7, 0000000000 },
- { 0x000ca000, 0x00000004 },
- { 0x000d0012, 0x00000038 },
- { 0x0000e8b4, 0x00000004 },
- { 0x000d0014, 0x00000038 },
- { 0x0000e8b6, 0x00000004 },
- { 0x000d0016, 0x00000038 },
- { 0x0000e854, 0x00000004 },
- { 0x000d0018, 0x00000038 },
- { 0x0000e855, 0x00000004 },
- { 0x000d001a, 0x00000038 },
- { 0x0000e856, 0x00000004 },
- { 0x000d001c, 0x00000038 },
- { 0x0000e857, 0x00000004 },
- { 0x000d001e, 0x00000038 },
- { 0x0000e824, 0x00000004 },
- { 0x000d0020, 0x00000038 },
- { 0x0000e825, 0x00000004 },
- { 0x000d0022, 0x00000038 },
- { 0x0000e830, 0x00000004 },
- { 0x000d0024, 0x00000038 },
- { 0x0000f0c0, 0x00000004 },
- { 0x000d0026, 0x00000038 },
- { 0x0000f0c1, 0x00000004 },
- { 0x000d0028, 0x00000038 },
- { 0x0000f041, 0x00000004 },
- { 0x000d002a, 0x00000038 },
- { 0x0000f184, 0x00000004 },
- { 0x000d002c, 0x00000038 },
- { 0x0000f185, 0x00000004 },
- { 0x000d002e, 0x00000038 },
- { 0x0000f186, 0x00000004 },
- { 0x000d0030, 0x00000038 },
- { 0x0000f187, 0x00000004 },
- { 0x000d0032, 0x00000038 },
- { 0x0000f180, 0x00000004 },
- { 0x000d0034, 0x00000038 },
- { 0x0000f393, 0x00000004 },
- { 0x000d0036, 0x00000038 },
- { 0x0000f38a, 0x00000004 },
- { 0x000d0038, 0x00000038 },
- { 0x0000f38e, 0x00000004 },
- { 0x0000e821, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00000043, 0x00000018 },
- { 0x00cce800, 0x00000004 },
- { 0x001b0001, 0x00000004 },
- { 0x08004800, 0x00000004 },
- { 0x001b0001, 0x00000004 },
- { 0x08004800, 0x00000004 },
- { 0x001b0001, 0x00000004 },
- { 0x08004800, 0x00000004 },
- { 0x0000003a, 0x00000008 },
- { 0x0000a000, 0000000000 },
- { 0x02c0a000, 0x00000004 },
- { 0x000ca000, 0x00000004 },
- { 0x00130000, 0x00000004 },
- { 0x000c2000, 0x00000004 },
- { 0xc980c045, 0x00000008 },
- { 0x2000451d, 0x00000004 },
- { 0x0000e580, 0x00000004 },
- { 0x000ce581, 0x00000004 },
- { 0x08004580, 0x00000004 },
- { 0x000ce581, 0x00000004 },
- { 0x0000004c, 0x00000008 },
- { 0x0000a000, 0000000000 },
- { 0x000c2000, 0x00000004 },
- { 0x0000e50e, 0x00000004 },
- { 0x00032000, 0x00000004 },
- { 0x00022056, 0x00000028 },
- { 0x00000056, 0x00000024 },
- { 0x0800450f, 0x00000004 },
- { 0x0000a050, 0x00000008 },
- { 0x0000e565, 0x00000004 },
- { 0x0000e566, 0x00000004 },
- { 0x00000057, 0x00000008 },
- { 0x03cca5b4, 0x00000004 },
- { 0x05432000, 0x00000004 },
- { 0x00022000, 0x00000004 },
- { 0x4ccce063, 0x00000030 },
- { 0x08274565, 0x00000004 },
- { 0x00000063, 0x00000030 },
- { 0x08004564, 0x00000004 },
- { 0x0000e566, 0x00000004 },
- { 0x0000005a, 0x00000008 },
- { 0x00802066, 0x00000010 },
- { 0x00202000, 0x00000004 },
- { 0x001b00ff, 0x00000004 },
- { 0x01000069, 0x00000010 },
- { 0x001f2000, 0x00000004 },
- { 0x001c00ff, 0x00000004 },
- { 0000000000, 0x0000000c },
- { 0x00000085, 0x00000030 },
- { 0x0000005a, 0x00000008 },
- { 0x0000e576, 0x00000004 },
- { 0x000ca000, 0x00000004 },
- { 0x00012000, 0x00000004 },
- { 0x00082000, 0x00000004 },
- { 0x1800650e, 0x00000004 },
- { 0x00092000, 0x00000004 },
- { 0x000a2000, 0x00000004 },
- { 0x000f0000, 0x00000004 },
- { 0x00400000, 0x00000004 },
- { 0x00000079, 0x00000018 },
- { 0x0000e563, 0x00000004 },
- { 0x00c0e5f9, 0x000000c2 },
- { 0x0000006e, 0x00000008 },
- { 0x0000a06e, 0x00000008 },
- { 0x0000e576, 0x00000004 },
- { 0x0000e577, 0x00000004 },
- { 0x0000e50e, 0x00000004 },
- { 0x0000e50f, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x0000007c, 0x00000018 },
- { 0x00c0e5f9, 0x000000c2 },
- { 0x0000007c, 0x00000008 },
- { 0x0014e50e, 0x00000004 },
- { 0x0040e50f, 0x00000004 },
- { 0x00c0007f, 0x00000008 },
- { 0x0000e570, 0x00000004 },
- { 0x0000e571, 0x00000004 },
- { 0x0000e572, 0x0000000c },
- { 0x0000a000, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x0000e568, 0x00000004 },
- { 0x000c2000, 0x00000004 },
- { 0x00000089, 0x00000018 },
- { 0x000b0000, 0x00000004 },
- { 0x18c0e562, 0x00000004 },
- { 0x0000008b, 0x00000008 },
- { 0x00c0008a, 0x00000008 },
- { 0x000700e4, 0x00000004 },
- { 0x00000097, 0x00000038 },
- { 0x000ca099, 0x00000030 },
- { 0x080045bb, 0x00000004 },
- { 0x000c209a, 0x00000030 },
- { 0x0800e5bc, 0000000000 },
- { 0x0000e5bb, 0x00000004 },
- { 0x0000e5bc, 0000000000 },
- { 0x00120000, 0x0000000c },
- { 0x00120000, 0x00000004 },
- { 0x001b0002, 0x0000000c },
- { 0x0000a000, 0x00000004 },
- { 0x0000e821, 0x00000004 },
- { 0x0000e800, 0000000000 },
- { 0x0000e821, 0x00000004 },
- { 0x0000e82e, 0000000000 },
- { 0x02cca000, 0x00000004 },
- { 0x00140000, 0x00000004 },
- { 0x000ce1cc, 0x00000004 },
- { 0x050de1cd, 0x00000004 },
- { 0x000000a7, 0x00000020 },
- { 0x4200e000, 0000000000 },
- { 0x000000ae, 0x00000038 },
- { 0x000ca000, 0x00000004 },
- { 0x00140000, 0x00000004 },
- { 0x000c2000, 0x00000004 },
- { 0x00160000, 0x00000004 },
- { 0x700ce000, 0x00000004 },
- { 0x001400aa, 0x00000008 },
- { 0x4000e000, 0000000000 },
- { 0x02400000, 0x00000004 },
- { 0x400ee000, 0x00000004 },
- { 0x02400000, 0x00000004 },
- { 0x4000e000, 0000000000 },
- { 0x000c2000, 0x00000004 },
- { 0x0240e51b, 0x00000004 },
- { 0x0080e50a, 0x00000005 },
- { 0x0080e50b, 0x00000005 },
- { 0x00220000, 0x00000004 },
- { 0x000700e4, 0x00000004 },
- { 0x000000c1, 0x00000038 },
- { 0x000c209a, 0x00000030 },
- { 0x0880e5bd, 0x00000005 },
- { 0x000c2099, 0x00000030 },
- { 0x0800e5bb, 0x00000005 },
- { 0x000c209a, 0x00000030 },
- { 0x0880e5bc, 0x00000005 },
- { 0x000000c4, 0x00000008 },
- { 0x0080e5bd, 0x00000005 },
- { 0x0000e5bb, 0x00000005 },
- { 0x0080e5bc, 0x00000005 },
- { 0x00210000, 0x00000004 },
- { 0x02800000, 0x00000004 },
- { 0x00c000c8, 0x00000018 },
- { 0x4180e000, 0x00000040 },
- { 0x000000ca, 0x00000024 },
- { 0x01000000, 0x0000000c },
- { 0x0100e51d, 0x0000000c },
- { 0x000045bb, 0x00000004 },
- { 0x000080c4, 0x00000008 },
- { 0x0000f3ce, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00cc2000, 0x00000004 },
- { 0x08c053cf, 0x00000040 },
- { 0x00008000, 0000000000 },
- { 0x0000f3d2, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00cc2000, 0x00000004 },
- { 0x08c053d3, 0x00000040 },
- { 0x00008000, 0000000000 },
- { 0x0000f39d, 0x00000004 },
- { 0x0140a000, 0x00000004 },
- { 0x00cc2000, 0x00000004 },
- { 0x08c0539e, 0x00000040 },
- { 0x00008000, 0000000000 },
- { 0x03c00830, 0x00000004 },
- { 0x4200e000, 0000000000 },
- { 0x0000a000, 0x00000004 },
- { 0x200045e0, 0x00000004 },
- { 0x0000e5e1, 0000000000 },
- { 0x00000001, 0000000000 },
- { 0x000700e1, 0x00000004 },
- { 0x0800e394, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
- { 0000000000, 0000000000 },
-};
+static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
+ ret = RADEON_READ(R520_MC_IND_DATA);
+ RADEON_WRITE(R520_MC_IND_INDEX, 0);
+ return ret;
+}
+
+static u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff);
+ ret = RADEON_READ(RS480_NB_MC_DATA);
+ RADEON_WRITE(RS480_NB_MC_INDEX, 0xff);
+ return ret;
+}
+
+static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
+ ret = RADEON_READ(RS690_MC_DATA);
+ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
+ return ret;
+}
+
+static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ return RS690_READ_MCIND(dev_priv, addr);
+ else
+ return RS480_READ_MCIND(dev_priv, addr);
+}
+
+u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
+{
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
+ else
+ return RADEON_READ(RADEON_MC_FB_LOCATION);
+}
+
+static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
+{
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
+ else
+ RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
+}
+
+static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
+{
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
+ else
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
+}
+
+static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
+{
+ u32 agp_base_hi = upper_32_bits(agp_base);
+ u32 agp_base_lo = agp_base & 0xffffffff;
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
+ R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
+ R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
+ RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
+ RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
+ } 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 {
+ 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);
+ }
+}
static int RADEON_READ_PLL(struct drm_device * dev, int addr)
{
@@ -830,15 +147,6 @@ static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
return RADEON_READ(RADEON_PCIE_DATA);
}
-static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
-{
- u32 ret;
- RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f);
- ret = RADEON_READ(RADEON_IGPGART_DATA);
- RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f);
- return ret;
-}
-
#if RADEON_FIFO_DEBUG
static void radeon_status(drm_radeon_private_t * dev_priv)
{
@@ -873,16 +181,36 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
- tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT);
- tmp |= RADEON_RB3D_DC_FLUSH_ALL;
- RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {
+ tmp = RADEON_READ(RADEON_RB3D_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_RB3D_DSTCACHE_CTLSTAT)
- & RADEON_RB3D_DC_BUSY)) {
- return 0;
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
+ & RADEON_RB3D_DC_BUSY)) {
+ return 0;
+ }
+ 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);
}
- DRM_UDELAY(1);
}
#if RADEON_FIFO_DEBUG
@@ -939,6 +267,50 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
return -EBUSY;
}
+static void radeon_init_pipes(drm_radeon_private_t * dev_priv)
+{
+ uint32_t gb_tile_config, gb_pipe_sel = 0;
+
+ /* RS4xx/RS6xx/R4xx/R5xx */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
+ gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
+ dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+ } else {
+ /* R3xx */
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+ dev_priv->num_gb_pipes = 2;
+ } else {
+ /* R3Vxx */
+ dev_priv->num_gb_pipes = 1;
+ }
+ }
+ DRM_INFO("Num pipes: %d\n", dev_priv->num_gb_pipes);
+
+ gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/);
+
+ switch(dev_priv->num_gb_pipes) {
+ case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+ case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+ case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+ default:
+ case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
+ }
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
+ RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+ RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
+ }
+ RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
+ radeon_do_wait_for_idle(dev_priv);
+ RADEON_WRITE(R300_DST_PIPE_CONFIG, RADEON_READ(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
+ RADEON_WRITE(R300_RB2D_DSTCACHE_MODE, (RADEON_READ(R300_RB2D_DSTCACHE_MODE) |
+ R300_DC_AUTOFLUSH_ENABLE |
+ R300_DC_DC_DISABLE_IGNORE_PE));
+
+
+}
+
/* ================================================================
* CP control, initialization
*/
@@ -953,7 +325,22 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
- if (dev_priv->microcode_version == UCODE_R200) {
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) {
+ DRM_INFO("Loading R100 Microcode\n");
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ R100_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ R100_cp_microcode[i][0]);
+ }
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) {
DRM_INFO("Loading R200 Microcode\n");
for (i = 0; i < 256; i++) {
RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
@@ -961,7 +348,11 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
R200_cp_microcode[i][0]);
}
- } else if (dev_priv->microcode_version == UCODE_R300) {
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
+ ((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_RS480)) {
DRM_INFO("Loading R300 Microcode\n");
for (i = 0; i < 256; i++) {
RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
@@ -969,12 +360,35 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
R300_cp_microcode[i][0]);
}
- } else {
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) {
+ DRM_INFO("Loading R400 Microcode\n");
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ R420_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ R420_cp_microcode[i][0]);
+ }
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
+ DRM_INFO("Loading RS690 Microcode\n");
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ RS690_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ RS690_cp_microcode[i][0]);
+ }
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R580) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) {
+ DRM_INFO("Loading R500 Microcode\n");
for (i = 0; i < 256; i++) {
RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
- radeon_cp_microcode[i][1]);
+ R520_cp_microcode[i][1]);
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
- radeon_cp_microcode[i][0]);
+ R520_cp_microcode[i][0]);
}
}
}
@@ -1069,21 +483,24 @@ static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
static int radeon_do_engine_reset(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+ u32 clock_cntl_index = 0, mclk_cntl = 0, rbbm_soft_reset;
DRM_DEBUG("\n");
radeon_do_pixcache_flush(dev_priv);
- clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
- mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
-
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
- RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB |
- RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC |
- RADEON_FORCEON_AIC));
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
+ /* may need something similar for newer chips */
+ clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
+ mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
+
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
+ RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB |
+ RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC |
+ RADEON_FORCEON_AIC));
+ }
rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
@@ -1106,9 +523,15 @@ static int radeon_do_engine_reset(struct drm_device * dev)
RADEON_SOFT_RESET_RB)));
RADEON_READ(RADEON_RBBM_SOFT_RESET);
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
- RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
- RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
+ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ }
+
+ /* setup the raster pipes */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
+ radeon_init_pipes(dev_priv);
/* Reset the CP ring */
radeon_do_cp_reset(dev_priv);
@@ -1134,14 +557,15 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
* always appended to the fb which is not necessarily the case
*/
if (!dev_priv->new_memmap)
- RADEON_WRITE(RADEON_MC_FB_LOCATION,
+ radeon_write_fb_location(dev_priv,
((dev_priv->gart_vm_start - 1) & 0xffff0000)
| (dev_priv->fb_location >> 16));
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
- RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
- RADEON_WRITE(RADEON_MC_AGP_LOCATION,
+ radeon_write_agp_base(dev_priv, dev->agp->base);
+
+ radeon_write_agp_location(dev_priv,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
(dev_priv->gart_vm_start >> 16)));
@@ -1284,40 +708,79 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
/* Enable or disable IGP GART on the chip */
static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
{
- u32 temp, tmp;
+ u32 temp;
- tmp = RADEON_READ(RADEON_AIC_CNTL);
- DRM_DEBUG("setting igpgart AIC CNTL is %08X\n", tmp);
if (on) {
- DRM_DEBUG("programming igpgart %08X %08lX %08X\n",
+ DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
dev_priv->gart_vm_start,
(long)dev_priv->gart_info.bus_addr,
dev_priv->gart_size);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR,
- dev_priv->gart_info.bus_addr);
+ temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL);
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN |
+ RS690_BLOCK_GFX_D3_EN));
+ else
+ IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN);
+
+ IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
+ RS480_VA_SIZE_32MB));
+
+ temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID);
+ IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN |
+ RS480_TLB_ENABLE |
+ RS480_GTW_LAC_EN |
+ RS480_1LEVEL_GART));
+
+ temp = dev_priv->gart_info.bus_addr & 0xfffff000;
+ temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4;
+ IGP_WRITE_MCIND(RS480_GART_BASE, temp);
+
+ temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL);
+ IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) |
+ RS480_REQ_TYPE_SNOOP_DIS));
- temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp);
+ 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(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
dev_priv->gart_size = 32*1024*1024;
- RADEON_WRITE(RADEON_MC_AGP_LOCATION,
- (((dev_priv->gart_vm_start - 1 +
- dev_priv->gart_size) & 0xffff0000) |
- (dev_priv->gart_vm_start >> 16)));
+ temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
+ 0xffff0000) | (dev_priv->gart_vm_start >> 16));
+
+ radeon_write_agp_location(dev_priv, temp);
+
+ temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE);
+ IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
+ RS480_VA_SIZE_32MB));
+
+ do {
+ temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
+ if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
+ break;
+ DRM_UDELAY(1);
+ } while(1);
- temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp);
+ IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL,
+ RS480_GART_CACHE_INVALIDATE);
- RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1);
- RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
- RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0);
- }
+ do {
+ temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
+ if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
+ break;
+ DRM_UDELAY(1);
+ } while(1);
+
+ IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0);
+ } else {
+ IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
+ }
}
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
@@ -1339,7 +802,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
dev_priv->gart_vm_start +
dev_priv->gart_size - 1);
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+ radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
RADEON_PCIE_TX_GART_EN);
@@ -1354,7 +817,8 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;
- if (dev_priv->flags & RADEON_IS_IGPGART) {
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ (dev_priv->flags & RADEON_IS_IGPGART)) {
radeon_set_igpgart(dev_priv, on);
return;
}
@@ -1382,7 +846,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
/* Turn off AGP aperture -- is this required for PCI GART?
*/
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+ radeon_write_agp_location(dev_priv, 0xffffffc0);
RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */
} else {
RADEON_WRITE(RADEON_AIC_CNTL,
@@ -1590,10 +1054,9 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
dev->agp_buffer_map->handle);
}
- dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
- & 0xffff) << 16;
+ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
dev_priv->fb_size =
- ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000)
+ ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
- dev_priv->fb_location;
dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
@@ -1689,6 +1152,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
} else
#endif
{
+ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
/* if we have an offset set from userspace */
if (dev_priv->pcigart_offset_set) {
dev_priv->gart_info.bus_addr =
@@ -1845,7 +1309,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (init->func == RADEON_INIT_R300_CP)
- r300_init_reg_flags();
+ r300_init_reg_flags(dev);
switch (init->func) {
case RADEON_INIT_CP:
@@ -1867,12 +1331,12 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (dev_priv->cp_running) {
- DRM_DEBUG("%s while CP running\n", __FUNCTION__);
+ DRM_DEBUG("while CP running\n");
return 0;
}
if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
- DRM_DEBUG("%s called with bogus CP mode (%d)\n",
- __FUNCTION__, dev_priv->cp_mode);
+ DRM_DEBUG("called with bogus CP mode (%d)\n",
+ dev_priv->cp_mode);
return 0;
}
@@ -1937,8 +1401,12 @@ void radeon_do_release(struct drm_device * dev)
#ifdef __linux__
schedule();
#else
- DRM_SLEEPLOCK(&ret, &dev->dev_lock, PZERO, "rdnrel",
+#if defined(__FreeBSD__) && __FreeBSD_version > 500000
+ mtx_sleep(&ret, &dev->dev_lock, PZERO, "rdnrel",
1);
+#else
+ tsleep(&ret, PZERO, "rdnrel", 1);
+#endif
#endif
}
radeon_do_cp_stop(dev_priv);
@@ -1978,7 +1446,7 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_DEBUG("%s called before init done\n", __FUNCTION__);
+ DRM_DEBUG("called before init done\n");
return -EINVAL;
}
@@ -2255,6 +1723,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
case CHIP_R350:
case CHIP_R420:
case CHIP_RV410:
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV570:
+ case CHIP_R580:
dev_priv->flags |= RADEON_HAS_HIERZ;
break;
default:
diff --git a/sys/dev/pci/drm/radeon_drm.h b/sys/dev/pci/drm/radeon_drm.h
index 4594a837388..ffaa46e4b5c 100644
--- a/sys/dev/pci/drm/radeon_drm.h
+++ b/sys/dev/pci/drm/radeon_drm.h
@@ -225,9 +225,22 @@ typedef union {
#define R300_CMD_WAIT 7
# define R300_WAIT_2D 0x1
# define R300_WAIT_3D 0x2
+/* these two defines are DOING IT WRONG - however
+ * we have userspace which relies on using these.
+ * The wait interface is backwards compat new
+ * code should use the NEW_WAIT defines below
+ * THESE ARE NOT BIT FIELDS
+ */
# define R300_WAIT_2D_CLEAN 0x3
# define R300_WAIT_3D_CLEAN 0x4
+
+# define R300_NEW_WAIT_2D_3D 0x3
+# define R300_NEW_WAIT_2D_2D_CLEAN 0x4
+# define R300_NEW_WAIT_3D_3D_CLEAN 0x6
+# define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8
+
#define R300_CMD_SCRATCH 8
+#define R300_CMD_R500FP 9
typedef union {
unsigned int u;
@@ -256,6 +269,9 @@ typedef union {
struct {
unsigned char cmd_type, reg, n_bufs, flags;
} scratch;
+ struct {
+ unsigned char cmd_type, count, adrlo, adrhi_flags;
+ } r500fp;
} drm_r300_cmd_header_t;
#define RADEON_FRONT 0x1
@@ -266,6 +282,9 @@ typedef union {
#define RADEON_USE_HIERZ 0x40000000
#define RADEON_USE_COMP_ZBUF 0x20000000
+#define R500FP_CONSTANT_TYPE (1 << 1)
+#define R500FP_CONSTANT_CLAMP (1 << 2)
+
/* Primitive types
*/
#define RADEON_POINTS 0x1
@@ -656,6 +675,8 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_SCRATCH_OFFSET 11
#define RADEON_PARAM_CARD_TYPE 12
#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
+#define RADEON_PARAM_FB_LOCATION 14 /* FB location */
+#define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */
typedef struct drm_radeon_getparam {
int param;
diff --git a/sys/dev/pci/drm/radeon_drv.c b/sys/dev/pci/drm/radeon_drv.c
index 082a4844db5..1f1819ca383 100644
--- a/sys/dev/pci/drm/radeon_drv.c
+++ b/sys/dev/pci/drm/radeon_drv.c
@@ -55,7 +55,9 @@ radeon_configure(drm_device_t *dev)
dev->driver.preclose = radeon_driver_preclose;
dev->driver.postclose = radeon_driver_postclose;
dev->driver.lastclose = radeon_driver_lastclose;
- dev->driver.vblank_wait = radeon_driver_vblank_wait;
+ dev->driver.get_vblank_counter = radeon_get_vblank_counter;
+ dev->driver.enable_vblank = radeon_enable_vblank;
+ dev->driver.disable_vblank = radeon_disable_vblank;
dev->driver.irq_preinstall = radeon_driver_irq_preinstall;
dev->driver.irq_postinstall = radeon_driver_irq_postinstall;
dev->driver.irq_uninstall = radeon_driver_irq_uninstall;
diff --git a/sys/dev/pci/drm/radeon_drv.h b/sys/dev/pci/drm/radeon_drv.h
index a1745cddcf6..e263c610934 100644
--- a/sys/dev/pci/drm/radeon_drv.h
+++ b/sys/dev/pci/drm/radeon_drv.h
@@ -38,7 +38,7 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20060524"
+#define DRIVER_DATE "20080528"
/* Interface history:
*
@@ -98,10 +98,11 @@
* 1.26- Add support for variable size PCI(E) gart aperture
* 1.27- Add support for IGP GART
* 1.28- Add support for VBL on CRTC2
+ * 1.29- R500 3D cmd buffer support
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 28
+#define DRIVER_MINOR 29
#define DRIVER_PATCHLEVEL 0
/*
@@ -123,7 +124,14 @@ enum radeon_family {
CHIP_RV380,
CHIP_R420,
CHIP_RV410,
- CHIP_RS400,
+ CHIP_RS480,
+ CHIP_RS690,
+ CHIP_RV515,
+ CHIP_R520,
+ CHIP_RV530,
+ CHIP_RV560,
+ CHIP_RV570,
+ CHIP_R580,
CHIP_LAST,
};
@@ -289,20 +297,25 @@ typedef struct drm_radeon_private {
int vblank_crtc;
uint32_t irq_enable_reg;
int irq_enabled;
+ uint32_t r500_disp_irq_reg;
struct radeon_surface surfaces[RADEON_MAX_SURFACES];
- struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES];
+ struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
unsigned long pcigart_offset;
unsigned int pcigart_offset_set;
- struct ati_pcigart_info gart_info;
+ struct drm_ati_pcigart_info gart_info;
u32 scratch_ages[5];
+ unsigned int crtc_last_cnt;
+ unsigned int crtc2_last_cnt;
+
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
unsigned long fb_aper_offset;
+ int num_gb_pipes;
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
@@ -345,6 +358,7 @@ extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file
extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
extern void radeon_freelist_reset(struct drm_device * dev);
extern struct drm_buf *radeon_freelist_get(struct drm_device * dev);
@@ -365,13 +379,12 @@ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *
extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern void radeon_do_release(struct drm_device * dev);
-extern int radeon_driver_vblank_wait(struct drm_device * dev,
- unsigned int *sequence);
-extern int radeon_driver_vblank_wait2(struct drm_device * dev,
- unsigned int *sequence);
+extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
+extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
+extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
extern void radeon_driver_irq_preinstall(struct drm_device * dev);
-extern void radeon_driver_irq_postinstall(struct drm_device * dev);
+extern int radeon_driver_irq_postinstall(struct drm_device * dev);
extern void radeon_driver_irq_uninstall(struct drm_device * dev);
extern int radeon_vblank_crtc_get(struct drm_device *dev);
extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
@@ -390,11 +403,11 @@ extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
/* r300_cmdbuf.c */
-extern void r300_init_reg_flags(void);
+extern void r300_init_reg_flags(struct drm_device *dev);
extern int r300_do_cp_cmdbuf(struct drm_device *dev,
struct drm_file *file_priv,
- drm_radeon_kcmd_buffer_t* cmdbuf);
+ drm_radeon_kcmd_buffer_t *cmdbuf);
/* Flags for stats.boxes
*/
@@ -437,13 +450,13 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_PCIE_DATA 0x0034
#define RADEON_PCIE_TX_GART_CNTL 0x10
# define RADEON_PCIE_TX_GART_EN (1 << 0)
-# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1)
-# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1<<1)
-# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3<<1)
-# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0<<3)
-# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1<<3)
-# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1<<5)
-# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1<<8)
+# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0 << 1)
+# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1 << 1)
+# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3 << 1)
+# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0 << 3)
+# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1 << 3)
+# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1 << 5)
+# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1 << 8)
#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11
#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12
#define RADEON_PCIE_TX_GART_BASE 0x13
@@ -452,21 +465,101 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_PCIE_TX_GART_END_LO 0x16
#define RADEON_PCIE_TX_GART_END_HI 0x17
-#define RADEON_IGPGART_INDEX 0x168
-#define RADEON_IGPGART_DATA 0x16c
-#define RADEON_IGPGART_UNK_18 0x18
-#define RADEON_IGPGART_CTRL 0x2b
-#define RADEON_IGPGART_BASE_ADDR 0x2c
-#define RADEON_IGPGART_FLUSH 0x2e
-#define RADEON_IGPGART_ENABLE 0x38
-#define RADEON_IGPGART_UNK_39 0x39
-
+#define RS480_NB_MC_INDEX 0x168
+# define RS480_NB_MC_IND_WR_EN (1 << 8)
+#define RS480_NB_MC_DATA 0x16c
+
+#define RS690_MC_INDEX 0x78
+# define RS690_MC_INDEX_MASK 0x1ff
+# define RS690_MC_INDEX_WR_EN (1 << 9)
+# define RS690_MC_INDEX_WR_ACK 0x7f
+#define RS690_MC_DATA 0x7c
+
+/* MC indirect registers */
+#define RS480_MC_MISC_CNTL 0x18
+# define RS480_DISABLE_GTW (1 << 1)
+/* switch between MCIND GART and MM GART registers. 0 = mmgart, 1 = mcind gart */
+# define RS480_GART_INDEX_REG_EN (1 << 12)
+# define RS690_BLOCK_GFX_D3_EN (1 << 14)
+#define RS480_K8_FB_LOCATION 0x1e
+#define RS480_GART_FEATURE_ID 0x2b
+# define RS480_HANG_EN (1 << 11)
+# define RS480_TLB_ENABLE (1 << 18)
+# define RS480_P2P_ENABLE (1 << 19)
+# define RS480_GTW_LAC_EN (1 << 25)
+# define RS480_2LEVEL_GART (0 << 30)
+# define RS480_1LEVEL_GART (1 << 30)
+# define RS480_PDC_EN (1 << 31)
+#define RS480_GART_BASE 0x2c
+#define RS480_GART_CACHE_CNTRL 0x2e
+# define RS480_GART_CACHE_INVALIDATE (1 << 0) /* wait for it to clear */
+#define RS480_AGP_ADDRESS_SPACE_SIZE 0x38
+# define RS480_GART_EN (1 << 0)
+# define RS480_VA_SIZE_32MB (0 << 1)
+# define RS480_VA_SIZE_64MB (1 << 1)
+# define RS480_VA_SIZE_128MB (2 << 1)
+# define RS480_VA_SIZE_256MB (3 << 1)
+# define RS480_VA_SIZE_512MB (4 << 1)
+# define RS480_VA_SIZE_1GB (5 << 1)
+# define RS480_VA_SIZE_2GB (6 << 1)
+#define RS480_AGP_MODE_CNTL 0x39
+# define RS480_POST_GART_Q_SIZE (1 << 18)
+# define RS480_NONGART_SNOOP (1 << 19)
+# define RS480_AGP_RD_BUF_SIZE (1 << 20)
+# define RS480_REQ_TYPE_SNOOP_SHIFT 22
+# define RS480_REQ_TYPE_SNOOP_MASK 0x3
+# define RS480_REQ_TYPE_SNOOP_DIS (1 << 24)
+#define RS480_MC_MISC_UMA_CNTL 0x5f
+#define RS480_MC_MCLK_CNTL 0x7a
+#define RS480_MC_UMA_DUALCH_CNTL 0x86
+
+#define RS690_MC_FB_LOCATION 0x100
+#define RS690_MC_AGP_LOCATION 0x101
+#define RS690_MC_AGP_BASE 0x102
+#define RS690_MC_AGP_BASE_2 0x103
+
+#define R520_MC_IND_INDEX 0x70
+#define R520_MC_IND_WR_EN (1 << 24)
+#define R520_MC_IND_DATA 0x74
+
+#define RV515_MC_FB_LOCATION 0x01
+#define RV515_MC_AGP_LOCATION 0x02
+#define RV515_MC_AGP_BASE 0x03
+#define RV515_MC_AGP_BASE_2 0x04
+
+#define R520_MC_FB_LOCATION 0x04
+#define R520_MC_AGP_LOCATION 0x05
+#define R520_MC_AGP_BASE 0x06
+#define R520_MC_AGP_BASE_2 0x07
#define RADEON_MPP_TB_CONFIG 0x01c0
#define RADEON_MEM_CNTL 0x0140
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
+#define RADEON_AGP_BASE_2 0x015c /* r200+ only */
+#define RS480_AGP_BASE_2 0x0164
#define RADEON_AGP_BASE 0x0170
+/* pipe config regs */
+#define R400_GB_PIPE_SELECT 0x402c
+#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */
+#define R500_SU_REG_DEST 0x42c8
+#define R300_GB_TILE_CONFIG 0x4018
+# define R300_ENABLE_TILING (1 << 0)
+# define R300_PIPE_COUNT_RV350 (0 << 1)
+# define R300_PIPE_COUNT_R300 (3 << 1)
+# define R300_PIPE_COUNT_R420_3P (6 << 1)
+# define R300_PIPE_COUNT_R420 (7 << 1)
+# define R300_TILE_SIZE_8 (0 << 4)
+# define R300_TILE_SIZE_16 (1 << 4)
+# define R300_TILE_SIZE_32 (2 << 4)
+# define R300_SUBPIXEL_1_12 (0 << 16)
+# define R300_SUBPIXEL_1_16 (1 << 16)
+#define R300_DST_PIPE_CONFIG 0x170c
+# define R300_PIPE_AUTO_CONFIG (1 << 31)
+#define R300_RB2D_DSTCACHE_MODE 0x3428
+# define R300_DC_AUTOFLUSH_ENABLE (1 << 8)
+# define R300_DC_DC_DISABLE_IGNORE_PE (1 << 17)
+
#define RADEON_RB3D_COLOROFFSET 0x1c40
#define RADEON_RB3D_COLORPITCH 0x1c48
@@ -512,6 +605,12 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
+#define RADEON_CRTC_CRNT_FRAME 0x0214
+#define RADEON_CRTC2_CRNT_FRAME 0x0314
+
+#define RADEON_CRTC_STATUS 0x005c
+#define RADEON_CRTC2_STATUS 0x03fc
+
#define RADEON_GEN_INT_CNTL 0x0040
# define RADEON_CRTC_VBLANK_MASK (1 << 0)
# define RADEON_CRTC2_VBLANK_MASK (1 << 9)
@@ -527,6 +626,8 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
# define RADEON_SW_INT_TEST (1 << 25)
# define RADEON_SW_INT_TEST_ACK (1 << 25)
# define RADEON_SW_INT_FIRE (1 << 26)
+# define R500_DISPLAY_INT_STATUS (1 << 0)
+
#define RADEON_HOST_PATH_CNTL 0x0130
# define RADEON_HDP_SOFT_RESET (1 << 26)
@@ -597,11 +698,18 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
# define RADEON_RB3D_ZC_FREE (1 << 2)
# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
# define RADEON_RB3D_ZC_BUSY (1 << 31)
+#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 RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
# define RADEON_RB3D_DC_FLUSH (3 << 0)
# define RADEON_RB3D_DC_FREE (3 << 2)
# define RADEON_RB3D_DC_FLUSH_ALL 0xf
# define RADEON_RB3D_DC_BUSY (1 << 31)
+#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c
+# define R300_RB3D_DC_FINISH (1 << 4)
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_Z_TEST_MASK (7 << 4)
# define RADEON_Z_TEST_ALWAYS (7 << 4)
@@ -1039,7 +1147,30 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_VHA_BACKFRAME0_OFF_V_2 0x1894
#define RADEON_VHA_BACKFRAME1_OFF_PITCH_V_2 0x1898
+#define R500_D1CRTC_STATUS 0x609c
+#define R500_D2CRTC_STATUS 0x689c
+#define R500_CRTC_V_BLANK (1<<0)
+#define R500_D1CRTC_FRAME_COUNT 0x60a4
+#define R500_D2CRTC_FRAME_COUNT 0x68a4
+
+#define R500_D1MODE_V_COUNTER 0x6530
+#define R500_D2MODE_V_COUNTER 0x6d30
+
+#define R500_D1MODE_VBLANK_STATUS 0x6534
+#define R500_D2MODE_VBLANK_STATUS 0x6d34
+#define R500_VBLANK_OCCURED (1<<0)
+#define R500_VBLANK_ACK (1<<4)
+#define R500_VBLANK_STAT (1<<12)
+#define R500_VBLANK_INT (1<<16)
+
+#define R500_DxMODE_INT_MASK 0x6540
+#define R500_D1MODE_INT_MASK (1<<0)
+#define R500_D2MODE_INT_MASK (1<<8)
+
+#define R500_DISP_INTERRUPT_STATUS 0x7edc
+#define R500_D1_VBLANK_INTERRUPT (1 << 4)
+#define R500_D2_VBLANK_INTERRUPT (1 << 5)
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -1057,8 +1188,8 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_PCIGART_TABLE_SIZE (32*1024)
-#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
-#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
+#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
+#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
@@ -1069,14 +1200,6 @@ do { \
RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
} while (0)
-#define RADEON_WRITE_IGPGART( addr, val ) \
-do { \
- RADEON_WRITE( RADEON_IGPGART_INDEX, \
- ((addr) & 0x7f) | (1 << 8)); \
- RADEON_WRITE( RADEON_IGPGART_DATA, (val) ); \
- RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f ); \
-} while (0)
-
#define RADEON_WRITE_PCIE( addr, val ) \
do { \
RADEON_WRITE8( RADEON_PCIE_INDEX, \
@@ -1084,6 +1207,36 @@ do { \
RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \
} while (0)
+#define R500_WRITE_MCIND( addr, val ) \
+do { \
+ RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \
+ RADEON_WRITE(R520_MC_IND_DATA, (val)); \
+ RADEON_WRITE(R520_MC_IND_INDEX, 0); \
+} while (0)
+
+#define RS480_WRITE_MCIND( addr, val ) \
+do { \
+ RADEON_WRITE( RS480_NB_MC_INDEX, \
+ ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN); \
+ RADEON_WRITE( RS480_NB_MC_DATA, (val) ); \
+ RADEON_WRITE( RS480_NB_MC_INDEX, 0xff ); \
+} while (0)
+
+#define RS690_WRITE_MCIND( addr, val ) \
+do { \
+ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \
+ RADEON_WRITE(RS690_MC_DATA, val); \
+ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
+} while (0)
+
+#define IGP_WRITE_MCIND( addr, val ) \
+do { \
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \
+ RS690_WRITE_MCIND( addr, val ); \
+ else \
+ RS480_WRITE_MCIND( addr, val ); \
+} while (0)
+
#define CP_PACKET0( reg, n ) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET0_TABLE( reg, n ) \
@@ -1124,23 +1277,43 @@ do { \
} while (0)
#define RADEON_FLUSH_CACHE() do { \
- OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
- OUT_RING( RADEON_RB3D_DC_FLUSH ); \
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
+ OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( RADEON_RB3D_DC_FLUSH ); \
+ } else { \
+ OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( RADEON_RB3D_DC_FLUSH ); \
+ } \
} while (0)
#define RADEON_PURGE_CACHE() do { \
- OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
- OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \
+ 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 ); \
+ } else { \
+ OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \
+ } \
} while (0)
#define RADEON_FLUSH_ZCACHE() do { \
- OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
- OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
+ OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
+ } else { \
+ OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( R300_ZC_FLUSH ); \
+ } \
} while (0)
#define RADEON_PURGE_ZCACHE() do { \
- OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
- OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
+ 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 ); \
+ } else { \
+ OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
+ OUT_RING( R300_ZC_FLUSH_ALL ); \
+ } \
} while (0)
/* ================================================================
@@ -1194,8 +1367,7 @@ do { \
#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
- DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
- n, __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
COMMIT_RING(); \
diff --git a/sys/dev/pci/drm/radeon_irq.c b/sys/dev/pci/drm/radeon_irq.c
index 1ece6399d6d..d21761fb6a5 100644
--- a/sys/dev/pci/drm/radeon_irq.c
+++ b/sys/dev/pci/drm/radeon_irq.c
@@ -35,12 +35,130 @@
#include "radeon_drm.h"
#include "radeon_drv.h"
-static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
- u32 mask)
+static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
{
- u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (state)
+ dev_priv->irq_enable_reg |= mask;
+ else
+ dev_priv->irq_enable_reg &= ~mask;
+
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
+}
+
+static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (state)
+ dev_priv->r500_disp_irq_reg |= mask;
+ else
+ dev_priv->r500_disp_irq_reg &= ~mask;
+
+ RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
+}
+
+int radeon_enable_vblank(struct drm_device *dev, int crtc)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ switch (crtc) {
+ case 0:
+ r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
+ break;
+ case 1:
+ r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return EINVAL;
+ }
+ } else {
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+void radeon_disable_vblank(struct drm_device *dev, int crtc)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ switch (crtc) {
+ case 0:
+ r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
+ break;
+ case 1:
+ r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+ } else {
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+ }
+}
+
+static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, u32 *r500_disp_int)
+{
+ u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS);
+ u32 irq_mask = RADEON_SW_INT_TEST;
+
+ *r500_disp_int = 0;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ /* vbl interrupts in a different place */
+
+ if (irqs & R500_DISPLAY_INT_STATUS) {
+ /* if a display interrupt */
+ u32 disp_irq;
+
+ disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS);
+
+ *r500_disp_int = disp_irq;
+ if (disp_irq & R500_D1_VBLANK_INTERRUPT) {
+ RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK);
+ }
+ if (disp_irq & R500_D2_VBLANK_INTERRUPT) {
+ RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK);
+ }
+ }
+ irq_mask |= R500_DISPLAY_INT_STATUS;
+ } else
+ irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT;
+
+ irqs &= irq_mask;
+
if (irqs)
RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
+
return irqs;
}
@@ -68,44 +186,33 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
u32 stat;
+ u32 r500_disp_int;
/* Only consider the bits we're interested in - others could be used
* outside the DRM
*/
- stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
- RADEON_CRTC_VBLANK_STAT |
- RADEON_CRTC2_VBLANK_STAT));
+ stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
if (!stat)
return IRQ_NONE;
stat &= dev_priv->irq_enable_reg;
/* SW interrupt */
- if (stat & RADEON_SW_INT_TEST) {
+ if (stat & RADEON_SW_INT_TEST)
DRM_WAKEUP(&dev_priv->swi_queue);
- }
/* VBLANK interrupt */
- if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) {
- int vblank_crtc = dev_priv->vblank_crtc;
-
- if ((vblank_crtc &
- (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) ==
- (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
- if (stat & RADEON_CRTC_VBLANK_STAT)
- atomic_inc(&dev->vbl_received);
- if (stat & RADEON_CRTC2_VBLANK_STAT)
- atomic_inc(&dev->vbl_received2);
- } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
- (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
- ((stat & RADEON_CRTC2_VBLANK_STAT) &&
- (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
- atomic_inc(&dev->vbl_received);
-
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
+ drm_handle_vblank(dev, 0);
+ if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
+ drm_handle_vblank(dev, 1);
+ } else {
+ if (stat & RADEON_CRTC_VBLANK_STAT)
+ drm_handle_vblank(dev, 0);
+ if (stat & RADEON_CRTC2_VBLANK_STAT)
+ drm_handle_vblank(dev, 1);
}
-
return IRQ_HANDLED;
}
@@ -144,55 +251,39 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
return ret;
}
-static int radeon_driver_vblank_do_wait(struct drm_device * dev,
- unsigned int *sequence,
- int crtc)
+u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
{
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *) dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
- int ack = 0;
- atomic_t *counter;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 crtc_cnt_reg, crtc_status_reg;
+
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- if (crtc == DRM_RADEON_VBLANK_CRTC1) {
- counter = &dev->vbl_received;
- ack |= RADEON_CRTC_VBLANK_STAT;
- } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
- counter = &dev->vbl_received2;
- ack |= RADEON_CRTC2_VBLANK_STAT;
- } else
- return -EINVAL;
-
- radeon_acknowledge_irqs(dev_priv, ack);
-
- dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
-
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1 << 23)));
-
- *sequence = cur_vblank;
-
- return ret;
-}
-
-int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
-}
-
-int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
+ 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);
+
+ } 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);
+ }
}
/* Needs the lock as it touches the ring.
@@ -206,7 +297,7 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -228,53 +319,48 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
drm_radeon_irq_wait_t *irqwait = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
return radeon_wait_irq(dev, irqwait->irq_seq);
}
-static void radeon_enable_interrupt(struct drm_device *dev)
-{
- drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
-
- dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
- dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
-
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
- dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
-
- RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
- dev_priv->irq_enabled = 1;
-}
-
/* drm_dma.h hooks
*/
void radeon_driver_irq_preinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
+ u32 dummy;
/* Disable *all* interrupts */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
/* Clear bits if they're already high */
- radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
- RADEON_CRTC_VBLANK_STAT |
- RADEON_CRTC2_VBLANK_STAT));
+ radeon_acknowledge_irqs(dev_priv, &dummy);
}
-void radeon_driver_irq_postinstall(struct drm_device * dev)
+int radeon_driver_irq_postinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
+ int ret;
atomic_set(&dev_priv->swi_emitted, 0);
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
- radeon_enable_interrupt(dev);
+ ret = drm_vblank_init(dev, 2);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0x001fffff;
+
+ radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
+
+ return 0;
}
void radeon_driver_irq_uninstall(struct drm_device * dev)
@@ -286,6 +372,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
dev_priv->irq_enabled = 0;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
/* Disable *all* interrupts */
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
}
@@ -297,14 +385,23 @@ int radeon_vblank_crtc_get(struct drm_device *dev)
u32 flag;
u32 value;
- 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;
+ 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;
}
@@ -316,6 +413,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
return -EINVAL;
}
dev_priv->vblank_crtc = (unsigned int)value;
- radeon_enable_interrupt(dev);
return 0;
}
diff --git a/sys/dev/pci/drm/radeon_mem.c b/sys/dev/pci/drm/radeon_mem.c
index 9947e9409b5..1e582ee0799 100644
--- a/sys/dev/pci/drm/radeon_mem.c
+++ b/sys/dev/pci/drm/radeon_mem.c
@@ -224,7 +224,7 @@ int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_p
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -259,7 +259,7 @@ int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_pr
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -285,7 +285,7 @@ int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *fi
struct mem_block **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/sys/dev/pci/drm/radeon_microcode.h b/sys/dev/pci/drm/radeon_microcode.h
new file mode 100644
index 00000000000..a50b58ea232
--- /dev/null
+++ b/sys/dev/pci/drm/radeon_microcode.h
@@ -0,0 +1,1844 @@
+/*
+ * Copyright 2007 Advanced Micro Devices, Inc.
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ *
+ */
+
+#ifndef RADEON_MICROCODE_H
+#define RADEON_MICROCODE_H
+
+/* production radeon ucode r1xx-r6xx */
+static const u32 R100_cp_microcode[][2]={
+ { 0x21007000, 0000000000 },
+ { 0x20007000, 0000000000 },
+ { 0x000000b4, 0x00000004 },
+ { 0x000000b8, 0x00000004 },
+ { 0x6f5b4d4c, 0000000000 },
+ { 0x4c4c427f, 0000000000 },
+ { 0x5b568a92, 0000000000 },
+ { 0x4ca09c6d, 0000000000 },
+ { 0xad4c4c4c, 0000000000 },
+ { 0x4ce1af3d, 0000000000 },
+ { 0xd8afafaf, 0000000000 },
+ { 0xd64c4cdc, 0000000000 },
+ { 0x4cd10d10, 0000000000 },
+ { 0x000f0000, 0x00000016 },
+ { 0x362f242d, 0000000000 },
+ { 0x00000012, 0x00000004 },
+ { 0x000f0000, 0x00000016 },
+ { 0x362f282d, 0000000000 },
+ { 0x000380e7, 0x00000002 },
+ { 0x04002c97, 0x00000002 },
+ { 0x000f0001, 0x00000016 },
+ { 0x333a3730, 0000000000 },
+ { 0x000077ef, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x00000021, 0x0000001a },
+ { 0x00004000, 0x0000001e },
+ { 0x00061000, 0x00000002 },
+ { 0x00000021, 0x0000001a },
+ { 0x00004000, 0x0000001e },
+ { 0x00061000, 0x00000002 },
+ { 0x00000021, 0x0000001a },
+ { 0x00004000, 0x0000001e },
+ { 0x00000017, 0x00000004 },
+ { 0x0003802b, 0x00000002 },
+ { 0x040067e0, 0x00000002 },
+ { 0x00000017, 0x00000004 },
+ { 0x000077e0, 0x00000002 },
+ { 0x00065000, 0x00000002 },
+ { 0x000037e1, 0x00000002 },
+ { 0x040067e1, 0x00000006 },
+ { 0x000077e0, 0x00000002 },
+ { 0x000077e1, 0x00000002 },
+ { 0x000077e1, 0x00000006 },
+ { 0xffffffff, 0000000000 },
+ { 0x10000000, 0000000000 },
+ { 0x0003802b, 0x00000002 },
+ { 0x040067e0, 0x00000006 },
+ { 0x00007675, 0x00000002 },
+ { 0x00007676, 0x00000002 },
+ { 0x00007677, 0x00000002 },
+ { 0x00007678, 0x00000006 },
+ { 0x0003802c, 0x00000002 },
+ { 0x04002676, 0x00000002 },
+ { 0x00007677, 0x00000002 },
+ { 0x00007678, 0x00000006 },
+ { 0x0000002f, 0x00000018 },
+ { 0x0000002f, 0x00000018 },
+ { 0000000000, 0x00000006 },
+ { 0x00000030, 0x00000018 },
+ { 0x00000030, 0x00000018 },
+ { 0000000000, 0x00000006 },
+ { 0x01605000, 0x00000002 },
+ { 0x00065000, 0x00000002 },
+ { 0x00098000, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x64c0603e, 0x00000004 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x00080000, 0x00000016 },
+ { 0000000000, 0000000000 },
+ { 0x0400251d, 0x00000002 },
+ { 0x00007580, 0x00000002 },
+ { 0x00067581, 0x00000002 },
+ { 0x04002580, 0x00000002 },
+ { 0x00067581, 0x00000002 },
+ { 0x00000049, 0x00000004 },
+ { 0x00005000, 0000000000 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x0000750e, 0x00000002 },
+ { 0x00019000, 0x00000002 },
+ { 0x00011055, 0x00000014 },
+ { 0x00000055, 0x00000012 },
+ { 0x0400250f, 0x00000002 },
+ { 0x0000504f, 0x00000004 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x00007565, 0x00000002 },
+ { 0x00007566, 0x00000002 },
+ { 0x00000058, 0x00000004 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x01e655b4, 0x00000002 },
+ { 0x4401b0e4, 0x00000002 },
+ { 0x01c110e4, 0x00000002 },
+ { 0x26667066, 0x00000018 },
+ { 0x040c2565, 0x00000002 },
+ { 0x00000066, 0x00000018 },
+ { 0x04002564, 0x00000002 },
+ { 0x00007566, 0x00000002 },
+ { 0x0000005d, 0x00000004 },
+ { 0x00401069, 0x00000008 },
+ { 0x00101000, 0x00000002 },
+ { 0x000d80ff, 0x00000002 },
+ { 0x0080006c, 0x00000008 },
+ { 0x000f9000, 0x00000002 },
+ { 0x000e00ff, 0x00000002 },
+ { 0000000000, 0x00000006 },
+ { 0x0000008f, 0x00000018 },
+ { 0x0000005b, 0x00000004 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x00007576, 0x00000002 },
+ { 0x00065000, 0x00000002 },
+ { 0x00009000, 0x00000002 },
+ { 0x00041000, 0x00000002 },
+ { 0x0c00350e, 0x00000002 },
+ { 0x00049000, 0x00000002 },
+ { 0x00051000, 0x00000002 },
+ { 0x01e785f8, 0x00000002 },
+ { 0x00200000, 0x00000002 },
+ { 0x0060007e, 0x0000000c },
+ { 0x00007563, 0x00000002 },
+ { 0x006075f0, 0x00000021 },
+ { 0x20007073, 0x00000004 },
+ { 0x00005073, 0x00000004 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x00007576, 0x00000002 },
+ { 0x00007577, 0x00000002 },
+ { 0x0000750e, 0x00000002 },
+ { 0x0000750f, 0x00000002 },
+ { 0x00a05000, 0x00000002 },
+ { 0x00600083, 0x0000000c },
+ { 0x006075f0, 0x00000021 },
+ { 0x000075f8, 0x00000002 },
+ { 0x00000083, 0x00000004 },
+ { 0x000a750e, 0x00000002 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x0020750f, 0x00000002 },
+ { 0x00600086, 0x00000004 },
+ { 0x00007570, 0x00000002 },
+ { 0x00007571, 0x00000002 },
+ { 0x00007572, 0x00000006 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x00005000, 0x00000002 },
+ { 0x00a05000, 0x00000002 },
+ { 0x00007568, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x00000095, 0x0000000c },
+ { 0x00058000, 0x00000002 },
+ { 0x0c607562, 0x00000002 },
+ { 0x00000097, 0x00000004 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x00600096, 0x00000004 },
+ { 0x400070e5, 0000000000 },
+ { 0x000380e6, 0x00000002 },
+ { 0x040025c5, 0x00000002 },
+ { 0x000380e5, 0x00000002 },
+ { 0x000000a8, 0x0000001c },
+ { 0x000650aa, 0x00000018 },
+ { 0x040025bb, 0x00000002 },
+ { 0x000610ab, 0x00000018 },
+ { 0x040075bc, 0000000000 },
+ { 0x000075bb, 0x00000002 },
+ { 0x000075bc, 0000000000 },
+ { 0x00090000, 0x00000006 },
+ { 0x00090000, 0x00000002 },
+ { 0x000d8002, 0x00000006 },
+ { 0x00007832, 0x00000002 },
+ { 0x00005000, 0x00000002 },
+ { 0x000380e7, 0x00000002 },
+ { 0x04002c97, 0x00000002 },
+ { 0x00007820, 0x00000002 },
+ { 0x00007821, 0x00000002 },
+ { 0x00007800, 0000000000 },
+ { 0x01200000, 0x00000002 },
+ { 0x20077000, 0x00000002 },
+ { 0x01200000, 0x00000002 },
+ { 0x20007000, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x0120751b, 0x00000002 },
+ { 0x8040750a, 0x00000002 },
+ { 0x8040750b, 0x00000002 },
+ { 0x00110000, 0x00000002 },
+ { 0x000380e5, 0x00000002 },
+ { 0x000000c6, 0x0000001c },
+ { 0x000610ab, 0x00000018 },
+ { 0x844075bd, 0x00000002 },
+ { 0x000610aa, 0x00000018 },
+ { 0x840075bb, 0x00000002 },
+ { 0x000610ab, 0x00000018 },
+ { 0x844075bc, 0x00000002 },
+ { 0x000000c9, 0x00000004 },
+ { 0x804075bd, 0x00000002 },
+ { 0x800075bb, 0x00000002 },
+ { 0x804075bc, 0x00000002 },
+ { 0x00108000, 0x00000002 },
+ { 0x01400000, 0x00000002 },
+ { 0x006000cd, 0x0000000c },
+ { 0x20c07000, 0x00000020 },
+ { 0x000000cf, 0x00000012 },
+ { 0x00800000, 0x00000006 },
+ { 0x0080751d, 0x00000006 },
+ { 0000000000, 0000000000 },
+ { 0x0000775c, 0x00000002 },
+ { 0x00a05000, 0x00000002 },
+ { 0x00661000, 0x00000002 },
+ { 0x0460275d, 0x00000020 },
+ { 0x00004000, 0000000000 },
+ { 0x01e00830, 0x00000002 },
+ { 0x21007000, 0000000000 },
+ { 0x6464614d, 0000000000 },
+ { 0x69687420, 0000000000 },
+ { 0x00000073, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x00005000, 0x00000002 },
+ { 0x000380d0, 0x00000002 },
+ { 0x040025e0, 0x00000002 },
+ { 0x000075e1, 0000000000 },
+ { 0x00000001, 0000000000 },
+ { 0x000380e0, 0x00000002 },
+ { 0x04002394, 0x00000002 },
+ { 0x00005000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x00000008, 0000000000 },
+ { 0x00000004, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+};
+
+static const u32 R200_cp_microcode[][2]={
+ { 0x21007000, 0000000000 },
+ { 0x20007000, 0000000000 },
+ { 0x000000bf, 0x00000004 },
+ { 0x000000c3, 0x00000004 },
+ { 0x7a685e5d, 0000000000 },
+ { 0x5d5d5588, 0000000000 },
+ { 0x68659197, 0000000000 },
+ { 0x5da19f78, 0000000000 },
+ { 0x5d5d5d5d, 0000000000 },
+ { 0x5dee5d50, 0000000000 },
+ { 0xf2acacac, 0000000000 },
+ { 0xe75df9e9, 0000000000 },
+ { 0xb1dd0e11, 0000000000 },
+ { 0xe2afafaf, 0000000000 },
+ { 0x000f0000, 0x00000016 },
+ { 0x452f232d, 0000000000 },
+ { 0x00000013, 0x00000004 },
+ { 0x000f0000, 0x00000016 },
+ { 0x452f272d, 0000000000 },
+ { 0x000f0001, 0x00000016 },
+ { 0x3e4d4a37, 0000000000 },
+ { 0x000077ef, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x00000020, 0x0000001a },
+ { 0x00004000, 0x0000001e },
+ { 0x00061000, 0x00000002 },
+ { 0x00000020, 0x0000001a },
+ { 0x00004000, 0x0000001e },
+ { 0x00061000, 0x00000002 },
+ { 0x00000020, 0x0000001a },
+ { 0x00004000, 0x0000001e },
+ { 0x00000016, 0x00000004 },
+ { 0x0003802a, 0x00000002 },
+ { 0x040067e0, 0x00000002 },
+ { 0x00000016, 0x00000004 },
+ { 0x000077e0, 0x00000002 },
+ { 0x00065000, 0x00000002 },
+ { 0x000037e1, 0x00000002 },
+ { 0x040067e1, 0x00000006 },
+ { 0x000077e0, 0x00000002 },
+ { 0x000077e1, 0x00000002 },
+ { 0x000077e1, 0x00000006 },
+ { 0xffffffff, 0000000000 },
+ { 0x10000000, 0000000000 },
+ { 0x07f007f0, 0000000000 },
+ { 0x0003802a, 0x00000002 },
+ { 0x040067e0, 0x00000006 },
+ { 0x0003802c, 0x00000002 },
+ { 0x04002741, 0x00000002 },
+ { 0x04002741, 0x00000002 },
+ { 0x04002743, 0x00000002 },
+ { 0x00007675, 0x00000002 },
+ { 0x00007676, 0x00000002 },
+ { 0x00007677, 0x00000002 },
+ { 0x00007678, 0x00000006 },
+ { 0x0003802c, 0x00000002 },
+ { 0x04002741, 0x00000002 },
+ { 0x04002741, 0x00000002 },
+ { 0x04002743, 0x00000002 },
+ { 0x00007676, 0x00000002 },
+ { 0x00007677, 0x00000002 },
+ { 0x00007678, 0x00000006 },
+ { 0x0003802b, 0x00000002 },
+ { 0x04002676, 0x00000002 },
+ { 0x00007677, 0x00000002 },
+ { 0x0003802c, 0x00000002 },
+ { 0x04002741, 0x00000002 },
+ { 0x04002743, 0x00000002 },
+ { 0x00007678, 0x00000006 },
+ { 0x0003802c, 0x00000002 },
+ { 0x04002741, 0x00000002 },
+ { 0x04002741, 0x00000002 },
+ { 0x04002743, 0x00000002 },
+ { 0x00007678, 0x00000006 },
+ { 0x0000002f, 0x00000018 },
+ { 0x0000002f, 0x00000018 },
+ { 0000000000, 0x00000006 },
+ { 0x00000037, 0x00000018 },
+ { 0x00000037, 0x00000018 },
+ { 0000000000, 0x00000006 },
+ { 0x01605000, 0x00000002 },
+ { 0x00065000, 0x00000002 },
+ { 0x00098000, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x64c06051, 0x00000004 },
+ { 0x00080000, 0x00000016 },
+ { 0000000000, 0000000000 },
+ { 0x0400251d, 0x00000002 },
+ { 0x00007580, 0x00000002 },
+ { 0x00067581, 0x00000002 },
+ { 0x04002580, 0x00000002 },
+ { 0x00067581, 0x00000002 },
+ { 0x0000005a, 0x00000004 },
+ { 0x00005000, 0000000000 },
+ { 0x00061000, 0x00000002 },
+ { 0x0000750e, 0x00000002 },
+ { 0x00019000, 0x00000002 },
+ { 0x00011064, 0x00000014 },
+ { 0x00000064, 0x00000012 },
+ { 0x0400250f, 0x00000002 },
+ { 0x0000505e, 0x00000004 },
+ { 0x00007565, 0x00000002 },
+ { 0x00007566, 0x00000002 },
+ { 0x00000065, 0x00000004 },
+ { 0x01e655b4, 0x00000002 },
+ { 0x4401b0f0, 0x00000002 },
+ { 0x01c110f0, 0x00000002 },
+ { 0x26667071, 0x00000018 },
+ { 0x040c2565, 0x00000002 },
+ { 0x00000071, 0x00000018 },
+ { 0x04002564, 0x00000002 },
+ { 0x00007566, 0x00000002 },
+ { 0x00000068, 0x00000004 },
+ { 0x00401074, 0x00000008 },
+ { 0x00101000, 0x00000002 },
+ { 0x000d80ff, 0x00000002 },
+ { 0x00800077, 0x00000008 },
+ { 0x000f9000, 0x00000002 },
+ { 0x000e00ff, 0x00000002 },
+ { 0000000000, 0x00000006 },
+ { 0x00000094, 0x00000018 },
+ { 0x00000068, 0x00000004 },
+ { 0x00007576, 0x00000002 },
+ { 0x00065000, 0x00000002 },
+ { 0x00009000, 0x00000002 },
+ { 0x00041000, 0x00000002 },
+ { 0x0c00350e, 0x00000002 },
+ { 0x00049000, 0x00000002 },
+ { 0x00051000, 0x00000002 },
+ { 0x01e785f8, 0x00000002 },
+ { 0x00200000, 0x00000002 },
+ { 0x00600087, 0x0000000c },
+ { 0x00007563, 0x00000002 },
+ { 0x006075f0, 0x00000021 },
+ { 0x2000707c, 0x00000004 },
+ { 0x0000507c, 0x00000004 },
+ { 0x00007576, 0x00000002 },
+ { 0x00007577, 0x00000002 },
+ { 0x0000750e, 0x00000002 },
+ { 0x0000750f, 0x00000002 },
+ { 0x00a05000, 0x00000002 },
+ { 0x0060008a, 0x0000000c },
+ { 0x006075f0, 0x00000021 },
+ { 0x000075f8, 0x00000002 },
+ { 0x0000008a, 0x00000004 },
+ { 0x000a750e, 0x00000002 },
+ { 0x0020750f, 0x00000002 },
+ { 0x0060008d, 0x00000004 },
+ { 0x00007570, 0x00000002 },
+ { 0x00007571, 0x00000002 },
+ { 0x00007572, 0x00000006 },
+ { 0x00005000, 0x00000002 },
+ { 0x00a05000, 0x00000002 },
+ { 0x00007568, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x00000098, 0x0000000c },
+ { 0x00058000, 0x00000002 },
+ { 0x0c607562, 0x00000002 },
+ { 0x0000009a, 0x00000004 },
+ { 0x00600099, 0x00000004 },
+ { 0x400070f1, 0000000000 },
+ { 0x000380f1, 0x00000002 },
+ { 0x000000a7, 0x0000001c },
+ { 0x000650a9, 0x00000018 },
+ { 0x040025bb, 0x00000002 },
+ { 0x000610aa, 0x00000018 },
+ { 0x040075bc, 0000000000 },
+ { 0x000075bb, 0x00000002 },
+ { 0x000075bc, 0000000000 },
+ { 0x00090000, 0x00000006 },
+ { 0x00090000, 0x00000002 },
+ { 0x000d8002, 0x00000006 },
+ { 0x00005000, 0x00000002 },
+ { 0x00007821, 0x00000002 },
+ { 0x00007800, 0000000000 },
+ { 0x00007821, 0x00000002 },
+ { 0x00007800, 0000000000 },
+ { 0x01665000, 0x00000002 },
+ { 0x000a0000, 0x00000002 },
+ { 0x000671cc, 0x00000002 },
+ { 0x0286f1cd, 0x00000002 },
+ { 0x000000b7, 0x00000010 },
+ { 0x21007000, 0000000000 },
+ { 0x000000be, 0x0000001c },
+ { 0x00065000, 0x00000002 },
+ { 0x000a0000, 0x00000002 },
+ { 0x00061000, 0x00000002 },
+ { 0x000b0000, 0x00000002 },
+ { 0x38067000, 0x00000002 },
+ { 0x000a00ba, 0x00000004 },
+ { 0x20007000, 0000000000 },
+ { 0x01200000, 0x00000002 },
+ { 0x20077000, 0x00000002 },
+ { 0x01200000, 0x00000002 },
+ { 0x20007000, 0000000000 },
+ { 0x00061000, 0x00000002 },
+ { 0x0120751b, 0x00000002 },
+ { 0x8040750a, 0x00000002 },
+ { 0x8040750b, 0x00000002 },
+ { 0x00110000, 0x00000002 },
+ { 0x000380f1, 0x00000002 },
+ { 0x000000d1, 0x0000001c },
+ { 0x000610aa, 0x00000018 },
+ { 0x844075bd, 0x00000002 },
+ { 0x000610a9, 0x00000018 },
+ { 0x840075bb, 0x00000002 },
+ { 0x000610aa, 0x00000018 },
+ { 0x844075bc, 0x00000002 },
+ { 0x000000d4, 0x00000004 },
+ { 0x804075bd, 0x00000002 },
+ { 0x800075bb, 0x00000002 },
+ { 0x804075bc, 0x00000002 },
+ { 0x00108000, 0x00000002 },
+ { 0x01400000, 0x00000002 },
+ { 0x006000d8, 0x0000000c },
+ { 0x20c07000, 0x00000020 },
+ { 0x000000da, 0x00000012 },
+ { 0x00800000, 0x00000006 },
+ { 0x0080751d, 0x00000006 },
+ { 0x000025bb, 0x00000002 },
+ { 0x000040d4, 0x00000004 },
+ { 0x0000775c, 0x00000002 },
+ { 0x00a05000, 0x00000002 },
+ { 0x00661000, 0x00000002 },
+ { 0x0460275d, 0x00000020 },
+ { 0x00004000, 0000000000 },
+ { 0x00007999, 0x00000002 },
+ { 0x00a05000, 0x00000002 },
+ { 0x00661000, 0x00000002 },
+ { 0x0460299b, 0x00000020 },
+ { 0x00004000, 0000000000 },
+ { 0x01e00830, 0x00000002 },
+ { 0x21007000, 0000000000 },
+ { 0x00005000, 0x00000002 },
+ { 0x00038056, 0x00000002 },
+ { 0x040025e0, 0x00000002 },
+ { 0x000075e1, 0000000000 },
+ { 0x00000001, 0000000000 },
+ { 0x000380ed, 0x00000002 },
+ { 0x04007394, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x000078c4, 0x00000002 },
+ { 0x000078c5, 0x00000002 },
+ { 0x000078c6, 0x00000002 },
+ { 0x00007924, 0x00000002 },
+ { 0x00007925, 0x00000002 },
+ { 0x00007926, 0x00000002 },
+ { 0x000000f2, 0x00000004 },
+ { 0x00007924, 0x00000002 },
+ { 0x00007925, 0x00000002 },
+ { 0x00007926, 0x00000002 },
+ { 0x000000f9, 0x00000004 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+};
+
+static const u32 R300_cp_microcode[][2]={
+ { 0x4200e000, 0000000000 },
+ { 0x4000e000, 0000000000 },
+ { 0x000000ae, 0x00000008 },
+ { 0x000000b2, 0x00000008 },
+ { 0x67554b4a, 0000000000 },
+ { 0x4a4a4475, 0000000000 },
+ { 0x55527d83, 0000000000 },
+ { 0x4a8c8b65, 0000000000 },
+ { 0x4aef4af6, 0000000000 },
+ { 0x4ae14a4a, 0000000000 },
+ { 0xe4979797, 0000000000 },
+ { 0xdb4aebdd, 0000000000 },
+ { 0x9ccc4a4a, 0000000000 },
+ { 0xd1989898, 0000000000 },
+ { 0x4a0f9ad6, 0000000000 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000d0012, 0x00000038 },
+ { 0x0000e8b4, 0x00000004 },
+ { 0x000d0014, 0x00000038 },
+ { 0x0000e8b6, 0x00000004 },
+ { 0x000d0016, 0x00000038 },
+ { 0x0000e854, 0x00000004 },
+ { 0x000d0018, 0x00000038 },
+ { 0x0000e855, 0x00000004 },
+ { 0x000d001a, 0x00000038 },
+ { 0x0000e856, 0x00000004 },
+ { 0x000d001c, 0x00000038 },
+ { 0x0000e857, 0x00000004 },
+ { 0x000d001e, 0x00000038 },
+ { 0x0000e824, 0x00000004 },
+ { 0x000d0020, 0x00000038 },
+ { 0x0000e825, 0x00000004 },
+ { 0x000d0022, 0x00000038 },
+ { 0x0000e830, 0x00000004 },
+ { 0x000d0024, 0x00000038 },
+ { 0x0000f0c0, 0x00000004 },
+ { 0x000d0026, 0x00000038 },
+ { 0x0000f0c1, 0x00000004 },
+ { 0x000d0028, 0x00000038 },
+ { 0x0000f041, 0x00000004 },
+ { 0x000d002a, 0x00000038 },
+ { 0x0000f184, 0x00000004 },
+ { 0x000d002c, 0x00000038 },
+ { 0x0000f185, 0x00000004 },
+ { 0x000d002e, 0x00000038 },
+ { 0x0000f186, 0x00000004 },
+ { 0x000d0030, 0x00000038 },
+ { 0x0000f187, 0x00000004 },
+ { 0x000d0032, 0x00000038 },
+ { 0x0000f180, 0x00000004 },
+ { 0x000d0034, 0x00000038 },
+ { 0x0000f393, 0x00000004 },
+ { 0x000d0036, 0x00000038 },
+ { 0x0000f38a, 0x00000004 },
+ { 0x000d0038, 0x00000038 },
+ { 0x0000f38e, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000043, 0x00000018 },
+ { 0x00cce800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x0000003a, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x2000451d, 0x00000004 },
+ { 0x0000e580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x08004580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x00000047, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x00032000, 0x00000004 },
+ { 0x00022051, 0x00000028 },
+ { 0x00000051, 0x00000024 },
+ { 0x0800450f, 0x00000004 },
+ { 0x0000a04b, 0x00000008 },
+ { 0x0000e565, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000052, 0x00000008 },
+ { 0x03cca5b4, 0x00000004 },
+ { 0x05432000, 0x00000004 },
+ { 0x00022000, 0x00000004 },
+ { 0x4ccce05e, 0x00000030 },
+ { 0x08274565, 0x00000004 },
+ { 0x0000005e, 0x00000030 },
+ { 0x08004564, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000055, 0x00000008 },
+ { 0x00802061, 0x00000010 },
+ { 0x00202000, 0x00000004 },
+ { 0x001b00ff, 0x00000004 },
+ { 0x01000064, 0x00000010 },
+ { 0x001f2000, 0x00000004 },
+ { 0x001c00ff, 0x00000004 },
+ { 0000000000, 0x0000000c },
+ { 0x00000080, 0x00000030 },
+ { 0x00000055, 0x00000008 },
+ { 0x0000e576, 0x00000004 },
+ { 0x000ca000, 0x00000004 },
+ { 0x00012000, 0x00000004 },
+ { 0x00082000, 0x00000004 },
+ { 0x1800650e, 0x00000004 },
+ { 0x00092000, 0x00000004 },
+ { 0x000a2000, 0x00000004 },
+ { 0x000f0000, 0x00000004 },
+ { 0x00400000, 0x00000004 },
+ { 0x00000074, 0x00000018 },
+ { 0x0000e563, 0x00000004 },
+ { 0x00c0e5f9, 0x000000c2 },
+ { 0x00000069, 0x00000008 },
+ { 0x0000a069, 0x00000008 },
+ { 0x0000e576, 0x00000004 },
+ { 0x0000e577, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x0000e50f, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000077, 0x00000018 },
+ { 0x00c0e5f9, 0x000000c2 },
+ { 0x00000077, 0x00000008 },
+ { 0x0014e50e, 0x00000004 },
+ { 0x0040e50f, 0x00000004 },
+ { 0x00c0007a, 0x00000008 },
+ { 0x0000e570, 0x00000004 },
+ { 0x0000e571, 0x00000004 },
+ { 0x0000e572, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x0000e568, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00000084, 0x00000018 },
+ { 0x000b0000, 0x00000004 },
+ { 0x18c0e562, 0x00000004 },
+ { 0x00000086, 0x00000008 },
+ { 0x00c00085, 0x00000008 },
+ { 0x000700e3, 0x00000004 },
+ { 0x00000092, 0x00000038 },
+ { 0x000ca094, 0x00000030 },
+ { 0x080045bb, 0x00000004 },
+ { 0x000c2095, 0x00000030 },
+ { 0x0800e5bc, 0000000000 },
+ { 0x0000e5bb, 0x00000004 },
+ { 0x0000e5bc, 0000000000 },
+ { 0x00120000, 0x0000000c },
+ { 0x00120000, 0x00000004 },
+ { 0x001b0002, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e800, 0000000000 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e82e, 0000000000 },
+ { 0x02cca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000ce1cc, 0x00000004 },
+ { 0x050de1cd, 0x00000004 },
+ { 0x00400000, 0x00000004 },
+ { 0x000000a4, 0x00000018 },
+ { 0x00c0a000, 0x00000004 },
+ { 0x000000a1, 0x00000008 },
+ { 0x000000a6, 0x00000020 },
+ { 0x4200e000, 0000000000 },
+ { 0x000000ad, 0x00000038 },
+ { 0x000ca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00160000, 0x00000004 },
+ { 0x700ce000, 0x00000004 },
+ { 0x001400a9, 0x00000008 },
+ { 0x4000e000, 0000000000 },
+ { 0x02400000, 0x00000004 },
+ { 0x400ee000, 0x00000004 },
+ { 0x02400000, 0x00000004 },
+ { 0x4000e000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0240e51b, 0x00000004 },
+ { 0x0080e50a, 0x00000005 },
+ { 0x0080e50b, 0x00000005 },
+ { 0x00220000, 0x00000004 },
+ { 0x000700e3, 0x00000004 },
+ { 0x000000c0, 0x00000038 },
+ { 0x000c2095, 0x00000030 },
+ { 0x0880e5bd, 0x00000005 },
+ { 0x000c2094, 0x00000030 },
+ { 0x0800e5bb, 0x00000005 },
+ { 0x000c2095, 0x00000030 },
+ { 0x0880e5bc, 0x00000005 },
+ { 0x000000c3, 0x00000008 },
+ { 0x0080e5bd, 0x00000005 },
+ { 0x0000e5bb, 0x00000005 },
+ { 0x0080e5bc, 0x00000005 },
+ { 0x00210000, 0x00000004 },
+ { 0x02800000, 0x00000004 },
+ { 0x00c000c7, 0x00000018 },
+ { 0x4180e000, 0x00000040 },
+ { 0x000000c9, 0x00000024 },
+ { 0x01000000, 0x0000000c },
+ { 0x0100e51d, 0x0000000c },
+ { 0x000045bb, 0x00000004 },
+ { 0x000080c3, 0x00000008 },
+ { 0x0000f3ce, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053cf, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f3d2, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053d3, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f39d, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c0539e, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x03c00830, 0x00000004 },
+ { 0x4200e000, 0000000000 },
+ { 0x0000a000, 0x00000004 },
+ { 0x200045e0, 0x00000004 },
+ { 0x0000e5e1, 0000000000 },
+ { 0x00000001, 0000000000 },
+ { 0x000700e0, 0x00000004 },
+ { 0x0800e394, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x0000e8c4, 0x00000004 },
+ { 0x0000e8c5, 0x00000004 },
+ { 0x0000e8c6, 0x00000004 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000e4, 0x00000008 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000eb, 0x00000008 },
+ { 0x02c02000, 0x00000004 },
+ { 0x00060000, 0x00000004 },
+ { 0x000000f3, 0x00000034 },
+ { 0x000000f0, 0x00000008 },
+ { 0x00008000, 0x00000004 },
+ { 0xc000e000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x001d0018, 0x00000004 },
+ { 0x001a0001, 0x00000004 },
+ { 0x000000fb, 0x00000034 },
+ { 0x0000004a, 0x00000008 },
+ { 0x0500a04a, 0x00000008 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+};
+
+static const u32 R420_cp_microcode[][2]={
+ { 0x4200e000, 0000000000 },
+ { 0x4000e000, 0000000000 },
+ { 0x00000099, 0x00000008 },
+ { 0x0000009d, 0x00000008 },
+ { 0x4a554b4a, 0000000000 },
+ { 0x4a4a4467, 0000000000 },
+ { 0x55526f75, 0000000000 },
+ { 0x4a7e7d65, 0000000000 },
+ { 0xd9d3dff6, 0000000000 },
+ { 0x4ac54a4a, 0000000000 },
+ { 0xc8828282, 0000000000 },
+ { 0xbf4acfc1, 0000000000 },
+ { 0x87b04a4a, 0000000000 },
+ { 0xb5838383, 0000000000 },
+ { 0x4a0f85ba, 0000000000 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000d0012, 0x00000038 },
+ { 0x0000e8b4, 0x00000004 },
+ { 0x000d0014, 0x00000038 },
+ { 0x0000e8b6, 0x00000004 },
+ { 0x000d0016, 0x00000038 },
+ { 0x0000e854, 0x00000004 },
+ { 0x000d0018, 0x00000038 },
+ { 0x0000e855, 0x00000004 },
+ { 0x000d001a, 0x00000038 },
+ { 0x0000e856, 0x00000004 },
+ { 0x000d001c, 0x00000038 },
+ { 0x0000e857, 0x00000004 },
+ { 0x000d001e, 0x00000038 },
+ { 0x0000e824, 0x00000004 },
+ { 0x000d0020, 0x00000038 },
+ { 0x0000e825, 0x00000004 },
+ { 0x000d0022, 0x00000038 },
+ { 0x0000e830, 0x00000004 },
+ { 0x000d0024, 0x00000038 },
+ { 0x0000f0c0, 0x00000004 },
+ { 0x000d0026, 0x00000038 },
+ { 0x0000f0c1, 0x00000004 },
+ { 0x000d0028, 0x00000038 },
+ { 0x0000f041, 0x00000004 },
+ { 0x000d002a, 0x00000038 },
+ { 0x0000f184, 0x00000004 },
+ { 0x000d002c, 0x00000038 },
+ { 0x0000f185, 0x00000004 },
+ { 0x000d002e, 0x00000038 },
+ { 0x0000f186, 0x00000004 },
+ { 0x000d0030, 0x00000038 },
+ { 0x0000f187, 0x00000004 },
+ { 0x000d0032, 0x00000038 },
+ { 0x0000f180, 0x00000004 },
+ { 0x000d0034, 0x00000038 },
+ { 0x0000f393, 0x00000004 },
+ { 0x000d0036, 0x00000038 },
+ { 0x0000f38a, 0x00000004 },
+ { 0x000d0038, 0x00000038 },
+ { 0x0000f38e, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000043, 0x00000018 },
+ { 0x00cce800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x0000003a, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x2000451d, 0x00000004 },
+ { 0x0000e580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x08004580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x00000047, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x00032000, 0x00000004 },
+ { 0x00022051, 0x00000028 },
+ { 0x00000051, 0x00000024 },
+ { 0x0800450f, 0x00000004 },
+ { 0x0000a04b, 0x00000008 },
+ { 0x0000e565, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000052, 0x00000008 },
+ { 0x03cca5b4, 0x00000004 },
+ { 0x05432000, 0x00000004 },
+ { 0x00022000, 0x00000004 },
+ { 0x4ccce05e, 0x00000030 },
+ { 0x08274565, 0x00000004 },
+ { 0x0000005e, 0x00000030 },
+ { 0x08004564, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000055, 0x00000008 },
+ { 0x00802061, 0x00000010 },
+ { 0x00202000, 0x00000004 },
+ { 0x001b00ff, 0x00000004 },
+ { 0x01000064, 0x00000010 },
+ { 0x001f2000, 0x00000004 },
+ { 0x001c00ff, 0x00000004 },
+ { 0000000000, 0x0000000c },
+ { 0x00000072, 0x00000030 },
+ { 0x00000055, 0x00000008 },
+ { 0x0000e576, 0x00000004 },
+ { 0x0000e577, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x0000e50f, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000069, 0x00000018 },
+ { 0x00c0e5f9, 0x000000c2 },
+ { 0x00000069, 0x00000008 },
+ { 0x0014e50e, 0x00000004 },
+ { 0x0040e50f, 0x00000004 },
+ { 0x00c0006c, 0x00000008 },
+ { 0x0000e570, 0x00000004 },
+ { 0x0000e571, 0x00000004 },
+ { 0x0000e572, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x0000e568, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00000076, 0x00000018 },
+ { 0x000b0000, 0x00000004 },
+ { 0x18c0e562, 0x00000004 },
+ { 0x00000078, 0x00000008 },
+ { 0x00c00077, 0x00000008 },
+ { 0x000700c7, 0x00000004 },
+ { 0x00000080, 0x00000038 },
+ { 0x0000e5bb, 0x00000004 },
+ { 0x0000e5bc, 0000000000 },
+ { 0x0000a000, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e800, 0000000000 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e82e, 0000000000 },
+ { 0x02cca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000ce1cc, 0x00000004 },
+ { 0x050de1cd, 0x00000004 },
+ { 0x00400000, 0x00000004 },
+ { 0x0000008f, 0x00000018 },
+ { 0x00c0a000, 0x00000004 },
+ { 0x0000008c, 0x00000008 },
+ { 0x00000091, 0x00000020 },
+ { 0x4200e000, 0000000000 },
+ { 0x00000098, 0x00000038 },
+ { 0x000ca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00160000, 0x00000004 },
+ { 0x700ce000, 0x00000004 },
+ { 0x00140094, 0x00000008 },
+ { 0x4000e000, 0000000000 },
+ { 0x02400000, 0x00000004 },
+ { 0x400ee000, 0x00000004 },
+ { 0x02400000, 0x00000004 },
+ { 0x4000e000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0240e51b, 0x00000004 },
+ { 0x0080e50a, 0x00000005 },
+ { 0x0080e50b, 0x00000005 },
+ { 0x00220000, 0x00000004 },
+ { 0x000700c7, 0x00000004 },
+ { 0x000000a4, 0x00000038 },
+ { 0x0080e5bd, 0x00000005 },
+ { 0x0000e5bb, 0x00000005 },
+ { 0x0080e5bc, 0x00000005 },
+ { 0x00210000, 0x00000004 },
+ { 0x02800000, 0x00000004 },
+ { 0x00c000ab, 0x00000018 },
+ { 0x4180e000, 0x00000040 },
+ { 0x000000ad, 0x00000024 },
+ { 0x01000000, 0x0000000c },
+ { 0x0100e51d, 0x0000000c },
+ { 0x000045bb, 0x00000004 },
+ { 0x000080a7, 0x00000008 },
+ { 0x0000f3ce, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053cf, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f3d2, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053d3, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f39d, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c0539e, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x03c00830, 0x00000004 },
+ { 0x4200e000, 0000000000 },
+ { 0x0000a000, 0x00000004 },
+ { 0x200045e0, 0x00000004 },
+ { 0x0000e5e1, 0000000000 },
+ { 0x00000001, 0000000000 },
+ { 0x000700c4, 0x00000004 },
+ { 0x0800e394, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x0000e8c4, 0x00000004 },
+ { 0x0000e8c5, 0x00000004 },
+ { 0x0000e8c6, 0x00000004 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000c8, 0x00000008 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000cf, 0x00000008 },
+ { 0x02c02000, 0x00000004 },
+ { 0x00060000, 0x00000004 },
+ { 0x000000d7, 0x00000034 },
+ { 0x000000d4, 0x00000008 },
+ { 0x00008000, 0x00000004 },
+ { 0xc000e000, 0000000000 },
+ { 0x0000e1cc, 0x00000004 },
+ { 0x0500e1cd, 0x00000004 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000000de, 0x00000034 },
+ { 0x000000da, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x0019e1cc, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x0500a000, 0x00000004 },
+ { 0x080041cd, 0x00000004 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000000fb, 0x00000034 },
+ { 0x0000004a, 0x00000008 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x001d0018, 0x00000004 },
+ { 0x001a0001, 0x00000004 },
+ { 0x000000fb, 0x00000034 },
+ { 0x0000004a, 0x00000008 },
+ { 0x0500a04a, 0x00000008 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+};
+
+static const u32 RS600_cp_microcode[][2]={
+ { 0x4200e000, 0000000000 },
+ { 0x4000e000, 0000000000 },
+ { 0x000000a0, 0x00000008 },
+ { 0x000000a4, 0x00000008 },
+ { 0x4a554b4a, 0000000000 },
+ { 0x4a4a4467, 0000000000 },
+ { 0x55526f75, 0000000000 },
+ { 0x4a7e7d65, 0000000000 },
+ { 0x4ae74af6, 0000000000 },
+ { 0x4ad34a4a, 0000000000 },
+ { 0xd6898989, 0000000000 },
+ { 0xcd4addcf, 0000000000 },
+ { 0x8ebe4ae2, 0000000000 },
+ { 0xc38a8a8a, 0000000000 },
+ { 0x4a0f8cc8, 0000000000 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000d0012, 0x00000038 },
+ { 0x0000e8b4, 0x00000004 },
+ { 0x000d0014, 0x00000038 },
+ { 0x0000e8b6, 0x00000004 },
+ { 0x000d0016, 0x00000038 },
+ { 0x0000e854, 0x00000004 },
+ { 0x000d0018, 0x00000038 },
+ { 0x0000e855, 0x00000004 },
+ { 0x000d001a, 0x00000038 },
+ { 0x0000e856, 0x00000004 },
+ { 0x000d001c, 0x00000038 },
+ { 0x0000e857, 0x00000004 },
+ { 0x000d001e, 0x00000038 },
+ { 0x0000e824, 0x00000004 },
+ { 0x000d0020, 0x00000038 },
+ { 0x0000e825, 0x00000004 },
+ { 0x000d0022, 0x00000038 },
+ { 0x0000e830, 0x00000004 },
+ { 0x000d0024, 0x00000038 },
+ { 0x0000f0c0, 0x00000004 },
+ { 0x000d0026, 0x00000038 },
+ { 0x0000f0c1, 0x00000004 },
+ { 0x000d0028, 0x00000038 },
+ { 0x0000f041, 0x00000004 },
+ { 0x000d002a, 0x00000038 },
+ { 0x0000f184, 0x00000004 },
+ { 0x000d002c, 0x00000038 },
+ { 0x0000f185, 0x00000004 },
+ { 0x000d002e, 0x00000038 },
+ { 0x0000f186, 0x00000004 },
+ { 0x000d0030, 0x00000038 },
+ { 0x0000f187, 0x00000004 },
+ { 0x000d0032, 0x00000038 },
+ { 0x0000f180, 0x00000004 },
+ { 0x000d0034, 0x00000038 },
+ { 0x0000f393, 0x00000004 },
+ { 0x000d0036, 0x00000038 },
+ { 0x0000f38a, 0x00000004 },
+ { 0x000d0038, 0x00000038 },
+ { 0x0000f38e, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000043, 0x00000018 },
+ { 0x00cce800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x0000003a, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x2000451d, 0x00000004 },
+ { 0x0000e580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x08004580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x00000047, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x00032000, 0x00000004 },
+ { 0x00022051, 0x00000028 },
+ { 0x00000051, 0x00000024 },
+ { 0x0800450f, 0x00000004 },
+ { 0x0000a04b, 0x00000008 },
+ { 0x0000e565, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000052, 0x00000008 },
+ { 0x03cca5b4, 0x00000004 },
+ { 0x05432000, 0x00000004 },
+ { 0x00022000, 0x00000004 },
+ { 0x4ccce05e, 0x00000030 },
+ { 0x08274565, 0x00000004 },
+ { 0x0000005e, 0x00000030 },
+ { 0x08004564, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000055, 0x00000008 },
+ { 0x00802061, 0x00000010 },
+ { 0x00202000, 0x00000004 },
+ { 0x001b00ff, 0x00000004 },
+ { 0x01000064, 0x00000010 },
+ { 0x001f2000, 0x00000004 },
+ { 0x001c00ff, 0x00000004 },
+ { 0000000000, 0x0000000c },
+ { 0x00000072, 0x00000030 },
+ { 0x00000055, 0x00000008 },
+ { 0x0000e576, 0x00000004 },
+ { 0x0000e577, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x0000e50f, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000069, 0x00000018 },
+ { 0x00c0e5f9, 0x000000c2 },
+ { 0x00000069, 0x00000008 },
+ { 0x0014e50e, 0x00000004 },
+ { 0x0040e50f, 0x00000004 },
+ { 0x00c0006c, 0x00000008 },
+ { 0x0000e570, 0x00000004 },
+ { 0x0000e571, 0x00000004 },
+ { 0x0000e572, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x0000e568, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00000076, 0x00000018 },
+ { 0x000b0000, 0x00000004 },
+ { 0x18c0e562, 0x00000004 },
+ { 0x00000078, 0x00000008 },
+ { 0x00c00077, 0x00000008 },
+ { 0x000700d5, 0x00000004 },
+ { 0x00000084, 0x00000038 },
+ { 0x000ca086, 0x00000030 },
+ { 0x080045bb, 0x00000004 },
+ { 0x000c2087, 0x00000030 },
+ { 0x0800e5bc, 0000000000 },
+ { 0x0000e5bb, 0x00000004 },
+ { 0x0000e5bc, 0000000000 },
+ { 0x00120000, 0x0000000c },
+ { 0x00120000, 0x00000004 },
+ { 0x001b0002, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e800, 0000000000 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e82e, 0000000000 },
+ { 0x02cca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000ce1cc, 0x00000004 },
+ { 0x050de1cd, 0x00000004 },
+ { 0x00400000, 0x00000004 },
+ { 0x00000096, 0x00000018 },
+ { 0x00c0a000, 0x00000004 },
+ { 0x00000093, 0x00000008 },
+ { 0x00000098, 0x00000020 },
+ { 0x4200e000, 0000000000 },
+ { 0x0000009f, 0x00000038 },
+ { 0x000ca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00160000, 0x00000004 },
+ { 0x700ce000, 0x00000004 },
+ { 0x0014009b, 0x00000008 },
+ { 0x4000e000, 0000000000 },
+ { 0x02400000, 0x00000004 },
+ { 0x400ee000, 0x00000004 },
+ { 0x02400000, 0x00000004 },
+ { 0x4000e000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0240e51b, 0x00000004 },
+ { 0x0080e50a, 0x00000005 },
+ { 0x0080e50b, 0x00000005 },
+ { 0x00220000, 0x00000004 },
+ { 0x000700d5, 0x00000004 },
+ { 0x000000b2, 0x00000038 },
+ { 0x000c2087, 0x00000030 },
+ { 0x0880e5bd, 0x00000005 },
+ { 0x000c2086, 0x00000030 },
+ { 0x0800e5bb, 0x00000005 },
+ { 0x000c2087, 0x00000030 },
+ { 0x0880e5bc, 0x00000005 },
+ { 0x000000b5, 0x00000008 },
+ { 0x0080e5bd, 0x00000005 },
+ { 0x0000e5bb, 0x00000005 },
+ { 0x0080e5bc, 0x00000005 },
+ { 0x00210000, 0x00000004 },
+ { 0x02800000, 0x00000004 },
+ { 0x00c000b9, 0x00000018 },
+ { 0x4180e000, 0x00000040 },
+ { 0x000000bb, 0x00000024 },
+ { 0x01000000, 0x0000000c },
+ { 0x0100e51d, 0x0000000c },
+ { 0x000045bb, 0x00000004 },
+ { 0x000080b5, 0x00000008 },
+ { 0x0000f3ce, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053cf, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f3d2, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053d3, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f39d, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c0539e, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x03c00830, 0x00000004 },
+ { 0x4200e000, 0000000000 },
+ { 0x0000a000, 0x00000004 },
+ { 0x200045e0, 0x00000004 },
+ { 0x0000e5e1, 0000000000 },
+ { 0x00000001, 0000000000 },
+ { 0x000700d2, 0x00000004 },
+ { 0x0800e394, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x0000e8c4, 0x00000004 },
+ { 0x0000e8c5, 0x00000004 },
+ { 0x0000e8c6, 0x00000004 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000d6, 0x00000008 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000dd, 0x00000008 },
+ { 0x00e00116, 0000000000 },
+ { 0x000700e1, 0x00000004 },
+ { 0x0800401c, 0x00000004 },
+ { 0x200050e7, 0x00000004 },
+ { 0x0000e01d, 0x00000004 },
+ { 0x000000e4, 0x00000008 },
+ { 0x02c02000, 0x00000004 },
+ { 0x00060000, 0x00000004 },
+ { 0x000000eb, 0x00000034 },
+ { 0x000000e8, 0x00000008 },
+ { 0x00008000, 0x00000004 },
+ { 0xc000e000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x001d0018, 0x00000004 },
+ { 0x001a0001, 0x00000004 },
+ { 0x000000fb, 0x00000034 },
+ { 0x0000004a, 0x00000008 },
+ { 0x0500a04a, 0x00000008 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+};
+
+static const u32 RS690_cp_microcode[][2]={
+ { 0x000000dd, 0x00000008 },
+ { 0x000000df, 0x00000008 },
+ { 0x000000a0, 0x00000008 },
+ { 0x000000a4, 0x00000008 },
+ { 0x4a554b4a, 0000000000 },
+ { 0x4a4a4467, 0000000000 },
+ { 0x55526f75, 0000000000 },
+ { 0x4a7e7d65, 0000000000 },
+ { 0x4ad74af6, 0000000000 },
+ { 0x4ac94a4a, 0000000000 },
+ { 0xcc898989, 0000000000 },
+ { 0xc34ad3c5, 0000000000 },
+ { 0x8e4a4a4a, 0000000000 },
+ { 0x4a8a8a8a, 0000000000 },
+ { 0x4a0f8c4a, 0000000000 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000d0012, 0x00000038 },
+ { 0x0000e8b4, 0x00000004 },
+ { 0x000d0014, 0x00000038 },
+ { 0x0000e8b6, 0x00000004 },
+ { 0x000d0016, 0x00000038 },
+ { 0x0000e854, 0x00000004 },
+ { 0x000d0018, 0x00000038 },
+ { 0x0000e855, 0x00000004 },
+ { 0x000d001a, 0x00000038 },
+ { 0x0000e856, 0x00000004 },
+ { 0x000d001c, 0x00000038 },
+ { 0x0000e857, 0x00000004 },
+ { 0x000d001e, 0x00000038 },
+ { 0x0000e824, 0x00000004 },
+ { 0x000d0020, 0x00000038 },
+ { 0x0000e825, 0x00000004 },
+ { 0x000d0022, 0x00000038 },
+ { 0x0000e830, 0x00000004 },
+ { 0x000d0024, 0x00000038 },
+ { 0x0000f0c0, 0x00000004 },
+ { 0x000d0026, 0x00000038 },
+ { 0x0000f0c1, 0x00000004 },
+ { 0x000d0028, 0x00000038 },
+ { 0x0000f041, 0x00000004 },
+ { 0x000d002a, 0x00000038 },
+ { 0x0000f184, 0x00000004 },
+ { 0x000d002c, 0x00000038 },
+ { 0x0000f185, 0x00000004 },
+ { 0x000d002e, 0x00000038 },
+ { 0x0000f186, 0x00000004 },
+ { 0x000d0030, 0x00000038 },
+ { 0x0000f187, 0x00000004 },
+ { 0x000d0032, 0x00000038 },
+ { 0x0000f180, 0x00000004 },
+ { 0x000d0034, 0x00000038 },
+ { 0x0000f393, 0x00000004 },
+ { 0x000d0036, 0x00000038 },
+ { 0x0000f38a, 0x00000004 },
+ { 0x000d0038, 0x00000038 },
+ { 0x0000f38e, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000043, 0x00000018 },
+ { 0x00cce800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x0000003a, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x2000451d, 0x00000004 },
+ { 0x0000e580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x08004580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x00000047, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x00032000, 0x00000004 },
+ { 0x00022051, 0x00000028 },
+ { 0x00000051, 0x00000024 },
+ { 0x0800450f, 0x00000004 },
+ { 0x0000a04b, 0x00000008 },
+ { 0x0000e565, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000052, 0x00000008 },
+ { 0x03cca5b4, 0x00000004 },
+ { 0x05432000, 0x00000004 },
+ { 0x00022000, 0x00000004 },
+ { 0x4ccce05e, 0x00000030 },
+ { 0x08274565, 0x00000004 },
+ { 0x0000005e, 0x00000030 },
+ { 0x08004564, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000055, 0x00000008 },
+ { 0x00802061, 0x00000010 },
+ { 0x00202000, 0x00000004 },
+ { 0x001b00ff, 0x00000004 },
+ { 0x01000064, 0x00000010 },
+ { 0x001f2000, 0x00000004 },
+ { 0x001c00ff, 0x00000004 },
+ { 0000000000, 0x0000000c },
+ { 0x00000072, 0x00000030 },
+ { 0x00000055, 0x00000008 },
+ { 0x0000e576, 0x00000004 },
+ { 0x0000e577, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x0000e50f, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000069, 0x00000018 },
+ { 0x00c0e5f9, 0x000000c2 },
+ { 0x00000069, 0x00000008 },
+ { 0x0014e50e, 0x00000004 },
+ { 0x0040e50f, 0x00000004 },
+ { 0x00c0006c, 0x00000008 },
+ { 0x0000e570, 0x00000004 },
+ { 0x0000e571, 0x00000004 },
+ { 0x0000e572, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x0000e568, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00000076, 0x00000018 },
+ { 0x000b0000, 0x00000004 },
+ { 0x18c0e562, 0x00000004 },
+ { 0x00000078, 0x00000008 },
+ { 0x00c00077, 0x00000008 },
+ { 0x000700cb, 0x00000004 },
+ { 0x00000084, 0x00000038 },
+ { 0x000ca086, 0x00000030 },
+ { 0x080045bb, 0x00000004 },
+ { 0x000c2087, 0x00000030 },
+ { 0x0800e5bc, 0000000000 },
+ { 0x0000e5bb, 0x00000004 },
+ { 0x0000e5bc, 0000000000 },
+ { 0x00120000, 0x0000000c },
+ { 0x00120000, 0x00000004 },
+ { 0x001b0002, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e800, 0000000000 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e82e, 0000000000 },
+ { 0x02cca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000ce1cc, 0x00000004 },
+ { 0x050de1cd, 0x00000004 },
+ { 0x00400000, 0x00000004 },
+ { 0x00000096, 0x00000018 },
+ { 0x00c0a000, 0x00000004 },
+ { 0x00000093, 0x00000008 },
+ { 0x00000098, 0x00000020 },
+ { 0x4200e000, 0000000000 },
+ { 0x0000009f, 0x00000038 },
+ { 0x000ca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00160000, 0x00000004 },
+ { 0x700ce000, 0x00000004 },
+ { 0x0014009b, 0x00000008 },
+ { 0x4000e000, 0000000000 },
+ { 0x02400000, 0x00000004 },
+ { 0x400ee000, 0x00000004 },
+ { 0x02400000, 0x00000004 },
+ { 0x4000e000, 0000000000 },
+ { 0x00100000, 0x0000002c },
+ { 0x00004000, 0000000000 },
+ { 0x080045c8, 0x00000004 },
+ { 0x00240005, 0x00000004 },
+ { 0x08004d0b, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0240e51b, 0x00000004 },
+ { 0x0080e50a, 0x00000005 },
+ { 0x0080e50b, 0x00000005 },
+ { 0x00220000, 0x00000004 },
+ { 0x000700cb, 0x00000004 },
+ { 0x000000b7, 0x00000038 },
+ { 0x000c2087, 0x00000030 },
+ { 0x0880e5bd, 0x00000005 },
+ { 0x000c2086, 0x00000030 },
+ { 0x0800e5bb, 0x00000005 },
+ { 0x000c2087, 0x00000030 },
+ { 0x0880e5bc, 0x00000005 },
+ { 0x000000ba, 0x00000008 },
+ { 0x0080e5bd, 0x00000005 },
+ { 0x0000e5bb, 0x00000005 },
+ { 0x0080e5bc, 0x00000005 },
+ { 0x00210000, 0x00000004 },
+ { 0x02800000, 0x00000004 },
+ { 0x00c000be, 0x00000018 },
+ { 0x4180e000, 0x00000040 },
+ { 0x000000c0, 0x00000024 },
+ { 0x01000000, 0x0000000c },
+ { 0x0100e51d, 0x0000000c },
+ { 0x000045bb, 0x00000004 },
+ { 0x000080ba, 0x00000008 },
+ { 0x03c00830, 0x00000004 },
+ { 0x4200e000, 0000000000 },
+ { 0x0000a000, 0x00000004 },
+ { 0x200045e0, 0x00000004 },
+ { 0x0000e5e1, 0000000000 },
+ { 0x00000001, 0000000000 },
+ { 0x000700c8, 0x00000004 },
+ { 0x0800e394, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x0000e8c4, 0x00000004 },
+ { 0x0000e8c5, 0x00000004 },
+ { 0x0000e8c6, 0x00000004 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000cc, 0x00000008 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000d3, 0x00000008 },
+ { 0x02c02000, 0x00000004 },
+ { 0x00060000, 0x00000004 },
+ { 0x000000db, 0x00000034 },
+ { 0x000000d8, 0x00000008 },
+ { 0x00008000, 0x00000004 },
+ { 0xc000e000, 0000000000 },
+ { 0x000000e1, 0x00000030 },
+ { 0x4200e000, 0000000000 },
+ { 0x000000e1, 0x00000030 },
+ { 0x4000e000, 0000000000 },
+ { 0x0025001b, 0x00000004 },
+ { 0x00230000, 0x00000004 },
+ { 0x00250005, 0x00000004 },
+ { 0x000000e6, 0x00000034 },
+ { 0000000000, 0x0000000c },
+ { 0x00244000, 0x00000004 },
+ { 0x080045c8, 0x00000004 },
+ { 0x00240005, 0x00000004 },
+ { 0x08004d0b, 0x0000000c },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x001d0018, 0x00000004 },
+ { 0x001a0001, 0x00000004 },
+ { 0x000000fb, 0x00000034 },
+ { 0x0000004a, 0x00000008 },
+ { 0x0500a04a, 0x00000008 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+};
+
+static const u32 R520_cp_microcode[][2]={
+ { 0x4200e000, 0000000000 },
+ { 0x4000e000, 0000000000 },
+ { 0x00000099, 0x00000008 },
+ { 0x0000009d, 0x00000008 },
+ { 0x4a554b4a, 0000000000 },
+ { 0x4a4a4467, 0000000000 },
+ { 0x55526f75, 0000000000 },
+ { 0x4a7e7d65, 0000000000 },
+ { 0xe0dae6f6, 0000000000 },
+ { 0x4ac54a4a, 0000000000 },
+ { 0xc8828282, 0000000000 },
+ { 0xbf4acfc1, 0000000000 },
+ { 0x87b04ad5, 0000000000 },
+ { 0xb5838383, 0000000000 },
+ { 0x4a0f85ba, 0000000000 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000d0012, 0x00000038 },
+ { 0x0000e8b4, 0x00000004 },
+ { 0x000d0014, 0x00000038 },
+ { 0x0000e8b6, 0x00000004 },
+ { 0x000d0016, 0x00000038 },
+ { 0x0000e854, 0x00000004 },
+ { 0x000d0018, 0x00000038 },
+ { 0x0000e855, 0x00000004 },
+ { 0x000d001a, 0x00000038 },
+ { 0x0000e856, 0x00000004 },
+ { 0x000d001c, 0x00000038 },
+ { 0x0000e857, 0x00000004 },
+ { 0x000d001e, 0x00000038 },
+ { 0x0000e824, 0x00000004 },
+ { 0x000d0020, 0x00000038 },
+ { 0x0000e825, 0x00000004 },
+ { 0x000d0022, 0x00000038 },
+ { 0x0000e830, 0x00000004 },
+ { 0x000d0024, 0x00000038 },
+ { 0x0000f0c0, 0x00000004 },
+ { 0x000d0026, 0x00000038 },
+ { 0x0000f0c1, 0x00000004 },
+ { 0x000d0028, 0x00000038 },
+ { 0x0000e000, 0x00000004 },
+ { 0x000d002a, 0x00000038 },
+ { 0x0000e000, 0x00000004 },
+ { 0x000d002c, 0x00000038 },
+ { 0x0000e000, 0x00000004 },
+ { 0x000d002e, 0x00000038 },
+ { 0x0000e000, 0x00000004 },
+ { 0x000d0030, 0x00000038 },
+ { 0x0000e000, 0x00000004 },
+ { 0x000d0032, 0x00000038 },
+ { 0x0000f180, 0x00000004 },
+ { 0x000d0034, 0x00000038 },
+ { 0x0000f393, 0x00000004 },
+ { 0x000d0036, 0x00000038 },
+ { 0x0000f38a, 0x00000004 },
+ { 0x000d0038, 0x00000038 },
+ { 0x0000f38e, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000043, 0x00000018 },
+ { 0x00cce800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x08004800, 0x00000004 },
+ { 0x0000003a, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x2000451d, 0x00000004 },
+ { 0x0000e580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x08004580, 0x00000004 },
+ { 0x000ce581, 0x00000004 },
+ { 0x00000047, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x00032000, 0x00000004 },
+ { 0x00022051, 0x00000028 },
+ { 0x00000051, 0x00000024 },
+ { 0x0800450f, 0x00000004 },
+ { 0x0000a04b, 0x00000008 },
+ { 0x0000e565, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000052, 0x00000008 },
+ { 0x03cca5b4, 0x00000004 },
+ { 0x05432000, 0x00000004 },
+ { 0x00022000, 0x00000004 },
+ { 0x4ccce05e, 0x00000030 },
+ { 0x08274565, 0x00000004 },
+ { 0x0000005e, 0x00000030 },
+ { 0x08004564, 0x00000004 },
+ { 0x0000e566, 0x00000004 },
+ { 0x00000055, 0x00000008 },
+ { 0x00802061, 0x00000010 },
+ { 0x00202000, 0x00000004 },
+ { 0x001b00ff, 0x00000004 },
+ { 0x01000064, 0x00000010 },
+ { 0x001f2000, 0x00000004 },
+ { 0x001c00ff, 0x00000004 },
+ { 0000000000, 0x0000000c },
+ { 0x00000072, 0x00000030 },
+ { 0x00000055, 0x00000008 },
+ { 0x0000e576, 0x00000004 },
+ { 0x0000e577, 0x00000004 },
+ { 0x0000e50e, 0x00000004 },
+ { 0x0000e50f, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00000069, 0x00000018 },
+ { 0x00c0e5f9, 0x000000c2 },
+ { 0x00000069, 0x00000008 },
+ { 0x0014e50e, 0x00000004 },
+ { 0x0040e50f, 0x00000004 },
+ { 0x00c0006c, 0x00000008 },
+ { 0x0000e570, 0x00000004 },
+ { 0x0000e571, 0x00000004 },
+ { 0x0000e572, 0x0000000c },
+ { 0x0000a000, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x0000e568, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00000076, 0x00000018 },
+ { 0x000b0000, 0x00000004 },
+ { 0x18c0e562, 0x00000004 },
+ { 0x00000078, 0x00000008 },
+ { 0x00c00077, 0x00000008 },
+ { 0x000700c7, 0x00000004 },
+ { 0x00000080, 0x00000038 },
+ { 0x0000e5bb, 0x00000004 },
+ { 0x0000e5bc, 0000000000 },
+ { 0x0000a000, 0x00000004 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e800, 0000000000 },
+ { 0x0000e821, 0x00000004 },
+ { 0x0000e82e, 0000000000 },
+ { 0x02cca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000ce1cc, 0x00000004 },
+ { 0x050de1cd, 0x00000004 },
+ { 0x00400000, 0x00000004 },
+ { 0x0000008f, 0x00000018 },
+ { 0x00c0a000, 0x00000004 },
+ { 0x0000008c, 0x00000008 },
+ { 0x00000091, 0x00000020 },
+ { 0x4200e000, 0000000000 },
+ { 0x00000098, 0x00000038 },
+ { 0x000ca000, 0x00000004 },
+ { 0x00140000, 0x00000004 },
+ { 0x000c2000, 0x00000004 },
+ { 0x00160000, 0x00000004 },
+ { 0x700ce000, 0x00000004 },
+ { 0x00140094, 0x00000008 },
+ { 0x4000e000, 0000000000 },
+ { 0x02400000, 0x00000004 },
+ { 0x400ee000, 0x00000004 },
+ { 0x02400000, 0x00000004 },
+ { 0x4000e000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x0240e51b, 0x00000004 },
+ { 0x0080e50a, 0x00000005 },
+ { 0x0080e50b, 0x00000005 },
+ { 0x00220000, 0x00000004 },
+ { 0x000700c7, 0x00000004 },
+ { 0x000000a4, 0x00000038 },
+ { 0x0080e5bd, 0x00000005 },
+ { 0x0000e5bb, 0x00000005 },
+ { 0x0080e5bc, 0x00000005 },
+ { 0x00210000, 0x00000004 },
+ { 0x02800000, 0x00000004 },
+ { 0x00c000ab, 0x00000018 },
+ { 0x4180e000, 0x00000040 },
+ { 0x000000ad, 0x00000024 },
+ { 0x01000000, 0x0000000c },
+ { 0x0100e51d, 0x0000000c },
+ { 0x000045bb, 0x00000004 },
+ { 0x000080a7, 0x00000008 },
+ { 0x0000f3ce, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053cf, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f3d2, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c053d3, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x0000f39d, 0x00000004 },
+ { 0x0140a000, 0x00000004 },
+ { 0x00cc2000, 0x00000004 },
+ { 0x08c0539e, 0x00000040 },
+ { 0x00008000, 0000000000 },
+ { 0x03c00830, 0x00000004 },
+ { 0x4200e000, 0000000000 },
+ { 0x0000a000, 0x00000004 },
+ { 0x200045e0, 0x00000004 },
+ { 0x0000e5e1, 0000000000 },
+ { 0x00000001, 0000000000 },
+ { 0x000700c4, 0x00000004 },
+ { 0x0800e394, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x0000e8c4, 0x00000004 },
+ { 0x0000e8c5, 0x00000004 },
+ { 0x0000e8c6, 0x00000004 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000c8, 0x00000008 },
+ { 0x0000e928, 0x00000004 },
+ { 0x0000e929, 0x00000004 },
+ { 0x0000e92a, 0x00000004 },
+ { 0x000000cf, 0x00000008 },
+ { 0xdeadbeef, 0000000000 },
+ { 0x00000116, 0000000000 },
+ { 0x000700d3, 0x00000004 },
+ { 0x080050e7, 0x00000004 },
+ { 0x000700d4, 0x00000004 },
+ { 0x0800401c, 0x00000004 },
+ { 0x0000e01d, 0000000000 },
+ { 0x02c02000, 0x00000004 },
+ { 0x00060000, 0x00000004 },
+ { 0x000000de, 0x00000034 },
+ { 0x000000db, 0x00000008 },
+ { 0x00008000, 0x00000004 },
+ { 0xc000e000, 0000000000 },
+ { 0x0000e1cc, 0x00000004 },
+ { 0x0500e1cd, 0x00000004 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000000e5, 0x00000034 },
+ { 0x000000e1, 0x00000008 },
+ { 0x0000a000, 0000000000 },
+ { 0x0019e1cc, 0x00000004 },
+ { 0x001b0001, 0x00000004 },
+ { 0x0500a000, 0x00000004 },
+ { 0x080041cd, 0x00000004 },
+ { 0x000ca000, 0x00000004 },
+ { 0x000000fb, 0x00000034 },
+ { 0x0000004a, 0x00000008 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0x000c2000, 0x00000004 },
+ { 0x001d0018, 0x00000004 },
+ { 0x001a0001, 0x00000004 },
+ { 0x000000fb, 0x00000034 },
+ { 0x0000004a, 0x00000008 },
+ { 0x0500a04a, 0x00000008 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+ { 0000000000, 0000000000 },
+};
+
+
+#endif
diff --git a/sys/dev/pci/drm/radeon_state.c b/sys/dev/pci/drm/radeon_state.c
index 71b19b1b40b..c50ac248dd7 100644
--- a/sys/dev/pci/drm/radeon_state.c
+++ b/sys/dev/pci/drm/radeon_state.c
@@ -898,7 +898,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
+ DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n",
x, y, w, h, flags);
if (flags & RADEON_FRONT) {
@@ -1368,7 +1368,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h);
+ DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
BEGIN_RING(9);
@@ -1422,8 +1422,7 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
- DRM_DEBUG("%s: pfCurrentPage=%d\n",
- __FUNCTION__,
+ DRM_DEBUG("pfCurrentPage=%d\n",
dev_priv->sarea_priv->pfCurrentPage);
/* Do some trivial performance monitoring...
@@ -1562,7 +1561,7 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev,
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
+ DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
if (start != end) {
int offset = (dev_priv->gart_buffers_offset
@@ -1663,7 +1662,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
u32 height;
int i;
u32 texpitch, microtile;
- u32 offset;
+ u32 offset, byte_offset;
RING_LOCALS;
if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
@@ -1728,6 +1727,13 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
} else
microtile = 0;
+ /* this might fail for zero-sized uploads - are those illegal? */
+ if (!radeon_check_offset(dev_priv, tex->offset + image->height *
+ blit_width - 1)) {
+ DRM_ERROR("Invalid final destination offset\n");
+ return -EINVAL;
+ }
+
DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
do {
@@ -1758,7 +1764,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
buf = radeon_freelist_get(dev);
}
if (!buf) {
- DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
+ DRM_DEBUG("EAGAIN\n");
if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
return -EFAULT;
return -EAGAIN;
@@ -1841,6 +1847,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
}
#undef RADEON_COPY_MT
+ byte_offset = (image->y & ~2047) * blit_width;
buf->file_priv = file_priv;
buf->used = size;
offset = dev_priv->gart_buffers_offset + buf->offset;
@@ -1855,9 +1862,9 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
RADEON_DP_SRC_SOURCE_MEMORY |
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
OUT_RING((spitch << 22) | (offset >> 10));
- OUT_RING((texpitch << 22) | (tex->offset >> 10));
+ OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10)));
OUT_RING(0);
- OUT_RING((image->x << 16) | image->y);
+ OUT_RING((image->x << 16) | (image->y % 2048));
OUT_RING((image->width << 16) | height);
RADEON_WAIT_UNTIL_2D_IDLE();
ADVANCE_RING();
@@ -2084,7 +2091,7 @@ static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_f
drm_radeon_surface_alloc_t *alloc = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2100,7 +2107,7 @@ static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_fi
drm_radeon_surface_free_t *memfree = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2215,7 +2222,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2299,7 +2306,7 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
sarea_priv = dev_priv->sarea_priv;
@@ -2437,11 +2444,11 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
+ DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
indirect->idx, indirect->start, indirect->end,
indirect->discard);
@@ -2509,7 +2516,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2814,7 +2821,7 @@ static int radeon_emit_wait(struct drm_device * dev, int flags)
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("%s: %x\n", __FUNCTION__, flags);
+ DRM_DEBUG("%x\n", flags);
switch (flags) {
case RADEON_WAIT_2D:
BEGIN_RING(2);
@@ -2852,7 +2859,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -3013,7 +3020,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -3081,6 +3088,12 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
case RADEON_PARAM_VBLANK_CRTC:
value = radeon_vblank_crtc_get(dev);
break;
+ case RADEON_PARAM_FB_LOCATION:
+ value = radeon_read_fb_location(dev_priv);
+ break;
+ case RADEON_PARAM_NUM_GB_PIPES:
+ value = dev_priv->num_gb_pipes;
+ break;
default:
DRM_DEBUG( "Invalid parameter %d\n", param->param );
return -EINVAL;
@@ -3101,7 +3114,7 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil
struct drm_radeon_driver_file_fields *radeon_priv;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -3116,12 +3129,14 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil
DRM_DEBUG("color tiling disabled\n");
dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
- dev_priv->sarea_priv->tiling_enabled = 0;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->tiling_enabled = 0;
} else if (sp->value == 1) {
DRM_DEBUG("color tiling enabled\n");
dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
- dev_priv->sarea_priv->tiling_enabled = 1;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->tiling_enabled = 1;
}
break;
case RADEON_SETPARAM_PCIGART_LOCATION:
@@ -3154,7 +3169,7 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil
*
* DRM infrastructure takes care of reclaiming dma buffers.
*/
-void radeon_driver_preclose(struct drm_device * dev,
+void radeon_driver_preclose(struct drm_device *dev,
struct drm_file *file_priv)
{
if (dev->dev_private) {
@@ -3166,7 +3181,7 @@ void radeon_driver_preclose(struct drm_device * dev,
}
}
-void radeon_driver_lastclose(struct drm_device * dev)
+void radeon_driver_lastclose(struct drm_device *dev)
{
if (dev->dev_private) {
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -3179,7 +3194,7 @@ void radeon_driver_lastclose(struct drm_device * dev)
radeon_do_release(dev);
}
-int radeon_driver_open(struct drm_device * dev, struct drm_file *file_priv)
+int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
struct drm_radeon_driver_file_fields *radeon_priv;
@@ -3201,7 +3216,7 @@ int radeon_driver_open(struct drm_device * dev, struct drm_file *file_priv)
return 0;
}
-void radeon_driver_postclose(struct drm_device * dev, struct drm_file *file_priv)
+void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
{
struct drm_radeon_driver_file_fields *radeon_priv =
file_priv->driver_priv;
diff --git a/sys/dev/pci/drm/savage_bci.c b/sys/dev/pci/drm/savage_bci.c
index 7710ba0d35a..4b8a89fea64 100644
--- a/sys/dev/pci/drm/savage_bci.c
+++ b/sys/dev/pci/drm/savage_bci.c
@@ -364,7 +364,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
unsigned int cur = dev_priv->current_dma_page;
unsigned int rest = SAVAGE_DMA_PAGE_SIZE -
dev_priv->dma_pages[cur].used;
- unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE-1) /
+ unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) /
SAVAGE_DMA_PAGE_SIZE;
uint32_t *dma_ptr;
unsigned int i;
@@ -374,7 +374,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
if (cur + nr_pages < dev_priv->nr_dma_pages) {
dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
- cur*SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
+ cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
if (n < rest)
rest = n;
dev_priv->dma_pages[cur].used += rest;
@@ -383,7 +383,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
} else {
dev_priv->dma_flush(dev_priv);
nr_pages =
- (n + SAVAGE_DMA_PAGE_SIZE-1) / SAVAGE_DMA_PAGE_SIZE;
+ (n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE;
for (i = cur; i < dev_priv->nr_dma_pages; ++i) {
dev_priv->dma_pages[i].age = dev_priv->last_dma_age;
dev_priv->dma_pages[i].used = 0;
@@ -443,7 +443,7 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
dev_priv->dma_pages[cur].used += pad;
- while(pad != 0) {
+ while (pad != 0) {
*dma_ptr++ = BCI_CMD_WAIT;
pad--;
}
@@ -587,12 +587,12 @@ int savage_driver_firstopen(struct drm_device *dev)
dev_priv->mtrr[0].handle =
drm_mtrr_add(dev_priv->mtrr[0].base,
dev_priv->mtrr[0].size, DRM_MTRR_WC);
- dev_priv->mtrr[1].base = fb_base+0x02000000;
+ dev_priv->mtrr[1].base = fb_base + 0x02000000;
dev_priv->mtrr[1].size = 0x02000000;
dev_priv->mtrr[1].handle =
drm_mtrr_add(dev_priv->mtrr[1].base,
dev_priv->mtrr[1].size, DRM_MTRR_WC);
- dev_priv->mtrr[2].base = fb_base+0x04000000;
+ dev_priv->mtrr[2].base = fb_base + 0x04000000;
dev_priv->mtrr[2].size = 0x04000000;
dev_priv->mtrr[2].handle =
drm_mtrr_add(dev_priv->mtrr[2].base,
@@ -833,7 +833,7 @@ static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init)
depth_tile_format = SAVAGE_BD_TILE_DEST;
}
front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8);
- back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8);
+ back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8);
depth_stride =
dev_priv->depth_pitch / (dev_priv->depth_bpp / 8);
@@ -888,7 +888,7 @@ static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init)
return -ENOMEM;
}
- if (savage_dma_init(dev_priv) < 0) {
+ if (savage_dma_init(dev_priv) < 0) {
DRM_ERROR("could not initialize command DMA\n");
savage_do_cleanup_bci(dev);
return -ENOMEM;
@@ -983,7 +983,7 @@ static int savage_bci_event_wait(struct drm_device *dev, void *data, struct drm_
* - event counter wrapped since the event was emitted or
* - the hardware has advanced up to or over the event to wait for.
*/
- if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) )
+ if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e))
return 0;
else
return dev_priv->wait_evnt(dev_priv, event_e);
@@ -1065,8 +1065,6 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv)
if (!dma->buflist)
return;
- /*i830_flush_queue(dev);*/
-
for (i = 0; i < dma->buf_count; i++) {
struct drm_buf *buf = dma->buflist[i];
drm_savage_buf_priv_t *buf_priv = buf->dev_private;
diff --git a/sys/dev/pci/drm/savage_state.c b/sys/dev/pci/drm/savage_state.c
index 61ec11cc6ca..1c5a0e2eace 100644
--- a/sys/dev/pci/drm/savage_state.c
+++ b/sys/dev/pci/drm/savage_state.c
@@ -30,23 +30,23 @@ void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
const struct drm_clip_rect *pbox)
{
uint32_t scstart = dev_priv->state.s3d.new_scstart;
- uint32_t scend = dev_priv->state.s3d.new_scend;
+ uint32_t scend = dev_priv->state.s3d.new_scend;
scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) |
((uint32_t)pbox->x1 & 0x000007ff) |
(((uint32_t)pbox->y1 << 16) & 0x07ff0000);
- scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
- (((uint32_t)pbox->x2-1) & 0x000007ff) |
- ((((uint32_t)pbox->y2-1) << 16) & 0x07ff0000);
+ scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
+ (((uint32_t)pbox->x2 - 1) & 0x000007ff) |
+ ((((uint32_t)pbox->y2 - 1) << 16) & 0x07ff0000);
if (scstart != dev_priv->state.s3d.scstart ||
scend != dev_priv->state.s3d.scend) {
DMA_LOCALS;
BEGIN_DMA(4);
- DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
+ DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2);
DMA_WRITE(scstart);
DMA_WRITE(scend);
dev_priv->state.s3d.scstart = scstart;
- dev_priv->state.s3d.scend = scend;
+ dev_priv->state.s3d.scend = scend;
dev_priv->waiting = 1;
DMA_COMMIT();
}
@@ -61,13 +61,13 @@ void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
((uint32_t)pbox->x1 & 0x000007ff) |
(((uint32_t)pbox->y1 << 12) & 0x00fff000);
drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) |
- (((uint32_t)pbox->x2-1) & 0x000007ff) |
- ((((uint32_t)pbox->y2-1) << 12) & 0x00fff000);
+ (((uint32_t)pbox->x2 - 1) & 0x000007ff) |
+ ((((uint32_t)pbox->y2 - 1) << 12) & 0x00fff000);
if (drawctrl0 != dev_priv->state.s4.drawctrl0 ||
drawctrl1 != dev_priv->state.s4.drawctrl1) {
DMA_LOCALS;
BEGIN_DMA(4);
- DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
+ DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2);
DMA_WRITE(drawctrl0);
DMA_WRITE(drawctrl1);
@@ -87,8 +87,8 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
}
if (!(addr & 1)) { /* local */
addr &= ~7;
- if (addr < dev_priv->texture_offset ||
- addr >= dev_priv->texture_offset+dev_priv->texture_size) {
+ if (addr < dev_priv->texture_offset ||
+ addr >= dev_priv->texture_offset + dev_priv->texture_size) {
DRM_ERROR
("bad texAddr%d %08x (local addr out of range)\n",
unit, addr);
@@ -114,10 +114,10 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
}
#define SAVE_STATE(reg,where) \
- if(start <= reg && start+count > reg) \
+ if(start <= reg && start + count > reg) \
dev_priv->state.where = regs[reg - start]
#define SAVE_STATE_MASK(reg,where,mask) do { \
- if(start <= reg && start+count > reg) { \
+ if(start <= reg && start + count > reg) { \
uint32_t tmp; \
tmp = regs[reg - start]; \
dev_priv->state.where = (tmp & (mask)) | \
@@ -129,9 +129,9 @@ static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
const uint32_t *regs)
{
if (start < SAVAGE_TEXPALADDR_S3D ||
- start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
+ start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
- start, start+count-1);
+ start, start + count - 1);
return -EINVAL;
}
@@ -142,7 +142,7 @@ static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
/* if any texture regs were changed ... */
if (start <= SAVAGE_TEXCTRL_S3D &&
- start+count > SAVAGE_TEXPALADDR_S3D) {
+ start + count > SAVAGE_TEXPALADDR_S3D) {
/* ... check texture state */
SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl);
SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
@@ -161,9 +161,9 @@ static int savage_verify_state_s4(drm_savage_private_t *dev_priv,
int ret = 0;
if (start < SAVAGE_DRAWLOCALCTRL_S4 ||
- start+count-1 > SAVAGE_TEXBLENDCOLOR_S4) {
+ start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) {
DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
- start, start+count-1);
+ start, start + count - 1);
return -EINVAL;
}
@@ -212,14 +212,14 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
return ret;
/* scissor regs are emitted in savage_dispatch_draw */
if (start < SAVAGE_SCSTART_S3D) {
- if (start+count > SAVAGE_SCEND_S3D+1)
- count2 = count - (SAVAGE_SCEND_S3D+1 - start);
- if (start+count > SAVAGE_SCSTART_S3D)
+ if (start + count > SAVAGE_SCEND_S3D + 1)
+ count2 = count - (SAVAGE_SCEND_S3D + 1 - start);
+ if (start + count > SAVAGE_SCSTART_S3D)
count = SAVAGE_SCSTART_S3D - start;
} else if (start <= SAVAGE_SCEND_S3D) {
- if (start+count > SAVAGE_SCEND_S3D+1) {
- count -= SAVAGE_SCEND_S3D+1 - start;
- start = SAVAGE_SCEND_S3D+1;
+ if (start + count > SAVAGE_SCEND_S3D + 1) {
+ count -= SAVAGE_SCEND_S3D + 1 - start;
+ start = SAVAGE_SCEND_S3D + 1;
} else
return 0;
}
@@ -229,24 +229,24 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
return ret;
/* scissor regs are emitted in savage_dispatch_draw */
if (start < SAVAGE_DRAWCTRL0_S4) {
- if (start+count > SAVAGE_DRAWCTRL1_S4+1)
+ if (start + count > SAVAGE_DRAWCTRL1_S4 + 1)
count2 = count -
(SAVAGE_DRAWCTRL1_S4 + 1 - start);
- if (start+count > SAVAGE_DRAWCTRL0_S4)
+ if (start + count > SAVAGE_DRAWCTRL0_S4)
count = SAVAGE_DRAWCTRL0_S4 - start;
} else if (start <= SAVAGE_DRAWCTRL1_S4) {
- if (start+count > SAVAGE_DRAWCTRL1_S4+1) {
- count -= SAVAGE_DRAWCTRL1_S4+1 - start;
- start = SAVAGE_DRAWCTRL1_S4+1;
+ if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) {
+ count -= SAVAGE_DRAWCTRL1_S4 + 1 - start;
+ start = SAVAGE_DRAWCTRL1_S4 + 1;
} else
return 0;
}
}
- bci_size = count + (count+254)/255 + count2 + (count2+254)/255;
+ bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255;
if (cmd_header->state.global) {
- BEGIN_DMA(bci_size+1);
+ BEGIN_DMA(bci_size + 1);
DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
dev_priv->waiting = 1;
} else {
@@ -286,8 +286,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
BCI_LOCALS;
if (!dmabuf) {
- DRM_ERROR("called without dma buffers!\n");
- return -EINVAL;
+ DRM_ERROR("called without dma buffers!\n");
+ return -EINVAL;
}
if (!n)
@@ -337,9 +337,9 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
}
}
- if (start + n > dmabuf->total/32) {
+ if (start + n > dmabuf->total / 32) {
DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
- start, start + n - 1, dmabuf->total/32);
+ start, start + n - 1, dmabuf->total / 32);
return -EINVAL;
}
@@ -374,33 +374,33 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
/* Need to reorder indices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {-1, -1, -1};
- reorder[start%3] = 2;
+ int reorder[3] = { -1, -1, -1 };
+ reorder[start % 3] = 2;
- BEGIN_BCI((count+1+1)/2);
- BCI_DRAW_INDICES_S3D(count, prim, start+2);
+ BEGIN_BCI((count + 1 + 1) / 2);
+ BCI_DRAW_INDICES_S3D(count, prim, start + 2);
- for (i = start+1; i+1 < start+count; i += 2)
+ for (i = start + 1; i + 1 < start + count; i += 2)
BCI_WRITE((i + reorder[i % 3]) |
((i + 1 +
reorder[(i + 1) % 3]) << 16));
- if (i < start+count)
- BCI_WRITE(i + reorder[i%3]);
+ if (i < start + count)
+ BCI_WRITE(i + reorder[i % 3]);
} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
- BEGIN_BCI((count+1+1)/2);
+ BEGIN_BCI((count + 1 + 1) / 2);
BCI_DRAW_INDICES_S3D(count, prim, start);
- for (i = start+1; i+1 < start+count; i += 2)
- BCI_WRITE(i | ((i+1) << 16));
- if (i < start+count)
+ for (i = start + 1; i + 1 < start + count; i += 2)
+ BCI_WRITE(i | ((i + 1) << 16));
+ if (i < start + count)
BCI_WRITE(i);
} else {
- BEGIN_BCI((count+2+1)/2);
+ BEGIN_BCI((count + 2 + 1) / 2);
BCI_DRAW_INDICES_S4(count, prim, skip);
- for (i = start; i+1 < start+count; i += 2)
- BCI_WRITE(i | ((i+1) << 16));
- if (i < start+count)
+ for (i = start; i + 1 < start + count; i += 2)
+ BCI_WRITE(i | ((i + 1) << 16));
+ if (i < start + count)
BCI_WRITE(i);
}
@@ -479,9 +479,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
return -EINVAL;
}
- if (start + n > vb_size / (vb_stride*4)) {
+ if (start + n > vb_size / (vb_stride * 4)) {
DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
- start, start + n - 1, vb_size / (vb_stride*4));
+ start, start + n - 1, vb_size / (vb_stride * 4));
return -EINVAL;
}
@@ -493,28 +493,28 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
/* Need to reorder vertices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {-1, -1, -1};
- reorder[start%3] = 2;
+ int reorder[3] = { -1, -1, -1 };
+ reorder[start % 3] = 2;
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
- for (i = start; i < start+count; ++i) {
+ for (i = start; i < start + count; ++i) {
unsigned int j = i + reorder[i % 3];
- DMA_COPY(&vtxbuf[vb_stride*j], vtx_size);
+ DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
}
DMA_COMMIT();
} else {
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
if (vb_stride == vtx_size) {
- DMA_COPY(&vtxbuf[vb_stride*start],
- vtx_size*count);
+ DMA_COPY(&vtxbuf[vb_stride * start],
+ vtx_size * count);
} else {
- for (i = start; i < start+count; ++i) {
- DMA_COPY(&vtxbuf[vb_stride*i],
+ for (i = start; i < start + count; ++i) {
+ DMA_COPY(&vtxbuf[vb_stride * i],
vtx_size);
}
}
@@ -544,8 +544,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
BCI_LOCALS;
if (!dmabuf) {
- DRM_ERROR("called without dma buffers!\n");
- return -EINVAL;
+ DRM_ERROR("called without dma buffers!\n");
+ return -EINVAL;
}
if (!n)
@@ -623,9 +623,9 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
/* check indices */
for (i = 0; i < count; ++i) {
- if (idx[i] > dmabuf->total/32) {
+ if (idx[i] > dmabuf->total / 32) {
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
- i, idx[i], dmabuf->total/32);
+ i, idx[i], dmabuf->total / 32);
return -EINVAL;
}
}
@@ -634,31 +634,31 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
/* Need to reorder indices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {2, -1, -1};
+ int reorder[3] = { 2, -1, -1 };
- BEGIN_BCI((count+1+1)/2);
+ BEGIN_BCI((count + 1 + 1) / 2);
BCI_DRAW_INDICES_S3D(count, prim, idx[2]);
- for (i = 1; i+1 < count; i += 2)
+ for (i = 1; i + 1 < count; i += 2)
BCI_WRITE(idx[i + reorder[i % 3]] |
(idx[i + 1 +
reorder[(i + 1) % 3]] << 16));
if (i < count)
- BCI_WRITE(idx[i + reorder[i%3]]);
+ BCI_WRITE(idx[i + reorder[i % 3]]);
} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
- BEGIN_BCI((count+1+1)/2);
+ BEGIN_BCI((count + 1 + 1) / 2);
BCI_DRAW_INDICES_S3D(count, prim, idx[0]);
- for (i = 1; i+1 < count; i += 2)
- BCI_WRITE(idx[i] | (idx[i+1] << 16));
+ for (i = 1; i + 1 < count; i += 2)
+ BCI_WRITE(idx[i] | (idx[i + 1] << 16));
if (i < count)
BCI_WRITE(idx[i]);
} else {
- BEGIN_BCI((count+2+1)/2);
+ BEGIN_BCI((count + 2 + 1) / 2);
BCI_DRAW_INDICES_S4(count, prim, skip);
- for (i = 0; i+1 < count; i += 2)
- BCI_WRITE(idx[i] | (idx[i+1] << 16));
+ for (i = 0; i + 1 < count; i += 2)
+ BCI_WRITE(idx[i] | (idx[i + 1] << 16));
if (i < count)
BCI_WRITE(idx[i]);
}
@@ -743,9 +743,9 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
/* Check indices */
for (i = 0; i < count; ++i) {
- if (idx[i] > vb_size / (vb_stride*4)) {
+ if (idx[i] > vb_size / (vb_stride * 4)) {
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
- i, idx[i], vb_size / (vb_stride*4));
+ i, idx[i], vb_size / (vb_stride * 4));
return -EINVAL;
}
}
@@ -754,24 +754,24 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
/* Need to reorder vertices for correct flat
* shading while preserving the clock sense
* for correct culling. Only on Savage3D. */
- int reorder[3] = {2, -1, -1};
+ int reorder[3] = { 2, -1, -1 };
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
for (i = 0; i < count; ++i) {
unsigned int j = idx[i + reorder[i % 3]];
- DMA_COPY(&vtxbuf[vb_stride*j], vtx_size);
+ DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
}
DMA_COMMIT();
} else {
- BEGIN_DMA(count*vtx_size+1);
+ BEGIN_DMA(count * vtx_size + 1);
DMA_DRAW_PRIMITIVE(count, prim, skip);
for (i = 0; i < count; ++i) {
unsigned int j = idx[i];
- DMA_COPY(&vtxbuf[vb_stride*j], vtx_size);
+ DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
}
DMA_COMMIT();
@@ -823,12 +823,12 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
x = boxes[i].x1, y = boxes[i].y1;
w = boxes[i].x2 - boxes[i].x1;
h = boxes[i].y2 - boxes[i].y1;
- BEGIN_DMA(nbufs*6);
+ BEGIN_DMA(nbufs * 6);
for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
if (!(flags & buf))
continue;
DMA_WRITE(clear_cmd);
- switch(buf) {
+ switch (buf) {
case SAVAGE_FRONT:
DMA_WRITE(dev_priv->front_offset);
DMA_WRITE(dev_priv->front_bd);
@@ -880,8 +880,8 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
DMA_WRITE(dev_priv->back_bd);
DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
- DMA_WRITE(BCI_W_H(boxes[i].x2-boxes[i].x1,
- boxes[i].y2-boxes[i].y1));
+ DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1,
+ boxes[i].y2 - boxes[i].y1));
DMA_COMMIT();
}
@@ -973,7 +973,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
if (cmdbuf->dma_idx > dma->buf_count) {
DRM_ERROR
("vertex buffer index %u out of range (0-%u)\n",
- cmdbuf->dma_idx, dma->buf_count-1);
+ cmdbuf->dma_idx, dma->buf_count - 1);
return -EINVAL;
}
dmabuf = dma->buflist[cmdbuf->dma_idx];
@@ -1064,15 +1064,15 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
case SAVAGE_CMD_DMA_PRIM:
case SAVAGE_CMD_VB_PRIM:
if (!first_draw_cmd)
- first_draw_cmd = cmdbuf->cmd_addr-1;
+ first_draw_cmd = cmdbuf->cmd_addr - 1;
cmdbuf->cmd_addr += j;
i += j;
break;
default:
if (first_draw_cmd) {
- ret = savage_dispatch_draw (
+ ret = savage_dispatch_draw(
dev_priv, first_draw_cmd,
- cmdbuf->cmd_addr-1,
+ cmdbuf->cmd_addr - 1,
dmabuf, cmdbuf->vb_addr,
cmdbuf->vb_size,
cmdbuf->vb_stride,
@@ -1134,7 +1134,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
}
if (first_draw_cmd) {
- ret = savage_dispatch_draw (
+ ret = savage_dispatch_draw(
dev_priv, first_draw_cmd, cmdbuf->cmd_addr, dmabuf,
cmdbuf->vb_addr, cmdbuf->vb_size, cmdbuf->vb_stride,
cmdbuf->nbox, cmdbuf->box_addr);
diff --git a/sys/dev/pci/drm/sis_drv.h b/sys/dev/pci/drm/sis_drv.h
index a4a88fe1db4..db532f3c3e1 100644
--- a/sys/dev/pci/drm/sis_drv.h
+++ b/sys/dev/pci/drm/sis_drv.h
@@ -84,8 +84,6 @@ extern int sis_final_context(struct drm_device * dev, int context);
#endif
-
-
extern struct drm_ioctl_desc sis_ioctls[];
extern int sis_max_ioctl;
diff --git a/sys/dev/pci/drm/via_3d_reg.h b/sys/dev/pci/drm/via_3d_reg.h
index cf61bb514db..462375d543b 100644
--- a/sys/dev/pci/drm/via_3d_reg.h
+++ b/sys/dev/pci/drm/via_3d_reg.h
@@ -1643,7 +1643,6 @@
#define HC_HAGPBpID_STOP 0x00000002
#define HC_HAGPBpH_MASK 0x00ffffff
-
#define VIA_VIDEO_HEADER5 0xFE040000
#define VIA_VIDEO_HEADER6 0xFE050000
#define VIA_VIDEO_HEADER7 0xFE060000
diff --git a/sys/dev/pci/drm/via_dma.c b/sys/dev/pci/drm/via_dma.c
index 89753aa6872..9f58bfa2bb9 100644
--- a/sys/dev/pci/drm/via_dma.c
+++ b/sys/dev/pci/drm/via_dma.c
@@ -54,11 +54,11 @@
*vb++ = (w2); \
dev_priv->dma_low += 8;
-static void via_cmdbuf_start(drm_via_private_t * dev_priv);
-static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
-static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
-static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
-static int via_wait_idle(drm_via_private_t * dev_priv);
+static void via_cmdbuf_start(drm_via_private_t *dev_priv);
+static void via_cmdbuf_pause(drm_via_private_t *dev_priv);
+static void via_cmdbuf_reset(drm_via_private_t *dev_priv);
+static void via_cmdbuf_rewind(drm_via_private_t *dev_priv);
+static int via_wait_idle(drm_via_private_t *dev_priv);
static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
@@ -110,9 +110,11 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
if (count-- == 0) {
DRM_ERROR
("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
- hw_addr, cur_addr, next_addr);
+ hw_addr, cur_addr, next_addr);
return -1;
}
+ if ((cur_addr < hw_addr) && (next_addr >= hw_addr))
+ msleep(1);
} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
return 0;
}
@@ -167,14 +169,12 @@ static int via_initialize(struct drm_device * dev,
}
if (dev_priv->ring.virtual_start != NULL) {
- DRM_ERROR("%s called again without calling cleanup\n",
- __FUNCTION__);
+ DRM_ERROR("called again without calling cleanup\n");
return -EFAULT;
}
if (!dev->agp || !dev->agp->base) {
- DRM_ERROR("%s called with no agp memory available\n",
- __FUNCTION__);
+ DRM_ERROR("called with no agp memory available\n");
return -EFAULT;
}
@@ -257,8 +257,7 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t *
dev_priv = (drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start == NULL) {
- DRM_ERROR("%s called without initializing AGP ring buffer.\n",
- __FUNCTION__);
+ DRM_ERROR("called without initializing AGP ring buffer.\n");
return -EFAULT;
}
@@ -327,8 +326,7 @@ static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *fi
LOCK_TEST_WITH_RETURN(dev, file_priv);
- DRM_DEBUG("via cmdbuffer, buf %p size %lu\n", cmdbuf->buf,
- cmdbuf->size);
+ DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
ret = via_dispatch_cmdbuffer(dev, cmdbuf);
if (ret) {
@@ -369,8 +367,7 @@ static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
- DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf->buf,
- cmdbuf->size);
+ DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf);
if (ret) {
@@ -411,27 +408,50 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
int paused, count;
volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
uint32_t reader,ptr;
+ uint32_t diff;
paused = 0;
via_flush_write_combine();
(void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1);
+
*paused_at = pause_addr_lo;
via_flush_write_combine();
(void) *paused_at;
+
reader = *(dev_priv->hw_addr_ptr);
ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+
dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
- if ((ptr - reader) <= dev_priv->dma_diff ) {
- count = 10000000;
- while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
+ /*
+ * If there is a possibility that the command reader will
+ * miss the new pause address and pause on the old one,
+ * In that case we need to program the new start address
+ * using PCI.
+ */
+
+ diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
+ count = 10000000;
+ while(diff == 0 && count--) {
+ paused = (VIA_READ(0x41c) & 0x80000000);
+ if (paused)
+ break;
+ reader = *(dev_priv->hw_addr_ptr);
+ diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
}
+ paused = VIA_READ(0x41c) & 0x80000000;
+
if (paused && !no_pci_fire) {
reader = *(dev_priv->hw_addr_ptr);
- if ((ptr - reader) == dev_priv->dma_diff) {
-
+ diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
+ diff &= (dev_priv->dma_high - 1);
+ if (diff != 0 && diff < (dev_priv->dma_high >> 1)) {
+ DRM_ERROR("Paused at incorrect address. "
+ "0x%08x, 0x%08x 0x%08x\n",
+ ptr, reader, dev_priv->dma_diff);
+ } else if (diff == 0) {
/*
* There is a concern that these writes may stall the PCI bus
* if the GPU is not idle. However, idling the GPU first
@@ -450,7 +470,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
-static int via_wait_idle(drm_via_private_t * dev_priv)
+static int via_wait_idle(drm_via_private_t *dev_priv)
{
int count = 10000000;
@@ -462,7 +482,7 @@ static int via_wait_idle(drm_via_private_t * dev_priv)
return count;
}
-static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
+static uint32_t *via_align_cmd(drm_via_private_t *dev_priv, uint32_t cmd_type,
uint32_t addr, uint32_t *cmd_addr_hi,
uint32_t *cmd_addr_lo, int skip_wait)
{
@@ -472,11 +492,12 @@ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
uint32_t qw_pad_count;
if (!skip_wait)
- via_cmdbuf_wait(dev_priv, 2*CMDBUF_ALIGNMENT_SIZE);
+ via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE);
vb = via_get_dma(dev_priv);
- VIA_OUT_RING_QW( HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
- (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
+ VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
+ (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
+
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
@@ -557,8 +578,8 @@ static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
via_cmdbuf_wait(dev_priv, qwords + 2);
vb = via_get_dma(dev_priv);
- VIA_OUT_RING_QW( HC_HEADER2, HC_ParaType_NotTex << 16);
- via_align_buffer(dev_priv,vb,qwords);
+ VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16);
+ via_align_buffer(dev_priv, vb, qwords);
}
static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
@@ -575,14 +596,14 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
uint32_t pause_addr_lo, pause_addr_hi;
uint32_t jump_addr_lo, jump_addr_hi;
volatile uint32_t *last_pause_ptr;
-
+ uint32_t dma_low_save1, dma_low_save2;
+
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
- via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
+ via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
&jump_addr_lo, 0);
dev_priv->dma_wrap = dev_priv->dma_low;
-
/*
* Wrap command buffer to the beginning.
*/
@@ -594,13 +615,37 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
via_dummy_bitblt(dev_priv);
via_dummy_bitblt(dev_priv);
- last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
- &pause_addr_lo, 0) -1;
- via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+
+ last_pause_ptr =
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0) - 1;
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
&pause_addr_lo, 0);
+
*last_pause_ptr = pause_addr_lo;
+ dma_low_save1 = dev_priv->dma_low;
+
+ /*
+ * Now, set a trap that will pause the regulator if it tries to rerun the old
+ * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
+ * and reissues the jump command over PCI, while the regulator has already taken the jump
+ * and actually paused at the current buffer end).
+ * There appears to be no other way to detect this condition, since the hw_addr_pointer
+ * does not seem to get updated immediately when a jump occurs.
+ */
- via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
+ last_pause_ptr =
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0) - 1;
+ via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
+ &pause_addr_lo, 0);
+ *last_pause_ptr = pause_addr_lo;
+
+ dma_low_save2 = dev_priv->dma_low;
+ dev_priv->dma_low = dma_low_save1;
+ via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
+ dev_priv->dma_low = dma_low_save2;
+ via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
}
@@ -614,7 +659,7 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
uint32_t pause_addr_lo, pause_addr_hi;
via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
- via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
+ via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
}
@@ -640,20 +685,19 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *
uint32_t tmp_size, count;
drm_via_private_t *dev_priv;
- DRM_DEBUG("via cmdbuf_size\n");
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
dev_priv = (drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start == NULL) {
- DRM_ERROR("%s called without initializing AGP ring buffer.\n",
- __FUNCTION__);
+ DRM_ERROR("called without initializing AGP ring buffer.\n");
return -EFAULT;
}
count = 1000000;
tmp_size = d_siz->size;
- switch(d_siz->func) {
+ switch (d_siz->func) {
case VIA_CMDBUF_SPACE:
while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size)
&& count--) {
diff --git a/sys/dev/pci/drm/via_drm.h b/sys/dev/pci/drm/via_drm.h
index 7ee69d28ef7..e6a8ec647f8 100644
--- a/sys/dev/pci/drm/via_drm.h
+++ b/sys/dev/pci/drm/via_drm.h
@@ -228,7 +228,7 @@ typedef enum {
#define VIA_IRQ_FLAGS_MASK 0xF0000000
-enum drm_via_irqs{
+enum drm_via_irqs {
drm_via_irq_hqv0 = 0,
drm_via_irq_hqv1,
drm_via_irq_dma0_dd,
@@ -238,7 +238,7 @@ enum drm_via_irqs{
drm_via_irq_num
};
-struct drm_via_wait_irq_request{
+struct drm_via_wait_irq_request {
unsigned irq;
via_irq_seq_type_t type;
uint32_t sequence;
@@ -270,9 +270,9 @@ typedef struct drm_via_dmablit {
uint32_t fb_stride;
unsigned char *mem_addr;
- uint32_t mem_stride;
+ uint32_t mem_stride;
- uint32_t flags;
+ uint32_t flags;
int to_fb;
drm_via_blitsync_t sync;
diff --git a/sys/dev/pci/drm/via_drv.c b/sys/dev/pci/drm/via_drv.c
index 86aa2b550ec..5f3a004c4f4 100644
--- a/sys/dev/pci/drm/via_drv.c
+++ b/sys/dev/pci/drm/via_drv.c
@@ -49,7 +49,9 @@ via_configure(drm_device_t *dev)
dev->driver.unload = via_driver_unload;
dev->driver.context_ctor = via_init_context;
dev->driver.context_dtor = via_final_context;
- dev->driver.vblank_wait = via_driver_vblank_wait;
+ dev->driver.get_vblank_counter = via_get_vblank_counter;
+ dev->driver.enable_vblank = via_enable_vblank;
+ dev->driver.disable_vblank = via_disable_vblank;
dev->driver.irq_preinstall = via_driver_irq_preinstall;
dev->driver.irq_postinstall = via_driver_irq_postinstall;
dev->driver.irq_uninstall = via_driver_irq_uninstall;
diff --git a/sys/dev/pci/drm/via_drv.h b/sys/dev/pci/drm/via_drv.h
index d6da8bd9e7d..941a2d77a07 100644
--- a/sys/dev/pci/drm/via_drv.h
+++ b/sys/dev/pci/drm/via_drv.h
@@ -102,6 +102,7 @@ typedef struct drm_via_private {
struct timeval last_vblank;
int last_vblank_valid;
unsigned usec_per_vblank;
+ atomic_t vbl_received;
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
@@ -166,11 +167,13 @@ extern int via_driver_unload(struct drm_device *dev);
extern int via_final_context(struct drm_device * dev, int context);
extern int via_do_cleanup_map(struct drm_device * dev);
-extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
+extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
+extern int via_enable_vblank(struct drm_device *dev, int crtc);
+extern void via_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
extern void via_driver_irq_preinstall(struct drm_device * dev);
-extern void via_driver_irq_postinstall(struct drm_device * dev);
+extern int via_driver_irq_postinstall(struct drm_device * dev);
extern void via_driver_irq_uninstall(struct drm_device * dev);
extern int via_dma_cleanup(struct drm_device * dev);
@@ -193,17 +196,6 @@ extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq
extern void via_init_dmablit(struct drm_device *dev);
#endif
-#ifdef VIA_HAVE_FENCE
-extern void via_fence_timer(unsigned long data);
-extern void via_poke_flush(struct drm_device * dev, uint32_t class);
-extern int via_fence_emit_sequence(struct drm_device * dev, uint32_t class,
- uint32_t flags,
- uint32_t * sequence,
- uint32_t * native_type);
-extern int via_fence_has_irq(struct drm_device * dev, uint32_t class,
- uint32_t flags);
-#endif
-
#ifdef VIA_HAVE_BUFFER
extern struct drm_ttm_backend *via_create_ttm_backend_entry(struct drm_device *dev);
extern int via_fence_types(struct drm_buffer_object *bo, uint32_t *fclass,
@@ -211,7 +203,7 @@ extern int via_fence_types(struct drm_buffer_object *bo, uint32_t *fclass,
extern int via_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
extern int via_init_mem_type(struct drm_device *dev, uint32_t type,
struct drm_mem_type_manager *man);
-extern uint32_t via_evict_mask(struct drm_buffer_object *bo);
+extern uint64_t via_evict_flags(struct drm_buffer_object *bo);
extern int via_move(struct drm_buffer_object *bo, int evict,
int no_wait, struct drm_bo_mem_reg *new_mem);
#endif
diff --git a/sys/dev/pci/drm/via_irq.c b/sys/dev/pci/drm/via_irq.c
index df91ab00fb7..c3279f8b5c2 100644
--- a/sys/dev/pci/drm/via_irq.c
+++ b/sys/dev/pci/drm/via_irq.c
@@ -76,8 +76,7 @@ static maskarray_t via_pro_group_a_irqs[] = {
{VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
};
-static int via_num_pro_group_a =
- sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t);
+static int via_num_pro_group_a = ARRAY_SIZE(via_pro_group_a_irqs);
static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3};
static maskarray_t via_unichrome_irqs[] = {
@@ -86,15 +85,24 @@ static maskarray_t via_unichrome_irqs[] = {
{VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}
};
-static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t);
+static int via_num_unichrome = ARRAY_SIZE(via_unichrome_irqs);
static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
static unsigned time_diff(struct timeval *now,struct timeval *then)
{
- return (now->tv_usec >= then->tv_usec) ?
- now->tv_usec - then->tv_usec :
- 1000000 - (then->tv_usec - now->tv_usec);
+ return (now->tv_usec >= then->tv_usec) ?
+ now->tv_usec - then->tv_usec :
+ 1000000 - (then->tv_usec - now->tv_usec);
+}
+
+u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
}
irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
@@ -109,8 +117,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
status = VIA_READ(VIA_REG_INTERRUPT);
if (status & VIA_IRQ_VBLANK_PENDING) {
- atomic_inc(&dev->vbl_received);
- if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
+ atomic_inc(&dev_priv->vbl_received);
+ if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
#ifdef __linux__
do_gettimeofday(&cur_vblank);
#else
@@ -124,19 +132,18 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
dev_priv->last_vblank = cur_vblank;
dev_priv->last_vblank_valid = 1;
}
- if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
+ if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
DRM_DEBUG("US per vblank is: %u\n",
- dev_priv->usec_per_vblank);
+ dev_priv->usec_per_vblank);
}
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ drm_handle_vblank(dev, 0);
handled = 1;
}
- for (i=0; i<dev_priv->num_irqs; ++i) {
+ for (i = 0; i < dev_priv->num_irqs; ++i) {
if (status & cur_irq->pending_mask) {
- atomic_inc( &cur_irq->irq_received );
- DRM_WAKEUP( &cur_irq->irq_queue );
+ atomic_inc(&cur_irq->irq_received);
+ DRM_WAKEUP(&cur_irq->irq_queue);
handled = 1;
#ifdef VIA_HAVE_DMABLIT
if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) {
@@ -171,31 +178,34 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
}
}
-int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int via_enable_vblank(struct drm_device *dev, int crtc)
{
- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
+ drm_via_private_t *dev_priv = dev->dev_private;
+ u32 status;
- DRM_DEBUG("viadrv_vblank_wait\n");
- if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ if (crtc != 0) {
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
return -EINVAL;
}
- viadrv_acknowledge_irqs(dev_priv);
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received)) -
- *sequence) <= (1 << 23)));
+ return 0;
+}
- *sequence = cur_vblank;
- return ret;
+void via_disable_vblank(struct drm_device *dev, int crtc)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
+
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
+
+ if (crtc != 0)
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
}
static int
@@ -209,24 +219,23 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc
maskarray_t *masks;
int real_irq;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- if (irq >= drm_via_irq_num ) {
- DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
- irq);
+ if (irq >= drm_via_irq_num) {
+ DRM_ERROR("Trying to wait on unknown irq %d\n", irq);
return -EINVAL;
}
real_irq = dev_priv->irq_map[irq];
if (real_irq < 0) {
- DRM_ERROR("%s Video IRQ %d not available on this hardware.\n",
- __FUNCTION__, irq);
+ DRM_ERROR("Video IRQ %d not available on this hardware.\n",
+ irq);
return -EINVAL;
}
@@ -260,7 +269,7 @@ void via_driver_irq_preinstall(struct drm_device * dev)
drm_via_irq_t *cur_irq;
int i;
- DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv);
+ DRM_DEBUG("dev_priv: %p\n", dev_priv);
if (dev_priv) {
cur_irq = dev_priv->via_irqs;
@@ -278,11 +287,11 @@ void via_driver_irq_preinstall(struct drm_device * dev)
dev_priv->irq_map = via_irqmap_unichrome;
}
- for(i=0; i < dev_priv->num_irqs; ++i) {
+ for (i = 0; i < dev_priv->num_irqs; ++i) {
atomic_set(&cur_irq->irq_received, 0);
cur_irq->enable_mask = dev_priv->irq_masks[i][0];
cur_irq->pending_mask = dev_priv->irq_masks[i][1];
- DRM_INIT_WAITQUEUE( &cur_irq->irq_queue );
+ DRM_INIT_WAITQUEUE(&cur_irq->irq_queue);
dev_priv->irq_enable_mask |= cur_irq->enable_mask;
dev_priv->irq_pending_mask |= cur_irq->pending_mask;
cur_irq++;
@@ -302,23 +311,25 @@ void via_driver_irq_preinstall(struct drm_device * dev)
}
}
-void via_driver_irq_postinstall(struct drm_device * dev)
+int via_driver_irq_postinstall(struct drm_device * dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
DRM_DEBUG("via_driver_irq_postinstall\n");
- if (dev_priv) {
- status = VIA_READ(VIA_REG_INTERRUPT);
- VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
- | dev_priv->irq_enable_mask);
+ if (!dev_priv)
+ return -EINVAL;
- /* Some magic, oh for some data sheets ! */
+ drm_vblank_init(dev, 1);
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
+ | dev_priv->irq_enable_mask);
- VIA_WRITE8(0x83d4, 0x11);
- VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
+ /* Some magic, oh for some data sheets ! */
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
- }
+ return 0;
}
void via_driver_irq_uninstall(struct drm_device * dev)
@@ -326,7 +337,7 @@ void via_driver_irq_uninstall(struct drm_device * dev)
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
- DRM_DEBUG("driver_irq_uninstall)\n");
+ DRM_DEBUG("\n");
if (dev_priv) {
/* Some more magic, oh for some data sheets ! */
@@ -353,7 +364,7 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
return -EINVAL;
if (irqwait->request.irq >= dev_priv->num_irqs) {
- DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
+ DRM_ERROR("Trying to wait on unknown irq %d\n",
irqwait->request.irq);
return -EINVAL;
}
@@ -372,8 +383,7 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
}
if (irqwait->request.type & VIA_IRQ_SIGNAL) {
- DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
- __FUNCTION__);
+ DRM_ERROR("Signals on Via IRQs not implemented yet.\n");
return -EINVAL;
}
diff --git a/sys/dev/pci/drm/via_map.c b/sys/dev/pci/drm/via_map.c
index b8f61673f85..54934367e4b 100644
--- a/sys/dev/pci/drm/via_map.c
+++ b/sys/dev/pci/drm/via_map.c
@@ -30,7 +30,7 @@ static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
drm_via_private_t *dev_priv = dev->dev_private;
int ret = 0;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
dev_priv->sarea = drm_getsarea(dev);
if (!dev_priv->sarea) {
@@ -69,9 +69,6 @@ static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
dev_priv->emit_0_sequence = 0;
dev_priv->have_idlelock = 0;
spin_lock_init(&dev_priv->fence_lock);
- init_timer(&dev_priv->fence_timer);
- dev_priv->fence_timer.function = &via_fence_timer;
- dev_priv->fence_timer.data = (unsigned long) dev;
#endif /* VIA_HAVE_FENCE */
dev->dev_private = (void *)dev_priv;
#ifdef VIA_HAVE_BUFFER
@@ -95,7 +92,7 @@ int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_init_t *init = data;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
switch (init->func) {
case VIA_INIT_MAP:
diff --git a/sys/dev/pci/drm/via_verifier.c b/sys/dev/pci/drm/via_verifier.c
index cfacd0caeef..d2b69f745ca 100644
--- a/sys/dev/pci/drm/via_verifier.c
+++ b/sys/dev/pci/drm/via_verifier.c
@@ -249,10 +249,10 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
* Partially stolen from drm_memory.h
*/
-static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq,
+static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq,
unsigned long offset,
unsigned long size,
- struct drm_device * dev)
+ struct drm_device *dev)
{
#ifdef __linux__
struct drm_map_list *r_list;
diff --git a/sys/dev/pci/drm/via_verifier.h b/sys/dev/pci/drm/via_verifier.h
index c50a8130c07..abdaa65362b 100644
--- a/sys/dev/pci/drm/via_verifier.h
+++ b/sys/dev/pci/drm/via_verifier.h
@@ -33,8 +33,6 @@ typedef enum {
tex_address
} drm_via_sequence_t;
-
-
typedef struct {
unsigned texture;
uint32_t z_addr;
@@ -45,7 +43,7 @@ typedef struct {
uint32_t tex_level_lo[2];
uint32_t tex_level_hi[2];
uint32_t tex_palette_size[2];
- uint32_t tex_npot[2];
+ uint32_t tex_npot[2];
drm_via_sequence_t unfinished;
int agp_texture;
int multitex;
@@ -56,9 +54,9 @@ typedef struct {
const uint32_t *buf_start;
} drm_via_state_t;
-extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
+extern int via_verify_command_stream(const uint32_t *buf, unsigned int size,
struct drm_device *dev, int agp);
-extern int via_parse_command_stream(struct drm_device *dev, const uint32_t * buf,
+extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf,
unsigned int size);
#endif
diff --git a/sys/dev/pci/drm/via_video.c b/sys/dev/pci/drm/via_video.c
index c15e75b54cb..6ec04ac1245 100644
--- a/sys/dev/pci/drm/via_video.c
+++ b/sys/dev/pci/drm/via_video.c
@@ -33,7 +33,7 @@ void via_init_futex(drm_via_private_t * dev_priv)
{
unsigned int i;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
DRM_INIT_WAITQUEUE(&(dev_priv->decoder_queue[i]));
@@ -73,7 +73,7 @@ int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_
drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
int ret = 0;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (fx->lock > VIA_NR_XVMC_LOCKS)
return -EFAULT;