summaryrefslogtreecommitdiff
path: root/shared/radeon_cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/radeon_cp.c')
-rw-r--r--shared/radeon_cp.c219
1 files changed, 49 insertions, 170 deletions
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;
}