diff options
author | Dave Airlie <airlied@linux.ie> | 2007-05-08 01:19:23 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-05-08 01:19:23 -0400 |
commit | f2b04cd219e5c0f1214c0eeeec814ddd08a12c1b (patch) | |
tree | fa114ea7f96b5985e10c7f8696d635b074649bab /drivers/char/drm | |
parent | 5b94f675f57e4ff16c8fda09088d7480a84dcd91 (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>
Diffstat (limited to 'drivers/char/drm')
-rw-r--r-- | drivers/char/drm/ati_pcigart.c | 84 | ||||
-rw-r--r-- | drivers/char/drm/drmP.h | 7 | ||||
-rw-r--r-- | drivers/char/drm/drm_pciids.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/r128_cce.c | 3 | ||||
-rw-r--r-- | drivers/char/drm/r128_drv.h | 2 | ||||
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 71 | ||||
-rw-r--r-- | drivers/char/drm/radeon_drm.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/radeon_drv.h | 23 | ||||
-rw-r--r-- | drivers/char/drm/radeon_state.c | 6 |
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 | ||
55 | static void *drm_ati_alloc_pcigart_table(void) | 38 | static 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 | ||
77 | static void drm_ati_free_pcigart_table(void *address) | 61 | static 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 | ||
91 | int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | 76 | int 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 | |||
133 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); | 123 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); |
134 | 124 | ||
135 | int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | 125 | int 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, |
163 | ATI_PCIGART_TABLE_PAGES * | 159 | num_pages * PAGE_SIZE, |
164 | PAGE_SIZE, PCI_DMA_TODEVICE); | 160 | PCI_DMA_TODEVICE); |
165 | if (bus_address == 0) { | 161 | if (bus_address == 0) { |
166 | DRM_ERROR("unable to map PCIGART pages!\n"); | 162 | DRM_ERROR("unable to map PCIGART pages!\n"); |
167 | drm_ati_free_pcigart_table(address); | 163 | order = drm_order((gart_info->table_size + |
164 | (PAGE_SIZE-1)) / PAGE_SIZE); | ||
165 | drm_ati_free_pcigart_table(address, order); | ||
168 | address = NULL; | 166 | address = NULL; |
169 | goto done; | 167 | goto done; |
170 | } | 168 | } |
@@ -177,10 +175,11 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
177 | 175 | ||
178 | pci_gart = (u32 *) address; | 176 | pci_gart = (u32 *) address; |
179 | 177 | ||
180 | pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) | 178 | max_pages = (gart_info->table_size / sizeof(u32)); |
181 | ? entry->pages : ATI_MAX_PCIGART_PAGES; | 179 | pages = (entry->pages <= max_pages) |
180 | ? entry->pages : max_pages; | ||
182 | 181 | ||
183 | memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32)); | 182 | memset(pci_gart, 0, max_pages * sizeof(u32)); |
184 | 183 | ||
185 | for (i = 0; i < pages; i++) { | 184 | for (i = 0; i < pages; i++) { |
186 | /* we need to support large memory configurations */ | 185 | /* we need to support large memory configurations */ |
@@ -198,10 +197,18 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
198 | page_base = (u32) entry->busaddr[i]; | 197 | page_base = (u32) entry->busaddr[i]; |
199 | 198 | ||
200 | for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { | 199 | for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { |
201 | if (gart_info->is_pcie) | 200 | switch(gart_info->gart_reg_if) { |
201 | case DRM_ATI_GART_IGP: | ||
202 | *pci_gart = cpu_to_le32((page_base) | 0xc); | ||
203 | break; | ||
204 | case DRM_ATI_GART_PCIE: | ||
202 | *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); | 205 | *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); |
203 | else | 206 | break; |
207 | default: | ||
208 | case DRM_ATI_GART_PCI: | ||
204 | *pci_gart = cpu_to_le32(page_base); | 209 | *pci_gart = cpu_to_le32(page_base); |
210 | break; | ||
211 | } | ||
205 | pci_gart++; | 212 | pci_gart++; |
206 | page_base += ATI_PCIGART_PAGE_SIZE; | 213 | page_base += ATI_PCIGART_PAGE_SIZE; |
207 | } | 214 | } |
@@ -220,5 +227,4 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
220 | gart_info->bus_addr = bus_address; | 227 | gart_info->bus_addr = bus_address; |
221 | return ret; | 228 | return ret; |
222 | } | 229 | } |
223 | |||
224 | EXPORT_SYMBOL(drm_ati_pcigart_init); | 230 | EXPORT_SYMBOL(drm_ati_pcigart_init); |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 80041d5b792d..d494315752a2 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -519,12 +519,17 @@ typedef struct drm_vbl_sig { | |||
519 | #define DRM_ATI_GART_MAIN 1 | 519 | #define DRM_ATI_GART_MAIN 1 |
520 | #define DRM_ATI_GART_FB 2 | 520 | #define DRM_ATI_GART_FB 2 |
521 | 521 | ||
522 | #define DRM_ATI_GART_PCI 1 | ||
523 | #define DRM_ATI_GART_PCIE 2 | ||
524 | #define DRM_ATI_GART_IGP 3 | ||
525 | |||
522 | typedef struct ati_pcigart_info { | 526 | typedef struct ati_pcigart_info { |
523 | int gart_table_location; | 527 | int gart_table_location; |
524 | int is_pcie; | 528 | int gart_reg_if; |
525 | void *addr; | 529 | void *addr; |
526 | dma_addr_t bus_addr; | 530 | dma_addr_t bus_addr; |
527 | drm_local_map_t mapping; | 531 | drm_local_map_t mapping; |
532 | int table_size; | ||
528 | } drm_ati_pcigart_info; | 533 | } drm_ati_pcigart_info; |
529 | 534 | ||
530 | /* | 535 | /* |
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 01cf482d2d00..31cdde83713b 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -102,6 +102,7 @@ | |||
102 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 102 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
103 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ | 103 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ |
104 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ | 104 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ |
105 | {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ | ||
105 | {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 106 | {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
106 | {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 107 | {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
107 | {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 108 | {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index db5a60450e68..1014602c43a7 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c | |||
@@ -560,9 +560,10 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) | |||
560 | if (dev_priv->is_pci) { | 560 | if (dev_priv->is_pci) { |
561 | #endif | 561 | #endif |
562 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; | 562 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; |
563 | dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; | ||
563 | dev_priv->gart_info.addr = NULL; | 564 | dev_priv->gart_info.addr = NULL; |
564 | dev_priv->gart_info.bus_addr = 0; | 565 | dev_priv->gart_info.bus_addr = 0; |
565 | dev_priv->gart_info.is_pcie = 0; | 566 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; |
566 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | 567 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { |
567 | DRM_ERROR("failed to init PCI GART!\n"); | 568 | DRM_ERROR("failed to init PCI GART!\n"); |
568 | dev->dev_private = (void *)dev_priv; | 569 | dev->dev_private = (void *)dev_priv; |
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index f1efb49de8df..9086835686dc 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h | |||
@@ -383,6 +383,8 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, | |||
383 | 383 | ||
384 | #define R128_PERFORMANCE_BOXES 0 | 384 | #define R128_PERFORMANCE_BOXES 0 |
385 | 385 | ||
386 | #define R128_PCIGART_TABLE_SIZE 32768 | ||
387 | |||
386 | #define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) | 388 | #define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) |
387 | #define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) | 389 | #define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) |
388 | #define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) | 390 | #define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index c1850ecac302..68338389d836 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -830,6 +830,15 @@ static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) | |||
830 | return RADEON_READ(RADEON_PCIE_DATA); | 830 | return RADEON_READ(RADEON_PCIE_DATA); |
831 | } | 831 | } |
832 | 832 | ||
833 | static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr) | ||
834 | { | ||
835 | u32 ret; | ||
836 | RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f); | ||
837 | ret = RADEON_READ(RADEON_IGPGART_DATA); | ||
838 | RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f); | ||
839 | return ret; | ||
840 | } | ||
841 | |||
833 | #if RADEON_FIFO_DEBUG | 842 | #if RADEON_FIFO_DEBUG |
834 | static void radeon_status(drm_radeon_private_t * dev_priv) | 843 | static void radeon_status(drm_radeon_private_t * dev_priv) |
835 | { | 844 | { |
@@ -1267,7 +1276,44 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) | |||
1267 | } | 1276 | } |
1268 | } | 1277 | } |
1269 | 1278 | ||
1270 | /* Enable or disable PCI-E GART on the chip */ | 1279 | /* Enable or disable IGP GART on the chip */ |
1280 | static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) | ||
1281 | { | ||
1282 | u32 temp, tmp; | ||
1283 | |||
1284 | tmp = RADEON_READ(RADEON_AIC_CNTL); | ||
1285 | if (on) { | ||
1286 | DRM_DEBUG("programming igpgart %08X %08lX %08X\n", | ||
1287 | dev_priv->gart_vm_start, | ||
1288 | (long)dev_priv->gart_info.bus_addr, | ||
1289 | dev_priv->gart_size); | ||
1290 | |||
1291 | RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000); | ||
1292 | RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1); | ||
1293 | RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800); | ||
1294 | RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR, | ||
1295 | dev_priv->gart_info.bus_addr); | ||
1296 | |||
1297 | temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39); | ||
1298 | RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp); | ||
1299 | |||
1300 | RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start); | ||
1301 | dev_priv->gart_size = 32*1024*1024; | ||
1302 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, | ||
1303 | (((dev_priv->gart_vm_start - 1 + | ||
1304 | dev_priv->gart_size) & 0xffff0000) | | ||
1305 | (dev_priv->gart_vm_start >> 16))); | ||
1306 | |||
1307 | temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE); | ||
1308 | RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp); | ||
1309 | |||
1310 | RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); | ||
1311 | RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1); | ||
1312 | RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); | ||
1313 | RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0); | ||
1314 | } | ||
1315 | } | ||
1316 | |||
1271 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | 1317 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) |
1272 | { | 1318 | { |
1273 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); | 1319 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); |
@@ -1302,6 +1348,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
1302 | { | 1348 | { |
1303 | u32 tmp; | 1349 | u32 tmp; |
1304 | 1350 | ||
1351 | if (dev_priv->flags & RADEON_IS_IGPGART) { | ||
1352 | radeon_set_igpgart(dev_priv, on); | ||
1353 | return; | ||
1354 | } | ||
1355 | |||
1305 | if (dev_priv->flags & RADEON_IS_PCIE) { | 1356 | if (dev_priv->flags & RADEON_IS_PCIE) { |
1306 | radeon_set_pciegart(dev_priv, on); | 1357 | radeon_set_pciegart(dev_priv, on); |
1307 | return; | 1358 | return; |
@@ -1620,20 +1671,22 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1620 | #endif | 1671 | #endif |
1621 | { | 1672 | { |
1622 | /* if we have an offset set from userspace */ | 1673 | /* if we have an offset set from userspace */ |
1623 | if (dev_priv->pcigart_offset) { | 1674 | if (dev_priv->pcigart_offset_set) { |
1624 | dev_priv->gart_info.bus_addr = | 1675 | dev_priv->gart_info.bus_addr = |
1625 | dev_priv->pcigart_offset + dev_priv->fb_location; | 1676 | dev_priv->pcigart_offset + dev_priv->fb_location; |
1626 | dev_priv->gart_info.mapping.offset = | 1677 | dev_priv->gart_info.mapping.offset = |
1627 | dev_priv->gart_info.bus_addr; | 1678 | dev_priv->gart_info.bus_addr; |
1628 | dev_priv->gart_info.mapping.size = | 1679 | dev_priv->gart_info.mapping.size = |
1629 | RADEON_PCIGART_TABLE_SIZE; | 1680 | dev_priv->gart_info.table_size; |
1630 | 1681 | ||
1631 | drm_core_ioremap(&dev_priv->gart_info.mapping, dev); | 1682 | drm_core_ioremap(&dev_priv->gart_info.mapping, dev); |
1632 | dev_priv->gart_info.addr = | 1683 | dev_priv->gart_info.addr = |
1633 | dev_priv->gart_info.mapping.handle; | 1684 | dev_priv->gart_info.mapping.handle; |
1634 | 1685 | ||
1635 | dev_priv->gart_info.is_pcie = | 1686 | if (dev_priv->flags & RADEON_IS_PCIE) |
1636 | !!(dev_priv->flags & RADEON_IS_PCIE); | 1687 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; |
1688 | else | ||
1689 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; | ||
1637 | dev_priv->gart_info.gart_table_location = | 1690 | dev_priv->gart_info.gart_table_location = |
1638 | DRM_ATI_GART_FB; | 1691 | DRM_ATI_GART_FB; |
1639 | 1692 | ||
@@ -1641,6 +1694,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1641 | dev_priv->gart_info.addr, | 1694 | dev_priv->gart_info.addr, |
1642 | dev_priv->pcigart_offset); | 1695 | dev_priv->pcigart_offset); |
1643 | } else { | 1696 | } else { |
1697 | if (dev_priv->flags & RADEON_IS_IGPGART) | ||
1698 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; | ||
1699 | else | ||
1700 | dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; | ||
1644 | dev_priv->gart_info.gart_table_location = | 1701 | dev_priv->gart_info.gart_table_location = |
1645 | DRM_ATI_GART_MAIN; | 1702 | DRM_ATI_GART_MAIN; |
1646 | dev_priv->gart_info.addr = NULL; | 1703 | dev_priv->gart_info.addr = NULL; |
@@ -1714,7 +1771,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) | |||
1714 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) | 1771 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) |
1715 | { | 1772 | { |
1716 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); | 1773 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); |
1717 | dev_priv->gart_info.addr = NULL; | 1774 | dev_priv->gart_info.addr = 0; |
1718 | } | 1775 | } |
1719 | } | 1776 | } |
1720 | /* only clear to the start of flags */ | 1777 | /* only clear to the start of flags */ |
@@ -2222,6 +2279,8 @@ int radeon_driver_firstopen(struct drm_device *dev) | |||
2222 | drm_local_map_t *map; | 2279 | drm_local_map_t *map; |
2223 | drm_radeon_private_t *dev_priv = dev->dev_private; | 2280 | drm_radeon_private_t *dev_priv = dev->dev_private; |
2224 | 2281 | ||
2282 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | ||
2283 | |||
2225 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | 2284 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), |
2226 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | 2285 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, |
2227 | _DRM_READ_ONLY, &dev_priv->mmio); | 2286 | _DRM_READ_ONLY, &dev_priv->mmio); |
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 8d6350dd5360..66c4b6fed04f 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h | |||
@@ -707,6 +707,7 @@ typedef struct drm_radeon_setparam { | |||
707 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ | 707 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ |
708 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ | 708 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ |
709 | #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ | 709 | #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ |
710 | #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ | ||
710 | 711 | ||
711 | /* 1.14: Clients can allocate/free a surface | 712 | /* 1.14: Clients can allocate/free a surface |
712 | */ | 713 | */ |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 8b105f1460a7..97c27da2d26d 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -95,9 +95,11 @@ | |||
95 | * 1.24- Add general-purpose packet for manipulating scratch registers (r300) | 95 | * 1.24- Add general-purpose packet for manipulating scratch registers (r300) |
96 | * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, | 96 | * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, |
97 | * new packet type) | 97 | * new packet type) |
98 | * 1.26- Add support for variable size PCI(E) gart aperture | ||
99 | * 1.27- Add support for IGP GART | ||
98 | */ | 100 | */ |
99 | #define DRIVER_MAJOR 1 | 101 | #define DRIVER_MAJOR 1 |
100 | #define DRIVER_MINOR 25 | 102 | #define DRIVER_MINOR 27 |
101 | #define DRIVER_PATCHLEVEL 0 | 103 | #define DRIVER_PATCHLEVEL 0 |
102 | 104 | ||
103 | /* | 105 | /* |
@@ -143,6 +145,7 @@ enum radeon_chip_flags { | |||
143 | RADEON_IS_PCIE = 0x00200000UL, | 145 | RADEON_IS_PCIE = 0x00200000UL, |
144 | RADEON_NEW_MEMMAP = 0x00400000UL, | 146 | RADEON_NEW_MEMMAP = 0x00400000UL, |
145 | RADEON_IS_PCI = 0x00800000UL, | 147 | RADEON_IS_PCI = 0x00800000UL, |
148 | RADEON_IS_IGPGART = 0x01000000UL, | ||
146 | }; | 149 | }; |
147 | 150 | ||
148 | #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ | 151 | #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ |
@@ -280,6 +283,7 @@ typedef struct drm_radeon_private { | |||
280 | struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; | 283 | struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; |
281 | 284 | ||
282 | unsigned long pcigart_offset; | 285 | unsigned long pcigart_offset; |
286 | unsigned int pcigart_offset_set; | ||
283 | drm_ati_pcigart_info gart_info; | 287 | drm_ati_pcigart_info gart_info; |
284 | 288 | ||
285 | u32 scratch_ages[5]; | 289 | u32 scratch_ages[5]; |
@@ -432,6 +436,15 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, | |||
432 | #define RADEON_PCIE_TX_GART_END_LO 0x16 | 436 | #define RADEON_PCIE_TX_GART_END_LO 0x16 |
433 | #define RADEON_PCIE_TX_GART_END_HI 0x17 | 437 | #define RADEON_PCIE_TX_GART_END_HI 0x17 |
434 | 438 | ||
439 | #define RADEON_IGPGART_INDEX 0x168 | ||
440 | #define RADEON_IGPGART_DATA 0x16c | ||
441 | #define RADEON_IGPGART_UNK_18 0x18 | ||
442 | #define RADEON_IGPGART_CTRL 0x2b | ||
443 | #define RADEON_IGPGART_BASE_ADDR 0x2c | ||
444 | #define RADEON_IGPGART_FLUSH 0x2e | ||
445 | #define RADEON_IGPGART_ENABLE 0x38 | ||
446 | #define RADEON_IGPGART_UNK_39 0x39 | ||
447 | |||
435 | #define RADEON_MPP_TB_CONFIG 0x01c0 | 448 | #define RADEON_MPP_TB_CONFIG 0x01c0 |
436 | #define RADEON_MEM_CNTL 0x0140 | 449 | #define RADEON_MEM_CNTL 0x0140 |
437 | #define RADEON_MEM_SDRAM_MODE_REG 0x0158 | 450 | #define RADEON_MEM_SDRAM_MODE_REG 0x0158 |
@@ -964,6 +977,14 @@ do { \ | |||
964 | RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ | 977 | RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ |
965 | } while (0) | 978 | } while (0) |
966 | 979 | ||
980 | #define RADEON_WRITE_IGPGART( addr, val ) \ | ||
981 | do { \ | ||
982 | RADEON_WRITE( RADEON_IGPGART_INDEX, \ | ||
983 | ((addr) & 0x7f) | (1 << 8)); \ | ||
984 | RADEON_WRITE( RADEON_IGPGART_DATA, (val) ); \ | ||
985 | RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f ); \ | ||
986 | } while (0) | ||
987 | |||
967 | #define RADEON_WRITE_PCIE( addr, val ) \ | 988 | #define RADEON_WRITE_PCIE( addr, val ) \ |
968 | do { \ | 989 | do { \ |
969 | RADEON_WRITE8( RADEON_PCIE_INDEX, \ | 990 | RADEON_WRITE8( RADEON_PCIE_INDEX, \ |
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 938eccb78cc0..d6041911c474 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -3145,10 +3145,16 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
3145 | break; | 3145 | break; |
3146 | case RADEON_SETPARAM_PCIGART_LOCATION: | 3146 | case RADEON_SETPARAM_PCIGART_LOCATION: |
3147 | dev_priv->pcigart_offset = sp.value; | 3147 | dev_priv->pcigart_offset = sp.value; |
3148 | dev_priv->pcigart_offset_set = 1; | ||
3148 | break; | 3149 | break; |
3149 | case RADEON_SETPARAM_NEW_MEMMAP: | 3150 | case RADEON_SETPARAM_NEW_MEMMAP: |
3150 | dev_priv->new_memmap = sp.value; | 3151 | dev_priv->new_memmap = sp.value; |
3151 | break; | 3152 | break; |
3153 | case RADEON_SETPARAM_PCIGART_TABLE_SIZE: | ||
3154 | dev_priv->gart_info.table_size = sp.value; | ||
3155 | if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) | ||
3156 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | ||
3157 | break; | ||
3152 | default: | 3158 | default: |
3153 | DRM_DEBUG("Invalid parameter %d\n", sp.param); | 3159 | DRM_DEBUG("Invalid parameter %d\n", sp.param); |
3154 | return DRM_ERR(EINVAL); | 3160 | return DRM_ERR(EINVAL); |