rpms/kernel/devel drm-modesetting-radeon.patch, 1.20, 1.21 kernel.spec, 1.930, 1.931

Dave Airlie airlied at fedoraproject.org
Fri Sep 5 06:29:57 UTC 2008


Author: airlied

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv5231

Modified Files:
	drm-modesetting-radeon.patch kernel.spec 
Log Message:
* Fri Sep 05 2008 Dave Airlie <airlied at redhat.com>
- introduce radeon suspend/resume + change pin api


drm-modesetting-radeon.patch:

Index: drm-modesetting-radeon.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/drm-modesetting-radeon.patch,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- drm-modesetting-radeon.patch	5 Sep 2008 01:28:57 -0000	1.20
+++ drm-modesetting-radeon.patch	5 Sep 2008 06:29:56 -0000	1.21
@@ -1,9 +1,29 @@
-commit 6d533f4ec5624d7d294f5ce5d698c30d4382b4bd
+commit 7111e3e07597d2eaeea9e39e22e9228458eb615b
 Author: Dave Airlie <airlied at redhat.com>
 Date:   Fri Sep 5 11:26:55 2008 +1000
 
     drm: export drm_i915_flip_t type to userspace to build Mesa
 
+commit b27e23f97a6896b0b9fb3981fbcc78246598fb1d
+Author: Dave Airlie <airlied at redhat.com>
+Date:   Fri Sep 5 16:12:59 2008 +1000
+
+    radeon: further suspend/resume support
+
+commit a17cee00496d74239715d8a8b653a87e8703201e
+Author: Dave Airlie <airlied at redhat.com>
+Date:   Fri Aug 29 14:52:15 2008 +1000
+
+    radeon: add initial suspend/resume support
+    
+    this gets us back to fbcon.. its dirty like zebra
+
+commit 0eea7b4958401d85f6191ee6fcd095eaff569052
+Author: Dave Airlie <airlied at redhat.com>
+Date:   Fri Aug 29 14:51:46 2008 +1000
+
+    drm/modesetting: add helper to force restore modes on crtcs at resume time
+
 commit 3b5d57a098300ad79dd2693e4480a83d7fd2298c
 Author: Dave Airlie <airlied at redhat.com>
 Date:   Fri Sep 5 11:15:03 2008 +1000
@@ -1608,10 +1628,10 @@
  	return -EINVAL;
 diff --git a/drivers/gpu/drm/drm_bo.c b/drivers/gpu/drm/drm_bo.c
 new file mode 100644
-index 0000000..d2d7d9d
+index 0000000..6ef99d2
 --- /dev/null
 +++ b/drivers/gpu/drm/drm_bo.c
-@@ -0,0 +1,2062 @@
+@@ -0,0 +1,2109 @@
 +/**************************************************************************
 + *
 + * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
@@ -2125,6 +2145,7 @@
 +		entry = list_entry(list, struct drm_buffer_object, ddestroy);
 +
 +		nentry = NULL;
++		DRM_DEBUG("bo is %p, %d\n", entry, entry->num_pages);
 +		if (next != &bm->ddestroy) {
 +			nentry = list_entry(next, struct drm_buffer_object,
 +					    ddestroy);
@@ -2935,14 +2956,15 @@
 +
 +	int ret;
 +
-+	DRM_DEBUG("Proposed flags 0x%016llx, Old flags 0x%016llx\n",
-+		  (unsigned long long) bo->mem.proposed_flags,
-+		  (unsigned long long) bo->mem.flags);
 +
 +	ret = drm_bo_modify_proposed_flags (bo, flags, mask);
 +	if (ret)
 +		return ret;
 +
++	DRM_DEBUG("Proposed flags 0x%016llx, Old flags 0x%016llx\n",
++		  (unsigned long long) bo->mem.proposed_flags,
++		  (unsigned long long) bo->mem.flags);
++
 +	ret = drm_bo_wait_unmapped(bo, no_wait);
 +	if (ret)
 +		return ret;
@@ -3674,6 +3696,51 @@
 +
 +	return 0;
 +}
++
++/* used to EVICT VRAM lru at suspend time */
++void drm_bo_evict_mm(struct drm_device *dev, int mem_type, int no_wait)
++{
++	struct drm_buffer_manager *bm = &dev->bm;
++	struct drm_mem_type_manager *man = &bm->man[mem_type];
++	struct drm_buffer_object *entry;
++	/* we need to migrate all objects in VRAM */
++	struct list_head *lru;
++	int ret;
++	/* evict all buffers on the LRU - won't evict pinned buffers */
++
++	mutex_lock(&dev->struct_mutex);
++	do {
++		lru = &man->lru;
++
++		if (lru->next == lru) {
++			DRM_ERROR("lru empty\n");
++			break;
++		}
++
++		entry = list_entry(lru->next, struct drm_buffer_object, lru);
++		atomic_inc(&entry->usage);
++		mutex_unlock(&dev->struct_mutex);
++		mutex_lock(&entry->mutex);
++
++		DRM_ERROR("Evicting %p %d\n", entry, entry->num_pages);
++		ret = drm_bo_evict(entry, mem_type, no_wait);
++		mutex_unlock(&entry->mutex);
++
++		if (ret)
++			DRM_ERROR("Evict failed for BO\n");
++
++		mutex_lock(&entry->mutex);
++		(void)drm_bo_expire_fence(entry, 0);
++		mutex_unlock(&entry->mutex);
++		drm_bo_usage_deref_unlocked(&entry);
++
++		mutex_lock(&dev->struct_mutex);
++	} while(0);
++
++	mutex_unlock(&dev->struct_mutex);
++
++}
++EXPORT_SYMBOL(drm_bo_evict_mm);
 diff --git a/drivers/gpu/drm/drm_bo_move.c b/drivers/gpu/drm/drm_bo_move.c
 new file mode 100644
 index 0000000..7a4b95b
@@ -7023,10 +7090,10 @@
 +}
 diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
 new file mode 100644
-index 0000000..708354a
+index 0000000..b507315
 --- /dev/null
 +++ b/drivers/gpu/drm/drm_crtc_helper.c
-@@ -0,0 +1,787 @@
+@@ -0,0 +1,805 @@
 +/* (c) 2006-2007 Intel Corporation
 + * Copyright (c) 2007 Dave Airlie <airlied at linux.ie>
 + *
@@ -7813,7 +7880,25 @@
 +}
 +EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
 +
++int drm_helper_resume_force_mode(struct drm_device *dev)
++{
++	struct drm_crtc *crtc;
++	int ret;
++
++	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
++
++		if (!crtc->enabled)
++			continue;
++		
++		ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
++					       crtc->y);
 +
++		if (ret == false)
++			DRM_ERROR("failed to set mode on crtc %p\n", crtc);
++	}
++	return 0;
++}
++EXPORT_SYMBOL(drm_helper_resume_force_mode);
 diff --git a/drivers/gpu/drm/drm_dma.c b/drivers/gpu/drm/drm_dma.c
 index 7a8e2fb..0b2df71 100644
 --- a/drivers/gpu/drm/drm_dma.c
@@ -8776,10 +8861,10 @@
 +EXPORT_SYMBOL(drm_add_edid_modes);
 diff --git a/drivers/gpu/drm/drm_fence.c b/drivers/gpu/drm/drm_fence.c
 new file mode 100644
-index 0000000..7130d1b
+index 0000000..f1c386c
 --- /dev/null
 +++ b/drivers/gpu/drm/drm_fence.c
-@@ -0,0 +1,543 @@
+@@ -0,0 +1,540 @@
 +/**************************************************************************
 + *
 + * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
@@ -9163,7 +9248,6 @@
 +	if (driver->wait)
 +		return driver->wait(fence, lazy, !ignore_signals, mask);
 +
-+
 +	drm_fence_object_flush(fence, mask);
 +	if (driver->has_irq(dev, fence->fence_class, mask)) {
 +		if (!ignore_signals)
@@ -9191,8 +9275,6 @@
 +}
 +EXPORT_SYMBOL(drm_fence_object_wait);
 +
-+
-+
 +int drm_fence_object_emit(struct drm_fence_object *fence, uint32_t fence_flags,
 +			  uint32_t fence_class, uint32_t type)
 +{
@@ -20457,7 +20539,7 @@
 +
 +#endif /* _I915_REG_H_ */
 diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
