Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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