diff options
Diffstat (limited to 'shared-core')
| -rw-r--r-- | shared-core/radeon_cp.c | 163 | ||||
| -rw-r--r-- | shared-core/radeon_drm.h | 2 | ||||
| -rw-r--r-- | shared-core/radeon_drv.h | 20 | 
3 files changed, 127 insertions, 58 deletions
| diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index f6964908..4efb6c2a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -859,7 +859,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,  		    | ( dev_priv->fb_location >> 16 ) );  #if __REALLY_HAVE_AGP -	if ( !dev_priv->is_pci ) { +	if (dev_priv->flags & CHIP_IS_AGP) {  		RADEON_WRITE( RADEON_MC_AGP_LOCATION,  			      (((dev_priv->gart_vm_start - 1 +  				 dev_priv->gart_size) & 0xffff0000) | @@ -868,7 +868,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,  		ring_start = (dev_priv->cp_ring->offset  			      - dev->agp->base  			      + dev_priv->gart_vm_start); -       } else +	} else  #endif  		ring_start = (dev_priv->cp_ring->offset  			      - dev->sg->handle @@ -886,7 +886,9 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,  	dev_priv->ring.tail = cur_read_ptr;  #if __REALLY_HAVE_AGP -	if ( !dev_priv->is_pci ) { +	if (dev_priv->flags & CHIP_IS_AGP) { +		/* set RADEON_AGP_BASE here instead of relying on X from user space */ +		RADEON_WRITE( RADEON_AGP_BASE, (unsigned int)dev->agp->base );  		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,  			      dev_priv->ring_rptr->offset  			      - dev->agp->base @@ -1003,20 +1005,11 @@ static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on )  static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  { -	drm_radeon_private_t *dev_priv; +	drm_radeon_private_t *dev_priv = dev->dev_private;  	DRM_DEBUG( "\n" ); -	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); -	if ( dev_priv == NULL ) -		return DRM_ERR(ENOMEM); - -	memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); - -	dev_priv->is_pci = init->is_pci; - -	if ( dev_priv->is_pci && !dev->sg ) { +	if ( (!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg ) {  		DRM_ERROR( "PCI GART memory not allocated!\n" ); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	} @@ -1025,7 +1018,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  	if ( dev_priv->usec_timeout < 1 ||  	     dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {  		DRM_DEBUG( "TIMEOUT problem!\n" ); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	} @@ -1041,7 +1033,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  	if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&  	     ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {  		DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode ); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	} @@ -1113,7 +1104,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  	if(!dev_priv->sarea) {  		DRM_ERROR("could not find sarea!\n"); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	} @@ -1121,28 +1111,24 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  	DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );  	if(!dev_priv->mmio) {  		DRM_ERROR("could not find mmio region!\n"); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	}  	DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset );  	if(!dev_priv->cp_ring) {  		DRM_ERROR("could not find cp ring region!\n"); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	}  	DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );  	if(!dev_priv->ring_rptr) {  		DRM_ERROR("could not find ring read pointer!\n"); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	}  	DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );  	if(!dev_priv->buffers) {  		DRM_ERROR("could not find dma buffer region!\n"); -		dev->dev_private = (void *)dev_priv;  		radeon_do_cleanup_cp(dev);  		return DRM_ERR(EINVAL);  	} @@ -1151,7 +1137,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  		DRM_FIND_MAP( dev_priv->gart_textures, init->gart_textures_offset );  		if ( !dev_priv->gart_textures ) {  			DRM_ERROR("could not find GART texture region!\n"); -			dev->dev_private = (void *)dev_priv;  			radeon_do_cleanup_cp(dev);  			return DRM_ERR(EINVAL);  		} @@ -1162,7 +1147,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  				       init->sarea_priv_offset);  #if __REALLY_HAVE_AGP -	if ( !dev_priv->is_pci ) { +	if (dev_priv->flags & CHIP_IS_AGP) {  		DRM_IOREMAP( dev_priv->cp_ring, dev );  		DRM_IOREMAP( dev_priv->ring_rptr, dev );  		DRM_IOREMAP( dev_priv->buffers, dev ); @@ -1170,7 +1155,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  		   !dev_priv->ring_rptr->handle ||  		   !dev_priv->buffers->handle) {  			DRM_ERROR("could not find ioremap agp regions!\n"); -			dev->dev_private = (void *)dev_priv;  			radeon_do_cleanup_cp(dev);  			return DRM_ERR(EINVAL);  		} @@ -1212,7 +1196,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  				+ RADEON_READ( RADEON_CONFIG_APER_SIZE );  #if __REALLY_HAVE_AGP -	if ( !dev_priv->is_pci ) +	if (dev_priv->flags & CHIP_IS_AGP)  		dev_priv->gart_buffers_offset = (dev_priv->buffers->offset  						- dev->agp->base  						+ dev_priv->gart_vm_start); @@ -1241,7 +1225,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;  #if __REALLY_HAVE_AGP -	if ( !dev_priv->is_pci ) { +	if (dev_priv->flags & CHIP_IS_AGP) {  		/* Turn off PCI GART */  		radeon_set_pcigart( dev_priv, 0 );  	} else @@ -1250,7 +1234,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,  					    &dev_priv->bus_pci_gart)) {  			DRM_ERROR( "failed to init PCI GART!\n" ); -			dev->dev_private = (void *)dev_priv;  			radeon_do_cleanup_cp(dev);  			return DRM_ERR(ENOMEM);  		} @@ -1264,8 +1247,6 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  	dev_priv->last_buf = 0; -	dev->dev_private = (void *)dev_priv; -  	radeon_do_engine_reset( dev );  	return 0; @@ -1273,6 +1254,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )  int radeon_do_cleanup_cp( drm_device_t *dev )  { +	drm_radeon_private_t *dev_priv = dev->dev_private;  	DRM_DEBUG( "\n" );  #if __HAVE_IRQ @@ -1283,29 +1265,26 @@ int radeon_do_cleanup_cp( drm_device_t *dev )  	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);  #endif -	if ( dev->dev_private ) { -		drm_radeon_private_t *dev_priv = dev->dev_private; -  #if __REALLY_HAVE_AGP -		if ( !dev_priv->is_pci ) { -			if ( dev_priv->cp_ring != NULL ) -				DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); -			if ( dev_priv->ring_rptr != NULL ) -				DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); -			if ( dev_priv->buffers != NULL ) -				DRM_IOREMAPFREE( dev_priv->buffers, dev ); -		} else +	if (dev_priv->flags & CHIP_IS_AGP) { +		if ( dev_priv->cp_ring != NULL ) +			DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); +		if ( dev_priv->ring_rptr != NULL ) +			DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); +		if ( dev_priv->buffers != NULL ) +			DRM_IOREMAPFREE( dev_priv->buffers, dev ); +	} else  #endif -		{ -			if (!DRM(ati_pcigart_cleanup)( dev, -						dev_priv->phys_pci_gart, -						dev_priv->bus_pci_gart )) -				DRM_ERROR( "failed to cleanup PCI GART!\n" ); -		} - -		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), -			   DRM_MEM_DRIVER ); -		dev->dev_private = NULL; +	{ +		if (!DRM(ati_pcigart_cleanup)( dev, +					dev_priv->phys_pci_gart, +					dev_priv->bus_pci_gart )) +			DRM_ERROR( "failed to cleanup PCI GART!\n" ); +	} +	{ +		int flags = dev_priv->flags; +		memset(dev_priv, 0, sizeof(*dev_priv)); +		dev_priv->flags = flags;  	}  	return 0; @@ -1330,7 +1309,7 @@ static int radeon_do_resume_cp( drm_device_t *dev )  	DRM_DEBUG("Starting radeon_do_resume_cp()\n");  #if __REALLY_HAVE_AGP -	if ( !dev_priv->is_pci ) { +	if (dev_priv->flags & CHIP_IS_AGP) {  		/* Turn off PCI GART */  		radeon_set_pcigart( dev_priv, 0 );  	} else @@ -1444,8 +1423,10 @@ void radeon_do_release( drm_device_t *dev )  {  	drm_radeon_private_t *dev_priv = dev->dev_private;  	int ret; +	DRM_DEBUG("dev_priv %ptr\n", dev_priv);  	if (dev_priv) { +  		if (dev_priv->cp_running) {  			/* Stop the cp */  			while ((ret = radeon_do_cp_idle( dev_priv )) != 0) { @@ -1461,7 +1442,8 @@ void radeon_do_release( drm_device_t *dev )  		}  		/* Disable *all* interrupts */ -		RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); +		if (dev_priv->mmio) /* remove this after permanent addmaps */ +			RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );  		/* Free memory heap structures */  		radeon_mem_takedown( &(dev_priv->gart_heap) ); @@ -1745,3 +1727,80 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS )  	return ret;  } + +static int radeon_register_regions(struct pci_dev *pdev) { +	int retcode = -EINVAL; + +	/* request the mem regions */ +	if (!request_mem_region (pci_resource_start( pdev, 2 ), +					pci_resource_len(pdev, 2), DRIVER_NAME)) { +		printk(KERN_ERR DRIVER_NAME ": cannot reserve MMIO region\n"); +		return retcode; +	} +	if (!request_mem_region (pci_resource_start( pdev, 0 ), +					pci_resource_len(pdev, 0), DRIVER_NAME)) { +		printk(KERN_ERR DRIVER_NAME ": cannot reserve FB region\n"); +		return retcode; +	} +	return 0; +} + +static void radeon_release_regions(struct pci_dev *pdev) { +        release_mem_region (pci_resource_start( pdev, 2 ), pci_resource_len(pdev, 2)); +        release_mem_region (pci_resource_start( pdev, 0 ), pci_resource_len(pdev, 0)); +} + +/* Always create a map record for MMIO and FB memory, done from DRIVER_POSTINIT */ +int radeon_preinit( drm_device_t *dev, unsigned long flags ) +{ +	int retcode = -EINVAL; +	u32 save, temp; +	drm_radeon_private_t *dev_priv; + +	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); +	if ( dev_priv == NULL ) +		return DRM_ERR(ENOMEM); +	DRM_DEBUG("dev_priv %ptr\n", dev_priv); + +	memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); +	dev->dev_private = (void *)dev_priv; +	dev_priv->flags = flags; + +	/* request the mem regions */ +	if (!DRM(fb_loaded)) +		if ((retcode = radeon_register_regions(dev->pdev)) != 0) +			return retcode; + +	/* There are signatures in BIOS and PCI-SSID for a PCI card, but they are not very reliable. +		Following detection method works for all cards tested so far. +		Note, checking AGP_ENABLE bit after drmAgpEnable call can also give the correct result. +		However, calling drmAgpEnable on a PCI card can cause some strange lockup when the server +		restarts next time. +	*/ +	pci_read_config_dword(dev->pdev, RADEON_AGP_COMMAND_PCI_CONFIG, &save); +	pci_write_config_dword(dev->pdev, RADEON_AGP_COMMAND_PCI_CONFIG, save | RADEON_AGP_ENABLE); +	pci_read_config_dword(dev->pdev, RADEON_AGP_COMMAND_PCI_CONFIG, &temp); +	if (temp & RADEON_AGP_ENABLE) +		dev_priv->flags |= CHIP_IS_AGP; +	DRM_DEBUG("%s card detected\n", ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); +	pci_write_config_dword(dev->pdev, RADEON_AGP_COMMAND_PCI_CONFIG, save); + +        return 0; +} + +int radeon_postinit( drm_device_t *dev, unsigned long flags ) +{ +	return 0; +} + +void radeon_postcleanup( drm_device_t *dev ) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; +	 +	DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER ); + +	if (!DRM(fb_loaded)) +		radeon_release_regions(dev->pdev); +	 +	dev->dev_private = NULL; +} diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index e447308b..207a0c00 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -433,7 +433,7 @@ typedef struct drm_radeon_init {  		RADEON_INIT_R200_CP = 0x03  	} func;  	unsigned long sarea_priv_offset; -	int is_pci; +	int is_pci;	/* not used, driver asks hardware */  	int cp_mode;  	int gart_size;  	int ring_size; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 81b9a98e..eb2d4dca 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -40,6 +40,7 @@ enum radeon_chip_flags {  	CHIP_IS_MOBILITY	= 0x00010000UL,  	CHIP_IS_IGP		= 0x00020000UL,  	CHIP_SINGLE_CRTC	= 0x00040000UL, +	CHIP_IS_AGP		= 0x00080000UL,   };  #define GET_RING_HEAD(dev_priv)		DRM_READ32(  (dev_priv)->ring_rptr, 0 ) @@ -81,6 +82,9 @@ struct mem_block {  };  typedef struct drm_radeon_private { + +	u32 flags;		/* see radeon_chip_flags */ +  	drm_radeon_ring_buffer_t ring;  	drm_radeon_sarea_t *sarea_priv; @@ -103,7 +107,6 @@ typedef struct drm_radeon_private {  	int is_r200; -	int is_pci;  	unsigned long phys_pci_gart;  	dma_addr_t bus_pci_gart; @@ -223,13 +226,13 @@ extern void radeon_do_release(drm_device_t *dev);  #define RADEON_BOX_WAIT_IDLE     0x8  #define RADEON_BOX_TEXTURE_LOAD  0x10 - -  /* Register definitions, register access macros and drmAddMap constants   * for Radeon kernel driver.   */ -  #define RADEON_AGP_COMMAND		0x0f60 +#define RADEON_AGP_COMMAND_PCI_CONFIG	0x0060		/* offset in PCI config*/ +#       define RADEON_AGP_ENABLE            (1<<8) +  #define RADEON_AUX_SCISSOR_CNTL		0x26f0  #	define RADEON_EXCLUSIVE_SCISSOR_0	(1 << 24)  #	define RADEON_EXCLUSIVE_SCISSOR_1	(1 << 25) @@ -252,6 +255,11 @@ extern void radeon_do_release(drm_device_t *dev);  #define RADEON_CRTC2_OFFSET		0x0324  #define RADEON_CRTC2_OFFSET_CNTL	0x0328 +#define RADEON_MPP_TB_CONFIG		0x01c0 +#define RADEON_MEM_CNTL			0x0140 +#define RADEON_MEM_SDRAM_MODE_REG	0x0158 +#define RADEON_AGP_BASE			0x0170 +  #define RADEON_RB3D_COLOROFFSET		0x1c40  #define RADEON_RB3D_COLORPITCH		0x1c48 @@ -730,7 +738,9 @@ do {									\  } while (0)  extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); - +extern int radeon_preinit( drm_device_t *dev, unsigned long flags ); +extern int radeon_postinit( drm_device_t *dev, unsigned long flags ); +extern void radeon_postcleanup( drm_device_t *dev );  #define CP_PACKET0( reg, n )						\  	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) | 
