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