This source file includes following definitions.
- agp_i810_attach
- agp_i810_get_aperture
- agp_i810_set_aperture
- agp_i810_bind_page
- agp_i810_unbind_page
- agp_i810_flush_tlb
- agp_i810_enable
- agp_i810_alloc_memory
- agp_i810_free_memory
- agp_i810_bind_memory
- agp_i810_unbind_memory
- agp_i810_write_gatt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/proc.h>
40 #include <sys/device.h>
41 #include <sys/conf.h>
42 #include <sys/agpio.h>
43
44 #include <dev/pci/pcivar.h>
45 #include <dev/pci/pcireg.h>
46 #include <dev/pci/pcidevs.h>
47 #include <dev/pci/agpvar.h>
48 #include <dev/pci/agpreg.h>
49 #include <dev/pci/vga_pcivar.h>
50
51 #include <machine/bus.h>
52
53 #define READ1(off) bus_space_read_1(isc->bst, isc->bsh, off)
54 #define READ4(off) bus_space_read_4(isc->bst, isc->bsh, off)
55 #define WRITE4(off,v) bus_space_write_4(isc->bst, isc->bsh, off, v)
56 #define WRITEGTT(off,v) bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, off, v)
57
58 #define WRITE_GATT(off, v) agp_i810_write_gatt(isc, off, v)
59
60 enum {
61 CHIP_I810 = 0,
62 CHIP_I830 = 1,
63 CHIP_I855 = 2,
64 CHIP_I915 = 3,
65 CHIP_I965 = 4
66 };
67
68 struct agp_i810_softc {
69 struct agp_gatt *gatt;
70 int chiptype;
71 u_int32_t dcache_size;
72 u_int32_t stolen;
73
74 bus_space_tag_t bst;
75 bus_space_handle_t bsh;
76 bus_size_t bsz;
77 bus_space_tag_t gtt_bst;
78 bus_space_handle_t gtt_bsh;
79 struct pci_attach_args bridge_pa;
80 };
81
82 u_int32_t agp_i810_get_aperture(struct vga_pci_softc *);
83 int agp_i810_set_aperture(struct vga_pci_softc *, u_int32_t);
84 int agp_i810_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
85 int agp_i810_unbind_page(struct vga_pci_softc *, off_t);
86 void agp_i810_flush_tlb(struct vga_pci_softc *);
87 int agp_i810_enable(struct vga_pci_softc *, u_int32_t mode);
88 struct agp_memory *
89 agp_i810_alloc_memory(struct vga_pci_softc *, int, vsize_t);
90 int agp_i810_free_memory(struct vga_pci_softc *, struct agp_memory *);
91 int agp_i810_bind_memory(struct vga_pci_softc *, struct agp_memory *,
92 off_t);
93 int agp_i810_unbind_memory(struct vga_pci_softc *, struct agp_memory *);
94 void agp_i810_write_gatt(struct agp_i810_softc *, bus_size_t, u_int32_t);
95
96 struct agp_methods agp_i810_methods = {
97 agp_i810_get_aperture,
98 agp_i810_set_aperture,
99 agp_i810_bind_page,
100 agp_i810_unbind_page,
101 agp_i810_flush_tlb,
102 agp_i810_enable,
103 agp_i810_alloc_memory,
104 agp_i810_free_memory,
105 agp_i810_bind_memory,
106 agp_i810_unbind_memory,
107 };
108
109 int
110 agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
111 struct pci_attach_args *pchb_pa)
112 {
113 struct agp_i810_softc *isc;
114 struct agp_gatt *gatt;
115 bus_addr_t mmaddr, gmaddr;
116 int error;
117 u_int memtype = 0;
118
119 isc = malloc(sizeof *isc, M_DEVBUF, M_NOWAIT);
120 if (isc == NULL) {
121 printf(": can't allocate chipset-specific softc\n");
122 return (ENOMEM);
123 }
124 memset(isc, 0, sizeof *isc);
125 sc->sc_chipc = isc;
126 sc->sc_methods = &agp_i810_methods;
127 memcpy(&isc->bridge_pa, pchb_pa, sizeof *pchb_pa);
128
129 switch (PCI_PRODUCT(pa->pa_id)) {
130 case PCI_PRODUCT_INTEL_82810_GC:
131 case PCI_PRODUCT_INTEL_82810_DC100_GC:
132 case PCI_PRODUCT_INTEL_82810E_GC:
133 case PCI_PRODUCT_INTEL_82815_FULL_GRAPH:
134 isc->chiptype = CHIP_I810;
135 break;
136 case PCI_PRODUCT_INTEL_82830MP_IV:
137 case PCI_PRODUCT_INTEL_82845G_IGD:
138 isc->chiptype = CHIP_I830;
139 break;
140 case PCI_PRODUCT_INTEL_82852GM_AGP:
141 case PCI_PRODUCT_INTEL_82865_IGD:
142 isc->chiptype = CHIP_I855;
143 break;
144 case PCI_PRODUCT_INTEL_82915G_IV:
145 case PCI_PRODUCT_INTEL_82915GM_IGD:
146 case PCI_PRODUCT_INTEL_82945G_IGD_1:
147 case PCI_PRODUCT_INTEL_82945GM_IGD:
148 isc->chiptype = CHIP_I915;
149 break;
150 case PCI_PRODUCT_INTEL_82965_IGD_1:
151 case PCI_PRODUCT_INTEL_82965GM_IGD_1:
152 isc->chiptype = CHIP_I965;
153 break;
154 }
155
156 switch (isc->chiptype) {
157 case CHIP_I915:
158 gmaddr = AGP_I915_GMADR;
159 mmaddr = AGP_I915_MMADR;
160 break;
161 case CHIP_I965:
162 gmaddr = AGP_I965_GMADR;
163 mmaddr = AGP_I965_MMADR;
164 memtype = PCI_MAPREG_MEM_TYPE_64BIT;
165 break;
166 default:
167 gmaddr = AGP_APBASE;
168 mmaddr = AGP_I810_MMADR;
169 break;
170 }
171
172 error = agp_map_aperture(sc, gmaddr, memtype);
173 if (error != 0) {
174 printf(": can't map aperture\n");
175 free(isc, M_DEVBUF);
176 return (error);
177 }
178
179 error = pci_mapreg_map(pa, mmaddr, memtype, 0,
180 &isc->bst, &isc->bsh, NULL, &isc->bsz, 0);
181 if (error != 0) {
182 printf(": can't map mmadr registers\n");
183 return (error);
184 }
185
186 if (isc->chiptype == CHIP_I915) {
187 error = pci_mapreg_map(pa, AGP_I915_GTTADR, memtype,
188 0, &isc->gtt_bst, &isc->gtt_bsh, NULL, NULL, 0);
189 if (error != 0) {
190 printf(": can't map gatt registers\n");
191 agp_generic_detach(sc);
192 return (error);
193 }
194 }
195
196 gatt = malloc(sizeof(struct agp_gatt), M_DEVBUF, M_NOWAIT);
197 if (!gatt) {
198 agp_generic_detach(sc);
199 return (ENOMEM);
200 }
201 isc->gatt = gatt;
202
203 gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT;
204
205 if (isc->chiptype == CHIP_I810) {
206 int dummyseg;
207
208 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
209 isc->dcache_size = 4 * 1024 * 1024;
210 else
211 isc->dcache_size = 0;
212
213
214 if (agp_alloc_dmamem(sc->sc_dmat, 64 * 1024,
215 0, &gatt->ag_dmamap, (caddr_t *)&gatt->ag_virtual,
216 &gatt->ag_physical, &gatt->ag_dmaseg, 1, &dummyseg) != 0) {
217 free(gatt, M_DEVBUF);
218 agp_generic_detach(sc);
219 return (ENOMEM);
220 }
221
222 gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t);
223 memset(gatt->ag_virtual, 0, gatt->ag_size);
224
225 agp_flush_cache();
226
227 WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1);
228 } else if (isc->chiptype == CHIP_I830) {
229
230 pcireg_t reg;
231 u_int32_t pgtblctl;
232 u_int16_t gcc1;
233
234 reg = pci_conf_read(isc->bridge_pa.pa_pc,
235 isc->bridge_pa.pa_tag, AGP_I830_GCC1);
236 gcc1 = (u_int16_t)(reg >> 16);
237 switch (gcc1 & AGP_I830_GCC1_GMS) {
238 case AGP_I830_GCC1_GMS_STOLEN_512:
239 isc->stolen = (512 - 132) * 1024 / 4096;
240 break;
241 case AGP_I830_GCC1_GMS_STOLEN_1024:
242 isc->stolen = (1024 - 132) * 1024 / 4096;
243 break;
244 case AGP_I830_GCC1_GMS_STOLEN_8192:
245 isc->stolen = (8192 - 132) * 1024 / 4096;
246 break;
247 default:
248 isc->stolen = 0;
249 printf(
250 ": unknown memory configuration, disabling\n");
251 agp_generic_detach(sc);
252 return (EINVAL);
253 }
254 #ifdef DEBUG
255 if (isc->stolen > 0) {
256 printf(": detected %dk stolen memory",
257 isc->stolen * 4);
258 }
259 #endif
260
261
262 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
263 pgtblctl |= 1;
264 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
265
266 gatt->ag_physical = pgtblctl & ~1;
267 } else if (isc->chiptype == CHIP_I915) {
268
269 pcireg_t reg;
270 u_int32_t pgtblctl;
271 u_int16_t gcc1;
272
273 reg = pci_conf_read(isc->bridge_pa.pa_pc,
274 isc->bridge_pa.pa_tag, AGP_I855_GCC1);
275 gcc1 = (u_int16_t)(reg >> 16);
276 switch (gcc1 & AGP_I855_GCC1_GMS) {
277 case AGP_I855_GCC1_GMS_STOLEN_1M:
278 isc->stolen = (1024 - 260) * 1024 / 4096;
279 break;
280 case AGP_I855_GCC1_GMS_STOLEN_4M:
281 isc->stolen = (4096 - 260) * 1024 / 4096;
282 break;
283 case AGP_I855_GCC1_GMS_STOLEN_8M:
284 isc->stolen = (8192 - 260) * 1024 / 4096;
285 break;
286 case AGP_I855_GCC1_GMS_STOLEN_16M:
287 isc->stolen = (16384 - 260) * 1024 / 4096;
288 break;
289 case AGP_I855_GCC1_GMS_STOLEN_32M:
290 isc->stolen = (32768 - 260) * 1024 / 4096;
291 break;
292 case AGP_I915_GCC1_GMS_STOLEN_48M:
293 isc->stolen = (49152 - 260) * 1024 / 4096;
294 break;
295 case AGP_I915_GCC1_GMS_STOLEN_64M:
296 isc->stolen = (65536 - 260) * 1024 / 4096;
297 break;
298 default:
299 isc->stolen = 0;
300 printf(
301 ": unknown memory configuration, disabling\n");
302 agp_generic_detach(sc);
303 return (EINVAL);
304 }
305 #ifdef DEBUG
306 if (isc->stolen > 0) {
307 printf(": detected %dk stolen memory",
308 isc->stolen * 4);
309 }
310 #endif
311
312
313 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
314 pgtblctl |= 1;
315 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
316
317 gatt->ag_physical = pgtblctl & ~1;
318 } else if (isc->chiptype == CHIP_I965) {
319 pcireg_t reg;
320 u_int32_t pgtblctl;
321 u_int16_t gcc1;
322 u_int32_t gttsize;
323
324 switch (READ4(AGP_I810_PGTBL_CTL) &
325 AGP_I810_PGTBL_SIZE_MASK) {
326 case AGP_I810_PGTBL_SIZE_512KB:
327 gttsize = 512 + 4;
328 break;
329 case AGP_I810_PGTBL_SIZE_256KB:
330 gttsize = 256 + 4;
331 break;
332 case AGP_I810_PGTBL_SIZE_128KB:
333 default:
334 gttsize = 128 + 4;
335 break;
336 }
337
338 reg = pci_conf_read(isc->bridge_pa.pa_pc,
339 isc->bridge_pa.pa_tag, AGP_I855_GCC1);
340 gcc1 = (u_int16_t)(reg >> 16);
341 switch (gcc1 & AGP_I855_GCC1_GMS) {
342 case AGP_I855_GCC1_GMS_STOLEN_1M:
343 isc->stolen = (1024 - gttsize) * 1024 / 4096;
344 break;
345 case AGP_I855_GCC1_GMS_STOLEN_4M:
346 isc->stolen = (4096 - gttsize) * 1024 / 4096;
347 break;
348 case AGP_I855_GCC1_GMS_STOLEN_8M:
349 isc->stolen = (8192 - gttsize) * 1024 / 4096;
350 break;
351 case AGP_I855_GCC1_GMS_STOLEN_16M:
352 isc->stolen = (16384 - gttsize) * 1024 / 4096;
353 break;
354 case AGP_I855_GCC1_GMS_STOLEN_32M:
355 isc->stolen = (32768 - gttsize) * 1024 / 4096;
356 break;
357 case AGP_I915_GCC1_GMS_STOLEN_48M:
358 isc->stolen = (49152 - gttsize) * 1024 / 4096;
359 break;
360 case AGP_I915_GCC1_GMS_STOLEN_64M:
361 isc->stolen = (65536 - gttsize) * 1024 / 4096;
362 break;
363 case AGP_G33_GCC1_GMS_STOLEN_128M:
364 isc->stolen = (131072 - gttsize) * 1024 / 4096;
365 break;
366 case AGP_G33_GCC1_GMS_STOLEN_256M:
367 isc->stolen = (262144 - gttsize) * 1024 / 4096;
368 break;
369 default:
370 isc->stolen = 0;
371 printf(": unknown memory configuration 0x%x, "
372 "disabling\n", reg);
373 agp_generic_detach(sc);
374 return (EINVAL);
375 }
376 #ifdef DEBUG
377 if (isc->stolen > 0) {
378 printf(": detected %dk stolen memory",
379 isc->stolen * 4);
380 }
381 #endif
382
383
384 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
385 pgtblctl |= 1;
386 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
387
388 gatt->ag_physical = pgtblctl & ~1;
389 } else {
390
391 pcireg_t reg;
392 u_int32_t pgtblctl;
393 u_int16_t gcc1;
394
395 reg = pci_conf_read(isc->bridge_pa.pa_pc,
396 isc->bridge_pa.pa_tag, AGP_I855_GCC1);
397 gcc1 = (u_int16_t)(reg >> 16);
398 switch (gcc1 & AGP_I855_GCC1_GMS) {
399 case AGP_I855_GCC1_GMS_STOLEN_1M:
400 isc->stolen = (1024 - 132) * 1024 / 4096;
401 break;
402 case AGP_I855_GCC1_GMS_STOLEN_4M:
403 isc->stolen = (4096 - 132) * 1024 / 4096;
404 break;
405 case AGP_I855_GCC1_GMS_STOLEN_8M:
406 isc->stolen = (8192 - 132) * 1024 / 4096;
407 break;
408 case AGP_I855_GCC1_GMS_STOLEN_16M:
409 isc->stolen = (16384 - 132) * 1024 / 4096;
410 break;
411 case AGP_I855_GCC1_GMS_STOLEN_32M:
412 isc->stolen = (32768 - 132) * 1024 / 4096;
413 break;
414 default:
415 isc->stolen = 0;
416 printf(
417 ": unknown memory configuration, disabling\n");
418 agp_generic_detach(sc);
419 return (EINVAL);
420 }
421 #ifdef DEBUG
422 if (isc->stolen > 0) {
423 printf(": detected %dk stolen memory",
424 isc->stolen * 4);
425 }
426 #endif
427
428
429 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
430 pgtblctl |= 1;
431 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
432
433 gatt->ag_physical = pgtblctl & ~1;
434 }
435
436
437
438
439 agp_flush_cache();
440
441 return (0);
442 }
443
444 u_int32_t
445 agp_i810_get_aperture(struct vga_pci_softc *sc)
446 {
447 struct agp_i810_softc *isc = sc->sc_chipc;
448 pcireg_t reg;
449
450 if (isc->chiptype == CHIP_I810) {
451 u_int16_t miscc;
452
453 reg = pci_conf_read(isc->bridge_pa.pa_pc,
454 isc->bridge_pa.pa_tag, AGP_I810_SMRAM);
455 miscc = (u_int16_t)(reg >> 16);
456 if ((miscc & AGP_I810_MISCC_WINSIZE) ==
457 AGP_I810_MISCC_WINSIZE_32)
458 return (32 * 1024 * 1024);
459 else
460 return (64 * 1024 * 1024);
461 } else if (isc->chiptype == CHIP_I830) {
462 u_int16_t gcc1;
463
464 reg = pci_conf_read(isc->bridge_pa.pa_pc,
465 isc->bridge_pa.pa_tag, AGP_I830_GCC0);
466 gcc1 = (u_int16_t)(reg >> 16);
467 if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
468 return (64 * 1024 * 1024);
469 else
470 return (128 * 1024 * 1024);
471 } else if (isc->chiptype == CHIP_I915) {
472 reg = pci_conf_read(isc->bridge_pa.pa_pc,
473 isc->bridge_pa.pa_tag, AGP_I915_MSAC);
474 if ((reg & AGP_I915_MSAC_GMASIZE) == AGP_I915_MSAC_GMASIZE_128) {
475 return (128 * 1024 * 1024);
476 } else {
477 return (256 * 1024 * 1024);
478 }
479 } else if (isc->chiptype == CHIP_I965) {
480 reg = pci_conf_read(isc->bridge_pa.pa_pc,
481 isc->bridge_pa.pa_tag, AGP_I965_MSAC);
482 switch (reg & AGP_I965_MSAC_GMASIZE) {
483 case AGP_I965_MSAC_GMASIZE_128:
484 return (128 * 1024 * 1024);
485 case AGP_I965_MSAC_GMASIZE_256:
486 return (256 * 1024 * 1024);
487 case AGP_I965_MSAC_GMASIZE_512:
488 return (512 * 1024 * 1024);
489 }
490 }
491
492
493 return (128 * 1024 * 1024);
494 }
495
496 int
497 agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
498 {
499 struct agp_i810_softc *isc = sc->sc_chipc;
500 pcireg_t reg;
501
502 if (isc->chiptype == CHIP_I810) {
503 u_int16_t miscc;
504
505
506
507
508 if (aperture != (32 * 1024 * 1024) &&
509 aperture != (64 * 1024 * 1024)) {
510 printf("agp: bad aperture size %d\n", aperture);
511 return (EINVAL);
512 }
513
514 reg = pci_conf_read(isc->bridge_pa.pa_pc,
515 isc->bridge_pa.pa_tag, AGP_I810_SMRAM);
516 miscc = (u_int16_t)(reg >> 16);
517 miscc &= ~AGP_I810_MISCC_WINSIZE;
518 if (aperture == 32 * 1024 * 1024)
519 miscc |= AGP_I810_MISCC_WINSIZE_32;
520 else
521 miscc |= AGP_I810_MISCC_WINSIZE_64;
522
523 reg &= 0x0000ffff;
524 reg |= ((pcireg_t)miscc) << 16;
525 pci_conf_write(isc->bridge_pa.pa_pc,
526 isc->bridge_pa.pa_tag, AGP_I810_SMRAM, reg);
527 } else if (isc->chiptype == CHIP_I830) {
528 u_int16_t gcc1;
529
530 if (aperture != (64 * 1024 * 1024) &&
531 aperture != (128 * 1024 * 1024)) {
532 printf("agp: bad aperture size %d\n", aperture);
533 return (EINVAL);
534 }
535 reg = pci_conf_read(isc->bridge_pa.pa_pc,
536 isc->bridge_pa.pa_tag, AGP_I830_GCC0);
537 gcc1 = (u_int16_t)(reg >> 16);
538 gcc1 &= ~AGP_I830_GCC1_GMASIZE;
539 if (aperture == 64 * 1024 * 1024)
540 gcc1 |= AGP_I830_GCC1_GMASIZE_64;
541 else
542 gcc1 |= AGP_I830_GCC1_GMASIZE_128;
543
544 reg &= 0x0000ffff;
545 reg |= ((pcireg_t)gcc1) << 16;
546 pci_conf_write(isc->bridge_pa.pa_pc,
547 isc->bridge_pa.pa_tag, AGP_I830_GCC0, reg);
548 } else if (isc->chiptype == CHIP_I915) {
549 if (aperture != (128 * 1024 * 1024) &&
550 aperture != (256 * 1024 * 1024)) {
551 printf("agp: bad aperture size %d\n", aperture);
552 return (EINVAL);
553 }
554 reg = pci_conf_read(isc->bridge_pa.pa_pc,
555 isc->bridge_pa.pa_tag, AGP_I915_MSAC);
556 reg &= ~AGP_I915_MSAC_GMASIZE;
557 if (aperture == (128 * 1024 * 1024))
558 reg |= AGP_I915_MSAC_GMASIZE_128;
559 else
560 reg |= AGP_I915_MSAC_GMASIZE_256;
561 pci_conf_write(isc->bridge_pa.pa_pc,
562 isc->bridge_pa.pa_tag, AGP_I915_MSAC, reg);
563 } else if (isc->chiptype == CHIP_I965) {
564 reg = pci_conf_read(isc->bridge_pa.pa_pc,
565 isc->bridge_pa.pa_tag, AGP_I965_MSAC);
566 reg &= ~AGP_I965_MSAC_GMASIZE;
567 switch (aperture) {
568 case (128 * 1024 * 1024):
569 reg |= AGP_I965_MSAC_GMASIZE_128;
570 break;
571 case (256 * 1024 * 1024):
572 reg |= AGP_I965_MSAC_GMASIZE_256;
573 break;
574 case (512 * 1024 * 1024):
575 reg |= AGP_I965_MSAC_GMASIZE_512;
576 break;
577 default:
578 printf("agp: bad aperture size %d\n", aperture);
579 return (EINVAL);
580 }
581 pci_conf_write(isc->bridge_pa.pa_pc,
582 isc->bridge_pa.pa_tag, AGP_I965_MSAC, reg);
583 } else {
584 if (aperture != (128 * 1024 * 1024)) {
585 printf("agp: bad aperture size %d\n", aperture);
586 return (EINVAL);
587 }
588 }
589
590 return (0);
591 }
592
593 int
594 agp_i810_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
595 {
596 struct agp_i810_softc *isc = sc->sc_chipc;
597
598 if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
599 #ifdef DEBUG
600 printf("agp: failed: offset 0x%08x, shift %d, entries %d\n",
601 (int)offset, AGP_PAGE_SHIFT,
602 isc->gatt->ag_entries);
603 #endif
604 return (EINVAL);
605 }
606
607 if (isc->chiptype != CHIP_I810) {
608 if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) {
609 #ifdef DEBUG
610 printf("agp: trying to bind into stolen memory\n");
611 #endif
612 return (EINVAL);
613 }
614 }
615
616 WRITE_GATT(offset, physical);
617 return (0);
618 }
619
620 int
621 agp_i810_unbind_page(struct vga_pci_softc *sc, off_t offset)
622 {
623 struct agp_i810_softc *isc = sc->sc_chipc;
624
625 if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT))
626 return (EINVAL);
627
628 if (isc->chiptype != CHIP_I810 ) {
629 if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) {
630 #ifdef DEBUG
631 printf("agp: trying to unbind from stolen memory\n");
632 #endif
633 return (EINVAL);
634 }
635 }
636
637 WRITE_GATT(offset, 0);
638 return (0);
639 }
640
641
642
643
644 void
645 agp_i810_flush_tlb(struct vga_pci_softc *sc)
646 {
647 }
648
649 int
650 agp_i810_enable(struct vga_pci_softc *sc, u_int32_t mode)
651 {
652 return (0);
653 }
654
655 struct agp_memory *
656 agp_i810_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
657 {
658 struct agp_i810_softc *isc = sc->sc_chipc;
659 struct agp_memory *mem;
660 int error;
661
662 if ((size & (AGP_PAGE_SIZE - 1)) != 0)
663 return 0;
664
665 if (type == 1) {
666
667
668
669 if (isc->chiptype != CHIP_I810 )
670 return (NULL);
671 if (size != isc->dcache_size)
672 return (NULL);
673 } else if (type == 2) {
674
675
676
677 if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE) {
678 printf("agp: trying to map %lu for hw cursor\n", size);
679 return (NULL);
680 }
681 }
682
683 mem = malloc(sizeof *mem, M_DEVBUF, M_WAITOK);
684 bzero(mem, sizeof *mem);
685 mem->am_id = sc->sc_nextid++;
686 mem->am_size = size;
687 mem->am_type = type;
688
689 if (type == 2) {
690
691
692
693
694 mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_DEVBUF,
695 M_WAITOK);
696 if (mem->am_dmaseg == NULL) {
697 free(mem, M_DEVBUF);
698 return (NULL);
699 }
700 if ((error = agp_alloc_dmamem(sc->sc_dmat, size, 0,
701 &mem->am_dmamap, &mem->am_virtual, &mem->am_physical,
702 mem->am_dmaseg, 1, &mem->am_nseg)) != 0) {
703 free(mem->am_dmaseg, M_DEVBUF);
704 free(mem, M_DEVBUF);
705 printf("agp: agp_alloc_dmamem(%d)\n", error);
706 return (NULL);
707 }
708 } else if (type != 1) {
709 if ((error = bus_dmamap_create(sc->sc_dmat, size,
710 size / PAGE_SIZE + 1, size, 0, BUS_DMA_NOWAIT,
711 &mem->am_dmamap)) != 0) {
712 free(mem, M_DEVBUF);
713 printf("agp: bus_dmamap_create(%d)\n", error);
714 return (NULL);
715 }
716 }
717
718 TAILQ_INSERT_TAIL(&sc->sc_memory, mem, am_link);
719 sc->sc_allocated += size;
720
721 return (mem);
722 }
723
724 int
725 agp_i810_free_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
726 {
727 if (mem->am_is_bound)
728 return (EBUSY);
729
730 if (mem->am_type == 2) {
731 agp_free_dmamem(sc->sc_dmat, mem->am_size, mem->am_dmamap,
732 mem->am_virtual, mem->am_dmaseg, mem->am_nseg);
733 free(mem->am_dmaseg, M_DEVBUF);
734 }
735
736 sc->sc_allocated -= mem->am_size;
737 TAILQ_REMOVE(&sc->sc_memory, mem, am_link);
738 free(mem, M_DEVBUF);
739 return (0);
740 }
741
742 int
743 agp_i810_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
744 off_t offset)
745 {
746 struct agp_i810_softc *isc = sc->sc_chipc;
747 u_int32_t regval, i;
748
749
750
751
752
753
754
755 regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL);
756 if (regval != (isc->gatt->ag_physical | 1)) {
757 #if DEBUG
758 printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n",
759 regval);
760 #endif
761 bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL,
762 isc->gatt->ag_physical | 1);
763 }
764
765 if (mem->am_type == 2) {
766 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
767 WRITE_GATT(offset + i, mem->am_physical + i);
768 }
769 mem->am_offset = offset;
770 mem->am_is_bound = 1;
771 return (0);
772 }
773
774 if (mem->am_type != 1)
775 return (agp_generic_bind_memory(sc, mem, offset));
776
777 if (isc->chiptype != CHIP_I810)
778 return (EINVAL);
779
780 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
781 WRITE4(AGP_I810_GTT +
782 (u_int32_t)(offset >> AGP_PAGE_SHIFT) * 4, i | 3);
783 }
784 mem->am_is_bound = 1;
785 return (0);
786 }
787
788 int
789 agp_i810_unbind_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
790 {
791 struct agp_i810_softc *isc = sc->sc_chipc;
792 u_int32_t i;
793
794 if (mem->am_type == 2) {
795 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
796 WRITE_GATT(mem->am_offset + i, 0);
797 }
798 mem->am_offset = 0;
799 mem->am_is_bound = 0;
800 return (0);
801 }
802
803 if (mem->am_type != 1)
804 return (agp_generic_unbind_memory(sc, mem));
805
806 if (isc->chiptype != CHIP_I810)
807 return (EINVAL);
808
809 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
810 WRITE4(AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0);
811 mem->am_is_bound = 0;
812 return (0);
813 }
814
815 void
816 agp_i810_write_gatt(struct agp_i810_softc *isc, bus_size_t off, u_int32_t v)
817 {
818 u_int32_t d;
819
820
821 d = v | 1;
822
823 if (isc->chiptype == CHIP_I915)
824 WRITEGTT((u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
825 else if (isc->chiptype == CHIP_I965) {
826 d |= (v & 0x0000000f00000000ULL) >> 28;
827 WRITE4(AGP_I965_GTT +
828 (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
829 } else
830 WRITE4(AGP_I810_GTT +
831 (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
832 }