mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-08 12:48:05 +02:00
preparation patch for radeon permanent mapping registers/framebuffer makes
dev_priv live always, and add AGP detection in kernel patch:
radeon-pre-2.patch From: Jon Smirl
This commit is contained in:
parent
02ef96053c
commit
93e8c201af
7 changed files with 258 additions and 116 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -127,6 +127,10 @@ do { \
|
|||
filp_priv->radeon_fb_delta = 0; \
|
||||
} while( 0 )
|
||||
|
||||
#define DRIVER_POSTINIT(dev, flags) radeon_postinit(dev, flags)
|
||||
#define DRIVER_PREINIT(dev, flags) radeon_preinit(dev, flags)
|
||||
#define DRIVER_POSTCLEANUP(dev) radeon_postcleanup(dev)
|
||||
|
||||
/* When a client dies:
|
||||
* - Check for and clean up flipped page state
|
||||
* - Free any alloced GART memory.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue