Annotation of sys/dev/pci/agp_ali.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: agp_ali.c,v 1.3 2007/08/04 19:40:25 reyk Exp $ */
2: /* $NetBSD: agp_ali.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
3:
4:
5: /*-
6: * Copyright (c) 2000 Doug Rabson
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28: * SUCH DAMAGE.
29: *
30: * $FreeBSD: src/sys/pci/agp_ali.c,v 1.3 2001/07/05 21:28:46 jhb Exp $
31: */
32:
33:
34:
35: #include <sys/param.h>
36: #include <sys/kernel.h>
37: #include <sys/malloc.h>
38: #include <sys/systm.h>
39: #include <sys/proc.h>
40: #include <sys/conf.h>
41: #include <sys/device.h>
42: #include <sys/lock.h>
43: #include <sys/agpio.h>
44:
45: #include <dev/pci/pcivar.h>
46: #include <dev/pci/pcireg.h>
47: #include <dev/pci/vga_pcivar.h>
48: #include <dev/pci/agpvar.h>
49: #include <dev/pci/agpreg.h>
50:
51: #include <machine/bus.h>
52:
53: struct agp_ali_softc {
54: u_int32_t initial_aperture; /* aperture size at startup */
55: struct agp_gatt *gatt;
56: };
57:
58: u_int32_t agp_ali_get_aperture(struct vga_pci_softc *);
59: int agp_ali_set_aperture(struct vga_pci_softc *sc, u_int32_t);
60: int agp_ali_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
61: int agp_ali_unbind_page(struct vga_pci_softc *, off_t);
62: void agp_ali_flush_tlb(struct vga_pci_softc *);
63:
64: struct agp_methods agp_ali_methods = {
65: agp_ali_get_aperture,
66: agp_ali_set_aperture,
67: agp_ali_bind_page,
68: agp_ali_unbind_page,
69: agp_ali_flush_tlb,
70: agp_generic_enable,
71: agp_generic_alloc_memory,
72: agp_generic_free_memory,
73: agp_generic_bind_memory,
74: agp_generic_unbind_memory,
75: };
76:
77: int
78: agp_ali_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
79: struct pci_attach_args *pchb_pa)
80: {
81: struct agp_ali_softc *asc;
82: struct agp_gatt *gatt;
83: pcireg_t reg;
84:
85: asc = malloc(sizeof *asc, M_DEVBUF, M_NOWAIT);
86: if (asc == NULL) {
87: printf(": failed to allocate softc\n");
88: return (ENOMEM);
89: }
90: sc->sc_chipc = asc;
91: sc->sc_methods = &agp_ali_methods;
92:
93: if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
94: printf(": failed to map aperture\n");
95: free(asc, M_DEVBUF);
96: return (ENXIO);
97: }
98:
99: asc->initial_aperture = agp_ali_get_aperture(sc);
100:
101: for (;;) {
102: gatt = agp_alloc_gatt(sc);
103: if (gatt != NULL)
104: break;
105:
106: /*
107: * Probably contigmalloc failure. Try reducing the
108: * aperture so that the gatt size reduces.
109: */
110: if (AGP_SET_APERTURE(sc, AGP_GET_APERTURE(sc) / 2)) {
111: agp_generic_detach(sc);
112: printf(": failed to set aperture\n");
113: return (ENOMEM);
114: }
115: }
116: asc->gatt = gatt;
117:
118: /* Install the gatt. */
119: reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_ALI_ATTBASE);
120: reg = (reg & 0xff) | gatt->ag_physical;
121: pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_ALI_ATTBASE, reg);
122:
123: /* Enable the TLB. */
124: reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_ALI_TLBCTRL);
125: reg = (reg & ~0xff) | 0x10;
126: pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_ALI_TLBCTRL, reg);
127:
128: return (0);
129: }
130:
131: #if 0
132: int
133: agp_ali_detach(struct vga_pci_softc *sc)
134: {
135: int error;
136: pcireg_t reg;
137: struct agp_ali_softc *asc = sc->sc_chipc;
138:
139: error = agp_generic_detach(sc);
140: if (error)
141: return (error);
142:
143: /* Disable the TLB.. */
144: reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_ALI_TLBCTRL);
145: reg &= ~0xff;
146: reg |= 0x90;
147: pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_ALI_TLBCTRL, reg);
148:
149: /* Put the aperture back the way it started. */
150: AGP_SET_APERTURE(sc, asc->initial_aperture);
151: reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_ALI_ATTBASE);
152: reg &= 0xff;
153: pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_ALI_ATTBASE, reg);
154:
155: agp_free_gatt(sc, asc->gatt);
156: return (0);
157: }
158: #endif
159:
160: #define M 1024*1024
161:
162: static const u_int32_t agp_ali_table[] = {
163: 0, /* 0 - invalid */
164: 1, /* 1 - invalid */
165: 2, /* 2 - invalid */
166: 4*M, /* 3 - invalid */
167: 8*M, /* 4 - invalid */
168: 0, /* 5 - invalid */
169: 16*M, /* 6 - invalid */
170: 32*M, /* 7 - invalid */
171: 64*M, /* 8 - invalid */
172: 128*M, /* 9 - invalid */
173: 256*M, /* 10 - invalid */
174: };
175: #define agp_ali_table_size (sizeof(agp_ali_table) / sizeof(agp_ali_table[0]))
176:
177: u_int32_t
178: agp_ali_get_aperture(struct vga_pci_softc *sc)
179: {
180: int i;
181:
182: /*
183: * The aperture size is derived from the low bits of attbase.
184: * I'm not sure this is correct..
185: */
186: i = (int)pci_conf_read(sc->sc_pc, sc->sc_pcitag,
187: AGP_ALI_ATTBASE) & 0xff;
188: if (i >= agp_ali_table_size)
189: return (0);
190: return (agp_ali_table[i]);
191: }
192:
193: int
194: agp_ali_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
195: {
196: int i;
197: pcireg_t reg;
198:
199: for (i = 0; i < agp_ali_table_size; i++)
200: if (agp_ali_table[i] == aperture)
201: break;
202: if (i == agp_ali_table_size)
203: return EINVAL;
204:
205: reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_ALI_ATTBASE);
206: reg &= ~0xff;
207: reg |= i;
208: pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_ALI_ATTBASE, reg);
209: return (0);
210: }
211:
212: int
213: agp_ali_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
214: {
215: struct agp_ali_softc *asc = sc->sc_chipc;
216:
217: if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
218: return (EINVAL);
219:
220: asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
221: return (0);
222: }
223:
224: int
225: agp_ali_unbind_page(struct vga_pci_softc *sc, off_t offset)
226: {
227: struct agp_ali_softc *asc = sc->sc_chipc;
228:
229: if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
230: return (EINVAL);
231:
232: asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
233: return (0);
234: }
235:
236: void
237: agp_ali_flush_tlb(struct vga_pci_softc *sc)
238: {
239: pcireg_t reg;
240:
241: reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_ALI_TLBCTRL);
242: reg &= ~0xff;
243: reg |= 0x90;
244: pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_ALI_TLBCTRL, reg);
245: reg &= ~0xff;
246: reg |= 0x10;
247: pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_ALI_TLBCTRL, reg);
248: }
249:
CVSweb