Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
76f92de7
Commit
76f92de7
authored
Sep 23, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge with DRI CVS tree
parent
60abdcb3
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
952 additions
and
354 deletions
+952
-354
drivers/char/drm/Makefile
drivers/char/drm/Makefile
+1
-1
drivers/char/drm/drmP.h
drivers/char/drm/drmP.h
+3
-3
drivers/char/drm/drm_bufs.h
drivers/char/drm/drm_bufs.h
+1
-0
drivers/char/drm/drm_drv.h
drivers/char/drm/drm_drv.h
+2
-2
drivers/char/drm/drm_lock.h
drivers/char/drm/drm_lock.h
+1
-1
drivers/char/drm/drm_os_linux.h
drivers/char/drm/drm_os_linux.h
+3
-0
drivers/char/drm/i830.h
drivers/char/drm/i830.h
+6
-46
drivers/char/drm/i830_dma.c
drivers/char/drm/i830_dma.c
+137
-272
drivers/char/drm/i830_drv.c
drivers/char/drm/i830_drv.c
+1
-0
drivers/char/drm/i830_drv.h
drivers/char/drm/i830_drv.h
+12
-9
drivers/char/drm/radeon.h
drivers/char/drm/radeon.h
+76
-6
drivers/char/drm/radeon_cp.c
drivers/char/drm/radeon_cp.c
+3
-0
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_drm.h
+55
-4
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_drv.h
+43
-0
drivers/char/drm/radeon_irq.c
drivers/char/drm/radeon_irq.c
+214
-0
drivers/char/drm/radeon_mem.c
drivers/char/drm/radeon_mem.c
+334
-0
drivers/char/drm/radeon_state.c
drivers/char/drm/radeon_state.c
+60
-10
No files found.
drivers/char/drm/Makefile
View file @
76f92de7
...
@@ -8,7 +8,7 @@ r128-objs := r128_drv.o r128_cce.o r128_state.o
...
@@ -8,7 +8,7 @@ r128-objs := r128_drv.o r128_cce.o r128_state.o
mga-objs
:=
mga_drv.o mga_dma.o mga_state.o mga_warp.o
mga-objs
:=
mga_drv.o mga_dma.o mga_state.o mga_warp.o
i810-objs
:=
i810_drv.o i810_dma.o
i810-objs
:=
i810_drv.o i810_dma.o
i830-objs
:=
i830_drv.o i830_dma.o
i830-objs
:=
i830_drv.o i830_dma.o
radeon-objs
:=
radeon_drv.o radeon_cp.o radeon_state.o
radeon-objs
:=
radeon_drv.o radeon_cp.o radeon_state.o
radeon_mem.o radeon_irq.o
ffb-objs
:=
ffb_drv.o ffb_context.o
ffb-objs
:=
ffb_drv.o ffb_context.o
obj-$(CONFIG_DRM_GAMMA)
+=
gamma.o
obj-$(CONFIG_DRM_GAMMA)
+=
gamma.o
...
...
drivers/char/drm/drmP.h
View file @
76f92de7
...
@@ -165,7 +165,7 @@
...
@@ -165,7 +165,7 @@
#define pte_unmap(pte)
#define pte_unmap(pte)
#endif
#endif
#if LINUX_VERSION_CODE <
0x020413
/* KERNEL_VERSION(2,4,19) */
#if LINUX_VERSION_CODE <
KERNEL_VERSION(2,4,19)
static
inline
struct
page
*
vmalloc_to_page
(
void
*
vmalloc_addr
)
static
inline
struct
page
*
vmalloc_to_page
(
void
*
vmalloc_addr
)
{
{
unsigned
long
addr
=
(
unsigned
long
)
vmalloc_addr
;
unsigned
long
addr
=
(
unsigned
long
)
vmalloc_addr
;
...
@@ -190,7 +190,7 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr)
...
@@ -190,7 +190,7 @@ static inline struct page * vmalloc_to_page(void * vmalloc_addr)
}
}
#endif
#endif
#if LINUX_VERSION_CODE <
0x020500
#if LINUX_VERSION_CODE <
KERNEL_VERSION(2,5,0)
#define DRM_RPR_ARG(vma)
#define DRM_RPR_ARG(vma)
#else
#else
#define DRM_RPR_ARG(vma) vma,
#define DRM_RPR_ARG(vma) vma,
...
@@ -597,7 +597,7 @@ typedef struct drm_device {
...
@@ -597,7 +597,7 @@ typedef struct drm_device {
#endif
#endif
struct
pci_dev
*
pdev
;
struct
pci_dev
*
pdev
;
#ifdef __alpha__
#ifdef __alpha__
#if LINUX_VERSION_CODE <
0x020403
#if LINUX_VERSION_CODE <
KERNEL_VERSION(2,4,3)
struct
pci_controler
*
hose
;
struct
pci_controler
*
hose
;
#else
#else
struct
pci_controller
*
hose
;
struct
pci_controller
*
hose
;
...
...
drivers/char/drm/drm_bufs.h
View file @
76f92de7
...
@@ -137,6 +137,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
...
@@ -137,6 +137,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
}
}
map
->
offset
=
(
unsigned
long
)
map
->
handle
;
map
->
offset
=
(
unsigned
long
)
map
->
handle
;
if
(
map
->
flags
&
_DRM_CONTAINS_LOCK
)
{
if
(
map
->
flags
&
_DRM_CONTAINS_LOCK
)
{
dev
->
sigdata
.
lock
=
dev
->
lock
.
hw_lock
=
map
->
handle
;
/* Pointer to lock */
dev
->
lock
.
hw_lock
=
map
->
handle
;
/* Pointer to lock */
}
}
break
;
break
;
...
...
drivers/char/drm/drm_drv.h
View file @
76f92de7
...
@@ -306,7 +306,7 @@ static int DRM(setup)( drm_device_t *dev )
...
@@ -306,7 +306,7 @@ static int DRM(setup)( drm_device_t *dev )
dev
->
map_count
=
0
;
dev
->
map_count
=
0
;
dev
->
vmalist
=
NULL
;
dev
->
vmalist
=
NULL
;
dev
->
lock
.
hw_lock
=
NULL
;
dev
->
sigdata
.
lock
=
dev
->
lock
.
hw_lock
=
NULL
;
init_waitqueue_head
(
&
dev
->
lock
.
lock_queue
);
init_waitqueue_head
(
&
dev
->
lock
.
lock_queue
);
dev
->
queue_count
=
0
;
dev
->
queue_count
=
0
;
dev
->
queue_reserved
=
0
;
dev
->
queue_reserved
=
0
;
...
@@ -491,7 +491,7 @@ static int DRM(takedown)( drm_device_t *dev )
...
@@ -491,7 +491,7 @@ static int DRM(takedown)( drm_device_t *dev )
DRM
(
dma_takedown
)(
dev
);
DRM
(
dma_takedown
)(
dev
);
#endif
#endif
if
(
dev
->
lock
.
hw_lock
)
{
if
(
dev
->
lock
.
hw_lock
)
{
dev
->
lock
.
hw_lock
=
NULL
;
/* SHM removed */
dev
->
sigdata
.
lock
=
dev
->
lock
.
hw_lock
=
NULL
;
/* SHM removed */
dev
->
lock
.
pid
=
0
;
dev
->
lock
.
pid
=
0
;
wake_up_interruptible
(
&
dev
->
lock
.
lock_queue
);
wake_up_interruptible
(
&
dev
->
lock
.
lock_queue
);
}
}
...
...
drivers/char/drm/drm_lock.h
View file @
76f92de7
...
@@ -237,7 +237,7 @@ int DRM(notifier)(void *priv)
...
@@ -237,7 +237,7 @@ int DRM(notifier)(void *priv)
/* Allow signal delivery if lock isn't held */
/* Allow signal delivery if lock isn't held */
if
(
!
_DRM_LOCK_IS_HELD
(
s
->
lock
->
lock
)
if
(
!
s
->
lock
||
!
_DRM_LOCK_IS_HELD
(
s
->
lock
->
lock
)
||
_DRM_LOCKING_CONTEXT
(
s
->
lock
->
lock
)
!=
s
->
context
)
return
1
;
||
_DRM_LOCKING_CONTEXT
(
s
->
lock
->
lock
)
!=
s
->
context
)
return
1
;
/* Otherwise, set flag to force call to
/* Otherwise, set flag to force call to
...
...
drivers/char/drm/drm_os_linux.h
View file @
76f92de7
...
@@ -16,6 +16,9 @@
...
@@ -16,6 +16,9 @@
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
drm_device_t *dev = priv->dev
drm_device_t *dev = priv->dev
#define DRM_IRQ_ARGS int irq, void *arg, struct pt_regs *regs
#define DRM_TASKQUEUE_ARGS void *arg
/* For data going from/to the kernel through the ioctl argument */
/* For data going from/to the kernel through the ioctl argument */
#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \
#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \
if ( copy_from_user(&arg1, arg2, arg3) ) \
if ( copy_from_user(&arg1, arg2, arg3) ) \
...
...
drivers/char/drm/i830.h
View file @
76f92de7
...
@@ -45,11 +45,11 @@
...
@@ -45,11 +45,11 @@
#define DRIVER_NAME "i830"
#define DRIVER_NAME "i830"
#define DRIVER_DESC "Intel 830M"
#define DRIVER_DESC "Intel 830M"
#define DRIVER_DATE "200
11004
"
#define DRIVER_DATE "200
20828
"
#define DRIVER_MAJOR 1
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 2
#define DRIVER_MINOR 2
#define DRIVER_PATCHLEVEL
0
#define DRIVER_PATCHLEVEL
1
#define DRIVER_IOCTLS \
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \
...
@@ -87,50 +87,10 @@
...
@@ -87,50 +87,10 @@
i830_dma_quiescent( dev ); \
i830_dma_quiescent( dev ); \
} while (0)
} while (0)
#define __HAVE_DMA_IRQ 1
/* Don't need an irq any more. The template code will make sure that
#define __HAVE_DMA_IRQ_BH 1
* a noop stub is generated for compatibility.
#define __HAVE_SHARED_IRQ 1
*/
#define DRIVER_PREINSTALL() do { \
#define __HAVE_DMA_IRQ 0
drm_i830_private_t *dev_priv = \
(drm_i830_private_t *)dev->dev_private; \
u16 tmp; \
tmp = I830_READ16( I830REG_HWSTAM ); \
tmp = tmp & 0x6000; \
I830_WRITE16( I830REG_HWSTAM, tmp ); \
\
tmp = I830_READ16( I830REG_INT_MASK_R ); \
tmp = tmp & 0x6000;
/* Unmask interrupts */
\
I830_WRITE16( I830REG_INT_MASK_R, tmp ); \
tmp = I830_READ16( I830REG_INT_ENABLE_R ); \
tmp = tmp & 0x6000;
/* Disable all interrupts */
\
I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \
} while (0)
#define DRIVER_POSTINSTALL() do { \
drm_i830_private_t *dev_priv = \
(drm_i830_private_t *)dev->dev_private; \
u16 tmp; \
tmp = I830_READ16( I830REG_INT_ENABLE_R ); \
tmp = tmp & 0x6000; \
tmp = tmp | 0x0003;
/* Enable bp & user interrupts */
\
I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \
} while (0)
#define DRIVER_UNINSTALL() do { \
drm_i830_private_t *dev_priv = \
(drm_i830_private_t *)dev->dev_private; \
u16 tmp; \
if ( dev_priv ) { \
tmp = I830_READ16( I830REG_INT_IDENTITY_R ); \
tmp = tmp & ~(0x6000);
/* Clear all interrupts */
\
if ( tmp != 0 ) \
I830_WRITE16( I830REG_INT_IDENTITY_R, tmp ); \
\
tmp = I830_READ16( I830REG_INT_ENABLE_R ); \
tmp = tmp & 0x6000;
/* Disable all interrupts */
\
I830_WRITE16( I830REG_INT_ENABLE_R, tmp ); \
} \
} while (0)
/* Buffer customization:
/* Buffer customization:
*/
*/
...
...
drivers/char/drm/i830_dma.c
View file @
76f92de7
This diff is collapsed.
Click to expand it.
drivers/char/drm/i830_drv.c
View file @
76f92de7
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
* Jeff Hartmann <jhartmann@valinux.com>
* Jeff Hartmann <jhartmann@valinux.com>
* Gareth Hughes <gareth@valinux.com>
* Gareth Hughes <gareth@valinux.com>
* Abraham vd Merwe <abraham@2d3d.co.za>
* Abraham vd Merwe <abraham@2d3d.co.za>
* Keith Whitwell <keith@tungstengraphics.com>
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
...
drivers/char/drm/i830_drv.h
View file @
76f92de7
...
@@ -64,14 +64,13 @@ typedef struct drm_i830_private {
...
@@ -64,14 +64,13 @@ typedef struct drm_i830_private {
unsigned
long
hw_status_page
;
unsigned
long
hw_status_page
;
unsigned
long
counter
;
unsigned
long
counter
;
atomic_t
flush_done
;
wait_queue_head_t
flush_queue
;
/* Processes waiting until flush */
drm_buf_t
*
mmap_buffer
;
drm_buf_t
*
mmap_buffer
;
u32
front_di1
,
back_di1
,
zi1
;
u32
front_di1
,
back_di1
,
zi1
;
int
back_offset
;
int
back_offset
;
int
depth_offset
;
int
depth_offset
;
int
front_offset
;
int
w
,
h
;
int
w
,
h
;
int
pitch
;
int
pitch
;
int
back_pitch
;
int
back_pitch
;
...
@@ -107,14 +106,13 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp,
...
@@ -107,14 +106,13 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp,
extern
int
i830_clear_bufs
(
struct
inode
*
inode
,
struct
file
*
filp
,
extern
int
i830_clear_bufs
(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
);
unsigned
int
cmd
,
unsigned
long
arg
);
#define I830_VERBOSE 0
#define I830_BASE(reg) ((unsigned long) \
#define I830_BASE(reg) ((unsigned long) \
dev_priv->mmio_map->handle)
dev_priv->mmio_map->handle)
#define I830_ADDR(reg) (I830_BASE(reg) + reg)
#define I830_ADDR(reg) (I830_BASE(reg) + reg)
#define I830_DEREF(reg) *(__volatile__ int *)I830_ADDR(reg)
#define I830_DEREF(reg) *(__volatile__
unsigned
int *)I830_ADDR(reg)
#define I830_READ(reg)
I830_DEREF(reg
)
#define I830_READ(reg)
readl((volatile u32 *)I830_ADDR(reg)
)
#define I830_WRITE(reg,val)
do { I830_DEREF(reg) = val; } while (0
)
#define I830_WRITE(reg,val)
writel(val, (volatile u32 *)I830_ADDR(reg)
)
#define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg)
#define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg)
#define I830_READ16(reg) I830_DEREF16(reg)
#define I830_READ16(reg) I830_DEREF16(reg)
#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
...
@@ -143,15 +141,15 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
...
@@ -143,15 +141,15 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define LP_RING 0x2030
#define LP_RING 0x2030
#define HP_RING 0x2040
#define HP_RING 0x2040
#define RING_TAIL 0x00
#define RING_TAIL 0x00
#define TAIL_ADDR 0x00
0
FFFF8
#define TAIL_ADDR 0x00
1
FFFF8
#define RING_HEAD 0x04
#define RING_HEAD 0x04
#define HEAD_WRAP_COUNT 0xFFE00000
#define HEAD_WRAP_COUNT 0xFFE00000
#define HEAD_WRAP_ONE 0x00200000
#define HEAD_WRAP_ONE 0x00200000
#define HEAD_ADDR 0x001FFFFC
#define HEAD_ADDR 0x001FFFFC
#define RING_START 0x08
#define RING_START 0x08
#define START_ADDR 0x0
0FFFFF8
#define START_ADDR 0x0
xFFFFF000
#define RING_LEN 0x0C
#define RING_LEN 0x0C
#define RING_NR_PAGES 0x00
0
FF000
#define RING_NR_PAGES 0x00
1
FF000
#define RING_REPORT_MASK 0x00000006
#define RING_REPORT_MASK 0x00000006
#define RING_REPORT_64K 0x00000002
#define RING_REPORT_64K 0x00000002
#define RING_REPORT_128K 0x00000004
#define RING_REPORT_128K 0x00000004
...
@@ -182,6 +180,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
...
@@ -182,6 +180,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
#define CMD_3D (0x3<<29)
#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16))
#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16))
#define BR00_BITBLT_CLIENT 0x40000000
#define BR00_BITBLT_CLIENT 0x40000000
#define BR00_OP_COLOR_BLT 0x10000000
#define BR00_OP_COLOR_BLT 0x10000000
...
@@ -206,6 +207,8 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
...
@@ -206,6 +207,8 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
#define MI_BATCH_BUFFER ((0x30<<23)|1)
#define MI_BATCH_BUFFER ((0x30<<23)|1)
#define MI_BATCH_BUFFER_START (0x31<<23)
#define MI_BATCH_BUFFER_END (0xA<<23)
#define MI_BATCH_NON_SECURE (1)
#define MI_BATCH_NON_SECURE (1)
...
...
drivers/char/drm/radeon.h
View file @
76f92de7
...
@@ -48,10 +48,10 @@
...
@@ -48,10 +48,10 @@
#define DRIVER_NAME "radeon"
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
#define DRIVER_DESC "ATI Radeon"
#define DRIVER_DATE "20020
611
"
#define DRIVER_DATE "20020
828
"
#define DRIVER_MAJOR 1
#define DRIVER_MAJOR 1
#define DRIVER_MINOR
5
#define DRIVER_MINOR
6
#define DRIVER_PATCHLEVEL 0
#define DRIVER_PATCHLEVEL 0
/* Interface history:
/* Interface history:
...
@@ -68,6 +68,11 @@
...
@@ -68,6 +68,11 @@
* 1.5 - Add r200 packets to cmdbuf ioctl
* 1.5 - Add r200 packets to cmdbuf ioctl
* - Add r200 function to init ioctl
* - Add r200 function to init ioctl
* - Add 'scalar2' instruction to cmdbuf
* - Add 'scalar2' instruction to cmdbuf
* 1.6 - Add static agp memory manager
* Add irq handler (won't be turned on unless X server knows to)
* Add irq ioctls and irq_active getparam.
* Add wait command for cmdbuf ioctl
* Add agp offset query for getparam
*/
*/
#define DRIVER_IOCTLS \
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
...
@@ -88,9 +93,18 @@
...
@@ -88,9 +93,18 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)] = { radeon_mem_free, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)] = { radeon_mem_init_heap, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 },
/* Driver customization:
/* When a client dies:
* - Check for and clean up flipped page state
* - Free any alloced agp memory.
*
* DRM infrastructure takes care of reclaiming dma buffers.
*/
*/
#define DRIVER_PRERELEASE() do { \
#define DRIVER_PRERELEASE() do { \
if ( dev->dev_private ) { \
if ( dev->dev_private ) { \
...
@@ -98,22 +112,78 @@
...
@@ -98,22 +112,78 @@
if ( dev_priv->page_flipping ) { \
if ( dev_priv->page_flipping ) { \
radeon_do_cleanup_pageflip( dev ); \
radeon_do_cleanup_pageflip( dev ); \
} \
} \
radeon_mem_release( dev_priv->agp_heap ); \
} \
} \
} while (0)
} while (0)
/* On unloading the module:
* - Free memory heap structure
* - Remove mappings made at startup and free dev_private.
*/
#define DRIVER_PRETAKEDOWN() do { \
#define DRIVER_PRETAKEDOWN() do { \
if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \
if ( dev->dev_private ) { \
drm_radeon_private_t *dev_priv = dev->dev_private; \
radeon_mem_takedown( &(dev_priv->agp_heap) ); \
radeon_do_cleanup_cp( dev ); \
} \
} while (0)
} while (0)
/* DMA customization:
/* DMA customization:
*/
*/
#define __HAVE_DMA 1
#define __HAVE_DMA 1
#define __HAVE_DMA_IRQ 1
#define __HAVE_DMA_IRQ_BH 1
#define __HAVE_SHARED_IRQ 1
#define DRIVER_PREINSTALL() do { \
drm_radeon_private_t *dev_priv = \
(drm_radeon_private_t *)dev->dev_private; \
u32 tmp; \
\
/* Clear bit if it's already high: */
\
tmp = RADEON_READ( RADEON_GEN_INT_STATUS ); \
tmp = tmp & RADEON_SW_INT_TEST_ACK; \
RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp ); \
\
/* Disable *all* interrupts */
\
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); \
} while (0)
#ifdef __linux__
#define IWH(x) init_waitqueue_head(x)
#else
#define IWH(x)
#endif
#define DRIVER_POSTINSTALL() do { \
drm_radeon_private_t *dev_priv = \
(drm_radeon_private_t *)dev->dev_private; \
\
atomic_set(&dev_priv->irq_received, 0); \
atomic_set(&dev_priv->irq_emitted, 0); \
IWH(&dev_priv->irq_queue); \
\
/* Turn on SW_INT only */
\
RADEON_WRITE( RADEON_GEN_INT_CNTL, \
RADEON_SW_INT_ENABLE ); \
} while (0)
#define DRIVER_UNINSTALL() do { \
drm_radeon_private_t *dev_priv = \
(drm_radeon_private_t *)dev->dev_private; \
if ( dev_priv ) { \
/* Disable *all* interrupts */
\
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); \
} \
} while (0)
/* Buffer customization:
/* Buffer customization:
*/
*/
#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t
#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t
#define DRIVER_AGP_BUFFERS_MAP( dev )
\
#define DRIVER_AGP_BUFFERS_MAP( dev ) \
((drm_radeon_private_t *)((dev)->dev_private))->buffers
((drm_radeon_private_t *)((dev)->dev_private))->buffers
#endif
#endif
drivers/char/drm/radeon_cp.c
View file @
76f92de7
...
@@ -1412,6 +1412,9 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
...
@@ -1412,6 +1412,9 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
LOCK_TEST_WITH_RETURN
(
dev
);
LOCK_TEST_WITH_RETURN
(
dev
);
/* if (dev->irq) */
/* radeon_emit_and_wait_irq( dev ); */
return
radeon_do_cp_idle
(
dev_priv
);
return
radeon_do_cp_idle
(
dev_priv
);
}
}
...
...
drivers/char/drm/radeon_drm.h
View file @
76f92de7
...
@@ -142,6 +142,9 @@
...
@@ -142,6 +142,9 @@
#define RADEON_CMD_PACKET3 5
/* emit hw packet */
#define RADEON_CMD_PACKET3 5
/* emit hw packet */
#define RADEON_CMD_PACKET3_CLIP 6
/* emit hw packet wrapped in cliprects */
#define RADEON_CMD_PACKET3_CLIP 6
/* emit hw packet wrapped in cliprects */
#define RADEON_CMD_SCALARS2 7
/* r200 stopgap */
#define RADEON_CMD_SCALARS2 7
/* r200 stopgap */
#define RADEON_CMD_WAIT 8
/* emit hw wait commands -- note:
* doesn't make the cpu wait, just
* the graphics hardware */
typedef
union
{
typedef
union
{
...
@@ -161,8 +164,14 @@ typedef union {
...
@@ -161,8 +164,14 @@ typedef union {
struct
{
struct
{
unsigned
char
cmd_type
,
buf_idx
,
pad0
,
pad1
;
unsigned
char
cmd_type
,
buf_idx
,
pad0
,
pad1
;
}
dma
;
}
dma
;
struct
{
unsigned
char
cmd_type
,
flags
,
pad0
,
pad1
;
}
wait
;
}
drm_radeon_cmd_header_t
;
}
drm_radeon_cmd_header_t
;
#define RADEON_WAIT_2D 0x1
#define RADEON_WAIT_3D 0x2
#define RADEON_FRONT 0x1
#define RADEON_FRONT 0x1
#define RADEON_BACK 0x2
#define RADEON_BACK 0x2
...
@@ -364,6 +373,11 @@ typedef struct {
...
@@ -364,6 +373,11 @@ typedef struct {
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR( 0x53, drm_radeon_mem_alloc_t)
#define DRM_IOCTL_RADEON_FREE DRM_IOW( 0x54, drm_radeon_mem_free_t)
#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( 0x55, drm_radeon_mem_init_heap_t)
#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR( 0x56, drm_radeon_irq_emit_t)
#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( 0x57, drm_radeon_irq_wait_t)
typedef
struct
drm_radeon_init
{
typedef
struct
drm_radeon_init
{
enum
{
enum
{
...
@@ -499,14 +513,51 @@ typedef struct drm_radeon_indirect {
...
@@ -499,14 +513,51 @@ typedef struct drm_radeon_indirect {
/* 1.3: An ioctl to get parameters that aren't available to the 3d
/* 1.3: An ioctl to get parameters that aren't available to the 3d
* client any other way.
* client any other way.
*/
*/
#define RADEON_PARAM_AGP_BUFFER_OFFSET 0x1
#define RADEON_PARAM_AGP_BUFFER_OFFSET 1
/* card offset of 1st agp buffer */
#define RADEON_PARAM_LAST_FRAME 0x2
#define RADEON_PARAM_LAST_FRAME 2
#define RADEON_PARAM_LAST_DISPATCH 0x3
#define RADEON_PARAM_LAST_DISPATCH 3
#define RADEON_PARAM_LAST_CLEAR 0x4
#define RADEON_PARAM_LAST_CLEAR 4
#define RADEON_PARAM_IRQ_ACTIVE 5
#define RADEON_PARAM_AGP_BASE 6
/* card offset of agp base */
typedef
struct
drm_radeon_getparam
{
typedef
struct
drm_radeon_getparam
{
int
param
;
int
param
;
int
*
value
;
int
*
value
;
}
drm_radeon_getparam_t
;
}
drm_radeon_getparam_t
;
/* 1.6: Set up a memory manager for regions of shared memory:
*/
#define RADEON_MEM_REGION_AGP 1
#define RADEON_MEM_REGION_FB 2
typedef
struct
drm_radeon_mem_alloc
{
int
region
;
int
alignment
;
int
size
;
int
*
region_offset
;
/* offset from start of fb or agp */
}
drm_radeon_mem_alloc_t
;
typedef
struct
drm_radeon_mem_free
{
int
region
;
int
region_offset
;
}
drm_radeon_mem_free_t
;
typedef
struct
drm_radeon_mem_init_heap
{
int
region
;
int
size
;
int
start
;
}
drm_radeon_mem_init_heap_t
;
/* 1.6: Userspace can request & wait on irq's:
*/
typedef
struct
drm_radeon_irq_emit
{
int
*
irq_seq
;
}
drm_radeon_irq_emit_t
;
typedef
struct
drm_radeon_irq_wait
{
int
irq_seq
;
}
drm_radeon_irq_wait_t
;
#endif
#endif
drivers/char/drm/radeon_drv.h
View file @
76f92de7
...
@@ -61,6 +61,15 @@ typedef struct drm_radeon_depth_clear_t {
...
@@ -61,6 +61,15 @@ typedef struct drm_radeon_depth_clear_t {
u32
se_cntl
;
u32
se_cntl
;
}
drm_radeon_depth_clear_t
;
}
drm_radeon_depth_clear_t
;
struct
mem_block
{
struct
mem_block
*
next
;
struct
mem_block
*
prev
;
int
start
;
int
size
;
int
pid
;
/* 0: free, -1: heap, other: real pids */
};
typedef
struct
drm_radeon_private
{
typedef
struct
drm_radeon_private
{
drm_radeon_ring_buffer_t
ring
;
drm_radeon_ring_buffer_t
ring
;
drm_radeon_sarea_t
*
sarea_priv
;
drm_radeon_sarea_t
*
sarea_priv
;
...
@@ -126,6 +135,14 @@ typedef struct drm_radeon_private {
...
@@ -126,6 +135,14 @@ typedef struct drm_radeon_private {
drm_map_t
*
ring_rptr
;
drm_map_t
*
ring_rptr
;
drm_map_t
*
buffers
;
drm_map_t
*
buffers
;
drm_map_t
*
agp_textures
;
drm_map_t
*
agp_textures
;
struct
mem_block
*
agp_heap
;
struct
mem_block
*
fb_heap
;
wait_queue_head_t
irq_queue
;
atomic_t
irq_received
;
atomic_t
irq_emitted
;
}
drm_radeon_private_t
;
}
drm_radeon_private_t
;
typedef
struct
drm_radeon_buf_priv
{
typedef
struct
drm_radeon_buf_priv
{
...
@@ -164,6 +181,20 @@ extern int radeon_cp_cmdbuf( DRM_IOCTL_ARGS );
...
@@ -164,6 +181,20 @@ extern int radeon_cp_cmdbuf( DRM_IOCTL_ARGS );
extern
int
radeon_cp_getparam
(
DRM_IOCTL_ARGS
);
extern
int
radeon_cp_getparam
(
DRM_IOCTL_ARGS
);
extern
int
radeon_cp_flip
(
DRM_IOCTL_ARGS
);
extern
int
radeon_cp_flip
(
DRM_IOCTL_ARGS
);
extern
int
radeon_mem_alloc
(
DRM_IOCTL_ARGS
);
extern
int
radeon_mem_free
(
DRM_IOCTL_ARGS
);
extern
int
radeon_mem_init_heap
(
DRM_IOCTL_ARGS
);
extern
void
radeon_mem_takedown
(
struct
mem_block
**
heap
);
extern
void
radeon_mem_release
(
struct
mem_block
*
heap
);
extern
int
radeon_irq_emit
(
DRM_IOCTL_ARGS
);
extern
int
radeon_irq_wait
(
DRM_IOCTL_ARGS
);
extern
int
radeon_emit_and_wait_irq
(
drm_device_t
*
dev
);
extern
int
radeon_wait_irq
(
drm_device_t
*
dev
,
int
irq_nr
);
extern
int
radeon_emit_irq
(
drm_device_t
*
dev
);
/* Flags for stats.boxes
/* Flags for stats.boxes
*/
*/
#define RADEON_BOX_DMA_IDLE 0x1
#define RADEON_BOX_DMA_IDLE 0x1
...
@@ -238,6 +269,16 @@ extern int radeon_cp_flip( DRM_IOCTL_ARGS );
...
@@ -238,6 +269,16 @@ extern int radeon_cp_flip( DRM_IOCTL_ARGS );
? DRM_READ32( &dev_priv->scratch[(x)] ) \
? DRM_READ32( &dev_priv->scratch[(x)] ) \
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
#define RADEON_GEN_INT_CNTL 0x0040
# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19)
# define RADEON_SW_INT_ENABLE (1 << 25)
#define RADEON_GEN_INT_STATUS 0x0044
# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19)
# define RADEON_SW_INT_TEST_ACK (1 << 25)
# define RADEON_SW_INT_FIRE (1 << 26)
#define RADEON_HOST_PATH_CNTL 0x0130
#define RADEON_HOST_PATH_CNTL 0x0130
# define RADEON_HDP_SOFT_RESET (1 << 26)
# define RADEON_HDP_SOFT_RESET (1 << 26)
# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28)
# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28)
...
@@ -526,6 +567,8 @@ extern int radeon_cp_flip( DRM_IOCTL_ARGS );
...
@@ -526,6 +567,8 @@ extern int radeon_cp_flip( DRM_IOCTL_ARGS );
#define RADEON_TXFORMAT_ARGB4444 5
#define RADEON_TXFORMAT_ARGB4444 5
#define RADEON_TXFORMAT_ARGB8888 6
#define RADEON_TXFORMAT_ARGB8888 6
#define RADEON_TXFORMAT_RGBA8888 7
#define RADEON_TXFORMAT_RGBA8888 7
#define RADEON_TXFORMAT_VYUY422 10
#define RADEON_TXFORMAT_YVYU422 11
#define R200_PP_TXCBLEND_0 0x2f00
#define R200_PP_TXCBLEND_0 0x2f00
#define R200_PP_TXCBLEND_1 0x2f10
#define R200_PP_TXCBLEND_1 0x2f10
...
...
drivers/char/drm/radeon_irq.c
0 → 100644
View file @
76f92de7
/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*-
*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
*
* The Weather Channel (TM) funded Tungsten Graphics to develop the
* initial release of the Radeon 8500 driver under the XFree86 license.
* This notice must be preserved.
*
* 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
* PRECISION INSIGHT 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "radeon.h"
#include "drmP.h"
#include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h"
/* Interrupts - Used for device synchronization and flushing in the
* following circumstances:
*
* - Exclusive FB access with hw idle:
* - Wait for GUI Idle (?) interrupt, then do normal flush.
*
* - Frame throttling, NV_fence:
* - Drop marker irq's into command stream ahead of time.
* - Wait on irq's with lock *not held*
* - Check each for termination condition
*
* - Internally in cp_getbuffer, etc:
* - as above, but wait with lock held???
*
* NOTE: These functions are misleadingly named -- the irq's aren't
* tied to dma at all, this is just a hangover from dri prehistory.
*/
void
DRM
(
dma_service
)(
DRM_IRQ_ARGS
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
arg
;
drm_radeon_private_t
*
dev_priv
=
(
drm_radeon_private_t
*
)
dev
->
dev_private
;
u32
temp
;
/* Need to wait for fifo to drain?
*/
temp
=
RADEON_READ
(
RADEON_GEN_INT_STATUS
);
temp
=
temp
&
RADEON_SW_INT_TEST_ACK
;
if
(
temp
==
0
)
return
;
RADEON_WRITE
(
RADEON_GEN_INT_STATUS
,
temp
);
atomic_inc
(
&
dev_priv
->
irq_received
);
#ifdef __linux__
queue_task
(
&
dev
->
tq
,
&
tq_immediate
);
mark_bh
(
IMMEDIATE_BH
);
#endif
/* __linux__ */
#ifdef __FreeBSD__
taskqueue_enqueue
(
taskqueue_swi
,
&
dev
->
task
);
#endif
/* __FreeBSD__ */
}
void
DRM
(
dma_immediate_bh
)(
DRM_TASKQUEUE_ARGS
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
arg
;
drm_radeon_private_t
*
dev_priv
=
(
drm_radeon_private_t
*
)
dev
->
dev_private
;
#ifdef __linux__
wake_up_interruptible
(
&
dev_priv
->
irq_queue
);
#endif
/* __linux__ */
#ifdef __FreeBSD__
wakeup
(
&
dev_priv
->
irq_queue
);
#endif
}
int
radeon_emit_irq
(
drm_device_t
*
dev
)
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
RING_LOCALS
;
atomic_inc
(
&
dev_priv
->
irq_emitted
);
BEGIN_RING
(
2
);
OUT_RING
(
CP_PACKET0
(
RADEON_GEN_INT_STATUS
,
0
)
);
OUT_RING
(
RADEON_SW_INT_FIRE
);
ADVANCE_RING
();
COMMIT_RING
();
return
atomic_read
(
&
dev_priv
->
irq_emitted
);
}
int
radeon_wait_irq
(
drm_device_t
*
dev
,
int
irq_nr
)
{
drm_radeon_private_t
*
dev_priv
=
(
drm_radeon_private_t
*
)
dev
->
dev_private
;
#ifdef __linux__
DECLARE_WAITQUEUE
(
entry
,
current
);
unsigned
long
end
=
jiffies
+
HZ
*
3
;
#endif
/* __linux__ */
int
ret
=
0
;
if
(
atomic_read
(
&
dev_priv
->
irq_received
)
>=
irq_nr
)
return
0
;
dev_priv
->
stats
.
boxes
|=
RADEON_BOX_WAIT_IDLE
;
#ifdef __linux__
add_wait_queue
(
&
dev_priv
->
irq_queue
,
&
entry
);
for
(;;)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
if
(
atomic_read
(
&
dev_priv
->
irq_received
)
>=
irq_nr
)
break
;
if
((
signed
)(
end
-
jiffies
)
<=
0
)
{
ret
=
-
EBUSY
;
/* Lockup? Missed irq? */
break
;
}
schedule_timeout
(
HZ
*
3
);
if
(
signal_pending
(
current
))
{
ret
=
-
EINTR
;
break
;
}
}
current
->
state
=
TASK_RUNNING
;
remove_wait_queue
(
&
dev_priv
->
irq_queue
,
&
entry
);
return
ret
;
#endif
/* __linux__ */
#ifdef __FreeBSD__
ret
=
tsleep
(
&
dev_priv
->
irq_queue
,
PZERO
|
PCATCH
,
\
"rdnirq"
,
3
*
hz
);
if
(
(
ret
==
EWOULDBLOCK
)
||
(
ret
==
EINTR
)
)
return
DRM_ERR
(
EBUSY
);
return
ret
;
#endif
/* __FreeBSD__ */
}
int
radeon_emit_and_wait_irq
(
drm_device_t
*
dev
)
{
return
radeon_wait_irq
(
dev
,
radeon_emit_irq
(
dev
)
);
}
/* Needs the lock as it touches the ring.
*/
int
radeon_irq_emit
(
DRM_IOCTL_ARGS
)
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_radeon_irq_emit_t
emit
;
int
result
;
LOCK_TEST_WITH_RETURN
(
dev
);
if
(
!
dev_priv
)
{
DRM_ERROR
(
"%s called with no initialization
\n
"
,
__FUNCTION__
);
return
DRM_ERR
(
EINVAL
);
}
DRM_COPY_FROM_USER_IOCTL
(
emit
,
(
drm_radeon_irq_emit_t
*
)
data
,
sizeof
(
emit
)
);
result
=
radeon_emit_irq
(
dev
);
if
(
DRM_COPY_TO_USER
(
emit
.
irq_seq
,
&
result
,
sizeof
(
int
)
)
)
{
DRM_ERROR
(
"copy_to_user
\n
"
);
return
DRM_ERR
(
EFAULT
);
}
return
0
;
}
/* Doesn't need the hardware lock.
*/
int
radeon_irq_wait
(
DRM_IOCTL_ARGS
)
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_radeon_irq_wait_t
irqwait
;
if
(
!
dev_priv
)
{
DRM_ERROR
(
"%s called with no initialization
\n
"
,
__FUNCTION__
);
return
DRM_ERR
(
EINVAL
);
}
DRM_COPY_FROM_USER_IOCTL
(
irqwait
,
(
drm_radeon_irq_wait_t
*
)
data
,
sizeof
(
irqwait
)
);
return
radeon_wait_irq
(
dev
,
irqwait
.
irq_seq
);
}
drivers/char/drm/radeon_mem.c
0 → 100644
View file @
76f92de7
/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*-
*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
*
* The Weather Channel (TM) funded Tungsten Graphics to develop the
* initial release of the Radeon 8500 driver under the XFree86 license.
* This notice must be preserved.
*
* 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
* PRECISION INSIGHT 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "radeon.h"
#include "drmP.h"
#include "drm.h"
#include "radeon_drm.h"
#include "radeon_drv.h"
/* Very simple allocator for agp memory, working on a static range
* already mapped into each client's address space.
*/
static
struct
mem_block
*
split_block
(
struct
mem_block
*
p
,
int
start
,
int
size
,
int
pid
)
{
/* Maybe cut off the start of an existing block */
if
(
start
>
p
->
start
)
{
struct
mem_block
*
newblock
=
DRM_MALLOC
(
sizeof
(
*
newblock
));
if
(
!
newblock
)
goto
out
;
newblock
->
start
=
start
;
newblock
->
size
=
p
->
size
-
(
start
-
p
->
start
);
newblock
->
pid
=
0
;
newblock
->
next
=
p
->
next
;
newblock
->
prev
=
p
;
p
->
next
->
prev
=
newblock
;
p
->
next
=
newblock
;
p
->
size
-=
newblock
->
size
;
p
=
newblock
;
}
/* Maybe cut off the end of an existing block */
if
(
size
<
p
->
size
)
{
struct
mem_block
*
newblock
=
DRM_MALLOC
(
sizeof
(
*
newblock
));
if
(
!
newblock
)
goto
out
;
newblock
->
start
=
start
+
size
;
newblock
->
size
=
p
->
size
-
size
;
newblock
->
pid
=
0
;
newblock
->
next
=
p
->
next
;
newblock
->
prev
=
p
;
p
->
next
->
prev
=
newblock
;
p
->
next
=
newblock
;
p
->
size
=
size
;
}
out:
/* Our block is in the middle */
p
->
pid
=
pid
;
return
p
;
}
static
struct
mem_block
*
alloc_block
(
struct
mem_block
*
heap
,
int
size
,
int
align2
,
int
pid
)
{
struct
mem_block
*
p
;
int
mask
=
(
1
<<
align2
)
-
1
;
for
(
p
=
heap
->
next
;
p
!=
heap
;
p
=
p
->
next
)
{
int
start
=
(
p
->
start
+
mask
)
&
~
mask
;
if
(
p
->
pid
==
0
&&
start
+
size
<=
p
->
start
+
p
->
size
)
return
split_block
(
p
,
start
,
size
,
pid
);
}
return
NULL
;
}
static
struct
mem_block
*
find_block
(
struct
mem_block
*
heap
,
int
start
)
{
struct
mem_block
*
p
;
for
(
p
=
heap
->
next
;
p
!=
heap
;
p
=
p
->
next
)
if
(
p
->
start
==
start
)
return
p
;
return
NULL
;
}
static
void
free_block
(
struct
mem_block
*
p
)
{
p
->
pid
=
0
;
/* Assumes a single contiguous range. Needs a special pid in
* 'heap' to stop it being subsumed.
*/
if
(
p
->
next
->
pid
==
0
)
{
struct
mem_block
*
q
=
p
->
next
;
p
->
size
+=
q
->
size
;
p
->
next
=
q
->
next
;
p
->
next
->
prev
=
p
;
DRM_FREE
(
p
);
}
if
(
p
->
prev
->
pid
==
0
)
{
struct
mem_block
*
q
=
p
->
prev
;
q
->
size
+=
p
->
size
;
q
->
next
=
p
->
next
;
q
->
next
->
prev
=
q
;
DRM_FREE
(
p
);
}
}
static
void
print_heap
(
struct
mem_block
*
heap
)
{
struct
mem_block
*
p
;
for
(
p
=
heap
->
next
;
p
!=
heap
;
p
=
p
->
next
)
DRM_DEBUG
(
"0x%x..0x%x (0x%x) -- owner %d
\n
"
,
p
->
start
,
p
->
start
+
p
->
size
,
p
->
size
,
p
->
pid
);
}
/* Initialize. How to check for an uninitialized heap?
*/
static
int
init_heap
(
struct
mem_block
**
heap
,
int
start
,
int
size
)
{
struct
mem_block
*
blocks
=
DRM_MALLOC
(
sizeof
(
*
blocks
));
if
(
!
blocks
)
return
-
ENOMEM
;
*
heap
=
DRM_MALLOC
(
sizeof
(
**
heap
));
if
(
!*
heap
)
{
DRM_FREE
(
blocks
);
return
-
ENOMEM
;
}
blocks
->
start
=
start
;
blocks
->
size
=
size
;
blocks
->
pid
=
0
;
blocks
->
next
=
blocks
->
prev
=
*
heap
;
memset
(
*
heap
,
0
,
sizeof
(
**
heap
)
);
(
*
heap
)
->
pid
=
-
1
;
(
*
heap
)
->
next
=
(
*
heap
)
->
prev
=
blocks
;
return
0
;
}
/* Free all blocks associated with the releasing pid.
*/
void
radeon_mem_release
(
struct
mem_block
*
heap
)
{
int
pid
=
DRM_CURRENTPID
;
struct
mem_block
*
p
;
if
(
!
heap
||
!
heap
->
next
)
return
;
for
(
p
=
heap
->
next
;
p
!=
heap
;
p
=
p
->
next
)
{
if
(
p
->
pid
==
pid
)
p
->
pid
=
0
;
}
/* Assumes a single contiguous range. Needs a special pid in
* 'heap' to stop it being subsumed.
*/
for
(
p
=
heap
->
next
;
p
!=
heap
;
p
=
p
->
next
)
{
while
(
p
->
pid
==
0
&&
p
->
next
->
pid
==
0
)
{
struct
mem_block
*
q
=
p
->
next
;
p
->
size
+=
q
->
size
;
p
->
next
=
q
->
next
;
p
->
next
->
prev
=
p
;
DRM_FREE
(
q
);
}
}
}
/* Shutdown.
*/
void
radeon_mem_takedown
(
struct
mem_block
**
heap
)
{
struct
mem_block
*
p
;
if
(
!*
heap
)
return
;
for
(
p
=
(
*
heap
)
->
next
;
p
!=
*
heap
;
)
{
struct
mem_block
*
q
=
p
;
p
=
p
->
next
;
DRM_FREE
(
q
);
}
DRM_FREE
(
*
heap
);
*
heap
=
0
;
}
/* IOCTL HANDLERS */
static
struct
mem_block
**
get_heap
(
drm_radeon_private_t
*
dev_priv
,
int
region
)
{
switch
(
region
)
{
case
RADEON_MEM_REGION_AGP
:
return
&
dev_priv
->
agp_heap
;
case
RADEON_MEM_REGION_FB
:
return
&
dev_priv
->
fb_heap
;
default:
return
0
;
}
}
int
radeon_mem_alloc
(
DRM_IOCTL_ARGS
)
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_radeon_mem_alloc_t
alloc
;
struct
mem_block
*
block
,
**
heap
;
if
(
!
dev_priv
)
{
DRM_ERROR
(
"%s called with no initialization
\n
"
,
__FUNCTION__
);
return
DRM_ERR
(
EINVAL
);
}
DRM_COPY_FROM_USER_IOCTL
(
alloc
,
(
drm_radeon_mem_alloc_t
*
)
data
,
sizeof
(
alloc
)
);
heap
=
get_heap
(
dev_priv
,
alloc
.
region
);
if
(
!
heap
||
!*
heap
)
return
DRM_ERR
(
EFAULT
);
/* Make things easier on ourselves: all allocations at least
* 4k aligned.
*/
if
(
alloc
.
alignment
<
12
)
alloc
.
alignment
=
12
;
block
=
alloc_block
(
*
heap
,
alloc
.
size
,
alloc
.
alignment
,
DRM_CURRENTPID
);
if
(
!
block
)
return
DRM_ERR
(
ENOMEM
);
if
(
DRM_COPY_TO_USER
(
alloc
.
region_offset
,
&
block
->
start
,
sizeof
(
int
)
)
)
{
DRM_ERROR
(
"copy_to_user
\n
"
);
return
DRM_ERR
(
EFAULT
);
}
return
0
;
}
int
radeon_mem_free
(
DRM_IOCTL_ARGS
)
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_radeon_mem_free_t
memfree
;
struct
mem_block
*
block
,
**
heap
;
if
(
!
dev_priv
)
{
DRM_ERROR
(
"%s called with no initialization
\n
"
,
__FUNCTION__
);
return
DRM_ERR
(
EINVAL
);
}
DRM_COPY_FROM_USER_IOCTL
(
memfree
,
(
drm_radeon_mem_free_t
*
)
data
,
sizeof
(
memfree
)
);
heap
=
get_heap
(
dev_priv
,
memfree
.
region
);
if
(
!
heap
||
!*
heap
)
return
DRM_ERR
(
EFAULT
);
block
=
find_block
(
*
heap
,
memfree
.
region_offset
);
if
(
!
block
)
return
DRM_ERR
(
EFAULT
);
if
(
block
->
pid
!=
DRM_CURRENTPID
)
return
DRM_ERR
(
EPERM
);
free_block
(
block
);
return
0
;
}
int
radeon_mem_init_heap
(
DRM_IOCTL_ARGS
)
{
DRM_DEVICE
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_radeon_mem_init_heap_t
initheap
;
struct
mem_block
**
heap
;
if
(
!
dev_priv
)
{
DRM_ERROR
(
"%s called with no initialization
\n
"
,
__FUNCTION__
);
return
DRM_ERR
(
EINVAL
);
}
DRM_COPY_FROM_USER_IOCTL
(
initheap
,
(
drm_radeon_mem_init_heap_t
*
)
data
,
sizeof
(
initheap
)
);
heap
=
get_heap
(
dev_priv
,
initheap
.
region
);
if
(
!
heap
)
return
DRM_ERR
(
EFAULT
);
if
(
*
heap
)
{
DRM_ERROR
(
"heap already initialized?"
);
return
DRM_ERR
(
EFAULT
);
}
return
init_heap
(
heap
,
initheap
.
start
,
initheap
.
size
);
}
drivers/char/drm/radeon_state.c
View file @
76f92de7
...
@@ -719,7 +719,6 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
...
@@ -719,7 +719,6 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
RING_LOCALS
;
RING_LOCALS
;
DRM_DEBUG
(
"
\n
"
);
DRM_DEBUG
(
"
\n
"
);
/* Do some trivial performance monitoring...
/* Do some trivial performance monitoring...
*/
*/
if
(
dev_priv
->
do_boxes
)
if
(
dev_priv
->
do_boxes
)
...
@@ -1088,6 +1087,8 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
...
@@ -1088,6 +1087,8 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
case
RADEON_TXFORMAT_ARGB1555
:
case
RADEON_TXFORMAT_ARGB1555
:
case
RADEON_TXFORMAT_RGB565
:
case
RADEON_TXFORMAT_RGB565
:
case
RADEON_TXFORMAT_ARGB4444
:
case
RADEON_TXFORMAT_ARGB4444
:
case
RADEON_TXFORMAT_VYUY422
:
case
RADEON_TXFORMAT_YVYU422
:
format
=
RADEON_COLOR_FORMAT_RGB565
;
format
=
RADEON_COLOR_FORMAT_RGB565
;
tex_width
=
tex
->
width
*
2
;
tex_width
=
tex
->
width
*
2
;
blit_width
=
image
->
width
*
2
;
blit_width
=
image
->
width
*
2
;
...
@@ -1226,6 +1227,7 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
...
@@ -1226,6 +1227,7 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
return
ret
;
return
ret
;
}
}
static
void
radeon_cp_dispatch_stipple
(
drm_device_t
*
dev
,
u32
*
stipple
)
static
void
radeon_cp_dispatch_stipple
(
drm_device_t
*
dev
,
u32
*
stipple
)
{
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
...
@@ -1306,6 +1308,9 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
...
@@ -1306,6 +1308,9 @@ static int radeon_do_init_pageflip( drm_device_t *dev )
return
0
;
return
0
;
}
}
/* Called whenever a client dies, from DRM(release).
* NOTE: Lock isn't necessarily held when this is called!
*/
int
radeon_do_cleanup_pageflip
(
drm_device_t
*
dev
)
int
radeon_do_cleanup_pageflip
(
drm_device_t
*
dev
)
{
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
...
@@ -1936,14 +1941,18 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
...
@@ -1936,14 +1941,18 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
if
(
i
<
cmdbuf
->
nbox
)
{
if
(
i
<
cmdbuf
->
nbox
)
{
if
(
DRM_COPY_FROM_USER_UNCHECKED
(
&
box
,
&
boxes
[
i
],
sizeof
(
box
)
))
if
(
DRM_COPY_FROM_USER_UNCHECKED
(
&
box
,
&
boxes
[
i
],
sizeof
(
box
)
))
return
DRM_ERR
(
EFAULT
);
return
DRM_ERR
(
EFAULT
);
/* FIXME The second and subsequent times round this loop, send a
/* FIXME The second and subsequent times round
* WAIT_UNTIL_3D_IDLE before calling emit_clip_rect(). This
* this loop, send a WAIT_UNTIL_3D_IDLE before
* fixes a lockup on fast machines when sending several
* calling emit_clip_rect(). This fixes a
* cliprects with a cmdbuf, as when waving a 2D window over
* lockup on fast machines when sending
* a 3D window. Something in the commands from user space
* several cliprects with a cmdbuf, as when
* seems to hang the card when they're sent several times
* waving a 2D window over a 3D
* in a row. That would be the correct place to fix it but
* window. Something in the commands from user
* this works around it until I can figure that out - Tim Smith */
* space seems to hang the card when they're
* sent several times in a row. That would be
* the correct place to fix it but this works
* around it until I can figure that out - Tim
* Smith */
if
(
i
)
{
if
(
i
)
{
BEGIN_RING
(
2
);
BEGIN_RING
(
2
);
RADEON_WAIT_UNTIL_3D_IDLE
();
RADEON_WAIT_UNTIL_3D_IDLE
();
...
@@ -1967,6 +1976,34 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
...
@@ -1967,6 +1976,34 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev,
}
}
static
int
radeon_emit_wait
(
drm_device_t
*
dev
,
int
flags
)
{
drm_radeon_private_t
*
dev_priv
=
dev
->
dev_private
;
RING_LOCALS
;
DRM_DEBUG
(
"%s: %x
\n
"
,
__FUNCTION__
,
flags
);
switch
(
flags
)
{
case
RADEON_WAIT_2D
:
BEGIN_RING
(
2
);
RADEON_WAIT_UNTIL_2D_IDLE
();
ADVANCE_RING
();
break
;
case
RADEON_WAIT_3D
:
BEGIN_RING
(
2
);
RADEON_WAIT_UNTIL_3D_IDLE
();
ADVANCE_RING
();
break
;
case
RADEON_WAIT_2D
|
RADEON_WAIT_3D
:
BEGIN_RING
(
2
);
RADEON_WAIT_UNTIL_IDLE
();
ADVANCE_RING
();
break
;
default:
return
DRM_ERR
(
EINVAL
);
}
return
0
;
}
int
radeon_cp_cmdbuf
(
DRM_IOCTL_ARGS
)
int
radeon_cp_cmdbuf
(
DRM_IOCTL_ARGS
)
{
{
...
@@ -1989,7 +2026,6 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
...
@@ -1989,7 +2026,6 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
DRM_COPY_FROM_USER_IOCTL
(
cmdbuf
,
(
drm_radeon_cmd_buffer_t
*
)
data
,
DRM_COPY_FROM_USER_IOCTL
(
cmdbuf
,
(
drm_radeon_cmd_buffer_t
*
)
data
,
sizeof
(
cmdbuf
)
);
sizeof
(
cmdbuf
)
);
DRM_DEBUG
(
"pid=%d
\n
"
,
DRM_CURRENTPID
);
RING_SPACE_TEST_WITH_RETURN
(
dev_priv
);
RING_SPACE_TEST_WITH_RETURN
(
dev_priv
);
VB_AGE_TEST_WITH_RETURN
(
dev_priv
);
VB_AGE_TEST_WITH_RETURN
(
dev_priv
);
...
@@ -2080,6 +2116,14 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
...
@@ -2080,6 +2116,14 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
return
DRM_ERR
(
EINVAL
);
return
DRM_ERR
(
EINVAL
);
}
}
break
;
break
;
case
RADEON_CMD_WAIT
:
DRM_DEBUG
(
"RADEON_CMD_WAIT
\n
"
);
if
(
radeon_emit_wait
(
dev
,
header
.
wait
.
flags
))
{
DRM_ERROR
(
"radeon_emit_wait failed
\n
"
);
return
DRM_ERR
(
EINVAL
);
}
break
;
default:
default:
DRM_ERROR
(
"bad cmd_type %d at %p
\n
"
,
DRM_ERROR
(
"bad cmd_type %d at %p
\n
"
,
header
.
header
.
cmd_type
,
header
.
header
.
cmd_type
,
...
@@ -2128,6 +2172,12 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS )
...
@@ -2128,6 +2172,12 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS )
dev_priv
->
stats
.
last_clear_reads
++
;
dev_priv
->
stats
.
last_clear_reads
++
;
value
=
GET_SCRATCH
(
2
);
value
=
GET_SCRATCH
(
2
);
break
;
break
;
case
RADEON_PARAM_IRQ_ACTIVE
:
value
=
dev
->
irq
?
1
:
0
;
break
;
case
RADEON_PARAM_AGP_BASE
:
value
=
dev_priv
->
agp_vm_start
;
break
;
default:
default:
return
DRM_ERR
(
EINVAL
);
return
DRM_ERR
(
EINVAL
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment