1/* 2 * intelfb 3 * 4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/ 5 * 945G/945GM/945GME/965G/965GM integrated graphics chips. 6 * 7 * Copyright �� 2002, 2003 David Dawes <dawes@xfree86.org> 8 * 2004 Sylvain Meyer 9 * 2006 David Airlie 10 * 11 * This driver consists of two parts. The first part (intelfbdrv.c) provides 12 * the basic fbdev interfaces, is derived in part from the radeonfb and 13 * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c) 14 * provides the code to program the hardware. Most of it is derived from 15 * the i810/i830 XFree86 driver. The HW-specific code is covered here 16 * under a dual license (GPL and MIT/XFree86 license). 17 * 18 * Author: David Dawes 19 * 20 */ 21 22/* $DHD: intelfb/intelfbdrv.c,v 1.20 2003/06/27 15:17:40 dawes Exp $ */ 23 24 25#include <linux/module.h> 26#include <linux/kernel.h> 27#include <linux/errno.h> 28#include <linux/string.h> 29#include <linux/mm.h> 30#include <linux/slab.h> 31#include <linux/delay.h> 32#include <linux/fb.h> 33#include <linux/ioport.h> 34#include <linux/init.h> 35#include <linux/pci.h> 36#include <linux/vmalloc.h> 37#include <linux/pagemap.h> 38#include <linux/screen_info.h> 39 40#include <asm/io.h> 41 42#ifdef CONFIG_MTRR 43#include <asm/mtrr.h> 44#endif 45 46#include "intelfb.h" 47#include "intelfbhw.h" 48#include "../edid.h" 49 50static void __devinit get_initial_mode(struct intelfb_info *dinfo); 51static void update_dinfo(struct intelfb_info *dinfo, 52 struct fb_var_screeninfo *var); 53static int intelfb_open(struct fb_info *info, int user); 54static int intelfb_release(struct fb_info *info, int user); 55static int intelfb_check_var(struct fb_var_screeninfo *var, 56 struct fb_info *info); 57static int intelfb_set_par(struct fb_info *info); 58static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 59 unsigned blue, unsigned transp, 60 struct fb_info *info); 61 62static int intelfb_blank(int blank, struct fb_info *info); 63static int intelfb_pan_display(struct fb_var_screeninfo *var, 64 struct fb_info *info); 65 66static void intelfb_fillrect(struct fb_info *info, 67 const struct fb_fillrect *rect); 68static void intelfb_copyarea(struct fb_info *info, 69 const struct fb_copyarea *region); 70static void intelfb_imageblit(struct fb_info *info, 71 const struct fb_image *image); 72static int intelfb_cursor(struct fb_info *info, 73 struct fb_cursor *cursor); 74 75static int intelfb_sync(struct fb_info *info); 76 77static int intelfb_ioctl(struct fb_info *info, 78 unsigned int cmd, unsigned long arg); 79 80static int __devinit intelfb_pci_register(struct pci_dev *pdev, 81 const struct pci_device_id *ent); 82static void __devexit intelfb_pci_unregister(struct pci_dev *pdev); 83static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo); 84 85/* 86 * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the 87 * mobile chipsets from being registered. 88 */ 89#if DETECT_VGA_CLASS_ONLY 90#define INTELFB_CLASS_MASK ~0 << 8 91#else 92#define INTELFB_CLASS_MASK 0 93#endif 94 95static struct pci_device_id intelfb_pci_table[] __devinitdata = { 96 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830M, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_830M }, 97 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G }, 98 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, 99 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, 100 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_854, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_854 }, 101 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, 102 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, 103 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, 104 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM }, 105 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME }, 106 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G }, 107 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM }, 108 { 0, } 109}; 110 111/* Global data */ 112static int num_registered = 0; 113 114/* fb ops */ 115static struct fb_ops intel_fb_ops = { 116 .owner = THIS_MODULE, 117 .fb_open = intelfb_open, 118 .fb_release = intelfb_release, 119 .fb_check_var = intelfb_check_var, 120 .fb_set_par = intelfb_set_par, 121 .fb_setcolreg = intelfb_setcolreg, 122 .fb_blank = intelfb_blank, 123 .fb_pan_display = intelfb_pan_display, 124 .fb_fillrect = intelfb_fillrect, 125 .fb_copyarea = intelfb_copyarea, 126 .fb_imageblit = intelfb_imageblit, 127 .fb_cursor = intelfb_cursor, 128 .fb_sync = intelfb_sync, 129 .fb_ioctl = intelfb_ioctl 130}; 131 132/* PCI driver module table */ 133static struct pci_driver intelfb_driver = { 134 .name = "intelfb", 135 .id_table = intelfb_pci_table, 136 .probe = intelfb_pci_register, 137 .remove = __devexit_p(intelfb_pci_unregister) 138}; 139 140/* Module description/parameters */ 141MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, " 142 "Sylvain Meyer <sylvain.meyer@worldonline.fr>"); 143MODULE_DESCRIPTION("Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS 144 " chipsets"); 145MODULE_LICENSE("Dual BSD/GPL"); 146MODULE_DEVICE_TABLE(pci, intelfb_pci_table); 147 148static int accel = 1; 149static int vram = 4; 150static int hwcursor = 0; 151static int mtrr = 1; 152static int fixed = 0; 153static int noinit = 0; 154static int noregister = 0; 155static int probeonly = 0; 156static int idonly = 0; 157static int bailearly = 0; 158static int voffset = 48; 159static char *mode = NULL; 160 161module_param(accel, bool, S_IRUGO); 162MODULE_PARM_DESC(accel, "Enable hardware acceleration"); 163module_param(vram, int, S_IRUGO); 164MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB"); 165module_param(voffset, int, S_IRUGO); 166MODULE_PARM_DESC(voffset, "Offset of framebuffer in MiB"); 167module_param(hwcursor, bool, S_IRUGO); 168MODULE_PARM_DESC(hwcursor, "Enable HW cursor"); 169module_param(mtrr, bool, S_IRUGO); 170MODULE_PARM_DESC(mtrr, "Enable MTRR support"); 171module_param(fixed, bool, S_IRUGO); 172MODULE_PARM_DESC(fixed, "Disable mode switching"); 173module_param(noinit, bool, 0); 174MODULE_PARM_DESC(noinit, "Don't initialise graphics mode when loading"); 175module_param(noregister, bool, 0); 176MODULE_PARM_DESC(noregister, "Don't register, just probe and exit (debug)"); 177module_param(probeonly, bool, 0); 178MODULE_PARM_DESC(probeonly, "Do a minimal probe (debug)"); 179module_param(idonly, bool, 0); 180MODULE_PARM_DESC(idonly, "Just identify without doing anything else (debug)"); 181module_param(bailearly, bool, 0); 182MODULE_PARM_DESC(bailearly, "Bail out early, depending on value (debug)"); 183module_param(mode, charp, S_IRUGO); 184MODULE_PARM_DESC(mode, 185 "Initial video mode \"<xres>x<yres>[-<depth>][@<refresh>]\""); 186 187#ifndef MODULE 188#define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name))) 189#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0) 190#define OPT_STRVAL(opt, name) (opt + strlen(name)) 191 192static __inline__ char * get_opt_string(const char *this_opt, const char *name) 193{ 194 const char *p; 195 int i; 196 char *ret; 197 198 p = OPT_STRVAL(this_opt, name); 199 i = 0; 200 while (p[i] && p[i] != ' ' && p[i] != ',') 201 i++; 202 ret = kmalloc(i + 1, GFP_KERNEL); 203 if (ret) { 204 strncpy(ret, p, i); 205 ret[i] = '\0'; 206 } 207 return ret; 208} 209 210static __inline__ int get_opt_int(const char *this_opt, const char *name, 211 int *ret) 212{ 213 if (!ret) 214 return 0; 215 216 if (!OPT_EQUAL(this_opt, name)) 217 return 0; 218 219 *ret = OPT_INTVAL(this_opt, name); 220 return 1; 221} 222 223static __inline__ int get_opt_bool(const char *this_opt, const char *name, 224 int *ret) 225{ 226 if (!ret) 227 return 0; 228 229 if (OPT_EQUAL(this_opt, name)) { 230 if (this_opt[strlen(name)] == '=') 231 *ret = simple_strtoul(this_opt + strlen(name) + 1, 232 NULL, 0); 233 else 234 *ret = 1; 235 } else { 236 if (OPT_EQUAL(this_opt, "no") && OPT_EQUAL(this_opt + 2, name)) 237 *ret = 0; 238 else 239 return 0; 240 } 241 return 1; 242} 243 244static int __init intelfb_setup(char *options) 245{ 246 char *this_opt; 247 248 DBG_MSG("intelfb_setup\n"); 249 250 if (!options || !*options) { 251 DBG_MSG("no options\n"); 252 return 0; 253 } else 254 DBG_MSG("options: %s\n", options); 255 256 /* 257 * These are the built-in options analogous to the module parameters 258 * defined above. 259 * 260 * The syntax is: 261 * 262 * video=intelfb:[mode][,<param>=<val>] ... 263 * 264 * e.g., 265 * 266 * video=intelfb:1024x768-16@75,accel=0 267 */ 268 269 while ((this_opt = strsep(&options, ","))) { 270 if (!*this_opt) 271 continue; 272 if (get_opt_bool(this_opt, "accel", &accel)) 273 ; 274 else if (get_opt_int(this_opt, "vram", &vram)) 275 ; 276 else if (get_opt_bool(this_opt, "hwcursor", &hwcursor)) 277 ; 278 else if (get_opt_bool(this_opt, "mtrr", &mtrr)) 279 ; 280 else if (get_opt_bool(this_opt, "fixed", &fixed)) 281 ; 282 else if (get_opt_bool(this_opt, "init", &noinit)) 283 noinit = !noinit; 284 else if (OPT_EQUAL(this_opt, "mode=")) 285 mode = get_opt_string(this_opt, "mode="); 286 else 287 mode = this_opt; 288 } 289 290 return 0; 291} 292 293#endif 294 295static int __init intelfb_init(void) 296{ 297#ifndef MODULE 298 char *option = NULL; 299#endif 300 301 DBG_MSG("intelfb_init\n"); 302 303 INF_MSG("Framebuffer driver for " 304 "Intel(R) " SUPPORTED_CHIPSETS " chipsets\n"); 305 INF_MSG("Version " INTELFB_VERSION "\n"); 306 307 if (idonly) 308 return -ENODEV; 309 310#ifndef MODULE 311 if (fb_get_options("intelfb", &option)) 312 return -ENODEV; 313 intelfb_setup(option); 314#endif 315 316 return pci_register_driver(&intelfb_driver); 317} 318 319static void __exit intelfb_exit(void) 320{ 321 DBG_MSG("intelfb_exit\n"); 322 pci_unregister_driver(&intelfb_driver); 323} 324 325module_init(intelfb_init); 326module_exit(intelfb_exit); 327 328/*************************************************************** 329 * mtrr support functions * 330 ***************************************************************/ 331 332#ifdef CONFIG_MTRR 333static inline void __devinit set_mtrr(struct intelfb_info *dinfo) 334{ 335 dinfo->mtrr_reg = mtrr_add(dinfo->aperture.physical, 336 dinfo->aperture.size, MTRR_TYPE_WRCOMB, 1); 337 if (dinfo->mtrr_reg < 0) { 338 ERR_MSG("unable to set MTRR\n"); 339 return; 340 } 341 dinfo->has_mtrr = 1; 342} 343static inline void unset_mtrr(struct intelfb_info *dinfo) 344{ 345 if (dinfo->has_mtrr) 346 mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical, 347 dinfo->aperture.size); 348} 349#else 350#define set_mtrr(x) WRN_MSG("MTRR is disabled in the kernel\n") 351 352#define unset_mtrr(x) do { } while (0) 353#endif /* CONFIG_MTRR */ 354 355/*************************************************************** 356 * driver init / cleanup * 357 ***************************************************************/ 358 359static void cleanup(struct intelfb_info *dinfo) 360{ 361 DBG_MSG("cleanup\n"); 362 363 if (!dinfo) 364 return; 365 366 intelfbhw_disable_irq(dinfo); 367 368 fb_dealloc_cmap(&dinfo->info->cmap); 369 kfree(dinfo->info->pixmap.addr); 370 371 if (dinfo->registered) 372 unregister_framebuffer(dinfo->info); 373 374 unset_mtrr(dinfo); 375 376 if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) { 377 agp_unbind_memory(dinfo->gtt_fb_mem); 378 agp_free_memory(dinfo->gtt_fb_mem); 379 } 380 if (dinfo->gtt_cursor_mem) { 381 agp_unbind_memory(dinfo->gtt_cursor_mem); 382 agp_free_memory(dinfo->gtt_cursor_mem); 383 } 384 if (dinfo->gtt_ring_mem) { 385 agp_unbind_memory(dinfo->gtt_ring_mem); 386 agp_free_memory(dinfo->gtt_ring_mem); 387 } 388 389#ifdef CONFIG_FB_INTEL_I2C 390 /* un-register I2C bus */ 391 intelfb_delete_i2c_busses(dinfo); 392#endif 393 394 if (dinfo->mmio_base) 395 iounmap((void __iomem *)dinfo->mmio_base); 396 if (dinfo->aperture.virtual) 397 iounmap((void __iomem *)dinfo->aperture.virtual); 398 399 if (dinfo->flag & INTELFB_MMIO_ACQUIRED) 400 release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE); 401 if (dinfo->flag & INTELFB_FB_ACQUIRED) 402 release_mem_region(dinfo->aperture.physical, 403 dinfo->aperture.size); 404 framebuffer_release(dinfo->info); 405} 406 407#define bailout(dinfo) do { \ 408 DBG_MSG("bailout\n"); \ 409 cleanup(dinfo); \ 410 INF_MSG("Not going to register framebuffer, exiting...\n"); \ 411 return -ENODEV; \ 412} while (0) 413 414 415static int __devinit intelfb_pci_register(struct pci_dev *pdev, 416 const struct pci_device_id *ent) 417{ 418 struct fb_info *info; 419 struct intelfb_info *dinfo; 420 int i, err, dvo; 421 int aperture_size, stolen_size; 422 struct agp_kern_info gtt_info; 423 int agp_memtype; 424 const char *s; 425 struct agp_bridge_data *bridge; 426 int aperture_bar = 0; 427 int mmio_bar = 1; 428 int offset; 429 430 DBG_MSG("intelfb_pci_register\n"); 431 432 num_registered++; 433 if (num_registered != 1) { 434 ERR_MSG("Attempted to register %d devices " 435 "(should be only 1).\n", num_registered); 436 return -ENODEV; 437 } 438 439 info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev); 440 if (!info) { 441 ERR_MSG("Could not allocate memory for intelfb_info.\n"); 442 return -ENODEV; 443 } 444 if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { 445 ERR_MSG("Could not allocate cmap for intelfb_info.\n"); 446 goto err_out_cmap; 447 return -ENODEV; 448 } 449 450 dinfo = info->par; 451 dinfo->info = info; 452 dinfo->fbops = &intel_fb_ops; 453 dinfo->pdev = pdev; 454 455 /* Reserve pixmap space. */ 456 info->pixmap.addr = kzalloc(64 * 1024, GFP_KERNEL); 457 if (info->pixmap.addr == NULL) { 458 ERR_MSG("Cannot reserve pixmap memory.\n"); 459 goto err_out_pixmap; 460 } 461 462 /* set early this option because it could be changed by tv encoder 463 driver */ 464 dinfo->fixed_mode = fixed; 465 466 /* Enable device. */ 467 if ((err = pci_enable_device(pdev))) { 468 ERR_MSG("Cannot enable device.\n"); 469 cleanup(dinfo); 470 return -ENODEV; 471 } 472 473 /* Set base addresses. */ 474 if ((ent->device == PCI_DEVICE_ID_INTEL_915G) || 475 (ent->device == PCI_DEVICE_ID_INTEL_915GM) || 476 (ent->device == PCI_DEVICE_ID_INTEL_945G) || 477 (ent->device == PCI_DEVICE_ID_INTEL_945GM) || 478 (ent->device == PCI_DEVICE_ID_INTEL_945GME) || 479 (ent->device == PCI_DEVICE_ID_INTEL_965G) || 480 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) { 481 482 aperture_bar = 2; 483 mmio_bar = 0; 484 } 485 dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); 486 dinfo->aperture.size = pci_resource_len(pdev, aperture_bar); 487 dinfo->mmio_base_phys = pci_resource_start(pdev, mmio_bar); 488 DBG_MSG("fb aperture: 0x%llx/0x%llx, MMIO region: 0x%llx/0x%llx\n", 489 (unsigned long long)pci_resource_start(pdev, aperture_bar), 490 (unsigned long long)pci_resource_len(pdev, aperture_bar), 491 (unsigned long long)pci_resource_start(pdev, mmio_bar), 492 (unsigned long long)pci_resource_len(pdev, mmio_bar)); 493 494 /* Reserve the fb and MMIO regions */ 495 if (!request_mem_region(dinfo->aperture.physical, dinfo->aperture.size, 496 INTELFB_MODULE_NAME)) { 497 ERR_MSG("Cannot reserve FB region.\n"); 498 cleanup(dinfo); 499 return -ENODEV; 500 } 501 502 dinfo->flag |= INTELFB_FB_ACQUIRED; 503 504 if (!request_mem_region(dinfo->mmio_base_phys, 505 INTEL_REG_SIZE, 506 INTELFB_MODULE_NAME)) { 507 ERR_MSG("Cannot reserve MMIO region.\n"); 508 cleanup(dinfo); 509 return -ENODEV; 510 } 511 512 dinfo->flag |= INTELFB_MMIO_ACQUIRED; 513 514 /* Get the chipset info. */ 515 dinfo->pci_chipset = pdev->device; 516 517 if (intelfbhw_get_chipset(pdev, dinfo)) { 518 cleanup(dinfo); 519 return -ENODEV; 520 } 521 522 if (intelfbhw_get_memory(pdev, &aperture_size,&stolen_size)) { 523 cleanup(dinfo); 524 return -ENODEV; 525 } 526 527 INF_MSG("%02x:%02x.%d: %s, aperture size %dMB, " 528 "stolen memory %dkB\n", 529 pdev->bus->number, PCI_SLOT(pdev->devfn), 530 PCI_FUNC(pdev->devfn), dinfo->name, 531 BtoMB(aperture_size), BtoKB(stolen_size)); 532 533 /* Set these from the options. */ 534 dinfo->accel = accel; 535 dinfo->hwcursor = hwcursor; 536 537 if (NOACCEL_CHIPSET(dinfo) && dinfo->accel == 1) { 538 INF_MSG("Acceleration is not supported for the %s chipset.\n", 539 dinfo->name); 540 dinfo->accel = 0; 541 } 542 543 /* Framebuffer parameters - Use all the stolen memory if >= vram */ 544 if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) { 545 dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size); 546 dinfo->fbmem_gart = 0; 547 } else { 548 dinfo->fb.size = MB(vram); 549 dinfo->fbmem_gart = 1; 550 } 551 552 /* Allocate space for the ring buffer and HW cursor if enabled. */ 553 if (dinfo->accel) { 554 dinfo->ring.size = RINGBUFFER_SIZE; 555 dinfo->ring_tail_mask = dinfo->ring.size - 1; 556 } 557 if (dinfo->hwcursor) 558 dinfo->cursor.size = HW_CURSOR_SIZE; 559 560 /* Use agpgart to manage the GATT */ 561 if (!(bridge = agp_backend_acquire(pdev))) { 562 ERR_MSG("cannot acquire agp\n"); 563 cleanup(dinfo); 564 return -ENODEV; 565 } 566 567 /* get the current gatt info */ 568 if (agp_copy_info(bridge, >t_info)) { 569 ERR_MSG("cannot get agp info\n"); 570 agp_backend_release(bridge); 571 cleanup(dinfo); 572 return -ENODEV; 573 } 574 575 if (MB(voffset) < stolen_size) 576 offset = (stolen_size >> 12); 577 else 578 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE; 579 580 /* set the mem offsets - set them after the already used pages */ 581 if (dinfo->accel) 582 dinfo->ring.offset = offset + gtt_info.current_memory; 583 if (dinfo->hwcursor) 584 dinfo->cursor.offset = offset + 585 + gtt_info.current_memory + (dinfo->ring.size >> 12); 586 if (dinfo->fbmem_gart) 587 dinfo->fb.offset = offset + 588 + gtt_info.current_memory + (dinfo->ring.size >> 12) 589 + (dinfo->cursor.size >> 12); 590 591 /* Allocate memories (which aren't stolen) */ 592 /* Map the fb and MMIO regions */ 593 /* ioremap only up to the end of used aperture */ 594 dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache 595 (dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12) 596 + dinfo->fb.size); 597 if (!dinfo->aperture.virtual) { 598 ERR_MSG("Cannot remap FB region.\n"); 599 cleanup(dinfo); 600 return -ENODEV; 601 } 602 603 dinfo->mmio_base = 604 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys, 605 INTEL_REG_SIZE); 606 if (!dinfo->mmio_base) { 607 ERR_MSG("Cannot remap MMIO region.\n"); 608 cleanup(dinfo); 609 return -ENODEV; 610 } 611 612 if (dinfo->accel) { 613 if (!(dinfo->gtt_ring_mem = 614 agp_allocate_memory(bridge, dinfo->ring.size >> 12, 615 AGP_NORMAL_MEMORY))) { 616 ERR_MSG("cannot allocate ring buffer memory\n"); 617 agp_backend_release(bridge); 618 cleanup(dinfo); 619 return -ENOMEM; 620 } 621 if (agp_bind_memory(dinfo->gtt_ring_mem, 622 dinfo->ring.offset)) { 623 ERR_MSG("cannot bind ring buffer memory\n"); 624 agp_backend_release(bridge); 625 cleanup(dinfo); 626 return -EBUSY; 627 } 628 dinfo->ring.physical = dinfo->aperture.physical 629 + (dinfo->ring.offset << 12); 630 dinfo->ring.virtual = dinfo->aperture.virtual 631 + (dinfo->ring.offset << 12); 632 dinfo->ring_head = 0; 633 } 634 if (dinfo->hwcursor) { 635 agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY 636 : AGP_NORMAL_MEMORY; 637 if (!(dinfo->gtt_cursor_mem = 638 agp_allocate_memory(bridge, dinfo->cursor.size >> 12, 639 agp_memtype))) { 640 ERR_MSG("cannot allocate cursor memory\n"); 641 agp_backend_release(bridge); 642 cleanup(dinfo); 643 return -ENOMEM; 644 } 645 if (agp_bind_memory(dinfo->gtt_cursor_mem, 646 dinfo->cursor.offset)) { 647 ERR_MSG("cannot bind cursor memory\n"); 648 agp_backend_release(bridge); 649 cleanup(dinfo); 650 return -EBUSY; 651 } 652 if (dinfo->mobile) 653 dinfo->cursor.physical 654 = dinfo->gtt_cursor_mem->physical; 655 else 656 dinfo->cursor.physical = dinfo->aperture.physical 657 + (dinfo->cursor.offset << 12); 658 dinfo->cursor.virtual = dinfo->aperture.virtual 659 + (dinfo->cursor.offset << 12); 660 } 661 if (dinfo->fbmem_gart) { 662 if (!(dinfo->gtt_fb_mem = 663 agp_allocate_memory(bridge, dinfo->fb.size >> 12, 664 AGP_NORMAL_MEMORY))) { 665 WRN_MSG("cannot allocate framebuffer memory - use " 666 "the stolen one\n"); 667 dinfo->fbmem_gart = 0; 668 } 669 if (agp_bind_memory(dinfo->gtt_fb_mem, 670 dinfo->fb.offset)) { 671 WRN_MSG("cannot bind framebuffer memory - use " 672 "the stolen one\n"); 673 dinfo->fbmem_gart = 0; 674 } 675 } 676 677 /* update framebuffer memory parameters */ 678 if (!dinfo->fbmem_gart) 679 dinfo->fb.offset = 0; /* starts at offset 0 */ 680 dinfo->fb.physical = dinfo->aperture.physical 681 + (dinfo->fb.offset << 12); 682 dinfo->fb.virtual = dinfo->aperture.virtual + (dinfo->fb.offset << 12); 683 dinfo->fb_start = dinfo->fb.offset << 12; 684 685 /* release agpgart */ 686 agp_backend_release(bridge); 687 688 if (mtrr) 689 set_mtrr(dinfo); 690 691 DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n", 692 dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size, 693 dinfo->fb.virtual); 694 DBG_MSG("MMIO: 0x%x/0x%x (0x%p)\n", 695 dinfo->mmio_base_phys, INTEL_REG_SIZE, 696 dinfo->mmio_base); 697 DBG_MSG("ring buffer: 0x%x/0x%x (0x%p)\n", 698 dinfo->ring.physical, dinfo->ring.size, 699 dinfo->ring.virtual); 700 DBG_MSG("HW cursor: 0x%x/0x%x (0x%p) (offset 0x%x) (phys 0x%x)\n", 701 dinfo->cursor.physical, dinfo->cursor.size, 702 dinfo->cursor.virtual, dinfo->cursor.offset, 703 dinfo->cursor.physical); 704 705 DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d, " 706 "noinit = %d\n", vram, accel, hwcursor, fixed, noinit); 707 DBG_MSG("options: mode = \"%s\"\n", mode ? mode : ""); 708 709 if (probeonly) 710 bailout(dinfo); 711 712 /* 713 * Check if the LVDS port or any DVO ports are enabled. If so, 714 * don't allow mode switching 715 */ 716 dvo = intelfbhw_check_non_crt(dinfo); 717 if (dvo) { 718 dinfo->fixed_mode = 1; 719 WRN_MSG("Non-CRT device is enabled ( "); 720 i = 0; 721 while (dvo) { 722 if (dvo & 1) { 723 s = intelfbhw_dvo_to_string(1 << i); 724 if (s) 725 printk("%s ", s); 726 } 727 dvo >>= 1; 728 ++i; 729 } 730 printk("). Disabling mode switching.\n"); 731 } 732 733 if (bailearly == 1) 734 bailout(dinfo); 735 736 if (FIXED_MODE(dinfo) && 737 screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) { 738 ERR_MSG("Video mode must be programmed at boot time.\n"); 739 cleanup(dinfo); 740 return -ENODEV; 741 } 742 743 if (bailearly == 2) 744 bailout(dinfo); 745 746 /* Initialise dinfo and related data. */ 747 /* If an initial mode was programmed at boot time, get its details. */ 748 if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) 749 get_initial_mode(dinfo); 750 751 if (bailearly == 3) 752 bailout(dinfo); 753 754 if (FIXED_MODE(dinfo)) /* remap fb address */ 755 update_dinfo(dinfo, &dinfo->initial_var); 756 757 if (bailearly == 4) 758 bailout(dinfo); 759 760 761 if (intelfb_set_fbinfo(dinfo)) { 762 cleanup(dinfo); 763 return -ENODEV; 764 } 765 766 if (bailearly == 5) 767 bailout(dinfo); 768 769#ifdef CONFIG_FB_INTEL_I2C 770 /* register I2C bus */ 771 intelfb_create_i2c_busses(dinfo); 772#endif 773 774 if (bailearly == 6) 775 bailout(dinfo); 776 777 pci_set_drvdata(pdev, dinfo); 778 779 /* Save the initial register state. */ 780 i = intelfbhw_read_hw_state(dinfo, &dinfo->save_state, 781 bailearly > 6 ? bailearly - 6 : 0); 782 if (i != 0) { 783 DBG_MSG("intelfbhw_read_hw_state returned %d\n", i); 784 bailout(dinfo); 785 } 786 787 intelfbhw_print_hw_state(dinfo, &dinfo->save_state); 788 789 if (bailearly == 18) 790 bailout(dinfo); 791 792 /* read active pipe */ 793 dinfo->pipe = intelfbhw_active_pipe(&dinfo->save_state); 794 795 /* Cursor initialisation */ 796 if (dinfo->hwcursor) { 797 intelfbhw_cursor_init(dinfo); 798 intelfbhw_cursor_reset(dinfo); 799 } 800 801 if (bailearly == 19) 802 bailout(dinfo); 803 804 /* 2d acceleration init */ 805 if (dinfo->accel) 806 intelfbhw_2d_start(dinfo); 807 808 if (bailearly == 20) 809 bailout(dinfo); 810 811 if (noregister) 812 bailout(dinfo); 813 814 if (register_framebuffer(dinfo->info) < 0) { 815 ERR_MSG("Cannot register framebuffer.\n"); 816 cleanup(dinfo); 817 return -ENODEV; 818 } 819 820 dinfo->registered = 1; 821 dinfo->open = 0; 822 823 init_waitqueue_head(&dinfo->vsync.wait); 824 spin_lock_init(&dinfo->int_lock); 825 dinfo->irq_flags = 0; 826 dinfo->vsync.pan_display = 0; 827 dinfo->vsync.pan_offset = 0; 828 829 return 0; 830 831err_out_pixmap: 832 fb_dealloc_cmap(&info->cmap); 833err_out_cmap: 834 framebuffer_release(info); 835 return -ENODEV; 836} 837 838static void __devexit 839intelfb_pci_unregister(struct pci_dev *pdev) 840{ 841 struct intelfb_info *dinfo = pci_get_drvdata(pdev); 842 843 DBG_MSG("intelfb_pci_unregister\n"); 844 845 if (!dinfo) 846 return; 847 848 cleanup(dinfo); 849 850 pci_set_drvdata(pdev, NULL); 851} 852 853/*************************************************************** 854 * helper functions * 855 ***************************************************************/ 856 857int __inline__ intelfb_var_to_depth(const struct fb_var_screeninfo *var) 858{ 859 DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n", 860 var->bits_per_pixel, var->green.length); 861 862 switch (var->bits_per_pixel) { 863 case 16: 864 return (var->green.length == 6) ? 16 : 15; 865 case 32: 866 return 24; 867 default: 868 return var->bits_per_pixel; 869 } 870} 871 872 873static __inline__ int var_to_refresh(const struct fb_var_screeninfo *var) 874{ 875 int xtot = var->xres + var->left_margin + var->right_margin + 876 var->hsync_len; 877 int ytot = var->yres + var->upper_margin + var->lower_margin + 878 var->vsync_len; 879 880 return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; 881} 882 883/*************************************************************** 884 * Various intialisation functions * 885 ***************************************************************/ 886 887static void __devinit get_initial_mode(struct intelfb_info *dinfo) 888{ 889 struct fb_var_screeninfo *var; 890 int xtot, ytot; 891 892 DBG_MSG("get_initial_mode\n"); 893 894 dinfo->initial_vga = 1; 895 dinfo->initial_fb_base = screen_info.lfb_base; 896 dinfo->initial_video_ram = screen_info.lfb_size * KB(64); 897 dinfo->initial_pitch = screen_info.lfb_linelength; 898 899 var = &dinfo->initial_var; 900 memset(var, 0, sizeof(*var)); 901 var->xres = screen_info.lfb_width; 902 var->yres = screen_info.lfb_height; 903 var->bits_per_pixel = screen_info.lfb_depth; 904 switch (screen_info.lfb_depth) { 905 case 15: 906 var->bits_per_pixel = 16; 907 break; 908 case 24: 909 var->bits_per_pixel = 32; 910 break; 911 } 912 913 DBG_MSG("Initial info: FB is 0x%x/0x%x (%d kByte)\n", 914 dinfo->initial_fb_base, dinfo->initial_video_ram, 915 BtoKB(dinfo->initial_video_ram)); 916 917 DBG_MSG("Initial info: mode is %dx%d-%d (%d)\n", 918 var->xres, var->yres, var->bits_per_pixel, 919 dinfo->initial_pitch); 920 921 /* Dummy timing values (assume 60Hz) */ 922 var->left_margin = (var->xres / 8) & 0xf8; 923 var->right_margin = 32; 924 var->upper_margin = 16; 925 var->lower_margin = 4; 926 var->hsync_len = (var->xres / 8) & 0xf8; 927 var->vsync_len = 4; 928 929 xtot = var->xres + var->left_margin + 930 var->right_margin + var->hsync_len; 931 ytot = var->yres + var->upper_margin + 932 var->lower_margin + var->vsync_len; 933 var->pixclock = 10000000 / xtot * 1000 / ytot * 100 / 60; 934 935 var->height = -1; 936 var->width = -1; 937 938 if (var->bits_per_pixel > 8) { 939 var->red.offset = screen_info.red_pos; 940 var->red.length = screen_info.red_size; 941 var->green.offset = screen_info.green_pos; 942 var->green.length = screen_info.green_size; 943 var->blue.offset = screen_info.blue_pos; 944 var->blue.length = screen_info.blue_size; 945 var->transp.offset = screen_info.rsvd_pos; 946 var->transp.length = screen_info.rsvd_size; 947 } else { 948 var->red.length = 8; 949 var->green.length = 8; 950 var->blue.length = 8; 951 } 952} 953 954static int __devinit intelfb_init_var(struct intelfb_info *dinfo) 955{ 956 struct fb_var_screeninfo *var; 957 int msrc = 0; 958 959 DBG_MSG("intelfb_init_var\n"); 960 961 var = &dinfo->info->var; 962 if (FIXED_MODE(dinfo)) { 963 memcpy(var, &dinfo->initial_var, 964 sizeof(struct fb_var_screeninfo)); 965 msrc = 5; 966 } else { 967 const u8 *edid_s = fb_firmware_edid(&dinfo->pdev->dev); 968 u8 *edid_d = NULL; 969 970 if (edid_s) { 971 edid_d = kmemdup(edid_s, EDID_LENGTH, GFP_KERNEL); 972 973 if (edid_d) { 974 fb_edid_to_monspecs(edid_d, 975 &dinfo->info->monspecs); 976 kfree(edid_d); 977 } 978 } 979 980 if (mode) { 981 printk("intelfb: Looking for mode in private " 982 "database\n"); 983 msrc = fb_find_mode(var, dinfo->info, mode, 984 dinfo->info->monspecs.modedb, 985 dinfo->info->monspecs.modedb_len, 986 NULL, 0); 987 988 if (msrc && msrc > 1) { 989 printk("intelfb: No mode in private database, " 990 "intelfb: looking for mode in global " 991 "database "); 992 msrc = fb_find_mode(var, dinfo->info, mode, 993 NULL, 0, NULL, 0); 994 995 if (msrc) 996 msrc |= 8; 997 } 998 999 } 1000 1001 if (!msrc) 1002 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, 1003 NULL, 0, NULL, 0); 1004 } 1005 1006 if (!msrc) { 1007 ERR_MSG("Cannot find a suitable video mode.\n"); 1008 return 1; 1009 } 1010 1011 INF_MSG("Initial video mode is %dx%d-%d@%d.\n", var->xres, var->yres, 1012 var->bits_per_pixel, var_to_refresh(var)); 1013 1014 DBG_MSG("Initial video mode is from %d.\n", msrc); 1015 1016#if ALLOCATE_FOR_PANNING 1017 /* Allow use of half of the video ram for panning */ 1018 var->xres_virtual = var->xres; 1019 var->yres_virtual = 1020 dinfo->fb.size / 2 / (var->bits_per_pixel * var->xres); 1021 if (var->yres_virtual < var->yres) 1022 var->yres_virtual = var->yres; 1023#else 1024 var->yres_virtual = var->yres; 1025#endif 1026 1027 if (dinfo->accel) 1028 var->accel_flags |= FB_ACCELF_TEXT; 1029 else 1030 var->accel_flags &= ~FB_ACCELF_TEXT; 1031 1032 return 0; 1033} 1034 1035static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo) 1036{ 1037 struct fb_info *info = dinfo->info; 1038 1039 DBG_MSG("intelfb_set_fbinfo\n"); 1040 1041 info->flags = FBINFO_FLAG_DEFAULT; 1042 info->fbops = &intel_fb_ops; 1043 info->pseudo_palette = dinfo->pseudo_palette; 1044 1045 info->pixmap.size = 64*1024; 1046 info->pixmap.buf_align = 8; 1047 info->pixmap.access_align = 32; 1048 info->pixmap.flags = FB_PIXMAP_SYSTEM; 1049 1050 if (intelfb_init_var(dinfo)) 1051 return 1; 1052 1053 info->pixmap.scan_align = 1; 1054 strcpy(info->fix.id, dinfo->name); 1055 info->fix.smem_start = dinfo->fb.physical; 1056 info->fix.smem_len = dinfo->fb.size; 1057 info->fix.type = FB_TYPE_PACKED_PIXELS; 1058 info->fix.type_aux = 0; 1059 info->fix.xpanstep = 8; 1060 info->fix.ypanstep = 1; 1061 info->fix.ywrapstep = 0; 1062 info->fix.mmio_start = dinfo->mmio_base_phys; 1063 info->fix.mmio_len = INTEL_REG_SIZE; 1064 info->fix.accel = FB_ACCEL_I830; 1065 update_dinfo(dinfo, &info->var); 1066 1067 return 0; 1068} 1069 1070/* Update dinfo to match the active video mode. */ 1071static void update_dinfo(struct intelfb_info *dinfo, 1072 struct fb_var_screeninfo *var) 1073{ 1074 DBG_MSG("update_dinfo\n"); 1075 1076 dinfo->bpp = var->bits_per_pixel; 1077 dinfo->depth = intelfb_var_to_depth(var); 1078 dinfo->xres = var->xres; 1079 dinfo->yres = var->xres; 1080 dinfo->pixclock = var->pixclock; 1081 1082 dinfo->info->fix.visual = dinfo->visual; 1083 dinfo->info->fix.line_length = dinfo->pitch; 1084 1085 switch (dinfo->bpp) { 1086 case 8: 1087 dinfo->visual = FB_VISUAL_PSEUDOCOLOR; 1088 dinfo->pitch = var->xres_virtual; 1089 break; 1090 case 16: 1091 dinfo->visual = FB_VISUAL_TRUECOLOR; 1092 dinfo->pitch = var->xres_virtual * 2; 1093 break; 1094 case 32: 1095 dinfo->visual = FB_VISUAL_TRUECOLOR; 1096 dinfo->pitch = var->xres_virtual * 4; 1097 break; 1098 } 1099 1100 /* Make sure the line length is a aligned correctly. */ 1101 if (IS_I9XX(dinfo)) 1102 dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT_I9XX); 1103 else 1104 dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); 1105 1106 if (FIXED_MODE(dinfo)) 1107 dinfo->pitch = dinfo->initial_pitch; 1108 1109 dinfo->info->screen_base = (char __iomem *)dinfo->fb.virtual; 1110 dinfo->info->fix.line_length = dinfo->pitch; 1111 dinfo->info->fix.visual = dinfo->visual; 1112} 1113 1114/* fbops functions */ 1115 1116/*************************************************************** 1117 * fbdev interface * 1118 ***************************************************************/ 1119 1120static int intelfb_open(struct fb_info *info, int user) 1121{ 1122 struct intelfb_info *dinfo = GET_DINFO(info); 1123 1124 if (user) 1125 dinfo->open++; 1126 1127 return 0; 1128} 1129 1130static int intelfb_release(struct fb_info *info, int user) 1131{ 1132 struct intelfb_info *dinfo = GET_DINFO(info); 1133 1134 if (user) { 1135 dinfo->open--; 1136 msleep(1); 1137 if (!dinfo->open) 1138 intelfbhw_disable_irq(dinfo); 1139 } 1140 1141 return 0; 1142} 1143 1144static int intelfb_check_var(struct fb_var_screeninfo *var, 1145 struct fb_info *info) 1146{ 1147 int change_var = 0; 1148 struct fb_var_screeninfo v; 1149 struct intelfb_info *dinfo; 1150 static int first = 1; 1151 int i; 1152 /* Good pitches to allow tiling. Don't care about pitches < 1024. */ 1153 static const int pitches[] = { 1154 128 * 8, 1155 128 * 16, 1156 128 * 32, 1157 128 * 64, 1158 0 1159 }; 1160 1161 DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags); 1162 1163 dinfo = GET_DINFO(info); 1164 1165 /* update the pitch */ 1166 if (intelfbhw_validate_mode(dinfo, var) != 0) 1167 return -EINVAL; 1168 1169 v = *var; 1170 1171 for (i = 0; pitches[i] != 0; i++) { 1172 if (pitches[i] >= v.xres_virtual) { 1173 v.xres_virtual = pitches[i]; 1174 break; 1175 } 1176 } 1177 1178 /* Check for a supported bpp. */ 1179 if (v.bits_per_pixel <= 8) 1180 v.bits_per_pixel = 8; 1181 else if (v.bits_per_pixel <= 16) { 1182 if (v.bits_per_pixel == 16) 1183 v.green.length = 6; 1184 v.bits_per_pixel = 16; 1185 } else if (v.bits_per_pixel <= 32) 1186 v.bits_per_pixel = 32; 1187 else 1188 return -EINVAL; 1189 1190 change_var = ((info->var.xres != var->xres) || 1191 (info->var.yres != var->yres) || 1192 (info->var.xres_virtual != var->xres_virtual) || 1193 (info->var.yres_virtual != var->yres_virtual) || 1194 (info->var.bits_per_pixel != var->bits_per_pixel) || 1195 memcmp(&info->var.red, &var->red, sizeof(var->red)) || 1196 memcmp(&info->var.green, &var->green, 1197 sizeof(var->green)) || 1198 memcmp(&info->var.blue, &var->blue, sizeof(var->blue))); 1199 1200 if (FIXED_MODE(dinfo) && 1201 (change_var || 1202 var->yres_virtual > dinfo->initial_var.yres_virtual || 1203 var->yres_virtual < dinfo->initial_var.yres || 1204 var->xoffset || var->nonstd)) { 1205 if (first) { 1206 ERR_MSG("Changing the video mode is not supported.\n"); 1207 first = 0; 1208 } 1209 return -EINVAL; 1210 } 1211 1212 switch (intelfb_var_to_depth(&v)) { 1213 case 8: 1214 v.red.offset = v.green.offset = v.blue.offset = 0; 1215 v.red.length = v.green.length = v.blue.length = 8; 1216 v.transp.offset = v.transp.length = 0; 1217 break; 1218 case 15: 1219 v.red.offset = 10; 1220 v.green.offset = 5; 1221 v.blue.offset = 0; 1222 v.red.length = v.green.length = v.blue.length = 5; 1223 v.transp.offset = v.transp.length = 0; 1224 break; 1225 case 16: 1226 v.red.offset = 11; 1227 v.green.offset = 5; 1228 v.blue.offset = 0; 1229 v.red.length = 5; 1230 v.green.length = 6; 1231 v.blue.length = 5; 1232 v.transp.offset = v.transp.length = 0; 1233 break; 1234 case 24: 1235 v.red.offset = 16; 1236 v.green.offset = 8; 1237 v.blue.offset = 0; 1238 v.red.length = v.green.length = v.blue.length = 8; 1239 v.transp.offset = v.transp.length = 0; 1240 break; 1241 case 32: 1242 v.red.offset = 16; 1243 v.green.offset = 8; 1244 v.blue.offset = 0; 1245 v.red.length = v.green.length = v.blue.length = 8; 1246 v.transp.offset = 24; 1247 v.transp.length = 8; 1248 break; 1249 } 1250 1251 if (v.xoffset < 0) 1252 v.xoffset = 0; 1253 if (v.yoffset < 0) 1254 v.yoffset = 0; 1255 1256 if (v.xoffset > v.xres_virtual - v.xres) 1257 v.xoffset = v.xres_virtual - v.xres; 1258 if (v.yoffset > v.yres_virtual - v.yres) 1259 v.yoffset = v.yres_virtual - v.yres; 1260 1261 v.red.msb_right = v.green.msb_right = v.blue.msb_right = 1262 v.transp.msb_right = 0; 1263 1264 *var = v; 1265 1266 return 0; 1267} 1268 1269static int intelfb_set_par(struct fb_info *info) 1270{ 1271 struct intelfb_hwstate *hw; 1272 struct intelfb_info *dinfo = GET_DINFO(info); 1273 1274 if (FIXED_MODE(dinfo)) { 1275 ERR_MSG("Changing the video mode is not supported.\n"); 1276 return -EINVAL; 1277 } 1278 1279 hw = kmalloc(sizeof(*hw), GFP_ATOMIC); 1280 if (!hw) 1281 return -ENOMEM; 1282 1283 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, 1284 info->var.yres, info->var.bits_per_pixel); 1285 1286 /* 1287 * Disable VCO prior to timing register change. 1288 */ 1289 OUTREG(DPLL_A, INREG(DPLL_A) & ~DPLL_VCO_ENABLE); 1290 1291 intelfb_blank(FB_BLANK_POWERDOWN, info); 1292 1293 if (ACCEL(dinfo, info)) 1294 intelfbhw_2d_stop(dinfo); 1295 1296 memcpy(hw, &dinfo->save_state, sizeof(*hw)); 1297 if (intelfbhw_mode_to_hw(dinfo, hw, &info->var)) 1298 goto invalid_mode; 1299 if (intelfbhw_program_mode(dinfo, hw, 0)) 1300 goto invalid_mode; 1301 1302#if REGDUMP > 0 1303 intelfbhw_read_hw_state(dinfo, hw, 0); 1304 intelfbhw_print_hw_state(dinfo, hw); 1305#endif 1306 1307 update_dinfo(dinfo, &info->var); 1308 1309 if (ACCEL(dinfo, info)) 1310 intelfbhw_2d_start(dinfo); 1311 1312 intelfb_pan_display(&info->var, info); 1313 1314 intelfb_blank(FB_BLANK_UNBLANK, info); 1315 1316 if (ACCEL(dinfo, info)) { 1317 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | 1318 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1319 FBINFO_HWACCEL_IMAGEBLIT; 1320 } else 1321 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1322 1323 kfree(hw); 1324 return 0; 1325invalid_mode: 1326 kfree(hw); 1327 return -EINVAL; 1328} 1329 1330static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1331 unsigned blue, unsigned transp, 1332 struct fb_info *info) 1333{ 1334 struct intelfb_info *dinfo = GET_DINFO(info); 1335 1336#if VERBOSE > 0 1337 DBG_MSG("intelfb_setcolreg: regno %d, depth %d\n", regno, dinfo->depth); 1338#endif 1339 1340 if (regno > 255) 1341 return 1; 1342 1343 if (dinfo->depth == 8) { 1344 red >>= 8; 1345 green >>= 8; 1346 blue >>= 8; 1347 1348 intelfbhw_setcolreg(dinfo, regno, red, green, blue, 1349 transp); 1350 } 1351 1352 if (regno < 16) { 1353 switch (dinfo->depth) { 1354 case 15: 1355 dinfo->pseudo_palette[regno] = ((red & 0xf800) >> 1) | 1356 ((green & 0xf800) >> 6) | 1357 ((blue & 0xf800) >> 11); 1358 break; 1359 case 16: 1360 dinfo->pseudo_palette[regno] = (red & 0xf800) | 1361 ((green & 0xfc00) >> 5) | 1362 ((blue & 0xf800) >> 11); 1363 break; 1364 case 24: 1365 dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) | 1366 (green & 0xff00) | 1367 ((blue & 0xff00) >> 8); 1368 break; 1369 } 1370 } 1371 1372 return 0; 1373} 1374 1375static int intelfb_blank(int blank, struct fb_info *info) 1376{ 1377 intelfbhw_do_blank(blank, info); 1378 return 0; 1379} 1380 1381static int intelfb_pan_display(struct fb_var_screeninfo *var, 1382 struct fb_info *info) 1383{ 1384 intelfbhw_pan_display(var, info); 1385 return 0; 1386} 1387 1388/* When/if we have our own ioctls. */ 1389static int intelfb_ioctl(struct fb_info *info, unsigned int cmd, 1390 unsigned long arg) 1391{ 1392 int retval = 0; 1393 struct intelfb_info *dinfo = GET_DINFO(info); 1394 u32 pipe = 0; 1395 1396 switch (cmd) { 1397 case FBIO_WAITFORVSYNC: 1398 if (get_user(pipe, (__u32 __user *)arg)) 1399 return -EFAULT; 1400 1401 retval = intelfbhw_wait_for_vsync(dinfo, pipe); 1402 break; 1403 default: 1404 break; 1405 } 1406 1407 return retval; 1408} 1409 1410static void intelfb_fillrect (struct fb_info *info, 1411 const struct fb_fillrect *rect) 1412{ 1413 struct intelfb_info *dinfo = GET_DINFO(info); 1414 u32 rop, color; 1415 1416#if VERBOSE > 0 1417 DBG_MSG("intelfb_fillrect\n"); 1418#endif 1419 1420 if (!ACCEL(dinfo, info) || dinfo->depth == 4) { 1421 cfb_fillrect(info, rect); 1422 return; 1423 } 1424 1425 if (rect->rop == ROP_COPY) 1426 rop = PAT_ROP_GXCOPY; 1427 else /* ROP_XOR */ 1428 rop = PAT_ROP_GXXOR; 1429 1430 if (dinfo->depth != 8) 1431 color = dinfo->pseudo_palette[rect->color]; 1432 else 1433 color = rect->color; 1434 1435 intelfbhw_do_fillrect(dinfo, rect->dx, rect->dy, 1436 rect->width, rect->height, color, 1437 dinfo->pitch, info->var.bits_per_pixel, 1438 rop); 1439} 1440 1441static void intelfb_copyarea(struct fb_info *info, 1442 const struct fb_copyarea *region) 1443{ 1444 struct intelfb_info *dinfo = GET_DINFO(info); 1445 1446#if VERBOSE > 0 1447 DBG_MSG("intelfb_copyarea\n"); 1448#endif 1449 1450 if (!ACCEL(dinfo, info) || dinfo->depth == 4) { 1451 cfb_copyarea(info, region); 1452 return; 1453 } 1454 1455 intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx, 1456 region->dy, region->width, region->height, 1457 dinfo->pitch, info->var.bits_per_pixel); 1458} 1459 1460static void intelfb_imageblit(struct fb_info *info, 1461 const struct fb_image *image) 1462{ 1463 struct intelfb_info *dinfo = GET_DINFO(info); 1464 u32 fgcolor, bgcolor; 1465 1466#if VERBOSE > 0 1467 DBG_MSG("intelfb_imageblit\n"); 1468#endif 1469 1470 if (!ACCEL(dinfo, info) || dinfo->depth == 4 1471 || image->depth != 1) { 1472 cfb_imageblit(info, image); 1473 return; 1474 } 1475 1476 if (dinfo->depth != 8) { 1477 fgcolor = dinfo->pseudo_palette[image->fg_color]; 1478 bgcolor = dinfo->pseudo_palette[image->bg_color]; 1479 } else { 1480 fgcolor = image->fg_color; 1481 bgcolor = image->bg_color; 1482 } 1483 1484 if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width, 1485 image->height, image->data, 1486 image->dx, image->dy, 1487 dinfo->pitch, info->var.bits_per_pixel)) { 1488 cfb_imageblit(info, image); 1489 return; 1490 } 1491} 1492 1493static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1494{ 1495 struct intelfb_info *dinfo = GET_DINFO(info); 1496 u32 physical; 1497#if VERBOSE > 0 1498 DBG_MSG("intelfb_cursor\n"); 1499#endif 1500 1501 if (!dinfo->hwcursor) 1502 return -ENODEV; 1503 1504 intelfbhw_cursor_hide(dinfo); 1505 1506 /* If XFree killed the cursor - restore it */ 1507 physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical : 1508 (dinfo->cursor.offset << 12); 1509 1510 if (INREG(CURSOR_A_BASEADDR) != physical) { 1511 u32 fg, bg; 1512 1513 DBG_MSG("the cursor was killed - restore it !!\n"); 1514 DBG_MSG("size %d, %d pos %d, %d\n", 1515 cursor->image.width, cursor->image.height, 1516 cursor->image.dx, cursor->image.dy); 1517 1518 intelfbhw_cursor_init(dinfo); 1519 intelfbhw_cursor_reset(dinfo); 1520 intelfbhw_cursor_setpos(dinfo, cursor->image.dx, 1521 cursor->image.dy); 1522 1523 if (dinfo->depth != 8) { 1524 fg =dinfo->pseudo_palette[cursor->image.fg_color]; 1525 bg =dinfo->pseudo_palette[cursor->image.bg_color]; 1526 } else { 1527 fg = cursor->image.fg_color; 1528 bg = cursor->image.bg_color; 1529 } 1530 intelfbhw_cursor_setcolor(dinfo, bg, fg); 1531 intelfbhw_cursor_load(dinfo, cursor->image.width, 1532 cursor->image.height, 1533 dinfo->cursor_src); 1534 1535 if (cursor->enable) 1536 intelfbhw_cursor_show(dinfo); 1537 return 0; 1538 } 1539 1540 if (cursor->set & FB_CUR_SETPOS) { 1541 u32 dx, dy; 1542 1543 dx = cursor->image.dx - info->var.xoffset; 1544 dy = cursor->image.dy - info->var.yoffset; 1545 1546 intelfbhw_cursor_setpos(dinfo, dx, dy); 1547 } 1548 1549 if (cursor->set & FB_CUR_SETSIZE) { 1550 if (cursor->image.width > 64 || cursor->image.height > 64) 1551 return -ENXIO; 1552 1553 intelfbhw_cursor_reset(dinfo); 1554 } 1555 1556 if (cursor->set & FB_CUR_SETCMAP) { 1557 u32 fg, bg; 1558 1559 if (dinfo->depth != 8) { 1560 fg = dinfo->pseudo_palette[cursor->image.fg_color]; 1561 bg = dinfo->pseudo_palette[cursor->image.bg_color]; 1562 } else { 1563 fg = cursor->image.fg_color; 1564 bg = cursor->image.bg_color; 1565 } 1566 1567 intelfbhw_cursor_setcolor(dinfo, bg, fg); 1568 } 1569 1570 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) { 1571 u32 s_pitch = (ROUND_UP_TO(cursor->image.width, 8) / 8); 1572 u32 size = s_pitch * cursor->image.height; 1573 u8 *dat = (u8 *) cursor->image.data; 1574 u8 *msk = (u8 *) cursor->mask; 1575 u8 src[64]; 1576 u32 i; 1577 1578 if (cursor->image.depth != 1) 1579 return -ENXIO; 1580 1581 switch (cursor->rop) { 1582 case ROP_XOR: 1583 for (i = 0; i < size; i++) 1584 src[i] = dat[i] ^ msk[i]; 1585 break; 1586 case ROP_COPY: 1587 default: 1588 for (i = 0; i < size; i++) 1589 src[i] = dat[i] & msk[i]; 1590 break; 1591 } 1592 1593 /* save the bitmap to restore it when XFree will 1594 make the cursor dirty */ 1595 memcpy(dinfo->cursor_src, src, size); 1596 1597 intelfbhw_cursor_load(dinfo, cursor->image.width, 1598 cursor->image.height, src); 1599 } 1600 1601 if (cursor->enable) 1602 intelfbhw_cursor_show(dinfo); 1603 1604 return 0; 1605} 1606 1607static int intelfb_sync(struct fb_info *info) 1608{ 1609 struct intelfb_info *dinfo = GET_DINFO(info); 1610 1611#if VERBOSE > 0 1612 DBG_MSG("intelfb_sync\n"); 1613#endif 1614 1615 if (dinfo->ring_lockup) 1616 return 0; 1617 1618 intelfbhw_do_sync(dinfo); 1619 return 0; 1620} 1621