diff options
| -rw-r--r-- | shared-core/i915_dma.c | 69 | ||||
| -rw-r--r-- | shared-core/i915_drm.h | 32 | 
2 files changed, 93 insertions, 8 deletions
| diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 63b2a3ea..449747a2 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1,4 +1,4 @@ -/ i915_dma.c -- DMA support for the I915 -*- linux-c -*- +/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-   */  /*   * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. @@ -31,11 +31,12 @@  #include "i915_drm.h"  #include "i915_drv.h" -#define IS_I965G(dev)  (dev->pdev->device == 0x2972 || \ -			dev->pdev->device == 0x2982 || \ -			dev->pdev->device == 0x2992 || \ -			dev->pdev->device == 0x29A2 || \ -			dev->pdev->device == 0x2A02) +#define IS_I965G(dev)  (dev->pci_device == 0x2972 || \ +			dev->pci_device == 0x2982 || \ +			dev->pci_device == 0x2992 || \ +			dev->pci_device == 0x29A2 || \ +			dev->pci_device == 0x2A02) +  /* Really want an OS-independent resettable timer.  Would like to have   * this loop run for (eg) 3 sec, but have the timer reset every time @@ -776,6 +777,61 @@ static int i915_setparam(DRM_IOCTL_ARGS)  	return 0;  } +drm_i915_mmio_entry_t mmio_table[] = { +	[MMIO_REGS_PS_DEPTH_COUNT] = { +		I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE, +		0x2350, +		8 +	}	 +}; + +static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t); + +static int i915_mmio(DRM_IOCTL_ARGS) +{ +	char buf[32]; +	DRM_DEVICE; +	drm_i915_private_t *dev_priv = dev->dev_private; +	drm_i915_mmio_entry_t *e;	  +	drm_i915_mmio_t mmio; +	void __iomem *base; +	if (!dev_priv) { +		DRM_ERROR("%s called with no initialization\n", __FUNCTION__); +		return DRM_ERR(EINVAL); +	} +	DRM_COPY_FROM_USER_IOCTL(mmio, (drm_i915_setparam_t __user *) data, +				 sizeof(mmio)); + +	if (mmio.reg >= mmio_table_size) +		return DRM_ERR(EINVAL); + +	e = &mmio_table[mmio.reg]; +	base = dev_priv->mmio_map->handle + e->offset; + +        switch (mmio.read_write) { +		case I915_MMIO_READ: +			if (!(e->flag & I915_MMIO_MAY_READ)) +				return DRM_ERR(EINVAL); +			memcpy_fromio(buf, base, e->size); +			if (DRM_COPY_TO_USER(mmio.data, buf, e->size)) { +				DRM_ERROR("DRM_COPY_TO_USER failed\n"); +				return DRM_ERR(EFAULT); +			} +			break; + +		case I915_MMIO_WRITE: +			if (!(e->flag & I915_MMIO_MAY_WRITE)) +				return DRM_ERR(EINVAL); +			if(DRM_COPY_FROM_USER(buf, mmio.data, e->size)) { +				DRM_ERROR("DRM_COPY_TO_USER failed\n"); +				return DRM_ERR(EFAULT); +			} +			memcpy_toio(base, buf, e->size); +			break; +	} +	return 0; +} +  int i915_driver_load(drm_device_t *dev, unsigned long flags)  {  	/* i915 has 4 more counters */ @@ -825,6 +881,7 @@ drm_ioctl_desc_t i915_ioctls[] = {  	[DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },  	[DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH },  	[DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH}, +	[DRM_IOCTL_NR(DRM_I915_MMIO)] = {i915_mmio, DRM_AUTH},  };  int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 9eec109e..b7cffbd7 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -151,7 +151,8 @@ typedef struct _drm_i915_sarea {  #define DRM_I915_DESTROY_HEAP	0x0c  #define DRM_I915_SET_VBLANK_PIPE	0x0d  #define DRM_I915_GET_VBLANK_PIPE	0x0e -#define DRM_I915_VBLANK_SWAP	0x0f +#define DRM_I915_VBLANK_SWAP		0x0f +#define DRM_I915_MMIO			0x10  #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)  #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -170,7 +171,6 @@ typedef struct _drm_i915_sarea {  #define DRM_IOCTL_I915_GET_VBLANK_PIPE	DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)  #define DRM_IOCTL_I915_VBLANK_SWAP	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) -  /* Allow drivers to submit batchbuffers directly to hardware, relying   * on the security mechanisms provided by hardware.   */ @@ -273,4 +273,32 @@ typedef struct drm_i915_vblank_swap {  	unsigned int sequence;  } drm_i915_vblank_swap_t; +#define I915_MMIO_READ 	0 +#define I915_MMIO_WRITE 1 + +#define I915_MMIO_MAY_READ  	0x1 +#define I915_MMIO_MAY_WRITE  	0x2 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT		0 +#define MMIO_REGS_IA_VERTICES_COUNT		1 +#define MMIO_REGS_VS_INVOCATION_COUNT		2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT		3 +#define MMIO_REGS_GS_INVOCATION_COUNT		4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT		5 +#define MMIO_REGS_CL_INVOCATION_COUNT		6 +#define MMIO_REGS_PS_INVOCATION_COUNT		7 +#define MMIO_REGS_PS_DEPTH_COUNT		8 + +typedef struct drm_i915_mmio_entry { +	unsigned int flag; +	unsigned int offset; +	unsigned int size; +}drm_i915_mmio_entry_t; + +typedef struct drm_i915_mmio { +	unsigned int read_write:1; +	unsigned int reg:31; +	void __user *data;	 +} drm_i915_mmio_t; +  #endif				/* _I915_DRM_H_ */ | 
