File:
[DragonFly] /
src /
sys /
dev /
agp /
agp_sis.c
Revision
1.3:
download - view:
text,
annotated -
select for diffs
Thu Aug 7 21:16:48 2003 UTC (9 years, 9 months ago) by
dillon
Branches:
MAIN
CVS tags:
HEAD
kernel tree reorganization stage 1: Major cvs repository work (not logged as
commits) plus a major reworking of the #include's to accomodate the
relocations.
* CVS repository files manually moved. Old directories left intact
and empty (temporary).
* Reorganize all filesystems into vfs/, most devices into dev/,
sub-divide devices by function.
* Begin to move device-specific architecture files to the device
subdirs rather then throwing them all into, e.g. i386/include
* Reorganize files related to system busses, placing the related code
in a new bus/ directory. Also move cam to bus/cam though this may
not have been the best idea in retrospect.
* Reorganize emulation code and place it in a new emulation/ directory.
* Remove the -I- compiler option in order to allow #include file
localization, rename all config generated X.h files to use_X.h to
clean up the conflicts.
* Remove /usr/src/include (or /usr/include) dependancies during the
kernel build, beyond what is normally needed to compile helper
programs.
* Make config create 'machine' softlinks for architecture specific
directories outside of the standard <arch>/include.
* Bump the config rev.
WARNING! after this commit /usr/include and /usr/src/sys/compile/*
should be regenerated from scratch.
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.3 2003/08/07 21:16:48 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: };
69:
70: if (pci_get_vendor(dev) == 0x1039)
71: return ("SIS Generic host to PCI bridge");
72:
73: return NULL;
74: }
75:
76: static int
77: agp_sis_probe(device_t dev)
78: {
79: const char *desc;
80:
81: desc = agp_sis_match(dev);
82: if (desc) {
83: device_verbose(dev);
84: device_set_desc(dev, desc);
85: return 0;
86: }
87:
88: return ENXIO;
89: }
90:
91: static int
92: agp_sis_attach(device_t dev)
93: {
94: struct agp_sis_softc *sc = device_get_softc(dev);
95: struct agp_gatt *gatt;
96: int error;
97:
98: error = agp_generic_attach(dev);
99: if (error)
100: return error;
101:
102: sc->initial_aperture = AGP_GET_APERTURE(dev);
103:
104: for (;;) {
105: gatt = agp_alloc_gatt(dev);
106: if (gatt)
107: break;
108:
109: /*
110: * Probably contigmalloc failure. Try reducing the
111: * aperture so that the gatt size reduces.
112: */
113: if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
114: agp_generic_detach(dev);
115: return ENOMEM;
116: }
117: }
118: sc->gatt = gatt;
119:
120: /* Install the gatt. */
121: pci_write_config(dev, AGP_SIS_ATTBASE, gatt->ag_physical, 4);
122:
123: /* Enable the aperture. */
124: pci_write_config(dev, AGP_SIS_WINCTRL,
125: pci_read_config(dev, AGP_SIS_WINCTRL, 1) | 3, 1);
126:
127: /*
128: * Enable the TLB and make it automatically invalidate entries
129: * when the GATT is written.
130: */
131: pci_write_config(dev, AGP_SIS_TLBCTRL, 0x05, 1);
132:
133: return 0;
134: }
135:
136: static int
137: agp_sis_detach(device_t dev)
138: {
139: struct agp_sis_softc *sc = device_get_softc(dev);
140: int error;
141:
142: error = agp_generic_detach(dev);
143: if (error)
144: return error;
145:
146: /* Disable the aperture.. */
147: pci_write_config(dev, AGP_SIS_WINCTRL,
148: pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~3, 1);
149:
150: /* and the TLB. */
151: pci_write_config(dev, AGP_SIS_TLBCTRL, 0, 1);
152:
153: /* Put the aperture back the way it started. */
154: AGP_SET_APERTURE(dev, sc->initial_aperture);
155:
156: agp_free_gatt(sc->gatt);
157: return 0;
158: }
159:
160: static u_int32_t
161: agp_sis_get_aperture(device_t dev)
162: {
163: int gws;
164:
165: /*
166: * The aperture size is equal to 4M<<gws.
167: */
168: gws = (pci_read_config(dev, AGP_SIS_WINCTRL, 1) & 0x70) >> 4;
169: return (4*1024*1024) << gws;
170: }
171:
172: static int
173: agp_sis_set_aperture(device_t dev, u_int32_t aperture)
174: {
175: int gws;
176:
177: /*
178: * Check for a power of two and make sure its within the
179: * programmable range.
180: */
181: if (aperture & (aperture - 1)
182: || aperture < 4*1024*1024
183: || aperture > 256*1024*1024)
184: return EINVAL;
185:
186: gws = ffs(aperture / 4*1024*1024) - 1;
187:
188: pci_write_config(dev, AGP_SIS_WINCTRL,
189: ((pci_read_config(dev, AGP_SIS_WINCTRL, 1) & ~0x70)
190: | gws << 4), 1);
191:
192: return 0;
193: }
194:
195: static int
196: agp_sis_bind_page(device_t dev, int offset, vm_offset_t physical)
197: {
198: struct agp_sis_softc *sc = device_get_softc(dev);
199:
200: if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
201: return EINVAL;
202:
203: sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
204: return 0;
205: }
206:
207: static int
208: agp_sis_unbind_page(device_t dev, int offset)
209: {
210: struct agp_sis_softc *sc = device_get_softc(dev);
211:
212: if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
213: return EINVAL;
214:
215: sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
216: return 0;
217: }
218:
219: static void
220: agp_sis_flush_tlb(device_t dev)
221: {
222: pci_write_config(dev, AGP_SIS_TLBFLUSH, 0x02, 1);
223: }
224:
225: static device_method_t agp_sis_methods[] = {
226: /* Device interface */
227: DEVMETHOD(device_probe, agp_sis_probe),
228: DEVMETHOD(device_attach, agp_sis_attach),
229: DEVMETHOD(device_detach, agp_sis_detach),
230: DEVMETHOD(device_shutdown, bus_generic_shutdown),
231: DEVMETHOD(device_suspend, bus_generic_suspend),
232: DEVMETHOD(device_resume, bus_generic_resume),
233:
234: /* AGP interface */
235: DEVMETHOD(agp_get_aperture, agp_sis_get_aperture),
236: DEVMETHOD(agp_set_aperture, agp_sis_set_aperture),
237: DEVMETHOD(agp_bind_page, agp_sis_bind_page),
238: DEVMETHOD(agp_unbind_page, agp_sis_unbind_page),
239: DEVMETHOD(agp_flush_tlb, agp_sis_flush_tlb),
240: DEVMETHOD(agp_enable, agp_generic_enable),
241: DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
242: DEVMETHOD(agp_free_memory, agp_generic_free_memory),
243: DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
244: DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
245:
246: { 0, 0 }
247: };
248:
249: static driver_t agp_sis_driver = {
250: "agp",
251: agp_sis_methods,
252: sizeof(struct agp_sis_softc),
253: };
254:
255: static devclass_t agp_devclass;
256:
257: DRIVER_MODULE(agp_sis, pci, agp_sis_driver, agp_devclass, 0, 0);