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