Clean up Radeon DRI resume code
parent
0f094c33da
commit
07a9b30082
|
@ -975,10 +975,36 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
|
||||||
RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
|
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 )
|
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;
|
||||||
u32 tmp;
|
|
||||||
DRM_DEBUG( "\n" );
|
DRM_DEBUG( "\n" );
|
||||||
|
|
||||||
dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
|
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;
|
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,
|
if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
|
||||||
&dev_priv->bus_pci_gart)) {
|
&dev_priv->bus_pci_gart)) {
|
||||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
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);
|
radeon_do_cleanup_cp(dev);
|
||||||
return DRM_ERR(ENOMEM);
|
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
|
/* Turn on PCI GART */
|
||||||
*/
|
radeon_set_pcigart( dev_priv, 1 );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
radeon_cp_load_microcode( dev_priv );
|
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.
|
/* 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
|
* 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
|
* here we make sure that all Radeon hardware initialisation is re-done without
|
||||||
* affecting running applications. This function is called radeon_do_resume_cp()
|
* affecting running applications.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Charl P. Botha <http://cpbotha.net>
|
* 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;
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
u32 tmp;
|
|
||||||
DRM_DEBUG( "\n" );
|
if ( !dev_priv ) {
|
||||||
|
DRM_ERROR( "Called with no initialization\n" );
|
||||||
|
return DRM_ERR( EINVAL );
|
||||||
|
}
|
||||||
|
|
||||||
DRM_DEBUG("Starting radeon_do_resume_cp()\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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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 );
|
|
||||||
|
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
if ( !dev_priv->is_pci ) {
|
if ( !dev_priv->is_pci ) {
|
||||||
/* Turn off PCI GART
|
/* Turn off PCI GART */
|
||||||
*/
|
radeon_set_pcigart( dev_priv, 0 );
|
||||||
tmp = RADEON_READ( RADEON_AIC_CNTL )
|
|
||||||
& ~RADEON_PCIGART_TRANSLATE_EN;
|
|
||||||
RADEON_WRITE( RADEON_AIC_CNTL, tmp );
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* I'm not so sure about this ati_picgart_init after at resume-time... */
|
/* Turn on PCI GART */
|
||||||
if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
|
radeon_set_pcigart( dev_priv, 1 );
|
||||||
&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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
radeon_cp_load_microcode( dev_priv );
|
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 );
|
radeon_do_engine_reset( dev );
|
||||||
|
|
||||||
|
DRM_DEBUG("radeon_do_resume_cp() complete\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,8 @@
|
||||||
* R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
|
* R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
|
||||||
* 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
|
* 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 'GET' queries for starting additional clients on different VT's.
|
||||||
* Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
|
* 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
|
||||||
* 1.9 - Add texture rectangle support for r100.
|
* Add texture rectangle support for r100.
|
||||||
*/
|
*/
|
||||||
#define DRIVER_IOCTLS \
|
#define DRIVER_IOCTLS \
|
||||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
|
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
|
||||||
|
|
|
@ -975,10 +975,36 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
|
||||||
RADEON_ISYNC_CPSCRATCH_IDLEGUI) );
|
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 )
|
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;
|
||||||
u32 tmp;
|
|
||||||
DRM_DEBUG( "\n" );
|
DRM_DEBUG( "\n" );
|
||||||
|
|
||||||
dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
|
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;
|
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,
|
if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
|
||||||
&dev_priv->bus_pci_gart)) {
|
&dev_priv->bus_pci_gart)) {
|
||||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
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);
|
radeon_do_cleanup_cp(dev);
|
||||||
return DRM_ERR(ENOMEM);
|
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
|
/* Turn on PCI GART */
|
||||||
*/
|
radeon_set_pcigart( dev_priv, 1 );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
radeon_cp_load_microcode( dev_priv );
|
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.
|
/* 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
|
* 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
|
* here we make sure that all Radeon hardware initialisation is re-done without
|
||||||
* affecting running applications. This function is called radeon_do_resume_cp()
|
* affecting running applications.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Charl P. Botha <http://cpbotha.net>
|
* 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;
|
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||||
u32 tmp;
|
|
||||||
DRM_DEBUG( "\n" );
|
if ( !dev_priv ) {
|
||||||
|
DRM_ERROR( "Called with no initialization\n" );
|
||||||
|
return DRM_ERR( EINVAL );
|
||||||
|
}
|
||||||
|
|
||||||
DRM_DEBUG("Starting radeon_do_resume_cp()\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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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 );
|
|
||||||
|
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
if ( !dev_priv->is_pci ) {
|
if ( !dev_priv->is_pci ) {
|
||||||
/* Turn off PCI GART
|
/* Turn off PCI GART */
|
||||||
*/
|
radeon_set_pcigart( dev_priv, 0 );
|
||||||
tmp = RADEON_READ( RADEON_AIC_CNTL )
|
|
||||||
& ~RADEON_PCIGART_TRANSLATE_EN;
|
|
||||||
RADEON_WRITE( RADEON_AIC_CNTL, tmp );
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* I'm not so sure about this ati_picgart_init after at resume-time... */
|
/* Turn on PCI GART */
|
||||||
if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
|
radeon_set_pcigart( dev_priv, 1 );
|
||||||
&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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
radeon_cp_load_microcode( dev_priv );
|
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 );
|
radeon_do_engine_reset( dev );
|
||||||
|
|
||||||
|
DRM_DEBUG("radeon_do_resume_cp() complete\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue