summaryrefslogtreecommitdiffstats
path: root/sys/dev/drm/radeon_cp.c
diff options
context:
space:
mode:
authoranholt <anholt@FreeBSD.org>2003-08-19 02:57:31 +0000
committeranholt <anholt@FreeBSD.org>2003-08-19 02:57:31 +0000
commit55fc74037ce1fed2313813918c5380b1c642828e (patch)
treee45c260fa868be8644bf3d316e3c7cc3cdc5a0eb /sys/dev/drm/radeon_cp.c
parentf9627255eea8f589c728f37d9a3a6e0040a24291 (diff)
downloadFreeBSD-src-55fc74037ce1fed2313813918c5380b1c642828e.zip
FreeBSD-src-55fc74037ce1fed2313813918c5380b1c642828e.tar.gz
Update DRM from DRI CVS as of today. Notable changes include Radeon
suspend/resume support and Rage 128 pageflipping support (both of which require XFree86 from CVS), along with miscellaneous cleanups.
Diffstat (limited to 'sys/dev/drm/radeon_cp.c')
-rw-r--r--sys/dev/drm/radeon_cp.c153
1 files changed, 111 insertions, 42 deletions
diff --git a/sys/dev/drm/radeon_cp.c b/sys/dev/drm/radeon_cp.c
index ba3aa99..4cabde8 100644
--- a/sys/dev/drm/radeon_cp.c
+++ b/sys/dev/drm/radeon_cp.c
@@ -906,7 +906,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
entry->busaddr[page_ofs]);
DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
- entry->busaddr[page_ofs],
+ (unsigned long) entry->busaddr[page_ofs],
entry->handle + tmp_ofs );
}
@@ -977,10 +977,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 );
@@ -1153,10 +1179,11 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
init->sarea_priv_offset);
+#if __REALLY_HAVE_AGP
if ( !dev_priv->is_pci ) {
- DRM_IOREMAP( dev_priv->cp_ring );
- DRM_IOREMAP( dev_priv->ring_rptr );
- DRM_IOREMAP( dev_priv->buffers );
+ DRM_IOREMAP( dev_priv->cp_ring, dev );
+ DRM_IOREMAP( dev_priv->ring_rptr, dev );
+ DRM_IOREMAP( dev_priv->buffers, dev );
if(!dev_priv->cp_ring->handle ||
!dev_priv->ring_rptr->handle ||
!dev_priv->buffers->handle) {
@@ -1165,7 +1192,9 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
radeon_do_cleanup_cp(dev);
return DRM_ERR(EINVAL);
}
- } else {
+ } else
+#endif
+ {
dev_priv->cp_ring->handle =
(void *)dev_priv->cp_ring->offset;
dev_priv->ring_rptr->handle =
@@ -1212,8 +1241,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 __REALLY_HAVE_SG
- 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,36 +1255,10 @@ 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 {
-#endif /* __REALLY_HAVE_SG */
- /* Turn off PCI GART
- */
- tmp = RADEON_READ( RADEON_AIC_CNTL )
- & ~RADEON_PCIGART_TRANSLATE_EN;
- RADEON_WRITE( RADEON_AIC_CNTL, tmp );
-#if __REALLY_HAVE_SG
+ /* Turn on PCI GART */
+ radeon_set_pcigart( dev_priv, 1 );
}
-#endif /* __REALLY_HAVE_SG */
radeon_cp_load_microcode( dev_priv );
radeon_cp_init_ring_buffer( dev, dev_priv );
@@ -1268,23 +1276,32 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
{
DRM_DEBUG( "\n" );
+#if _HAVE_DMA_IRQ
+ /* Make sure interrupts are disabled here because the uninstall ioctl
+ * may not have been called from userspace and after dev_private
+ * is freed, it's too late.
+ */
+ if ( dev->irq ) 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 );
+ DRM_IOREMAPFREE( dev_priv->cp_ring, dev );
if ( dev_priv->ring_rptr != NULL )
- DRM_IOREMAPFREE( dev_priv->ring_rptr );
+ DRM_IOREMAPFREE( dev_priv->ring_rptr, dev );
if ( dev_priv->buffers != NULL )
- DRM_IOREMAPFREE( dev_priv->buffers );
- } else {
-#if __REALLY_HAVE_SG
+ 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" );
-#endif /* __REALLY_HAVE_SG */
}
DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
@@ -1295,11 +1312,53 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
return 0;
}
+/* 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.
+ *
+ * Charl P. Botha <http://cpbotha.net>
+ */
+static int radeon_do_resume_cp( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "Called with no initialization\n" );
+ return DRM_ERR( EINVAL );
+ }
+
+ DRM_DEBUG("Starting radeon_do_resume_cp()\n");
+
+#if __REALLY_HAVE_AGP
+ if ( !dev_priv->is_pci ) {
+ /* Turn off PCI GART */
+ radeon_set_pcigart( dev_priv, 0 );
+ } else
+#endif
+ {
+ /* Turn on PCI GART */
+ radeon_set_pcigart( dev_priv, 1 );
+ }
+
+ radeon_cp_load_microcode( dev_priv );
+ radeon_cp_init_ring_buffer( dev, dev_priv );
+
+ radeon_do_engine_reset( dev );
+
+ DRM_DEBUG("radeon_do_resume_cp() complete\n");
+
+ return 0;
+}
+
+
int radeon_cp_init( DRM_IOCTL_ARGS )
{
DRM_DEVICE;
drm_radeon_init_t init;
+ LOCK_TEST_WITH_RETURN( dev, filp );
+
DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) );
switch ( init.func ) {
@@ -1448,6 +1507,16 @@ int radeon_cp_idle( DRM_IOCTL_ARGS )
return radeon_do_cp_idle( dev_priv );
}
+/* Added by Charl P. Botha to call radeon_do_resume_cp().
+ */
+int radeon_cp_resume( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+
+ return radeon_do_resume_cp(dev);
+}
+
+
int radeon_engine_reset( DRM_IOCTL_ARGS )
{
DRM_DEVICE;
OpenPOWER on IntegriCloud