agp_amd.c (83699) | agp_amd.c (87479) |
---|---|
1/*- 2 * Copyright (c) 2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/dev/agp/agp_amd.c 83699 2001-09-20 05:13:12Z cokane $ | 26 * $FreeBSD: head/sys/dev/agp/agp_amd.c 87479 2001-12-07 05:41:26Z cokane $ |
27 */ 28 29#include "opt_bus.h" 30#include "opt_pci.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/malloc.h> --- 19 unchanged lines hidden (view full) --- 54 55#define READ2(off) bus_space_read_2(sc->bst, sc->bsh, off) 56#define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off) 57#define WRITE2(off,v) bus_space_write_2(sc->bst, sc->bsh, off, v) 58#define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) 59 60struct agp_amd_gatt { 61 u_int32_t ag_entries; | 27 */ 28 29#include "opt_bus.h" 30#include "opt_pci.h" 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/malloc.h> --- 19 unchanged lines hidden (view full) --- 54 55#define READ2(off) bus_space_read_2(sc->bst, sc->bsh, off) 56#define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off) 57#define WRITE2(off,v) bus_space_write_2(sc->bst, sc->bsh, off, v) 58#define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v) 59 60struct agp_amd_gatt { 61 u_int32_t ag_entries; |
62 u_int32_t *ag_virtual; /* virtual address of gatt */ 63 vm_offset_t ag_physical; |
|
62 u_int32_t *ag_vdir; /* virtual address of page dir */ 63 vm_offset_t ag_pdir; /* physical address of page dir */ | 64 u_int32_t *ag_vdir; /* virtual address of page dir */ 65 vm_offset_t ag_pdir; /* physical address of page dir */ |
64 u_int32_t *ag_virtual; /* virtual address of gatt */ | |
65}; 66 67struct agp_amd_softc { 68 struct agp_softc agp; 69 struct resource *regs; /* memory mapped control registers */ 70 bus_space_tag_t bst; /* bus_space tag */ 71 bus_space_handle_t bsh; /* bus_space handle */ 72 u_int32_t initial_aperture; /* aperture size at startup */ 73 struct agp_amd_gatt *gatt; 74}; 75 76static struct agp_amd_gatt * 77agp_amd_alloc_gatt(device_t dev) 78{ 79 u_int32_t apsize = AGP_GET_APERTURE(dev); 80 u_int32_t entries = apsize >> AGP_PAGE_SHIFT; 81 struct agp_amd_gatt *gatt; | 66}; 67 68struct agp_amd_softc { 69 struct agp_softc agp; 70 struct resource *regs; /* memory mapped control registers */ 71 bus_space_tag_t bst; /* bus_space tag */ 72 bus_space_handle_t bsh; /* bus_space handle */ 73 u_int32_t initial_aperture; /* aperture size at startup */ 74 struct agp_amd_gatt *gatt; 75}; 76 77static struct agp_amd_gatt * 78agp_amd_alloc_gatt(device_t dev) 79{ 80 u_int32_t apsize = AGP_GET_APERTURE(dev); 81 u_int32_t entries = apsize >> AGP_PAGE_SHIFT; 82 struct agp_amd_gatt *gatt; |
82 int i, npages; | 83 int i, npages, pdir_offset; |
83 84 if (bootverbose) 85 device_printf(dev, 86 "allocating GATT for aperture of size %dM\n", 87 apsize / (1024*1024)); 88 89 gatt = malloc(sizeof(struct agp_amd_gatt), M_AGP, M_NOWAIT); 90 if (!gatt) 91 return 0; 92 93 /* 94 * The AMD751 uses a page directory to map a non-contiguous 95 * gatt so we don't need to use contigmalloc. | 84 85 if (bootverbose) 86 device_printf(dev, 87 "allocating GATT for aperture of size %dM\n", 88 apsize / (1024*1024)); 89 90 gatt = malloc(sizeof(struct agp_amd_gatt), M_AGP, M_NOWAIT); 91 if (!gatt) 92 return 0; 93 94 /* 95 * The AMD751 uses a page directory to map a non-contiguous 96 * gatt so we don't need to use contigmalloc. |
97 * Malloc individual gatt pages and map them into the page 98 * directory. |
|
96 */ 97 gatt->ag_entries = entries; 98 gatt->ag_virtual = malloc(entries * sizeof(u_int32_t), 99 M_AGP, M_NOWAIT); 100 if (!gatt->ag_virtual) { 101 if (bootverbose) 102 device_printf(dev, "allocation failed\n"); 103 free(gatt, M_AGP); 104 return 0; 105 } 106 bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); 107 108 /* 109 * Allocate the page directory. 110 */ 111 gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT); | 99 */ 100 gatt->ag_entries = entries; 101 gatt->ag_virtual = malloc(entries * sizeof(u_int32_t), 102 M_AGP, M_NOWAIT); 103 if (!gatt->ag_virtual) { 104 if (bootverbose) 105 device_printf(dev, "allocation failed\n"); 106 free(gatt, M_AGP); 107 return 0; 108 } 109 bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); 110 111 /* 112 * Allocate the page directory. 113 */ 114 gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT); |
115 bzero(gatt->ag_vdir, AGP_PAGE_SIZE); 116 |
|
112 if (!gatt->ag_vdir) { 113 if (bootverbose) 114 device_printf(dev, 115 "failed to allocate page directory\n"); 116 free(gatt->ag_virtual, M_AGP); 117 free(gatt, M_AGP); 118 return 0; 119 } | 117 if (!gatt->ag_vdir) { 118 if (bootverbose) 119 device_printf(dev, 120 "failed to allocate page directory\n"); 121 free(gatt->ag_virtual, M_AGP); 122 free(gatt, M_AGP); 123 return 0; 124 } |
120 bzero(gatt->ag_vdir, AGP_PAGE_SIZE); | |
121 gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir); | 125 gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir); |
122 gatt->ag_pdir = vtophys(gatt->ag_virtual); | 126 if(bootverbose) 127 device_printf(dev, "gatt -> ag_pdir %8x\n", 128 (vm_offset_t)gatt->ag_pdir); 129 /* 130 * Allocate the gatt pages 131 */ 132 gatt->ag_entries = entries; 133 if(bootverbose) 134 device_printf(dev, "allocating GATT for %d AGP page entries\n", 135 gatt->ag_entries); 136 gatt->ag_virtual = malloc(entries * sizeof(u_int32_t), M_AGP, 137 M_NOWAIT); 138 if(!gatt->ag_virtual) { 139 if(bootverbose) 140 device_printf(dev, "allocation failed\n"); 141 free(gatt, M_AGP); 142 return 0; 143 } 144 gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); |
123 124 /* 125 * Map the pages of the GATT into the page directory. | 145 146 /* 147 * Map the pages of the GATT into the page directory. |
148 * 149 * The GATT page addresses are mapped into the directory offset by 150 * an amount dependent on the base address of the aperture. This 151 * is and offset into the page directory, not an offset added to 152 * the addresses of the gatt pages. |
|
126 */ | 153 */ |
154 155 pdir_offset = pci_read_config(dev, AGP_AMD751_APBASE, 4) >> 22; 156 |
|
127 npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1) 128 >> AGP_PAGE_SHIFT); | 157 npages = ((entries * sizeof(u_int32_t) + AGP_PAGE_SIZE - 1) 158 >> AGP_PAGE_SHIFT); |
159 |
|
129 for (i = 0; i < npages; i++) { 130 vm_offset_t va; 131 vm_offset_t pa; 132 133 va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE; 134 pa = vtophys(va); | 160 for (i = 0; i < npages; i++) { 161 vm_offset_t va; 162 vm_offset_t pa; 163 164 va = ((vm_offset_t) gatt->ag_virtual) + i * AGP_PAGE_SIZE; 165 pa = vtophys(va); |
135 gatt->ag_vdir[i] = pa | 1; | 166 gatt->ag_vdir[i + pdir_offset] = pa | 1; |
136 } 137 138 /* 139 * Make sure the chipset can see everything. 140 */ 141 agp_flush_cache(); 142 143 return gatt; --- 13 unchanged lines hidden (view full) --- 157 if (pci_get_class(dev) != PCIC_BRIDGE 158 || pci_get_subclass(dev) != PCIS_BRIDGE_HOST) 159 return NULL; 160 161 if (agp_find_caps(dev) == 0) 162 return NULL; 163 164 switch (pci_get_devid(dev)) { | 167 } 168 169 /* 170 * Make sure the chipset can see everything. 171 */ 172 agp_flush_cache(); 173 174 return gatt; --- 13 unchanged lines hidden (view full) --- 188 if (pci_get_class(dev) != PCIC_BRIDGE 189 || pci_get_subclass(dev) != PCIS_BRIDGE_HOST) 190 return NULL; 191 192 if (agp_find_caps(dev) == 0) 193 return NULL; 194 195 switch (pci_get_devid(dev)) { |
196 |
|
165 case 0x700e1022: 166 return ("AMD 761 host to AGP bridge"); | 197 case 0x700e1022: 198 return ("AMD 761 host to AGP bridge"); |
199 |
|
167 case 0x70061022: 168 return ("AMD 751 host to AGP bridge"); | 200 case 0x70061022: 201 return ("AMD 751 host to AGP bridge"); |
202 203 case 0x700c1022: 204 return ("AMD 762 host to AGP bridge"); 205 |
|
169 }; 170 171 return NULL; 172} 173 174static int 175agp_amd_probe(device_t dev) 176{ --- 122 unchanged lines hidden (view full) --- 299 */ 300 if (aperture & (aperture - 1) 301 || aperture < 32*1024*1024 302 || aperture > 2U*1024*1024*1024) 303 return EINVAL; 304 305 vas = ffs(aperture / 32*1024*1024) - 1; 306 | 206 }; 207 208 return NULL; 209} 210 211static int 212agp_amd_probe(device_t dev) 213{ --- 122 unchanged lines hidden (view full) --- 336 */ 337 if (aperture & (aperture - 1) 338 || aperture < 32*1024*1024 339 || aperture > 2U*1024*1024*1024) 340 return EINVAL; 341 342 vas = ffs(aperture / 32*1024*1024) - 1; 343 |
344 /* 345 * While the size register is bits 1-3 of APCTRL, bit 0 must be 346 * set for the size value to be 'valid' 347 */ |
|
307 pci_write_config(dev, AGP_AMD751_APCTRL, | 348 pci_write_config(dev, AGP_AMD751_APCTRL, |
308 ((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06) 309 | vas << 1), 1); | 349 (((pci_read_config(dev, AGP_AMD751_APCTRL, 1) & ~0x06) 350 | ((vas << 1) | 1))), 1); |
310 311 return 0; 312} 313 314static int 315agp_amd_bind_page(device_t dev, int offset, vm_offset_t physical) 316{ 317 struct agp_amd_softc *sc = device_get_softc(dev); 318 319 if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 320 return EINVAL; 321 322 sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1; | 351 352 return 0; 353} 354 355static int 356agp_amd_bind_page(device_t dev, int offset, vm_offset_t physical) 357{ 358 struct agp_amd_softc *sc = device_get_softc(dev); 359 360 if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 361 return EINVAL; 362 363 sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 1; |
364 365 /* invalidate the cache */ 366 AGP_FLUSH_TLB(dev); |
|
323 return 0; 324} 325 326static int 327agp_amd_unbind_page(device_t dev, int offset) 328{ 329 struct agp_amd_softc *sc = device_get_softc(dev); 330 --- 52 unchanged lines hidden --- | 367 return 0; 368} 369 370static int 371agp_amd_unbind_page(device_t dev, int offset) 372{ 373 struct agp_amd_softc *sc = device_get_softc(dev); 374 --- 52 unchanged lines hidden --- |