diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-09-11 06:28:11 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-09-11 06:28:11 -0400 |
commit | ea98a92ff18c03bf7f4d21536986cbbcb4c10cd9 (patch) | |
tree | fbff15aaacf19824083c9edb8d37548031636580 | |
parent | 9d17601c4e132eee9fe450191f6866fb9fb5a762 (diff) |
drm: add radeon PCI express support
Add support for Radeon PCI Express cards (needs a new X.org DDX)
Also allows PCI GART table to be stored in VRAM for non PCIE cards
Signed-off-by: Dave Airlie <airlied@linux.ie>
-rw-r--r-- | drivers/char/drm/ati_pcigart.c | 82 | ||||
-rw-r--r-- | drivers/char/drm/drmP.h | 24 | ||||
-rw-r--r-- | drivers/char/drm/r128_cce.c | 16 | ||||
-rw-r--r-- | drivers/char/drm/r128_drv.h | 3 | ||||
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 77 | ||||
-rw-r--r-- | drivers/char/drm/radeon_drm.h | 1 | ||||
-rw-r--r-- | drivers/char/drm/radeon_drv.h | 39 | ||||
-rw-r--r-- | drivers/char/drm/radeon_state.c | 3 |
8 files changed, 186 insertions, 59 deletions
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 0aec5ef481b8..957596c63934 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
@@ -91,9 +91,7 @@ static void drm_ati_free_pcigart_table( unsigned long address ) | |||
91 | free_pages( address, ATI_PCIGART_TABLE_ORDER ); | 91 | free_pages( address, ATI_PCIGART_TABLE_ORDER ); |
92 | } | 92 | } |
93 | 93 | ||
94 | int drm_ati_pcigart_cleanup( drm_device_t *dev, | 94 | int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) |
95 | unsigned long addr, | ||
96 | dma_addr_t bus_addr) | ||
97 | { | 95 | { |
98 | drm_sg_mem_t *entry = dev->sg; | 96 | drm_sg_mem_t *entry = dev->sg; |
99 | unsigned long pages; | 97 | unsigned long pages; |
@@ -105,10 +103,12 @@ int drm_ati_pcigart_cleanup( drm_device_t *dev, | |||
105 | return 0; | 103 | return 0; |
106 | } | 104 | } |
107 | 105 | ||
108 | if ( bus_addr ) { | 106 | if (gart_info->bus_addr) { |
109 | pci_unmap_single(dev->pdev, bus_addr, | 107 | if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) { |
110 | ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, | 108 | pci_unmap_single(dev->pdev, gart_info->bus_addr, |
111 | PCI_DMA_TODEVICE); | 109 | ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, |
110 | PCI_DMA_TODEVICE); | ||
111 | } | ||
112 | 112 | ||
113 | pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) | 113 | pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) |
114 | ? entry->pages : ATI_MAX_PCIGART_PAGES; | 114 | ? entry->pages : ATI_MAX_PCIGART_PAGES; |
@@ -118,19 +118,21 @@ int drm_ati_pcigart_cleanup( drm_device_t *dev, | |||
118 | pci_unmap_single(dev->pdev, entry->busaddr[i], | 118 | pci_unmap_single(dev->pdev, entry->busaddr[i], |
119 | PAGE_SIZE, PCI_DMA_TODEVICE); | 119 | PAGE_SIZE, PCI_DMA_TODEVICE); |
120 | } | 120 | } |
121 | |||
122 | if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) | ||
123 | gart_info->bus_addr=0; | ||
121 | } | 124 | } |
122 | 125 | ||
123 | if ( addr ) { | 126 | if (gart_info->gart_table_location==DRM_ATI_GART_MAIN && gart_info->addr) { |
124 | drm_ati_free_pcigart_table( addr ); | 127 | drm_ati_free_pcigart_table(gart_info->addr); |
128 | gart_info->addr=0; | ||
125 | } | 129 | } |
126 | 130 | ||
127 | return 1; | 131 | return 1; |
128 | } | 132 | } |
129 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); | 133 | EXPORT_SYMBOL(drm_ati_pcigart_cleanup); |
130 | 134 | ||
131 | int drm_ati_pcigart_init( drm_device_t *dev, | 135 | int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) |
132 | unsigned long *addr, | ||
133 | dma_addr_t *bus_addr) | ||
134 | { | 136 | { |
135 | drm_sg_mem_t *entry = dev->sg; | 137 | drm_sg_mem_t *entry = dev->sg; |
136 | unsigned long address = 0; | 138 | unsigned long address = 0; |
@@ -143,25 +145,36 @@ int drm_ati_pcigart_init( drm_device_t *dev, | |||
143 | goto done; | 145 | goto done; |
144 | } | 146 | } |
145 | 147 | ||
146 | address = drm_ati_alloc_pcigart_table(); | 148 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) |
147 | if ( !address ) { | 149 | { |
148 | DRM_ERROR( "cannot allocate PCI GART page!\n" ); | 150 | DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); |
149 | goto done; | 151 | |
150 | } | 152 | address = drm_ati_alloc_pcigart_table(); |
153 | if ( !address ) { | ||
154 | DRM_ERROR( "cannot allocate PCI GART page!\n" ); | ||
155 | goto done; | ||
156 | } | ||
157 | |||
158 | if ( !dev->pdev ) { | ||
159 | DRM_ERROR( "PCI device unknown!\n" ); | ||
160 | goto done; | ||
161 | } | ||
151 | 162 | ||
152 | if ( !dev->pdev ) { | 163 | bus_address = pci_map_single(dev->pdev, (void *)address, |
153 | DRM_ERROR( "PCI device unknown!\n" ); | 164 | ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, |
154 | goto done; | 165 | PCI_DMA_TODEVICE); |
166 | if (bus_address == 0) { | ||
167 | DRM_ERROR( "unable to map PCIGART pages!\n" ); | ||
168 | drm_ati_free_pcigart_table( address ); | ||
169 | address = 0; | ||
170 | goto done; | ||
171 | } | ||
155 | } | 172 | } |
156 | 173 | else | |
157 | bus_address = pci_map_single(dev->pdev, (void *)address, | 174 | { |
158 | ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, | 175 | address = gart_info->addr; |
159 | PCI_DMA_TODEVICE); | 176 | bus_address = gart_info->bus_addr; |
160 | if (bus_address == 0) { | 177 | DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", bus_address, address); |
161 | DRM_ERROR( "unable to map PCIGART pages!\n" ); | ||
162 | drm_ati_free_pcigart_table( address ); | ||
163 | address = 0; | ||
164 | goto done; | ||
165 | } | 178 | } |
166 | 179 | ||
167 | pci_gart = (u32 *)address; | 180 | pci_gart = (u32 *)address; |
@@ -179,7 +192,7 @@ int drm_ati_pcigart_init( drm_device_t *dev, | |||
179 | PCI_DMA_TODEVICE); | 192 | PCI_DMA_TODEVICE); |
180 | if (entry->busaddr[i] == 0) { | 193 | if (entry->busaddr[i] == 0) { |
181 | DRM_ERROR( "unable to map PCIGART pages!\n" ); | 194 | DRM_ERROR( "unable to map PCIGART pages!\n" ); |
182 | drm_ati_pcigart_cleanup( dev, address, bus_address ); | 195 | drm_ati_pcigart_cleanup(dev, gart_info); |
183 | address = 0; | 196 | address = 0; |
184 | bus_address = 0; | 197 | bus_address = 0; |
185 | goto done; | 198 | goto done; |
@@ -187,7 +200,10 @@ int drm_ati_pcigart_init( drm_device_t *dev, | |||
187 | page_base = (u32) entry->busaddr[i]; | 200 | page_base = (u32) entry->busaddr[i]; |
188 | 201 | ||
189 | for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { | 202 | for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { |
190 | *pci_gart++ = cpu_to_le32( page_base ); | 203 | if (gart_info->is_pcie) |
204 | *pci_gart = (cpu_to_le32(page_base)>>8) | 0xc; | ||
205 | else | ||
206 | *pci_gart++ = cpu_to_le32( page_base ); | ||
191 | page_base += ATI_PCIGART_PAGE_SIZE; | 207 | page_base += ATI_PCIGART_PAGE_SIZE; |
192 | } | 208 | } |
193 | } | 209 | } |
@@ -201,8 +217,8 @@ int drm_ati_pcigart_init( drm_device_t *dev, | |||
201 | #endif | 217 | #endif |
202 | 218 | ||
203 | done: | 219 | done: |
204 | *addr = address; | 220 | gart_info->addr = address; |
205 | *bus_addr = bus_address; | 221 | gart_info->bus_addr = bus_address; |
206 | return ret; | 222 | return ret; |
207 | } | 223 | } |
208 | EXPORT_SYMBOL(drm_ati_pcigart_init); | 224 | EXPORT_SYMBOL(drm_ati_pcigart_init); |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 6f98701dfe15..c164c76e33f3 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -532,6 +532,17 @@ typedef struct drm_vbl_sig { | |||
532 | } drm_vbl_sig_t; | 532 | } drm_vbl_sig_t; |
533 | 533 | ||
534 | 534 | ||
535 | /* location of GART table */ | ||
536 | #define DRM_ATI_GART_MAIN 1 | ||
537 | #define DRM_ATI_GART_FB 2 | ||
538 | |||
539 | typedef struct ati_pcigart_info { | ||
540 | int gart_table_location; | ||
541 | int is_pcie; | ||
542 | unsigned long addr; | ||
543 | dma_addr_t bus_addr; | ||
544 | } drm_ati_pcigart_info; | ||
545 | |||
535 | /** | 546 | /** |
536 | * DRM driver structure. This structure represent the common code for | 547 | * DRM driver structure. This structure represent the common code for |
537 | * a family of cards. There will one drm_device for each card present | 548 | * a family of cards. There will one drm_device for each card present |
@@ -975,12 +986,8 @@ extern int drm_sg_free(struct inode *inode, struct file *filp, | |||
975 | unsigned int cmd, unsigned long arg); | 986 | unsigned int cmd, unsigned long arg); |
976 | 987 | ||
977 | /* ATI PCIGART support (ati_pcigart.h) */ | 988 | /* ATI PCIGART support (ati_pcigart.h) */ |
978 | extern int drm_ati_pcigart_init(drm_device_t *dev, | 989 | extern int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info *gart_info); |
979 | unsigned long *addr, | 990 | extern int drm_ati_pcigart_cleanup(drm_device_t * dev, drm_ati_pcigart_info *gart_info); |
980 | dma_addr_t *bus_addr); | ||
981 | extern int drm_ati_pcigart_cleanup(drm_device_t *dev, | ||
982 | unsigned long addr, | ||
983 | dma_addr_t bus_addr); | ||
984 | 991 | ||
985 | extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, | 992 | extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, |
986 | size_t align, dma_addr_t maxaddr); | 993 | size_t align, dma_addr_t maxaddr); |
@@ -1038,6 +1045,11 @@ static __inline__ int drm_device_is_agp(drm_device_t *dev) | |||
1038 | return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP); | 1045 | return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP); |
1039 | } | 1046 | } |
1040 | 1047 | ||
1048 | static __inline__ int drm_device_is_pcie(drm_device_t *dev) | ||
1049 | { | ||
1050 | return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); | ||
1051 | } | ||
1052 | |||
1041 | static __inline__ void drm_core_dropmap(struct drm_map *map) | 1053 | static __inline__ void drm_core_dropmap(struct drm_map *map) |
1042 | { | 1054 | { |
1043 | } | 1055 | } |
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c index 895152206b31..ac3ea2bc9b28 100644 --- a/drivers/char/drm/r128_cce.c +++ b/drivers/char/drm/r128_cce.c | |||
@@ -562,14 +562,16 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) | |||
562 | #if __OS_HAS_AGP | 562 | #if __OS_HAS_AGP |
563 | if ( dev_priv->is_pci ) { | 563 | if ( dev_priv->is_pci ) { |
564 | #endif | 564 | #endif |
565 | if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart, | 565 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; |
566 | &dev_priv->bus_pci_gart) ) { | 566 | dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0; |
567 | dev_priv->gart_info.is_pcie = 0; | ||
568 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | ||
567 | DRM_ERROR( "failed to init PCI GART!\n" ); | 569 | DRM_ERROR( "failed to init PCI GART!\n" ); |
568 | dev->dev_private = (void *)dev_priv; | 570 | dev->dev_private = (void *)dev_priv; |
569 | r128_do_cleanup_cce( dev ); | 571 | r128_do_cleanup_cce( dev ); |
570 | return DRM_ERR(ENOMEM); | 572 | return DRM_ERR(ENOMEM); |
571 | } | 573 | } |
572 | R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart ); | 574 | R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); |
573 | #if __OS_HAS_AGP | 575 | #if __OS_HAS_AGP |
574 | } | 576 | } |
575 | #endif | 577 | #endif |
@@ -607,10 +609,10 @@ int r128_do_cleanup_cce( drm_device_t *dev ) | |||
607 | } else | 609 | } else |
608 | #endif | 610 | #endif |
609 | { | 611 | { |
610 | if (!drm_ati_pcigart_cleanup( dev, | 612 | if (dev_priv->gart_info.bus_addr) |
611 | dev_priv->phys_pci_gart, | 613 | if (!drm_ati_pcigart_cleanup( dev, |
612 | dev_priv->bus_pci_gart )) | 614 | &dev_priv->gart_info)) |
613 | DRM_ERROR( "failed to cleanup PCI GART!\n" ); | 615 | DRM_ERROR( "failed to cleanup PCI GART!\n" ); |
614 | } | 616 | } |
615 | 617 | ||
616 | drm_free( dev->dev_private, sizeof(drm_r128_private_t), | 618 | drm_free( dev->dev_private, sizeof(drm_r128_private_t), |
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h index 0fb687c9505e..938dfaea553a 100644 --- a/drivers/char/drm/r128_drv.h +++ b/drivers/char/drm/r128_drv.h | |||
@@ -88,8 +88,6 @@ typedef struct drm_r128_private { | |||
88 | 88 | ||
89 | int usec_timeout; | 89 | int usec_timeout; |
90 | int is_pci; | 90 | int is_pci; |
91 | unsigned long phys_pci_gart; | ||
92 | dma_addr_t bus_pci_gart; | ||
93 | unsigned long cce_buffers_offset; | 91 | unsigned long cce_buffers_offset; |
94 | 92 | ||
95 | atomic_t idle_count; | 93 | atomic_t idle_count; |
@@ -120,6 +118,7 @@ typedef struct drm_r128_private { | |||
120 | drm_local_map_t *cce_ring; | 118 | drm_local_map_t *cce_ring; |
121 | drm_local_map_t *ring_rptr; | 119 | drm_local_map_t *ring_rptr; |
122 | drm_local_map_t *agp_textures; | 120 | drm_local_map_t *agp_textures; |
121 | drm_ati_pcigart_info gart_info; | ||
123 | } drm_r128_private_t; | 122 | } drm_r128_private_t; |
124 | 123 | ||
125 | typedef struct drm_r128_buf_priv { | 124 | typedef struct drm_r128_buf_priv { |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 6d9080a3ca7e..6dff5e43f713 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -825,6 +825,12 @@ static int RADEON_READ_PLL(drm_device_t *dev, int addr) | |||
825 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); | 825 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); |
826 | } | 826 | } |
827 | 827 | ||
828 | static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) | ||
829 | { | ||
830 | RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); | ||
831 | return RADEON_READ(RADEON_PCIE_DATA); | ||
832 | } | ||
833 | |||
828 | #if RADEON_FIFO_DEBUG | 834 | #if RADEON_FIFO_DEBUG |
829 | static void radeon_status( drm_radeon_private_t *dev_priv ) | 835 | static void radeon_status( drm_radeon_private_t *dev_priv ) |
830 | { | 836 | { |
@@ -1241,17 +1247,46 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, | |||
1241 | RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); | 1247 | RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); |
1242 | } | 1248 | } |
1243 | 1249 | ||
1250 | /* Enable or disable PCI-E GART on the chip */ | ||
1251 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | ||
1252 | { | ||
1253 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); | ||
1254 | if (on) { | ||
1255 | |||
1256 | DRM_DEBUG("programming pcie %08X %08lX %08X\n", | ||
1257 | dev_priv->gart_vm_start, (long)dev_priv->gart_info.bus_addr, | ||
1258 | dev_priv->gart_size); | ||
1259 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start); | ||
1260 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->gart_info.bus_addr); | ||
1261 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start); | ||
1262 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, dev_priv->gart_vm_start | ||
1263 | + dev_priv->gart_size - 1); | ||
1264 | |||
1265 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ | ||
1266 | |||
1267 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN); | ||
1268 | } else { | ||
1269 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1244 | /* Enable or disable PCI GART on the chip */ | 1273 | /* Enable or disable PCI GART on the chip */ |
1245 | static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) | 1274 | static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) |
1246 | { | 1275 | { |
1247 | u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); | 1276 | u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); |
1248 | 1277 | ||
1278 | if (dev_priv->flags & CHIP_IS_PCIE) | ||
1279 | { | ||
1280 | radeon_set_pciegart(dev_priv, on); | ||
1281 | return; | ||
1282 | } | ||
1283 | |||
1249 | if ( on ) { | 1284 | if ( on ) { |
1250 | RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); | 1285 | RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); |
1251 | 1286 | ||
1252 | /* set PCI GART page-table base address | 1287 | /* set PCI GART page-table base address |
1253 | */ | 1288 | */ |
1254 | RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); | 1289 | RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); |
1255 | 1290 | ||
1256 | /* set address range for PCI address translate | 1291 | /* set address range for PCI address translate |
1257 | */ | 1292 | */ |
@@ -1519,8 +1554,28 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) | |||
1519 | } else | 1554 | } else |
1520 | #endif | 1555 | #endif |
1521 | { | 1556 | { |
1522 | if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart, | 1557 | /* if we have an offset set from userspace */ |
1523 | &dev_priv->bus_pci_gart)) { | 1558 | if (dev_priv->pcigart_offset) { |
1559 | dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location; | ||
1560 | dev_priv->gart_info.addr = (unsigned long)drm_ioremap(dev_priv->gart_info.bus_addr, RADEON_PCIGART_TABLE_SIZE, dev); | ||
1561 | |||
1562 | dev_priv->gart_info.is_pcie = !!(dev_priv->flags & CHIP_IS_PCIE); | ||
1563 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; | ||
1564 | |||
1565 | DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", dev_priv->gart_info.addr, dev_priv->pcigart_offset); | ||
1566 | } | ||
1567 | else { | ||
1568 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; | ||
1569 | dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr= 0; | ||
1570 | if (dev_priv->flags & CHIP_IS_PCIE) | ||
1571 | { | ||
1572 | DRM_ERROR("Cannot use PCI Express without GART in FB memory\n"); | ||
1573 | radeon_do_cleanup_cp(dev); | ||
1574 | return DRM_ERR(EINVAL); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | ||
1524 | DRM_ERROR( "failed to init PCI GART!\n" ); | 1579 | DRM_ERROR( "failed to init PCI GART!\n" ); |
1525 | dev->dev_private = (void *)dev_priv; | 1580 | dev->dev_private = (void *)dev_priv; |
1526 | radeon_do_cleanup_cp(dev); | 1581 | radeon_do_cleanup_cp(dev); |
@@ -1568,10 +1623,15 @@ static int radeon_do_cleanup_cp( drm_device_t *dev ) | |||
1568 | } else | 1623 | } else |
1569 | #endif | 1624 | #endif |
1570 | { | 1625 | { |
1571 | if (!drm_ati_pcigart_cleanup( dev, | 1626 | if (dev_priv->gart_info.bus_addr) |
1572 | dev_priv->phys_pci_gart, | 1627 | if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) |
1573 | dev_priv->bus_pci_gart )) | 1628 | DRM_ERROR("failed to cleanup PCI GART!\n"); |
1574 | DRM_ERROR( "failed to cleanup PCI GART!\n" ); | 1629 | |
1630 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) | ||
1631 | { | ||
1632 | drm_ioremapfree((void *)dev_priv->gart_info.addr, RADEON_PCIGART_TABLE_SIZE, dev); | ||
1633 | dev_priv->gart_info.addr = 0; | ||
1634 | } | ||
1575 | } | 1635 | } |
1576 | 1636 | ||
1577 | /* only clear to the start of flags */ | 1637 | /* only clear to the start of flags */ |
@@ -2057,6 +2117,9 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) | |||
2057 | if (drm_device_is_agp(dev)) | 2117 | if (drm_device_is_agp(dev)) |
2058 | dev_priv->flags |= CHIP_IS_AGP; | 2118 | dev_priv->flags |= CHIP_IS_AGP; |
2059 | 2119 | ||
2120 | if (drm_device_is_pcie(dev)) | ||
2121 | dev_priv->flags |= CHIP_IS_PCIE; | ||
2122 | |||
2060 | DRM_DEBUG("%s card detected\n", | 2123 | DRM_DEBUG("%s card detected\n", |
2061 | ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); | 2124 | ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); |
2062 | return ret; | 2125 | return ret; |
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h index 67a8bf04970e..dd526617faec 100644 --- a/drivers/char/drm/radeon_drm.h +++ b/drivers/char/drm/radeon_drm.h | |||
@@ -698,6 +698,7 @@ typedef struct drm_radeon_setparam { | |||
698 | 698 | ||
699 | #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ | 699 | #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ |
700 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ | 700 | #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ |
701 | #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ | ||
701 | 702 | ||
702 | /* 1.14: Clients can allocate/free a surface | 703 | /* 1.14: Clients can allocate/free a surface |
703 | */ | 704 | */ |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 430598e1fa67..9c10141845e7 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define DRIVER_NAME "radeon" | 39 | #define DRIVER_NAME "radeon" |
40 | #define DRIVER_DESC "ATI Radeon" | 40 | #define DRIVER_DESC "ATI Radeon" |
41 | #define DRIVER_DATE "20050720" | 41 | #define DRIVER_DATE "20050911" |
42 | 42 | ||
43 | /* Interface history: | 43 | /* Interface history: |
44 | * | 44 | * |
@@ -87,9 +87,10 @@ | |||
87 | * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces | 87 | * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces |
88 | * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR | 88 | * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR |
89 | * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) | 89 | * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) |
90 | * 1.19- Add support for gart table in FB memory and PCIE r300 | ||
90 | */ | 91 | */ |
91 | #define DRIVER_MAJOR 1 | 92 | #define DRIVER_MAJOR 1 |
92 | #define DRIVER_MINOR 18 | 93 | #define DRIVER_MINOR 19 |
93 | #define DRIVER_PATCHLEVEL 0 | 94 | #define DRIVER_PATCHLEVEL 0 |
94 | 95 | ||
95 | #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) | 96 | #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) |
@@ -134,6 +135,7 @@ enum radeon_chip_flags { | |||
134 | CHIP_SINGLE_CRTC = 0x00040000UL, | 135 | CHIP_SINGLE_CRTC = 0x00040000UL, |
135 | CHIP_IS_AGP = 0x00080000UL, | 136 | CHIP_IS_AGP = 0x00080000UL, |
136 | CHIP_HAS_HIERZ = 0x00100000UL, | 137 | CHIP_HAS_HIERZ = 0x00100000UL, |
138 | CHIP_IS_PCIE = 0x00200000UL, | ||
137 | }; | 139 | }; |
138 | 140 | ||
139 | typedef struct drm_radeon_freelist { | 141 | typedef struct drm_radeon_freelist { |
@@ -213,8 +215,6 @@ typedef struct drm_radeon_private { | |||
213 | int microcode_version; | 215 | int microcode_version; |
214 | 216 | ||
215 | int is_pci; | 217 | int is_pci; |
216 | unsigned long phys_pci_gart; | ||
217 | dma_addr_t bus_pci_gart; | ||
218 | 218 | ||
219 | struct { | 219 | struct { |
220 | u32 boxes; | 220 | u32 boxes; |
@@ -270,6 +270,9 @@ typedef struct drm_radeon_private { | |||
270 | struct radeon_surface surfaces[RADEON_MAX_SURFACES]; | 270 | struct radeon_surface surfaces[RADEON_MAX_SURFACES]; |
271 | struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; | 271 | struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; |
272 | 272 | ||
273 | unsigned long pcigart_offset; | ||
274 | drm_ati_pcigart_info gart_info; | ||
275 | |||
273 | /* starting from here on, data is preserved accross an open */ | 276 | /* starting from here on, data is preserved accross an open */ |
274 | uint32_t flags; /* see radeon_chip_flags */ | 277 | uint32_t flags; /* see radeon_chip_flags */ |
275 | } drm_radeon_private_t; | 278 | } drm_radeon_private_t; |
@@ -373,6 +376,25 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, | |||
373 | #define RADEON_CRTC2_OFFSET 0x0324 | 376 | #define RADEON_CRTC2_OFFSET 0x0324 |
374 | #define RADEON_CRTC2_OFFSET_CNTL 0x0328 | 377 | #define RADEON_CRTC2_OFFSET_CNTL 0x0328 |
375 | 378 | ||
379 | #define RADEON_PCIE_INDEX 0x0030 | ||
380 | #define RADEON_PCIE_DATA 0x0034 | ||
381 | #define RADEON_PCIE_TX_GART_CNTL 0x10 | ||
382 | # define RADEON_PCIE_TX_GART_EN (1 << 0) | ||
383 | # define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1) | ||
384 | # define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1<<1) | ||
385 | # define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3<<1) | ||
386 | # define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0<<3) | ||
387 | # define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1<<3) | ||
388 | # define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1<<5) | ||
389 | # define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1<<8) | ||
390 | #define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11 | ||
391 | #define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12 | ||
392 | #define RADEON_PCIE_TX_GART_BASE 0x13 | ||
393 | #define RADEON_PCIE_TX_GART_START_LO 0x14 | ||
394 | #define RADEON_PCIE_TX_GART_START_HI 0x15 | ||
395 | #define RADEON_PCIE_TX_GART_END_LO 0x16 | ||
396 | #define RADEON_PCIE_TX_GART_END_HI 0x17 | ||
397 | |||
376 | #define RADEON_MPP_TB_CONFIG 0x01c0 | 398 | #define RADEON_MPP_TB_CONFIG 0x01c0 |
377 | #define RADEON_MEM_CNTL 0x0140 | 399 | #define RADEON_MEM_CNTL 0x0140 |
378 | #define RADEON_MEM_SDRAM_MODE_REG 0x0158 | 400 | #define RADEON_MEM_SDRAM_MODE_REG 0x0158 |
@@ -878,6 +900,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp, | |||
878 | 900 | ||
879 | #define RADEON_RING_HIGH_MARK 128 | 901 | #define RADEON_RING_HIGH_MARK 128 |
880 | 902 | ||
903 | #define RADEON_PCIGART_TABLE_SIZE (32*1024) | ||
904 | |||
881 | #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) | 905 | #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) |
882 | #define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) | 906 | #define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) |
883 | #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) | 907 | #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) |
@@ -890,6 +914,13 @@ do { \ | |||
890 | RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ | 914 | RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ |
891 | } while (0) | 915 | } while (0) |
892 | 916 | ||
917 | #define RADEON_WRITE_PCIE( addr, val ) \ | ||
918 | do { \ | ||
919 | RADEON_WRITE8( RADEON_PCIE_INDEX, \ | ||
920 | ((addr) & 0xff)); \ | ||
921 | RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \ | ||
922 | } while (0) | ||
923 | |||
893 | #define CP_PACKET0( reg, n ) \ | 924 | #define CP_PACKET0( reg, n ) \ |
894 | (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) | 925 | (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) |
895 | #define CP_PACKET0_TABLE( reg, n ) \ | 926 | #define CP_PACKET0_TABLE( reg, n ) \ |
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index c4325f1e2294..74c2fe8033c2 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -3034,6 +3034,9 @@ static int radeon_cp_setparam( DRM_IOCTL_ARGS ) { | |||
3034 | dev_priv->sarea_priv->tiling_enabled = 1; | 3034 | dev_priv->sarea_priv->tiling_enabled = 1; |
3035 | } | 3035 | } |
3036 | break; | 3036 | break; |
3037 | case RADEON_SETPARAM_PCIGART_LOCATION: | ||
3038 | dev_priv->pcigart_offset = sp.value; | ||
3039 | break; | ||
3037 | default: | 3040 | default: |
3038 | DRM_DEBUG( "Invalid parameter %d\n", sp.param ); | 3041 | DRM_DEBUG( "Invalid parameter %d\n", sp.param ); |
3039 | return DRM_ERR( EINVAL ); | 3042 | return DRM_ERR( EINVAL ); |