mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-31 20:40:22 +01:00
Added IOCTL for writing 2D DMA command buffers over PCI. Bumped minor
version number.
This commit is contained in:
parent
c33f4449fc
commit
b0c73b7fcb
8 changed files with 200 additions and 8 deletions
|
|
@ -16,6 +16,8 @@
|
|||
#include "via_drm.h"
|
||||
#include "via_drv.h"
|
||||
|
||||
#define VIA_2D_CMD 0xF0000000
|
||||
|
||||
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);
|
||||
|
|
@ -223,6 +225,92 @@ int via_cmdbuffer( DRM_IOCTL_ARGS )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int via_parse_pci_cmdbuffer( drm_device_t *dev, const char *buf,
|
||||
unsigned int size )
|
||||
{
|
||||
drm_via_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t offset, value;
|
||||
const uint32_t *regbuf = (uint32_t *)buf;
|
||||
unsigned int i;
|
||||
|
||||
size >>=3 ;
|
||||
for (i=0; i<size; ++i) {
|
||||
offset = *regbuf;
|
||||
regbuf += 2;
|
||||
if ((offset > ((0x7FF >> 2) | VIA_2D_CMD)) &&
|
||||
(offset < ((0xC00 >> 2) | VIA_2D_CMD)) ) {
|
||||
DRM_DEBUG("Attempt to access Burst Command Area.\n");
|
||||
return DRM_ERR( EINVAL );
|
||||
} else if (offset > ((0xDFF >> 2) | VIA_2D_CMD)) {
|
||||
DRM_DEBUG("Attempt to access DMA or VGA registers.\n");
|
||||
return DRM_ERR( EINVAL );
|
||||
}
|
||||
}
|
||||
|
||||
regbuf = (uint32_t *)buf;
|
||||
for ( i=0; i<size; ++i ) {
|
||||
offset = (*regbuf++ & ~VIA_2D_CMD) << 2;
|
||||
value = *regbuf++;
|
||||
VIA_WRITE( offset, value );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int via_dispatch_pci_cmdbuffer(drm_device_t *dev,
|
||||
drm_via_cmdbuffer_t *cmd )
|
||||
{
|
||||
drm_via_private_t *dev_priv = dev->dev_private;
|
||||
char *hugebuf;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* We must be able to parse the buffer all at a time, so as
|
||||
* to return an error on an invalid operation without doing
|
||||
* anything.
|
||||
* Small buffers must, on the other hand be handled fast.
|
||||
*/
|
||||
|
||||
if ( cmd->size > VIA_MAX_PCI_SIZE ) {
|
||||
return DRM_ERR( ENOMEM );
|
||||
} else if ( cmd->size > VIA_PREALLOCATED_PCI_SIZE ) {
|
||||
if (NULL == (hugebuf = (char *) kmalloc( cmd-> size, GFP_KERNEL )))
|
||||
return DRM_ERR( ENOMEM );
|
||||
DRM_COPY_FROM_USER( hugebuf, cmd->buf, cmd->size );
|
||||
ret = via_parse_pci_cmdbuffer( dev, hugebuf, cmd->size );
|
||||
kfree( hugebuf );
|
||||
} else {
|
||||
DRM_COPY_FROM_USER( dev_priv->pci_buf, cmd->buf, cmd->size );
|
||||
ret = via_parse_pci_cmdbuffer( dev, dev_priv->pci_buf, cmd->size );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int via_pci_cmdbuffer( DRM_IOCTL_ARGS )
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_via_cmdbuffer_t cmdbuf;
|
||||
int ret;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_via_cmdbuffer_t *)data,
|
||||
sizeof(cmdbuf) );
|
||||
|
||||
DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf.buf, cmdbuf.size);
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("via_pci_cmdbuffer called without lock held\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
ret = via_dispatch_pci_cmdbuffer( dev, &cmdbuf );
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#define VIA_NR_XVMC_PORTS 10
|
||||
#define VIA_NR_XVMC_LOCKS 5
|
||||
#define VIA_MAX_CACHELINE_SIZE 64
|
||||
#define VIA_PREALLOCATED_PCI_SIZE 16384
|
||||
#define VIA_MAX_PCI_SIZE 65536
|
||||
#define XVMCLOCKPTR(saPriv,lockNo) \
|
||||
((volatile int *)(((((unsigned long) (saPriv)->XvMCLockArea) + \
|
||||
(VIA_MAX_CACHELINE_SIZE - 1)) & \
|
||||
|
|
@ -67,8 +69,10 @@
|
|||
#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(0x44, drm_via_init_t)
|
||||
#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW(0x45, drm_via_futex_t)
|
||||
#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(0x47, drm_via_dma_init_t)
|
||||
#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOWR(0x48, drm_via_dma_init_t)
|
||||
#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW(0x48, drm_via_cmdbuffer_t)
|
||||
#define DRM_IOCTL_VIA_FLUSH DRM_IO(0x49)
|
||||
#define DRM_IOCTL_VIA_PCICMD DRM_IOW(0x4A, drm_via_cmdbuffer_t)
|
||||
|
||||
|
||||
/* Indices into buf.Setup where various bits of state are mirrored per
|
||||
* context and per buffer. These can be fired at the card as a unit,
|
||||
|
|
@ -200,6 +204,7 @@ int via_decoder_futex( DRM_IOCTL_ARGS );
|
|||
int via_dma_init( DRM_IOCTL_ARGS );
|
||||
int via_cmdbuffer( DRM_IOCTL_ARGS );
|
||||
int via_flush_ioctl( DRM_IOCTL_ARGS );
|
||||
int via_pci_cmdbuffer( DRM_IOCTL_ARGS );
|
||||
|
||||
#endif
|
||||
#endif /* _VIA_DRM_H_ */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include "via.h"
|
||||
#include "drmP.h"
|
||||
|
|
@ -31,10 +32,10 @@
|
|||
|
||||
#define DRIVER_NAME "via"
|
||||
#define DRIVER_DESC "VIA Unichrome"
|
||||
#define DRIVER_DATE "20040819"
|
||||
#define DRIVER_DATE "20040907"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 4
|
||||
#define DRIVER_MINOR 5
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
|
||||
|
|
@ -47,7 +48,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_DEC_FUTEX)] = { via_decoder_futex, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_DMA_INIT)] = { via_dma_init, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_CMDBUFFER)] = { via_cmdbuffer, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_FLUSH)] = { via_flush_ioctl, 1, 0}
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_FLUSH)] = { via_flush_ioctl, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_PCICMD)] = { via_pci_cmdbuffer, 1, 0}
|
||||
|
||||
|
||||
#define __HAVE_COUNTERS 0
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ typedef struct drm_via_private {
|
|||
uint32_t * last_pause_ptr;
|
||||
volatile uint32_t * hw_addr_ptr;
|
||||
drm_via_ring_buffer_t ring;
|
||||
char pci_buf[VIA_PREALLOCATED_PCI_SIZE];
|
||||
} drm_via_private_t;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#include "via_drm.h"
|
||||
#include "via_drv.h"
|
||||
|
||||
#define VIA_2D_CMD 0xF0000000
|
||||
|
||||
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);
|
||||
|
|
@ -223,6 +225,92 @@ int via_cmdbuffer( DRM_IOCTL_ARGS )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int via_parse_pci_cmdbuffer( drm_device_t *dev, const char *buf,
|
||||
unsigned int size )
|
||||
{
|
||||
drm_via_private_t *dev_priv = dev->dev_private;
|
||||
uint32_t offset, value;
|
||||
const uint32_t *regbuf = (uint32_t *)buf;
|
||||
unsigned int i;
|
||||
|
||||
size >>=3 ;
|
||||
for (i=0; i<size; ++i) {
|
||||
offset = *regbuf;
|
||||
regbuf += 2;
|
||||
if ((offset > ((0x7FF >> 2) | VIA_2D_CMD)) &&
|
||||
(offset < ((0xC00 >> 2) | VIA_2D_CMD)) ) {
|
||||
DRM_DEBUG("Attempt to access Burst Command Area.\n");
|
||||
return DRM_ERR( EINVAL );
|
||||
} else if (offset > ((0xDFF >> 2) | VIA_2D_CMD)) {
|
||||
DRM_DEBUG("Attempt to access DMA or VGA registers.\n");
|
||||
return DRM_ERR( EINVAL );
|
||||
}
|
||||
}
|
||||
|
||||
regbuf = (uint32_t *)buf;
|
||||
for ( i=0; i<size; ++i ) {
|
||||
offset = (*regbuf++ & ~VIA_2D_CMD) << 2;
|
||||
value = *regbuf++;
|
||||
VIA_WRITE( offset, value );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int via_dispatch_pci_cmdbuffer(drm_device_t *dev,
|
||||
drm_via_cmdbuffer_t *cmd )
|
||||
{
|
||||
drm_via_private_t *dev_priv = dev->dev_private;
|
||||
char *hugebuf;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* We must be able to parse the buffer all at a time, so as
|
||||
* to return an error on an invalid operation without doing
|
||||
* anything.
|
||||
* Small buffers must, on the other hand be handled fast.
|
||||
*/
|
||||
|
||||
if ( cmd->size > VIA_MAX_PCI_SIZE ) {
|
||||
return DRM_ERR( ENOMEM );
|
||||
} else if ( cmd->size > VIA_PREALLOCATED_PCI_SIZE ) {
|
||||
if (NULL == (hugebuf = (char *) kmalloc( cmd-> size, GFP_KERNEL )))
|
||||
return DRM_ERR( ENOMEM );
|
||||
DRM_COPY_FROM_USER( hugebuf, cmd->buf, cmd->size );
|
||||
ret = via_parse_pci_cmdbuffer( dev, hugebuf, cmd->size );
|
||||
kfree( hugebuf );
|
||||
} else {
|
||||
DRM_COPY_FROM_USER( dev_priv->pci_buf, cmd->buf, cmd->size );
|
||||
ret = via_parse_pci_cmdbuffer( dev, dev_priv->pci_buf, cmd->size );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int via_pci_cmdbuffer( DRM_IOCTL_ARGS )
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_via_cmdbuffer_t cmdbuf;
|
||||
int ret;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_via_cmdbuffer_t *)data,
|
||||
sizeof(cmdbuf) );
|
||||
|
||||
DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf.buf, cmdbuf.size);
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("via_pci_cmdbuffer called without lock held\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
ret = via_dispatch_pci_cmdbuffer( dev, &cmdbuf );
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#define VIA_NR_XVMC_PORTS 10
|
||||
#define VIA_NR_XVMC_LOCKS 5
|
||||
#define VIA_MAX_CACHELINE_SIZE 64
|
||||
#define VIA_PREALLOCATED_PCI_SIZE 16384
|
||||
#define VIA_MAX_PCI_SIZE 65536
|
||||
#define XVMCLOCKPTR(saPriv,lockNo) \
|
||||
((volatile int *)(((((unsigned long) (saPriv)->XvMCLockArea) + \
|
||||
(VIA_MAX_CACHELINE_SIZE - 1)) & \
|
||||
|
|
@ -67,8 +69,10 @@
|
|||
#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(0x44, drm_via_init_t)
|
||||
#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW(0x45, drm_via_futex_t)
|
||||
#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(0x47, drm_via_dma_init_t)
|
||||
#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOWR(0x48, drm_via_dma_init_t)
|
||||
#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW(0x48, drm_via_cmdbuffer_t)
|
||||
#define DRM_IOCTL_VIA_FLUSH DRM_IO(0x49)
|
||||
#define DRM_IOCTL_VIA_PCICMD DRM_IOW(0x4A, drm_via_cmdbuffer_t)
|
||||
|
||||
|
||||
/* Indices into buf.Setup where various bits of state are mirrored per
|
||||
* context and per buffer. These can be fired at the card as a unit,
|
||||
|
|
@ -200,6 +204,7 @@ int via_decoder_futex( DRM_IOCTL_ARGS );
|
|||
int via_dma_init( DRM_IOCTL_ARGS );
|
||||
int via_cmdbuffer( DRM_IOCTL_ARGS );
|
||||
int via_flush_ioctl( DRM_IOCTL_ARGS );
|
||||
int via_pci_cmdbuffer( DRM_IOCTL_ARGS );
|
||||
|
||||
#endif
|
||||
#endif /* _VIA_DRM_H_ */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include "via.h"
|
||||
#include "drmP.h"
|
||||
|
|
@ -31,10 +32,10 @@
|
|||
|
||||
#define DRIVER_NAME "via"
|
||||
#define DRIVER_DESC "VIA Unichrome"
|
||||
#define DRIVER_DATE "20040819"
|
||||
#define DRIVER_DATE "20040907"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 4
|
||||
#define DRIVER_MINOR 5
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
|
||||
|
|
@ -47,7 +48,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_DEC_FUTEX)] = { via_decoder_futex, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_DMA_INIT)] = { via_dma_init, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_CMDBUFFER)] = { via_cmdbuffer, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_FLUSH)] = { via_flush_ioctl, 1, 0}
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_FLUSH)] = { via_flush_ioctl, 1, 0}, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VIA_PCICMD)] = { via_pci_cmdbuffer, 1, 0}
|
||||
|
||||
|
||||
#define __HAVE_COUNTERS 0
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ typedef struct drm_via_private {
|
|||
uint32_t * last_pause_ptr;
|
||||
volatile uint32_t * hw_addr_ptr;
|
||||
drm_via_ring_buffer_t ring;
|
||||
char pci_buf[VIA_PREALLOCATED_PCI_SIZE];
|
||||
} drm_via_private_t;
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue