Merge from DRM upstream:
- Add support for Intel 965 Express chipsets. - Add support for R200 vertex programs, along with minor bugfixes. - Add support for vblank synchronization to pipe B of Intel hardware (laptop screens).
This commit is contained in:
parent
6f44289f61
commit
50839278da
@ -173,7 +173,7 @@ MALLOC_DECLARE(M_DRM);
|
||||
#define wait_queue_head_t atomic_t
|
||||
#define DRM_WAKEUP(w) wakeup((void *)w)
|
||||
#define DRM_WAKEUP_INT(w) wakeup(w)
|
||||
#define DRM_INIT_WAITQUEUE(queue) do {} while (0)
|
||||
#define DRM_INIT_WAITQUEUE(queue) do {(void)(queue);} while (0)
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD_version < 502109
|
||||
#define bus_alloc_resource_any(dev, type, rid, flags) \
|
||||
@ -273,6 +273,7 @@ extern struct cfdriver drm_cd;
|
||||
#endif
|
||||
|
||||
typedef unsigned long dma_addr_t;
|
||||
typedef u_int64_t u64;
|
||||
typedef u_int32_t u32;
|
||||
typedef u_int16_t u16;
|
||||
typedef u_int8_t u8;
|
||||
@ -716,6 +717,9 @@ struct drm_device {
|
||||
struct drm_driver_info driver;
|
||||
drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */
|
||||
|
||||
u_int16_t pci_device; /* PCI device id */
|
||||
u_int16_t pci_vendor; /* PCI vendor id */
|
||||
|
||||
char *unique; /* Unique identifier: e.g., busid */
|
||||
int unique_len; /* Length of unique field */
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -519,6 +519,9 @@ static int drm_load(drm_device_t *dev)
|
||||
dev->pci_slot = pci_get_slot(dev->device);
|
||||
dev->pci_func = pci_get_function(dev->device);
|
||||
|
||||
dev->pci_vendor = pci_get_vendor(dev->device);
|
||||
dev->pci_device = pci_get_device(dev->device);
|
||||
|
||||
TAILQ_INIT(&dev->maplist);
|
||||
|
||||
drm_mem_init();
|
||||
|
@ -230,6 +230,7 @@
|
||||
{0x1106, 0x3122, 0, "VIA CLE266"}, \
|
||||
{0x1106, 0x7205, 0, "VIA KM400"}, \
|
||||
{0x1106, 0x3108, 0, "VIA K8M800"}, \
|
||||
{0x1106, 0x3344, 0, "VIA P4VM800PRO"}, \
|
||||
{0, 0, 0, NULL}
|
||||
|
||||
#define i810_PCI_IDS \
|
||||
@ -288,6 +289,10 @@
|
||||
{0x8086, 0x2592, 0, "Intel i915GM"}, \
|
||||
{0x8086, 0x2772, 0, "Intel i945G"}, \
|
||||
{0x8086, 0x27A2, 0, "Intel i945GM"}, \
|
||||
{0x8086, 0x2972, 0, "Intel i946GZ"}, \
|
||||
{0x8086, 0x2982, 0, "Intel i965G"}, \
|
||||
{0x8086, 0x2992, 0, "Intel i965Q"}, \
|
||||
{0x8086, 0x29A2, 0, "Intel i965G"}, \
|
||||
{0, 0, 0, NULL}
|
||||
|
||||
#define imagine_PCI_IDS \
|
||||
|
@ -34,6 +34,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include "dev/drm/i915_drm.h"
|
||||
#include "dev/drm/i915_drv.h"
|
||||
|
||||
#define IS_I965G(dev) (dev->pci_device == 0x2972 || \
|
||||
dev->pci_device == 0x2982 || \
|
||||
dev->pci_device == 0x2992 || \
|
||||
dev->pci_device == 0x29A2)
|
||||
|
||||
|
||||
/* Really want an OS-independent resettable timer. Would like to have
|
||||
* this loop run for (eg) 3 sec, but have the timer reset every time
|
||||
* the head pointer changes, so that EBUSY only happens if the ring
|
||||
@ -350,14 +356,15 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
|
||||
if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
BEGIN_LP_RING(((dwords+1)&~1));
|
||||
BEGIN_LP_RING((dwords+1)&~1);
|
||||
|
||||
for (i = 0; i < dwords;) {
|
||||
int cmd, sz;
|
||||
|
||||
if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
|
||||
return DRM_ERR(EINVAL);
|
||||
if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) {
|
||||
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
@ -398,25 +405,40 @@ static int i915_emit_box(drm_device_t * dev,
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
BEGIN_LP_RING(6);
|
||||
OUT_RING(GFX_OP_DRAWRECT_INFO);
|
||||
OUT_RING(DR1);
|
||||
OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
|
||||
OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
|
||||
OUT_RING(DR4);
|
||||
OUT_RING(0);
|
||||
ADVANCE_LP_RING();
|
||||
if (IS_I965G(dev)) {
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
|
||||
OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
|
||||
OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
|
||||
OUT_RING(DR4);
|
||||
ADVANCE_LP_RING();
|
||||
} else {
|
||||
BEGIN_LP_RING(6);
|
||||
OUT_RING(GFX_OP_DRAWRECT_INFO);
|
||||
OUT_RING(DR1);
|
||||
OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
|
||||
OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
|
||||
OUT_RING(DR4);
|
||||
OUT_RING(0);
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* XXX: Emitting the counter should really be moved to part of the IRQ
|
||||
* emit. For now, do it in both places:
|
||||
*/
|
||||
|
||||
static void i915_emit_breadcrumb(drm_device_t *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
|
||||
dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
|
||||
|
||||
if (dev_priv->counter > 0x7FFFFFFFUL)
|
||||
dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
|
||||
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING(CMD_STORE_DWORD_IDX);
|
||||
@ -775,7 +797,9 @@ drm_ioctl_desc_t i915_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
|
||||
[DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH},
|
||||
[DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }
|
||||
[DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
|
||||
[DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH },
|
||||
};
|
||||
|
||||
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
|
||||
|
@ -100,7 +100,13 @@ typedef struct _drm_i915_sarea {
|
||||
int rotated_offset;
|
||||
int rotated_size;
|
||||
int rotated_pitch;
|
||||
int virtualX, virtualY;
|
||||
int virtualX, virtualY;
|
||||
|
||||
unsigned int front_tiled;
|
||||
unsigned int back_tiled;
|
||||
unsigned int depth_tiled;
|
||||
unsigned int rotated_tiled;
|
||||
unsigned int rotated2_tiled;
|
||||
} drm_i915_sarea_t;
|
||||
|
||||
/* Flags for perf_boxes
|
||||
@ -127,6 +133,8 @@ typedef struct _drm_i915_sarea {
|
||||
#define DRM_I915_INIT_HEAP 0x0a
|
||||
#define DRM_I915_CMDBUFFER 0x0b
|
||||
#define DRM_I915_DESTROY_HEAP 0x0c
|
||||
#define DRM_I915_SET_VBLANK_PIPE 0x0d
|
||||
#define DRM_I915_GET_VBLANK_PIPE 0x0e
|
||||
|
||||
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
|
||||
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
|
||||
@ -141,6 +149,8 @@ typedef struct _drm_i915_sarea {
|
||||
#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
|
||||
#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
|
||||
#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
|
||||
#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)
|
||||
|
||||
|
||||
/* Allow drivers to submit batchbuffers directly to hardware, relying
|
||||
@ -228,4 +238,13 @@ typedef struct drm_i915_mem_destroy_heap {
|
||||
int region;
|
||||
} drm_i915_mem_destroy_heap_t;
|
||||
|
||||
/* Allow X server to configure which pipes to monitor for vblank signals
|
||||
*/
|
||||
#define DRM_I915_VBLANK_PIPE_A 1
|
||||
#define DRM_I915_VBLANK_PIPE_B 2
|
||||
|
||||
typedef struct drm_i915_vblank_pipe {
|
||||
int pipe;
|
||||
} drm_i915_vblank_pipe_t;
|
||||
|
||||
#endif /* _I915_DRM_H_ */
|
||||
|
@ -48,9 +48,10 @@ __FBSDID("$FreeBSD$");
|
||||
* 1.2: Add Power Management
|
||||
* 1.3: Add vblank support
|
||||
* 1.4: Fix cmdbuffer path, add heap destroy
|
||||
* 1.5: Add vblank pipe configuration
|
||||
*/
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 4
|
||||
#define DRIVER_MINOR 5
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
typedef struct _drm_i915_ring_buffer {
|
||||
@ -99,6 +100,7 @@ typedef struct drm_i915_private {
|
||||
int allow_batchbuffer;
|
||||
struct mem_block *agp_heap;
|
||||
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
|
||||
int vblank_pipe;
|
||||
} drm_i915_private_t;
|
||||
|
||||
extern drm_ioctl_desc_t i915_ioctls[];
|
||||
@ -122,6 +124,8 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
|
||||
extern void i915_driver_irq_preinstall(drm_device_t * dev);
|
||||
extern void i915_driver_irq_postinstall(drm_device_t * dev);
|
||||
extern void i915_driver_irq_uninstall(drm_device_t * dev);
|
||||
extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS);
|
||||
extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS);
|
||||
|
||||
/* i915_mem.c */
|
||||
extern int i915_mem_alloc(DRM_IOCTL_ARGS);
|
||||
@ -140,14 +144,14 @@ extern void i915_mem_release(drm_device_t * dev,
|
||||
#define I915_VERBOSE 0
|
||||
|
||||
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
|
||||
volatile char *virt;
|
||||
volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I915_VERBOSE) \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
|
||||
n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i915_wait_ring(dev, n*4, __FUNCTION__); \
|
||||
(n), __FUNCTION__); \
|
||||
if (dev_priv->ring.space < (n)*4) \
|
||||
i915_wait_ring(dev, (n)*4, __FUNCTION__); \
|
||||
outcount = 0; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
@ -156,8 +160,8 @@ extern void i915_mem_release(drm_device_t * dev,
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outcount++; \
|
||||
*(volatile unsigned int *)(virt + outring) = (n); \
|
||||
outcount++; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0)
|
||||
@ -253,6 +257,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
|
||||
#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
|
||||
#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
|
||||
|
||||
#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
|
||||
|
||||
#define MI_BATCH_BUFFER ((0x30<<23)|1)
|
||||
#define MI_BATCH_BUFFER_START (0x31<<23)
|
||||
#define MI_BATCH_BUFFER_END (0xA<<23)
|
||||
|
@ -48,7 +48,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
|
||||
temp = I915_READ16(I915REG_INT_IDENTITY_R);
|
||||
|
||||
temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG);
|
||||
temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
|
||||
|
||||
DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
|
||||
|
||||
@ -62,7 +62,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
if (temp & USER_INT_FLAG)
|
||||
DRM_WAKEUP(&dev_priv->irq_queue);
|
||||
|
||||
if (temp & VSYNC_PIPEA_FLAG) {
|
||||
if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
|
||||
atomic_inc(&dev->vbl_received);
|
||||
DRM_WAKEUP(&dev->vbl_queue);
|
||||
drm_vbl_send_signals(dev);
|
||||
@ -73,22 +73,32 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
|
||||
static int i915_emit_irq(drm_device_t * dev)
|
||||
{
|
||||
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
u32 ret;
|
||||
RING_LOCALS;
|
||||
|
||||
i915_kernel_lost_context(dev);
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
ret = dev_priv->counter;
|
||||
dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
|
||||
|
||||
BEGIN_LP_RING(2);
|
||||
if (dev_priv->counter > 0x7FFFFFFFUL)
|
||||
dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
|
||||
|
||||
BEGIN_LP_RING(6);
|
||||
OUT_RING(CMD_STORE_DWORD_IDX);
|
||||
OUT_RING(20);
|
||||
OUT_RING(dev_priv->counter);
|
||||
|
||||
OUT_RING(0);
|
||||
OUT_RING(0);
|
||||
OUT_RING(GFX_OP_USER_INTERRUPT);
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
return ret;
|
||||
return dev_priv->counter;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int i915_wait_irq(drm_device_t * dev, int irq_nr)
|
||||
@ -185,6 +195,68 @@ int i915_irq_wait(DRM_IOCTL_ARGS)
|
||||
return i915_wait_irq(dev, irqwait.irq_seq);
|
||||
}
|
||||
|
||||
static int i915_enable_interrupt (drm_device_t *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
u16 flag;
|
||||
|
||||
flag = 0;
|
||||
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
|
||||
flag |= VSYNC_PIPEA_FLAG;
|
||||
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
|
||||
flag |= VSYNC_PIPEB_FLAG;
|
||||
if (dev_priv->vblank_pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
|
||||
DRM_ERROR("%s called with invalid pipe 0x%x\n",
|
||||
__FUNCTION__, dev_priv->vblank_pipe);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the vblank monitor pipe
|
||||
*/
|
||||
int i915_vblank_pipe_set(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
drm_i915_vblank_pipe_t pipe;
|
||||
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data,
|
||||
sizeof(pipe));
|
||||
|
||||
dev_priv->vblank_pipe = pipe.pipe;
|
||||
return i915_enable_interrupt (dev);
|
||||
}
|
||||
|
||||
int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
drm_i915_vblank_pipe_t pipe;
|
||||
u16 flag;
|
||||
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
flag = I915_READ(I915REG_INT_ENABLE_R);
|
||||
pipe.pipe = 0;
|
||||
if (flag & VSYNC_PIPEA_FLAG)
|
||||
pipe.pipe |= DRM_I915_VBLANK_PIPE_A;
|
||||
if (flag & VSYNC_PIPEB_FLAG)
|
||||
pipe.pipe |= DRM_I915_VBLANK_PIPE_B;
|
||||
DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_pipe_t __user *) data, pipe,
|
||||
sizeof(pipe));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* drm_dma.h hooks
|
||||
*/
|
||||
void i915_driver_irq_preinstall(drm_device_t * dev)
|
||||
@ -200,7 +272,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
|
||||
I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG);
|
||||
i915_enable_interrupt(dev);
|
||||
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ __FBSDID("$FreeBSD$");
|
||||
/* Max number of swaps allowed on the ring
|
||||
* before the client must wait
|
||||
*/
|
||||
#define MACH64_MAX_QUEUED_FRAMES 3
|
||||
#define MACH64_MAX_QUEUED_FRAMES 3U
|
||||
|
||||
/* Byte offsets for host blit buffer data
|
||||
*/
|
||||
|
@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
static int radeon_do_cleanup_cp(drm_device_t * dev);
|
||||
|
||||
/* CP microcode (from ATI) */
|
||||
static u32 R200_cp_microcode[][2] = {
|
||||
static const u32 R200_cp_microcode[][2] = {
|
||||
{0x21007000, 0000000000},
|
||||
{0x20007000, 0000000000},
|
||||
{0x000000ab, 0x00000004},
|
||||
@ -301,7 +301,7 @@ static u32 R200_cp_microcode[][2] = {
|
||||
{0000000000, 0000000000},
|
||||
};
|
||||
|
||||
static u32 radeon_cp_microcode[][2] = {
|
||||
static const u32 radeon_cp_microcode[][2] = {
|
||||
{0x21007000, 0000000000},
|
||||
{0x20007000, 0000000000},
|
||||
{0x000000b4, 0x00000004},
|
||||
@ -560,7 +560,7 @@ static u32 radeon_cp_microcode[][2] = {
|
||||
{0000000000, 0000000000},
|
||||
};
|
||||
|
||||
static u32 R300_cp_microcode[][2] = {
|
||||
static const u32 R300_cp_microcode[][2] = {
|
||||
{ 0x4200e000, 0000000000 },
|
||||
{ 0x4000e000, 0000000000 },
|
||||
{ 0x000000af, 0x00000008 },
|
||||
@ -867,13 +867,13 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
|
||||
|
||||
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
|
||||
|
||||
tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT);
|
||||
tmp |= RADEON_RB2D_DC_FLUSH_ALL;
|
||||
RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp);
|
||||
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_RB2D_DSTCACHE_CTLSTAT)
|
||||
& RADEON_RB2D_DC_BUSY)) {
|
||||
if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
|
||||
& RADEON_RB3D_DC_BUSY)) {
|
||||
return 0;
|
||||
}
|
||||
DRM_UDELAY(1);
|
||||
@ -1261,6 +1261,12 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
|
||||
dev_priv->writeback_works = 0;
|
||||
DRM_INFO("writeback forced off\n");
|
||||
}
|
||||
|
||||
if (!dev_priv->writeback_works) {
|
||||
/* Disable writeback to avoid unnecessary bus master transfers */
|
||||
RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | RADEON_RB_NO_UPDATE);
|
||||
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable or disable PCI-E GART on the chip */
|
||||
@ -1348,6 +1354,12 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
|
||||
DRM_DEBUG("Forcing AGP card to PCI mode\n");
|
||||
dev_priv->flags &= ~CHIP_IS_AGP;
|
||||
}
|
||||
else if (!(dev_priv->flags & (CHIP_IS_AGP | CHIP_IS_PCI | CHIP_IS_PCIE))
|
||||
&& !init->is_pci)
|
||||
{
|
||||
DRM_DEBUG("Restoring AGP flag\n");
|
||||
dev_priv->flags |= CHIP_IS_AGP;
|
||||
}
|
||||
|
||||
if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) {
|
||||
DRM_ERROR("PCI GART memory not allocated!\n");
|
||||
@ -2202,9 +2214,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
|
||||
|
||||
if (drm_device_is_agp(dev))
|
||||
dev_priv->flags |= CHIP_IS_AGP;
|
||||
|
||||
if (drm_device_is_pcie(dev))
|
||||
else if (drm_device_is_pcie(dev))
|
||||
dev_priv->flags |= CHIP_IS_PCIE;
|
||||
else
|
||||
dev_priv->flags |= CHIP_IS_PCI;
|
||||
|
||||
DRM_DEBUG("%s card detected\n",
|
||||
((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI"))));
|
||||
|
@ -164,7 +164,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define R200_EMIT_PP_TXCTLALL_3 91
|
||||
#define R200_EMIT_PP_TXCTLALL_4 92
|
||||
#define R200_EMIT_PP_TXCTLALL_5 93
|
||||
#define RADEON_MAX_STATE_PACKETS 94
|
||||
#define R200_EMIT_VAP_PVS_CNTL 94
|
||||
#define RADEON_MAX_STATE_PACKETS 95
|
||||
|
||||
/* Commands understood by cmd_buffer ioctl. More can be added but
|
||||
* obviously these can't be removed or changed:
|
||||
@ -179,6 +180,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
|
||||
* doesn't make the cpu wait, just
|
||||
* the graphics hardware */
|
||||
#define RADEON_CMD_VECLINEAR 9 /* another r200 stopgap */
|
||||
|
||||
typedef union {
|
||||
int i;
|
||||
@ -194,6 +196,9 @@ typedef union {
|
||||
struct {
|
||||
unsigned char cmd_type, offset, stride, count;
|
||||
} vectors;
|
||||
struct {
|
||||
unsigned char cmd_type, addr_lo, addr_hi, count;
|
||||
} veclinear;
|
||||
struct {
|
||||
unsigned char cmd_type, buf_idx, pad0, pad1;
|
||||
} dma;
|
||||
|
@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define DRIVER_NAME "radeon"
|
||||
#define DRIVER_DESC "ATI Radeon"
|
||||
#define DRIVER_DATE "20060225"
|
||||
#define DRIVER_DATE "20060524"
|
||||
|
||||
/* Interface history:
|
||||
*
|
||||
@ -96,10 +96,12 @@ __FBSDID("$FreeBSD$");
|
||||
* 1.22- Add support for texture cache flushes (R300_TX_CNTL)
|
||||
* 1.23- Add new radeon memory map work from benh
|
||||
* 1.24- Add general-purpose packet for manipulating scratch registers (r300)
|
||||
* 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
|
||||
* new packet type)
|
||||
*/
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 24
|
||||
#define DRIVER_MINOR 25
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
/*
|
||||
@ -144,6 +146,7 @@ enum radeon_chip_flags {
|
||||
CHIP_HAS_HIERZ = 0x00100000UL,
|
||||
CHIP_IS_PCIE = 0x00200000UL,
|
||||
CHIP_NEW_MEMMAP = 0x00400000UL,
|
||||
CHIP_IS_PCI = 0x00800000UL,
|
||||
};
|
||||
|
||||
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
|
||||
@ -544,6 +547,11 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,
|
||||
# define RADEON_RB3D_ZC_FREE (1 << 2)
|
||||
# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
|
||||
# define RADEON_RB3D_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 RADEON_RB3D_ZSTENCILCNTL 0x1c2c
|
||||
# define RADEON_Z_TEST_MASK (7 << 4)
|
||||
# define RADEON_Z_TEST_ALWAYS (7 << 4)
|
||||
@ -680,6 +688,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,
|
||||
#define RADEON_CP_RB_BASE 0x0700
|
||||
#define RADEON_CP_RB_CNTL 0x0704
|
||||
# define RADEON_BUF_SWAP_32BIT (2 << 16)
|
||||
# define RADEON_RB_NO_UPDATE (1 << 27)
|
||||
#define RADEON_CP_RB_RPTR_ADDR 0x070c
|
||||
#define RADEON_CP_RB_RPTR 0x0710
|
||||
#define RADEON_CP_RB_WPTR 0x0714
|
||||
@ -885,6 +894,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,
|
||||
#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00
|
||||
#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14
|
||||
|
||||
#define RADEON_SE_TCL_STATE_FLUSH 0x2284
|
||||
|
||||
#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001
|
||||
#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000
|
||||
#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012
|
||||
@ -906,6 +917,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,
|
||||
#define R200_PP_AFS_0 0x2f80
|
||||
#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */
|
||||
|
||||
#define R200_VAP_PVS_CNTL_1 0x22D0
|
||||
|
||||
/* MPEG settings from VHA code */
|
||||
#define RADEON_VHA_SETTO16_1 0x2694
|
||||
#define RADEON_VHA_SETTO16_2 0x2680
|
||||
@ -1011,13 +1024,13 @@ do { \
|
||||
} while (0)
|
||||
|
||||
#define RADEON_FLUSH_CACHE() do { \
|
||||
OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
|
||||
OUT_RING( RADEON_RB2D_DC_FLUSH ); \
|
||||
OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
|
||||
OUT_RING( RADEON_RB3D_DC_FLUSH ); \
|
||||
} while (0)
|
||||
|
||||
#define RADEON_PURGE_CACHE() do { \
|
||||
OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
|
||||
OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \
|
||||
OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
|
||||
OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \
|
||||
} while (0)
|
||||
|
||||
#define RADEON_FLUSH_ZCACHE() do { \
|
||||
@ -1085,7 +1098,7 @@ do { \
|
||||
n, __FUNCTION__ ); \
|
||||
} \
|
||||
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
|
||||
COMMIT_RING(); \
|
||||
COMMIT_RING(); \
|
||||
radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
|
||||
} \
|
||||
_nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
|
||||
|
@ -45,7 +45,11 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
|
||||
drm_file_t * filp_priv,
|
||||
u32 * offset)
|
||||
{
|
||||
u32 off = *offset;
|
||||
u64 off = *offset;
|
||||
u32 fb_start = dev_priv->fb_location;
|
||||
u32 fb_end = fb_start + dev_priv->fb_size - 1;
|
||||
u32 gart_start = dev_priv->gart_vm_start;
|
||||
u32 gart_end = gart_start + dev_priv->gart_size - 1;
|
||||
struct drm_radeon_driver_file_fields *radeon_priv;
|
||||
|
||||
/* Hrm ... the story of the offset ... So this function converts
|
||||
@ -65,10 +69,8 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
|
||||
/* First, the best case, the offset already lands in either the
|
||||
* framebuffer or the GART mapped space
|
||||
*/
|
||||
if ((off >= dev_priv->fb_location &&
|
||||
off < (dev_priv->fb_location + dev_priv->fb_size)) ||
|
||||
(off >= dev_priv->gart_vm_start &&
|
||||
off < (dev_priv->gart_vm_start + dev_priv->gart_size)))
|
||||
if ((off >= fb_start && off <= fb_end) ||
|
||||
(off >= gart_start && off <= gart_end))
|
||||
return 0;
|
||||
|
||||
/* Ok, that didn't happen... now check if we have a zero based
|
||||
@ -81,16 +83,13 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
|
||||
}
|
||||
|
||||
/* Finally, assume we aimed at a GART offset if beyond the fb */
|
||||
if (off > (dev_priv->fb_location + dev_priv->fb_size))
|
||||
off = off - (dev_priv->fb_location + dev_priv->fb_size) +
|
||||
dev_priv->gart_vm_start;
|
||||
if (off > fb_end)
|
||||
off = off - fb_end - 1 + gart_start;
|
||||
|
||||
/* Now recheck and fail if out of bounds */
|
||||
if ((off >= dev_priv->fb_location &&
|
||||
off < (dev_priv->fb_location + dev_priv->fb_size)) ||
|
||||
(off >= dev_priv->gart_vm_start &&
|
||||
off < (dev_priv->gart_vm_start + dev_priv->gart_size))) {
|
||||
DRM_DEBUG("offset fixed up to 0x%x\n", off);
|
||||
if ((off >= fb_start && off <= fb_end) ||
|
||||
(off >= gart_start && off <= gart_end)) {
|
||||
DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
|
||||
*offset = off;
|
||||
return 0;
|
||||
}
|
||||
@ -252,6 +251,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
|
||||
case R200_EMIT_PP_TXCTLALL_3:
|
||||
case R200_EMIT_PP_TXCTLALL_4:
|
||||
case R200_EMIT_PP_TXCTLALL_5:
|
||||
case R200_EMIT_VAP_PVS_CNTL:
|
||||
/* These packets don't contain memory offsets */
|
||||
break;
|
||||
|
||||
@ -629,6 +629,7 @@ static struct {
|
||||
{R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
|
||||
{R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
|
||||
{R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
|
||||
{R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},
|
||||
};
|
||||
|
||||
/* ================================================================
|
||||
@ -2633,7 +2634,8 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
|
||||
int stride = header.vectors.stride;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_RING(3 + sz);
|
||||
BEGIN_RING(5 + sz);
|
||||
OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
|
||||
OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
|
||||
OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
|
||||
OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
|
||||
@ -2645,6 +2647,32 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv,
|
||||
drm_radeon_cmd_header_t header,
|
||||
drm_radeon_kcmd_buffer_t *cmdbuf)
|
||||
{
|
||||
int sz = header.veclinear.count * 4;
|
||||
int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8);
|
||||
RING_LOCALS;
|
||||
|
||||
if (!sz)
|
||||
return 0;
|
||||
if (sz * 4 > cmdbuf->bufsz)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
BEGIN_RING(5 + sz);
|
||||
OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
|
||||
OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
|
||||
OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
|
||||
OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
|
||||
OUT_RING_TABLE(cmdbuf->buf, sz);
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += sz * sizeof(int);
|
||||
cmdbuf->bufsz -= sz * sizeof(int);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_emit_packet3(drm_device_t * dev,
|
||||
drm_file_t * filp_priv,
|
||||
drm_radeon_kcmd_buffer_t *cmdbuf)
|
||||
@ -2908,6 +2936,14 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case RADEON_CMD_VECLINEAR:
|
||||
DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
|
||||
if (radeon_emit_veclinear(dev_priv, header, &cmdbuf)) {
|
||||
DRM_ERROR("radeon_emit_veclinear failed\n");
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM_ERROR("bad cmd_type %d at %p\n",
|
||||
header.header.cmd_type,
|
||||
@ -2991,6 +3027,11 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
|
||||
case RADEON_PARAM_GART_TEX_HANDLE:
|
||||
value = dev_priv->gart_textures_offset;
|
||||
break;
|
||||
case RADEON_PARAM_SCRATCH_OFFSET:
|
||||
if (!dev_priv->writeback_works)
|
||||
return DRM_ERR(EINVAL);
|
||||
value = RADEON_SCRATCH_REG_OFFSET;
|
||||
break;
|
||||
|
||||
case RADEON_PARAM_CARD_TYPE:
|
||||
if (dev_priv->flags & CHIP_IS_PCIE)
|
||||
@ -3001,6 +3042,7 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
|
||||
value = RADEON_CARD_PCI;
|
||||
break;
|
||||
default:
|
||||
DRM_DEBUG( "Invalid parameter %d\n", param.param );
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user