diff mbox

drm/radeon/kms: fix gart set/clear page on r6xx/r7xx

Message ID a728f9f91002101551j4afa8107h4b09a7d5eed6e3a8@mail.gmail.com (mailing list archive)
State Superseded
Headers show

Commit Message

Alex Deucher Feb. 10, 2010, 11:51 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 1ecca29..213780b 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -353,6 +353,33 @@  void r600_hpd_fini(struct radeon_device *rdev)
 /*
  * R600 PCIE GART
  */
+#define R600_PTE_VALID     (1 << 0)
+#define R600_PTE_SYSTEM    (1 << 1)
+#define R600_PTE_SNOOPED   (1 << 2)
+#define R600_PTE_READABLE  (1 << 5)
+#define R600_PTE_WRITEABLE (1 << 6)
+
+int r600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
+{
+	void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+
+	if (i < 0 || i > rdev->gart.num_gpu_pages)
+		return -EINVAL;
+
+	/* Flush VM TLBs, L2 */
+	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
+
+	addr = addr & 0xFFFFFFFFFFFFF000ULL;
+	addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
+	addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
+	writeq(addr, ((void __iomem *)ptr) + (i * 8));
+
+	/* flush hdp cache so updates hit vram */
+	WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+
+	return 0;
+}
+
 int r600_gart_clear_page(struct radeon_device *rdev, int i)
 {
 	void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
@@ -360,8 +387,16 @@  int r600_gart_clear_page(struct radeon_device *rdev, int i)

 	if (i < 0 || i > rdev->gart.num_gpu_pages)
 		return -EINVAL;
+
+	/* Flush VM TLBs, L2 */
+	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
+
 	pte = 0;
 	writeq(pte, ((void __iomem *)ptr) + (i * 8));
+
+	/* flush hdp cache so updates hit vram */
+	WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
+
 	return 0;
 }

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9cb323a..30903f3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1266,7 +1266,6 @@  extern void r600_ring_init(struct radeon_device
*rdev, unsigned ring_size);
 extern int r600_cp_resume(struct radeon_device *rdev);
 extern void r600_cp_fini(struct radeon_device *rdev);
 extern int r600_count_pipe_bits(uint32_t val);
-extern int r600_gart_clear_page(struct radeon_device *rdev, int i);
 extern int r600_mc_wait_for_idle(struct radeon_device *rdev);
 extern int r600_pcie_gart_init(struct radeon_device *rdev);
 extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h
b/drivers/gpu/drm/radeon/radeon_asic.h
index 6367946..8e1938a 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -506,6 +506,8 @@  int r600_wb_init(struct radeon_device *rdev);
 void r600_wb_fini(struct radeon_device *rdev);
 void r600_cp_commit(struct radeon_device *rdev);
 void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
+int r600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
+int r600_gart_clear_page(struct radeon_device *rdev, int i);
 uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
 void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 int r600_cs_parse(struct radeon_cs_parser *p);
@@ -544,8 +546,8 @@  static struct radeon_asic r600_asic = {
 	.vga_set_state = &r600_vga_set_state,
 	.gpu_reset = &r600_gpu_reset,
 	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
-	.gart_set_page = &rs600_gart_set_page,
-	.gart_clear_page = &rs600_gart_clear_page,
+	.gart_set_page = &r600_gart_set_page,
+	.gart_clear_page = &r600_gart_clear_page,
 	.ring_test = &r600_ring_test,
 	.ring_ib_execute = &r600_ring_ib_execute,
 	.irq_set = &r600_irq_set,
@@ -591,8 +593,8 @@  static struct radeon_asic rv770_asic = {
 	.gpu_reset = &rv770_gpu_reset,
 	.vga_set_state = &r600_vga_set_state,
 	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
-	.gart_set_page = &rs600_gart_set_page,
-	.gart_clear_page = &rs600_gart_clear_page,
+	.gart_set_page = &r600_gart_set_page,
+	.gart_clear_page = &r600_gart_clear_page,
 	.ring_test = &r600_ring_test,
 	.ring_ib_execute = &r600_ring_ib_execute,
 	.irq_set = &r600_irq_set,