-index feb521e..a802a28 100644
+index feb521e..f611328 100644
 --- a/drivers/gpu/drm/radeon/Makefile
 +++ b/drivers/gpu/drm/radeon/Makefile
 @@ -3,7 +3,11 @@
@@ -20469,7 +20551,7 @@
 +	    radeon_gem.o radeon_buffer.o radeon_fence.o radeon_cs.o \
 +	    radeon_i2c.o radeon_fb.o radeon_encoders.o radeon_connectors.o radeon_display.o \
 +	    atombios_crtc.o atom.o radeon_atombios.o radeon_combios.o radeon_legacy_crtc.o \
-+	    radeon_legacy_encoders.o radeon_cursor.o
++	    radeon_legacy_encoders.o radeon_cursor.o radeon_pm.o
  
  radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
  
@@ -21173,10 +21255,10 @@
 +#endif
 diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
 new file mode 100644
-index 0000000..33fb02f
+index 0000000..2a660a4
 --- /dev/null
 +++ b/drivers/gpu/drm/radeon/atom.c
-@@ -0,0 +1,1145 @@
+@@ -0,0 +1,1143 @@
 +/*
 + * Copyright 2008 Advanced Micro Devices, Inc.  
 + *
@@ -21449,7 +21531,6 @@
 +	if(print)
 +	    DEBUG("MC[0x%02X]", idx);
 +	val = gctx->card->mc_read(gctx->card, idx);
-+	printk(KERN_INFO "MC registers are not implemented.\n");
 +	return 0;
 +    }
 +    if(saved)
@@ -21631,7 +21712,6 @@
 +	(*ptr)++;
 +	DEBUG("MC[0x%02X]", idx);
 +	gctx->card->mc_write(gctx->card, idx, val);
-+	printk(KERN_INFO "MC registers are not implemented.\n");
 +	return;
 +    }
 +    switch(align) {
@@ -30455,7 +30535,7 @@
 +	return NULL;
 +}
 diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
-index 248ab4a..e96037e 100644
+index 248ab4a..8994326 100644
 --- a/drivers/gpu/drm/radeon/radeon_cp.c
 +++ b/drivers/gpu/drm/radeon/radeon_cp.c
 @@ -31,6 +31,7 @@
@@ -30547,9 +30627,7 @@
 -	drm_radeon_private_t *dev_priv = dev->dev_private;
 +	if (!(dev_priv->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS))
 +		return;
- 
--	RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
--	return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
++
 +	(void)RADEON_READ(RADEON_CLOCK_CNTL_DATA);
 +	(void)RADEON_READ(RADEON_CRTC_GEN_CNTL);
 +}
@@ -30577,7 +30655,9 @@
 +		RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, save);
 +	}
 +}
-+
+ 
+-	RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
+-	return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
 +u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr)
 +{
 +	uint32_t data;
@@ -30647,7 +30727,15 @@
  		RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
  	}
  	RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
-@@ -492,15 +614,15 @@ static int radeon_do_engine_reset(struct drm_device * dev)
+@@ -397,7 +519,6 @@ static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv)
+ 	DRM_DEBUG("\n");
+ #if 0
+ 	u32 tmp;
+-
+ 	tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31);
+ 	RADEON_WRITE(RADEON_CP_RB_WPTR, tmp);
+ #endif
+@@ -492,15 +613,15 @@ static int radeon_do_engine_reset(struct drm_device * dev)
  	if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
  		/* may need something similar for newer chips */
  		clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
@@ -30672,7 +30760,7 @@
  	}
  
  	rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
-@@ -525,7 +647,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)
+@@ -525,7 +646,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)
  	RADEON_READ(RADEON_RBBM_SOFT_RESET);
  
  	if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
@@ -30681,7 +30769,7 @@
  		RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
  		RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
  	}
-@@ -541,7 +663,8 @@ static int radeon_do_engine_reset(struct drm_device * dev)
+@@ -541,7 +662,8 @@ static int radeon_do_engine_reset(struct drm_device * dev)
  	dev_priv->cp_running = 0;
  
  	/* Reset any pending vertex, indirect buffers */
@@ -30691,7 +30779,7 @@
  
  	return 0;
  }
