aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2011-11-03 11:16:49 -0400
committerDave Airlie <airlied@redhat.com>2011-11-04 06:39:51 -0400
commitc9a1be96277b3b2d2e8aff2ba69d7817ea8e46c9 (patch)
tree7f27b6d926b44184f8ef089527be81d981c08b9f /drivers/gpu/drm
parent0e2c978ef2248156f36db7fcda8c7b67998ec58a (diff)
drm/radeon/kms: consolidate GART code, fix segfault after GPU lockup V2
After GPU lockup VRAM gart table is unpinned and thus its pointer becomes unvalid. This patch move the unpin code to a common helper function and set pointer to NULL so that page update code can check if it should update GPU page table or not. That way bo still bound to GART can be unbound (pci_unmap_page for all there page) properly while there is no need to update the GPU page table. V2 move the test for null gart out of the loop, small optimization Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c12
-rw-r--r--drivers/gpu/drm/radeon/ni.c13
-rw-r--r--drivers/gpu/drm/radeon/r100.c6
-rw-r--r--drivers/gpu/drm/radeon/r300.c16
-rw-r--r--drivers/gpu/drm/radeon/r600.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon.h22
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c71
-rw-r--r--drivers/gpu/drm/radeon/rs400.c5
-rw-r--r--drivers/gpu/drm/radeon/rs600.c16
-rw-r--r--drivers/gpu/drm/radeon/rv770.c13
10 files changed, 75 insertions, 116 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 7ce9c87e695e..e4c384b9511c 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -894,7 +894,7 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)
894 u32 tmp; 894 u32 tmp;
895 int r; 895 int r;
896 896
897 if (rdev->gart.table.vram.robj == NULL) { 897 if (rdev->gart.robj == NULL) {
898 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 898 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
899 return -EINVAL; 899 return -EINVAL;
900 } 900 }
@@ -946,7 +946,6 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)
946void evergreen_pcie_gart_disable(struct radeon_device *rdev) 946void evergreen_pcie_gart_disable(struct radeon_device *rdev)
947{ 947{
948 u32 tmp; 948 u32 tmp;
949 int r;
950 949
951 /* Disable all tables */ 950 /* Disable all tables */
952 WREG32(VM_CONTEXT0_CNTL, 0); 951 WREG32(VM_CONTEXT0_CNTL, 0);
@@ -966,14 +965,7 @@ void evergreen_pcie_gart_disable(struct radeon_device *rdev)
966 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); 965 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
967 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); 966 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
968 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); 967 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
969 if (rdev->gart.table.vram.robj) { 968 radeon_gart_table_vram_unpin(rdev);
970 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
971 if (likely(r == 0)) {
972 radeon_bo_kunmap(rdev->gart.table.vram.robj);
973 radeon_bo_unpin(rdev->gart.table.vram.robj);
974 radeon_bo_unreserve(rdev->gart.table.vram.robj);
975 }
976 }
977} 969}
978 970
979void evergreen_pcie_gart_fini(struct radeon_device *rdev) 971void evergreen_pcie_gart_fini(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 722cfb398992..8402661fc206 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -935,7 +935,7 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
935{ 935{
936 int r; 936 int r;
937 937
938 if (rdev->gart.table.vram.robj == NULL) { 938 if (rdev->gart.robj == NULL) {
939 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 939 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
940 return -EINVAL; 940 return -EINVAL;
941 } 941 }
@@ -980,8 +980,6 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev)
980 980
981void cayman_pcie_gart_disable(struct radeon_device *rdev) 981void cayman_pcie_gart_disable(struct radeon_device *rdev)
982{ 982{
983 int r;
984
985 /* Disable all tables */ 983 /* Disable all tables */
986 WREG32(VM_CONTEXT0_CNTL, 0); 984 WREG32(VM_CONTEXT0_CNTL, 0);
987 WREG32(VM_CONTEXT1_CNTL, 0); 985 WREG32(VM_CONTEXT1_CNTL, 0);
@@ -997,14 +995,7 @@ void cayman_pcie_gart_disable(struct radeon_device *rdev)
997 WREG32(VM_L2_CNTL2, 0); 995 WREG32(VM_L2_CNTL2, 0);
998 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | 996 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
999 L2_CACHE_BIGK_FRAGMENT_SIZE(6)); 997 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1000 if (rdev->gart.table.vram.robj) { 998 radeon_gart_table_vram_unpin(rdev);
1001 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
1002 if (likely(r == 0)) {
1003 radeon_bo_kunmap(rdev->gart.table.vram.robj);
1004 radeon_bo_unpin(rdev->gart.table.vram.robj);
1005 radeon_bo_unreserve(rdev->gart.table.vram.robj);
1006 }
1007 }
1008} 999}
1009 1000
1010void cayman_pcie_gart_fini(struct radeon_device *rdev) 1001void cayman_pcie_gart_fini(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 4191eaf47381..6d7766260419 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -577,7 +577,7 @@ int r100_pci_gart_init(struct radeon_device *rdev)
577{ 577{
578 int r; 578 int r;
579 579
580 if (rdev->gart.table.ram.ptr) { 580 if (rdev->gart.ptr) {
581 WARN(1, "R100 PCI GART already initialized\n"); 581 WARN(1, "R100 PCI GART already initialized\n");
582 return 0; 582 return 0;
583 } 583 }
@@ -636,10 +636,12 @@ void r100_pci_gart_disable(struct radeon_device *rdev)
636 636
637int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 637int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
638{ 638{
639 u32 *gtt = rdev->gart.ptr;
640
639 if (i < 0 || i > rdev->gart.num_gpu_pages) { 641 if (i < 0 || i > rdev->gart.num_gpu_pages) {
640 return -EINVAL; 642 return -EINVAL;
641 } 643 }
642 rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr)); 644 gtt[i] = cpu_to_le32(lower_32_bits(addr));
643 return 0; 645 return 0;
644} 646}
645 647
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 33f2b68c680b..400b26df652a 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -74,7 +74,7 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
74 74
75int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 75int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
76{ 76{
77 void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; 77 void __iomem *ptr = rdev->gart.ptr;
78 78
79 if (i < 0 || i > rdev->gart.num_gpu_pages) { 79 if (i < 0 || i > rdev->gart.num_gpu_pages) {
80 return -EINVAL; 80 return -EINVAL;
@@ -93,7 +93,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev)
93{ 93{
94 int r; 94 int r;
95 95
96 if (rdev->gart.table.vram.robj) { 96 if (rdev->gart.robj) {
97 WARN(1, "RV370 PCIE GART already initialized\n"); 97 WARN(1, "RV370 PCIE GART already initialized\n");
98 return 0; 98 return 0;
99 } 99 }
@@ -116,7 +116,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
116 uint32_t tmp; 116 uint32_t tmp;
117 int r; 117 int r;
118 118
119 if (rdev->gart.table.vram.robj == NULL) { 119 if (rdev->gart.robj == NULL) {
120 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 120 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
121 return -EINVAL; 121 return -EINVAL;
122 } 122 }
@@ -154,7 +154,6 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
154void rv370_pcie_gart_disable(struct radeon_device *rdev) 154void rv370_pcie_gart_disable(struct radeon_device *rdev)
155{ 155{
156 u32 tmp; 156 u32 tmp;
157 int r;
158 157
159 WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); 158 WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0);
160 WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); 159 WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0);
@@ -163,14 +162,7 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
163 tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); 162 tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
164 tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; 163 tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
165 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); 164 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
166 if (rdev->gart.table.vram.robj) { 165 radeon_gart_table_vram_unpin(rdev);
167 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
168 if (likely(r == 0)) {
169 radeon_bo_kunmap(rdev->gart.table.vram.robj);
170 radeon_bo_unpin(rdev->gart.table.vram.robj);
171 radeon_bo_unreserve(rdev->gart.table.vram.robj);
172 }
173 }
174} 166}
175 167
176void rv370_pcie_gart_fini(struct radeon_device *rdev) 168void rv370_pcie_gart_fini(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index ff3ae48aa1a7..06f7682c87c7 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -895,7 +895,7 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
895 /* flush hdp cache so updates hit vram */ 895 /* flush hdp cache so updates hit vram */
896 if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && 896 if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
897 !(rdev->flags & RADEON_IS_AGP)) { 897 !(rdev->flags & RADEON_IS_AGP)) {
898 void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; 898 void __iomem *ptr = (void *)rdev->gart.ptr;
899 u32 tmp; 899 u32 tmp;
900 900
901 /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read 901 /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
@@ -930,7 +930,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev)
930{ 930{
931 int r; 931 int r;
932 932
933 if (rdev->gart.table.vram.robj) { 933 if (rdev->gart.robj) {
934 WARN(1, "R600 PCIE GART already initialized\n"); 934 WARN(1, "R600 PCIE GART already initialized\n");
935 return 0; 935 return 0;
936 } 936 }
@@ -947,7 +947,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
947 u32 tmp; 947 u32 tmp;
948 int r, i; 948 int r, i;
949 949
950 if (rdev->gart.table.vram.robj == NULL) { 950 if (rdev->gart.robj == NULL) {
951 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 951 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
952 return -EINVAL; 952 return -EINVAL;
953 } 953 }
@@ -1002,7 +1002,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
1002void r600_pcie_gart_disable(struct radeon_device *rdev) 1002void r600_pcie_gart_disable(struct radeon_device *rdev)
1003{ 1003{
1004 u32 tmp; 1004 u32 tmp;
1005 int i, r; 1005 int i;
1006 1006
1007 /* Disable all tables */ 1007 /* Disable all tables */
1008 for (i = 0; i < 7; i++) 1008 for (i = 0; i < 7; i++)
@@ -1029,14 +1029,7 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
1029 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); 1029 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
1030 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); 1030 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
1031 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); 1031 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
1032 if (rdev->gart.table.vram.robj) { 1032 radeon_gart_table_vram_unpin(rdev);
1033 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
1034 if (likely(r == 0)) {
1035 radeon_bo_kunmap(rdev->gart.table.vram.robj);
1036 radeon_bo_unpin(rdev->gart.table.vram.robj);
1037 radeon_bo_unreserve(rdev->gart.table.vram.robj);
1038 }
1039 }
1040} 1033}
1041 1034
1042void r600_pcie_gart_fini(struct radeon_device *rdev) 1035void r600_pcie_gart_fini(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e94c6f18a157..b316b301152f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -307,30 +307,17 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
307 */ 307 */
308struct radeon_mc; 308struct radeon_mc;
309 309
310struct radeon_gart_table_ram {
311 volatile uint32_t *ptr;
312};
313
314struct radeon_gart_table_vram {
315 struct radeon_bo *robj;
316 volatile uint32_t *ptr;
317};
318
319union radeon_gart_table {
320 struct radeon_gart_table_ram ram;
321 struct radeon_gart_table_vram vram;
322};
323
324#define RADEON_GPU_PAGE_SIZE 4096 310#define RADEON_GPU_PAGE_SIZE 4096
325#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) 311#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
326#define RADEON_GPU_PAGE_SHIFT 12 312#define RADEON_GPU_PAGE_SHIFT 12
327 313
328struct radeon_gart { 314struct radeon_gart {
329 dma_addr_t table_addr; 315 dma_addr_t table_addr;
316 struct radeon_bo *robj;
317 void *ptr;
330 unsigned num_gpu_pages; 318 unsigned num_gpu_pages;
331 unsigned num_cpu_pages; 319 unsigned num_cpu_pages;
332 unsigned table_size; 320 unsigned table_size;
333 union radeon_gart_table table;
334 struct page **pages; 321 struct page **pages;
335 dma_addr_t *pages_addr; 322 dma_addr_t *pages_addr;
336 bool *ttm_alloced; 323 bool *ttm_alloced;
@@ -341,6 +328,8 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev);
341void radeon_gart_table_ram_free(struct radeon_device *rdev); 328void radeon_gart_table_ram_free(struct radeon_device *rdev);
342int radeon_gart_table_vram_alloc(struct radeon_device *rdev); 329int radeon_gart_table_vram_alloc(struct radeon_device *rdev);
343void radeon_gart_table_vram_free(struct radeon_device *rdev); 330void radeon_gart_table_vram_free(struct radeon_device *rdev);
331int radeon_gart_table_vram_pin(struct radeon_device *rdev);
332void radeon_gart_table_vram_unpin(struct radeon_device *rdev);
344int radeon_gart_init(struct radeon_device *rdev); 333int radeon_gart_init(struct radeon_device *rdev);
345void radeon_gart_fini(struct radeon_device *rdev); 334void radeon_gart_fini(struct radeon_device *rdev);
346void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, 335void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
@@ -348,6 +337,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
348int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, 337int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
349 int pages, struct page **pagelist, 338 int pages, struct page **pagelist,
350 dma_addr_t *dma_addr); 339 dma_addr_t *dma_addr);
340void radeon_gart_restore(struct radeon_device *rdev);
351 341
352 342
353/* 343/*
@@ -1445,8 +1435,6 @@ void radeon_ring_write(struct radeon_device *rdev, uint32_t v);
1445/* AGP */ 1435/* AGP */
1446extern int radeon_gpu_reset(struct radeon_device *rdev); 1436extern int radeon_gpu_reset(struct radeon_device *rdev);
1447extern void radeon_agp_disable(struct radeon_device *rdev); 1437extern void radeon_agp_disable(struct radeon_device *rdev);
1448extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
1449extern void radeon_gart_restore(struct radeon_device *rdev);
1450extern int radeon_modeset_init(struct radeon_device *rdev); 1438extern int radeon_modeset_init(struct radeon_device *rdev);
1451extern void radeon_modeset_fini(struct radeon_device *rdev); 1439extern void radeon_modeset_fini(struct radeon_device *rdev);
1452extern bool radeon_card_posted(struct radeon_device *rdev); 1440extern bool radeon_card_posted(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index fdc3a9a54bf8..ba7ab79e12c1 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -49,27 +49,27 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev)
49 rdev->gart.table_size >> PAGE_SHIFT); 49 rdev->gart.table_size >> PAGE_SHIFT);
50 } 50 }
51#endif 51#endif
52 rdev->gart.table.ram.ptr = ptr; 52 rdev->gart.ptr = ptr;
53 memset((void *)rdev->gart.table.ram.ptr, 0, rdev->gart.table_size); 53 memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size);
54 return 0; 54 return 0;
55} 55}
56 56
57void radeon_gart_table_ram_free(struct radeon_device *rdev) 57void radeon_gart_table_ram_free(struct radeon_device *rdev)
58{ 58{
59 if (rdev->gart.table.ram.ptr == NULL) { 59 if (rdev->gart.ptr == NULL) {
60 return; 60 return;
61 } 61 }
62#ifdef CONFIG_X86 62#ifdef CONFIG_X86
63 if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || 63 if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 ||
64 rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { 64 rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
65 set_memory_wb((unsigned long)rdev->gart.table.ram.ptr, 65 set_memory_wb((unsigned long)rdev->gart.ptr,
66 rdev->gart.table_size >> PAGE_SHIFT); 66 rdev->gart.table_size >> PAGE_SHIFT);
67 } 67 }
68#endif 68#endif
69 pci_free_consistent(rdev->pdev, rdev->gart.table_size, 69 pci_free_consistent(rdev->pdev, rdev->gart.table_size,
70 (void *)rdev->gart.table.ram.ptr, 70 (void *)rdev->gart.ptr,
71 rdev->gart.table_addr); 71 rdev->gart.table_addr);
72 rdev->gart.table.ram.ptr = NULL; 72 rdev->gart.ptr = NULL;
73 rdev->gart.table_addr = 0; 73 rdev->gart.table_addr = 0;
74} 74}
75 75
@@ -77,10 +77,10 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
77{ 77{
78 int r; 78 int r;
79 79
80 if (rdev->gart.table.vram.robj == NULL) { 80 if (rdev->gart.robj == NULL) {
81 r = radeon_bo_create(rdev, rdev->gart.table_size, 81 r = radeon_bo_create(rdev, rdev->gart.table_size,
82 PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, 82 PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
83 &rdev->gart.table.vram.robj); 83 &rdev->gart.robj);
84 if (r) { 84 if (r) {
85 return r; 85 return r;
86 } 86 }
@@ -93,38 +93,46 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev)
93 uint64_t gpu_addr; 93 uint64_t gpu_addr;
94 int r; 94 int r;
95 95
96 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); 96 r = radeon_bo_reserve(rdev->gart.robj, false);
97 if (unlikely(r != 0)) 97 if (unlikely(r != 0))
98 return r; 98 return r;
99 r = radeon_bo_pin(rdev->gart.table.vram.robj, 99 r = radeon_bo_pin(rdev->gart.robj,
100 RADEON_GEM_DOMAIN_VRAM, &gpu_addr); 100 RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
101 if (r) { 101 if (r) {
102 radeon_bo_unreserve(rdev->gart.table.vram.robj); 102 radeon_bo_unreserve(rdev->gart.robj);
103 return r; 103 return r;
104 } 104 }
105 r = radeon_bo_kmap(rdev->gart.table.vram.robj, 105 r = radeon_bo_kmap(rdev->gart.robj, &rdev->gart.ptr);
106 (void **)&rdev->gart.table.vram.ptr);
107 if (r) 106 if (r)
108 radeon_bo_unpin(rdev->gart.table.vram.robj); 107 radeon_bo_unpin(rdev->gart.robj);
109 radeon_bo_unreserve(rdev->gart.table.vram.robj); 108 radeon_bo_unreserve(rdev->gart.robj);
110 rdev->gart.table_addr = gpu_addr; 109 rdev->gart.table_addr = gpu_addr;
111 return r; 110 return r;
112} 111}
113 112
114void radeon_gart_table_vram_free(struct radeon_device *rdev) 113void radeon_gart_table_vram_unpin(struct radeon_device *rdev)
115{ 114{
116 int r; 115 int r;
117 116
118 if (rdev->gart.table.vram.robj == NULL) { 117 if (rdev->gart.robj == NULL) {
119 return; 118 return;
120 } 119 }
121 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); 120 r = radeon_bo_reserve(rdev->gart.robj, false);
122 if (likely(r == 0)) { 121 if (likely(r == 0)) {
123 radeon_bo_kunmap(rdev->gart.table.vram.robj); 122 radeon_bo_kunmap(rdev->gart.robj);
124 radeon_bo_unpin(rdev->gart.table.vram.robj); 123 radeon_bo_unpin(rdev->gart.robj);
125 radeon_bo_unreserve(rdev->gart.table.vram.robj); 124 radeon_bo_unreserve(rdev->gart.robj);
125 rdev->gart.ptr = NULL;
126 } 126 }
127 radeon_bo_unref(&rdev->gart.table.vram.robj); 127}
128
129void radeon_gart_table_vram_free(struct radeon_device *rdev)
130{
131 if (rdev->gart.robj == NULL) {
132 return;
133 }
134 radeon_gart_table_vram_unpin(rdev);
135 radeon_bo_unref(&rdev->gart.robj);
128} 136}
129 137
130 138
@@ -151,12 +159,14 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
151 if (rdev->gart.pages[p]) { 159 if (rdev->gart.pages[p]) {
152 if (!rdev->gart.ttm_alloced[p]) 160 if (!rdev->gart.ttm_alloced[p])
153 pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], 161 pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p],
154 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 162 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
155 rdev->gart.pages[p] = NULL; 163 rdev->gart.pages[p] = NULL;
156 rdev->gart.pages_addr[p] = rdev->dummy_page.addr; 164 rdev->gart.pages_addr[p] = rdev->dummy_page.addr;
157 page_base = rdev->gart.pages_addr[p]; 165 page_base = rdev->gart.pages_addr[p];
158 for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { 166 for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
159 radeon_gart_set_page(rdev, t, page_base); 167 if (rdev->gart.ptr) {
168 radeon_gart_set_page(rdev, t, page_base);
169 }
160 page_base += RADEON_GPU_PAGE_SIZE; 170 page_base += RADEON_GPU_PAGE_SIZE;
161 } 171 }
162 } 172 }
@@ -199,10 +209,12 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
199 } 209 }
200 } 210 }
201 rdev->gart.pages[p] = pagelist[i]; 211 rdev->gart.pages[p] = pagelist[i];
202 page_base = rdev->gart.pages_addr[p]; 212 if (rdev->gart.ptr) {
203 for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { 213 page_base = rdev->gart.pages_addr[p];
204 radeon_gart_set_page(rdev, t, page_base); 214 for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
205 page_base += RADEON_GPU_PAGE_SIZE; 215 radeon_gart_set_page(rdev, t, page_base);
216 page_base += RADEON_GPU_PAGE_SIZE;
217 }
206 } 218 }
207 } 219 }
208 mb(); 220 mb();
@@ -215,6 +227,9 @@ void radeon_gart_restore(struct radeon_device *rdev)
215 int i, j, t; 227 int i, j, t;
216 u64 page_base; 228 u64 page_base;
217 229
230 if (!rdev->gart.ptr) {
231 return;
232 }
218 for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { 233 for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) {
219 page_base = rdev->gart.pages_addr[i]; 234 page_base = rdev->gart.pages_addr[i];
220 for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { 235 for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index 89a6e1ecea8d..06b90c87f8f3 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -77,7 +77,7 @@ int rs400_gart_init(struct radeon_device *rdev)
77{ 77{
78 int r; 78 int r;
79 79
80 if (rdev->gart.table.ram.ptr) { 80 if (rdev->gart.ptr) {
81 WARN(1, "RS400 GART already initialized\n"); 81 WARN(1, "RS400 GART already initialized\n");
82 return 0; 82 return 0;
83 } 83 }
@@ -212,6 +212,7 @@ void rs400_gart_fini(struct radeon_device *rdev)
212int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 212int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
213{ 213{
214 uint32_t entry; 214 uint32_t entry;
215 u32 *gtt = rdev->gart.ptr;
215 216
216 if (i < 0 || i > rdev->gart.num_gpu_pages) { 217 if (i < 0 || i > rdev->gart.num_gpu_pages) {
217 return -EINVAL; 218 return -EINVAL;
@@ -221,7 +222,7 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
221 ((upper_32_bits(addr) & 0xff) << 4) | 222 ((upper_32_bits(addr) & 0xff) << 4) |
222 RS400_PTE_WRITEABLE | RS400_PTE_READABLE; 223 RS400_PTE_WRITEABLE | RS400_PTE_READABLE;
223 entry = cpu_to_le32(entry); 224 entry = cpu_to_le32(entry);
224 rdev->gart.table.ram.ptr[i] = entry; 225 gtt[i] = entry;
225 return 0; 226 return 0;
226} 227}
227 228
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 02e0390daa8e..481b99e89f65 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -414,7 +414,7 @@ int rs600_gart_init(struct radeon_device *rdev)
414{ 414{
415 int r; 415 int r;
416 416
417 if (rdev->gart.table.vram.robj) { 417 if (rdev->gart.robj) {
418 WARN(1, "RS600 GART already initialized\n"); 418 WARN(1, "RS600 GART already initialized\n");
419 return 0; 419 return 0;
420 } 420 }
@@ -432,7 +432,7 @@ static int rs600_gart_enable(struct radeon_device *rdev)
432 u32 tmp; 432 u32 tmp;
433 int r, i; 433 int r, i;
434 434
435 if (rdev->gart.table.vram.robj == NULL) { 435 if (rdev->gart.robj == NULL) {
436 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 436 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
437 return -EINVAL; 437 return -EINVAL;
438 } 438 }
@@ -495,20 +495,12 @@ static int rs600_gart_enable(struct radeon_device *rdev)
495void rs600_gart_disable(struct radeon_device *rdev) 495void rs600_gart_disable(struct radeon_device *rdev)
496{ 496{
497 u32 tmp; 497 u32 tmp;
498 int r;
499 498
500 /* FIXME: disable out of gart access */ 499 /* FIXME: disable out of gart access */
501 WREG32_MC(R_000100_MC_PT0_CNTL, 0); 500 WREG32_MC(R_000100_MC_PT0_CNTL, 0);
502 tmp = RREG32_MC(R_000009_MC_CNTL1); 501 tmp = RREG32_MC(R_000009_MC_CNTL1);
503 WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); 502 WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES);
504 if (rdev->gart.table.vram.robj) { 503 radeon_gart_table_vram_unpin(rdev);
505 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
506 if (r == 0) {
507 radeon_bo_kunmap(rdev->gart.table.vram.robj);
508 radeon_bo_unpin(rdev->gart.table.vram.robj);
509 radeon_bo_unreserve(rdev->gart.table.vram.robj);
510 }
511 }
512} 504}
513 505
514void rs600_gart_fini(struct radeon_device *rdev) 506void rs600_gart_fini(struct radeon_device *rdev)
@@ -526,7 +518,7 @@ void rs600_gart_fini(struct radeon_device *rdev)
526 518
527int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 519int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
528{ 520{
529 void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; 521 void __iomem *ptr = (void *)rdev->gart.ptr;
530 522
531 if (i < 0 || i > rdev->gart.num_gpu_pages) { 523 if (i < 0 || i > rdev->gart.num_gpu_pages) {
532 return -EINVAL; 524 return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index a09049d15901..a983f410ab89 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -124,7 +124,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
124 u32 tmp; 124 u32 tmp;
125 int r, i; 125 int r, i;
126 126
127 if (rdev->gart.table.vram.robj == NULL) { 127 if (rdev->gart.robj == NULL) {
128 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 128 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
129 return -EINVAL; 129 return -EINVAL;
130 } 130 }
@@ -171,7 +171,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
171void rv770_pcie_gart_disable(struct radeon_device *rdev) 171void rv770_pcie_gart_disable(struct radeon_device *rdev)
172{ 172{
173 u32 tmp; 173 u32 tmp;
174 int i, r; 174 int i;
175 175
176 /* Disable all tables */ 176 /* Disable all tables */
177 for (i = 0; i < 7; i++) 177 for (i = 0; i < 7; i++)
@@ -191,14 +191,7 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
191 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); 191 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
192 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); 192 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
193 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); 193 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
194 if (rdev->gart.table.vram.robj) { 194 radeon_gart_table_vram_unpin(rdev);
195 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
196 if (likely(r == 0)) {
197 radeon_bo_kunmap(rdev->gart.table.vram.robj);
198 radeon_bo_unpin(rdev->gart.table.vram.robj);
199 radeon_bo_unreserve(rdev->gart.table.vram.robj);
200 }
201 }
202} 195}
203 196
204void rv770_pcie_gart_fini(struct radeon_device *rdev) 197void rv770_pcie_gart_fini(struct radeon_device *rdev)