gdb - Local mods (compile)
[dragonfly.git] / sys / dev / agp / agp_i810.c
CommitLineData
ab5a0ec8 1/*
984263bc
MD
2 * Copyright (c) 2000 Doug Rabson
3 * Copyright (c) 2000 Ruslan Ermilov
a904aa53 4 * Copyright (c) 2011 The FreeBSD Foundation
984263bc
MD
5 * All rights reserved.
6 *
a904aa53
FT
7 * Portions of this software were developed by Konstantin Belousov
8 * under sponsorship from the FreeBSD Foundation.
9 *
984263bc
MD
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
984263bc
MD
30 */
31
32/*
33 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
fdc3c5be 34 * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
a904aa53
FT
35 *
36 * This is generic Intel GTT handling code, morphed from the AGP
37 * bridge code.
984263bc
MD
38 */
39
a904aa53
FT
40#if 0
41#define KTR_AGP_I810 KTR_DEV
42#else
43#define KTR_AGP_I810 0
44#endif
45
984263bc
MD
46#include <sys/param.h>
47#include <sys/systm.h>
48#include <sys/malloc.h>
49#include <sys/kernel.h>
50#include <sys/bus.h>
51#include <sys/lock.h>
1f7ab7c9 52#include <sys/rman.h>
984263bc 53
dcb4b80d 54#include "pcidevs.h"
1f2de5d4
MD
55#include <bus/pci/pcivar.h>
56#include <bus/pci/pcireg.h>
57#include "agppriv.h"
58#include "agpreg.h"
b2776052 59#include <drm/intel-gtt.h>
984263bc
MD
60
61#include <vm/vm.h>
62#include <vm/vm_object.h>
63#include <vm/vm_page.h>
7414ebeb 64#include <vm/vm_param.h>
984263bc
MD
65#include <vm/vm_pageout.h>
66#include <vm/pmap.h>
67
7414ebeb
MD
68#include <vm/vm_page2.h>
69
fdc3c5be
HT
70#include <machine/md_var.h>
71
72#define bus_read_1(r, o) \
73 bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o))
74#define bus_read_4(r, o) \
75 bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o))
76#define bus_write_4(r, o, v) \
77 bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
78
984263bc
MD
79MALLOC_DECLARE(M_AGP);
80
a904aa53
FT
81struct agp_i810_match;
82
a904aa53
FT
83static int agp_i915_check_active(device_t bridge_dev);
84static int agp_sb_check_active(device_t bridge_dev);
85
a904aa53
FT
86static void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match);
87
a904aa53
FT
88static void agp_i915_dump_regs(device_t dev);
89static void agp_i965_dump_regs(device_t dev);
90static void agp_sb_dump_regs(device_t dev);
91
a904aa53
FT
92static int agp_i915_get_stolen_size(device_t dev);
93static int agp_sb_get_stolen_size(device_t dev);
94
a904aa53
FT
95static int agp_i915_get_gtt_mappable_entries(device_t dev);
96
97static int agp_i810_get_gtt_total_entries(device_t dev);
98static int agp_i965_get_gtt_total_entries(device_t dev);
99static int agp_gen5_get_gtt_total_entries(device_t dev);
100static int agp_sb_get_gtt_total_entries(device_t dev);
101
a904aa53 102static int agp_i830_install_gatt(device_t dev);
7414ebeb 103static int agp_sb_install_gatt(device_t dev);
a904aa53 104
a904aa53 105static void agp_i830_deinstall_gatt(device_t dev);
7414ebeb 106static void agp_sb_deinstall_gatt(device_t dev);
a904aa53 107
a904aa53
FT
108static void agp_i915_install_gtt_pte(device_t dev, u_int index,
109 vm_offset_t physical, int flags);
110static void agp_i965_install_gtt_pte(device_t dev, u_int index,
111 vm_offset_t physical, int flags);
112static void agp_g4x_install_gtt_pte(device_t dev, u_int index,
113 vm_offset_t physical, int flags);
114static void agp_sb_install_gtt_pte(device_t dev, u_int index,
115 vm_offset_t physical, int flags);
116
a904aa53
FT
117static void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte);
118static void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte);
119static void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte);
120static void agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte);
121
09d2c144
MD
122static void agp_i915_sync_gtt_pte(device_t dev, u_int index);
123static void agp_i965_sync_gtt_pte(device_t dev, u_int index);
124static void agp_g4x_sync_gtt_pte(device_t dev, u_int index);
a904aa53 125
a904aa53
FT
126static int agp_i915_set_aperture(device_t dev, u_int32_t aperture);
127
128static int agp_i810_chipset_flush_setup(device_t dev);
129static int agp_i915_chipset_flush_setup(device_t dev);
130static int agp_i965_chipset_flush_setup(device_t dev);
131
132static void agp_i810_chipset_flush_teardown(device_t dev);
133static void agp_i915_chipset_flush_teardown(device_t dev);
134static void agp_i965_chipset_flush_teardown(device_t dev);
135
136static void agp_i810_chipset_flush(device_t dev);
a904aa53
FT
137static void agp_i915_chipset_flush(device_t dev);
138
fdc3c5be
HT
139enum {
140 CHIP_I810, /* i810/i815 */
141 CHIP_I830, /* 830M/845G */
142 CHIP_I855, /* 852GM/855GM/865G */
143 CHIP_I915, /* 915G/915GM */
144 CHIP_I965, /* G965 */
145 CHIP_G33, /* G33/Q33/Q35 */
7f9ec87c 146 CHIP_IGD, /* Pineview */
f16c0bab 147 CHIP_G4X, /* G45/Q45 */
a904aa53 148 CHIP_SB, /* SandyBridge */
fdc3c5be 149};
984263bc 150
fdc3c5be
HT
151/* The i810 through i855 have the registers at BAR 1, and the GATT gets
152 * allocated by us. The i915 has registers in BAR 0 and the GATT is at the
153 * start of the stolen memory, and should only be accessed by the OS through
154 * BAR 3. The G965 has registers and GATT in the same BAR (0) -- first 512KB
155 * is registers, second 512KB is GATT.
156 */
fdc3c5be
HT
157static struct resource_spec agp_i915_res_spec[] = {
158 { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE },
159 { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE },
160 { -1, 0 }
161};
162
163static struct resource_spec agp_i965_res_spec[] = {
164 { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE },
165 { -1, 0 }
166};
984263bc 167
a904aa53
FT
168static struct resource_spec agp_g4x_res_spec[] = {
169 { SYS_RES_MEMORY, AGP_G4X_MMADR, RF_ACTIVE | RF_SHAREABLE },
170 { SYS_RES_MEMORY, AGP_G4X_GTTADR, RF_ACTIVE | RF_SHAREABLE },
171 { -1, 0 }
172};
173
984263bc
MD
174struct agp_i810_softc {
175 struct agp_softc agp;
176 u_int32_t initial_aperture; /* aperture size at startup */
177 struct agp_gatt *gatt;
984263bc 178 u_int32_t dcache_size; /* i810 only */
a904aa53
FT
179 u_int32_t stolen; /* number of i830/845 gtt
180 entries for stolen memory */
181 u_int stolen_size; /* BIOS-reserved graphics memory */
182 u_int gtt_total_entries; /* Total number of gtt ptes */
183 u_int gtt_mappable_entries; /* Number of gtt ptes mappable by CPU */
984263bc 184 device_t bdev; /* bridge device */
fdc3c5be 185 void *argb_cursor; /* contigmalloc area for ARGB cursor */
7414ebeb 186 struct resource *sc_res[3];
a904aa53
FT
187 const struct agp_i810_match *match;
188 int sc_flush_page_rid;
189 struct resource *sc_flush_page_res;
190 void *sc_flush_page_vaddr;
191 int sc_bios_allocated_flush_page;
192};
193
194static device_t intel_agp;
195
196struct agp_i810_driver {
197 int chiptype;
198 int gen;
199 int busdma_addr_mask_sz;
200 struct resource_spec *res_spec;
201 int (*check_active)(device_t);
202 void (*set_desc)(device_t, const struct agp_i810_match *);
203 void (*dump_regs)(device_t);
204 int (*get_stolen_size)(device_t);
205 int (*get_gtt_total_entries)(device_t);
206 int (*get_gtt_mappable_entries)(device_t);
207 int (*install_gatt)(device_t);
208 void (*deinstall_gatt)(device_t);
209 void (*write_gtt)(device_t, u_int, uint32_t);
210 void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int);
09d2c144 211 void (*sync_gtt_pte)(device_t, u_int);
a904aa53
FT
212 int (*set_aperture)(device_t, u_int32_t);
213 int (*chipset_flush_setup)(device_t);
214 void (*chipset_flush_teardown)(device_t);
215 void (*chipset_flush)(device_t);
216};
217
bc2fd6c1
FT
218static struct {
219 struct intel_gtt base;
220} intel_private;
221
a904aa53
FT
222static const struct agp_i810_driver agp_i810_i915_driver = {
223 .chiptype = CHIP_I915,
224 .gen = 3,
225 .busdma_addr_mask_sz = 32,
226 .res_spec = agp_i915_res_spec,
227 .check_active = agp_i915_check_active,
228 .set_desc = agp_i810_set_desc,
229 .dump_regs = agp_i915_dump_regs,
230 .get_stolen_size = agp_i915_get_stolen_size,
231 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
232 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
233 .install_gatt = agp_i830_install_gatt,
234 .deinstall_gatt = agp_i830_deinstall_gatt,
235 .write_gtt = agp_i915_write_gtt,
236 .install_gtt_pte = agp_i915_install_gtt_pte,
09d2c144 237 .sync_gtt_pte = agp_i915_sync_gtt_pte,
a904aa53
FT
238 .set_aperture = agp_i915_set_aperture,
239 .chipset_flush_setup = agp_i915_chipset_flush_setup,
240 .chipset_flush_teardown = agp_i915_chipset_flush_teardown,
241 .chipset_flush = agp_i915_chipset_flush,
242};
243
244static const struct agp_i810_driver agp_i810_g965_driver = {
245 .chiptype = CHIP_I965,
246 .gen = 4,
247 .busdma_addr_mask_sz = 36,
248 .res_spec = agp_i965_res_spec,
249 .check_active = agp_i915_check_active,
250 .set_desc = agp_i810_set_desc,
251 .dump_regs = agp_i965_dump_regs,
252 .get_stolen_size = agp_i915_get_stolen_size,
253 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
254 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
255 .install_gatt = agp_i830_install_gatt,
256 .deinstall_gatt = agp_i830_deinstall_gatt,
257 .write_gtt = agp_i965_write_gtt,
258 .install_gtt_pte = agp_i965_install_gtt_pte,
09d2c144 259 .sync_gtt_pte = agp_i965_sync_gtt_pte,
a904aa53
FT
260 .set_aperture = agp_i915_set_aperture,
261 .chipset_flush_setup = agp_i965_chipset_flush_setup,
262 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
263 .chipset_flush = agp_i915_chipset_flush,
264};
265
266static const struct agp_i810_driver agp_i810_g33_driver = {
267 .chiptype = CHIP_G33,
268 .gen = 3,
269 .busdma_addr_mask_sz = 36,
270 .res_spec = agp_i915_res_spec,
271 .check_active = agp_i915_check_active,
272 .set_desc = agp_i810_set_desc,
273 .dump_regs = agp_i965_dump_regs,
274 .get_stolen_size = agp_i915_get_stolen_size,
275 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
276 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
277 .install_gatt = agp_i830_install_gatt,
278 .deinstall_gatt = agp_i830_deinstall_gatt,
279 .write_gtt = agp_i915_write_gtt,
99e9e211 280 .install_gtt_pte = agp_i965_install_gtt_pte,
09d2c144 281 .sync_gtt_pte = agp_i915_sync_gtt_pte,
a904aa53
FT
282 .set_aperture = agp_i915_set_aperture,
283 .chipset_flush_setup = agp_i965_chipset_flush_setup,
284 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
285 .chipset_flush = agp_i915_chipset_flush,
286};
287
99e9e211 288static const struct agp_i810_driver pineview_gtt_driver = {
a904aa53
FT
289 .chiptype = CHIP_IGD,
290 .gen = 3,
291 .busdma_addr_mask_sz = 36,
292 .res_spec = agp_i915_res_spec,
293 .check_active = agp_i915_check_active,
294 .set_desc = agp_i810_set_desc,
295 .dump_regs = agp_i915_dump_regs,
296 .get_stolen_size = agp_i915_get_stolen_size,
297 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
298 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
299 .install_gatt = agp_i830_install_gatt,
300 .deinstall_gatt = agp_i830_deinstall_gatt,
301 .write_gtt = agp_i915_write_gtt,
99e9e211 302 .install_gtt_pte = agp_i965_install_gtt_pte,
09d2c144 303 .sync_gtt_pte = agp_i915_sync_gtt_pte,
a904aa53
FT
304 .set_aperture = agp_i915_set_aperture,
305 .chipset_flush_setup = agp_i965_chipset_flush_setup,
306 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
307 .chipset_flush = agp_i915_chipset_flush,
308};
309
310static const struct agp_i810_driver agp_i810_g4x_driver = {
311 .chiptype = CHIP_G4X,
312 .gen = 5,
313 .busdma_addr_mask_sz = 36,
314 .res_spec = agp_i965_res_spec,
315 .check_active = agp_i915_check_active,
316 .set_desc = agp_i810_set_desc,
317 .dump_regs = agp_i965_dump_regs,
318 .get_stolen_size = agp_i915_get_stolen_size,
319 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
320 .get_gtt_total_entries = agp_gen5_get_gtt_total_entries,
321 .install_gatt = agp_i830_install_gatt,
322 .deinstall_gatt = agp_i830_deinstall_gatt,
323 .write_gtt = agp_g4x_write_gtt,
324 .install_gtt_pte = agp_g4x_install_gtt_pte,
09d2c144 325 .sync_gtt_pte = agp_g4x_sync_gtt_pte,
a904aa53
FT
326 .set_aperture = agp_i915_set_aperture,
327 .chipset_flush_setup = agp_i965_chipset_flush_setup,
328 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
329 .chipset_flush = agp_i915_chipset_flush,
330};
331
332static const struct agp_i810_driver agp_i810_sb_driver = {
333 .chiptype = CHIP_SB,
334 .gen = 6,
335 .busdma_addr_mask_sz = 40,
336 .res_spec = agp_g4x_res_spec,
337 .check_active = agp_sb_check_active,
338 .set_desc = agp_i810_set_desc,
339 .dump_regs = agp_sb_dump_regs,
340 .get_stolen_size = agp_sb_get_stolen_size,
341 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
342 .get_gtt_total_entries = agp_sb_get_gtt_total_entries,
7414ebeb
MD
343 .install_gatt = agp_sb_install_gatt,
344 .deinstall_gatt = agp_sb_deinstall_gatt,
a904aa53
FT
345 .write_gtt = agp_sb_write_gtt,
346 .install_gtt_pte = agp_sb_install_gtt_pte,
09d2c144 347 .sync_gtt_pte = agp_g4x_sync_gtt_pte,
a904aa53
FT
348 .set_aperture = agp_i915_set_aperture,
349 .chipset_flush_setup = agp_i810_chipset_flush_setup,
350 .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
351 .chipset_flush = agp_i810_chipset_flush,
fdc3c5be
HT
352};
353
354/* For adding new devices, devid is the id of the graphics controller
355 * (pci:0:2:0, for example). The placeholder (usually at pci:0:2:1) for the
356 * second head should never be added. The bridge_offset is the offset to
357 * subtract from devid to get the id of the hostb that the device is on.
358 */
359static const struct agp_i810_match {
8d36a65a 360 uint16_t devid;
fdc3c5be 361 char *name;
a904aa53 362 const struct agp_i810_driver *driver;
fdc3c5be 363} agp_i810_matches[] = {
a904aa53 364 {
31d142df 365 .devid = 0x2582,
a904aa53
FT
366 .name = "Intel 82915G (915G GMCH) SVGA controller",
367 .driver = &agp_i810_i915_driver
368 },
369 {
31d142df 370 .devid = 0x258A,
a904aa53
FT
371 .name = "Intel E7221 SVGA controller",
372 .driver = &agp_i810_i915_driver
373 },
374 {
31d142df 375 .devid = 0x2592,
a904aa53
FT
376 .name = "Intel 82915GM (915GM GMCH) SVGA controller",
377 .driver = &agp_i810_i915_driver
378 },
379 {
31d142df 380 .devid = 0x2772,
a904aa53
FT
381 .name = "Intel 82945G (945G GMCH) SVGA controller",
382 .driver = &agp_i810_i915_driver
383 },
384 {
31d142df 385 .devid = 0x27A2,
a904aa53
FT
386 .name = "Intel 82945GM (945GM GMCH) SVGA controller",
387 .driver = &agp_i810_i915_driver
388 },
389 {
31d142df 390 .devid = 0x27AE,
a904aa53
FT
391 .name = "Intel 945GME SVGA controller",
392 .driver = &agp_i810_i915_driver
393 },
394 {
31d142df 395 .devid = 0x2972,
a904aa53
FT
396 .name = "Intel 946GZ SVGA controller",
397 .driver = &agp_i810_g965_driver
398 },
399 {
31d142df 400 .devid = 0x2982,
a904aa53
FT
401 .name = "Intel G965 SVGA controller",
402 .driver = &agp_i810_g965_driver
403 },
404 {
31d142df 405 .devid = 0x2992,
a904aa53
FT
406 .name = "Intel Q965 SVGA controller",
407 .driver = &agp_i810_g965_driver
408 },
409 {
31d142df 410 .devid = 0x29A2,
a904aa53
FT
411 .name = "Intel G965 SVGA controller",
412 .driver = &agp_i810_g965_driver
413 },
414 {
31d142df 415 .devid = 0x29B2,
a904aa53
FT
416 .name = "Intel Q35 SVGA controller",
417 .driver = &agp_i810_g33_driver
418 },
419 {
31d142df 420 .devid = 0x29C2,
a904aa53
FT
421 .name = "Intel G33 SVGA controller",
422 .driver = &agp_i810_g33_driver
423 },
424 {
31d142df 425 .devid = 0x29D2,
a904aa53
FT
426 .name = "Intel Q33 SVGA controller",
427 .driver = &agp_i810_g33_driver
428 },
429 {
31d142df 430 .devid = 0xA001,
a904aa53 431 .name = "Intel Pineview SVGA controller",
99e9e211 432 .driver = &pineview_gtt_driver
a904aa53
FT
433 },
434 {
31d142df 435 .devid = 0xA011,
a904aa53 436 .name = "Intel Pineview (M) SVGA controller",
99e9e211 437 .driver = &pineview_gtt_driver
a904aa53
FT
438 },
439 {
31d142df 440 .devid = 0x2A02,
a904aa53
FT
441 .name = "Intel GM965 SVGA controller",
442 .driver = &agp_i810_g965_driver
443 },
444 {
31d142df 445 .devid = 0x2A12,
a904aa53
FT
446 .name = "Intel GME965 SVGA controller",
447 .driver = &agp_i810_g965_driver
448 },
449 {
31d142df 450 .devid = 0x2A42,
a904aa53
FT
451 .name = "Intel GM45 SVGA controller",
452 .driver = &agp_i810_g4x_driver
453 },
454 {
31d142df 455 .devid = 0x2E02,
a904aa53
FT
456 .name = "Intel Eaglelake SVGA controller",
457 .driver = &agp_i810_g4x_driver
458 },
459 {
31d142df 460 .devid = 0x2E12,
a904aa53
FT
461 .name = "Intel Q45 SVGA controller",
462 .driver = &agp_i810_g4x_driver
463 },
464 {
31d142df 465 .devid = 0x2E22,
a904aa53
FT
466 .name = "Intel G45 SVGA controller",
467 .driver = &agp_i810_g4x_driver
468 },
469 {
31d142df 470 .devid = 0x2E32,
a904aa53
FT
471 .name = "Intel G41 SVGA controller",
472 .driver = &agp_i810_g4x_driver
473 },
474 {
31d142df 475 .devid = 0x0042,
a904aa53
FT
476 .name = "Intel Ironlake (D) SVGA controller",
477 .driver = &agp_i810_g4x_driver
478 },
479 {
31d142df 480 .devid = 0x0046,
a904aa53
FT
481 .name = "Intel Ironlake (M) SVGA controller",
482 .driver = &agp_i810_g4x_driver
483 },
484 {
31d142df 485 .devid = 0x0102,
a904aa53
FT
486 .name = "SandyBridge desktop GT1 IG",
487 .driver = &agp_i810_sb_driver
488 },
489 {
31d142df 490 .devid = 0x0112,
a904aa53
FT
491 .name = "SandyBridge desktop GT2 IG",
492 .driver = &agp_i810_sb_driver
493 },
494 {
31d142df 495 .devid = 0x0122,
a904aa53
FT
496 .name = "SandyBridge desktop GT2+ IG",
497 .driver = &agp_i810_sb_driver
498 },
499 {
31d142df 500 .devid = 0x0106,
a904aa53
FT
501 .name = "SandyBridge mobile GT1 IG",
502 .driver = &agp_i810_sb_driver
503 },
504 {
31d142df 505 .devid = 0x0116,
a904aa53
FT
506 .name = "SandyBridge mobile GT2 IG",
507 .driver = &agp_i810_sb_driver
508 },
509 {
31d142df 510 .devid = 0x0126,
a904aa53
FT
511 .name = "SandyBridge mobile GT2+ IG",
512 .driver = &agp_i810_sb_driver
513 },
514 {
31d142df 515 .devid = 0x010a,
a904aa53
FT
516 .name = "SandyBridge server IG",
517 .driver = &agp_i810_sb_driver
518 },
519 {
31d142df 520 .devid = 0x0152,
a904aa53
FT
521 .name = "IvyBridge desktop GT1 IG",
522 .driver = &agp_i810_sb_driver
523 },
524 {
31d142df 525 .devid = 0x0162,
a904aa53
FT
526 .name = "IvyBridge desktop GT2 IG",
527 .driver = &agp_i810_sb_driver
528 },
529 {
31d142df 530 .devid = 0x0156,
a904aa53
FT
531 .name = "IvyBridge mobile GT1 IG",
532 .driver = &agp_i810_sb_driver
533 },
534 {
31d142df 535 .devid = 0x0166,
a904aa53
FT
536 .name = "IvyBridge mobile GT2 IG",
537 .driver = &agp_i810_sb_driver
538 },
539 {
31d142df 540 .devid = 0x015a,
a904aa53
FT
541 .name = "IvyBridge server GT1 IG",
542 .driver = &agp_i810_sb_driver
543 },
246f9ec5 544 {
31d142df 545 .devid = 0x016a,
246f9ec5
FT
546 .name = "IvyBridge server GT2 IG",
547 .driver = &agp_i810_sb_driver
548 },
8d36a65a
FT
549 {
550 .devid = 0x0402,
551 .name = "Haswell desktop GT1 IG",
552 .driver = &agp_i810_sb_driver
553 },
554 {
555 .devid = 0x0412,
556 .name = "Haswell desktop GT2 IG",
557 .driver = &agp_i810_sb_driver
558 },
bb66151c 559 { 0x041e, "Haswell", &agp_i810_sb_driver },
cf614546 560 { 0x0422, "Haswell", &agp_i810_sb_driver },
8d36a65a
FT
561 {
562 .devid = 0x0406,
563 .name = "Haswell mobile GT1 IG",
564 .driver = &agp_i810_sb_driver
565 },
566 {
567 .devid = 0x0416,
568 .name = "Haswell mobile GT2 IG",
569 .driver = &agp_i810_sb_driver
570 },
cf614546 571 { 0x0426, "Haswell", &agp_i810_sb_driver },
8d36a65a
FT
572 {
573 .devid = 0x040a,
574 .name = "Haswell server GT1 IG",
575 .driver = &agp_i810_sb_driver
576 },
577 {
578 .devid = 0x041a,
579 .name = "Haswell server GT2 IG",
580 .driver = &agp_i810_sb_driver
581 },
cf614546
FT
582 { 0x042a, "Haswell", &agp_i810_sb_driver },
583 { 0x0c02, "Haswell", &agp_i810_sb_driver },
584 { 0x0c12, "Haswell", &agp_i810_sb_driver },
585 { 0x0c22, "Haswell", &agp_i810_sb_driver },
586 { 0x0c06, "Haswell", &agp_i810_sb_driver },
8d36a65a
FT
587 {
588 .devid = 0x0c16,
589 .name = "Haswell SDV",
590 .driver = &agp_i810_sb_driver
591 },
cf614546
FT
592 { 0x0c26, "Haswell", &agp_i810_sb_driver },
593 { 0x0c0a, "Haswell", &agp_i810_sb_driver },
594 { 0x0c1a, "Haswell", &agp_i810_sb_driver },
595 { 0x0c2a, "Haswell", &agp_i810_sb_driver },
596 { 0x0a02, "Haswell", &agp_i810_sb_driver },
597 { 0x0a12, "Haswell", &agp_i810_sb_driver },
598 { 0x0a22, "Haswell", &agp_i810_sb_driver },
599 { 0x0a06, "Haswell", &agp_i810_sb_driver },
600 { 0x0a16, "Haswell", &agp_i810_sb_driver },
601 { 0x0a26, "Haswell", &agp_i810_sb_driver },
602 { 0x0a0a, "Haswell", &agp_i810_sb_driver },
603 { 0x0a1a, "Haswell", &agp_i810_sb_driver },
604 { 0x0a2a, "Haswell", &agp_i810_sb_driver },
605 { 0x0d12, "Haswell", &agp_i810_sb_driver },
606 { 0x0d22, "Haswell", &agp_i810_sb_driver },
607 { 0x0d32, "Haswell", &agp_i810_sb_driver },
608 { 0x0d16, "Haswell", &agp_i810_sb_driver },
609 { 0x0d26, "Haswell", &agp_i810_sb_driver },
610 { 0x0d36, "Haswell", &agp_i810_sb_driver },
611 { 0x0d1a, "Haswell", &agp_i810_sb_driver },
612 { 0x0d2a, "Haswell", &agp_i810_sb_driver },
613 { 0x0d3a, "Haswell", &agp_i810_sb_driver },
09d2c144 614
a904aa53
FT
615 {
616 .devid = 0,
617 }
984263bc
MD
618};
619
fdc3c5be 620static const struct agp_i810_match*
984263bc
MD
621agp_i810_match(device_t dev)
622{
fdc3c5be
HT
623 int i, devid;
624
31d142df 625 if (pci_get_vendor(dev) != PCI_VENDOR_INTEL)
a904aa53 626 return (NULL);
984263bc 627
26b66f28 628 devid = pci_get_device(dev);
fdc3c5be
HT
629 for (i = 0; agp_i810_matches[i].devid != 0; i++) {
630 if (agp_i810_matches[i].devid == devid)
a904aa53 631 break;
fdc3c5be
HT
632 }
633 if (agp_i810_matches[i].devid == 0)
a904aa53 634 return (NULL);
fdc3c5be 635 else
a904aa53 636 return (&agp_i810_matches[i]);
984263bc
MD
637}
638
639/*
640 * Find bridge device.
641 */
642static device_t
643agp_i810_find_bridge(device_t dev)
644{
984263bc 645
a904aa53 646 return (pci_find_dbsf(0, 0, 0, 0));
984263bc
MD
647}
648
fdc3c5be
HT
649static void
650agp_i810_identify(driver_t *driver, device_t parent)
651{
652
653 if (device_find_child(parent, "agp", -1) == NULL &&
654 agp_i810_match(parent))
655 device_add_child(parent, "agp", -1);
656}
657
a904aa53
FT
658static int
659agp_i915_check_active(device_t bridge_dev)
660{
661 int deven;
662
663 deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
664 if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
665 return (ENXIO);
666 return (0);
667}
668
669static int
670agp_sb_check_active(device_t bridge_dev)
671{
672 int deven;
673
674 deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
675 if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED)
676 return (ENXIO);
677 return (0);
678}
679
a904aa53
FT
680static void
681agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
682{
683
684 device_set_desc(dev, match->name);
685}
686
984263bc
MD
687static int
688agp_i810_probe(device_t dev)
689{
fdc3c5be
HT
690 device_t bdev;
691 const struct agp_i810_match *match;
7414ebeb 692 int err = 0;
fdc3c5be
HT
693
694 if (resource_disabled("agp", device_get_unit(dev)))
695 return (ENXIO);
696 match = agp_i810_match(dev);
697 if (match == NULL)
a904aa53 698 return (ENXIO);
984263bc 699
fdc3c5be 700 bdev = agp_i810_find_bridge(dev);
a904aa53 701 if (bdev == NULL) {
fdc3c5be
HT
702 if (bootverbose)
703 kprintf("I810: can't find bridge device\n");
a904aa53 704 return (ENXIO);
fdc3c5be 705 }
984263bc 706
fdc3c5be
HT
707 /*
708 * checking whether internal graphics device has been activated.
709 */
7414ebeb
MD
710 if (match->driver->check_active != NULL) {
711 err = match->driver->check_active(bdev);
712 if (err != 0) {
713 if (bootverbose)
714 kprintf("i810: disabled, not probing\n");
715 return (err);
716 }
984263bc
MD
717 }
718
a904aa53
FT
719 match->driver->set_desc(dev, match);
720 return (BUS_PROBE_DEFAULT);
fdc3c5be
HT
721}
722
a904aa53
FT
723static void
724agp_i915_dump_regs(device_t dev)
725{
726 struct agp_i810_softc *sc = device_get_softc(dev);
984263bc 727
a904aa53
FT
728 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
729 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
730 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
731 pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
732 device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
733 pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
734}
fdc3c5be 735
a904aa53
FT
736static void
737agp_i965_dump_regs(device_t dev)
738{
739 struct agp_i810_softc *sc = device_get_softc(dev);
984263bc 740
a904aa53
FT
741 device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
742 bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
743 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
7414ebeb 744 pci_read_config(dev, AGP_I855_GCC1, 1));
a904aa53 745 device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
7414ebeb 746 pci_read_config(dev, AGP_I965_MSAC, 1));
a904aa53 747}
fdc3c5be 748
a904aa53
FT
749static void
750agp_sb_dump_regs(device_t dev)
751{
752 struct agp_i810_softc *sc = device_get_softc(dev);
984263bc 753
a904aa53
FT
754 device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n",
755 bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE));
756 device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n",
7414ebeb 757 pci_read_config(dev, AGP_SNB_GCC1, 2));
a904aa53
FT
758}
759
a904aa53
FT
760static int
761agp_i915_get_stolen_size(device_t dev)
762{
763 struct agp_i810_softc *sc;
764 unsigned int gcc1, stolen, gtt_size;
984263bc 765
a904aa53 766 sc = device_get_softc(dev);
fdc3c5be 767
a904aa53
FT
768 /*
769 * Stolen memory is set up at the beginning of the aperture by
770 * the BIOS, consisting of the GATT followed by 4kb for the
771 * BIOS display.
772 */
773 switch (sc->match->driver->chiptype) {
774 case CHIP_I855:
775 gtt_size = 128;
776 break;
777 case CHIP_I915:
778 gtt_size = 256;
779 break;
780 case CHIP_I965:
781 switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
782 AGP_I810_PGTBL_SIZE_MASK) {
783 case AGP_I810_PGTBL_SIZE_128KB:
fdc3c5be
HT
784 gtt_size = 128;
785 break;
a904aa53 786 case AGP_I810_PGTBL_SIZE_256KB:
fdc3c5be
HT
787 gtt_size = 256;
788 break;
a904aa53
FT
789 case AGP_I810_PGTBL_SIZE_512KB:
790 gtt_size = 512;
f16c0bab 791 break;
a904aa53
FT
792 case AGP_I965_PGTBL_SIZE_1MB:
793 gtt_size = 1024;
fdc3c5be 794 break;
a904aa53
FT
795 case AGP_I965_PGTBL_SIZE_2MB:
796 gtt_size = 2048;
797 break;
798 case AGP_I965_PGTBL_SIZE_1_5MB:
799 gtt_size = 1024 + 512;
f16c0bab 800 break;
fdc3c5be 801 default:
a904aa53
FT
802 device_printf(dev, "Bad PGTBL size\n");
803 return (EINVAL);
fdc3c5be 804 }
a904aa53
FT
805 break;
806 case CHIP_G33:
807 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
808 switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
809 case AGP_G33_MGGC_GGMS_SIZE_1M:
810 gtt_size = 1024;
f16c0bab 811 break;
a904aa53
FT
812 case AGP_G33_MGGC_GGMS_SIZE_2M:
813 gtt_size = 2048;
ab5a0ec8
MD
814 break;
815 default:
a904aa53
FT
816 device_printf(dev, "Bad PGTBL size\n");
817 return (EINVAL);
ab5a0ec8 818 }
a904aa53
FT
819 break;
820 case CHIP_IGD:
821 case CHIP_G4X:
822 gtt_size = 0;
823 break;
824 default:
825 device_printf(dev, "Bad chiptype\n");
826 return (EINVAL);
827 }
f16c0bab 828
a904aa53
FT
829 /* GCC1 is called MGGC on i915+ */
830 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
831 switch (gcc1 & AGP_I855_GCC1_GMS) {
832 case AGP_I855_GCC1_GMS_STOLEN_1M:
833 stolen = 1024;
834 break;
835 case AGP_I855_GCC1_GMS_STOLEN_4M:
836 stolen = 4 * 1024;
837 break;
838 case AGP_I855_GCC1_GMS_STOLEN_8M:
839 stolen = 8 * 1024;
840 break;
841 case AGP_I855_GCC1_GMS_STOLEN_16M:
842 stolen = 16 * 1024;
843 break;
844 case AGP_I855_GCC1_GMS_STOLEN_32M:
845 stolen = 32 * 1024;
846 break;
847 case AGP_I915_GCC1_GMS_STOLEN_48M:
848 stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
849 break;
850 case AGP_I915_GCC1_GMS_STOLEN_64M:
851 stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
852 break;
853 case AGP_G33_GCC1_GMS_STOLEN_128M:
854 stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
855 break;
856 case AGP_G33_GCC1_GMS_STOLEN_256M:
857 stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
858 break;
859 case AGP_G4X_GCC1_GMS_STOLEN_96M:
860 if (sc->match->driver->chiptype == CHIP_I965 ||
861 sc->match->driver->chiptype == CHIP_G4X)
862 stolen = 96 * 1024;
863 else
864 stolen = 0;
865 break;
866 case AGP_G4X_GCC1_GMS_STOLEN_160M:
867 if (sc->match->driver->chiptype == CHIP_I965 ||
868 sc->match->driver->chiptype == CHIP_G4X)
869 stolen = 160 * 1024;
870 else
871 stolen = 0;
872 break;
873 case AGP_G4X_GCC1_GMS_STOLEN_224M:
874 if (sc->match->driver->chiptype == CHIP_I965 ||
875 sc->match->driver->chiptype == CHIP_G4X)
876 stolen = 224 * 1024;
877 else
878 stolen = 0;
879 break;
880 case AGP_G4X_GCC1_GMS_STOLEN_352M:
881 if (sc->match->driver->chiptype == CHIP_I965 ||
882 sc->match->driver->chiptype == CHIP_G4X)
883 stolen = 352 * 1024;
884 else
885 stolen = 0;
886 break;
887 default:
888 device_printf(dev,
889 "unknown memory configuration, disabling (GCC1 %x)\n",
890 gcc1);
891 return (EINVAL);
892 }
f16c0bab 893
a904aa53
FT
894 gtt_size += 4;
895 sc->stolen_size = stolen * 1024;
896 sc->stolen = (stolen - gtt_size) * 1024 / 4096;
984263bc 897
a904aa53
FT
898 return (0);
899}
ab5a0ec8 900
a904aa53
FT
901static int
902agp_sb_get_stolen_size(device_t dev)
903{
904 struct agp_i810_softc *sc;
905 uint16_t gmch_ctl;
906
907 sc = device_get_softc(dev);
7414ebeb
MD
908 gmch_ctl = pci_read_config(dev, AGP_SNB_GCC1, 2);
909
a904aa53
FT
910 switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) {
911 case AGP_SNB_GMCH_GMS_STOLEN_32M:
912 sc->stolen_size = 32 * 1024 * 1024;
913 break;
914 case AGP_SNB_GMCH_GMS_STOLEN_64M:
915 sc->stolen_size = 64 * 1024 * 1024;
916 break;
917 case AGP_SNB_GMCH_GMS_STOLEN_96M:
918 sc->stolen_size = 96 * 1024 * 1024;
919 break;
920 case AGP_SNB_GMCH_GMS_STOLEN_128M:
921 sc->stolen_size = 128 * 1024 * 1024;
922 break;
923 case AGP_SNB_GMCH_GMS_STOLEN_160M:
924 sc->stolen_size = 160 * 1024 * 1024;
925 break;
926 case AGP_SNB_GMCH_GMS_STOLEN_192M:
927 sc->stolen_size = 192 * 1024 * 1024;
928 break;
929 case AGP_SNB_GMCH_GMS_STOLEN_224M:
930 sc->stolen_size = 224 * 1024 * 1024;
931 break;
932 case AGP_SNB_GMCH_GMS_STOLEN_256M:
933 sc->stolen_size = 256 * 1024 * 1024;
934 break;
935 case AGP_SNB_GMCH_GMS_STOLEN_288M:
936 sc->stolen_size = 288 * 1024 * 1024;
937 break;
938 case AGP_SNB_GMCH_GMS_STOLEN_320M:
939 sc->stolen_size = 320 * 1024 * 1024;
940 break;
941 case AGP_SNB_GMCH_GMS_STOLEN_352M:
942 sc->stolen_size = 352 * 1024 * 1024;
943 break;
944 case AGP_SNB_GMCH_GMS_STOLEN_384M:
945 sc->stolen_size = 384 * 1024 * 1024;
946 break;
947 case AGP_SNB_GMCH_GMS_STOLEN_416M:
948 sc->stolen_size = 416 * 1024 * 1024;
949 break;
950 case AGP_SNB_GMCH_GMS_STOLEN_448M:
951 sc->stolen_size = 448 * 1024 * 1024;
952 break;
953 case AGP_SNB_GMCH_GMS_STOLEN_480M:
954 sc->stolen_size = 480 * 1024 * 1024;
955 break;
956 case AGP_SNB_GMCH_GMS_STOLEN_512M:
957 sc->stolen_size = 512 * 1024 * 1024;
958 break;
fdc3c5be 959 }
a904aa53
FT
960 sc->stolen = (sc->stolen_size - 4) / 4096;
961 return (0);
962}
963
a904aa53
FT
964static int
965agp_i915_get_gtt_mappable_entries(device_t dev)
966{
967 struct agp_i810_softc *sc;
968 uint32_t ap;
969
970 sc = device_get_softc(dev);
971 ap = AGP_GET_APERTURE(dev);
972 sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
973 return (0);
974}
975
976static int
977agp_i810_get_gtt_total_entries(device_t dev)
978{
979 struct agp_i810_softc *sc;
980
981 sc = device_get_softc(dev);
982 sc->gtt_total_entries = sc->gtt_mappable_entries;
983 return (0);
984}
fdc3c5be 985
a904aa53
FT
986static int
987agp_i965_get_gtt_total_entries(device_t dev)
988{
989 struct agp_i810_softc *sc;
990 uint32_t pgetbl_ctl;
991 int error;
992
993 sc = device_get_softc(dev);
994 error = 0;
995 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
996 switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
997 case AGP_I810_PGTBL_SIZE_128KB:
998 sc->gtt_total_entries = 128 * 1024 / 4;
999 break;
1000 case AGP_I810_PGTBL_SIZE_256KB:
1001 sc->gtt_total_entries = 256 * 1024 / 4;
1002 break;
1003 case AGP_I810_PGTBL_SIZE_512KB:
1004 sc->gtt_total_entries = 512 * 1024 / 4;
1005 break;
1006 /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
1007 case AGP_I810_PGTBL_SIZE_1MB:
1008 sc->gtt_total_entries = 1024 * 1024 / 4;
1009 break;
1010 case AGP_I810_PGTBL_SIZE_2MB:
1011 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1012 break;
1013 case AGP_I810_PGTBL_SIZE_1_5MB:
1014 sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
1015 break;
1016 default:
1017 device_printf(dev, "Unknown page table size\n");
1018 error = ENXIO;
1019 }
1020 return (error);
1021}
1022
1023static void
1024agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
1025{
1026 struct agp_i810_softc *sc;
1027 uint32_t pgetbl_ctl, pgetbl_ctl2;
1028
1029 sc = device_get_softc(dev);
1030
1031 /* Disable per-process page table. */
1032 pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
1033 pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
1034 bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
1035
1036 /* Write the new ggtt size. */
1037 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1038 pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
1039 pgetbl_ctl |= sz;
1040 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
1041}
1042
1043static int
1044agp_gen5_get_gtt_total_entries(device_t dev)
1045{
1046 struct agp_i810_softc *sc;
1047 uint16_t gcc1;
1048
1049 sc = device_get_softc(dev);
1050
1051 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1052 switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
1053 case AGP_G4x_GCC1_SIZE_1M:
1054 case AGP_G4x_GCC1_SIZE_VT_1M:
1055 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
1056 break;
1057 case AGP_G4x_GCC1_SIZE_VT_1_5M:
1058 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
1059 break;
1060 case AGP_G4x_GCC1_SIZE_2M:
1061 case AGP_G4x_GCC1_SIZE_VT_2M:
1062 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
1063 break;
1064 default:
1065 device_printf(dev, "Unknown page table size\n");
1066 return (ENXIO);
1067 }
1068
1069 return (agp_i965_get_gtt_total_entries(dev));
1070}
1071
1072static int
1073agp_sb_get_gtt_total_entries(device_t dev)
1074{
1075 struct agp_i810_softc *sc;
1076 uint16_t gcc1;
1077
1078 sc = device_get_softc(dev);
1079
7414ebeb 1080 gcc1 = pci_read_config(dev, AGP_SNB_GCC1, 2);
a904aa53
FT
1081 switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) {
1082 default:
1083 case AGP_SNB_GTT_SIZE_0M:
1084 kprintf("Bad GTT size mask: 0x%04x\n", gcc1);
1085 return (ENXIO);
1086 case AGP_SNB_GTT_SIZE_1M:
1087 sc->gtt_total_entries = 1024 * 1024 / 4;
1088 break;
1089 case AGP_SNB_GTT_SIZE_2M:
1090 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1091 break;
1092 }
1093 return (0);
1094}
1095
a904aa53
FT
1096static int
1097agp_i830_install_gatt(device_t dev)
1098{
1099 struct agp_i810_softc *sc;
1100 uint32_t pgtblctl;
1101
1102 sc = device_get_softc(dev);
1103
1104 /*
1105 * The i830 automatically initializes the 128k gatt on boot.
1106 * GATT address is already in there, make sure it's enabled.
1107 */
1108 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1109 pgtblctl |= 1;
1110 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
1111
1112 sc->gatt->ag_physical = pgtblctl & ~1;
1113 return (0);
1114}
1115
7414ebeb
MD
1116static int
1117agp_sb_install_gatt(device_t dev)
1118{
1119 struct agp_i810_softc *sc;
1120 uint32_t pgtblctl;
1121
1122 sc = device_get_softc(dev);
1123
1124 /*
1125 * The i830 automatically initializes the 128k gatt on boot.
1126 * GATT address is already in there, make sure it's enabled.
1127 */
1128 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1129 pgtblctl |= 1;
1130 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
1131
1132 sc->gatt->ag_physical = pgtblctl & ~1;
1133 return (0);
1134}
1135
a904aa53
FT
1136static int
1137agp_i810_attach(device_t dev)
1138{
1139 struct agp_i810_softc *sc;
1140 int error;
1141
1142 sc = device_get_softc(dev);
1143 sc->bdev = agp_i810_find_bridge(dev);
1144 if (sc->bdev == NULL)
1145 return (ENOENT);
1146
1147 sc->match = agp_i810_match(dev);
1148
1149 agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ?
1150 AGP_APBASE : AGP_I915_GMADR);
1151 error = agp_generic_attach(dev);
1152 if (error)
1153 return (error);
1154
1155 if (ptoa((vm_paddr_t)Maxmem) >
1156 (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
1157 device_printf(dev, "agp_i810 does not support physical "
1158 "memory above %ju.\n", (uintmax_t)(1ULL <<
1159 sc->match->driver->busdma_addr_mask_sz) - 1);
1160 return (ENOENT);
1161 }
1162
1163 if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) {
1164 agp_generic_detach(dev);
1165 return (ENODEV);
1166 }
1167
1168 sc->initial_aperture = AGP_GET_APERTURE(dev);
1169 sc->gatt = kmalloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK);
1170 sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
1171
1172 if ((error = sc->match->driver->get_stolen_size(dev)) != 0 ||
1173 (error = sc->match->driver->install_gatt(dev)) != 0 ||
1174 (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 ||
1175 (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 ||
1176 (error = sc->match->driver->chipset_flush_setup(dev)) != 0) {
1177 bus_release_resources(dev, sc->match->driver->res_spec,
1178 sc->sc_res);
1179 kfree(sc->gatt, M_AGP);
1180 agp_generic_detach(dev);
1181 return (error);
1182 }
1183
1184 intel_agp = dev;
7f9ec87c
FT
1185 device_printf(dev, "aperture size is %dM",
1186 sc->initial_aperture / 1024 / 1024);
1187 if (sc->stolen > 0)
1188 kprintf(", detected %dk stolen memory\n", sc->stolen * 4);
1189 else
1190 kprintf("\n");
a904aa53
FT
1191 if (bootverbose) {
1192 sc->match->driver->dump_regs(dev);
1193 device_printf(dev, "Mappable GTT entries: %d\n",
1194 sc->gtt_mappable_entries);
1195 device_printf(dev, "Total GTT entries: %d\n",
1196 sc->gtt_total_entries);
1197 }
1198 return (0);
1199}
7f9ec87c 1200
a904aa53
FT
1201static void
1202agp_i830_deinstall_gatt(device_t dev)
1203{
1204 struct agp_i810_softc *sc;
1205 unsigned int pgtblctl;
1206
1207 sc = device_get_softc(dev);
1208 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1209 pgtblctl &= ~1;
1210 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
984263bc
MD
1211}
1212
7414ebeb
MD
1213static void
1214agp_sb_deinstall_gatt(device_t dev)
1215{
1216 struct agp_i810_softc *sc;
1217 unsigned int pgtblctl;
1218
1219 sc = device_get_softc(dev);
1220 if (sc->sc_res[0]) {
1221 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1222 pgtblctl &= ~1;
1223 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
1224 }
1225}
1226
984263bc
MD
1227static int
1228agp_i810_detach(device_t dev)
1229{
a904aa53 1230 struct agp_i810_softc *sc;
984263bc 1231
a904aa53 1232 sc = device_get_softc(dev);
67e2dc5d 1233 agp_free_cdev(dev);
984263bc
MD
1234
1235 /* Clear the GATT base. */
a904aa53
FT
1236 sc->match->driver->deinstall_gatt(dev);
1237
1238 sc->match->driver->chipset_flush_teardown(dev);
984263bc
MD
1239
1240 /* Put the aperture back the way it started. */
1241 AGP_SET_APERTURE(dev, sc->initial_aperture);
1242
efda3bd0 1243 kfree(sc->gatt, M_AGP);
a904aa53 1244 bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res);
67e2dc5d 1245 agp_free_res(dev);
984263bc 1246
a904aa53 1247 return (0);
984263bc
MD
1248}
1249
2f1d30c1
HT
1250static int
1251agp_i810_resume(device_t dev)
1252{
1253 struct agp_i810_softc *sc;
1254 sc = device_get_softc(dev);
1255
1256 AGP_SET_APERTURE(dev, sc->initial_aperture);
1257
1258 /* Install the GATT. */
1259 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
1260 sc->gatt->ag_physical | 1);
1261
1262 return (bus_generic_resume(dev));
1263}
1264
fdc3c5be
HT
1265/**
1266 * Sets the PCI resource size of the aperture on i830-class and below chipsets,
1267 * while returning failure on later chipsets when an actual change is
1268 * requested.
1269 *
1270 * This whole function is likely bogus, as the kernel would probably need to
1271 * reconfigure the placement of the AGP aperture if a larger size is requested,
1272 * which doesn't happen currently.
1273 */
a904aa53
FT
1274
1275static int
1276agp_i915_set_aperture(device_t dev, u_int32_t aperture)
1277{
984263bc 1278
a904aa53
FT
1279 return (agp_generic_set_aperture(dev, aperture));
1280}
1281
1282static int
1283agp_i810_method_set_aperture(device_t dev, u_int32_t aperture)
1284{
1285 struct agp_i810_softc *sc;
1286
1287 sc = device_get_softc(dev);
1288 return (sc->match->driver->set_aperture(dev, aperture));
984263bc
MD
1289}
1290
fdc3c5be 1291/**
a904aa53
FT
1292 * Writes a GTT entry mapping the page at the given offset from the
1293 * beginning of the aperture to the given physical address. Setup the
1294 * caching mode according to flags.
1295 *
1296 * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset
1297 * from corresponding BAR start. For gen 4, offset is 512KB +
1298 * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT.
1299 *
1300 * Also, the bits of the physical page address above 4GB needs to be
1301 * placed into bits 40-32 of PTE.
fdc3c5be 1302 */
a904aa53
FT
1303static void
1304agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1305 int flags)
1306{
1307 uint32_t pte;
1308
1309 pte = (u_int32_t)physical | I810_PTE_VALID;
1310 if (flags == AGP_USER_CACHED_MEMORY)
1311 pte |= I830_PTE_SYSTEM_CACHED;
99e9e211 1312
a904aa53
FT
1313 agp_i915_write_gtt(dev, index, pte);
1314}
1315
1316static void
1317agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte)
1318{
1319 struct agp_i810_softc *sc;
1320
1321 sc = device_get_softc(dev);
7414ebeb 1322 bus_write_4(sc->sc_res[0], index * 4, pte);
a904aa53
FT
1323}
1324
1325static void
1326agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1327 int flags)
1328{
1329 uint32_t pte;
1330
1331 pte = (u_int32_t)physical | I810_PTE_VALID;
1332 if (flags == AGP_USER_CACHED_MEMORY)
1333 pte |= I830_PTE_SYSTEM_CACHED;
99e9e211
FT
1334
1335 pte |= (physical >> 28) & 0xf0;
a904aa53
FT
1336 agp_i965_write_gtt(dev, index, pte);
1337}
1338
1339static void
1340agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte)
1341{
1342 struct agp_i810_softc *sc;
1343
1344 sc = device_get_softc(dev);
1345 bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte);
1346}
1347
1348static void
1349agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1350 int flags)
1351{
1352 uint32_t pte;
1353
1354 pte = (u_int32_t)physical | I810_PTE_VALID;
1355 if (flags == AGP_USER_CACHED_MEMORY)
1356 pte |= I830_PTE_SYSTEM_CACHED;
99e9e211
FT
1357
1358 pte |= (physical >> 28) & 0xf0;
a904aa53
FT
1359 agp_g4x_write_gtt(dev, index, pte);
1360}
1361
1362static void
1363agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte)
1364{
1365 struct agp_i810_softc *sc;
1366
1367 sc = device_get_softc(dev);
1368 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
1369}
1370
1371static void
09d2c144
MD
1372agp_sb_install_gtt_pte(device_t dev, u_int index,
1373 vm_offset_t physical, int flags)
a904aa53
FT
1374{
1375 int type_mask, gfdt;
1376 uint32_t pte;
1377
1378 pte = (u_int32_t)physical | I810_PTE_VALID;
1379 type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT;
1380 gfdt = (flags & AGP_USER_CACHED_MEMORY_GFDT) != 0 ? GEN6_PTE_GFDT : 0;
1381
1382 if (type_mask == AGP_USER_MEMORY)
1383 pte |= GEN6_PTE_UNCACHED;
1384 else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
1385 pte |= GEN6_PTE_LLC_MLC | gfdt;
1386 else
1387 pte |= GEN6_PTE_LLC | gfdt;
1388
1389 pte |= (physical & 0x000000ff00000000ull) >> 28;
1390 agp_sb_write_gtt(dev, index, pte);
7414ebeb
MD
1391}
1392
a904aa53
FT
1393static void
1394agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte)
1395{
1396 struct agp_i810_softc *sc;
1397
1398 sc = device_get_softc(dev);
1399 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
1400}
1401
1402static int
1403agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
fdc3c5be
HT
1404{
1405 struct agp_i810_softc *sc = device_get_softc(dev);
a904aa53 1406 u_int index;
fdc3c5be 1407
a904aa53
FT
1408 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
1409 device_printf(dev, "failed: offset is 0x%08jx, "
1410 "shift is %d, entries is %d\n", (intmax_t)offset,
1411 AGP_PAGE_SHIFT, sc->gatt->ag_entries);
1412 return (EINVAL);
1413 }
1414 index = offset >> AGP_PAGE_SHIFT;
1415 if (sc->stolen != 0 && index < sc->stolen) {
1416 device_printf(dev, "trying to bind into stolen memory\n");
1417 return (EINVAL);
fdc3c5be 1418 }
a904aa53
FT
1419 sc->match->driver->install_gtt_pte(dev, index, physical, 0);
1420 return (0);
1421}
fdc3c5be 1422
a904aa53
FT
1423static int
1424agp_i810_unbind_page(device_t dev, vm_offset_t offset)
1425{
1426 struct agp_i810_softc *sc;
1427 u_int index;
1428
1429 sc = device_get_softc(dev);
1430 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
1431 return (EINVAL);
1432 index = offset >> AGP_PAGE_SHIFT;
1433 if (sc->stolen != 0 && index < sc->stolen) {
1434 device_printf(dev, "trying to unbind from stolen memory\n");
1435 return (EINVAL);
fdc3c5be 1436 }
a904aa53
FT
1437 sc->match->driver->install_gtt_pte(dev, index, 0, 0);
1438 return (0);
1439}
1440
09d2c144
MD
1441static void
1442agp_i915_sync_gtt_pte(device_t dev, u_int index)
a904aa53
FT
1443{
1444 struct agp_i810_softc *sc;
fdc3c5be 1445
a904aa53 1446 sc = device_get_softc(dev);
09d2c144 1447 bus_read_4(sc->sc_res[1], index * 4);
984263bc
MD
1448}
1449
09d2c144
MD
1450static void
1451agp_i965_sync_gtt_pte(device_t dev, u_int index)
a904aa53
FT
1452{
1453 struct agp_i810_softc *sc;
984263bc 1454
a904aa53 1455 sc = device_get_softc(dev);
09d2c144 1456 bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024));
a904aa53
FT
1457}
1458
09d2c144
MD
1459static void
1460agp_g4x_sync_gtt_pte(device_t dev, u_int index)
a904aa53
FT
1461{
1462 struct agp_i810_softc *sc;
fdc3c5be 1463
a904aa53 1464 sc = device_get_softc(dev);
09d2c144 1465 bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024));
984263bc
MD
1466}
1467
1468/*
1469 * Writing via memory mapped registers already flushes all TLBs.
1470 */
1471static void
1472agp_i810_flush_tlb(device_t dev)
1473{
1474}
1475
1476static int
1477agp_i810_enable(device_t dev, u_int32_t mode)
1478{
1479
a904aa53 1480 return (0);
984263bc
MD
1481}
1482
1483static struct agp_memory *
1484agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
1485{
a904aa53 1486 struct agp_i810_softc *sc;
984263bc 1487 struct agp_memory *mem;
a904aa53 1488 vm_page_t m;
984263bc 1489
a904aa53 1490 sc = device_get_softc(dev);
984263bc 1491
a904aa53
FT
1492 if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
1493 sc->agp.as_allocated + size > sc->agp.as_maxmem)
1494 return (0);
984263bc
MD
1495
1496 if (type == 1) {
1497 /*
1498 * Mapping local DRAM into GATT.
1499 */
a904aa53
FT
1500 if (sc->match->driver->chiptype != CHIP_I810)
1501 return (0);
984263bc 1502 if (size != sc->dcache_size)
a904aa53 1503 return (0);
984263bc
MD
1504 } else if (type == 2) {
1505 /*
fdc3c5be
HT
1506 * Type 2 is the contiguous physical memory type, that hands
1507 * back a physical address. This is used for cursors on i810.
1508 * Hand back as many single pages with physical as the user
1509 * wants, but only allow one larger allocation (ARGB cursor)
1510 * for simplicity.
984263bc 1511 */
fdc3c5be
HT
1512 if (size != AGP_PAGE_SIZE) {
1513 if (sc->argb_cursor != NULL)
a904aa53 1514 return (0);
fdc3c5be
HT
1515
1516 /* Allocate memory for ARGB cursor, if we can. */
1517 sc->argb_cursor = contigmalloc(size, M_AGP,
1518 0, 0, ~0, PAGE_SIZE, 0);
1519 if (sc->argb_cursor == NULL)
a904aa53 1520 return (0);
fdc3c5be 1521 }
984263bc
MD
1522 }
1523
efda3bd0 1524 mem = kmalloc(sizeof *mem, M_AGP, M_INTWAIT);
984263bc
MD
1525 mem->am_id = sc->agp.as_nextid++;
1526 mem->am_size = size;
1527 mem->am_type = type;
fdc3c5be 1528 if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
984263bc 1529 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
a904aa53 1530 atop(round_page(size)));
984263bc
MD
1531 else
1532 mem->am_obj = 0;
1533
1534 if (type == 2) {
fdc3c5be
HT
1535 if (size == AGP_PAGE_SIZE) {
1536 /*
1537 * Allocate and wire down the page now so that we can
1538 * get its physical address.
1539 */
a904aa53 1540 VM_OBJECT_LOCK(mem->am_obj);
d2d8515b
MD
1541 m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NORMAL |
1542 VM_ALLOC_ZERO |
1543 VM_ALLOC_RETRY);
fdc3c5be 1544 vm_page_wire(m);
a904aa53 1545 VM_OBJECT_UNLOCK(mem->am_obj);
fdc3c5be
HT
1546 mem->am_physical = VM_PAGE_TO_PHYS(m);
1547 vm_page_wakeup(m);
1548 } else {
1549 /* Our allocation is already nicely wired down for us.
1550 * Just grab the physical address.
1551 */
1552 mem->am_physical = vtophys(sc->argb_cursor);
1553 }
a904aa53 1554 } else
984263bc 1555 mem->am_physical = 0;
984263bc
MD
1556
1557 mem->am_offset = 0;
1558 mem->am_is_bound = 0;
1559 TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
1560 sc->agp.as_allocated += size;
1561
a904aa53 1562 return (mem);
984263bc
MD
1563}
1564
1565static int
1566agp_i810_free_memory(device_t dev, struct agp_memory *mem)
1567{
a904aa53 1568 struct agp_i810_softc *sc;
984263bc
MD
1569
1570 if (mem->am_is_bound)
a904aa53
FT
1571 return (EBUSY);
1572
1573 sc = device_get_softc(dev);
984263bc
MD
1574
1575 if (mem->am_type == 2) {
fdc3c5be
HT
1576 if (mem->am_size == AGP_PAGE_SIZE) {
1577 /*
1578 * Unwire the page which we wired in alloc_memory.
1579 */
77912481 1580 vm_page_t m;
b12defdc
MD
1581
1582 vm_object_hold(mem->am_obj);
1583 m = vm_page_lookup_busy_wait(mem->am_obj, 0,
1584 FALSE, "agppg");
1585 vm_object_drop(mem->am_obj);
fdc3c5be 1586 vm_page_unwire(m, 0);
b12defdc 1587 vm_page_wakeup(m);
fdc3c5be
HT
1588 } else {
1589 contigfree(sc->argb_cursor, mem->am_size, M_AGP);
1590 sc->argb_cursor = NULL;
1591 }
984263bc
MD
1592 }
1593
1594 sc->agp.as_allocated -= mem->am_size;
1595 TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
1596 if (mem->am_obj)
1597 vm_object_deallocate(mem->am_obj);
efda3bd0 1598 kfree(mem, M_AGP);
a904aa53 1599 return (0);
984263bc
MD
1600}
1601
1602static int
a904aa53 1603agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
984263bc 1604{
a904aa53 1605 struct agp_i810_softc *sc;
984263bc
MD
1606 vm_offset_t i;
1607
fdc3c5be 1608 /* Do some sanity checks first. */
7f9ec87c 1609 if ((offset & (AGP_PAGE_SIZE - 1)) != 0 ||
fdc3c5be
HT
1610 offset + mem->am_size > AGP_GET_APERTURE(dev)) {
1611 device_printf(dev, "binding memory at bad offset %#x\n",
1612 (int)offset);
a904aa53 1613 return (EINVAL);
fdc3c5be
HT
1614 }
1615
a904aa53 1616 sc = device_get_softc(dev);
fdc3c5be
HT
1617 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
1618 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
1619 if (mem->am_is_bound) {
1620 lockmgr(&sc->agp.as_lock, LK_RELEASE);
1621 return EINVAL;
1622 }
1623 /* The memory's already wired down, just stick it in the GTT. */
1624 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
a904aa53
FT
1625 sc->match->driver->install_gtt_pte(dev, (offset + i) >>
1626 AGP_PAGE_SHIFT, mem->am_physical + i, 0);
fdc3c5be
HT
1627 }
1628 agp_flush_cache();
1629 mem->am_offset = offset;
1630 mem->am_is_bound = 1;
1631 lockmgr(&sc->agp.as_lock, LK_RELEASE);
a904aa53 1632 return (0);
fdc3c5be
HT
1633 }
1634
984263bc 1635 if (mem->am_type != 1)
a904aa53 1636 return (agp_generic_bind_memory(dev, mem, offset));
984263bc 1637
a904aa53
FT
1638 /*
1639 * Mapping local DRAM into GATT.
1640 */
1641 if (sc->match->driver->chiptype != CHIP_I810)
1642 return (EINVAL);
1643 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
fdc3c5be
HT
1644 bus_write_4(sc->sc_res[0],
1645 AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
984263bc 1646
a904aa53 1647 return (0);
984263bc
MD
1648}
1649
1650static int
1651agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
1652{
a904aa53 1653 struct agp_i810_softc *sc;
984263bc
MD
1654 vm_offset_t i;
1655
a904aa53
FT
1656 sc = device_get_softc(dev);
1657
fdc3c5be
HT
1658 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
1659 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
1660 if (!mem->am_is_bound) {
1661 lockmgr(&sc->agp.as_lock, LK_RELEASE);
a904aa53 1662 return (EINVAL);
fdc3c5be
HT
1663 }
1664
1665 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
a904aa53
FT
1666 sc->match->driver->install_gtt_pte(dev,
1667 (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
fdc3c5be
HT
1668 }
1669 agp_flush_cache();
1670 mem->am_is_bound = 0;
1671 lockmgr(&sc->agp.as_lock, LK_RELEASE);
a904aa53 1672 return (0);
fdc3c5be
HT
1673 }
1674
984263bc 1675 if (mem->am_type != 1)
a904aa53 1676 return (agp_generic_unbind_memory(dev, mem));
984263bc 1677
a904aa53
FT
1678 if (sc->match->driver->chiptype != CHIP_I810)
1679 return (EINVAL);
fdc3c5be 1680 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
a904aa53
FT
1681 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
1682 0, 0);
fdc3c5be 1683 }
a904aa53 1684 return (0);
984263bc
MD
1685}
1686
1687static device_method_t agp_i810_methods[] = {
1688 /* Device interface */
fdc3c5be 1689 DEVMETHOD(device_identify, agp_i810_identify),
984263bc
MD
1690 DEVMETHOD(device_probe, agp_i810_probe),
1691 DEVMETHOD(device_attach, agp_i810_attach),
1692 DEVMETHOD(device_detach, agp_i810_detach),
2f1d30c1
HT
1693 DEVMETHOD(device_suspend, bus_generic_suspend),
1694 DEVMETHOD(device_resume, agp_i810_resume),
984263bc
MD
1695
1696 /* AGP interface */
fdc3c5be 1697 DEVMETHOD(agp_get_aperture, agp_generic_get_aperture),
a904aa53 1698 DEVMETHOD(agp_set_aperture, agp_i810_method_set_aperture),
984263bc
MD
1699 DEVMETHOD(agp_bind_page, agp_i810_bind_page),
1700 DEVMETHOD(agp_unbind_page, agp_i810_unbind_page),
1701 DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb),
1702 DEVMETHOD(agp_enable, agp_i810_enable),
1703 DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory),
1704 DEVMETHOD(agp_free_memory, agp_i810_free_memory),
1705 DEVMETHOD(agp_bind_memory, agp_i810_bind_memory),
1706 DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory),
a904aa53 1707 DEVMETHOD(agp_chipset_flush, agp_intel_gtt_chipset_flush),
984263bc 1708
d3c9c58e 1709 DEVMETHOD_END
984263bc
MD
1710};
1711
1712static driver_t agp_i810_driver = {
1713 "agp",
1714 agp_i810_methods,
1715 sizeof(struct agp_i810_softc),
1716};
1717
1718static devclass_t agp_devclass;
1719
aa2b9d05 1720DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, NULL, NULL);
f7841f3c
MD
1721MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
1722MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
a904aa53
FT
1723
1724extern vm_page_t bogus_page;
1725
1726void
1727agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
1728{
1729 struct agp_i810_softc *sc;
1730 u_int i;
1731
1732 sc = device_get_softc(dev);
1733 for (i = 0; i < num_entries; i++)
1734 sc->match->driver->install_gtt_pte(dev, first_entry + i,
1735 VM_PAGE_TO_PHYS(bogus_page), 0);
09d2c144 1736 sc->match->driver->sync_gtt_pte(dev, first_entry + num_entries - 1);
a904aa53
FT
1737}
1738
1739void
1740agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
1741 vm_page_t *pages, u_int flags)
1742{
1743 struct agp_i810_softc *sc;
1744 u_int i;
1745
1746 sc = device_get_softc(dev);
1747 for (i = 0; i < num_entries; i++) {
1748 KKASSERT(pages[i]->valid == VM_PAGE_BITS_ALL);
1749 KKASSERT(pages[i]->wire_count > 0);
1750 sc->match->driver->install_gtt_pte(dev, first_entry + i,
1751 VM_PAGE_TO_PHYS(pages[i]), flags);
1752 }
09d2c144 1753 sc->match->driver->sync_gtt_pte(dev, first_entry + num_entries - 1);
a904aa53
FT
1754}
1755
1756struct intel_gtt
1757agp_intel_gtt_get(device_t dev)
1758{
1759 struct agp_i810_softc *sc;
1760 struct intel_gtt res;
1761
1762 sc = device_get_softc(dev);
1763 res.stolen_size = sc->stolen_size;
1764 res.gtt_total_entries = sc->gtt_total_entries;
1765 res.gtt_mappable_entries = sc->gtt_mappable_entries;
1766 res.do_idle_maps = 0;
1767 res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
1768 return (res);
1769}
1770
1771static int
1772agp_i810_chipset_flush_setup(device_t dev)
1773{
1774
1775 return (0);
1776}
1777
1778static void
1779agp_i810_chipset_flush_teardown(device_t dev)
1780{
1781
1782 /* Nothing to do. */
1783}
1784
1785static void
1786agp_i810_chipset_flush(device_t dev)
1787{
1788
1789 /* Nothing to do. */
1790}
1791
a904aa53
FT
1792static int
1793agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
1794{
1795 struct agp_i810_softc *sc;
1796 device_t vga;
1797
1798 sc = device_get_softc(dev);
1799 vga = device_get_parent(dev);
1800 sc->sc_flush_page_rid = 100;
1801 sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
1802 SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
1803 RF_ACTIVE, -1);
1804 if (sc->sc_flush_page_res == NULL) {
1805 device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
1806 (uintmax_t)start);
1807 return (EINVAL);
1808 }
1809 sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
1810 if (bootverbose) {
1811 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
1812 (uintmax_t)rman_get_start(sc->sc_flush_page_res),
1813 sc->sc_flush_page_vaddr);
1814 }
1815 return (0);
1816}
1817
1818static void
1819agp_i915_chipset_flush_free_page(device_t dev)
1820{
1821 struct agp_i810_softc *sc;
1822 device_t vga;
1823
1824 sc = device_get_softc(dev);
1825 vga = device_get_parent(dev);
1826 if (sc->sc_flush_page_res == NULL)
1827 return;
1828 BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
1829 sc->sc_flush_page_rid, sc->sc_flush_page_res);
1830 BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
1831 sc->sc_flush_page_rid, sc->sc_flush_page_res);
1832}
1833
1834static int
1835agp_i915_chipset_flush_setup(device_t dev)
1836{
1837 struct agp_i810_softc *sc;
1838 uint32_t temp;
1839 int error;
1840
1841 sc = device_get_softc(dev);
1842 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
1843 if ((temp & 1) != 0) {
1844 temp &= ~1;
1845 if (bootverbose)
1846 device_printf(dev,
1847 "Found already configured flush page at 0x%jx\n",
1848 (uintmax_t)temp);
1849 sc->sc_bios_allocated_flush_page = 1;
1850 /*
1851 * In the case BIOS initialized the flush pointer (?)
1852 * register, expect that BIOS also set up the resource
1853 * for the page.
1854 */
1855 error = agp_i915_chipset_flush_alloc_page(dev, temp,
1856 temp + PAGE_SIZE - 1);
1857 if (error != 0)
1858 return (error);
1859 } else {
1860 sc->sc_bios_allocated_flush_page = 0;
1861 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
1862 if (error != 0)
1863 return (error);
1864 temp = rman_get_start(sc->sc_flush_page_res);
1865 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
1866 }
1867 return (0);
1868}
1869
1870static void
1871agp_i915_chipset_flush_teardown(device_t dev)
1872{
1873 struct agp_i810_softc *sc;
1874 uint32_t temp;
1875
1876 sc = device_get_softc(dev);
1877 if (sc->sc_flush_page_res == NULL)
1878 return;
1879 if (!sc->sc_bios_allocated_flush_page) {
1880 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
1881 temp &= ~1;
1882 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
1883 }
1884 agp_i915_chipset_flush_free_page(dev);
1885}
1886
1887static int
1888agp_i965_chipset_flush_setup(device_t dev)
1889{
1890 struct agp_i810_softc *sc;
1891 uint64_t temp;
1892 uint32_t temp_hi, temp_lo;
1893 int error;
1894
1895 sc = device_get_softc(dev);
1896
1897 temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
1898 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
1899
1900 if ((temp_lo & 1) != 0) {
1901 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
1902 if (bootverbose)
1903 device_printf(dev,
1904 "Found already configured flush page at 0x%jx\n",
1905 (uintmax_t)temp);
1906 sc->sc_bios_allocated_flush_page = 1;
1907 /*
1908 * In the case BIOS initialized the flush pointer (?)
1909 * register, expect that BIOS also set up the resource
1910 * for the page.
1911 */
1912 error = agp_i915_chipset_flush_alloc_page(dev, temp,
1913 temp + PAGE_SIZE - 1);
1914 if (error != 0)
1915 return (error);
1916 } else {
1917 sc->sc_bios_allocated_flush_page = 0;
1918 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
1919 if (error != 0)
1920 return (error);
1921 temp = rman_get_start(sc->sc_flush_page_res);
1922 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
1923 (temp >> 32) & UINT32_MAX, 4);
1924 pci_write_config(sc->bdev, AGP_I965_IFPADDR,
1925 (temp & UINT32_MAX) | 1, 4);
1926 }
1927 return (0);
1928}
1929
1930static void
1931agp_i965_chipset_flush_teardown(device_t dev)
1932{
1933 struct agp_i810_softc *sc;
1934 uint32_t temp_lo;
1935
1936 sc = device_get_softc(dev);
1937 if (sc->sc_flush_page_res == NULL)
1938 return;
1939 if (!sc->sc_bios_allocated_flush_page) {
1940 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
1941 temp_lo &= ~1;
1942 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
1943 }
1944 agp_i915_chipset_flush_free_page(dev);
1945}
1946
1947static void
1948agp_i915_chipset_flush(device_t dev)
1949{
1950 struct agp_i810_softc *sc;
1951
1952 sc = device_get_softc(dev);
1953 *(uint32_t *)sc->sc_flush_page_vaddr = 1;
1954}
1955
1956int
1957agp_intel_gtt_chipset_flush(device_t dev)
1958{
1959 struct agp_i810_softc *sc;
1960
1961 sc = device_get_softc(dev);
1962 sc->match->driver->chipset_flush(dev);
1963 return (0);
1964}
1965
1966void
1967agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list)
1968{
1969}
1970
1971int
1972agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
1973 struct sglist **sg_list)
1974{
839fbabb 1975#if 0
a904aa53 1976 struct agp_i810_softc *sc;
839fbabb 1977#endif
a904aa53
FT
1978 struct sglist *sg;
1979 int i;
1980#if 0
1981 int error;
1982 bus_dma_tag_t dmat;
1983#endif
1984
1985 if (*sg_list != NULL)
1986 return (0);
839fbabb 1987#if 0
a904aa53 1988 sc = device_get_softc(dev);
839fbabb 1989#endif
a904aa53
FT
1990 sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */);
1991 for (i = 0; i < num_entries; i++) {
1992 sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]);
1993 sg->sg_segs[i].ss_len = PAGE_SIZE;
1994 }
1995
1996#if 0
1997 error = bus_dma_tag_create(bus_get_dma_tag(dev),
1998 1 /* alignment */, 0 /* boundary */,
1999 1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */,
2000 BUS_SPACE_MAXADDR /* highaddr */,
2001 NULL /* filtfunc */, NULL /* filtfuncarg */,
2002 BUS_SPACE_MAXADDR /* maxsize */,
2003 BUS_SPACE_UNRESTRICTED /* nsegments */,
2004 BUS_SPACE_MAXADDR /* maxsegsz */,
2005 0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */,
2006 &dmat);
2007 if (error != 0) {
2008 sglist_free(sg);
2009 return (error);
2010 }
2011 /* XXXKIB */
2012#endif
2013 *sg_list = sg;
2014 return (0);
2015}
2016
2017void
2018agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
2019 u_int first_entry, u_int flags)
2020{
2021 struct agp_i810_softc *sc;
2022 vm_paddr_t spaddr;
2023 size_t slen;
2024 u_int i, j;
2025
2026 sc = device_get_softc(dev);
2027 for (i = j = 0; j < sg_list->sg_nseg; j++) {
2028 spaddr = sg_list->sg_segs[i].ss_paddr;
2029 slen = sg_list->sg_segs[i].ss_len;
2030 for (; slen > 0; i++) {
2031 sc->match->driver->install_gtt_pte(dev, first_entry + i,
2032 spaddr, flags);
2033 spaddr += AGP_PAGE_SIZE;
2034 slen -= AGP_PAGE_SIZE;
2035 }
2036 }
09d2c144 2037 sc->match->driver->sync_gtt_pte(dev, first_entry + i - 1);
a904aa53
FT
2038}
2039
2040void
2041intel_gtt_clear_range(u_int first_entry, u_int num_entries)
2042{
2043
2044 agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
2045}
2046
2047void
2048intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages,
2049 u_int flags)
2050{
2051
2052 agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries,
2053 pages, flags);
2054}
2055
9edbd4a0
FT
2056void intel_gtt_get(size_t *gtt_total, size_t *stolen_size,
2057 phys_addr_t *mappable_base, unsigned long *mappable_end)
a904aa53 2058{
26efd328
FT
2059 struct agp_info ainfo;
2060
bc2fd6c1 2061 intel_private.base = agp_intel_gtt_get(intel_agp);
9edbd4a0
FT
2062
2063 *gtt_total = intel_private.base.gtt_total_entries << PAGE_SHIFT;
2064 *stolen_size = intel_private.base.stolen_size;
26efd328
FT
2065 agp_get_info(intel_agp, &ainfo);
2066 *mappable_base = ainfo.ai_aperture_base;
9edbd4a0 2067 *mappable_end = intel_private.base.gtt_mappable_entries << PAGE_SHIFT;
a904aa53
FT
2068}
2069
2070int
2071intel_gtt_chipset_flush(void)
2072{
2073
2074 return (agp_intel_gtt_chipset_flush(intel_agp));
2075}
2076
2077void
2078intel_gtt_unmap_memory(struct sglist *sg_list)
2079{
2080
2081 agp_intel_gtt_unmap_memory(intel_agp, sg_list);
2082}
2083
2084int
2085intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
2086 struct sglist **sg_list)
2087{
2088
2089 return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries,
2090 sg_list));
2091}
2092
2093void
2094intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry,
2095 u_int flags)
2096{
2097
2098 agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags);
2099}
2100
09d2c144
MD
2101/*
2102 * Only used by gen6
2103 */
2104void
2105intel_gtt_sync_pte(u_int entry)
a904aa53
FT
2106{
2107 struct agp_i810_softc *sc;
2108
2109 sc = device_get_softc(intel_agp);
09d2c144 2110 sc->match->driver->sync_gtt_pte(intel_agp, entry);
a904aa53
FT
2111}
2112
09d2c144
MD
2113/*
2114 * Only used by gen6
2115 */
a904aa53
FT
2116void
2117intel_gtt_write(u_int entry, uint32_t val)
2118{
2119 struct agp_i810_softc *sc;
2120
2121 sc = device_get_softc(intel_agp);
d63cf994 2122 sc->match->driver->write_gtt(intel_agp, entry, val);
a904aa53 2123}