-@@ -559,9 +682,13 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
+@@ -559,9 +681,13 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
  	 */
  	if (!dev_priv->new_memmap)
  		radeon_write_fb_location(dev_priv,
@@ -30708,7 +30796,7 @@
  #if __OS_HAS_AGP
  	if (dev_priv->flags & RADEON_IS_AGP) {
  		radeon_write_agp_base(dev_priv, dev->agp->base);
-@@ -569,7 +696,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
+@@ -569,7 +695,7 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
  		radeon_write_agp_location(dev_priv,
  			     (((dev_priv->gart_vm_start - 1 +
  				dev_priv->gart_size) & 0xffff0000) |
@@ -30717,7 +30805,7 @@
  
  		ring_start = (dev_priv->cp_ring->offset
  			      - dev->agp->base
-@@ -591,6 +718,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
+@@ -591,6 +717,12 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
  	SET_RING_HEAD(dev_priv, cur_read_ptr);
  	dev_priv->ring.tail = cur_read_ptr;
  
@@ -30730,7 +30818,16 @@
  #if __OS_HAS_AGP
  	if (dev_priv->flags & RADEON_IS_AGP) {
  		RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
-@@ -639,9 +772,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
+@@ -626,8 +758,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
+ 		     dev_priv->ring.size_l2qw);
+ #endif
+ 
+-	/* Start with assuming that writeback doesn't work */
+-	dev_priv->writeback_works = 0;
+ 
+ 	/* Initialize the scratch register pointer.  This will cause
+ 	 * the scratch register values to be written out to memory
+@@ -639,9 +769,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
  	RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
  		     + RADEON_SCRATCH_REG_OFFSET);
  
@@ -30748,7 +30845,7 @@
  
  	RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
  
-@@ -649,39 +787,50 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
+@@ -649,39 +784,50 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
  	tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
  	RADEON_WRITE(RADEON_BUS_CNTL, tmp);
  
@@ -30809,7 +30906,7 @@
  		    0xdeadbeef)
  			break;
  		DRM_UDELAY(1);
-@@ -700,9 +849,8 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
+@@ -700,9 +846,8 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
  	}
  
  	if (!dev_priv->writeback_works) {
@@ -30821,7 +30918,7 @@
  		RADEON_WRITE(RADEON_SCRATCH_UMSK, 0);
  	}
  }
-@@ -714,11 +862,12 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
+@@ -714,11 +859,12 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
  
  	if (on) {
  		DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
@@ -30837,7 +30934,7 @@
  		if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
  			IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN |
  							     RS690_BLOCK_GFX_D3_EN));
-@@ -742,13 +891,20 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
+@@ -742,13 +888,20 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
  		IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) |
  						      RS480_REQ_TYPE_SNOOP_DIS));
  
@@ -30862,7 +30959,7 @@
  
  		temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE);
  		IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
-@@ -759,7 +915,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
+@@ -759,7 +912,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
  			if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
  				break;
  			DRM_UDELAY(1);
@@ -30871,7 +30968,7 @@
  
  		IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL,
  				RS480_GART_CACHE_INVALIDATE);
-@@ -769,7 +925,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
+@@ -769,7 +922,7 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
  			if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
  				break;
  			DRM_UDELAY(1);
@@ -30880,7 +30977,7 @@
  
  		IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0);
  	} else {
-@@ -796,7 +952,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
+@@ -796,7 +949,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
  				  dev_priv->gart_vm_start +
  				  dev_priv->gart_size - 1);
  
@@ -30889,7 +30986,7 @@
  
  		RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
  				  RADEON_PCIE_TX_GART_EN);
-@@ -807,7 +963,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
+@@ -807,7 +960,7 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
  }
  
  /* Enable or disable PCI GART on the chip */
@@ -30898,7 +30995,7 @@
  {
  	u32 tmp;
  
-@@ -840,7 +996,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
+@@ -840,7 +993,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
  
  		/* Turn off AGP aperture -- is this required for PCI GART?
  		 */
@@ -30907,7 +31004,7 @@
  		RADEON_WRITE(RADEON_AGP_COMMAND, 0);	/* clear AGP_COMMAND */
  	} else {
  		RADEON_WRITE(RADEON_AIC_CNTL,
-@@ -848,9 +1004,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
+@@ -848,9 +1001,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
  	}
  }
  
@@ -30920,7 +31017,7 @@
  
  	DRM_DEBUG("\n");
  
-@@ -888,17 +1046,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+@@ -888,17 +1043,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
  	 */
  	dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
  
@@ -30938,7 +31035,7 @@
  	dev_priv->do_boxes = 0;
  	dev_priv->cp_mode = init->cp_mode;
  
-@@ -946,9 +1093,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+@@ -946,9 +1090,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
  	 */
  	dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
  					   (dev_priv->color_fmt << 10) |
@@ -30950,7 +31047,7 @@
  	dev_priv->depth_clear.rb3d_zstencilcntl =
  	    (dev_priv->depth_fmt |
  	     RADEON_Z_TEST_ALWAYS |
-@@ -975,8 +1121,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+@@ -975,8 +1118,8 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
  	dev_priv->buffers_offset = init->buffers_offset;
  	dev_priv->gart_textures_offset = init->gart_textures_offset;
  
@@ -30961,7 +31058,7 @@
  		DRM_ERROR("could not find sarea!\n");
  		radeon_do_cleanup_cp(dev);
  		return -EINVAL;
-@@ -1012,10 +1158,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+@@ -1012,10 +1155,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
  		}
  	}
  
@@ -30972,7 +31069,7 @@
  #if __OS_HAS_AGP
  	if (dev_priv->flags & RADEON_IS_AGP) {
  		drm_core_ioremap(dev_priv->cp_ring, dev);
-@@ -1145,28 +1287,41 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+@@ -1145,28 +1284,41 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
  		dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
  		/* if we have an offset set from userspace */
  		if (dev_priv->pcigart_offset_set) {
@@ -31034,7 +31131,7 @@
  			if (dev_priv->flags & RADEON_IS_IGPGART)
  				dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
  			else
-@@ -1175,12 +1330,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+@@ -1175,12 +1327,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
  			    DRM_ATI_GART_MAIN;
  			dev_priv->gart_info.addr = NULL;
  			dev_priv->gart_info.bus_addr = 0;
@@ -31048,6 +31145,16 @@
  		}
  
  		if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
+@@ -1193,6 +1340,9 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
+ 		radeon_set_pcigart(dev_priv, 1);
+ 	}
+ 
++	/* Start with assuming that writeback doesn't work */
++	dev_priv->writeback_works = 0;
++
+ 	radeon_cp_load_microcode(dev_priv);
+ 	radeon_cp_init_ring_buffer(dev, dev_priv);
+ 
 @@ -1237,14 +1387,16 @@ static int radeon_do_cleanup_cp(struct drm_device * dev)
  		if (dev_priv->gart_info.bus_addr) {
  			/* Turn off PCI GART */
@@ -31178,7 +31285,7 @@
  	LOCK_TEST_WITH_RETURN(dev, file_priv);
  
  	return radeon_do_engine_reset(dev);
-@@ -1688,6 +1866,553 @@ int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_
+@@ -1688,6 +1866,602 @@ int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_
  	return ret;
  }
  
@@ -31611,14 +31718,64 @@
 +	
 +}
 +
-+int radeon_modeset_cp_init(struct drm_device *dev)
++int radeon_modeset_cp_suspend(struct drm_device *dev)
++{
++	drm_radeon_private_t *dev_priv = dev->dev_private;
++	int ret;
++
++	ret = radeon_do_cp_idle(dev_priv);
++	if (ret)
++		DRM_ERROR("failed to idle CP on suspend\n");
++
++	radeon_do_cp_stop(dev_priv);
++	radeon_do_engine_reset(dev);
++	if (dev_priv->flags & RADEON_IS_AGP) {
++	} else {
++		radeon_set_pcigart(dev_priv, 0);
++	}
++	
++	return 0;
++}
++
++int radeon_modeset_cp_resume(struct drm_device *dev)
 +{
 +	drm_radeon_private_t *dev_priv = dev->dev_private;
 +	uint32_t tmp;
 +
++	radeon_do_wait_for_idle(dev_priv);
++#if __OS_HAS_AGP
++	if (dev_priv->flags & RADEON_IS_AGP) {
++		/* Turn off PCI GART */
++		radeon_set_pcigart(dev_priv, 0);
++	} else
++#endif
++	{
++		/* Turn on PCI GART */
++		radeon_set_pcigart(dev_priv, 1);
++	}
++	radeon_gart_flush(dev);
++
++	DRM_ERROR("microcode loading\n");
++	radeon_cp_load_microcode(dev_priv);
++	radeon_cp_init_ring_buffer(dev, dev_priv);
++
++	DRM_ERROR("engine init\n");
++	radeon_do_engine_reset(dev);
++
++	radeon_do_cp_start(dev_priv);
++	return 0;
++}
++
++int radeon_modeset_cp_init(struct drm_device *dev)
++{
++	drm_radeon_private_t *dev_priv = dev->dev_private;
++
 +	/* allocate a ring and ring rptr bits from GART space */
 +	/* these are allocated in GEM files */
 +	
++	/* Start with assuming that writeback doesn't work */
++	dev_priv->writeback_works = 0;
++
 +	dev_priv->usec_timeout = RADEON_DEFAULT_CP_TIMEOUT;
 +	dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE;
 +	dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM;
@@ -31637,23 +31794,8 @@
 +	dev_priv->new_memmap = true;
 +
 +	r300_init_reg_flags(dev);
-+		
-+	radeon_cp_load_microcode(dev_priv);
 +	
-+	DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset);
-+
-+	radeon_cp_init_ring_buffer(dev, dev_priv);
-+
-+	/* need to enable BUS mastering in Buscntl */
-+	tmp = RADEON_READ(RADEON_BUS_CNTL);
-+	tmp &= ~RADEON_BUS_MASTER_DIS;
-+	RADEON_WRITE(RADEON_BUS_CNTL, tmp);
-+
-+	radeon_do_engine_reset(dev);
-+	radeon_test_writeback(dev_priv);
-+
-+	radeon_do_cp_start(dev_priv);
-+	return 0;
++	return radeon_modeset_cp_resume(dev);
 +}
 +
 +static bool radeon_get_bios(struct drm_device *dev)
@@ -31728,11 +31870,25 @@
 +	return 0;
 +}
 +
++int radeon_static_clocks_init(struct drm_device *dev)
++{
++	drm_radeon_private_t *dev_priv = dev->dev_private;
++
++	if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) {
++		radeon_set_dynamic_clock(dev, radeon_dynclks);
++	} else if (radeon_is_avivo(dev_priv)) {
++		if (radeon_dynclks) {
++			radeon_atom_static_pwrmgt_setup(dev, 1);
++			radeon_atom_dyn_clk_setup(dev, 1);
++		}
++	}
++	radeon_force_some_clocks(dev);
++}
 +
  int radeon_driver_load(struct drm_device *dev, unsigned long flags)
  {
  	drm_radeon_private_t *dev_priv;
-@@ -1701,6 +2426,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
+@@ -1701,6 +2475,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
  	dev->dev_private = (void *)dev_priv;
  	dev_priv->flags = flags;
  
@@ -31741,7 +31897,7 @@
  	switch (flags & RADEON_FAMILY_MASK) {
  	case CHIP_R100:
  	case CHIP_RV200:
-@@ -1720,18 +2447,129 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
+@@ -1720,18 +2496,119 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
  		break;
  	}
  
@@ -31773,7 +31929,6 @@
 +	if (drm_core_check_feature(dev, DRIVER_MODESET))
 +		radeon_modeset_preinit(dev);
 +
-+
 +	radeon_get_vram_type(dev);
 +
 +	dev_priv->pll_errata = 0;
@@ -31793,17 +31948,8 @@
 +		dev_priv->pll_errata |= CHIP_ERRATA_PLL_DELAY;
 +
 +
-+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-+		if ((dev_priv->flags & RADEON_IS_MOBILITY) && !radeon_is_avivo(dev_priv)) {
-+			radeon_set_dynamic_clock(dev, radeon_dynclks);
-+		} else if (radeon_is_avivo(dev_priv)) {
-+			if (radeon_dynclks) {
-+				radeon_atom_static_pwrmgt_setup(dev, 1);
-+				radeon_atom_dyn_clk_setup(dev, 1);
-+			}
-+		}
-+		radeon_force_some_clocks(dev);
-+	}
++	if (drm_core_check_feature(dev, DRIVER_MODESET))
++		radeon_static_clocks_init(dev);
 +		
 +	/* init memory manager - start with all of VRAM and a 32MB GART aperture for now */
 +	dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
