diff options
Diffstat (limited to 'shared-core')
| -rw-r--r-- | shared-core/drm.h | 108 | ||||
| -rw-r--r-- | shared-core/i915_dma.c | 165 | ||||
| -rw-r--r-- | shared-core/i915_drm.h | 10 | ||||
| -rw-r--r-- | shared-core/i915_drv.h | 149 | ||||
| -rw-r--r-- | shared-core/i915_init.c | 329 | ||||
| -rw-r--r-- | shared-core/i915_irq.c | 85 | ||||
| -rw-r--r-- | shared-core/i915_mem.c | 22 | ||||
| -rw-r--r-- | shared-core/radeon_cp.c | 25 | ||||
| -rw-r--r-- | shared-core/radeon_drm.h | 9 | ||||
| -rw-r--r-- | shared-core/radeon_drv.h | 51 | ||||
| -rw-r--r-- | shared-core/radeon_irq.c | 20 | 
11 files changed, 763 insertions, 210 deletions
| diff --git a/shared-core/drm.h b/shared-core/drm.h index 4059a6fb..b79f7a65 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -249,7 +249,8 @@ enum drm_map_flags {  	_DRM_KERNEL = 0x08,	     /**< kernel requires access */  	_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */  	_DRM_CONTAINS_LOCK = 0x20,   /**< SHM page that contains lock */ -	_DRM_REMOVABLE = 0x40	     /**< Removable mapping */ +	_DRM_REMOVABLE = 0x40,	     /**< Removable mapping */ +        _DRM_DRIVER = 0x80           /**< Driver will take care of it */  };  struct drm_ctx_priv_map { @@ -890,6 +891,99 @@ struct drm_mm_init_arg {  	uint64_t p_size;  }; +/* + * Drm mode setting + */ +#define DRM_DISPLAY_INFO_LEN 32 +#define DRM_OUTPUT_NAME_LEN 32 +#define DRM_DISPLAY_MODE_LEN 32 + +struct drm_mode_modeinfo { + +	unsigned int id; + +	unsigned int clock; +	unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew; +	unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan; + +	unsigned int vrefresh; /* vertical refresh * 1000 */ + +	unsigned int flags; + +	char name[DRM_DISPLAY_MODE_LEN]; +}; + +struct drm_mode_card_res { + +	int count_fbs; +	unsigned int __user *fb_id; + +	int count_crtcs; +	unsigned int __user *crtc_id; + +	int count_outputs; +	unsigned int __user *output_id; + +	int count_modes; +        struct drm_mode_modeinfo __user *modes; + +}; + +struct drm_mode_crtc { +	unsigned int crtc_id; /**< Id */ +	unsigned int fb_id; /**< Id of framebuffer */ + +	int x, y; /**< Position on the frameuffer */ + +	unsigned int mode; /**< Current mode used */ + +	int count_outputs; +	unsigned int outputs; /**< Outputs that are connected */ + +	int count_possibles; +	unsigned int possibles; /**< Outputs that can be connected */ + +	unsigned int __user *set_outputs; /**< Outputs to be connected */ + +	int gamma_size; + +}; + +struct drm_mode_get_output { + +	unsigned int output; /**< Id */ +	unsigned int crtc; /**< Id of crtc */ +	unsigned char name[DRM_OUTPUT_NAME_LEN]; + +	unsigned int connection; +	unsigned int mm_width, mm_height; /**< HxW in millimeters */ +	unsigned int subpixel; + +	int count_crtcs; +	unsigned int crtcs; /**< possible crtc to connect to */ + +	int count_clones; +	unsigned int clones; /**< list of clones */ + +	int count_modes; +	unsigned int __user *modes; /**< list of modes it supports */ + +}; + +struct drm_mode_fb_cmd { +        unsigned int buffer_id; +        unsigned int width, height; +        unsigned int pitch; +        unsigned int bpp; +        unsigned int handle; +	unsigned int depth; +}; + +struct drm_mode_mode_cmd { +	unsigned int output_id; +	unsigned int mode_id; +}; +  /**   * \name Ioctls Definitions   */ @@ -982,6 +1076,18 @@ struct drm_mm_init_arg {  #define DRM_IOCTL_BO_VERSION          DRM_IOR(0xd6, struct drm_bo_version_arg) +#define DRM_IOCTL_MODE_GETRESOURCES     DRM_IOWR(0xA0, struct drm_mode_card_res) +#define DRM_IOCTL_MODE_GETCRTC          DRM_IOWR(0xA1, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_GETOUTPUT        DRM_IOWR(0xA2, struct drm_mode_get_output) +#define DRM_IOCTL_MODE_SETCRTC          DRM_IOWR(0xA3, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_ADDFB            DRM_IOWR(0xA4, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB             DRM_IOWR(0xA5, unsigned int) +#define DRM_IOCTL_MODE_GETFB            DRM_IOWR(0xA6, struct drm_mode_fb_cmd) + +#define DRM_IOCTL_MODE_ADDMODE         DRM_IOWR(0xA7, struct drm_mode_modeinfo) +#define DRM_IOCTL_MODE_RMMODE          DRM_IOWR(0xA8, unsigned int) +#define DRM_IOCTL_MODE_ATTACHMODE      DRM_IOWR(0xA9, struct drm_mode_mode_cmd) +#define DRM_IOCTL_MODE_DETACHMODE      DRM_IOWR(0xAA, struct drm_mode_mode_cmd)  /*@}*/  /** diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 18c3f0f0..44a3d786 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -38,8 +38,8 @@   */  int i915_wait_ring(struct drm_device * dev, int n, const char *caller)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_ring_buffer_t *ring = &(dev_priv->ring); +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_ring_buffer *ring = &(dev_priv->ring);  	u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;  	int i; @@ -65,8 +65,8 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)  void i915_kernel_lost_context(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_ring_buffer_t *ring = &(dev_priv->ring); +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_ring_buffer *ring = &(dev_priv->ring);  	ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;  	ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR; @@ -78,9 +78,8 @@ void i915_kernel_lost_context(struct drm_device * dev)  		dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;  } -static int i915_dma_cleanup(struct drm_device * dev) +int i915_dma_cleanup(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = dev->dev_private;  	/* Make sure interrupts are disabled here because the uninstall ioctl  	 * may not have been called from userspace and after dev_private  	 * is freed, it's too late. @@ -88,32 +87,12 @@ static int i915_dma_cleanup(struct drm_device * dev)  	if (dev->irq)  		drm_irq_uninstall(dev); -	if (dev_priv->ring.virtual_start) { -		drm_core_ioremapfree(&dev_priv->ring.map, dev); -		dev_priv->ring.virtual_start = 0; -		dev_priv->ring.map.handle = 0; -		dev_priv->ring.map.size = 0; -	} - -	if (dev_priv->status_page_dmah) { -		drm_pci_free(dev, dev_priv->status_page_dmah); -		dev_priv->status_page_dmah = NULL; -		/* Need to rewrite hardware status page */ -		I915_WRITE(0x02080, 0x1ffff000); -	} - -	if (dev_priv->status_gfx_addr) { -		dev_priv->status_gfx_addr = 0; -		drm_core_ioremapfree(&dev_priv->hws_map, dev); -		I915_WRITE(0x02080, 0x1ffff000); -	} -  	return 0;  }  static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	dev_priv->sarea = drm_getsarea(dev);  	if (!dev_priv->sarea) { @@ -198,7 +177,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)  static int i915_dma_resume(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	DRM_DEBUG("%s\n", __FUNCTION__); @@ -237,7 +216,7 @@ static int i915_dma_resume(struct drm_device * dev)  static int i915_dma_init(struct drm_device *dev, void *data,  			 struct drm_file *file_priv)  { -	drm_i915_init_t *init = data; +	struct drm_i915_init *init = data;  	int retcode = 0;  	switch (init->func) { @@ -337,7 +316,7 @@ static int validate_cmd(int cmd)  static int i915_emit_cmds(struct drm_device * dev, int __user * buffer,  			  int dwords)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	int i;  	RING_LOCALS; @@ -378,7 +357,7 @@ static int i915_emit_box(struct drm_device * dev,  			 struct drm_clip_rect __user * boxes,  			 int i, int DR1, int DR4)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_clip_rect box;  	RING_LOCALS; @@ -419,7 +398,7 @@ static int i915_emit_box(struct drm_device * dev,  void i915_emit_breadcrumb(struct drm_device *dev)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	RING_LOCALS;  	if (++dev_priv->counter > BREADCRUMB_MASK) { @@ -440,7 +419,7 @@ void i915_emit_breadcrumb(struct drm_device *dev)  int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	uint32_t flush_cmd = CMD_MI_FLUSH;  	RING_LOCALS; @@ -460,10 +439,10 @@ int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)  static int i915_dispatch_cmdbuffer(struct drm_device * dev, -				   drm_i915_cmdbuffer_t * cmd) +				   struct drm_i915_cmdbuffer * cmd)  {  #ifdef I915_HAVE_FENCE -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  #endif  	int nbox = cmd->num_cliprects;  	int i = 0, count, ret; @@ -500,7 +479,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,  static int i915_dispatch_batchbuffer(struct drm_device * dev,  				     drm_i915_batchbuffer_t * batch)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_clip_rect __user *boxes = batch->cliprects;  	int nbox = batch->num_cliprects;  	int i = 0, count; @@ -553,7 +532,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,  static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	u32 num_pages, current_page, next_page, dspbase;  	int shift = 2 * plane, x, y;  	RING_LOCALS; @@ -605,7 +584,7 @@ static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)  void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	int i;  	DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n", @@ -627,7 +606,7 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)  static int i915_quiescent(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	i915_kernel_lost_context(dev);  	return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); @@ -645,7 +624,7 @@ static int i915_flush_ioctl(struct drm_device *dev, void *data,  static int i915_batchbuffer(struct drm_device *dev, void *data,  			    struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)  	    dev_priv->sarea_priv;  	drm_i915_batchbuffer_t *batch = data; @@ -675,10 +654,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,  static int i915_cmdbuffer(struct drm_device *dev, void *data,  			  struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; -	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; +	struct drm_i915_sarea *sarea_priv = (struct drm_i915_sarea *)  	    dev_priv->sarea_priv; -	drm_i915_cmdbuffer_t *cmdbuf = data; +	struct drm_i915_cmdbuffer *cmdbuf = data;  	int ret;  	DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", @@ -985,11 +964,11 @@ out_err:  static int i915_execbuffer(struct drm_device *dev, void *data,  			   struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)  		dev_priv->sarea_priv;  	struct drm_i915_execbuffer *exec_buf = data; -	struct _drm_i915_batchbuffer *batch = &exec_buf->batch; +	struct drm_i915_batchbuffer *batch = &exec_buf->batch;  	struct drm_fence_arg *fence_arg = &exec_buf->fence_arg;  	int num_buffers;  	int ret; @@ -1088,14 +1067,14 @@ out_free:  }  #endif -static int i915_do_cleanup_pageflip(struct drm_device * dev) +int i915_do_cleanup_pageflip(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;  	DRM_DEBUG("%s\n", __FUNCTION__); -	for (i = 0, planes = 0; i < 2; i++) +	for (i = 0, planes = 0; i < 2; i++) {  		if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {  			dev_priv->sarea_priv->pf_current_page =  				(dev_priv->sarea_priv->pf_current_page & @@ -1103,6 +1082,7 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev)  			planes |= 1 << i;  		} +	}  	if (planes)  		i915_dispatch_flip(dev, planes, 0); @@ -1112,7 +1092,7 @@ static int i915_do_cleanup_pageflip(struct drm_device * dev)  static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv)  { -	drm_i915_flip_t *param = data; +	struct drm_i915_flip *param = data;  	DRM_DEBUG("%s\n", __FUNCTION__); @@ -1134,8 +1114,8 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *f  static int i915_getparam(struct drm_device *dev, void *data,  			 struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_getparam_t *param = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_getparam *param = data;  	int value;  	if (!dev_priv) { @@ -1169,7 +1149,7 @@ static int i915_getparam(struct drm_device *dev, void *data,  static int i915_setparam(struct drm_device *dev, void *data,  			 struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	drm_i915_setparam_t *param = data;  	if (!dev_priv) { @@ -1209,7 +1189,7 @@ static int i915_mmio(struct drm_device *dev, void *data,  		     struct drm_file *file_priv)  {  	uint32_t buf[8]; -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	drm_i915_mmio_entry_t *e;	   	drm_i915_mmio_t *mmio = data;  	void __iomem *base; @@ -1255,7 +1235,7 @@ static int i915_mmio(struct drm_device *dev, void *data,  static int i915_set_status_page(struct drm_device *dev, void *data,  				struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	drm_i915_hws_addr_t *hws = data;  	if (!dev_priv) { @@ -1283,80 +1263,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data,  	dev_priv->hw_status_page = dev_priv->hws_map.handle;  	memset(dev_priv->hw_status_page, 0, PAGE_SIZE); -	I915_WRITE(0x02080, dev_priv->status_gfx_addr); +	I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr);  	DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",  			dev_priv->status_gfx_addr);  	DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);  	return 0;  } -int i915_driver_load(struct drm_device *dev, unsigned long flags) -{ -	struct drm_i915_private *dev_priv = dev->dev_private; -	unsigned long base, size; -	int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; - -	/* i915 has 4 more counters */ -	dev->counters += 4; -	dev->types[6] = _DRM_STAT_IRQ; -	dev->types[7] = _DRM_STAT_PRIMARY; -	dev->types[8] = _DRM_STAT_SECONDARY; -	dev->types[9] = _DRM_STAT_DMA; - -	dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); -	if (dev_priv == NULL) -		return -ENOMEM; - -	memset(dev_priv, 0, sizeof(drm_i915_private_t)); - -	dev->dev_private = (void *)dev_priv; - -	/* Add register map (needed for suspend/resume) */ -	base = drm_get_resource_start(dev, mmio_bar); -	size = drm_get_resource_len(dev, mmio_bar); - -	ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL, -			 &dev_priv->mmio_map); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) -	intel_init_chipset_flush_compat(dev); -#endif -	return ret; -} - -int i915_driver_unload(struct drm_device *dev) -{ -	struct drm_i915_private *dev_priv = dev->dev_private; - -	if (dev_priv->mmio_map) -		drm_rmmap(dev, dev_priv->mmio_map); - -	drm_free(dev->dev_private, sizeof(drm_i915_private_t), -		 DRM_MEM_DRIVER); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) -	intel_fini_chipset_flush_compat(dev); -#endif -	return 0; -} - -void i915_driver_lastclose(struct drm_device * dev) -{ -	drm_i915_private_t *dev_priv = dev->dev_private; - -	if (drm_getsarea(dev) && dev_priv->sarea_priv) -		i915_do_cleanup_pageflip(dev); -	if (dev_priv->agp_heap) -		i915_mem_takedown(&(dev_priv->agp_heap)); - -	i915_dma_cleanup(dev); -} - -void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) -{ -	drm_i915_private_t *dev_priv = dev->dev_private; -	i915_mem_release(dev, file_priv, dev_priv->agp_heap); -} -  struct drm_ioctl_desc i915_ioctls[] = {  	DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),  	DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), @@ -1399,10 +1312,4 @@ int i915_driver_device_is_agp(struct drm_device * dev)  	return 1;  } -int i915_driver_firstopen(struct drm_device *dev) -{ -#ifdef I915_HAVE_BUFFER -	drm_bo_driver_init(dev); -#endif -	return 0; -} + diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index a6c3cf30..e517fac0 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -39,7 +39,7 @@  				 * of chars for next/prev indices */  #define I915_LOG_MIN_TEX_REGION_SIZE 14 -typedef struct _drm_i915_init { +typedef struct drm_i915_init {  	enum {  		I915_INIT_DMA = 0x01,  		I915_CLEANUP_DMA = 0x02, @@ -63,7 +63,7 @@ typedef struct _drm_i915_init {  	unsigned int chipset;  } drm_i915_init_t; -typedef struct _drm_i915_sarea { +typedef struct drm_i915_sarea {  	struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];  	int last_upload;	/* last time texture was uploaded */  	int last_enqueue;	/* last time a buffer was enqueued */ @@ -195,7 +195,7 @@ typedef struct drm_i915_flip {  /* Allow drivers to submit batchbuffers directly to hardware, relying   * on the security mechanisms provided by hardware.   */ -typedef struct _drm_i915_batchbuffer { +typedef struct drm_i915_batchbuffer {  	int start;		/* agp offset */  	int used;		/* nr bytes in use */  	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */ @@ -207,7 +207,7 @@ typedef struct _drm_i915_batchbuffer {  /* As above, but pass a pointer to userspace buffer which can be   * validated by the kernel prior to sending to hardware.   */ -typedef struct _drm_i915_cmdbuffer { +typedef struct drm_i915_cmdbuffer {  	char __user *buf;	/* pointer to userspace command buffer */  	int sz;			/* nr bytes in buf */  	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */ @@ -358,7 +358,7 @@ struct drm_i915_op_arg {  struct drm_i915_execbuffer {  	uint64_t ops_list;  	uint32_t num_buffers; -	struct _drm_i915_batchbuffer batch; +	struct drm_i915_batchbuffer batch;  	struct drm_fence_arg fence_arg;  }; diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 6ff34eb7..02d0ba34 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -70,7 +70,7 @@  #define I915_MAX_VALIDATE_BUFFERS 4096  #endif -typedef struct _drm_i915_ring_buffer { +struct drm_i915_ring_buffer {  	int tail_mask;  	unsigned long Start;  	unsigned long End; @@ -80,7 +80,7 @@ typedef struct _drm_i915_ring_buffer {  	int tail;  	int space;  	drm_local_map_t map; -} drm_i915_ring_buffer_t; +};  struct mem_block {  	struct mem_block *next; @@ -90,22 +90,26 @@ struct mem_block {  	struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */  }; -typedef struct _drm_i915_vbl_swap { +struct drm_i915_vbl_swap {  	struct list_head head;  	drm_drawable_t drw_id;  	unsigned int plane;  	unsigned int sequence;  	int flip; -} drm_i915_vbl_swap_t; +}; -typedef struct drm_i915_private { +struct drm_i915_private { +	struct drm_buffer_object *ring_buffer;  	drm_local_map_t *sarea;  	drm_local_map_t *mmio_map; -	drm_i915_sarea_t *sarea_priv; -	drm_i915_ring_buffer_t ring; +	unsigned long mmiobase; +	unsigned long mmiolen; + +	struct drm_i915_sarea *sarea_priv; +	struct drm_i915_ring_buffer ring; -	drm_dma_handle_t *status_page_dmah; +	struct drm_dma_handle *status_page_dmah;  	void *hw_status_page;  	dma_addr_t dma_status_page;  	uint32_t counter; @@ -143,9 +147,14 @@ typedef struct drm_i915_private {  #endif  	DRM_SPINTYPE swaps_lock; -	drm_i915_vbl_swap_t vbl_swaps; +	struct drm_i915_vbl_swap vbl_swaps;  	unsigned int swaps_pending; +	/* LVDS info */ +	int backlight_duty_cycle;  /* restore backlight to this value */ +	bool panel_wants_dither; +	struct drm_display_mode *panel_fixed_mode; +   	/* Register state */  	u8 saveLBB;   	u32 saveDSPACNTR; @@ -224,7 +233,7 @@ typedef struct drm_i915_private {  	u8 saveDACMASK;  	u8 saveDACDATA[256*3]; /* 256 3-byte colors */  	u8 saveCR[36]; -} drm_i915_private_t; +};  enum intel_chip_family {  	CHIP_I8XX = 0x01, @@ -239,7 +248,7 @@ extern int i915_max_ioctl;  				/* i915_dma.c */  extern void i915_kernel_lost_context(struct drm_device * dev);  extern int i915_driver_load(struct drm_device *, unsigned long flags); -extern int i915_driver_unload(struct drm_device *); +extern int i915_driver_unload(struct drm_device *dev);  extern void i915_driver_lastclose(struct drm_device * dev);  extern void i915_driver_preclose(struct drm_device *dev,  				 struct drm_file *file_priv); @@ -250,6 +259,8 @@ extern void i915_emit_breadcrumb(struct drm_device *dev);  extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync);  extern int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush);  extern int i915_driver_firstopen(struct drm_device *dev); +extern int i915_do_cleanup_pageflip(struct drm_device *dev); +extern int i915_dma_cleanup(struct drm_device *dev);  /* i915_irq.c */  extern int i915_irq_emit(struct drm_device *dev, void *data, @@ -257,6 +268,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,  extern int i915_irq_wait(struct drm_device *dev, void *data,  			 struct drm_file *file_priv); +extern void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe);  extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);  extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);  extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); @@ -268,8 +280,9 @@ extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,  extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,  				struct drm_file *file_priv);  extern int i915_emit_irq(struct drm_device * dev); -extern void i915_user_irq_on(drm_i915_private_t *dev_priv); -extern void i915_user_irq_off(drm_i915_private_t *dev_priv); +extern void i915_user_irq_on(struct drm_i915_private *dev_priv); +extern void i915_user_irq_off(struct drm_i915_private *dev_priv); +extern void i915_enable_interrupt (struct drm_device *dev);  extern int i915_vblank_swap(struct drm_device *dev, void *data,  			    struct drm_file *file_priv); @@ -318,6 +331,12 @@ extern void intel_init_chipset_flush_compat(struct drm_device *dev);  extern void intel_fini_chipset_flush_compat(struct drm_device *dev);  #endif + +/* modesetting */ +extern void intel_modeset_init(struct drm_device *dev); +extern void intel_modeset_cleanup(struct drm_device *dev); + +  #define I915_READ(reg)          DRM_READ32(dev_priv->mmio_map, (reg))  #define I915_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, (reg), (val))  #define I915_READ16(reg) 	DRM_READ16(dev_priv->mmio_map, (reg)) @@ -355,8 +374,31 @@ extern void intel_fini_chipset_flush_compat(struct drm_device *dev);  	I915_WRITE(LP_RING + RING_TAIL, outring);			\  } while(0) +#define MI_NOOP	(0x00 << 23) +  extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); +/* + * The Bridge device's PCI config space has information about the + * fb aperture size and the amount of pre-reserved memory. + */ +#define INTEL_GMCH_CTRL		0x52 +#define INTEL_GMCH_ENABLED	0x4 +#define INTEL_GMCH_MEM_MASK	0x1 +#define INTEL_GMCH_MEM_64M	0x1 +#define INTEL_GMCH_MEM_128M	0 + +#define INTEL_855_GMCH_GMS_MASK		(0x7 << 4) +#define INTEL_855_GMCH_GMS_DISABLED	(0x0 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_1M	(0x1 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_4M	(0x2 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_8M	(0x3 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_16M	(0x4 << 4) +#define INTEL_855_GMCH_GMS_STOLEN_32M	(0x5 << 4) + +#define INTEL_915G_GMCH_GMS_STOLEN_48M	(0x6 << 4) +#define INTEL_915G_GMCH_GMS_STOLEN_64M	(0x7 << 4) +  /* Extended config space */  #define LBB 0xf4 @@ -423,6 +465,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define BB1_UNPROTECTED       (0<<0)  #define BB2_END_ADDR_MASK     (~0x7) +#define I915REG_HWS_PGA		0x02080 +  /* Framebuffer compression */  #define FBC_CFB_BASE		0x03200 /* 4k page aligned */  #define FBC_LL_BASE		0x03204 /* 4k page aligned */ @@ -473,6 +517,63 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define I915_VBLANK_INTERRUPT_ENABLE	(1UL<<17)  #define I915_VBLANK_CLEAR		(1UL<<1) +#define GPIOA			0x5010 +#define GPIOB			0x5014 +#define GPIOC			0x5018 +#define GPIOD			0x501c +#define GPIOE			0x5020 +#define GPIOF			0x5024 +#define GPIOG			0x5028 +#define GPIOH			0x502c +# define GPIO_CLOCK_DIR_MASK		(1 << 0) +# define GPIO_CLOCK_DIR_IN		(0 << 1) +# define GPIO_CLOCK_DIR_OUT		(1 << 1) +# define GPIO_CLOCK_VAL_MASK		(1 << 2) +# define GPIO_CLOCK_VAL_OUT		(1 << 3) +# define GPIO_CLOCK_VAL_IN		(1 << 4) +# define GPIO_CLOCK_PULLUP_DISABLE	(1 << 5) +# define GPIO_DATA_DIR_MASK		(1 << 8) +# define GPIO_DATA_DIR_IN		(0 << 9) +# define GPIO_DATA_DIR_OUT		(1 << 9) +# define GPIO_DATA_VAL_MASK		(1 << 10) +# define GPIO_DATA_VAL_OUT		(1 << 11) +# define GPIO_DATA_VAL_IN		(1 << 12) +# define GPIO_DATA_PULLUP_DISABLE	(1 << 13) + +/* p317, 319 + */ +#define VCLK2_VCO_M        0x6008 /* treat as 16 bit? (includes msbs) */ +#define VCLK2_VCO_N        0x600a +#define VCLK2_VCO_DIV_SEL  0x6012 + +#define VCLK_DIVISOR_VGA0   0x6000 +#define VCLK_DIVISOR_VGA1   0x6004 +#define VCLK_POST_DIV	    0x6010 +/** Selects a post divisor of 4 instead of 2. */ +# define VGA1_PD_P2_DIV_4	(1 << 15) +/** Overrides the p2 post divisor field */ +# define VGA1_PD_P1_DIV_2	(1 << 13) +# define VGA1_PD_P1_SHIFT	8 +/** P1 value is 2 greater than this field */ +# define VGA1_PD_P1_MASK	(0x1f << 8) +/** Selects a post divisor of 4 instead of 2. */ +# define VGA0_PD_P2_DIV_4	(1 << 7) +/** Overrides the p2 post divisor field */ +# define VGA0_PD_P1_DIV_2	(1 << 5) +# define VGA0_PD_P1_SHIFT	0 +/** P1 value is 2 greater than this field */ +# define VGA0_PD_P1_MASK	(0x1f << 0) + +#define POST_DIV_SELECT        0x70 +#define POST_DIV_1             0x00 +#define POST_DIV_2             0x10 +#define POST_DIV_4             0x20 +#define POST_DIV_8             0x30 +#define POST_DIV_16            0x40 +#define POST_DIV_32            0x50 +#define VCO_LOOP_DIV_BY_4M     0x00 +#define VCO_LOOP_DIV_BY_16M    0x04 +  #define SRX_INDEX		0x3c4  #define SRX_DATA		0x3c5  #define SR01			1 @@ -481,6 +582,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define PPCR			0x61204  #define PPCR_ON			(1<<0) +#define DVOA			0x61120 +#define DVOA_ON			(1<<31)  #define DVOB			0x61140  #define DVOB_ON			(1<<31)  #define DVOC			0x61160 @@ -637,8 +740,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define SRC_COPY_BLT_CMD                ((2<<29)|(0x43<<22)|4)  #define XY_SRC_COPY_BLT_CMD		((2<<29)|(0x53<<22)|6) +#define XY_MONO_SRC_COPY_IMM_BLT	((2<<29)|(0x71<<22)|5)  #define XY_SRC_COPY_BLT_WRITE_ALPHA	(1<<21)  #define XY_SRC_COPY_BLT_WRITE_RGB	(1<<20) +#define   BLT_DEPTH_8			(0<<24) +#define   BLT_DEPTH_16_565		(1<<24) +#define   BLT_DEPTH_16_1555		(2<<24) +#define   BLT_DEPTH_32			(3<<24) +#define   BLT_ROP_GXCOPY		(0xcc<<16)  #define MI_BATCH_BUFFER 	((0x30<<23)|1)  #define MI_BATCH_BUFFER_START 	(0x31<<23) @@ -680,6 +789,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)  #define BLC_PWM_CTL2		0x61250 +  /**   * This is the most significant 15 bits of the number of backlight cycles in a   * complete cycle of the modulated backlight control. @@ -1119,13 +1229,17 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);   */  #define SWF0			0x71410 +#define SWF1			0x71414 +#define SWF2			0x71418 +#define SWF3			0x7141c +#define SWF4			0x71420 +#define SWF5			0x71424 +#define SWF6			0x71428 -/* - * 855 scratch registers. - */  #define SWF10			0x70410 -  #define SWF30			0x72414 +#define SWF31			0x72418 +#define SWF32			0x7241c  /*   * Overlay registers.  These are overlay registers accessed via MMIO. @@ -1142,6 +1256,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define OGAMC2			0x3001c  #define OGAMC1			0x30020  #define OGAMC0			0x30024 +  /*   * Palette registers   */ diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c new file mode 100644 index 00000000..3b43c722 --- /dev/null +++ b/shared-core/i915_init.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2007 Intel Corporation + *   Jesse Barnes <jesse.barnes@intel.com> + * + * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> + *                   2004 Sylvain Meyer + * + * GPL/BSD dual license + */ +#include "drmP.h" +#include "drm.h" +#include "drm_sarea.h" +#include "i915_drm.h" +#include "i915_drv.h" + +/** + * i915_probe_agp - get AGP bootup configuration + * @pdev: PCI device + * @aperture_size: returns AGP aperture configured size + * @preallocated_size: returns size of BIOS preallocated AGP space + * + * Since Intel integrated graphics are UMA, the BIOS has to set aside + * some RAM for the framebuffer at early boot.  This code figures out + * how much was set aside so we can use it for our own purposes. + */ +int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, +		   unsigned long *preallocated_size) +{ +	struct pci_dev *bridge_dev; +	u16 tmp = 0; +	unsigned long overhead; + +	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); +	if (!bridge_dev) { +		DRM_ERROR("bridge device not found\n"); +		return -1; +	} + +	/* Get the fb aperture size and "stolen" memory amount. */ +	pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); +	pci_dev_put(bridge_dev); + +	*aperture_size = 1024 * 1024; +	*preallocated_size = 1024 * 1024; + +	switch (pdev->device) { +	case PCI_DEVICE_ID_INTEL_82830_CGC: +	case PCI_DEVICE_ID_INTEL_82845G_IG: +	case PCI_DEVICE_ID_INTEL_82855GM_IG: +	case PCI_DEVICE_ID_INTEL_82865_IG: +		if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) +			*aperture_size *= 64; +		else +			*aperture_size *= 128; +		break; +	default: +		/* 9xx supports large sizes, just look at the length */ +		*aperture_size = pci_resource_len(pdev, 2); +		break; +	} + +	/* +	 * Some of the preallocated space is taken by the GTT +	 * and popup.  GTT is 1K per MB of aperture size, and popup is 4K. +	 */ +	overhead = (*aperture_size / 1024) + 4096; +	switch (tmp & INTEL_855_GMCH_GMS_MASK) { +	case INTEL_855_GMCH_GMS_STOLEN_1M: +		break; /* 1M already */ +	case INTEL_855_GMCH_GMS_STOLEN_4M: +		*preallocated_size *= 4; +		break; +	case INTEL_855_GMCH_GMS_STOLEN_8M: +		*preallocated_size *= 8; +		break; +	case INTEL_855_GMCH_GMS_STOLEN_16M: +		*preallocated_size *= 16; +		break; +	case INTEL_855_GMCH_GMS_STOLEN_32M: +		*preallocated_size *= 32; +		break; +	case INTEL_915G_GMCH_GMS_STOLEN_48M: +		*preallocated_size *= 48; +		break; +	case INTEL_915G_GMCH_GMS_STOLEN_64M: +		*preallocated_size *= 64; +		break; +	case INTEL_855_GMCH_GMS_DISABLED: +		DRM_ERROR("video memory is disabled\n"); +		return -1; +	default: +		DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", +			tmp & INTEL_855_GMCH_GMS_MASK); +		return -1; +	} +	*preallocated_size -= overhead; + +	return 0; +} + +/** + * i915_driver_load - setup chip and create an initial config + * @dev: DRM device + * @flags: startup flags + * + * The driver load routine has to do several things: + *   - drive output discovery via intel_modeset_init() + *   - initialize the memory manager + *   - allocate initial config memory + *   - setup the DRM framebuffer with the allocated memory + */ +int i915_driver_load(struct drm_device *dev, unsigned long flags) +{ +	struct drm_i915_private *dev_priv; +	unsigned long agp_size, prealloc_size; +	unsigned long sareapage; +	int size, ret; + +	dev_priv = drm_alloc(sizeof(struct drm_i915_private), DRM_MEM_DRIVER); +	if (dev_priv == NULL) +		return -ENOMEM; + +	memset(dev_priv, 0, sizeof(struct drm_i915_private)); +	dev->dev_private = (void *)dev_priv; +//	dev_priv->flags = flags; + +	/* i915 has 4 more counters */ +	dev->counters += 4; +	dev->types[6] = _DRM_STAT_IRQ; +	dev->types[7] = _DRM_STAT_PRIMARY; +	dev->types[8] = _DRM_STAT_SECONDARY; +	dev->types[9] = _DRM_STAT_DMA; + +	if (IS_I9XX(dev)) { +		dev_priv->mmiobase = drm_get_resource_start(dev, 0); +		dev_priv->mmiolen = drm_get_resource_len(dev, 0); +		dev->mode_config.fb_base = +			drm_get_resource_start(dev, 2) & 0xff000000; +	} else if (drm_get_resource_start(dev, 1)) { +		dev_priv->mmiobase = drm_get_resource_start(dev, 1); +		dev_priv->mmiolen = drm_get_resource_len(dev, 1); +		dev->mode_config.fb_base = +			drm_get_resource_start(dev, 0) & 0xff000000; +	} else { +		DRM_ERROR("Unable to find MMIO registers\n"); +		return -ENODEV; +	} + +	DRM_DEBUG("fb_base: 0x%08lx\n", dev->mode_config.fb_base); + +	ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, +			 _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map); +	if (ret != 0) { +		DRM_ERROR("Cannot add mapping for MMIO registers\n"); +		return ret; +	} + +	/* prebuild the SAREA */ +	sareapage = max(SAREA_MAX, PAGE_SIZE); +	ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER, +			 &dev_priv->sarea); +	if (ret) { +		DRM_ERROR("SAREA setup failed\n"); +		return ret; +	} + +	init_waitqueue_head(&dev->lock.lock_queue); + +	/* FIXME: assume sarea_priv is right after SAREA */ +        dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(struct drm_sarea); + +	/* +	 * Initialize the memory manager for local and AGP space +	 */ +	drm_bo_driver_init(dev); + +	i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); +	printk("setting up %ld bytes of VRAM space\n", prealloc_size); +	printk("setting up %ld bytes of TT space\n", (agp_size - prealloc_size)); +	drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT); +	drm_bo_init_mm(dev, DRM_BO_MEM_TT, prealloc_size >> PAGE_SHIFT, (agp_size - prealloc_size) >> PAGE_SHIFT); + +	I915_WRITE(LP_RING + RING_LEN, 0); +	I915_WRITE(LP_RING + RING_HEAD, 0); +	I915_WRITE(LP_RING + RING_TAIL, 0); + +	size = PRIMARY_RINGBUFFER_SIZE; +	ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel, +				       DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | +				       DRM_BO_FLAG_MEM_VRAM | +				       DRM_BO_FLAG_NO_EVICT | +				       DRM_BO_HINT_DONT_FENCE, 0, 0x1, 0, +				       &dev_priv->ring_buffer); +	if (ret < 0) { +		DRM_ERROR("Unable to allocate or pin ring buffer\n"); +		return -EINVAL; +	} + +	/* remap the buffer object properly */ +	dev_priv->ring.Start = dev_priv->ring_buffer->offset; +	dev_priv->ring.End = dev_priv->ring.Start + size; +	dev_priv->ring.Size = size; +	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; + +	/* FIXME: need wrapper with PCI mem checks */ +	ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem, +				  (void **) &dev_priv->ring.virtual_start); +	if (ret) +		DRM_ERROR("error mapping ring buffer: %d\n", ret); + +	DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start, +		  dev_priv->ring.virtual_start, dev_priv->ring.Size); + +	dev_priv->sarea_priv->pf_current_page = 0; + +	memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size); + +	I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start); +	I915_WRITE(LP_RING + RING_LEN, +		   ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) | +		   (RING_NO_REPORT | RING_VALID)); + +	/* We are using separate values as placeholders for mechanisms for +	 * private backbuffer/depthbuffer usage. +	 */ +	dev_priv->use_mi_batchbuffer_start = 0; + +	/* Allow hardware batchbuffers unless told otherwise. +	 */ +	dev_priv->allow_batchbuffer = 1; + +	/* Program Hardware Status Page */ +	if (!IS_G33(dev)) { +		dev_priv->status_page_dmah =  +			drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); + +		if (!dev_priv->status_page_dmah) { +			dev->dev_private = (void *)dev_priv; +			i915_dma_cleanup(dev); +			DRM_ERROR("Can not allocate hardware status page\n"); +			return -ENOMEM; +		} +		dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; +		dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; + +		memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + +		I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page); +	} +	DRM_DEBUG("Enabled hardware status page\n"); + +	intel_modeset_init(dev); +	drm_initial_config(dev, false); + +	return 0; +} + +int i915_driver_unload(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	if (dev_priv->ring.virtual_start) { +		drm_core_ioremapfree(&dev_priv->ring.map, dev); +	} + +	if (dev_priv->status_page_dmah) { +		drm_pci_free(dev, dev_priv->status_page_dmah); +		dev_priv->status_page_dmah = NULL; +		dev_priv->hw_status_page = NULL; +		dev_priv->dma_status_page = 0; +		/* Need to rewrite hardware status page */ +		I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); +	} + +	if (dev_priv->status_gfx_addr) { +		dev_priv->status_gfx_addr = 0; +		drm_core_ioremapfree(&dev_priv->hws_map, dev); +		I915_WRITE(I915REG_HWS_PGA, 0x1ffff000); +	} + +	I915_WRITE(LP_RING + RING_LEN, 0); + +	intel_modeset_cleanup(dev); + +	drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, +			    dev_priv->ring.virtual_start); + +	DRM_DEBUG("usage is %d\n", atomic_read(&dev_priv->ring_buffer->usage)); +	mutex_lock(&dev->struct_mutex); +	drm_bo_usage_deref_locked(&dev_priv->ring_buffer); + +	if (drm_bo_clean_mm(dev, DRM_BO_MEM_TT)) { +		DRM_ERROR("Memory manager type 3 not clean. " +			  "Delaying takedown\n"); +	} +	if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) { +		DRM_ERROR("Memory manager type 3 not clean. " +			  "Delaying takedown\n"); +	} +	mutex_unlock(&dev->struct_mutex); + +	drm_bo_driver_finish(dev); + +        DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea); +        drm_rmmap(dev, dev_priv->mmio_map); +        drm_rmmap(dev, dev_priv->sarea); + +	drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); + +	dev->dev_private = NULL; +	return 0; +} + +void i915_driver_lastclose(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	i915_do_cleanup_pageflip(dev); +	//i915_mem_takedown(&(dev_priv->agp_heap)); +	i915_dma_cleanup(dev); +} + +void i915_driver_preclose(struct drm_device *dev, struct drm_file *filp) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	//i915_mem_release(dev, filp, dev_priv->agp_heap); +} + diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index db18a895..11cb20ab 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -49,7 +49,7 @@  static int  i915_get_pipe(struct drm_device *dev, int plane)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	u32 dspcntr;  	dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); @@ -66,8 +66,8 @@ static void  i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,  			 int plane)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; -	drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private; +	struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;  	u16 x1, y1, x2, y2;  	int pf_planes = 1 << plane; @@ -111,13 +111,13 @@ i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,   */  static void i915_vblank_tasklet(struct drm_device *dev)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	struct list_head *list, *tmp, hits, *hit;  	int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;  	unsigned counter[2] = { atomic_read(&dev->vbl_received),  				atomic_read(&dev->vbl_received2) };  	struct drm_drawable_info *drw; -	drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; +	struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;  	u32 cpp = dev_priv->cpp,  offsets[3];  	u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |  				XY_SRC_COPY_BLT_WRITE_ALPHA | @@ -142,8 +142,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)  	/* Find buffer swaps scheduled for this vertical blank */  	list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { -		drm_i915_vbl_swap_t *vbl_swap = -			list_entry(list, drm_i915_vbl_swap_t, head); +		struct drm_i915_vbl_swap *vbl_swap = +			list_entry(list, struct drm_i915_vbl_swap, head);  		int pipe = i915_get_pipe(dev, vbl_swap->plane);  		if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) @@ -165,8 +165,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)  		}  		list_for_each(hit, &hits) { -			drm_i915_vbl_swap_t *swap_cmp = -				list_entry(hit, drm_i915_vbl_swap_t, head); +			struct drm_i915_vbl_swap *swap_cmp = +				list_entry(hit, struct drm_i915_vbl_swap, head);  			struct drm_drawable_info *drw_cmp =  				drm_get_drawable_info(dev, swap_cmp->drw_id); @@ -223,8 +223,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)  			lower[0] = lower[1] = sarea_priv->height;  		list_for_each(hit, &hits) { -			drm_i915_vbl_swap_t *swap_hit = -				list_entry(hit, drm_i915_vbl_swap_t, head); +			struct drm_i915_vbl_swap *swap_hit = +				list_entry(hit, struct drm_i915_vbl_swap, head);  			struct drm_clip_rect *rect;  			int num_rects, plane, front, back;  			unsigned short top, bottom; @@ -292,8 +292,8 @@ static void i915_vblank_tasklet(struct drm_device *dev)  	DRM_SPINUNLOCK(&dev->drw_lock);  	list_for_each_safe(hit, tmp, &hits) { -		drm_i915_vbl_swap_t *swap_hit = -			list_entry(hit, drm_i915_vbl_swap_t, head); +		struct drm_i915_vbl_swap *swap_hit = +			list_entry(hit, struct drm_i915_vbl_swap, head);  		list_del(hit); @@ -304,7 +304,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)  irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)  {  	struct drm_device *dev = (struct drm_device *) arg; -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	u16 temp;  	u32 pipea_stats, pipeb_stats; @@ -368,7 +368,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)  int i915_emit_irq(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	RING_LOCALS;  	i915_kernel_lost_context(dev); @@ -387,7 +387,7 @@ int i915_emit_irq(struct drm_device * dev)  } -void i915_user_irq_on(drm_i915_private_t *dev_priv) +void i915_user_irq_on(struct drm_i915_private *dev_priv)  {  	DRM_SPINLOCK(&dev_priv->user_irq_lock);  	if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ @@ -398,7 +398,7 @@ void i915_user_irq_on(drm_i915_private_t *dev_priv)  } -void i915_user_irq_off(drm_i915_private_t *dev_priv) +void i915_user_irq_off(struct drm_i915_private *dev_priv)  {  	DRM_SPINLOCK(&dev_priv->user_irq_lock);  	if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { @@ -411,7 +411,7 @@ void i915_user_irq_off(drm_i915_private_t *dev_priv)  static int i915_wait_irq(struct drm_device * dev, int irq_nr)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	int ret = 0;  	DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr, @@ -441,7 +441,7 @@ static int i915_driver_vblank_do_wait(struct drm_device *dev,  				      unsigned int *sequence,  				      atomic_t *counter)  { -	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_i915_private *dev_priv = dev->dev_private;  	unsigned int cur_vblank;  	int ret = 0; @@ -459,6 +459,19 @@ static int i915_driver_vblank_do_wait(struct drm_device *dev,  	return ret;  } +void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe) +{ +	unsigned int seq; + +	seq = pipe ? atomic_read(&dev->vbl_received2) + 1 : +		atomic_read(&dev->vbl_received) + 1; + +	if (!pipe) +		i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received); +	else +		i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received2); +} +  int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)  {  	return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received); @@ -473,8 +486,8 @@ int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)   */  int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_irq_emit_t *emit = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_irq_emit *emit = data;  	int result;  	LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -499,8 +512,8 @@ int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv  int i915_irq_wait(struct drm_device *dev, void *data,  		  struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_irq_wait_t *irqwait = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_irq_wait *irqwait = data;  	if (!dev_priv) {  		DRM_ERROR("%s called with no initialization\n", __FUNCTION__); @@ -510,9 +523,9 @@ int i915_irq_wait(struct drm_device *dev, void *data,  	return i915_wait_irq(dev, irqwait->irq_seq);  } -static void i915_enable_interrupt (struct drm_device *dev) +void i915_enable_interrupt (struct drm_device *dev)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	dev_priv->irq_enable_reg = USER_INT_FLAG;   	if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A) @@ -529,8 +542,8 @@ static void i915_enable_interrupt (struct drm_device *dev)  int i915_vblank_pipe_set(struct drm_device *dev, void *data,  			 struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_vblank_pipe_t *pipe = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_vblank_pipe *pipe = data;  	if (!dev_priv) {  		DRM_ERROR("%s called with no initialization\n", __FUNCTION__); @@ -553,8 +566,8 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,  int i915_vblank_pipe_get(struct drm_device *dev, void *data,  			 struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_vblank_pipe_t *pipe = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_vblank_pipe *pipe = data;  	u16 flag;  	if (!dev_priv) { @@ -578,9 +591,9 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,  int i915_vblank_swap(struct drm_device *dev, void *data,  		     struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_vblank_swap_t *swap = data; -	drm_i915_vbl_swap_t *vbl_swap; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_vblank_swap *swap = data; +	struct drm_i915_vbl_swap *vbl_swap;  	unsigned int pipe, seqtype, curseq, plane;  	unsigned long irqflags;  	struct list_head *list; @@ -672,7 +685,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,  	DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);  	list_for_each(list, &dev_priv->vbl_swaps.head) { -		vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); +		vbl_swap = list_entry(list, struct drm_i915_vbl_swap, head);  		if (vbl_swap->drw_id == swap->drawable &&  		    vbl_swap->plane == plane && @@ -722,7 +735,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,  */  void i915_driver_irq_preinstall(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	I915_WRITE16(I915REG_HWSTAM, 0xeffe);  	I915_WRITE16(I915REG_INT_MASK_R, 0x0); @@ -731,7 +744,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev)  void i915_driver_irq_postinstall(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	DRM_SPININIT(&dev_priv->swaps_lock, "swap");  	INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); @@ -752,7 +765,7 @@ void i915_driver_irq_postinstall(struct drm_device * dev)  void i915_driver_irq_uninstall(struct drm_device * dev)  { -	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +	struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;  	u16 temp;  	if (!dev_priv)  		return; diff --git a/shared-core/i915_mem.c b/shared-core/i915_mem.c index 5bf29a1e..2916d5a1 100644 --- a/shared-core/i915_mem.c +++ b/shared-core/i915_mem.c @@ -45,8 +45,8 @@   */  static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;  	struct drm_tex_region *list;  	unsigned shift, nr;  	unsigned start; @@ -256,7 +256,7 @@ void i915_mem_takedown(struct mem_block **heap)  	*heap = NULL;  } -static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region) +static struct mem_block **get_heap(struct drm_i915_private * dev_priv, int region)  {  	switch (region) {  	case I915_MEM_REGION_AGP: @@ -271,8 +271,8 @@ static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region)  int i915_mem_alloc(struct drm_device *dev, void *data,  		   struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_mem_alloc_t *alloc = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_mem_alloc *alloc = data;  	struct mem_block *block, **heap;  	if (!dev_priv) { @@ -309,8 +309,8 @@ int i915_mem_alloc(struct drm_device *dev, void *data,  int i915_mem_free(struct drm_device *dev, void *data,  		  struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_mem_free_t *memfree = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_mem_free *memfree = data;  	struct mem_block *block, **heap;  	if (!dev_priv) { @@ -337,8 +337,8 @@ int i915_mem_free(struct drm_device *dev, void *data,  int i915_mem_init_heap(struct drm_device *dev, void *data,  		       struct drm_file *file_priv)  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_mem_init_heap_t *initheap = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_mem_init_heap *initheap = data;  	struct mem_block **heap;  	if (!dev_priv) { @@ -361,8 +361,8 @@ int i915_mem_init_heap(struct drm_device *dev, void *data,  int i915_mem_destroy_heap( struct drm_device *dev, void *data,  			   struct drm_file *file_priv )  { -	drm_i915_private_t *dev_priv = dev->dev_private; -	drm_i915_mem_destroy_heap_t *destroyheap = data; +	struct drm_i915_private *dev_priv = dev->dev_private; +	struct drm_i915_mem_destroy_heap *destroyheap = data;  	struct mem_block **heap;  	if ( !dev_priv ) { diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 06861381..006d04f3 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1390,6 +1390,28 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)  	}  } +void radeon_gart_flush(struct drm_device *dev) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; +	 +	if (dev_priv->flags & RADEON_IS_IGPGART) { +		RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); +		RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1); +		RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); +		RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0); +	} else if (dev_priv->flags & RADEON_IS_PCIE) { +		u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); +		tmp |= RADEON_PCIE_TX_GART_INVALIDATE_TLB; +		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); +		tmp &= ~RADEON_PCIE_TX_GART_INVALIDATE_TLB; +		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); +	} else { + + +	} + +} +  static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)  {  	drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2301,6 +2323,9 @@ int radeon_driver_firstopen(struct drm_device *dev)  	if (ret != 0)  		return ret; +#ifdef RADEON_HAVE_BUFFER +	drm_bo_driver_init(dev); +#endif  	return 0;  } diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index b0ef702b..913b23c5 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -434,8 +434,17 @@ typedef struct {  	int pfCurrentPage;	/* which buffer is being displayed? */  	int crtc2_base;		/* CRTC2 frame offset */  	int tiling_enabled;	/* set by drm, read by 2d + 3d clients */ + +	unsigned int last_fence;  } drm_radeon_sarea_t; +/* The only fence class we support */ +#define DRM_RADEON_FENCE_CLASS_ACCEL 0 +/* Fence type that guarantees read-write flush */ +#define DRM_RADEON_FENCE_TYPE_RW 2 +/* cache flushes programmed just before the fence */ +#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000 +  /* WARNING: If you change any of these defines, make sure to change the   * defines in the Xserver file (xf86drmRadeon.h)   * diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 006559df..f74fe933 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -104,6 +104,11 @@  #define DRIVER_MINOR		28  #define DRIVER_PATCHLEVEL	0 +#if defined(__linux__) +#define RADEON_HAVE_FENCE +#define RADEON_HAVE_BUFFER +#endif +  /*   * Radeon chip families   */ @@ -284,8 +289,9 @@ typedef struct drm_radeon_private {  	struct mem_block *fb_heap;  	/* SW interrupt */ -	wait_queue_head_t swi_queue; -	atomic_t swi_emitted; +	wait_queue_head_t irq_queue; +	int counter; +  	int vblank_crtc;  	uint32_t irq_enable_reg;  	int irq_enabled; @@ -344,6 +350,7 @@ extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file  extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);  extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);  extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern void radeon_gart_flush(struct drm_device *dev);  extern void radeon_freelist_reset(struct drm_device * dev);  extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); @@ -362,6 +369,7 @@ extern void radeon_mem_release(struct drm_file *file_priv,  				/* radeon_irq.c */  extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);  extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_emit_irq(struct drm_device * dev);  extern void radeon_do_release(struct drm_device * dev);  extern int radeon_driver_vblank_wait(struct drm_device * dev, @@ -395,6 +403,30 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,  			     struct drm_file *file_priv,  			     drm_radeon_kcmd_buffer_t* cmdbuf); + +#ifdef RADEON_HAVE_FENCE +/* i915_fence.c */ + + +extern void radeon_fence_handler(struct drm_device *dev); +extern int radeon_fence_emit_sequence(struct drm_device *dev, uint32_t class, +				      uint32_t flags, uint32_t *sequence,  +				    uint32_t *native_type); +extern void radeon_poke_flush(struct drm_device *dev, uint32_t class); +extern int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags); +#endif + +#ifdef RADEON_HAVE_BUFFER +/* radeon_buffer.c */ +extern drm_ttm_backend_t *radeon_create_ttm_backend_entry(struct drm_device *dev); +extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type); +extern int radeon_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); +extern uint32_t radeon_evict_mask(struct drm_buffer_object *bo); +extern int radeon_init_mem_type(struct drm_device * dev, uint32_t type, +				struct drm_mem_type_manager * man); +extern int radeon_move(struct drm_buffer_object * bo, +		       int evict, int no_wait, struct drm_bo_mem_reg * new_mem); +#endif  /* Flags for stats.boxes   */  #define RADEON_BOX_DMA_IDLE      0x1 @@ -1266,4 +1298,19 @@ do {									\  	write &= mask;						\  } while (0) +/* Breadcrumb - swi irq */ +#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG) + +static inline int radeon_update_breadcrumb(struct drm_device *dev) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; + +	dev_priv->sarea_priv->last_fence = ++dev_priv->counter; + +	if (dev_priv->counter > 0x7FFFFFFFUL) +		dev_priv->sarea_priv->last_fence = dev_priv->counter = 1; + +	return dev_priv->counter; +} +  #endif				/* __RADEON_DRV_H__ */ diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 1ece6399..3162e266 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -82,7 +82,10 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)  	/* SW interrupt */  	if (stat & RADEON_SW_INT_TEST) { -		DRM_WAKEUP(&dev_priv->swi_queue); +		DRM_WAKEUP(&dev_priv->irq_queue); +#ifdef RADEON_HAVE_FENCE +		radeon_fence_handler(dev); +#endif  	}  	/* VBLANK interrupt */ @@ -109,14 +112,13 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)  	return IRQ_HANDLED;  } -static int radeon_emit_irq(struct drm_device * dev) +int radeon_emit_irq(struct drm_device * dev)  {  	drm_radeon_private_t *dev_priv = dev->dev_private;  	unsigned int ret;  	RING_LOCALS; -	atomic_inc(&dev_priv->swi_emitted); -	ret = atomic_read(&dev_priv->swi_emitted); +	ret = radeon_update_breadcrumb(dev);  	BEGIN_RING(4);  	OUT_RING_REG(RADEON_LAST_SWI_REG, ret); @@ -133,13 +135,13 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)  	    (drm_radeon_private_t *) dev->dev_private;  	int ret = 0; -	if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) +	if (READ_BREADCRUMB(dev_priv) >= swi_nr)  		return 0;  	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; -	DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, -		    RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); +	DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, +		    READ_BREADCRUMB(dev_priv) >= swi_nr);  	return ret;  } @@ -271,8 +273,8 @@ void radeon_driver_irq_postinstall(struct drm_device * dev)  	drm_radeon_private_t *dev_priv =  	    (drm_radeon_private_t *) dev->dev_private; -	atomic_set(&dev_priv->swi_emitted, 0); -	DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); +	dev_priv->counter = 0; +	DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);  	radeon_enable_interrupt(dev);  } | 
