Home | History | Annotate | Line # | Download | only in via
      1  1.6  riastrad /*	$NetBSD: via_dma.c,v 1.6 2021/12/18 23:45:44 riastradh Exp $	*/
      2  1.3  riastrad 
      3  1.1  riastrad /* via_dma.c -- DMA support for the VIA Unichrome/Pro
      4  1.1  riastrad  *
      5  1.1  riastrad  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
      6  1.1  riastrad  * All Rights Reserved.
      7  1.1  riastrad  *
      8  1.1  riastrad  * Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
      9  1.1  riastrad  * All Rights Reserved.
     10  1.1  riastrad  *
     11  1.1  riastrad  * Copyright 2004 The Unichrome project.
     12  1.1  riastrad  * All Rights Reserved.
     13  1.1  riastrad  *
     14  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
     15  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
     16  1.1  riastrad  * to deal in the Software without restriction, including without limitation
     17  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sub license,
     18  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     19  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     20  1.1  riastrad  *
     21  1.1  riastrad  * The above copyright notice and this permission notice (including the
     22  1.1  riastrad  * next paragraph) shall be included in all copies or substantial portions
     23  1.1  riastrad  * of the Software.
     24  1.1  riastrad  *
     25  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     26  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     27  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     28  1.1  riastrad  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     29  1.1  riastrad  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     30  1.1  riastrad  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     31  1.1  riastrad  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     32  1.1  riastrad  *
     33  1.1  riastrad  * Authors:
     34  1.1  riastrad  *    Tungsten Graphics,
     35  1.1  riastrad  *    Erdi Chen,
     36  1.1  riastrad  *    Thomas Hellstrom.
     37  1.1  riastrad  */
     38  1.1  riastrad 
     39  1.3  riastrad #include <sys/cdefs.h>
     40  1.6  riastrad __KERNEL_RCSID(0, "$NetBSD: via_dma.c,v 1.6 2021/12/18 23:45:44 riastradh Exp $");
     41  1.3  riastrad 
     42  1.6  riastrad #include <linux/delay.h>
     43  1.6  riastrad #include <linux/uaccess.h>
     44  1.6  riastrad 
     45  1.6  riastrad #include <drm/drm.h>
     46  1.6  riastrad #include <drm/drm_agpsupport.h>
     47  1.6  riastrad #include <drm/drm_device.h>
     48  1.6  riastrad #include <drm/drm_file.h>
     49  1.1  riastrad #include <drm/via_drm.h>
     50  1.6  riastrad 
     51  1.1  riastrad #include "via_drv.h"
     52  1.1  riastrad #include "via_3d_reg.h"
     53  1.1  riastrad 
     54  1.1  riastrad #define CMDBUF_ALIGNMENT_SIZE   (0x100)
     55  1.1  riastrad #define CMDBUF_ALIGNMENT_MASK   (0x0ff)
     56  1.1  riastrad 
     57  1.1  riastrad /* defines for VIA 3D registers */
     58  1.1  riastrad #define VIA_REG_STATUS          0x400
     59  1.1  riastrad #define VIA_REG_TRANSET         0x43C
     60  1.1  riastrad #define VIA_REG_TRANSPACE       0x440
     61  1.1  riastrad 
     62  1.1  riastrad /* VIA_REG_STATUS(0x400): Engine Status */
     63  1.1  riastrad #define VIA_CMD_RGTR_BUSY       0x00000080	/* Command Regulator is busy */
     64  1.1  riastrad #define VIA_2D_ENG_BUSY         0x00000001	/* 2D Engine is busy */
     65  1.1  riastrad #define VIA_3D_ENG_BUSY         0x00000002	/* 3D Engine is busy */
     66  1.1  riastrad #define VIA_VR_QUEUE_BUSY       0x00020000	/* Virtual Queue is busy */
     67  1.1  riastrad 
     68  1.1  riastrad #define SetReg2DAGP(nReg, nData) {				\
     69  1.1  riastrad 	*((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1;	\
     70  1.1  riastrad 	*((uint32_t *)(vb) + 1) = (nData);			\
     71  1.1  riastrad 	vb = ((uint32_t *)vb) + 2;				\
     72  1.1  riastrad 	dev_priv->dma_low += 8;					\
     73  1.1  riastrad }
     74  1.1  riastrad 
     75  1.2  riastrad #define via_flush_write_combine() mb()
     76  1.1  riastrad 
     77  1.1  riastrad #define VIA_OUT_RING_QW(w1, w2)	do {		\
     78  1.1  riastrad 	*vb++ = (w1);				\
     79  1.1  riastrad 	*vb++ = (w2);				\
     80  1.1  riastrad 	dev_priv->dma_low += 8;			\
     81  1.1  riastrad } while (0)
     82  1.1  riastrad 
     83  1.1  riastrad static void via_cmdbuf_start(drm_via_private_t *dev_priv);
     84  1.1  riastrad static void via_cmdbuf_pause(drm_via_private_t *dev_priv);
     85  1.1  riastrad static void via_cmdbuf_reset(drm_via_private_t *dev_priv);
     86  1.1  riastrad static void via_cmdbuf_rewind(drm_via_private_t *dev_priv);
     87  1.1  riastrad static int via_wait_idle(drm_via_private_t *dev_priv);
     88  1.1  riastrad static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
     89  1.1  riastrad 
     90  1.1  riastrad /*
     91  1.1  riastrad  * Free space in command buffer.
     92  1.1  riastrad  */
     93  1.1  riastrad 
     94  1.1  riastrad static uint32_t via_cmdbuf_space(drm_via_private_t *dev_priv)
     95  1.1  riastrad {
     96  1.1  riastrad 	uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
     97  1.1  riastrad 	uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
     98  1.1  riastrad 
     99  1.1  riastrad 	return ((hw_addr <= dev_priv->dma_low) ?
    100  1.1  riastrad 		(dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
    101  1.1  riastrad 		(hw_addr - dev_priv->dma_low));
    102  1.1  riastrad }
    103  1.1  riastrad 
    104  1.1  riastrad /*
    105  1.1  riastrad  * How much does the command regulator lag behind?
    106  1.1  riastrad  */
    107  1.1  riastrad 
    108  1.1  riastrad static uint32_t via_cmdbuf_lag(drm_via_private_t *dev_priv)
    109  1.1  riastrad {
    110  1.1  riastrad 	uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
    111  1.1  riastrad 	uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
    112  1.1  riastrad 
    113  1.1  riastrad 	return ((hw_addr <= dev_priv->dma_low) ?
    114  1.1  riastrad 		(dev_priv->dma_low - hw_addr) :
    115  1.1  riastrad 		(dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
    116  1.1  riastrad }
    117  1.1  riastrad 
    118  1.1  riastrad /*
    119  1.1  riastrad  * Check that the given size fits in the buffer, otherwise wait.
    120  1.1  riastrad  */
    121  1.1  riastrad 
    122  1.1  riastrad static inline int
    123  1.1  riastrad via_cmdbuf_wait(drm_via_private_t *dev_priv, unsigned int size)
    124  1.1  riastrad {
    125  1.1  riastrad 	uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
    126  1.1  riastrad 	uint32_t cur_addr, hw_addr, next_addr;
    127  1.1  riastrad 	volatile uint32_t *hw_addr_ptr;
    128  1.1  riastrad 	uint32_t count;
    129  1.1  riastrad 	hw_addr_ptr = dev_priv->hw_addr_ptr;
    130  1.1  riastrad 	cur_addr = dev_priv->dma_low;
    131  1.1  riastrad 	next_addr = cur_addr + size + 512 * 1024;
    132  1.1  riastrad 	count = 1000000;
    133  1.1  riastrad 	do {
    134  1.1  riastrad 		hw_addr = *hw_addr_ptr - agp_base;
    135  1.1  riastrad 		if (count-- == 0) {
    136  1.1  riastrad 			DRM_ERROR
    137  1.1  riastrad 			    ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
    138  1.1  riastrad 			     hw_addr, cur_addr, next_addr);
    139  1.1  riastrad 			return -1;
    140  1.1  riastrad 		}
    141  1.1  riastrad 		if  ((cur_addr < hw_addr) && (next_addr >= hw_addr))
    142  1.1  riastrad 			msleep(1);
    143  1.1  riastrad 	} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
    144  1.1  riastrad 	return 0;
    145  1.1  riastrad }
    146  1.1  riastrad 
    147  1.1  riastrad /*
    148  1.1  riastrad  * Checks whether buffer head has reach the end. Rewind the ring buffer
    149  1.1  riastrad  * when necessary.
    150  1.1  riastrad  *
    151  1.1  riastrad  * Returns virtual pointer to ring buffer.
    152  1.1  riastrad  */
    153  1.1  riastrad 
    154  1.1  riastrad static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
    155  1.1  riastrad 				      unsigned int size)
    156  1.1  riastrad {
    157  1.1  riastrad 	if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) >
    158  1.1  riastrad 	    dev_priv->dma_high) {
    159  1.1  riastrad 		via_cmdbuf_rewind(dev_priv);
    160  1.1  riastrad 	}
    161  1.1  riastrad 	if (via_cmdbuf_wait(dev_priv, size) != 0)
    162  1.1  riastrad 		return NULL;
    163  1.1  riastrad 
    164  1.1  riastrad 	return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
    165  1.1  riastrad }
    166  1.1  riastrad 
    167  1.1  riastrad int via_dma_cleanup(struct drm_device *dev)
    168  1.1  riastrad {
    169  1.1  riastrad 	if (dev->dev_private) {
    170  1.1  riastrad 		drm_via_private_t *dev_priv =
    171  1.1  riastrad 		    (drm_via_private_t *) dev->dev_private;
    172  1.1  riastrad 
    173  1.1  riastrad 		if (dev_priv->ring.virtual_start) {
    174  1.1  riastrad 			via_cmdbuf_reset(dev_priv);
    175  1.1  riastrad 
    176  1.3  riastrad 			drm_legacy_ioremapfree(&dev_priv->ring.map, dev);
    177  1.1  riastrad 			dev_priv->ring.virtual_start = NULL;
    178  1.1  riastrad 		}
    179  1.1  riastrad 
    180  1.1  riastrad 	}
    181  1.1  riastrad 
    182  1.1  riastrad 	return 0;
    183  1.1  riastrad }
    184  1.1  riastrad 
    185  1.1  riastrad static int via_initialize(struct drm_device *dev,
    186  1.1  riastrad 			  drm_via_private_t *dev_priv,
    187  1.1  riastrad 			  drm_via_dma_init_t *init)
    188  1.1  riastrad {
    189  1.1  riastrad 	if (!dev_priv || !dev_priv->mmio) {
    190  1.1  riastrad 		DRM_ERROR("via_dma_init called before via_map_init\n");
    191  1.1  riastrad 		return -EFAULT;
    192  1.1  riastrad 	}
    193  1.1  riastrad 
    194  1.1  riastrad 	if (dev_priv->ring.virtual_start != NULL) {
    195  1.1  riastrad 		DRM_ERROR("called again without calling cleanup\n");
    196  1.1  riastrad 		return -EFAULT;
    197  1.1  riastrad 	}
    198  1.1  riastrad 
    199  1.1  riastrad 	if (!dev->agp || !dev->agp->base) {
    200  1.1  riastrad 		DRM_ERROR("called with no agp memory available\n");
    201  1.1  riastrad 		return -EFAULT;
    202  1.1  riastrad 	}
    203  1.1  riastrad 
    204  1.1  riastrad 	if (dev_priv->chipset == VIA_DX9_0) {
    205  1.1  riastrad 		DRM_ERROR("AGP DMA is not supported on this chip\n");
    206  1.1  riastrad 		return -EINVAL;
    207  1.1  riastrad 	}
    208  1.1  riastrad 
    209  1.1  riastrad 	dev_priv->ring.map.offset = dev->agp->base + init->offset;
    210  1.1  riastrad 	dev_priv->ring.map.size = init->size;
    211  1.1  riastrad 	dev_priv->ring.map.type = 0;
    212  1.1  riastrad 	dev_priv->ring.map.flags = 0;
    213  1.1  riastrad 	dev_priv->ring.map.mtrr = 0;
    214  1.1  riastrad 
    215  1.3  riastrad 	drm_legacy_ioremap(&dev_priv->ring.map, dev);
    216  1.1  riastrad 
    217  1.1  riastrad 	if (dev_priv->ring.map.handle == NULL) {
    218  1.1  riastrad 		via_dma_cleanup(dev);
    219  1.1  riastrad 		DRM_ERROR("can not ioremap virtual address for"
    220  1.1  riastrad 			  " ring buffer\n");
    221  1.1  riastrad 		return -ENOMEM;
    222  1.1  riastrad 	}
    223  1.1  riastrad 
    224  1.1  riastrad 	dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
    225  1.1  riastrad 
    226  1.1  riastrad 	dev_priv->dma_ptr = dev_priv->ring.virtual_start;
    227  1.1  riastrad 	dev_priv->dma_low = 0;
    228  1.1  riastrad 	dev_priv->dma_high = init->size;
    229  1.1  riastrad 	dev_priv->dma_wrap = init->size;
    230  1.1  riastrad 	dev_priv->dma_offset = init->offset;
    231  1.1  riastrad 	dev_priv->last_pause_ptr = NULL;
    232  1.1  riastrad 	dev_priv->hw_addr_ptr =
    233  1.1  riastrad 		(volatile uint32_t *)((char *)dev_priv->mmio->handle +
    234  1.1  riastrad 		init->reg_pause_addr);
    235  1.1  riastrad 
    236  1.1  riastrad 	via_cmdbuf_start(dev_priv);
    237  1.1  riastrad 
    238  1.1  riastrad 	return 0;
    239  1.1  riastrad }
    240  1.1  riastrad 
    241  1.1  riastrad static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
    242  1.1  riastrad {
    243  1.1  riastrad 	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
    244  1.1  riastrad 	drm_via_dma_init_t *init = data;
    245  1.1  riastrad 	int retcode = 0;
    246  1.1  riastrad 
    247  1.1  riastrad 	switch (init->func) {
    248  1.1  riastrad 	case VIA_INIT_DMA:
    249  1.2  riastrad 		if (!capable(CAP_SYS_ADMIN))
    250  1.1  riastrad 			retcode = -EPERM;
    251  1.1  riastrad 		else
    252  1.1  riastrad 			retcode = via_initialize(dev, dev_priv, init);
    253  1.1  riastrad 		break;
    254  1.1  riastrad 	case VIA_CLEANUP_DMA:
    255  1.2  riastrad 		if (!capable(CAP_SYS_ADMIN))
    256  1.1  riastrad 			retcode = -EPERM;
    257  1.1  riastrad 		else
    258  1.1  riastrad 			retcode = via_dma_cleanup(dev);
    259  1.1  riastrad 		break;
    260  1.1  riastrad 	case VIA_DMA_INITIALIZED:
    261  1.1  riastrad 		retcode = (dev_priv->ring.virtual_start != NULL) ?
    262  1.1  riastrad 			0 : -EFAULT;
    263  1.1  riastrad 		break;
    264  1.1  riastrad 	default:
    265  1.1  riastrad 		retcode = -EINVAL;
    266  1.1  riastrad 		break;
    267  1.1  riastrad 	}
    268  1.1  riastrad 
    269  1.1  riastrad 	return retcode;
    270  1.1  riastrad }
    271  1.1  riastrad 
    272  1.1  riastrad static int via_dispatch_cmdbuffer(struct drm_device *dev, drm_via_cmdbuffer_t *cmd)
    273  1.1  riastrad {
    274  1.1  riastrad 	drm_via_private_t *dev_priv;
    275  1.1  riastrad 	uint32_t *vb;
    276  1.1  riastrad 	int ret;
    277  1.1  riastrad 
    278  1.1  riastrad 	dev_priv = (drm_via_private_t *) dev->dev_private;
    279  1.1  riastrad 
    280  1.1  riastrad 	if (dev_priv->ring.virtual_start == NULL) {
    281  1.1  riastrad 		DRM_ERROR("called without initializing AGP ring buffer.\n");
    282  1.1  riastrad 		return -EFAULT;
    283  1.1  riastrad 	}
    284  1.1  riastrad 
    285  1.1  riastrad 	if (cmd->size > VIA_PCI_BUF_SIZE)
    286  1.1  riastrad 		return -ENOMEM;
    287  1.1  riastrad 
    288  1.2  riastrad 	if (copy_from_user(dev_priv->pci_buf, cmd->buf, cmd->size))
    289  1.1  riastrad 		return -EFAULT;
    290  1.1  riastrad 
    291  1.1  riastrad 	/*
    292  1.1  riastrad 	 * Running this function on AGP memory is dead slow. Therefore
    293  1.1  riastrad 	 * we run it on a temporary cacheable system memory buffer and
    294  1.1  riastrad 	 * copy it to AGP memory when ready.
    295  1.1  riastrad 	 */
    296  1.1  riastrad 
    297  1.1  riastrad 	if ((ret =
    298  1.1  riastrad 	     via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
    299  1.1  riastrad 				       cmd->size, dev, 1))) {
    300  1.1  riastrad 		return ret;
    301  1.1  riastrad 	}
    302  1.1  riastrad 
    303  1.1  riastrad 	vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
    304  1.1  riastrad 	if (vb == NULL)
    305  1.1  riastrad 		return -EAGAIN;
    306  1.1  riastrad 
    307  1.1  riastrad 	memcpy(vb, dev_priv->pci_buf, cmd->size);
    308  1.1  riastrad 
    309  1.1  riastrad 	dev_priv->dma_low += cmd->size;
    310  1.1  riastrad 
    311  1.1  riastrad 	/*
    312  1.1  riastrad 	 * Small submissions somehow stalls the CPU. (AGP cache effects?)
    313  1.1  riastrad 	 * pad to greater size.
    314  1.1  riastrad 	 */
    315  1.1  riastrad 
    316  1.1  riastrad 	if (cmd->size < 0x100)
    317  1.1  riastrad 		via_pad_cache(dev_priv, (0x100 - cmd->size) >> 3);
    318  1.1  riastrad 	via_cmdbuf_pause(dev_priv);
    319  1.1  riastrad 
    320  1.1  riastrad 	return 0;
    321  1.1  riastrad }
    322  1.1  riastrad 
    323  1.1  riastrad int via_driver_dma_quiescent(struct drm_device *dev)
    324  1.1  riastrad {
    325  1.1  riastrad 	drm_via_private_t *dev_priv = dev->dev_private;
    326  1.1  riastrad 
    327  1.1  riastrad 	if (!via_wait_idle(dev_priv))
    328  1.1  riastrad 		return -EBUSY;
    329  1.1  riastrad 	return 0;
    330  1.1  riastrad }
    331  1.1  riastrad 
    332  1.1  riastrad static int via_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
    333  1.1  riastrad {
    334  1.1  riastrad 
    335  1.1  riastrad 	LOCK_TEST_WITH_RETURN(dev, file_priv);
    336  1.1  riastrad 
    337  1.1  riastrad 	return via_driver_dma_quiescent(dev);
    338  1.1  riastrad }
    339  1.1  riastrad 
    340  1.1  riastrad static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv)
    341  1.1  riastrad {
    342  1.1  riastrad 	drm_via_cmdbuffer_t *cmdbuf = data;
    343  1.1  riastrad 	int ret;
    344  1.1  riastrad 
    345  1.1  riastrad 	LOCK_TEST_WITH_RETURN(dev, file_priv);
    346  1.1  riastrad 
    347  1.1  riastrad 	DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
    348  1.1  riastrad 
    349  1.1  riastrad 	ret = via_dispatch_cmdbuffer(dev, cmdbuf);
    350  1.1  riastrad 	return ret;
    351  1.1  riastrad }
    352  1.1  riastrad 
    353  1.1  riastrad static int via_dispatch_pci_cmdbuffer(struct drm_device *dev,
    354  1.1  riastrad 				      drm_via_cmdbuffer_t *cmd)
    355  1.1  riastrad {
    356  1.1  riastrad 	drm_via_private_t *dev_priv = dev->dev_private;
    357  1.1  riastrad 	int ret;
    358  1.1  riastrad 
    359  1.1  riastrad 	if (cmd->size > VIA_PCI_BUF_SIZE)
    360  1.1  riastrad 		return -ENOMEM;
    361  1.2  riastrad 	if (copy_from_user(dev_priv->pci_buf, cmd->buf, cmd->size))
    362  1.1  riastrad 		return -EFAULT;
    363  1.1  riastrad 
    364  1.1  riastrad 	if ((ret =
    365  1.1  riastrad 	     via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
    366  1.1  riastrad 				       cmd->size, dev, 0))) {
    367  1.1  riastrad 		return ret;
    368  1.1  riastrad 	}
    369  1.1  riastrad 
    370  1.1  riastrad 	ret =
    371  1.1  riastrad 	    via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf,
    372  1.1  riastrad 				     cmd->size);
    373  1.1  riastrad 	return ret;
    374  1.1  riastrad }
    375  1.1  riastrad 
    376  1.1  riastrad static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv)
    377  1.1  riastrad {
    378  1.1  riastrad 	drm_via_cmdbuffer_t *cmdbuf = data;
    379  1.1  riastrad 	int ret;
    380  1.1  riastrad 
    381  1.1  riastrad 	LOCK_TEST_WITH_RETURN(dev, file_priv);
    382  1.1  riastrad 
    383  1.1  riastrad 	DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
    384  1.1  riastrad 
    385  1.1  riastrad 	ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf);
    386  1.1  riastrad 	return ret;
    387  1.1  riastrad }
    388  1.1  riastrad 
    389  1.1  riastrad static inline uint32_t *via_align_buffer(drm_via_private_t *dev_priv,
    390  1.1  riastrad 					 uint32_t * vb, int qw_count)
    391  1.1  riastrad {
    392  1.1  riastrad 	for (; qw_count > 0; --qw_count)
    393  1.1  riastrad 		VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
    394  1.1  riastrad 	return vb;
    395  1.1  riastrad }
    396  1.1  riastrad 
    397  1.1  riastrad /*
    398  1.1  riastrad  * This function is used internally by ring buffer management code.
    399  1.1  riastrad  *
    400  1.1  riastrad  * Returns virtual pointer to ring buffer.
    401  1.1  riastrad  */
    402  1.1  riastrad static inline uint32_t *via_get_dma(drm_via_private_t *dev_priv)
    403  1.1  riastrad {
    404  1.1  riastrad 	return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
    405  1.1  riastrad }
    406  1.1  riastrad 
    407  1.1  riastrad /*
    408  1.1  riastrad  * Hooks a segment of data into the tail of the ring-buffer by
    409  1.1  riastrad  * modifying the pause address stored in the buffer itself. If
    410  1.1  riastrad  * the regulator has already paused, restart it.
    411  1.1  riastrad  */
    412  1.1  riastrad static int via_hook_segment(drm_via_private_t *dev_priv,
    413  1.1  riastrad 			    uint32_t pause_addr_hi, uint32_t pause_addr_lo,
    414  1.1  riastrad 			    int no_pci_fire)
    415  1.1  riastrad {
    416  1.1  riastrad 	int paused, count;
    417  1.1  riastrad 	volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
    418  1.1  riastrad 	uint32_t reader, ptr;
    419  1.1  riastrad 	uint32_t diff;
    420  1.1  riastrad 
    421  1.1  riastrad 	paused = 0;
    422  1.1  riastrad 	via_flush_write_combine();
    423  1.1  riastrad 	(void) *(volatile uint32_t *)(via_get_dma(dev_priv) - 1);
    424  1.1  riastrad 
    425  1.1  riastrad 	*paused_at = pause_addr_lo;
    426  1.1  riastrad 	via_flush_write_combine();
    427  1.1  riastrad 	(void) *paused_at;
    428  1.1  riastrad 
    429  1.1  riastrad 	reader = *(dev_priv->hw_addr_ptr);
    430  1.1  riastrad 	ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
    431  1.1  riastrad 		dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
    432  1.1  riastrad 
    433  1.1  riastrad 	dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
    434  1.1  riastrad 
    435  1.1  riastrad 	/*
    436  1.1  riastrad 	 * If there is a possibility that the command reader will
    437  1.1  riastrad 	 * miss the new pause address and pause on the old one,
    438  1.1  riastrad 	 * In that case we need to program the new start address
    439  1.1  riastrad 	 * using PCI.
    440  1.1  riastrad 	 */
    441  1.1  riastrad 
    442  1.1  riastrad 	diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
    443  1.1  riastrad 	count = 10000000;
    444  1.1  riastrad 	while (diff == 0 && count--) {
    445  1.6  riastrad 		paused = (via_read(dev_priv, 0x41c) & 0x80000000);
    446  1.1  riastrad 		if (paused)
    447  1.1  riastrad 			break;
    448  1.1  riastrad 		reader = *(dev_priv->hw_addr_ptr);
    449  1.1  riastrad 		diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
    450  1.1  riastrad 	}
    451  1.1  riastrad 
    452  1.6  riastrad 	paused = via_read(dev_priv, 0x41c) & 0x80000000;
    453  1.1  riastrad 
    454  1.1  riastrad 	if (paused && !no_pci_fire) {
    455  1.1  riastrad 		reader = *(dev_priv->hw_addr_ptr);
    456  1.1  riastrad 		diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
    457  1.1  riastrad 		diff &= (dev_priv->dma_high - 1);
    458  1.1  riastrad 		if (diff != 0 && diff < (dev_priv->dma_high >> 1)) {
    459  1.1  riastrad 			DRM_ERROR("Paused at incorrect address. "
    460  1.1  riastrad 				  "0x%08x, 0x%08x 0x%08x\n",
    461  1.1  riastrad 				  ptr, reader, dev_priv->dma_diff);
    462  1.1  riastrad 		} else if (diff == 0) {
    463  1.1  riastrad 			/*
    464  1.1  riastrad 			 * There is a concern that these writes may stall the PCI bus
    465  1.1  riastrad 			 * if the GPU is not idle. However, idling the GPU first
    466  1.1  riastrad 			 * doesn't make a difference.
    467  1.1  riastrad 			 */
    468  1.1  riastrad 
    469  1.6  riastrad 			via_write(dev_priv, VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
    470  1.6  riastrad 			via_write(dev_priv, VIA_REG_TRANSPACE, pause_addr_hi);
    471  1.6  riastrad 			via_write(dev_priv, VIA_REG_TRANSPACE, pause_addr_lo);
    472  1.6  riastrad 			via_read(dev_priv, VIA_REG_TRANSPACE);
    473  1.1  riastrad 		}
    474  1.1  riastrad 	}
    475  1.1  riastrad 	return paused;
    476  1.1  riastrad }
    477  1.1  riastrad 
    478  1.1  riastrad static int via_wait_idle(drm_via_private_t *dev_priv)
    479  1.1  riastrad {
    480  1.1  riastrad 	int count = 10000000;
    481  1.1  riastrad 
    482  1.6  riastrad 	while (!(via_read(dev_priv, VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && --count)
    483  1.1  riastrad 		;
    484  1.1  riastrad 
    485  1.6  riastrad 	while (count && (via_read(dev_priv, VIA_REG_STATUS) &
    486  1.1  riastrad 			   (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
    487  1.1  riastrad 			    VIA_3D_ENG_BUSY)))
    488  1.1  riastrad 		--count;
    489  1.1  riastrad 	return count;
    490  1.1  riastrad }
    491  1.1  riastrad 
    492  1.1  riastrad static uint32_t *via_align_cmd(drm_via_private_t *dev_priv, uint32_t cmd_type,
    493  1.1  riastrad 			       uint32_t addr, uint32_t *cmd_addr_hi,
    494  1.1  riastrad 			       uint32_t *cmd_addr_lo, int skip_wait)
    495  1.1  riastrad {
    496  1.1  riastrad 	uint32_t agp_base;
    497  1.1  riastrad 	uint32_t cmd_addr, addr_lo, addr_hi;
    498  1.1  riastrad 	uint32_t *vb;
    499  1.1  riastrad 	uint32_t qw_pad_count;
    500  1.1  riastrad 
    501  1.1  riastrad 	if (!skip_wait)
    502  1.1  riastrad 		via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE);
    503  1.1  riastrad 
    504  1.1  riastrad 	vb = via_get_dma(dev_priv);
    505  1.1  riastrad 	VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
    506  1.1  riastrad 			(VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
    507  1.1  riastrad 	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
    508  1.1  riastrad 	qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
    509  1.1  riastrad 	    ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
    510  1.1  riastrad 
    511  1.1  riastrad 	cmd_addr = (addr) ? addr :
    512  1.1  riastrad 	    agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
    513  1.1  riastrad 	addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
    514  1.1  riastrad 		   (cmd_addr & HC_HAGPBpL_MASK));
    515  1.1  riastrad 	addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
    516  1.1  riastrad 
    517  1.1  riastrad 	vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
    518  1.1  riastrad 	VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, *cmd_addr_lo = addr_lo);
    519  1.1  riastrad 	return vb;
    520  1.1  riastrad }
    521  1.1  riastrad 
    522  1.1  riastrad static void via_cmdbuf_start(drm_via_private_t *dev_priv)
    523  1.1  riastrad {
    524  1.1  riastrad 	uint32_t pause_addr_lo, pause_addr_hi;
    525  1.1  riastrad 	uint32_t start_addr, start_addr_lo;
    526  1.1  riastrad 	uint32_t end_addr, end_addr_lo;
    527  1.1  riastrad 	uint32_t command;
    528  1.1  riastrad 	uint32_t agp_base;
    529  1.1  riastrad 	uint32_t ptr;
    530  1.1  riastrad 	uint32_t reader;
    531  1.1  riastrad 	int count;
    532  1.1  riastrad 
    533  1.1  riastrad 	dev_priv->dma_low = 0;
    534  1.1  riastrad 
    535  1.1  riastrad 	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
    536  1.1  riastrad 	start_addr = agp_base;
    537  1.1  riastrad 	end_addr = agp_base + dev_priv->dma_high;
    538  1.1  riastrad 
    539  1.1  riastrad 	start_addr_lo = ((HC_SubA_HAGPBstL << 24) | (start_addr & 0xFFFFFF));
    540  1.1  riastrad 	end_addr_lo = ((HC_SubA_HAGPBendL << 24) | (end_addr & 0xFFFFFF));
    541  1.1  riastrad 	command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
    542  1.1  riastrad 		   ((end_addr & 0xff000000) >> 16));
    543  1.1  riastrad 
    544  1.1  riastrad 	dev_priv->last_pause_ptr =
    545  1.1  riastrad 	    via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
    546  1.1  riastrad 			  &pause_addr_hi, &pause_addr_lo, 1) - 1;
    547  1.1  riastrad 
    548  1.1  riastrad 	via_flush_write_combine();
    549  1.1  riastrad 	(void) *(volatile uint32_t *)dev_priv->last_pause_ptr;
    550  1.1  riastrad 
    551  1.6  riastrad 	via_write(dev_priv, VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
    552  1.6  riastrad 	via_write(dev_priv, VIA_REG_TRANSPACE, command);
    553  1.6  riastrad 	via_write(dev_priv, VIA_REG_TRANSPACE, start_addr_lo);
    554  1.6  riastrad 	via_write(dev_priv, VIA_REG_TRANSPACE, end_addr_lo);
    555  1.1  riastrad 
    556  1.6  riastrad 	via_write(dev_priv, VIA_REG_TRANSPACE, pause_addr_hi);
    557  1.6  riastrad 	via_write(dev_priv, VIA_REG_TRANSPACE, pause_addr_lo);
    558  1.2  riastrad 	wmb();
    559  1.6  riastrad 	via_write(dev_priv, VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
    560  1.6  riastrad 	via_read(dev_priv, VIA_REG_TRANSPACE);
    561  1.1  riastrad 
    562  1.1  riastrad 	dev_priv->dma_diff = 0;
    563  1.1  riastrad 
    564  1.1  riastrad 	count = 10000000;
    565  1.6  riastrad 	while (!(via_read(dev_priv, 0x41c) & 0x80000000) && count--);
    566  1.1  riastrad 
    567  1.1  riastrad 	reader = *(dev_priv->hw_addr_ptr);
    568  1.1  riastrad 	ptr = ((volatile char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
    569  1.1  riastrad 	    dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
    570  1.1  riastrad 
    571  1.1  riastrad 	/*
    572  1.1  riastrad 	 * This is the difference between where we tell the
    573  1.1  riastrad 	 * command reader to pause and where it actually pauses.
    574  1.1  riastrad 	 * This differs between hw implementation so we need to
    575  1.1  riastrad 	 * detect it.
    576  1.1  riastrad 	 */
    577  1.1  riastrad 
    578  1.1  riastrad 	dev_priv->dma_diff = ptr - reader;
    579  1.1  riastrad }
    580  1.1  riastrad 
    581  1.1  riastrad static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
    582  1.1  riastrad {
    583  1.1  riastrad 	uint32_t *vb;
    584  1.1  riastrad 
    585  1.1  riastrad 	via_cmdbuf_wait(dev_priv, qwords + 2);
    586  1.1  riastrad 	vb = via_get_dma(dev_priv);
    587  1.1  riastrad 	VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16);
    588  1.1  riastrad 	via_align_buffer(dev_priv, vb, qwords);
    589  1.1  riastrad }
    590  1.1  riastrad 
    591  1.1  riastrad static inline void via_dummy_bitblt(drm_via_private_t *dev_priv)
    592  1.1  riastrad {
    593  1.1  riastrad 	uint32_t *vb = via_get_dma(dev_priv);
    594  1.1  riastrad 	SetReg2DAGP(0x0C, (0 | (0 << 16)));
    595  1.1  riastrad 	SetReg2DAGP(0x10, 0 | (0 << 16));
    596  1.1  riastrad 	SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
    597  1.1  riastrad }
    598  1.1  riastrad 
    599  1.1  riastrad static void via_cmdbuf_jump(drm_via_private_t *dev_priv)
    600  1.1  riastrad {
    601  1.1  riastrad 	uint32_t pause_addr_lo, pause_addr_hi;
    602  1.1  riastrad 	uint32_t jump_addr_lo, jump_addr_hi;
    603  1.1  riastrad 	volatile uint32_t *last_pause_ptr;
    604  1.1  riastrad 	uint32_t dma_low_save1, dma_low_save2;
    605  1.1  riastrad 
    606  1.1  riastrad 	via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
    607  1.1  riastrad 		      &jump_addr_lo, 0);
    608  1.1  riastrad 
    609  1.1  riastrad 	dev_priv->dma_wrap = dev_priv->dma_low;
    610  1.1  riastrad 
    611  1.1  riastrad 	/*
    612  1.1  riastrad 	 * Wrap command buffer to the beginning.
    613  1.1  riastrad 	 */
    614  1.1  riastrad 
    615  1.1  riastrad 	dev_priv->dma_low = 0;
    616  1.1  riastrad 	if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0)
    617  1.1  riastrad 		DRM_ERROR("via_cmdbuf_jump failed\n");
    618  1.1  riastrad 
    619  1.1  riastrad 	via_dummy_bitblt(dev_priv);
    620  1.1  riastrad 	via_dummy_bitblt(dev_priv);
    621  1.1  riastrad 
    622  1.1  riastrad 	last_pause_ptr =
    623  1.1  riastrad 	    via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
    624  1.1  riastrad 			  &pause_addr_lo, 0) - 1;
    625  1.1  riastrad 	via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
    626  1.1  riastrad 		      &pause_addr_lo, 0);
    627  1.1  riastrad 
    628  1.1  riastrad 	*last_pause_ptr = pause_addr_lo;
    629  1.1  riastrad 	dma_low_save1 = dev_priv->dma_low;
    630  1.1  riastrad 
    631  1.1  riastrad 	/*
    632  1.1  riastrad 	 * Now, set a trap that will pause the regulator if it tries to rerun the old
    633  1.1  riastrad 	 * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
    634  1.1  riastrad 	 * and reissues the jump command over PCI, while the regulator has already taken the jump
    635  1.1  riastrad 	 * and actually paused at the current buffer end).
    636  1.1  riastrad 	 * There appears to be no other way to detect this condition, since the hw_addr_pointer
    637  1.1  riastrad 	 * does not seem to get updated immediately when a jump occurs.
    638  1.1  riastrad 	 */
    639  1.1  riastrad 
    640  1.1  riastrad 	last_pause_ptr =
    641  1.1  riastrad 		via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
    642  1.1  riastrad 			      &pause_addr_lo, 0) - 1;
    643  1.1  riastrad 	via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
    644  1.1  riastrad 		      &pause_addr_lo, 0);
    645  1.1  riastrad 	*last_pause_ptr = pause_addr_lo;
    646  1.1  riastrad 
    647  1.1  riastrad 	dma_low_save2 = dev_priv->dma_low;
    648  1.1  riastrad 	dev_priv->dma_low = dma_low_save1;
    649  1.1  riastrad 	via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
    650  1.1  riastrad 	dev_priv->dma_low = dma_low_save2;
    651  1.1  riastrad 	via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
    652  1.1  riastrad }
    653  1.1  riastrad 
    654  1.1  riastrad 
    655  1.1  riastrad static void via_cmdbuf_rewind(drm_via_private_t *dev_priv)
    656  1.1  riastrad {
    657  1.1  riastrad 	via_cmdbuf_jump(dev_priv);
    658  1.1  riastrad }
    659  1.1  riastrad 
    660  1.1  riastrad static void via_cmdbuf_flush(drm_via_private_t *dev_priv, uint32_t cmd_type)
    661  1.1  riastrad {
    662  1.1  riastrad 	uint32_t pause_addr_lo, pause_addr_hi;
    663  1.1  riastrad 
    664  1.1  riastrad 	via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
    665  1.1  riastrad 	via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
    666  1.1  riastrad }
    667  1.1  riastrad 
    668  1.1  riastrad static void via_cmdbuf_pause(drm_via_private_t *dev_priv)
    669  1.1  riastrad {
    670  1.1  riastrad 	via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
    671  1.1  riastrad }
    672  1.1  riastrad 
    673  1.1  riastrad static void via_cmdbuf_reset(drm_via_private_t *dev_priv)
    674  1.1  riastrad {
    675  1.1  riastrad 	via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP);
    676  1.1  riastrad 	via_wait_idle(dev_priv);
    677  1.1  riastrad }
    678  1.1  riastrad 
    679  1.1  riastrad /*
    680  1.1  riastrad  * User interface to the space and lag functions.
    681  1.1  riastrad  */
    682  1.1  riastrad 
    683  1.1  riastrad static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *file_priv)
    684  1.1  riastrad {
    685  1.1  riastrad 	drm_via_cmdbuf_size_t *d_siz = data;
    686  1.1  riastrad 	int ret = 0;
    687  1.1  riastrad 	uint32_t tmp_size, count;
    688  1.1  riastrad 	drm_via_private_t *dev_priv;
    689  1.1  riastrad 
    690  1.1  riastrad 	DRM_DEBUG("\n");
    691  1.1  riastrad 	LOCK_TEST_WITH_RETURN(dev, file_priv);
    692  1.1  riastrad 
    693  1.1  riastrad 	dev_priv = (drm_via_private_t *) dev->dev_private;
    694  1.1  riastrad 
    695  1.1  riastrad 	if (dev_priv->ring.virtual_start == NULL) {
    696  1.1  riastrad 		DRM_ERROR("called without initializing AGP ring buffer.\n");
    697  1.1  riastrad 		return -EFAULT;
    698  1.1  riastrad 	}
    699  1.1  riastrad 
    700  1.1  riastrad 	count = 1000000;
    701  1.1  riastrad 	tmp_size = d_siz->size;
    702  1.1  riastrad 	switch (d_siz->func) {
    703  1.1  riastrad 	case VIA_CMDBUF_SPACE:
    704  1.1  riastrad 		while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size)
    705  1.1  riastrad 		       && --count) {
    706  1.1  riastrad 			if (!d_siz->wait)
    707  1.1  riastrad 				break;
    708  1.1  riastrad 		}
    709  1.1  riastrad 		if (!count) {
    710  1.1  riastrad 			DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n");
    711  1.1  riastrad 			ret = -EAGAIN;
    712  1.1  riastrad 		}
    713  1.1  riastrad 		break;
    714  1.1  riastrad 	case VIA_CMDBUF_LAG:
    715  1.1  riastrad 		while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size)
    716  1.1  riastrad 		       && --count) {
    717  1.1  riastrad 			if (!d_siz->wait)
    718  1.1  riastrad 				break;
    719  1.1  riastrad 		}
    720  1.1  riastrad 		if (!count) {
    721  1.1  riastrad 			DRM_ERROR("VIA_CMDBUF_LAG timed out.\n");
    722  1.1  riastrad 			ret = -EAGAIN;
    723  1.1  riastrad 		}
    724  1.1  riastrad 		break;
    725  1.1  riastrad 	default:
    726  1.1  riastrad 		ret = -EFAULT;
    727  1.1  riastrad 	}
    728  1.1  riastrad 	d_siz->size = tmp_size;
    729  1.1  riastrad 
    730  1.1  riastrad 	return ret;
    731  1.1  riastrad }
    732  1.1  riastrad 
    733  1.2  riastrad const struct drm_ioctl_desc via_ioctls[] = {
    734  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH),
    735  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_FREEMEM, via_mem_free, DRM_AUTH),
    736  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER),
    737  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER),
    738  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER),
    739  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH),
    740  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_DMA_INIT, via_dma_init, DRM_AUTH),
    741  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH),
    742  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_FLUSH, via_flush_ioctl, DRM_AUTH),
    743  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH),
    744  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH),
    745  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH),
    746  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_DMA_BLIT, via_dma_blit, DRM_AUTH),
    747  1.1  riastrad 	DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH)
    748  1.1  riastrad };
    749  1.1  riastrad 
    750  1.3  riastrad int via_max_ioctl = ARRAY_SIZE(via_ioctls);
    751