@@ -31872,7 +32018,7 @@
  /* Create mappings for registers and framebuffer so userland doesn't necessarily
   * have to find them.
   */
-@@ -1743,19 +2581,6 @@ int radeon_driver_firstopen(struct drm_device *dev)
+@@ -1743,19 +2620,6 @@ int radeon_driver_firstopen(struct drm_device *dev)
  
  	dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
  
@@ -31892,7 +32038,7 @@
  	return 0;
  }
  
-@@ -1763,9 +2588,40 @@ int radeon_driver_unload(struct drm_device *dev)
+@@ -1763,9 +2627,40 @@ int radeon_driver_unload(struct drm_device *dev)
  {
  	drm_radeon_private_t *dev_priv = dev->dev_private;
  
@@ -33251,7 +33397,7 @@
 +
 +}
 diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
-index 637bd7f..36335a7 100644
+index 637bd7f..9a96b05 100644
 --- a/drivers/gpu/drm/radeon/radeon_drv.c
 +++ b/drivers/gpu/drm/radeon/radeon_drv.c
 @@ -35,12 +35,20 @@
@@ -33310,7 +33456,16 @@
  	.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
  	.load = radeon_driver_load,
  	.firstopen = radeon_driver_firstopen,
-@@ -80,7 +109,11 @@ static struct drm_driver driver = {
+@@ -69,6 +98,8 @@ static struct drm_driver driver = {
+ 	.postclose = radeon_driver_postclose,
+ 	.lastclose = radeon_driver_lastclose,
+ 	.unload = radeon_driver_unload,
++	.suspend = radeon_suspend,
++	.resume = radeon_resume,
+ 	.vblank_wait = radeon_driver_vblank_wait,
+ 	.vblank_wait2 = radeon_driver_vblank_wait2,
+ 	.dri_library_name = dri_library_name,
+@@ -80,7 +111,11 @@ static struct drm_driver driver = {
  	.get_map_ofs = drm_core_get_map_ofs,
  	.get_reg_ofs = drm_core_get_reg_ofs,
  	.ioctls = radeon_ioctls,
@@ -33322,7 +33477,7 @@
  	.fops = {
  		 .owner = THIS_MODULE,
  		 .open = drm_open,
-@@ -99,6 +132,9 @@ static struct drm_driver driver = {
+@@ -99,6 +134,9 @@ static struct drm_driver driver = {
  		 .id_table = pciidlist,
  	},
  
@@ -33332,7 +33487,7 @@
  	.name = DRIVER_NAME,
  	.desc = DRIVER_DESC,
  	.date = DRIVER_DATE,
-@@ -110,6 +146,23 @@ static struct drm_driver driver = {
+@@ -110,6 +148,23 @@ static struct drm_driver driver = {
  static int __init radeon_init(void)
  {
  	driver.num_ioctls = radeon_max_ioctl;
@@ -33357,7 +33512,7 @@
  }
  
 diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
-index 0993816..7eebd51 100644
+index 0993816..e35122e 100644
 --- a/drivers/gpu/drm/radeon/radeon_drv.h
 +++ b/drivers/gpu/drm/radeon/radeon_drv.h
 @@ -34,6 +34,8 @@
@@ -33450,7 +33605,7 @@
  
  typedef struct drm_radeon_freelist {
  	unsigned int age;
-@@ -223,14 +264,61 @@ struct radeon_virt_surface {
+@@ -223,14 +264,68 @@ struct radeon_virt_surface {
  #define RADEON_FLUSH_EMITED	(1 < 0)
  #define RADEON_PURGE_EMITED	(1 < 1)
  
@@ -33468,6 +33623,8 @@
 +	
 +	uint64_t gart_start;
 +	uint64_t gart_size;
++
++	void *pcie_table_backup;
 +	
 +	struct radeon_mm_obj pcie_table;
 +	struct radeon_mm_obj ring;
@@ -33508,6 +33665,11 @@
 +	int (*relocate)(struct drm_device *dev, struct drm_file *file_priv,
 +			 uint32_t *reloc, uint32_t *offset);
 +};
++
++struct radeon_pm_regs {
++	uint32_t crtc_ext_cntl;
++	uint32_t bios_scratch[8];
++};
  
 +typedef struct drm_radeon_private {
 +	drm_radeon_ring_buffer_t ring;
@@ -33517,7 +33679,7 @@
  	int gart_size;
  	u32 gart_vm_start;
  	unsigned long gart_buffers_offset;
-@@ -246,8 +334,6 @@ typedef struct drm_radeon_private {
+@@ -246,8 +341,6 @@ typedef struct drm_radeon_private {
  
  	int usec_timeout;
  
@@ -33526,7 +33688,7 @@
  	struct {
  		u32 boxes;
  		int freelist_timeouts;
-@@ -283,8 +369,6 @@ typedef struct drm_radeon_private {
+@@ -283,8 +376,6 @@ typedef struct drm_radeon_private {
  	unsigned long buffers_offset;
  	unsigned long gart_textures_offset;
  
@@ -33535,7 +33697,7 @@
  	drm_local_map_t *cp_ring;
  	drm_local_map_t *ring_rptr;
  	drm_local_map_t *gart_textures;
-@@ -293,8 +377,8 @@ typedef struct drm_radeon_private {
+@@ -293,8 +384,8 @@ typedef struct drm_radeon_private {
  	struct mem_block *fb_heap;
  
  	/* SW interrupt */
@@ -33545,7 +33707,7 @@
  	int vblank_crtc;
  	uint32_t irq_enable_reg;
  	int irq_enabled;
-@@ -303,9 +387,6 @@ typedef struct drm_radeon_private {
+@@ -303,9 +394,6 @@ typedef struct drm_radeon_private {
  	struct radeon_surface surfaces[RADEON_MAX_SURFACES];
  	struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
  
@@ -33555,7 +33717,7 @@
  
  	u32 scratch_ages[5];
  
-@@ -315,6 +396,37 @@ typedef struct drm_radeon_private {
+@@ -315,6 +403,39 @@ typedef struct drm_radeon_private {
  
  	int num_gb_pipes;
  	int track_flush;
@@ -33590,10 +33752,12 @@
 +	/* ib bitmap */
 +	uint64_t ib_alloc_bitmap; // TO DO replace with a real bitmap
 +	struct drm_radeon_cs_priv cs;
++
++	struct radeon_pm_regs pmregs;
  } drm_radeon_private_t;
  
  typedef struct drm_radeon_buf_priv {
-@@ -329,6 +441,7 @@ typedef struct drm_radeon_kcmd_buffer {
+@@ -329,6 +450,7 @@ typedef struct drm_radeon_kcmd_buffer {
  } drm_radeon_kcmd_buffer_t;
  
  extern int radeon_no_wb;
@@ -33601,7 +33765,7 @@
  extern struct drm_ioctl_desc radeon_ioctls[];
  extern int radeon_max_ioctl;
  
-@@ -366,10 +479,6 @@ extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n);
+@@ -366,10 +488,6 @@ extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n);
  
  extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
  
@@ -33612,7 +33776,7 @@
  extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
  extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
  extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv);
-@@ -397,13 +506,19 @@ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
+@@ -397,13 +515,19 @@ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
  extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
  extern int radeon_driver_unload(struct drm_device *dev);
  extern int radeon_driver_firstopen(struct drm_device *dev);
@@ -33635,7 +33799,19 @@
  /* r300_cmdbuf.c */
  extern void r300_init_reg_flags(struct drm_device *dev);
  
-@@ -419,10 +534,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -411,6 +535,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+ 			     struct drm_file *file_priv,
+ 			     drm_radeon_kcmd_buffer_t * cmdbuf);
+ 
++extern int radeon_modeset_cp_suspend(struct drm_device *dev);
++extern int radeon_modeset_cp_resume(struct drm_device *dev);
++/* radeon_pm.c */
++int radeon_suspend(struct drm_device *dev, pm_message_t state);
++int radeon_resume(struct drm_device *dev);
+ /* Flags for stats.boxes
+  */
+ #define RADEON_BOX_DMA_IDLE      0x1
+@@ -419,10 +548,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #define RADEON_BOX_WAIT_IDLE     0x8
  #define RADEON_BOX_TEXTURE_LOAD  0x10
  
@@ -33650,7 +33826,7 @@
  #define RADEON_AGP_COMMAND		0x0f60
  #define RADEON_AGP_COMMAND_PCI_CONFIG   0x0060	/* offset in PCI config */
  #	define RADEON_AGP_ENABLE	(1<<8)
-@@ -525,16 +644,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -525,16 +658,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #define R520_MC_IND_WR_EN (1 << 24)
  #define R520_MC_IND_DATA  0x74
  
@@ -33667,7 +33843,7 @@
  #define RADEON_MPP_TB_CONFIG		0x01c0
  #define RADEON_MEM_CNTL			0x0140
  #define RADEON_MEM_SDRAM_MODE_REG	0x0158
-@@ -599,14 +708,23 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -599,14 +722,23 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #define RADEON_SCRATCH_REG3		0x15ec
  #define RADEON_SCRATCH_REG4		0x15f0
  #define RADEON_SCRATCH_REG5		0x15f4
@@ -33694,25 +33870,25 @@
  
  #define RADEON_GEN_INT_CNTL		0x0040
  #	define RADEON_CRTC_VBLANK_MASK		(1 << 0)
-@@ -623,11 +741,13 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -623,11 +755,13 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #	define RADEON_SW_INT_TEST		(1 << 25)
  #	define RADEON_SW_INT_TEST_ACK		(1 << 25)
  #	define RADEON_SW_INT_FIRE		(1 << 26)
 +#       define R500_DISPLAY_INT_STATUS          (1 << 0)
-+
-+#define RADEON_HOST_PATH_CNTL               0x0130
-+#       define RADEON_HDP_SOFT_RESET        (1 << 26)
-+#       define RADEON_HDP_APER_CNTL         (1 << 23)
  
 -#define RADEON_HOST_PATH_CNTL		0x0130
 -#	define RADEON_HDP_SOFT_RESET		(1 << 26)
 -#	define RADEON_HDP_WC_TIMEOUT_MASK	(7 << 28)
 -#	define RADEON_HDP_WC_TIMEOUT_28BCLK	(7 << 28)
++#define RADEON_HOST_PATH_CNTL               0x0130
++#       define RADEON_HDP_SOFT_RESET        (1 << 26)
++#       define RADEON_HDP_APER_CNTL         (1 << 23)
++
 +#define RADEON_NB_TOM                       0x15c
  
  #define RADEON_ISYNC_CNTL		0x1724
  #	define RADEON_ISYNC_ANY2D_IDLE3D	(1 << 0)
-@@ -666,12 +786,17 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -666,12 +800,17 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #define RADEON_PP_TXFILTER_1		0x1c6c
  #define RADEON_PP_TXFILTER_2		0x1c84
  
@@ -33736,7 +33912,7 @@
  #define RADEON_RB3D_CNTL		0x1c3c
  #	define RADEON_ALPHA_BLEND_ENABLE	(1 << 0)
  #	define RADEON_PLANE_MASK_ENABLE		(1 << 1)
-@@ -698,11 +823,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -698,11 +837,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #	define R300_ZC_FLUSH		        (1 << 0)
  #	define R300_ZC_FREE		        (1 << 1)
  #	define R300_ZC_BUSY		        (1 << 31)
@@ -33748,7 +33924,7 @@
  #define R300_RB3D_DSTCACHE_CTLSTAT              0x4e4c
  #	define R300_RB3D_DC_FLUSH		(2 << 0)
  #	define R300_RB3D_DC_FREE		(2 << 2)
-@@ -710,15 +830,15 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -710,15 +844,15 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #define RADEON_RB3D_ZSTENCILCNTL	0x1c2c
  #	define RADEON_Z_TEST_MASK		(7 << 4)
  #	define RADEON_Z_TEST_ALWAYS		(7 << 4)
@@ -33768,7 +33944,7 @@
  #define RADEON_RBBM_SOFT_RESET		0x00f0
  #	define RADEON_SOFT_RESET_CP		(1 <<  0)
  #	define RADEON_SOFT_RESET_HI		(1 <<  1)
-@@ -978,27 +1098,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -978,27 +1112,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #define RADEON_NUM_VERTICES_SHIFT		16
  
  #define RADEON_COLOR_FORMAT_CI8		2
@@ -33796,7 +33972,7 @@
  
  #define R200_PP_TXCBLEND_0                0x2f00
  #define R200_PP_TXCBLEND_1                0x2f10
-@@ -1109,13 +1208,41 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -1109,13 +1222,41 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  
  #define R200_SE_TCL_POINT_SPRITE_CNTL     0x22c4
  
@@ -33840,7 +34016,7 @@
  #define R500_D1CRTC_STATUS 0x609c
  #define R500_D2CRTC_STATUS 0x689c
  #define R500_CRTC_V_BLANK (1<<0)
-@@ -1156,19 +1283,35 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+@@ -1156,19 +1297,35 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
  #define RADEON_RING_HIGH_MARK		128
  
  #define RADEON_PCIGART_TABLE_SIZE      (32*1024)
@@ -33883,7 +34059,7 @@
  #define RADEON_WRITE_PCIE(addr, val)					\
  do {									\
  	RADEON_WRITE8(RADEON_PCIE_INDEX,				\
-@@ -1224,7 +1367,7 @@ do {									\
+@@ -1224,7 +1381,7 @@ do {									\
  #define RADEON_WAIT_UNTIL_2D_IDLE() do {				\
  	OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );			\
  	OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |				\
@@ -33892,7 +34068,7 @@
  } while (0)
  
  #define RADEON_WAIT_UNTIL_3D_IDLE() do {				\
-@@ -1301,8 +1444,9 @@ do {									\
+@@ -1301,8 +1458,9 @@ do {									\
  } while (0)
  
  #define VB_AGE_TEST_WITH_RETURN( dev_priv )				\
@@ -33904,7 +34080,16 @@
  	if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) {		\
  		int __ret = radeon_do_cp_idle( dev_priv );		\
  		if ( __ret ) return __ret;				\
-@@ -1408,4 +1552,139 @@ do {									\
+@@ -1330,7 +1488,7 @@ do {									\
+  * Ring control
+  */
+ 
+-#define RADEON_VERBOSE	0
++#define RADEON_VERBOSE	1
+ 
+ #define RING_LOCALS	int write, _nr; unsigned int mask; u32 *ring;
+ 
+@@ -1408,4 +1566,142 @@ do {									\
  	write &= mask;						\
  } while (0)
  
@@ -34014,7 +34199,8 @@
 +extern int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
 +				  struct drm_file *file_priv);
 +int radeon_gem_object_pin(struct drm_gem_object *obj,
-+			  uint32_t alignment);
++			  uint32_t alignment, uint32_t pin_domain);
++int radeon_gem_object_unpin(struct drm_gem_object *obj);
 +int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
 +			      struct drm_file *file_priv);
 +int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
@@ -34036,6 +34222,8 @@
 +extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
 +extern int radeon_cs_init(struct drm_device *dev);
 +void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master);
++void radeon_init_memory_map(struct drm_device *dev);
++
 +
 +#define MARK_SAFE		1
 +#define MARK_CHECK_OFFSET	2
@@ -35133,7 +35321,7 @@
 +}
 diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
 new file mode 100644
-index 0000000..2da5cc0
+index 0000000..83d39d3
 --- /dev/null
 +++ b/drivers/gpu/drm/radeon/radeon_fb.c
 @@ -0,0 +1,923 @@
@@ -35635,7 +35823,7 @@
 +	}
 +	obj_priv = fbo->driver_private;
 +
-+	ret = radeon_gem_object_pin(fbo, PAGE_SIZE);
++	ret = radeon_gem_object_pin(fbo, PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM);
 +	if (ret) {
 +		DRM_ERROR("failed to pin fb: %d\n", ret);
 +		mutex_lock(&dev->struct_mutex);
@@ -36062,10 +36250,10 @@
 +MODULE_LICENSE("GPL");
 diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
 new file mode 100644
-index 0000000..1b32736
+index 0000000..591ad53
 --- /dev/null
 +++ b/drivers/gpu/drm/radeon/radeon_fence.c
-@@ -0,0 +1,96 @@
+@@ -0,0 +1,99 @@
 +/**************************************************************************
 + * 
 + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
@@ -36113,6 +36301,8 @@
 +		return -EINVAL;
 +
 +	radeon_emit_irq(dev);
++
++	DRM_DEBUG("emitting %d\n", dev_priv->counter);
 +	*sequence = (uint32_t) dev_priv->counter;
 +	*native_type = DRM_FENCE_TYPE_EXE;
 +
@@ -36128,6 +36318,7 @@
 +
 +                sequence = READ_BREADCRUMB(dev_priv);
 +
++		DRM_DEBUG("polling %d\n", sequence);
 +                drm_fence_handler(dev, 0, sequence,
 +                                  DRM_FENCE_TYPE_EXE, 0);
 +        }
@@ -36164,10 +36355,10 @@
 +
 diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
 new file mode 100644
-index 0000000..24c806a
+index 0000000..f4a0a6c
 --- /dev/null
 +++ b/drivers/gpu/drm/radeon/radeon_gem.c
-@@ -0,0 +1,1337 @@
+@@ -0,0 +1,1387 @@
 +/*
 + * Copyright 2008 Red Hat Inc.
 + *
@@ -36213,7 +36404,6 @@
 +
 +	obj->driver_private = obj_priv;
 +	obj_priv->obj = obj;
-+	
 +	return 0;
 +}
 +
@@ -36490,6 +36680,8 @@
 +	struct drm_gem_object *obj;
 +	struct drm_radeon_gem_object *obj_priv;
 +	int ret;
++	int flags = DRM_BO_FLAG_NO_EVICT;
++	int mask = DRM_BO_FLAG_NO_EVICT;
 +
 +	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 +	if (obj == NULL)
@@ -36499,15 +36691,24 @@
 +
 +	DRM_DEBUG("got here %p %p %d\n", obj, obj_priv->bo, atomic_read(&obj_priv->bo->usage));
 +	/* validate into a pin with no fence */
++	if (args->pin_domain) {
++		mask |= DRM_BO_MASK_MEM;
++		if (args->pin_domain == RADEON_GEM_DOMAIN_GTT)
++			flags |= DRM_BO_FLAG_MEM_TT;
++		else if (args->pin_domain == RADEON_GEM_DOMAIN_VRAM)
++			flags |= DRM_BO_FLAG_MEM_VRAM;
++		else
++			return -EINVAL;
++	}
 +
 +	if (!(obj_priv->bo->type != drm_bo_type_kernel && !DRM_SUSER(DRM_CURPROC))) {
-+		ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
++		ret = drm_bo_do_validate(obj_priv->bo, flags, mask,
 +					 DRM_BO_HINT_DONT_FENCE, 0);
 +	} else
 +	  ret = 0;
 +
 +	args->offset = obj_priv->bo->offset;
-+	DRM_DEBUG("got here %p %p\n", obj, obj_priv->bo);
++	DRM_DEBUG("got here %p %p %x\n", obj, obj_priv->bo, obj_priv->bo->offset);
 +
 +	mutex_lock(&dev->struct_mutex);
 +	drm_gem_object_unreference(obj);
@@ -36531,7 +36732,7 @@
 +
 +	/* validate into a pin with no fence */
 +
-+	ret = drm_bo_do_validate(obj_priv->bo, DRM_BO_FLAG_NO_EVICT, DRM_BO_FLAG_NO_EVICT,
++	ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
 +				 DRM_BO_HINT_DONT_FENCE, 0);
 +
 +	mutex_lock(&dev->struct_mutex);
@@ -36768,7 +36969,11 @@
 +		if (ret)
 +			return -EINVAL;
 +
-+		DRM_DEBUG("pcie table bo created %p, %x\n", dev_priv->mm.pcie_table.bo, dev_priv->mm.pcie_table.bo->offset);
++		dev_priv->mm.pcie_table_backup = kzalloc(RADEON_PCIGART_TABLE_SIZE, GFP_KERNEL);
++		if (!dev_priv->mm.pcie_table_backup)
++			return -EINVAL;
++
++		DRM_ERROR("pcie table bo created %p, %x\n", dev_priv->mm.pcie_table.bo, dev_priv->mm.pcie_table.bo->offset);
 +		ret = drm_bo_kmap(dev_priv->mm.pcie_table.bo, 0, RADEON_PCIGART_TABLE_SIZE >> PAGE_SHIFT,
 +				  &dev_priv->mm.pcie_table.kmap);
 +		if (ret)
@@ -36860,10 +37065,16 @@
 +
 +}
 +
-+static void radeon_init_memory_map(struct drm_device *dev)
++void radeon_init_memory_map(struct drm_device *dev)
 +{
 +	drm_radeon_private_t *dev_priv = dev->dev_private;
 +	u32 mem_size, aper_size;
++	u32 tmp;
++
++	/* turn off VGA IO bits */
++	tmp = RADEON_READ(RADEON_CONFIG_CNTL);
++	tmp |= (1 << 9);
++	RADEON_WRITE(RADEON_CONFIG_CNTL, tmp);
 +
 +	dev_priv->mc_fb_location = radeon_read_fb_location(dev_priv);
 +	radeon_read_agp_location(dev_priv, &dev_priv->mc_agp_loc_lo, &dev_priv->mc_agp_loc_hi);
@@ -37011,6 +37222,10 @@
 +	}
 +
 +	if (dev_priv->flags & RADEON_IS_PCIE) {
++		if (dev_priv->mm.pcie_table_backup) {
++			kfree(dev_priv->mm.pcie_table_backup);
++			dev_priv->mm.pcie_table_backup = NULL;
++		}
 +		if (dev_priv->mm.pcie_table.bo) {
 +			drm_bo_kunmap(&dev_priv->mm.pcie_table.kmap);
 +			drm_bo_usage_deref_locked(&dev_priv->mm.pcie_table.bo);
@@ -37028,7 +37243,31 @@
 +}
 +
 +int radeon_gem_object_pin(struct drm_gem_object *obj,
-+			  uint32_t alignment)
++			  uint32_t alignment, uint32_t pin_domain)
++{
++	struct drm_radeon_gem_object *obj_priv;
++	int ret;
++	uint32_t flags = DRM_BO_FLAG_NO_EVICT;
++	uint32_t mask = DRM_BO_FLAG_NO_EVICT;
++
++	obj_priv = obj->driver_private;
++
++	if (pin_domain) {
++		mask |= DRM_BO_MASK_MEM;
++		if (pin_domain == RADEON_GEM_DOMAIN_GTT)
++			flags |= DRM_BO_FLAG_MEM_TT;
++		else if (pin_domain == RADEON_GEM_DOMAIN_VRAM)
++			flags |= DRM_BO_FLAG_MEM_VRAM;
++		else
++			return -EINVAL;
++	}
++	ret = drm_bo_do_validate(obj_priv->bo, flags, mask,
++				 DRM_BO_HINT_DONT_FENCE, 0);
++
++	return ret;
++}
++
++int radeon_gem_object_unpin(struct drm_gem_object *obj)
 +{
 +	struct drm_radeon_gem_object *obj_priv;
 +	int ret;
@@ -37505,6 +37744,8 @@
 +	dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
 +
 +}
++
++
 diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
 new file mode 100644
 index 0000000..00fc7c0
@@ -40089,10 +40330,10 @@
 +}
 diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
 new file mode 100644
-index 0000000..f4d2757
+index 0000000..8236d1c
 --- /dev/null
 +++ b/drivers/gpu/drm/radeon/radeon_mode.h
-@@ -0,0 +1,331 @@
+@@ -0,0 +1,333 @@
 +/*
 + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
 + *                VA Linux Systems Inc., Fremont, California.
@@ -40423,7 +40664,195 @@
 +			   uint32_t dst_offset,
 +			   uint32_t pages);
 +void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj);
++void radeon_combios_asic_init(struct drm_device *dev);
++extern int radeon_static_clocks_init(struct drm_device *dev);
 +#endif
+diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
+new file mode 100644
+index 0000000..c7a57b9
+--- /dev/null
++++ b/drivers/gpu/drm/radeon/radeon_pm.c
+@@ -0,0 +1,180 @@
++/*
++ * Copyright 2007-8 Advanced Micro Devices, Inc.
++ * Copyright 2008 Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * Authors: Dave Airlie
++ *          Alex Deucher
++ */
++#include "drmP.h"
++#include "radeon_drm.h"
++#include "radeon_drv.h"
++
++#include "atom.h"
++
++#include "drm_crtc_helper.h"
++
++int radeon_suspend(struct drm_device *dev, pm_message_t state)
++{
++	struct drm_radeon_private *dev_priv = dev->dev_private;
++	struct drm_framebuffer *fb;
++	int i;
++
++	if (!dev || !dev_priv) {
++		return -ENODEV;
++	}
++
++	if (state.event == PM_EVENT_PRETHAW)
++		return 0;
++
++	if (!drm_core_check_feature(dev, DRIVER_MODESET))
++		return 0;
++
++	/* unpin the front buffers */
++	list_for_each_entry(fb, &dev->mode_config.fb_kernel_list, filp_head) {
++		struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
++
++		if (!radeon_fb)
++			continue;
++
++		if (!radeon_fb->obj)
++			continue;
++		
++		radeon_gem_object_unpin(radeon_fb->obj);
++	}
++
++	if (!(dev_priv->flags & RADEON_IS_IGP))
++		drm_bo_evict_mm(dev, DRM_BO_MEM_VRAM, 0);
++
++	if (dev_priv->flags & RADEON_IS_PCIE) {
++		memcpy_fromio(dev_priv->mm.pcie_table_backup, dev_priv->mm.pcie_table.kmap.virtual, RADEON_PCIGART_TABLE_SIZE);
++	}
++
++	dev_priv->pmregs.crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL);
++	for (i = 0; i < 8; i++)
++		dev_priv->pmregs.bios_scratch[i] = RADEON_READ(RADEON_BIOS_0_SCRATCH + (i * 4));
++
++	radeon_modeset_cp_suspend(dev);
++
++	pci_save_state(dev->pdev);
++
++	if (state.event == PM_EVENT_SUSPEND) {
++		/* Shut down the device */
++		pci_disable_device(dev->pdev);
++		pci_set_power_state(dev->pdev, PCI_D3hot);
++	}
++	return 0;
++}
++
++int radeon_resume(struct drm_device *dev)
++{
++	struct drm_radeon_private *dev_priv = dev->dev_private;
++	struct drm_framebuffer *fb;
++	int i;
++	u32 tmp;
++
++	if (!drm_core_check_feature(dev, DRIVER_MODESET))
++		return 0;
++
++	pci_set_power_state(dev->pdev, PCI_D0);
++	pci_restore_state(dev->pdev);
++	if (pci_enable_device(dev->pdev))
++		return -1;
++	pci_set_master(dev->pdev);
++
++	/* Turn on bus mastering */
++	tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
++	RADEON_WRITE(RADEON_BUS_CNTL, tmp);
++
++	/* on atom cards re init the whole card 
++	   and set the modes again */
++
++	if (dev_priv->is_atom_bios) {
++		struct atom_context *ctx = dev_priv->mode_info.atom_context;
++		atom_asic_init(ctx);
++	} else {
++		radeon_combios_asic_init(dev);
++	}
++
++	for (i = 0; i < 8; i++)
++		RADEON_WRITE(RADEON_BIOS_0_SCRATCH + (i * 4), dev_priv->pmregs.bios_scratch[i]);
++
++	/* VGA render mayhaps */
++	if (dev_priv->chip_family >= CHIP_RS600) {
++		uint32_t tmp;
++
++		RADEON_WRITE(AVIVO_D1VGA_CONTROL, 0);
++		RADEON_WRITE(AVIVO_D2VGA_CONTROL, 0);
++		tmp = RADEON_READ(0x300);
++		tmp &= ~(3 << 16);
++		RADEON_WRITE(0x300, tmp);
++		RADEON_WRITE(0x308, (1 << 8));
++		RADEON_WRITE(0x310, dev_priv->fb_location);
++		RADEON_WRITE(0x594, 0);
++	}
++
++	RADEON_WRITE(RADEON_CRTC_EXT_CNTL, dev_priv->pmregs.crtc_ext_cntl);
++
++	radeon_static_clocks_init(dev);
++	
++	radeon_init_memory_map(dev);
++
++	if (dev_priv->flags & RADEON_IS_PCIE) {
++		memcpy_toio(dev_priv->mm.pcie_table.kmap.virtual, dev_priv->mm.pcie_table_backup, RADEON_PCIGART_TABLE_SIZE);
++	}
++
++	if (dev_priv->mm.ring.kmap.virtual)
++		memset(dev_priv->mm.ring.kmap.virtual, 0, RADEON_DEFAULT_RING_SIZE);
++
++	if (dev_priv->mm.ring_read.kmap.virtual)
++		memset(dev_priv->mm.ring_read.kmap.virtual, 0, PAGE_SIZE);
++
++	radeon_modeset_cp_resume(dev);
++
++	/* reset swi reg */
++	RADEON_WRITE(RADEON_LAST_SWI_REG, dev_priv->counter);
++
++	radeon_enable_interrupt(dev);
++
++	/* reset the context for userspace */
++	if (dev->primary->master) {
++		struct drm_radeon_master_private *master_priv = dev->primary->master->driver_priv;
++		if (master_priv->sarea_priv)
++			master_priv->sarea_priv->ctx_owner = 0;
++	}
++
++	/* unpin the front buffers */
++	list_for_each_entry(fb, &dev->mode_config.fb_kernel_list, filp_head) {
++		
++		struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
++
++		if (!radeon_fb)
++			continue;
++
++		if (!radeon_fb->obj)
++			continue;
++		
++		radeon_gem_object_pin(radeon_fb->obj, PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM);
++	}
++	/* blat the mode back in */
++	drm_helper_resume_force_mode(dev);
++
++	return 0;
++}
 diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
 new file mode 100644
 index 0000000..5910897
@@ -48218,10 +48647,10 @@
 +
 diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
 new file mode 100644
-index 0000000..dcb46f9
+index 0000000..c071915
 --- /dev/null
 +++ b/include/drm/drm_crtc_helper.h
-@@ -0,0 +1,97 @@
+@@ -0,0 +1,96 @@
 +/*
 + * Copyright © 2006 Keith Packard
 + * Copyright © 2007 Intel Corporation
@@ -48316,8 +48745,7 @@
 +	connector->helper_private = (void *)funcs;
 +}
 +
-+extern int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_object **bo, unsigned long handle);
-+
++extern int drm_helper_resume_force_mode(struct drm_device *dev);
 +#endif
 diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
 new file mode 100644
@@ -48505,10 +48933,10 @@
 +#endif /* __DRM_EDID_H__ */
 diff --git a/include/drm/drm_objects.h b/include/drm/drm_objects.h
 new file mode 100644
-index 0000000..e0ec1ba
+index 0000000..fa9fd96
 --- /dev/null
 +++ b/include/drm/drm_objects.h
-@@ -0,0 +1,893 @@
+@@ -0,0 +1,894 @@
 +/**************************************************************************
 + *
 + * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
@@ -49303,6 +49731,7 @@
 +extern int drm_bo_evict_cached(struct drm_buffer_object *bo);
 +
 +extern void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo);
++extern void drm_bo_evict_mm(struct drm_device *dev, int mem_type, int no_wait);
 +/*
 + * Buffer object memory move- and map helpers.
 + * drm_bo_move.c
@@ -49855,7 +50284,7 @@
 +
  #endif				/* _I915_DRM_H_ */
 diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
-index 73ff51f..77b97fb 100644
+index 73ff51f..1347faf 100644
 --- a/include/drm/radeon_drm.h
 +++ b/include/drm/radeon_drm.h
 @@ -453,6 +453,15 @@ typedef struct {
@@ -49974,7 +50403,7 @@
 +
 +struct drm_radeon_gem_pin {
 +	uint32_t handle;
-+	uint32_t pad;
++	uint32_t pin_domain;
 +	uint64_t alignment;
 +	uint64_t offset;
 +};


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.930
retrieving revision 1.931
diff -u -r1.930 -r1.931
--- kernel.spec	5 Sep 2008 06:06:18 -0000	1.930
+++ kernel.spec	5 Sep 2008 06:29:57 -0000	1.931
@@ -1747,6 +1747,9 @@
 %kernel_variant_files -k vmlinux %{with_kdump} kdump
 
 %changelog
+* Fri Sep 05 2008 Dave Airlie <airlied at redhat.com>
+- introduce radeon suspend/resume + change pin api
+
 * Fri Sep 05 2008 Chuck Ebbert <cebbert at redhat.com>
 - Restore most of the dropped powerpc32 drivers.
 




More information about the fedora-extras-commits mailing list