preparation patch for radeon permanent mapping registers/framebuffer makes
authorDave Airlie <airlied@linux.ie>
Tue, 17 Aug 2004 11:24:50 +0000 (11:24 +0000)
committerDave Airlie <airlied@linux.ie>
Tue, 17 Aug 2004 11:24:50 +0000 (11:24 +0000)
    dev_priv live always, and add AGP detection in kernel patch:
    radeon-pre-2.patch From: Jon Smirl

shared-core/radeon_cp.c
shared-core/radeon_drm.h
shared-core/radeon_drv.h
shared/radeon.h
shared/radeon_cp.c
shared/radeon_drm.h
shared/radeon_drv.h

index f696490..4efb6c2 100644 (file)
@@ -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;
+}
index e447308..207a0c0 100644 (file)
@@ -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;
index 81b9a98..eb2d4dc 100644 (file)
@@ -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))
index eb857da..44c4aee 100644 (file)
@@ -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.
index f696490..4efb6c2 100644 (file)
@@ -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;
+}
index e447308..207a0c0 100644 (file)
@@ -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;
index 81b9a98..eb2d4dc 100644 (file)
@@ -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))