File:
[DragonFly] /
src /
sys /
dev /
agp /
agp_sis.c
Revision
1.4:
download - view:
text,
annotated -
select for diffs
Tue Dec 9 19:40:56 2003 UTC (9 years, 5 months ago) by
dillon
Branches:
MAIN
CVS tags:
HEAD,
DragonFly_1_0_RC1
This patch adds a bunch of stuff from FreeBSD5. It consistantly makes
vendor specific drivers depend on agp, consistantly checks the gart size
!= 0, changes agp_generic_enable to the FreeBSD5 function, initializing
the device as v2 or v3 accordingly, syncs up agpio.h, and adds a couple
PCI Ids from FreeBSD5.
Submitted-by: Craig Dooley <cd5697@albany.edu>
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: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
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: src/sys/pci/agp_sis.c,v 1.1.2.1 2000/07/19 09:48:04 ru Exp $
27: * $DragonFly: src/sys/dev/agp/agp_sis.c,v 1.4 2003/12/09 19:40:56 dillon Exp $
28: */
29:
30: #include "opt_bus.h"
31: #include "opt_pci.h"
32:
33: #include <sys/param.h>
34: #include <sys/systm.h>
35: #include <sys/malloc.h>
36: #include <sys/kernel.h>
37: #include <sys/bus.h>
38: #include <sys/lock.h>
39:
40: #include <bus/pci/pcivar.h>
41: #include <bus/pci/pcireg.h>
42: #include "agppriv.h"
43: #include "agpreg.h"
44:
45: #include <vm/vm.h>
46: #include <vm/vm_object.h>
47: #include <vm/pmap.h>
48:
49: struct agp_sis_softc {
50: struct agp_softc agp;
51: u_int32_t initial_aperture; /* aperture size at startup */
52: struct agp_gatt *gatt;
53: };
54:
55: static const char*
56: agp_sis_match(device_t dev)
57: {
58: if (pci_get_class(dev) != PCIC_BRIDGE
59: || pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
60: return NULL;
61:
62: if (agp_find_caps(dev) == 0)
63: return NULL;
64:
65: switch (pci_get_devid(dev)) {
66: case 0x00011039:
67: return ("SiS 5591 host to AGP bridge");
68: case 0x06481039:
69: return ("SiS 648 host to AGP bridge");
70: };
71:
72: if (pci_get_vendor(dev) == 0x1039)
73: return ("SIS Generic host to PCI bridge");
74:
75: return NULL;
76: }
77:
78: static int
79: agp_sis_probe(device_t dev)
80: {
81: const char *desc;
82:
83: desc = agp_sis_match(dev);
84: if (desc) {
85: device_verbose(dev);
86: device_set_desc(dev, desc);
87: return 0;
88: }
89:
90: return ENXIO;
91: }
92:
93: static int
94: agp_sis_attach(device_t dev)
95: {
96: struct agp_sis_softc *sc = device_get_softc(dev);
97: struct agp_gatt *gatt;
98: int error;
99:
100: error = agp_generic_attach(dev);
101: if (error)
102: return error;
103:
104: sc->initial_aperture = AGP_GET_APERTURE(dev);
105: if (sc->initial_aperture == 0) {
106: device_printf(dev, "bad initial aperture size, disabling\n");
107: return ENXIO;
108: }
109:
110: for (;;) {
111: gatt = agp_alloc_gatt(dev);
112: if (gatt)
113: break;
114:
115: /*
116: * Probably contigmalloc failure. Try reducing the
117: * aperture so that the gatt size reduces.
118: */
119: if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
120: agp_generic_detach(dev);
121: return ENOMEM;
122: }
123: }
124: sc->gatt = gatt;
125:
126: /* Install the gatt. */
127: pci_write_config(dev, AGP_SIS_ATTBASE, gatt->ag_physical, 4);
128:
129: /* Enable the aperture. */
130: pci_write_config(dev, AGP_SIS_WINCTRL,
131: pci_read_config(dev, AGP_SIS_WINCTRL, 1) | 3, 1);
132:
133: /*
134: * Enable the TLB and make it automatically invalidate entries
135: * when the GATT is written.
136: */
137: pci_write_config(dev, AGP_SIS_TLBCTRL, 0x05, 1);
138:
139: return 0;
140: }
141:
142: static int
143: agp_sis_detach(device_t dev)
144: {
145: struct agp_sis_softc *sc = device_get_softc(dev);
146: int error;
147:
148: error = agp_generic_detach(dev);
149: if (error)
150: return error;
151:
152: /* Disable the aperture.. */
153: pci_write_config(dev, AGP_SIS_WINCTRL,
154: pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~3, 1);
155:
156: /* and the TLB. */
157: pci_write_config(dev, AGP_SIS_TLBCTRL, 0, 1);
158:
159: /* Put the aperture back the way it started. */
160: AGP_SET_APERTURE(dev, sc->initial_aperture);
161:
162: agp_free_gatt(sc->gatt);
163: return 0;
164: }
165:
166: static u_int32_t
167: agp_sis_get_aperture(device_t dev)
168: {
169: int gws;
170:
171: /*
172: * The aperture size is equal to 4M<<gws.
173: */
174: gws = (pci_read_config(dev, AGP_SIS_WINCTRL, 1) & 0x70) >> 4;
175: return (4*1024*1024) << gws;
176: }
177:
178: static int
179: agp_sis_set_aperture(device_t dev, u_int32_t aperture)
180: {
181: int gws;
182:
183: /*
184: * Check for a power of two and make sure its within the
185: * programmable range.
186: */
187: if (aperture & (aperture - 1)
188: || aperture < 4*1024*1024
189: || aperture > 256*1024*1024)
190: return EINVAL;
191:
192: gws = ffs(aperture / 4*1024*1024) - 1;
193:
194: pci_write_config(dev, AGP_SIS_WINCTRL,
195: ((pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~0x70)
196: | gws << 4), 1);
197:
198: return 0;
199: }
200:
201: static int
202: agp_sis_bind_page(device_t dev, int offset, vm_offset_t physical)
203: {
204: struct agp_sis_softc *sc = device_get_softc(dev);
205:
206: if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
207: return EINVAL;
208:
209: sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
210: return 0;
211: }
212:
213: static int
214: agp_sis_unbind_page(device_t dev, int offset)
215: {
216: struct agp_sis_softc *sc = device_get_softc(dev);
217:
218: if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
219: return EINVAL;
220:
221: sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
222: return 0;
223: }
224:
225: static void
226: agp_sis_flush_tlb(device_t dev)
227: {
228: pci_write_config(dev, AGP_SIS_TLBFLUSH, 0x02, 1);
229: }
230:
231: static device_method_t agp_sis_methods[] = {
232: /* Device interface */
233: DEVMETHOD(device_probe, agp_sis_probe),
234: DEVMETHOD(device_attach, agp_sis_attach),
235: DEVMETHOD(device_detach, agp_sis_detach),
236: DEVMETHOD(device_shutdown, bus_generic_shutdown),
237: DEVMETHOD(device_suspend, bus_generic_suspend),
238: DEVMETHOD(device_resume, bus_generic_resume),
239:
240: /* AGP interface */
241: DEVMETHOD(agp_get_aperture, agp_sis_get_aperture),
242: DEVMETHOD(agp_set_aperture, agp_sis_set_aperture),
243: DEVMETHOD(agp_bind_page, agp_sis_bind_page),
244: DEVMETHOD(agp_unbind_page, agp_sis_unbind_page),
245: DEVMETHOD(agp_flush_tlb, agp_sis_flush_tlb),
246: DEVMETHOD(agp_enable, agp_generic_enable),
247: DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
248: DEVMETHOD(agp_free_memory, agp_generic_free_memory),
249: DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
250: DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
251:
252: { 0, 0 }
253: };
254:
255: static driver_t agp_sis_driver = {
256: "agp",
257: agp_sis_methods,
258: sizeof(struct agp_sis_softc),
259: };
260:
261: static devclass_t agp_devclass;
262:
263: DRIVER_MODULE(agp_sis, pci, agp_sis_driver, agp_devclass, 0, 0);
264: MODULE_DEPEND(agp_sis, agp, 1, 1, 1);
265: MODULE_DEPEND(agp_sis, pci, 1, 1, 1);