diff options
Diffstat (limited to 'shared-core')
| -rw-r--r-- | shared-core/drm_pciids.txt | 3 | ||||
| -rw-r--r-- | shared-core/i915_dma.c | 85 | ||||
| -rw-r--r-- | shared-core/i915_drm.h | 5 | ||||
| -rw-r--r-- | shared-core/i915_drv.h | 2 | 
4 files changed, 79 insertions, 16 deletions
diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index 4b07e4f6..ba02aa89 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -289,6 +289,9 @@  0x8086 0x29A2 CHIP_I9XX|CHIP_I965 "Intel i965G"  0x8086 0x2A02 CHIP_I9XX|CHIP_I965 "Intel i965GM"  0x8086 0x2A12 CHIP_I9XX|CHIP_I965 "Intel i965GME/GLE" +0x8086 0x29C2 CHIP_I9XX|CHIP_I915 "Intel G33" +0x8086 0x29B2 CHIP_I9XX|CHIP_I915 "Intel Q35" +0x8086 0x29D2 CHIP_I9XX|CHIP_I915 "Intel Q33"  [imagine]  0x105d 0x2309 IMAGINE_128 "Imagine 128" diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index c6a80f1c..ebb184cc 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -38,6 +38,9 @@  			dev->pci_device == 0x2A02 || \  			dev->pci_device == 0x2A12) +#define IS_G33(dev)    (dev->pci_device == 0x29C2 || \ +		   	dev->pci_device == 0x29B2 || \ +			dev->pci_device == 0x29D2)   /* 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 @@ -108,7 +111,11 @@ static int i915_dma_cleanup(drm_device_t * dev)  			/* 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); +		}  		drm_free(dev->dev_private, sizeof(drm_i915_private_t),  			 DRM_MEM_DRIVER); @@ -183,22 +190,23 @@ static int i915_initialize(drm_device_t * dev,      	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;  	/* Program Hardware Status Page */ -	dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,  -	    0xffffffff); +	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 DRM_ERR(ENOMEM); +		} +		dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; +		dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; -	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 DRM_ERR(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); -	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); +		memset(dev_priv->hw_status_page, 0, PAGE_SIZE); -	I915_WRITE(0x02080, dev_priv->dma_status_page); +		I915_WRITE(0x02080, dev_priv->dma_status_page); +	}  	DRM_DEBUG("Enabled hardware status page\n");  	dev->dev_private = (void *)dev_priv;  	return 0; @@ -233,7 +241,10 @@ static int i915_dma_resume(drm_device_t * dev)  	}  	DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); -	I915_WRITE(0x02080, dev_priv->dma_status_page); +	if (dev_priv->status_gfx_addr != 0) +		I915_WRITE(0x02080, dev_priv->status_gfx_addr); +	else +		I915_WRITE(0x02080, dev_priv->dma_status_page);  	DRM_DEBUG("Enabled hardware status page\n");  	return 0; @@ -885,6 +896,47 @@ static int i915_mmio(DRM_IOCTL_ARGS)  	return 0;  } +static int i915_set_status_page(DRM_IOCTL_ARGS) +{ +	DRM_DEVICE; +	drm_i915_private_t *dev_priv = dev->dev_private; +	drm_i915_hws_addr_t hws; + +	if (!dev_priv) { +		DRM_ERROR("%s called with no initialization\n", __FUNCTION__); +		return DRM_ERR(EINVAL); +	} +	DRM_COPY_FROM_USER_IOCTL(hws, (drm_i915_hws_addr_t __user *) data, +			sizeof(hws)); +	printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws.addr); + +	dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12); + +	dev_priv->hws_map.offset = dev->agp->agp_info.aper_base + hws.addr; +	dev_priv->hws_map.size = 4*1024; +	dev_priv->hws_map.type = 0; +	dev_priv->hws_map.flags = 0; +	dev_priv->hws_map.mtrr = 0; + +	drm_core_ioremap(&dev_priv->hws_map, dev); +	if (dev_priv->hws_map.handle == NULL) { +		dev->dev_private = (void *)dev_priv; +		i915_dma_cleanup(dev); +		dev_priv->status_gfx_addr = 0; +		DRM_ERROR("can not ioremap virtual address for" +				" G33 hw status page\n"); +		return DRM_ERR(ENOMEM); +	} +	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); +	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(drm_device_t *dev, unsigned long flags)  {  	/* i915 has 4 more counters */ @@ -933,6 +985,7 @@ drm_ioctl_desc_t i915_ioctls[] = {  	[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}, +	[DRM_IOCTL_NR(DRM_I915_HWS_ADDR)] = {i915_set_status_page, 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 1f32313e..1c6ff4d3 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -159,6 +159,7 @@ typedef struct _drm_i915_sarea {  #define DRM_I915_GET_VBLANK_PIPE	0x0e  #define DRM_I915_VBLANK_SWAP	0x0f  #define DRM_I915_MMIO		0x10 +#define DRM_I915_HWS_ADDR	0x11  #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) @@ -314,4 +315,8 @@ typedef struct drm_i915_mmio {  	void __user *data;	  } drm_i915_mmio_t; +typedef struct drm_i915_hws_addr { +	uint64_t addr; +} drm_i915_hws_addr_t; +  #endif				/* _I915_DRM_H_ */ diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index e8a7be29..9deee8ec 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -99,6 +99,8 @@ typedef struct drm_i915_private {  	void *hw_status_page;  	dma_addr_t dma_status_page;  	uint32_t counter; +	unsigned int status_gfx_addr; +	drm_local_map_t hws_map;  	unsigned int cpp;  	int use_mi_batchbuffer_start;  | 
