This source file includes following definitions.
- agp_sis_attach
- agp_sis_detach
- agp_sis_get_aperture
- agp_sis_set_aperture
- agp_sis_bind_page
- agp_sis_unbind_page
- agp_sis_flush_tlb
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 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/malloc.h>
36 #include <sys/kernel.h>
37 #include <sys/lock.h>
38 #include <sys/proc.h>
39 #include <sys/conf.h>
40 #include <sys/device.h>
41 #include <sys/agpio.h>
42
43 #include <dev/pci/pcivar.h>
44 #include <dev/pci/pcireg.h>
45 #include <dev/pci/vga_pcivar.h>
46 #include <dev/pci/agpvar.h>
47 #include <dev/pci/agpreg.h>
48
49 #include <machine/bus.h>
50
51 struct agp_sis_softc {
52 u_int32_t initial_aperture;
53 struct agp_gatt *gatt;
54 };
55
56 static u_int32_t agp_sis_get_aperture(struct vga_pci_softc *);
57 static int agp_sis_set_aperture(struct vga_pci_softc *, u_int32_t);
58 static int agp_sis_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
59 static int agp_sis_unbind_page(struct vga_pci_softc *, off_t);
60 static void agp_sis_flush_tlb(struct vga_pci_softc *);
61
62 struct agp_methods agp_sis_methods = {
63 agp_sis_get_aperture,
64 agp_sis_set_aperture,
65 agp_sis_bind_page,
66 agp_sis_unbind_page,
67 agp_sis_flush_tlb,
68 agp_generic_enable,
69 agp_generic_alloc_memory,
70 agp_generic_free_memory,
71 agp_generic_bind_memory,
72 agp_generic_unbind_memory,
73 };
74
75
76 int
77 agp_sis_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
78 struct pci_attach_args *pchb_pa)
79 {
80 struct agp_sis_softc *ssc;
81 struct agp_gatt *gatt;
82 pcireg_t reg;
83
84 ssc = malloc(sizeof *ssc, M_DEVBUF, M_NOWAIT);
85 if (ssc == NULL) {
86 printf(": can't allocate chipset-specific softc\n");
87 return (ENOMEM);
88 }
89 sc->sc_methods = &agp_sis_methods;
90 sc->sc_chipc = ssc;
91
92 if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
93 printf(": can't map aperture\n");
94 free(ssc, M_DEVBUF);
95 return (ENXIO);
96 }
97
98 ssc->initial_aperture = AGP_GET_APERTURE(sc);
99
100 for (;;) {
101 gatt = agp_alloc_gatt(sc);
102 if (gatt)
103 break;
104
105
106
107
108
109 if (AGP_SET_APERTURE(sc, AGP_GET_APERTURE(sc) / 2)) {
110 agp_generic_detach(sc);
111 printf(": failed to set aperture\n");
112 return (ENOMEM);
113 }
114 }
115 ssc->gatt = gatt;
116
117
118 pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_ATTBASE,
119 gatt->ag_physical);
120
121
122 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL);
123 reg |= (0x05 << 24) | 3;
124 pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL, reg);
125
126 return (0);
127 }
128
129 #if 0
130 static int
131 agp_sis_detach(struct vga_pci_softc *sc)
132 {
133 struct agp_sis_softc *ssc = sc->sc_chipc;
134 pcireg_t reg;
135 int error;
136
137 error = agp_generic_detach(sc);
138 if (error)
139 return (error);
140
141 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL);
142 reg &= ~3;
143 reg &= 0x00ffffff;
144 pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL, reg);
145
146
147 AGP_SET_APERTURE(sc, ssc->initial_aperture);
148
149 agp_free_gatt(sc, ssc->gatt);
150 return (0);
151 }
152 #endif
153
154 static u_int32_t
155 agp_sis_get_aperture(struct vga_pci_softc *sc)
156 {
157 int gws;
158
159
160
161
162 gws = (pci_conf_read(sc->sc_pc, sc->sc_pcitag,
163 AGP_SIS_WINCTRL)&0x70) >> 4;
164 return ((4 * 1024 * 1024) << gws);
165 }
166
167 static int
168 agp_sis_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
169 {
170 int gws;
171 pcireg_t reg;
172
173
174
175
176
177 if (aperture & (aperture - 1)
178 || aperture < 4*1024*1024
179 || aperture > 256*1024*1024)
180 return (EINVAL);
181
182 gws = ffs(aperture / 4*1024*1024) - 1;
183
184 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL);
185 reg &= ~0x00000070;
186 reg |= gws << 4;
187 pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_WINCTRL, reg);
188
189 return (0);
190 }
191
192 static int
193 agp_sis_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
194 {
195 struct agp_sis_softc *ssc = sc->sc_chipc;
196
197 if (offset < 0 || offset >= (ssc->gatt->ag_entries << AGP_PAGE_SHIFT))
198 return (EINVAL);
199
200 ssc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
201 return (0);
202 }
203
204 static int
205 agp_sis_unbind_page(struct vga_pci_softc *sc, off_t offset)
206 {
207 struct agp_sis_softc *ssc = sc->sc_chipc;
208
209 if (offset < 0 || offset >= (ssc->gatt->ag_entries << AGP_PAGE_SHIFT))
210 return (EINVAL);
211
212 ssc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
213 return (0);
214 }
215
216 static void
217 agp_sis_flush_tlb(struct vga_pci_softc *sc)
218 {
219 pcireg_t reg;
220
221 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_SIS_TLBFLUSH);
222 reg &= 0xffffff00;
223 reg |= 0x02;
224 pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_SIS_TLBFLUSH, reg);
225 }