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