aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-05-08 01:19:23 -0400
committerDave Airlie <airlied@linux.ie>2007-05-08 01:19:23 -0400
commitf2b04cd219e5c0f1214c0eeeec814ddd08a12c1b (patch)
treefa114ea7f96b5985e10c7f8696d635b074649bab
parent5b94f675f57e4ff16c8fda09088d7480a84dcd91 (diff)
drm/radeon: upgrade to 1.27 - make PCI GART more flexible
radeon: make PCI GART aperture size variable, but making table size variable This is precursor to getting a TTM backend for this stuff, and also allows the PCI table to be allocated at fb 0 radeon: add support for reverse engineered xpress200m The IGPGART setup code was traced using mmio-trace on fglrx by myself and Phillip Ezolt <phillipezolt@gmail.com> on dri-devel. This code doesn't let the 3D driver work properly as the card has no vertex shader support. Thanks to Matthew Garrett + Ubuntu for providing me some hardware to do this work on. Signed-off-by: Dave Airlie <airlied@linux.ie>
-rw-r--r--drivers/char/drm/ati_pcigart.c84
-rw-r--r--drivers/char/drm/drmP.h7
-rw-r--r--drivers/char/drm/drm_pciids.h1
-rw-r--r--drivers/char/drm/r128_cce.c3
-rw-r--r--drivers/char/drm/r128_drv.h2
-rw-r--r--drivers/char/drm/radeon_cp.c71
-rw-r--r--drivers/char/drm/radeon_drm.h1
-rw-r--r--drivers/char/drm/radeon_drv.h23
-rw-r--r--drivers/char/drm/radeon_state.c6
9 files changed, 150 insertions, 48 deletions
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index bd7be09ea53d..5b91bc04ea4e 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -33,59 +33,44 @@
33 33
34#include "drmP.h" 34#include "drmP.h"
35 35
36#if PAGE_SIZE == 65536
37# define ATI_PCIGART_TABLE_ORDER 0
38# define ATI_PCIGART_TABLE_PAGES (1 << 0)
39#elif PAGE_SIZE == 16384
40# define ATI_PCIGART_TABLE_ORDER 1
41# define ATI_PCIGART_TABLE_PAGES (1 << 1)
42#elif PAGE_SIZE == 8192
43# define ATI_PCIGART_TABLE_ORDER 2
44# define ATI_PCIGART_TABLE_PAGES (1 << 2)
45#elif PAGE_SIZE == 4096
46# define ATI_PCIGART_TABLE_ORDER 3
47# define ATI_PCIGART_TABLE_PAGES (1 << 3)
48#else
49# error - PAGE_SIZE not 64K, 16K, 8K or 4K
50#endif
51
52# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
53# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ 36# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
54 37
55static void *drm_ati_alloc_pcigart_table(void) 38static void *drm_ati_alloc_pcigart_table(int order)
56{ 39{
57 unsigned long address; 40 unsigned long address;
58 struct page *page; 41 struct page *page;
59 int i; 42 int i;
60 DRM_DEBUG("%s\n", __FUNCTION__); 43
44 DRM_DEBUG("%s: alloc %d order\n", __FUNCTION__, order);
61 45
62 address = __get_free_pages(GFP_KERNEL | __GFP_COMP, 46 address = __get_free_pages(GFP_KERNEL | __GFP_COMP,
63 ATI_PCIGART_TABLE_ORDER); 47 order);
64 if (address == 0UL) { 48 if (address == 0UL) {
65 return NULL; 49 return NULL;
66 } 50 }
67 51
68 page = virt_to_page(address); 52 page = virt_to_page(address);
69 53
70 for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) 54 for (i = 0; i < order; i++, page++)
71 SetPageReserved(page); 55 SetPageReserved(page);
72 56
73 DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); 57 DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
74 return (void *)address; 58 return (void *)address;
75} 59}
76 60
77static void drm_ati_free_pcigart_table(void *address) 61static void drm_ati_free_pcigart_table(void *address, int order)
78{ 62{
79 struct page *page; 63 struct page *page;
80 int i; 64 int i;
65 int num_pages = 1 << order;
81 DRM_DEBUG("%s\n", __FUNCTION__); 66 DRM_DEBUG("%s\n", __FUNCTION__);
82 67
83 page = virt_to_page((unsigned long)address); 68 page = virt_to_page((unsigned long)address);
84 69
85 for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) 70 for (i = 0; i < num_pages; i++, page++)
86 ClearPageReserved(page); 71 ClearPageReserved(page);
87 72
88 free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); 73 free_pages((unsigned long)address, order);
89} 74}
90 75
91int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) 76int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
@@ -93,6 +78,8 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
93 drm_sg_mem_t *entry = dev->sg; 78 drm_sg_mem_t *entry = dev->sg;
94 unsigned long pages; 79 unsigned long pages;
95 int i; 80 int i;
81 int order;
82 int num_pages, max_pages;
96 83
97 /* we need to support large memory configurations */ 84 /* we need to support large memory configurations */
98 if (!entry) { 85 if (!entry) {
@@ -100,15 +87,19 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
100 return 0; 87 return 0;
101 } 88 }
102 89
90 order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE);
91 num_pages = 1 << order;
92
103 if (gart_info->bus_addr) { 93 if (gart_info->bus_addr) {
104 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { 94 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
105 pci_unmap_single(dev->pdev, gart_info->bus_addr, 95 pci_unmap_single(dev->pdev, gart_info->bus_addr,
106 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, 96 num_pages * PAGE_SIZE,
107 PCI_DMA_TODEVICE); 97 PCI_DMA_TODEVICE);
108 } 98 }
109 99
110 pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) 100 max_pages = (gart_info->table_size / sizeof(u32));
111 ? entry->pages : ATI_MAX_PCIGART_PAGES; 101 pages = (entry->pages <= max_pages)
102 ? entry->pages : max_pages;
112 103
113 for (i = 0; i < pages; i++) { 104 for (i = 0; i < pages; i++) {
114 if (!entry->busaddr[i]) 105 if (!entry->busaddr[i])
@@ -123,13 +114,12 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
123 114
124 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN 115 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
125 && gart_info->addr) { 116 && gart_info->addr) {
126 drm_ati_free_pcigart_table(gart_info->addr); 117 drm_ati_free_pcigart_table(gart_info->addr, order);
127 gart_info->addr = NULL; 118 gart_info->addr = NULL;
128 } 119 }
129 120
130 return 1; 121 return 1;
131} 122}
132
133EXPORT_SYMBOL(drm_ati_pcigart_cleanup); 123EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
134 124
135int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) 125int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
@@ -139,6 +129,9 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
139 unsigned long pages; 129 unsigned long pages;
140 u32 *pci_gart, page_base, bus_address = 0; 130 u32 *pci_gart, page_base, bus_address = 0;
141 int i, j, ret = 0; 131 int i, j, ret = 0;
132 int order;
133 int max_pages;
134 int num_pages;
142 135
143 if (!entry) { 136 if (!entry) {
144 DRM_ERROR("no scatter/gather memory!\n"); 137 DRM_ERROR("no scatter/gather memory!\n");
@@ -148,7 +141,10 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
148 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { 141 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
149 DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); 142 DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
150 143
151 address = drm_ati_alloc_pcigart_table(); 144 order = drm_order((gart_info->table_size +
145 (PAGE_SIZE-1)) / PAGE_SIZE);
146 num_pages = 1 << order;
147 address = drm_ati_alloc_pcigart_table(order);
152 if (!address) { 148 if (!address) {
153 DRM_ERROR("cannot allocate PCI GART page!\n"); 149 DRM_ERROR("cannot allocate PCI GART page!\n");
154 goto done; 150 goto done;
@@ -160,11 +156,13 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
160 } 156 }
161 157
162 bus_address = pci_map_single(dev->pdev, address, 158 bus_address = pci_map_single(dev->pdev, address,