diff options
-rw-r--r-- | shared-core/radeon_cp.c | 219 | ||||
-rw-r--r-- | shared/radeon.h | 4 | ||||
-rw-r--r-- | shared/radeon_cp.c | 219 |
3 files changed, 100 insertions, 342 deletions
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index cec9df59..f53ab5b7 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -975,10 +975,36 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); } +/* Enable or disable PCI GART on the chip */ +static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) +{ + u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); + + if ( on ) { + RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); + + /* set PCI GART page-table base address + */ + RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); + + /* set address range for PCI address translate + */ + RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); + RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start + + dev_priv->agp_size - 1); + + /* Turn off AGP aperture -- is this required for PCIGART? + */ + RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ + RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ + } else { + RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN ); + } +} + static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) { drm_radeon_private_t *dev_priv; - u32 tmp; DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); @@ -1213,7 +1239,13 @@ 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 ( dev_priv->is_pci ) { +#if __REALLY_HAVE_AGP + if ( !dev_priv->is_pci ) { + /* Turn off PCI GART */ + radeon_set_pcigart( dev_priv, 0 ); + } else +#endif + { if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart)) { DRM_ERROR( "failed to init PCI GART!\n" ); @@ -1221,32 +1253,9 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) radeon_do_cleanup_cp(dev); return DRM_ERR(ENOMEM); } - /* Turn on PCI GART - */ - tmp = RADEON_READ( RADEON_AIC_CNTL ) - | RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); - - /* set PCI GART page-table base address - */ - RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); - - /* set address range for PCI address translate - */ - RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); - RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start - + dev_priv->agp_size - 1); - /* Turn off AGP aperture -- is this required for PCIGART? - */ - RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ - RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ - } else { - /* Turn off PCI GART - */ - tmp = RADEON_READ( RADEON_AIC_CNTL ) - & ~RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); + /* Turn on PCI GART */ + radeon_set_pcigart( dev_priv, 1 ); } radeon_cp_load_microcode( dev_priv ); @@ -1304,162 +1313,30 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) /* This code will reinit the Radeon CP hardware after a resume from disc. * AFAIK, it would be very difficult to pickle the state at suspend time, so * here we make sure that all Radeon hardware initialisation is re-done without - * affecting running applications. This function is called radeon_do_resume_cp() - * as it was derived from radeon_init_cp, where most of the initialisation takes - * place during DRI init. - * - * This patch is NOT to be confused with my and Michel Daenzer's earlier DRI - * reinit work, which de- and re-initialised the complete DRI at every VT - * switch. + * affecting running applications. * * Charl P. Botha <http://cpbotha.net> */ -static int radeon_do_resume_cp( drm_device_t *dev) +static int radeon_do_resume_cp( drm_device_t *dev ) { - drm_radeon_private_t *dev_priv; - u32 tmp; - DRM_DEBUG( "\n" ); - - DRM_DEBUG("Starting radeon_do_resume_cp()\n"); - - /* get the existing dev_private */ - dev_priv = dev->dev_private; - -#if !defined(PCIGART_ENABLED) - /* PCI support is not 100% working, so we disable it here. - */ - if ( dev_priv->is_pci ) { - DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } -#endif - - if ( dev_priv->is_pci && !dev->sg ) { - DRM_ERROR( "PCI GART memory not allocated!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if ( dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { - DRM_DEBUG( "TIMEOUT problem!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if ( ( dev_priv->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && - ( dev_priv->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { - DRM_DEBUG( "BAD cp_mode (%x)!\n", dev_priv->cp_mode ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->fb) { - DRM_ERROR("could not find framebuffer!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->mmio) { - DRM_ERROR("could not find mmio region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->cp_ring) { - DRM_ERROR("could not find cp ring region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->buffers) { - DRM_ERROR("could not find dma buffer region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if ( !dev_priv->is_pci ) { - if(!dev_priv->agp_textures) { - DRM_ERROR("could not find agp texture region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - } + drm_radeon_private_t *dev_priv = dev->dev_private; - if ( !dev_priv->is_pci ) { - if(!dev_priv->cp_ring->handle || - !dev_priv->ring_rptr->handle || - !dev_priv->buffers->handle) { - DRM_ERROR("could not find ioremap agp regions!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - } else { - DRM_DEBUG( "dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle ); - DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", - dev_priv->ring_rptr->handle ); - DRM_DEBUG( "dev_priv->buffers->handle %p\n", - dev_priv->buffers->handle ); + if ( !dev_priv ) { + DRM_ERROR( "Called with no initialization\n" ); + return DRM_ERR( EINVAL ); } - - DRM_DEBUG( "dev_priv->agp_size %d\n", - dev_priv->agp_size ); - DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n", - dev_priv->agp_vm_start ); - DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n", - dev_priv->agp_buffers_offset ); + DRM_DEBUG("Starting radeon_do_resume_cp()\n"); #if __REALLY_HAVE_AGP if ( !dev_priv->is_pci ) { - /* Turn off PCI GART - */ - tmp = RADEON_READ( RADEON_AIC_CNTL ) - & ~RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); + /* Turn off PCI GART */ + radeon_set_pcigart( dev_priv, 0 ); } else #endif { - /* I'm not so sure about this ati_picgart_init after at resume-time... */ - if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, - &dev_priv->bus_pci_gart)) { - DRM_ERROR( "failed to init PCI GART!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(ENOMEM); - } - - tmp = RADEON_READ( RADEON_AIC_CNTL ) - | RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); - - /* set PCI GART page-table base address - */ - RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); - - /* set address range for PCI address translate - */ - RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); - RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start - + dev_priv->agp_size - 1); - - /* Turn off AGP aperture -- is this required for PCIGART? - */ - RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ - RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ + /* Turn on PCI GART */ + radeon_set_pcigart( dev_priv, 1 ); } radeon_cp_load_microcode( dev_priv ); @@ -1467,6 +1344,8 @@ static int radeon_do_resume_cp( drm_device_t *dev) radeon_do_engine_reset( dev ); + DRM_DEBUG("radeon_do_resume_cp() complete\n"); + return 0; } diff --git a/shared/radeon.h b/shared/radeon.h index 7df3dd74..7fe08ea8 100644 --- a/shared/radeon.h +++ b/shared/radeon.h @@ -79,8 +79,8 @@ * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian) * 1.8 - Remove need to call cleanup ioctls on last client exit (keith) * Add 'GET' queries for starting additional clients on different VT's. - * Add DRM_IOCTL_RADEON_CP_RESUME ioctl. - * 1.9 - Add texture rectangle support for r100. + * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl. + * Add texture rectangle support for r100. */ #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c index cec9df59..f53ab5b7 100644 --- a/shared/radeon_cp.c +++ b/shared/radeon_cp.c @@ -975,10 +975,36 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); } +/* Enable or disable PCI GART on the chip */ +static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) +{ + u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); + + if ( on ) { + RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); + + /* set PCI GART page-table base address + */ + RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); + + /* set address range for PCI address translate + */ + RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); + RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start + + dev_priv->agp_size - 1); + + /* Turn off AGP aperture -- is this required for PCIGART? + */ + RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ + RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ + } else { + RADEON_WRITE( RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN ); + } +} + static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) { drm_radeon_private_t *dev_priv; - u32 tmp; DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); @@ -1213,7 +1239,13 @@ 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 ( dev_priv->is_pci ) { +#if __REALLY_HAVE_AGP + if ( !dev_priv->is_pci ) { + /* Turn off PCI GART */ + radeon_set_pcigart( dev_priv, 0 ); + } else +#endif + { if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart)) { DRM_ERROR( "failed to init PCI GART!\n" ); @@ -1221,32 +1253,9 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) radeon_do_cleanup_cp(dev); return DRM_ERR(ENOMEM); } - /* Turn on PCI GART - */ - tmp = RADEON_READ( RADEON_AIC_CNTL ) - | RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); - - /* set PCI GART page-table base address - */ - RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); - - /* set address range for PCI address translate - */ - RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); - RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start - + dev_priv->agp_size - 1); - /* Turn off AGP aperture -- is this required for PCIGART? - */ - RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ - RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ - } else { - /* Turn off PCI GART - */ - tmp = RADEON_READ( RADEON_AIC_CNTL ) - & ~RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); + /* Turn on PCI GART */ + radeon_set_pcigart( dev_priv, 1 ); } radeon_cp_load_microcode( dev_priv ); @@ -1304,162 +1313,30 @@ int radeon_do_cleanup_cp( drm_device_t *dev ) /* This code will reinit the Radeon CP hardware after a resume from disc. * AFAIK, it would be very difficult to pickle the state at suspend time, so * here we make sure that all Radeon hardware initialisation is re-done without - * affecting running applications. This function is called radeon_do_resume_cp() - * as it was derived from radeon_init_cp, where most of the initialisation takes - * place during DRI init. - * - * This patch is NOT to be confused with my and Michel Daenzer's earlier DRI - * reinit work, which de- and re-initialised the complete DRI at every VT - * switch. + * affecting running applications. * * Charl P. Botha <http://cpbotha.net> */ -static int radeon_do_resume_cp( drm_device_t *dev) +static int radeon_do_resume_cp( drm_device_t *dev ) { - drm_radeon_private_t *dev_priv; - u32 tmp; - DRM_DEBUG( "\n" ); - - DRM_DEBUG("Starting radeon_do_resume_cp()\n"); - - /* get the existing dev_private */ - dev_priv = dev->dev_private; - -#if !defined(PCIGART_ENABLED) - /* PCI support is not 100% working, so we disable it here. - */ - if ( dev_priv->is_pci ) { - DRM_ERROR( "PCI GART not yet supported for Radeon!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } -#endif - - if ( dev_priv->is_pci && !dev->sg ) { - DRM_ERROR( "PCI GART memory not allocated!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if ( dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { - DRM_DEBUG( "TIMEOUT problem!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if ( ( dev_priv->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && - ( dev_priv->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { - DRM_DEBUG( "BAD cp_mode (%x)!\n", dev_priv->cp_mode ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->fb) { - DRM_ERROR("could not find framebuffer!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->mmio) { - DRM_ERROR("could not find mmio region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->cp_ring) { - DRM_ERROR("could not find cp ring region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if(!dev_priv->buffers) { - DRM_ERROR("could not find dma buffer region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - - if ( !dev_priv->is_pci ) { - if(!dev_priv->agp_textures) { - DRM_ERROR("could not find agp texture region!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - } + drm_radeon_private_t *dev_priv = dev->dev_private; - if ( !dev_priv->is_pci ) { - if(!dev_priv->cp_ring->handle || - !dev_priv->ring_rptr->handle || - !dev_priv->buffers->handle) { - DRM_ERROR("could not find ioremap agp regions!\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - } else { - DRM_DEBUG( "dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle ); - DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", - dev_priv->ring_rptr->handle ); - DRM_DEBUG( "dev_priv->buffers->handle %p\n", - dev_priv->buffers->handle ); + if ( !dev_priv ) { + DRM_ERROR( "Called with no initialization\n" ); + return DRM_ERR( EINVAL ); } - - DRM_DEBUG( "dev_priv->agp_size %d\n", - dev_priv->agp_size ); - DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n", - dev_priv->agp_vm_start ); - DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n", - dev_priv->agp_buffers_offset ); + DRM_DEBUG("Starting radeon_do_resume_cp()\n"); #if __REALLY_HAVE_AGP if ( !dev_priv->is_pci ) { - /* Turn off PCI GART - */ - tmp = RADEON_READ( RADEON_AIC_CNTL ) - & ~RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); + /* Turn off PCI GART */ + radeon_set_pcigart( dev_priv, 0 ); } else #endif { - /* I'm not so sure about this ati_picgart_init after at resume-time... */ - if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, - &dev_priv->bus_pci_gart)) { - DRM_ERROR( "failed to init PCI GART!\n" ); - radeon_do_cleanup_cp(dev); - return DRM_ERR(ENOMEM); - } - - tmp = RADEON_READ( RADEON_AIC_CNTL ) - | RADEON_PCIGART_TRANSLATE_EN; - RADEON_WRITE( RADEON_AIC_CNTL, tmp ); - - /* set PCI GART page-table base address - */ - RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); - - /* set address range for PCI address translate - */ - RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start ); - RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start - + dev_priv->agp_size - 1); - - /* Turn off AGP aperture -- is this required for PCIGART? - */ - RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ - RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ + /* Turn on PCI GART */ + radeon_set_pcigart( dev_priv, 1 ); } radeon_cp_load_microcode( dev_priv ); @@ -1467,6 +1344,8 @@ static int radeon_do_resume_cp( drm_device_t *dev) radeon_do_engine_reset( dev ); + DRM_DEBUG("radeon_do_resume_cp() complete\n"); + return 0; } |