0077fba489ddac8b2645f321a8bc0fac0f663ad0
[dragonfly.git] / sys / dev / agp / agp_intel.c
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_intel.c,v 1.1.2.5 2003/06/02 17:38:19 jhb Exp $
27  *      $DragonFly: src/sys/dev/agp/agp_intel.c,v 1.7 2006/12/22 23:26:14 swildner 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 #define MAX_APSIZE      0x3f            /* 256 MB */
50
51 struct agp_intel_softc {
52         struct agp_softc agp;
53         u_int32_t       initial_aperture; /* aperture size at startup */
54         struct agp_gatt *gatt;
55         u_int           aperture_mask;
56 };
57
58 static const char*
59 agp_intel_match(device_t dev)
60 {
61         if (pci_get_class(dev) != PCIC_BRIDGE
62             || pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
63                 return NULL;
64
65         if (agp_find_caps(dev) == 0)
66                 return NULL;
67
68         switch (pci_get_devid(dev)) {
69         /* Intel -- vendor 0x8086 */
70         case 0x71808086:
71                 return ("Intel 82443LX (440 LX) host to PCI bridge");
72
73         case 0x71908086:
74                 return ("Intel 82443BX (440 BX) host to PCI bridge");
75
76         case 0x71a08086:
77                 return ("Intel 82443GX host to PCI bridge");
78
79         case 0x71a18086:
80                 return ("Intel 82443GX host to AGP bridge");
81
82         case 0x11308086:
83                 return ("Intel 82815 (i815 GMCH) host to PCI bridge");
84
85         case 0x25008086:
86         case 0x25018086:
87                 return ("Intel 82820 host to AGP bridge");
88
89         case 0x35758086:
90                 return ("Intel 82830 host to AGP bridge");
91
92         case 0x1a218086:
93                 return ("Intel 82840 host to AGP bridge");
94
95         case 0x1a308086:
96                 return ("Intel 82845 host to AGP bridge");
97
98         case 0x25308086:
99                 return ("Intel 82850 host to AGP bridge");
100
101         case 0x33408086:
102                 return ("Intel 82855 host to AGP bridge");
103
104         case 0x25318086:
105                 return ("Intel 82860 host to AGP bridge");
106
107         case 0x25708086:
108                 return ("Intel 82865 host to AGP bridge");
109
110         case 0x25788086:
111                 return ("Intel 82875P host to AGP bridge");
112
113         case 0x25608086: /* i845G */
114                 return ("Intel 82845G host to AGP bridge");
115         };
116
117         if (pci_get_vendor(dev) == 0x8086)
118                 return ("Intel Generic host to PCI bridge");
119
120         return NULL;
121 }
122
123 static int
124 agp_intel_probe(device_t dev)
125 {
126         const char *desc;
127
128         desc = agp_intel_match(dev);
129         if (desc) {
130                 device_verbose(dev);
131                 device_set_desc(dev, desc);
132                 return 0;
133         }
134
135         return ENXIO;
136 }
137
138 static int
139 agp_intel_attach(device_t dev)
140 {
141         struct agp_intel_softc *sc = device_get_softc(dev);
142         struct agp_gatt *gatt;
143         u_int32_t type = pci_get_devid(dev);
144         u_int32_t value;
145         int error;
146
147         error = agp_generic_attach(dev);
148         if (error)
149                 return error;
150
151         /* Determine maximum supported aperture size. */
152         value = pci_read_config(dev, AGP_INTEL_APSIZE, 1);
153         pci_write_config(dev, AGP_INTEL_APSIZE, MAX_APSIZE, 1);
154         sc->aperture_mask = pci_read_config(dev, AGP_INTEL_APSIZE, 1) &
155             MAX_APSIZE;
156         pci_write_config(dev, AGP_INTEL_APSIZE, value, 1);
157         sc->initial_aperture = AGP_GET_APERTURE(dev);
158
159         for (;;) {
160                 gatt = agp_alloc_gatt(dev);
161                 if (gatt)
162                         break;
163
164                 /*
165                  * Probably contigmalloc failure. Try reducing the
166                  * aperture so that the gatt size reduces.
167                  */
168                 if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) {
169                         agp_generic_detach(dev);
170                         return ENOMEM;
171                 }
172         }
173         sc->gatt = gatt;
174
175         /* Install the gatt. */
176         pci_write_config(dev, AGP_INTEL_ATTBASE, gatt->ag_physical, 4);
177
178         /* Enable the GLTB and setup the control register. */
179         switch (type) {
180         case 0x71908086: /* 440LX/EX */
181                 pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2080, 4);
182                 break;
183         case 0x71808086: /* 440BX */
184                 /*
185                  * XXX: Should be 0xa080?  Bit 9 is undefined, and
186                  * bit 13 being on and bit 15 being clear is illegal.
187                  */
188                 pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2280, 4);
189                 break;
190         default:
191                 value = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
192                 pci_write_config(dev, AGP_INTEL_AGPCTRL, value | 0x80, 4);
193         }
194
195         /* Enable things, clear errors etc. */
196         switch (type) {
197         case 0x1a218086: /* i840 */
198         case 0x25308086: /* i850 */
199         case 0x25318086: /* i860 */
200                 pci_write_config(dev, AGP_INTEL_MCHCFG,
201                                  (pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
202                                   | (1 << 9)), 2);
203                 break;
204
205         case 0x25008086: /* i820 */
206         case 0x25018086: /* i820 */
207                 pci_write_config(dev, AGP_INTEL_I820_RDCR,
208                                  (pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
209                                   | (1 << 1)), 1);
210                 break;
211
212         case 0x1a308086: /* i845 */
213         case 0x33408086: /* i855 */
214         case 0x25708086: /* i865 */
215         case 0x25788086: /* i875P */
216         case 0x25608086: /* i845G */
217                 pci_write_config(dev, AGP_INTEL_I845_MCHCFG,
218                                  (pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
219                                   | (1 << 1)), 1);
220                 break;
221
222         default: /* Intel Generic (maybe) */
223                 pci_write_config(dev, AGP_INTEL_NBXCFG,
224                                  (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
225                                   & ~(1 << 10)) | (1 << 9), 4);
226         }
227
228         switch (type) {
229         case 0x1a218086: /* i840 */
230                 pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0xc000, 2);
231                 break;
232
233         case 0x25008086: /* i820 */
234         case 0x25018086: /* i820 */
235         case 0x1a308086: /* i845 */
236         case 0x25308086: /* i850 */
237         case 0x33408086: /* i855 */
238         case 0x25318086: /* i860 */
239         case 0x25708086: /* i865 */
240         case 0x25788086: /* i875P */
241         case 0x25608086: /* i845G */
242                 pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0x00ff, 2);
243                 break;
244
245         default: /* Intel Generic (maybe) */
246                 pci_write_config(dev, AGP_INTEL_ERRSTS + 1, 7, 1);
247         }
248
249         return 0;
250 }
251
252 static int
253 agp_intel_detach(device_t dev)
254 {
255         struct agp_intel_softc *sc = device_get_softc(dev);
256         u_int32_t type = pci_get_devid(dev);
257         int error;
258
259         error = agp_generic_detach(dev);
260         if (error)
261                 return error;
262
263         switch (type) {
264         case 0x1a218086: /* i840 */
265         case 0x25308086: /* i850 */
266         case 0x25318086: /* i860 */
267                 kprintf("%s: set MCHCFG to %x\n", __func__, (unsigned)
268                                 (pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
269                                 & ~(1 << 9)));
270                 pci_write_config(dev, AGP_INTEL_MCHCFG,
271                                 (pci_read_config(dev, AGP_INTEL_MCHCFG, 2)
272                                 & ~(1 << 9)), 2);
273
274         case 0x25008086: /* i820 */
275         case 0x25018086: /* i820 */
276                 kprintf("%s: set RDCR to %x\n", __func__, (unsigned)
277                                 (pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
278                                 & ~(1 << 1)));
279                 pci_write_config(dev, AGP_INTEL_I820_RDCR,
280                                 (pci_read_config(dev, AGP_INTEL_I820_RDCR, 1)
281                                 & ~(1 << 1)), 1);
282
283         case 0x1a308086: /* i845 */
284         case 0x25608086: /* i845G */
285         case 0x33408086: /* i855 */
286         case 0x25708086: /* i865 */
287         case 0x25788086: /* i875P */
288                 kprintf("%s: set MCHCFG to %x\n", __func__, (unsigned)
289                                 (pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
290                                 & ~(1 << 1)));
291                 pci_write_config(dev, AGP_INTEL_MCHCFG,
292                                 (pci_read_config(dev, AGP_INTEL_I845_MCHCFG, 1)
293                                 & ~(1 << 1)), 1);
294
295         default: /* Intel Generic (maybe) */
296                 kprintf("%s: set NBXCFG to %x\n", __func__,
297                                  (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
298                                   & ~(1 << 9)));
299                 pci_write_config(dev, AGP_INTEL_NBXCFG,
300                                  (pci_read_config(dev, AGP_INTEL_NBXCFG, 4)
301                                   & ~(1 << 9)), 4);
302         }
303         pci_write_config(dev, AGP_INTEL_ATTBASE, 0, 4);
304         AGP_SET_APERTURE(dev, sc->initial_aperture);
305         agp_free_gatt(sc->gatt);
306
307         return 0;
308 }
309
310 static u_int32_t
311 agp_intel_get_aperture(device_t dev)
312 {
313         struct agp_intel_softc *sc = device_get_softc(dev);
314         u_int32_t apsize;
315
316         apsize = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & sc->aperture_mask;
317
318         /*
319          * The size is determined by the number of low bits of
320          * register APBASE which are forced to zero. The low 22 bits
321          * are always forced to zero and each zero bit in the apsize
322          * field just read forces the corresponding bit in the 27:22
323          * to be zero. We calculate the aperture size accordingly.
324          */
325         return (((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1;
326 }
327
328 static int
329 agp_intel_set_aperture(device_t dev, u_int32_t aperture)
330 {
331         struct agp_intel_softc *sc = device_get_softc(dev);
332         u_int32_t apsize;
333
334         /*
335          * Reverse the magic from get_aperture.
336          */
337         apsize = ((aperture - 1) >> 22) ^ sc->aperture_mask;
338
339         /*
340          * Double check for sanity.
341          */
342         if ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1 != aperture)
343                 return EINVAL;
344
345         pci_write_config(dev, AGP_INTEL_APSIZE, apsize, 1);
346
347         return 0;
348 }
349
350 static int
351 agp_intel_bind_page(device_t dev, int offset, vm_offset_t physical)
352 {
353         struct agp_intel_softc *sc = device_get_softc(dev);
354
355         if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
356                 return EINVAL;
357
358         sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 0x17;
359         return 0;
360 }
361
362 static int
363 agp_intel_unbind_page(device_t dev, int offset)
364 {
365         struct agp_intel_softc *sc = device_get_softc(dev);
366
367         if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
368                 return EINVAL;
369
370         sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
371         return 0;
372 }
373
374 static void
375 agp_intel_flush_tlb(device_t dev)
376 {
377         u_int32_t val;
378
379         val = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4);
380         pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 7), 4);
381         pci_write_config(dev, AGP_INTEL_AGPCTRL, val, 4);
382 }
383
384 static device_method_t agp_intel_methods[] = {
385         /* Device interface */
386         DEVMETHOD(device_probe,         agp_intel_probe),
387         DEVMETHOD(device_attach,        agp_intel_attach),
388         DEVMETHOD(device_detach,        agp_intel_detach),
389         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
390         DEVMETHOD(device_suspend,       bus_generic_suspend),
391         DEVMETHOD(device_resume,        bus_generic_resume),
392
393         /* AGP interface */
394         DEVMETHOD(agp_get_aperture,     agp_intel_get_aperture),
395         DEVMETHOD(agp_set_aperture,     agp_intel_set_aperture),
396         DEVMETHOD(agp_bind_page,        agp_intel_bind_page),
397         DEVMETHOD(agp_unbind_page,      agp_intel_unbind_page),
398         DEVMETHOD(agp_flush_tlb,        agp_intel_flush_tlb),
399         DEVMETHOD(agp_enable,           agp_generic_enable),
400         DEVMETHOD(agp_alloc_memory,     agp_generic_alloc_memory),
401         DEVMETHOD(agp_free_memory,      agp_generic_free_memory),
402         DEVMETHOD(agp_bind_memory,      agp_generic_bind_memory),
403         DEVMETHOD(agp_unbind_memory,    agp_generic_unbind_memory),
404
405         { 0, 0 }
406 };
407
408 static driver_t agp_intel_driver = {
409         "agp",
410         agp_intel_methods,
411         sizeof(struct agp_intel_softc),
412 };
413
414 static devclass_t agp_devclass;
415
416 DRIVER_MODULE(agp_intel, pci, agp_intel_driver, agp_devclass, 0, 0);
417 MODULE_DEPEND(agp_intel, agp, 1, 1, 1);
418 MODULE_DEPEND(agp_intel, pci, 1, 1, 1);