xref: /titanic_44/usr/src/uts/intel/io/agpmaster/agpmaster.c (revision fdd1ecae0dfe07e6aa8ee90687e2e91c876dc189)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Misc module for AGP master device support
31  */
32 
33 #include <sys/modctl.h>
34 #include <sys/pci.h>
35 #include <sys/stat.h>
36 #include <sys/file.h>
37 #include <sys/types.h>
38 #include <sys/dditypes.h>
39 #include <sys/sunddi.h>
40 #include <sys/agpgart.h>
41 #include <sys/agp/agpdefs.h>
42 #include <sys/agp/agpmaster_io.h>
43 
44 #define	PGTBL_CTL	0x2020	/* Page table control register */
45 #define	I8XX_FB_BAR	1
46 #define	I8XX_MMIO_BAR	2
47 #define	I8XX_PTE_OFFSET	0x10000
48 #define	I915_MMADR	1	/* mem-mapped registers BAR */
49 #define	I915_GMADR	3	/* graphics mem BAR */
50 #define	I915_GTTADDR	4	/* GTT BAR */
51 #define	I965_GTTMMADR	1	/* mem-mapped registers BAR + GTT */
52 #define	I965_GMADR	2	/* graphics mem BAR */
53 /* In 965 1MB GTTMMADR, GTT reside in the latter 512KB */
54 #define	I965_GTT_OFFSET	0x80000
55 #define	GTT_SIZE_MASK	0xe
56 #define	GTT_512KB	(0 << 1)
57 #define	GTT_256KB	(1 << 1)
58 #define	GTT_128KB	(2 << 1)
59 
60 #define	MMIO_BASE(x)	(x)->agpm_data.agpm_gtt.gtt_mmio_base
61 #define	MMIO_HANDLE(x)	(x)->agpm_data.agpm_gtt.gtt_mmio_handle
62 #define	GTT_ADDR(x)	(x)->agpm_data.agpm_gtt.gtt_addr
63 #define	APER_BASE(x)	(x)->agpm_data.agpm_gtt.gtt_info.igd_aperbase
64 
65 #define	AGPM_WRITE(x, off, val) \
66     ddi_put32(MMIO_HANDLE(x), (uint32_t *)(MMIO_BASE(x) + (off)), (val));
67 
68 #define	AGPM_READ(x, off) \
69     ddi_get32(MMIO_HANDLE(x), (uint32_t *)(MMIO_BASE(x) + (off)));
70 
71 #ifdef DEBUG
72 #define	CONFIRM(value) ASSERT(value)
73 #else
74 #define	CONFIRM(value) if (!(value)) return (EINVAL)
75 #endif
76 
77 int agpm_debug = 0;
78 #define	AGPM_DEBUG(args)	if (agpm_debug >= 1) cmn_err args
79 
80 /*
81  * Whether it is a Intel integrated graphics card
82  */
83 #define	IS_IGD(agpmaster) ((agpmaster->agpm_dev_type == DEVICE_IS_I810) || \
84 	(agpmaster->agpm_dev_type == DEVICE_IS_I830))
85 
86 
87 /* Intel 915 and 945 series */
88 #define	IS_INTEL_915(agpmaster) ((agpmaster->agpm_id == INTEL_IGD_915) || \
89 	(agpmaster->agpm_id == INTEL_IGD_915GM) || \
90 	(agpmaster->agpm_id == INTEL_IGD_945) || \
91 	(agpmaster->agpm_id == INTEL_IGD_945GM))
92 
93 /* Intel 965 series */
94 #define	IS_INTEL_965(agpmaster) ((agpmaster->agpm_id == INTEL_IGD_946GZ) || \
95 	(agpmaster->agpm_id == INTEL_IGD_965G1) || \
96 	(agpmaster->agpm_id == INTEL_IGD_965Q) || \
97 	(agpmaster->agpm_id == INTEL_IGD_965G2) || \
98 	(agpmaster->agpm_id == INTEL_IGD_965GM) || \
99 	(agpmaster->agpm_id == INTEL_IGD_965GME))
100 
101 static struct modlmisc modlmisc = {
102 	&mod_miscops, "AGP master interfaces v%I%"
103 };
104 
105 static struct modlinkage modlinkage = {
106 	MODREV_1, (void *)&modlmisc, NULL
107 };
108 
109 static ddi_device_acc_attr_t i8xx_dev_access = {
110 	DDI_DEVICE_ATTR_V0,
111 	DDI_NEVERSWAP_ACC,
112 	DDI_STRICTORDER_ACC
113 };
114 
115 static off_t agpmaster_cap_find(ddi_acc_handle_t);
116 static int detect_i8xx_device(agp_master_softc_t *);
117 static int detect_agp_devcice(agp_master_softc_t *, ddi_acc_handle_t);
118 static int i8xx_add_to_gtt(gtt_impl_t *, igd_gtt_seg_t);
119 static void i8xx_remove_from_gtt(gtt_impl_t *, igd_gtt_seg_t);
120 
121 int
122 _init(void)
123 {
124 	int	err;
125 
126 	if ((err = mod_install(&modlinkage)) != 0)
127 		return (err);
128 
129 	return (0);
130 }
131 
132 int
133 _fini(void)
134 {
135 	int	err;
136 
137 	if ((err = mod_remove(&modlinkage)) != 0)
138 		return (err);
139 
140 	return (0);
141 }
142 
143 int
144 _info(struct modinfo *modinfop)
145 {
146 	return (mod_info(&modlinkage, modinfop));
147 }
148 
149 /*
150  * Minor node is not removed here, since the caller (xx_attach) is
151  * responsible for removing all nodes.
152  */
153 void
154 agpmaster_detach(agp_master_softc_t **master_softcp)
155 {
156 	agp_master_softc_t *master_softc;
157 
158 	ASSERT(master_softcp);
159 	master_softc = *master_softcp;
160 
161 	/* intel integrated device */
162 	if (IS_IGD(master_softc)) {
163 		if (MMIO_HANDLE(master_softc) != NULL) {
164 			ddi_regs_map_free(&MMIO_HANDLE(master_softc));
165 		}
166 	}
167 
168 	kmem_free(master_softc, sizeof (agp_master_softc_t));
169 	master_softc = NULL;
170 
171 	return;
172 
173 }
174 
175 /*
176  * 965 has a fixed GTT table size (512KB), so check to see the actual aperture
177  * size. Aperture size = GTT table size * 1024.
178  */
179 static off_t
180 i965_apersize(agp_master_softc_t *agpmaster)
181 {
182 	off_t apersize;
183 
184 	apersize = AGPM_READ(agpmaster, PGTBL_CTL);
185 	AGPM_DEBUG((CE_NOTE, "i965_apersize: PGTBL_CTL = %lx", apersize));
186 	switch (apersize & GTT_SIZE_MASK) {
187 	case GTT_512KB:
188 		apersize = 512;
189 		break;
190 	case GTT_256KB:
191 		apersize = 256;
192 		break;
193 	case GTT_128KB:
194 		apersize = 128;
195 		break;
196 	default:
197 		AGPM_DEBUG((CE_WARN,
198 		    "i965_apersize: invalid GTT size in PGTBL_CTL"));
199 	}
200 	apersize = MB2BYTES(apersize);
201 	return (apersize);
202 }
203 
204 #define	CHECK_STATUS(status)	\
205     if (status != DDI_SUCCESS) { \
206 	    AGPM_DEBUG((CE_WARN, \
207 		"set_gtt_mmio: regs_map_setup error")); \
208 	    return (-1); \
209 }
210 /*
211  * Set gtt_addr, gtt_mmio_base, igd_apersize, igd_aperbase and igd_devid
212  * according to chipset.
213  */
214 static int
215 set_gtt_mmio(dev_info_t *devi, agp_master_softc_t *agpmaster, ddi_acc_handle_t
216     pci_acc_hdl)
217 {
218 	off_t apersize;
219 	uint32_t value;
220 	off_t conf_off; /* offset in PCI conf space for aperture */
221 	int status;
222 
223 	if (IS_INTEL_965(agpmaster)) {
224 		status = ddi_regs_map_setup(devi, I965_GTTMMADR,
225 		    &MMIO_BASE(agpmaster), 0, 0, &i8xx_dev_access,
226 		    &MMIO_HANDLE(agpmaster));
227 		CHECK_STATUS(status);
228 		GTT_ADDR(agpmaster) = MMIO_BASE(agpmaster) + I965_GTT_OFFSET;
229 
230 		conf_off = I915_CONF_GMADR;
231 		apersize = i965_apersize(agpmaster);
232 		/* make this the last line, to clear follow-up status check */
233 		status = DDI_SUCCESS;
234 
235 	} else if (IS_INTEL_915(agpmaster)) {
236 		status = ddi_regs_map_setup(devi, I915_GTTADDR,
237 		    &GTT_ADDR(agpmaster), 0, 0, &i8xx_dev_access,
238 		    &MMIO_HANDLE(agpmaster));
239 		CHECK_STATUS(status);
240 
241 		status = ddi_regs_map_setup(devi, I915_MMADR,
242 		    &MMIO_BASE(agpmaster), 0, 0, &i8xx_dev_access,
243 		    &MMIO_HANDLE(agpmaster));
244 		CHECK_STATUS(status);
245 
246 		conf_off = I915_CONF_GMADR;
247 		status = ddi_dev_regsize(devi, I915_GMADR, &apersize);
248 	} else {
249 		/* I8XX series */
250 		status = ddi_regs_map_setup(devi, I8XX_MMIO_BAR,
251 		    &MMIO_BASE(agpmaster), 0, 0, &i8xx_dev_access,
252 		    &MMIO_HANDLE(agpmaster));
253 		CHECK_STATUS(status);
254 
255 		GTT_ADDR(agpmaster) = MMIO_BASE(agpmaster) + I8XX_PTE_OFFSET;
256 		conf_off = I8XX_CONF_GMADR;
257 		status = ddi_dev_regsize(devi, I8XX_FB_BAR, &apersize);
258 		CHECK_STATUS(status);
259 	}
260 
261 	/*
262 	 * if memory size is smaller than a certain value, it means
263 	 * the register set number for graphics memory range might
264 	 * be wrong
265 	 */
266 	if (status != DDI_SUCCESS || apersize < 0x400000) {
267 		AGPM_DEBUG((CE_WARN,
268 		    "set_gtt_mmio: ddi_dev_regsize error"));
269 		return (-1);
270 	}
271 
272 	agpmaster->agpm_data.agpm_gtt.gtt_info.igd_apersize =
273 	    BYTES2MB(apersize);
274 
275 	/* get GTT base */
276 	value = pci_config_get32(pci_acc_hdl, conf_off);
277 
278 	APER_BASE(agpmaster) = value & GTT_BASE_MASK;
279 	agpmaster->agpm_data.agpm_gtt.gtt_info.igd_devid =
280 	    agpmaster->agpm_id;
281 	AGPM_DEBUG((CE_NOTE, "set_gtt_mmio: aperbase = %x, apersize = %lx, "
282 	    "gtt_addr = %p, mmio_base = %p", APER_BASE(agpmaster), apersize,
283 	    (void *)GTT_ADDR(agpmaster), (void *)MMIO_BASE(agpmaster)));
284 	return (0);
285 }
286 
287 /*
288  * Try to initialize agp master.
289  * 0 is returned if the device is successfully initialized. AGP master soft
290  * state is returned in master_softcp if needed.
291  * Otherwise -1 is returned and *master_softcp is set to NULL.
292  */
293 int
294 agpmaster_attach(dev_info_t *devi, agp_master_softc_t **master_softcp,
295     ddi_acc_handle_t pci_acc_hdl, minor_t minor)
296 {
297 	int instance;
298 	int status;
299 	agp_master_softc_t *agpmaster;
300 	char buf[80];
301 
302 
303 	ASSERT(pci_acc_hdl);
304 	*master_softcp = NULL;
305 	agpmaster = (agp_master_softc_t *)
306 	    kmem_zalloc(sizeof (agp_master_softc_t), KM_SLEEP);
307 
308 	agpmaster->agpm_id =
309 	    pci_config_get32(pci_acc_hdl, PCI_CONF_VENID);
310 	agpmaster->agpm_acc_hdl = pci_acc_hdl;
311 
312 	if (!detect_i8xx_device(agpmaster)) {
313 		/* Intel 8XX, 915, 945 and 965 series */
314 		if (set_gtt_mmio(devi, agpmaster, pci_acc_hdl) != 0)
315 			goto fail;
316 	} else if (detect_agp_devcice(agpmaster, pci_acc_hdl)) {
317 		/* non IGD or AGP devices, AMD64 gart */
318 		AGPM_DEBUG((CE_WARN,
319 		    "agpmaster_attach: neither IGD or AGP devices exists"));
320 		agpmaster_detach(&agpmaster);
321 		return (0);
322 	}
323 
324 	/* create minor node for IGD or AGP device */
325 	instance = ddi_get_instance(devi);
326 
327 	(void) sprintf(buf, "%s%d", AGPMASTER_NAME, instance);
328 	status = ddi_create_minor_node(devi, buf, S_IFCHR, minor,
329 	    DDI_NT_AGP_MASTER, 0);
330 
331 	if (status != DDI_SUCCESS) {
332 		AGPM_DEBUG((CE_WARN,
333 		    "agpmaster_attach: create agpmaster node failed"));
334 		goto fail;
335 	}
336 
337 	*master_softcp = agpmaster;
338 	return (0);
339 fail:
340 	agpmaster_detach(&agpmaster);
341 	return (-1);
342 }
343 
344 /*
345  * Currently, it handles ioctl requests related with agp master device for
346  * layered driver (agpgart) only.
347  */
348 /*ARGSUSED*/
349 int
350 agpmaster_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *cred,
351     int *rval, agp_master_softc_t *softc)
352 {
353 	uint32_t base;
354 	uint32_t addr;
355 	igd_gtt_seg_t seg;
356 	agp_info_t info;
357 	uint32_t value;
358 	off_t cap;
359 	uint32_t command;
360 	static char kernel_only[] =
361 	    "agpmaster_ioctl: %s is a kernel only ioctl";
362 
363 	CONFIRM(softc);
364 
365 	switch (cmd) {
366 	case DEVICE_DETECT:
367 		if (!(mode & FKIOCTL)) {
368 			AGPM_DEBUG((CE_CONT, kernel_only, "DEVICE_DETECT"));
369 			return (ENXIO);
370 		}
371 
372 		if (ddi_copyout(&softc->agpm_dev_type,
373 		    (void *)data, sizeof (int), mode))
374 			return (EFAULT);
375 		break;
376 	case AGP_MASTER_SETCMD:
377 		if (!(mode & FKIOCTL)) {
378 			AGPM_DEBUG((CE_CONT, kernel_only, "AGP_MASTER_SETCMD"));
379 			return (ENXIO);
380 		}
381 
382 		CONFIRM(softc->agpm_dev_type == DEVICE_IS_AGP);
383 		CONFIRM(softc->agpm_data.agpm_acaptr);
384 
385 		if (ddi_copyin((void *)data, &command,
386 		    sizeof (uint32_t), mode))
387 			return (EFAULT);
388 
389 		pci_config_put32(softc->agpm_acc_hdl,
390 		    softc->agpm_data.agpm_acaptr + AGP_CONF_COMMAND,
391 		    command);
392 		break;
393 	case AGP_MASTER_GETINFO:
394 		if (!(mode & FKIOCTL)) {
395 			AGPM_DEBUG((CE_CONT, kernel_only,
396 			    "AGP_MASTER_GETINFO"));
397 			return (ENXIO);
398 		}
399 
400 		CONFIRM(softc->agpm_dev_type == DEVICE_IS_AGP);
401 		CONFIRM(softc->agpm_data.agpm_acaptr);
402 
403 		cap = softc->agpm_data.agpm_acaptr;
404 		value = pci_config_get32(softc->agpm_acc_hdl, cap);
405 		info.agpi_version.agpv_major = (uint16_t)((value >> 20) & 0xf);
406 		info.agpi_version.agpv_minor = (uint16_t)((value >> 16) & 0xf);
407 		info.agpi_devid = softc->agpm_id;
408 		info.agpi_mode = pci_config_get32(
409 		    softc->agpm_acc_hdl, cap + AGP_CONF_STATUS);
410 
411 		if (ddi_copyout(&info, (void *)data,
412 		    sizeof (agp_info_t), mode))
413 			return (EFAULT);
414 		break;
415 	case I810_SET_GTT_BASE:
416 		if (!(mode & FKIOCTL)) {
417 			AGPM_DEBUG((CE_CONT, kernel_only, "I810_SET_GTT_ADDR"));
418 			return (ENXIO);
419 		}
420 
421 		CONFIRM(softc->agpm_dev_type == DEVICE_IS_I810);
422 
423 		if (ddi_copyin((void *)data, &base, sizeof (uint32_t), mode))
424 			return (EFAULT);
425 
426 		/* enables page table */
427 		addr = (base & GTT_BASE_MASK) | GTT_TABLE_VALID;
428 
429 		AGPM_WRITE(softc, PGTBL_CTL, addr);
430 		break;
431 	case I8XX_GET_INFO:
432 		if (!(mode & FKIOCTL)) {
433 			AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_GET_INFO"));
434 			return (ENXIO);
435 		}
436 
437 		CONFIRM(IS_IGD(softc));
438 
439 		if (ddi_copyout(&softc->agpm_data.agpm_gtt.gtt_info,
440 		    (void *)data, sizeof (igd_info_t), mode))
441 			return (EFAULT);
442 		break;
443 	case I8XX_ADD2GTT:
444 		if (!(mode & FKIOCTL)) {
445 			AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_ADD2GTT"));
446 			return (ENXIO);
447 		}
448 
449 		CONFIRM(IS_IGD(softc));
450 
451 		if (ddi_copyin((void *)data, &seg,
452 		    sizeof (igd_gtt_seg_t), mode))
453 			return (EFAULT);
454 
455 		if (i8xx_add_to_gtt(&softc->agpm_data.agpm_gtt, seg))
456 			return (EINVAL);
457 		break;
458 	case I8XX_REM_GTT:
459 		if (!(mode & FKIOCTL)) {
460 			AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_REM_GTT"));
461 			return (ENXIO);
462 		}
463 
464 		CONFIRM(IS_IGD(softc));
465 
466 		if (ddi_copyin((void *)data, &seg,
467 		    sizeof (igd_gtt_seg_t), mode))
468 			return (EFAULT);
469 
470 		i8xx_remove_from_gtt(&softc->agpm_data.agpm_gtt, seg);
471 		break;
472 	case I8XX_UNCONFIG:
473 		if (!(mode & FKIOCTL)) {
474 			AGPM_DEBUG((CE_CONT, kernel_only, "I8XX_UNCONFIG"));
475 			return (ENXIO);
476 		}
477 
478 		CONFIRM(IS_IGD(softc));
479 
480 		if (softc->agpm_dev_type == DEVICE_IS_I810)
481 			AGPM_WRITE(softc, PGTBL_CTL, 0);
482 		/*
483 		 * may need to clear all gtt entries here for i830 series,
484 		 * but may not be necessary
485 		 */
486 		break;
487 	}
488 	return (0);
489 }
490 
491 /*
492  * If AGP cap pointer is successfully found, none-zero value is returned.
493  * Otherwise 0 is returned.
494  */
495 static off_t
496 agpmaster_cap_find(ddi_acc_handle_t acc_handle)
497 {
498 	off_t		nextcap;
499 	uint32_t	ncapid;
500 	uint8_t		value;
501 
502 	/* check if this device supports capibility pointer */
503 	value = (uint8_t)(pci_config_get16(acc_handle, PCI_CONF_STAT)
504 	    & PCI_CONF_CAP_MASK);
505 
506 	if (!value)
507 		return (0);
508 	/* get the offset of the first capability pointer from CAPPTR */
509 	nextcap = (off_t)(pci_config_get8(acc_handle, AGP_CONF_CAPPTR));
510 
511 	/* check AGP capability from the first capability pointer */
512 	while (nextcap) {
513 		ncapid = pci_config_get32(acc_handle, nextcap);
514 		if ((ncapid & PCI_CONF_CAPID_MASK)
515 		    == AGP_CAP_ID) /* find AGP cap */
516 			break;
517 
518 		nextcap = (off_t)((ncapid & PCI_CONF_NCAPID_MASK) >> 8);
519 	}
520 
521 	return (nextcap);
522 
523 }
524 
525 /*
526  * If i8xx device is successfully detected, 0 is returned.
527  * Otherwise -1 is returned.
528  */
529 static int
530 detect_i8xx_device(agp_master_softc_t *master_softc)
531 {
532 
533 	switch (master_softc->agpm_id) {
534 	case INTEL_IGD_810:
535 	case INTEL_IGD_810DC:
536 	case INTEL_IGD_810E:
537 	case INTEL_IGD_815:
538 		master_softc->agpm_dev_type = DEVICE_IS_I810;
539 		break;
540 	case INTEL_IGD_830M:
541 	case INTEL_IGD_845G:
542 	case INTEL_IGD_855GM:
543 	case INTEL_IGD_865G:
544 	case INTEL_IGD_915:
545 	case INTEL_IGD_915GM:
546 	case INTEL_IGD_945:
547 	case INTEL_IGD_945GM:
548 	case INTEL_IGD_946GZ:
549 	case INTEL_IGD_965G1:
550 	case INTEL_IGD_965G2:
551 	case INTEL_IGD_965GM:
552 	case INTEL_IGD_965GME:
553 	case INTEL_IGD_965Q:
554 		master_softc->agpm_dev_type = DEVICE_IS_I830;
555 		break;
556 	default:		/* unknown id */
557 		return (-1);
558 	}
559 
560 	return (0);
561 }
562 
563 /*
564  * If agp master is succssfully detected, 0 is returned.
565  * Otherwise -1 is returned.
566  */
567 static int
568 detect_agp_devcice(agp_master_softc_t *master_softc,
569     ddi_acc_handle_t acc_handle)
570 {
571 	off_t cap;
572 
573 	cap = agpmaster_cap_find(acc_handle);
574 	if (cap) {
575 		master_softc->agpm_dev_type = DEVICE_IS_AGP;
576 		master_softc->agpm_data.agpm_acaptr = cap;
577 		return (0);
578 	} else {
579 		return (-1);
580 	}
581 
582 }
583 
584 /*
585  * Please refer to GART and GTT entry format table in agpdefs.h for
586  * intel GTT entry format.
587  */
588 static int
589 phys2entry(uint32_t type, uint32_t physaddr, uint32_t *entry)
590 {
591 	uint32_t value;
592 
593 	switch (type) {
594 	case AGP_PHYSICAL:
595 	case AGP_NORMAL:
596 		value = (physaddr & GTT_PTE_MASK) | GTT_PTE_VALID;
597 		break;
598 	default:
599 		return (-1);
600 	}
601 
602 	*entry = value;
603 
604 	return (0);
605 }
606 
607 static int
608 i8xx_add_to_gtt(gtt_impl_t *gtt, igd_gtt_seg_t seg)
609 {
610 	int i;
611 	uint32_t *paddr;
612 	uint32_t entry;
613 	uint32_t maxpages;
614 
615 	maxpages = gtt->gtt_info.igd_apersize;
616 	maxpages = GTT_MB_TO_PAGES(maxpages);
617 
618 	paddr = seg.igs_phyaddr;
619 
620 	/* check if gtt max page number is reached */
621 	if ((seg.igs_pgstart + seg.igs_npage) > maxpages)
622 		return (-1);
623 
624 	paddr = seg.igs_phyaddr;
625 	for (i = seg.igs_pgstart; i < (seg.igs_pgstart + seg.igs_npage);
626 	    i++, paddr++) {
627 		if (phys2entry(seg.igs_type, *paddr, &entry))
628 			return (-1);
629 		ddi_put32(gtt->gtt_mmio_handle,
630 		    (uint32_t *)(gtt->gtt_addr + i * sizeof (uint32_t)),
631 		    entry);
632 	}
633 
634 	return (0);
635 }
636 
637 static void
638 i8xx_remove_from_gtt(gtt_impl_t *gtt, igd_gtt_seg_t seg)
639 {
640 	int i;
641 	uint32_t maxpages;
642 
643 	maxpages = gtt->gtt_info.igd_apersize;
644 	maxpages = GTT_MB_TO_PAGES(maxpages);
645 
646 	/* check if gtt max page number is reached */
647 	if ((seg.igs_pgstart + seg.igs_npage) > maxpages)
648 		return;
649 
650 	for (i = seg.igs_pgstart; i < (seg.igs_pgstart + seg.igs_npage); i++) {
651 		ddi_put32(gtt->gtt_mmio_handle,
652 		    (uint32_t *)(gtt->gtt_addr + i * sizeof (uint32_t)), 0);
653 	}
654 }
655