1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) Intel Corp. 2007. 4 * All Rights Reserved. 5 * 6 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to 7 * develop this driver. 8 * 9 * This file is part of the Vermilion Range fb driver. 10 * 11 * Authors: 12 * Thomas Hellström <thomas-at-tungstengraphics-dot-com> 13 * Michel Dänzer <michel-at-tungstengraphics-dot-com> 14 * Alan Hourihane <alanh-at-tungstengraphics-dot-com> 15 */ 16 17 #include <linux/module.h> 18 #include <linux/kernel.h> 19 #include <linux/errno.h> 20 #include <linux/string.h> 21 #include <linux/delay.h> 22 #include <linux/slab.h> 23 #include <linux/mm.h> 24 #include <linux/fb.h> 25 #include <linux/pci.h> 26 #include <asm/set_memory.h> 27 #include <asm/tlbflush.h> 28 #include <linux/mmzone.h> 29 30 /* #define VERMILION_DEBUG */ 31 32 #include "vermilion.h" 33 34 #define MODULE_NAME "vmlfb" 35 36 #define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) 37 38 static struct mutex vml_mutex; 39 static struct list_head global_no_mode; 40 static struct list_head global_has_mode; 41 static struct fb_ops vmlfb_ops; 42 static struct vml_sys *subsys = NULL; 43 static char *vml_default_mode = "1024x768@60"; 44 static const struct fb_videomode defaultmode = { 45 NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6, 46 0, FB_VMODE_NONINTERLACED 47 }; 48 49 static u32 vml_mem_requested = (10 * 1024 * 1024); 50 static u32 vml_mem_contig = (4 * 1024 * 1024); 51 static u32 vml_mem_min = (4 * 1024 * 1024); 52 53 static u32 vml_clocks[] = { 54 6750, 55 13500, 56 27000, 57 29700, 58 37125, 59 54000, 60 59400, 61 74250, 62 120000, 63 148500 64 }; 65 66 static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks); 67 68 /* 69 * Allocate a contiguous vram area and make its linear kernel map 70 * uncached. 71 */ 72 73 static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order, 74 unsigned min_order) 75 { 76 gfp_t flags; 77 unsigned long i; 78 79 max_order++; 80 do { 81 /* 82 * Really try hard to get the needed memory. 83 * We need memory below the first 32MB, so we 84 * add the __GFP_DMA flag that guarantees that we are 85 * below the first 16MB. 86 */ 87 88 flags = __GFP_DMA | __GFP_HIGH | __GFP_KSWAPD_RECLAIM; 89 va->logical = 90 __get_free_pages(flags, --max_order); 91 } while (va->logical == 0 && max_order > min_order); 92 93 if (!va->logical) 94 return -ENOMEM; 95 96 va->phys = virt_to_phys((void *)va->logical); 97 va->size = PAGE_SIZE << max_order; 98 va->order = max_order; 99 100 /* 101 * It seems like __get_free_pages only ups the usage count 102 * of the first page. This doesn't work with fault mapping, so 103 * up the usage count once more (XXX: should use split_page or 104 * compound page). 105 */ 106 107 memset((void *)va->logical, 0x00, va->size); 108 for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) { 109 get_page(virt_to_page(i)); 110 } 111 112 /* 113 * Change caching policy of the linear kernel map to avoid 114 * mapping type conflicts with user-space mappings. 115 */ 116 set_pages_uc(virt_to_page(va->logical), va->size >> PAGE_SHIFT); 117 118 printk(KERN_DEBUG MODULE_NAME 119 ": Allocated %ld bytes vram area at 0x%08lx\n", 120 va->size, va->phys); 121 122 return 0; 123 } 124 125 /* 126 * Free a contiguous vram area and reset its linear kernel map 127 * mapping type. 128 */ 129 130 static void vmlfb_free_vram_area(struct vram_area *va) 131 { 132 unsigned long j; 133 134 if (va->logical) { 135 136 /* 137 * Reset the linear kernel map caching policy. 138 */ 139 140 set_pages_wb(virt_to_page(va->logical), 141 va->size >> PAGE_SHIFT); 142 143 /* 144 * Decrease the usage count on the pages we've used 145 * to compensate for upping when allocating. 146 */ 147 148 for (j = va->logical; j < va->logical + va->size; 149 j += PAGE_SIZE) { 150 (void)put_page_testzero(virt_to_page(j)); 151 } 152 153 printk(KERN_DEBUG MODULE_NAME 154 ": Freeing %ld bytes vram area at 0x%08lx\n", 155 va->size, va->phys); 156 free_pages(va->logical, va->order); 157 158 va->logical = 0; 159 } 160 } 161 162 /* 163 * Free allocated vram. 164 */ 165 166 static void vmlfb_free_vram(struct vml_info *vinfo) 167 { 168 int i; 169 170 for (i = 0; i < vinfo->num_areas; ++i) { 171 vmlfb_free_vram_area(&vinfo->vram[i]); 172 } 173 vinfo->num_areas = 0; 174 } 175 176 /* 177 * Allocate vram. Currently we try to allocate contiguous areas from the 178 * __GFP_DMA zone and puzzle them together. A better approach would be to 179 * allocate one contiguous area for scanout and use one-page allocations for 180 * offscreen areas. This requires user-space and GPU virtual mappings. 181 */ 182 183 static int vmlfb_alloc_vram(struct vml_info *vinfo, 184 size_t requested, 185 size_t min_total, size_t min_contig) 186 { 187 int i, j; 188 int order; 189 int contiguous; 190 int err; 191 struct vram_area *va; 192 struct vram_area *va2; 193 194 vinfo->num_areas = 0; 195 for (i = 0; i < VML_VRAM_AREAS; ++i) { 196 va = &vinfo->vram[i]; 197 order = 0; 198 199 while (requested > (PAGE_SIZE << order) && order < MAX_ORDER) 200 order++; 201 202 err = vmlfb_alloc_vram_area(va, order, 0); 203 204 if (err) 205 break; 206 207 if (i == 0) { 208 vinfo->vram_start = va->phys; 209 vinfo->vram_logical = (void __iomem *) va->logical; 210 vinfo->vram_contig_size = va->size; 211 vinfo->num_areas = 1; 212 } else { 213 contiguous = 0; 214 215 for (j = 0; j < i; ++j) { 216 va2 = &vinfo->vram[j]; 217 if (va->phys + va->size == va2->phys || 218 va2->phys + va2->size == va->phys) { 219 contiguous = 1; 220 break; 221 } 222 } 223 224 if (contiguous) { 225 vinfo->num_areas++; 226 if (va->phys < vinfo->vram_start) { 227 vinfo->vram_start = va->phys; 228 vinfo->vram_logical = 229 (void __iomem *)va->logical; 230 } 231 vinfo->vram_contig_size += va->size; 232 } else { 233 vmlfb_free_vram_area(va); 234 break; 235 } 236 } 237 238 if (requested < va->size) 239 break; 240 else 241 requested -= va->size; 242 } 243 244 if (vinfo->vram_contig_size > min_total && 245 vinfo->vram_contig_size > min_contig) { 246 247 printk(KERN_DEBUG MODULE_NAME 248 ": Contiguous vram: %ld bytes at physical 0x%08lx.\n", 249 (unsigned long)vinfo->vram_contig_size, 250 (unsigned long)vinfo->vram_start); 251 252 return 0; 253 } 254 255 printk(KERN_ERR MODULE_NAME 256 ": Could not allocate requested minimal amount of vram.\n"); 257 258 vmlfb_free_vram(vinfo); 259 260 return -ENOMEM; 261 } 262 263 /* 264 * Find the GPU to use with our display controller. 265 */ 266 267 static int vmlfb_get_gpu(struct vml_par *par) 268 { 269 mutex_lock(&vml_mutex); 270 271 par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL); 272 273 if (!par->gpu) { 274 mutex_unlock(&vml_mutex); 275 return -ENODEV; 276 } 277 278 mutex_unlock(&vml_mutex); 279 280 if (pci_enable_device(par->gpu) < 0) 281 return -ENODEV; 282 283 return 0; 284 } 285 286 /* 287 * Find a contiguous vram area that contains a given offset from vram start. 288 */ 289 static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset) 290 { 291 unsigned long aoffset; 292 unsigned i; 293 294 for (i = 0; i < vinfo->num_areas; ++i) { 295 aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start); 296 297 if (aoffset < vinfo->vram[i].size) { 298 return 0; 299 } 300 } 301 302 return -EINVAL; 303 } 304 305 /* 306 * Remap the MMIO register spaces of the VDC and the GPU. 307 */ 308 309 static int vmlfb_enable_mmio(struct vml_par *par) 310 { 311 int err; 312 313 par->vdc_mem_base = pci_resource_start(par->vdc, 0); 314 par->vdc_mem_size = pci_resource_len(par->vdc, 0); 315 if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) { 316 printk(KERN_ERR MODULE_NAME 317 ": Could not claim display controller MMIO.\n"); 318 return -EBUSY; 319 } 320 par->vdc_mem = ioremap_nocache(par->vdc_mem_base, par->vdc_mem_size); 321 if (par->vdc_mem == NULL) { 322 printk(KERN_ERR MODULE_NAME 323 ": Could not map display controller MMIO.\n"); 324 err = -ENOMEM; 325 goto out_err_0; 326 } 327 328 par->gpu_mem_base = pci_resource_start(par->gpu, 0); 329 par->gpu_mem_size = pci_resource_len(par->gpu, 0); 330 if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) { 331 printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n"); 332 err = -EBUSY; 333 goto out_err_1; 334 } 335 par->gpu_mem = ioremap_nocache(par->gpu_mem_base, par->gpu_mem_size); 336 if (par->gpu_mem == NULL) { 337 printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n"); 338 err = -ENOMEM; 339 goto out_err_2; 340 } 341 342 return 0; 343 344 out_err_2: 345 release_mem_region(par->gpu_mem_base, par->gpu_mem_size); 346 out_err_1: 347 iounmap(par->vdc_mem); 348 out_err_0: 349 release_mem_region(par->vdc_mem_base, par->vdc_mem_size); 350 return err; 351 } 352 353 /* 354 * Unmap the VDC and GPU register spaces. 355 */ 356 357 static void vmlfb_disable_mmio(struct vml_par *par) 358 { 359 iounmap(par->gpu_mem); 360 release_mem_region(par->gpu_mem_base, par->gpu_mem_size); 361 iounmap(par->vdc_mem); 362 release_mem_region(par->vdc_mem_base, par->vdc_mem_size); 363 } 364 365 /* 366 * Release and uninit the VDC and GPU. 367 */ 368 369 static void vmlfb_release_devices(struct vml_par *par) 370 { 371 if (atomic_dec_and_test(&par->refcount)) { 372 pci_disable_device(par->gpu); 373 pci_disable_device(par->vdc); 374 } 375 } 376 377 /* 378 * Free up allocated resources for a device. 379 */ 380 381 static void vml_pci_remove(struct pci_dev *dev) 382 { 383 struct fb_info *info; 384 struct vml_info *vinfo; 385 struct vml_par *par; 386 387 info = pci_get_drvdata(dev); 388 if (info) { 389 vinfo = container_of(info, struct vml_info, info); 390 par = vinfo->par; 391 mutex_lock(&vml_mutex); 392 unregister_framebuffer(info); 393 fb_dealloc_cmap(&info->cmap); 394 vmlfb_free_vram(vinfo); 395 vmlfb_disable_mmio(par); 396 vmlfb_release_devices(par); 397 kfree(vinfo); 398 kfree(par); 399 mutex_unlock(&vml_mutex); 400 } 401 } 402 403 static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var) 404 { 405 switch (var->bits_per_pixel) { 406 case 16: 407 var->blue.offset = 0; 408 var->blue.length = 5; 409 var->green.offset = 5; 410 var->green.length = 5; 411 var->red.offset = 10; 412 var->red.length = 5; 413 var->transp.offset = 15; 414 var->transp.length = 1; 415 break; 416 case 32: 417 var->blue.offset = 0; 418 var->blue.length = 8; 419 var->green.offset = 8; 420 var->green.length = 8; 421 var->red.offset = 16; 422 var->red.length = 8; 423 var->transp.offset = 24; 424 var->transp.length = 0; 425 break; 426 default: 427 break; 428 } 429 430 var->blue.msb_right = var->green.msb_right = 431 var->red.msb_right = var->transp.msb_right = 0; 432 } 433 434 /* 435 * Device initialization. 436 * We initialize one vml_par struct per device and one vml_info 437 * struct per pipe. Currently we have only one pipe. 438 */ 439 440 static int vml_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 441 { 442 struct vml_info *vinfo; 443 struct fb_info *info; 444 struct vml_par *par; 445 int err = 0; 446 447 par = kzalloc(sizeof(*par), GFP_KERNEL); 448 if (par == NULL) 449 return -ENOMEM; 450 451 vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL); 452 if (vinfo == NULL) { 453 err = -ENOMEM; 454 goto out_err_0; 455 } 456 457 vinfo->par = par; 458 par->vdc = dev; 459 atomic_set(&par->refcount, 1); 460 461 switch (id->device) { 462 case VML_DEVICE_VDC: 463 if ((err = vmlfb_get_gpu(par))) 464 goto out_err_1; 465 pci_set_drvdata(dev, &vinfo->info); 466 break; 467 default: 468 err = -ENODEV; 469 goto out_err_1; 470 } 471 472 info = &vinfo->info; 473 info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK; 474 475 err = vmlfb_enable_mmio(par); 476 if (err) 477 goto out_err_2; 478 479 err = vmlfb_alloc_vram(vinfo, vml_mem_requested, 480 vml_mem_contig, vml_mem_min); 481 if (err) 482 goto out_err_3; 483 484 strcpy(info->fix.id, "Vermilion Range"); 485 info->fix.mmio_start = 0; 486 info->fix.mmio_len = 0; 487 info->fix.smem_start = vinfo->vram_start; 488 info->fix.smem_len = vinfo->vram_contig_size; 489 info->fix.type = FB_TYPE_PACKED_PIXELS; 490 info->fix.visual = FB_VISUAL_TRUECOLOR; 491 info->fix.ypanstep = 1; 492 info->fix.xpanstep = 1; 493 info->fix.ywrapstep = 0; 494 info->fix.accel = FB_ACCEL_NONE; 495 info->screen_base = vinfo->vram_logical; 496 info->pseudo_palette = vinfo->pseudo_palette; 497 info->par = par; 498 info->fbops = &vmlfb_ops; 499 info->device = &dev->dev; 500 501 INIT_LIST_HEAD(&vinfo->head); 502 vinfo->pipe_disabled = 1; 503 vinfo->cur_blank_mode = FB_BLANK_UNBLANK; 504 505 info->var.grayscale = 0; 506 info->var.bits_per_pixel = 16; 507 vmlfb_set_pref_pixel_format(&info->var); 508 509 if (!fb_find_mode 510 (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) { 511 printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n"); 512 } 513 514 if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { 515 err = -ENOMEM; 516 goto out_err_4; 517 } 518 519 err = register_framebuffer(info); 520 if (err) { 521 printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n"); 522 goto out_err_5; 523 } 524 525 printk("Initialized vmlfb\n"); 526 527 return 0; 528 529 out_err_5: 530 fb_dealloc_cmap(&info->cmap); 531 out_err_4: 532 vmlfb_free_vram(vinfo); 533 out_err_3: 534 vmlfb_disable_mmio(par); 535 out_err_2: 536 vmlfb_release_devices(par); 537 out_err_1: 538 kfree(vinfo); 539 out_err_0: 540 kfree(par); 541 return err; 542 } 543 544 static int vmlfb_open(struct fb_info *info, int user) 545 { 546 /* 547 * Save registers here? 548 */ 549 return 0; 550 } 551 552 static int vmlfb_release(struct fb_info *info, int user) 553 { 554 /* 555 * Restore registers here. 556 */ 557 558 return 0; 559 } 560 561 static int vml_nearest_clock(int clock) 562 { 563 564 int i; 565 int cur_index; 566 int cur_diff; 567 int diff; 568 569 cur_index = 0; 570 cur_diff = clock - vml_clocks[0]; 571 cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; 572 for (i = 1; i < vml_num_clocks; ++i) { 573 diff = clock - vml_clocks[i]; 574 diff = (diff < 0) ? -diff : diff; 575 if (diff < cur_diff) { 576 cur_index = i; 577 cur_diff = diff; 578 } 579 } 580 return vml_clocks[cur_index]; 581 } 582 583 static int vmlfb_check_var_locked(struct fb_var_screeninfo *var, 584 struct vml_info *vinfo) 585 { 586 u32 pitch; 587 u64 mem; 588 int nearest_clock; 589 int clock; 590 int clock_diff; 591 struct fb_var_screeninfo v; 592 593 v = *var; 594 clock = PICOS2KHZ(var->pixclock); 595 596 if (subsys && subsys->nearest_clock) { 597 nearest_clock = subsys->nearest_clock(subsys, clock); 598 } else { 599 nearest_clock = vml_nearest_clock(clock); 600 } 601 602 /* 603 * Accept a 20% diff. 604 */ 605 606 clock_diff = nearest_clock - clock; 607 clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff; 608 if (clock_diff > clock / 5) { 609 #if 0 610 printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock); 611 #endif 612 return -EINVAL; 613 } 614 615 v.pixclock = KHZ2PICOS(nearest_clock); 616 617 if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) { 618 printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n"); 619 return -EINVAL; 620 } 621 if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) { 622 printk(KERN_DEBUG MODULE_NAME 623 ": Virtual resolution failure.\n"); 624 return -EINVAL; 625 } 626 switch (v.bits_per_pixel) { 627 case 0 ... 16: 628 v.bits_per_pixel = 16; 629 break; 630 case 17 ... 32: 631 v.bits_per_pixel = 32; 632 break; 633 default: 634 printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n", 635 var->bits_per_pixel); 636 return -EINVAL; 637 } 638 639 pitch = ALIGN((var->xres * var->bits_per_pixel) >> 3, 0x40); 640 mem = (u64)pitch * var->yres_virtual; 641 if (mem > vinfo->vram_contig_size) { 642 return -ENOMEM; 643 } 644 645 switch (v.bits_per_pixel) { 646 case 16: 647 if (var->blue.offset != 0 || 648 var->blue.length != 5 || 649 var->green.offset != 5 || 650 var->green.length != 5 || 651 var->red.offset != 10 || 652 var->red.length != 5 || 653 var->transp.offset != 15 || var->transp.length != 1) { 654 vmlfb_set_pref_pixel_format(&v); 655 } 656 break; 657 case 32: 658 if (var->blue.offset != 0 || 659 var->blue.length != 8 || 660 var->green.offset != 8 || 661 var->green.length != 8 || 662 var->red.offset != 16 || 663 var->red.length != 8 || 664 (var->transp.length != 0 && var->transp.length != 8) || 665 (var->transp.length == 8 && var->transp.offset != 24)) { 666 vmlfb_set_pref_pixel_format(&v); 667 } 668 break; 669 default: 670 return -EINVAL; 671 } 672 673 *var = v; 674 675 return 0; 676 } 677 678 static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 679 { 680 struct vml_info *vinfo = container_of(info, struct vml_info, info); 681 int ret; 682 683 mutex_lock(&vml_mutex); 684 ret = vmlfb_check_var_locked(var, vinfo); 685 mutex_unlock(&vml_mutex); 686 687 return ret; 688 } 689 690 static void vml_wait_vblank(struct vml_info *vinfo) 691 { 692 /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ 693 mdelay(20); 694 } 695 696 static void vmlfb_disable_pipe(struct vml_info *vinfo) 697 { 698 struct vml_par *par = vinfo->par; 699 700 /* Disable the MDVO pad */ 701 VML_WRITE32(par, VML_RCOMPSTAT, 0); 702 while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ; 703 704 /* Disable display planes */ 705 VML_WRITE32(par, VML_DSPCCNTR, 706 VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE); 707 (void)VML_READ32(par, VML_DSPCCNTR); 708 /* Wait for vblank for the disable to take effect */ 709 vml_wait_vblank(vinfo); 710 711 /* Next, disable display pipes */ 712 VML_WRITE32(par, VML_PIPEACONF, 0); 713 (void)VML_READ32(par, VML_PIPEACONF); 714 715 vinfo->pipe_disabled = 1; 716 } 717 718 #ifdef VERMILION_DEBUG 719 static void vml_dump_regs(struct vml_info *vinfo) 720 { 721 struct vml_par *par = vinfo->par; 722 723 printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n"); 724 printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A : 0x%08x\n", 725 (unsigned)VML_READ32(par, VML_HTOTAL_A)); 726 printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A : 0x%08x\n", 727 (unsigned)VML_READ32(par, VML_HBLANK_A)); 728 printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A : 0x%08x\n", 729 (unsigned)VML_READ32(par, VML_HSYNC_A)); 730 printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A : 0x%08x\n", 731 (unsigned)VML_READ32(par, VML_VTOTAL_A)); 732 printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A : 0x%08x\n", 733 (unsigned)VML_READ32(par, VML_VBLANK_A)); 734 printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A : 0x%08x\n", 735 (unsigned)VML_READ32(par, VML_VSYNC_A)); 736 printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE : 0x%08x\n", 737 (unsigned)VML_READ32(par, VML_DSPCSTRIDE)); 738 printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE : 0x%08x\n", 739 (unsigned)VML_READ32(par, VML_DSPCSIZE)); 740 printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS : 0x%08x\n", 741 (unsigned)VML_READ32(par, VML_DSPCPOS)); 742 printk(KERN_DEBUG MODULE_NAME ": \tDSPARB : 0x%08x\n", 743 (unsigned)VML_READ32(par, VML_DSPARB)); 744 printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR : 0x%08x\n", 745 (unsigned)VML_READ32(par, VML_DSPCADDR)); 746 printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A : 0x%08x\n", 747 (unsigned)VML_READ32(par, VML_BCLRPAT_A)); 748 printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A : 0x%08x\n", 749 (unsigned)VML_READ32(par, VML_CANVSCLR_A)); 750 printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC : 0x%08x\n", 751 (unsigned)VML_READ32(par, VML_PIPEASRC)); 752 printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF : 0x%08x\n", 753 (unsigned)VML_READ32(par, VML_PIPEACONF)); 754 printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR : 0x%08x\n", 755 (unsigned)VML_READ32(par, VML_DSPCCNTR)); 756 printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT : 0x%08x\n", 757 (unsigned)VML_READ32(par, VML_RCOMPSTAT)); 758 printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n"); 759 } 760 #endif 761 762 static int vmlfb_set_par_locked(struct vml_info *vinfo) 763 { 764 struct vml_par *par = vinfo->par; 765 struct fb_info *info = &vinfo->info; 766 struct fb_var_screeninfo *var = &info->var; 767 u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end; 768 u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end; 769 u32 dspcntr; 770 int clock; 771 772 vinfo->bytes_per_pixel = var->bits_per_pixel >> 3; 773 vinfo->stride = ALIGN(var->xres_virtual * vinfo->bytes_per_pixel, 0x40); 774 info->fix.line_length = vinfo->stride; 775 776 if (!subsys) 777 return 0; 778 779 htotal = 780 var->xres + var->right_margin + var->hsync_len + var->left_margin; 781 hactive = var->xres; 782 hblank_start = var->xres; 783 hblank_end = htotal; 784 hsync_start = hactive + var->right_margin; 785 hsync_end = hsync_start + var->hsync_len; 786 787 vtotal = 788 var->yres + var->lower_margin + var->vsync_len + var->upper_margin; 789 vactive = var->yres; 790 vblank_start = var->yres; 791 vblank_end = vtotal; 792 vsync_start = vactive + var->lower_margin; 793 vsync_end = vsync_start + var->vsync_len; 794 795 dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS; 796 clock = PICOS2KHZ(var->pixclock); 797 798 if (subsys->nearest_clock) { 799 clock = subsys->nearest_clock(subsys, clock); 800 } else { 801 clock = vml_nearest_clock(clock); 802 } 803 printk(KERN_DEBUG MODULE_NAME 804 ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal, 805 ((clock / htotal) * 1000) / vtotal); 806 807 switch (var->bits_per_pixel) { 808 case 16: 809 dspcntr |= VML_GFX_ARGB1555; 810 break; 811 case 32: 812 if (var->transp.length == 8) 813 dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT; 814 else 815 dspcntr |= VML_GFX_RGB0888; 816 break; 817 default: 818 return -EINVAL; 819 } 820 821 vmlfb_disable_pipe(vinfo); 822 mb(); 823 824 if (subsys->set_clock) 825 subsys->set_clock(subsys, clock); 826 else 827 return -EINVAL; 828 829 VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1)); 830 VML_WRITE32(par, VML_HBLANK_A, 831 ((hblank_end - 1) << 16) | (hblank_start - 1)); 832 VML_WRITE32(par, VML_HSYNC_A, 833 ((hsync_end - 1) << 16) | (hsync_start - 1)); 834 VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1)); 835 VML_WRITE32(par, VML_VBLANK_A, 836 ((vblank_end - 1) << 16) | (vblank_start - 1)); 837 VML_WRITE32(par, VML_VSYNC_A, 838 ((vsync_end - 1) << 16) | (vsync_start - 1)); 839 VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride); 840 VML_WRITE32(par, VML_DSPCSIZE, 841 ((var->yres - 1) << 16) | (var->xres - 1)); 842 VML_WRITE32(par, VML_DSPCPOS, 0x00000000); 843 VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT); 844 VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000); 845 VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000); 846 VML_WRITE32(par, VML_PIPEASRC, 847 ((var->xres - 1) << 16) | (var->yres - 1)); 848 849 wmb(); 850 VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE); 851 wmb(); 852 VML_WRITE32(par, VML_DSPCCNTR, dspcntr); 853 wmb(); 854 VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + 855 var->yoffset * vinfo->stride + 856 var->xoffset * vinfo->bytes_per_pixel); 857 858 VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE); 859 860 while (!(VML_READ32(par, VML_RCOMPSTAT) & 861 (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ; 862 863 vinfo->pipe_disabled = 0; 864 #ifdef VERMILION_DEBUG 865 vml_dump_regs(vinfo); 866 #endif 867 868 return 0; 869 } 870 871 static int vmlfb_set_par(struct fb_info *info) 872 { 873 struct vml_info *vinfo = container_of(info, struct vml_info, info); 874 int ret; 875 876 mutex_lock(&vml_mutex); 877 list_move(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode); 878 ret = vmlfb_set_par_locked(vinfo); 879 880 mutex_unlock(&vml_mutex); 881 return ret; 882 } 883 884 static int vmlfb_blank_locked(struct vml_info *vinfo) 885 { 886 struct vml_par *par = vinfo->par; 887 u32 cur = VML_READ32(par, VML_PIPEACONF); 888 889 switch (vinfo->cur_blank_mode) { 890 case FB_BLANK_UNBLANK: 891 if (vinfo->pipe_disabled) { 892 vmlfb_set_par_locked(vinfo); 893 } 894 VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER); 895 (void)VML_READ32(par, VML_PIPEACONF); 896 break; 897 case FB_BLANK_NORMAL: 898 if (vinfo->pipe_disabled) { 899 vmlfb_set_par_locked(vinfo); 900 } 901 VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER); 902 (void)VML_READ32(par, VML_PIPEACONF); 903 break; 904 case FB_BLANK_VSYNC_SUSPEND: 905 case FB_BLANK_HSYNC_SUSPEND: 906 if (!vinfo->pipe_disabled) { 907 vmlfb_disable_pipe(vinfo); 908 } 909 break; 910 case FB_BLANK_POWERDOWN: 911 if (!vinfo->pipe_disabled) { 912 vmlfb_disable_pipe(vinfo); 913 } 914 break; 915 default: 916 return -EINVAL; 917 } 918 919 return 0; 920 } 921 922 static int vmlfb_blank(int blank_mode, struct fb_info *info) 923 { 924 struct vml_info *vinfo = container_of(info, struct vml_info, info); 925 int ret; 926 927 mutex_lock(&vml_mutex); 928 vinfo->cur_blank_mode = blank_mode; 929 ret = vmlfb_blank_locked(vinfo); 930 mutex_unlock(&vml_mutex); 931 return ret; 932 } 933 934 static int vmlfb_pan_display(struct fb_var_screeninfo *var, 935 struct fb_info *info) 936 { 937 struct vml_info *vinfo = container_of(info, struct vml_info, info); 938 struct vml_par *par = vinfo->par; 939 940 mutex_lock(&vml_mutex); 941 VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + 942 var->yoffset * vinfo->stride + 943 var->xoffset * vinfo->bytes_per_pixel); 944 (void)VML_READ32(par, VML_DSPCADDR); 945 mutex_unlock(&vml_mutex); 946 947 return 0; 948 } 949 950 static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 951 u_int transp, struct fb_info *info) 952 { 953 u32 v; 954 955 if (regno >= 16) 956 return -EINVAL; 957 958 if (info->var.grayscale) { 959 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 960 } 961 962 if (info->fix.visual != FB_VISUAL_TRUECOLOR) 963 return -EINVAL; 964 965 red = VML_TOHW(red, info->var.red.length); 966 blue = VML_TOHW(blue, info->var.blue.length); 967 green = VML_TOHW(green, info->var.green.length); 968 transp = VML_TOHW(transp, info->var.transp.length); 969 970 v = (red << info->var.red.offset) | 971 (green << info->var.green.offset) | 972 (blue << info->var.blue.offset) | 973 (transp << info->var.transp.offset); 974 975 switch (info->var.bits_per_pixel) { 976 case 16: 977 ((u32 *) info->pseudo_palette)[regno] = v; 978 break; 979 case 24: 980 case 32: 981 ((u32 *) info->pseudo_palette)[regno] = v; 982 break; 983 } 984 return 0; 985 } 986 987 static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) 988 { 989 struct vml_info *vinfo = container_of(info, struct vml_info, info); 990 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 991 int ret; 992 unsigned long prot; 993 994 ret = vmlfb_vram_offset(vinfo, offset); 995 if (ret) 996 return -EINVAL; 997 998 prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK; 999 pgprot_val(vma->vm_page_prot) = 1000 prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS); 1001 1002 return vm_iomap_memory(vma, vinfo->vram_start, 1003 vinfo->vram_contig_size); 1004 } 1005 1006 static int vmlfb_sync(struct fb_info *info) 1007 { 1008 return 0; 1009 } 1010 1011 static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1012 { 1013 return -EINVAL; /* just to force soft_cursor() call */ 1014 } 1015 1016 static struct fb_ops vmlfb_ops = { 1017 .owner = THIS_MODULE, 1018 .fb_open = vmlfb_open, 1019 .fb_release = vmlfb_release, 1020 .fb_check_var = vmlfb_check_var, 1021 .fb_set_par = vmlfb_set_par, 1022 .fb_blank = vmlfb_blank, 1023 .fb_pan_display = vmlfb_pan_display, 1024 .fb_fillrect = cfb_fillrect, 1025 .fb_copyarea = cfb_copyarea, 1026 .fb_imageblit = cfb_imageblit, 1027 .fb_cursor = vmlfb_cursor, 1028 .fb_sync = vmlfb_sync, 1029 .fb_mmap = vmlfb_mmap, 1030 .fb_setcolreg = vmlfb_setcolreg 1031 }; 1032 1033 static const struct pci_device_id vml_ids[] = { 1034 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)}, 1035 {0} 1036 }; 1037 1038 static struct pci_driver vmlfb_pci_driver = { 1039 .name = "vmlfb", 1040 .id_table = vml_ids, 1041 .probe = vml_pci_probe, 1042 .remove = vml_pci_remove, 1043 }; 1044 1045 static void __exit vmlfb_cleanup(void) 1046 { 1047 pci_unregister_driver(&vmlfb_pci_driver); 1048 } 1049 1050 static int __init vmlfb_init(void) 1051 { 1052 1053 #ifndef MODULE 1054 char *option = NULL; 1055 1056 if (fb_get_options(MODULE_NAME, &option)) 1057 return -ENODEV; 1058 #endif 1059 1060 printk(KERN_DEBUG MODULE_NAME ": initializing\n"); 1061 mutex_init(&vml_mutex); 1062 INIT_LIST_HEAD(&global_no_mode); 1063 INIT_LIST_HEAD(&global_has_mode); 1064 1065 return pci_register_driver(&vmlfb_pci_driver); 1066 } 1067 1068 int vmlfb_register_subsys(struct vml_sys *sys) 1069 { 1070 struct vml_info *entry; 1071 struct list_head *list; 1072 u32 save_activate; 1073 1074 mutex_lock(&vml_mutex); 1075 if (subsys != NULL) { 1076 subsys->restore(subsys); 1077 } 1078 subsys = sys; 1079 subsys->save(subsys); 1080 1081 /* 1082 * We need to restart list traversal for each item, since we 1083 * release the list mutex in the loop. 1084 */ 1085 1086 list = global_no_mode.next; 1087 while (list != &global_no_mode) { 1088 list_del_init(list); 1089 entry = list_entry(list, struct vml_info, head); 1090 1091 /* 1092 * First, try the current mode which might not be 1093 * completely validated with respect to the pixel clock. 1094 */ 1095 1096 if (!vmlfb_check_var_locked(&entry->info.var, entry)) { 1097 vmlfb_set_par_locked(entry); 1098 list_add_tail(list, &global_has_mode); 1099 } else { 1100 1101 /* 1102 * Didn't work. Try to find another mode, 1103 * that matches this subsys. 1104 */ 1105 1106 mutex_unlock(&vml_mutex); 1107 save_activate = entry->info.var.activate; 1108 entry->info.var.bits_per_pixel = 16; 1109 vmlfb_set_pref_pixel_format(&entry->info.var); 1110 if (fb_find_mode(&entry->info.var, 1111 &entry->info, 1112 vml_default_mode, NULL, 0, NULL, 16)) { 1113 entry->info.var.activate |= 1114 FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; 1115 fb_set_var(&entry->info, &entry->info.var); 1116 } else { 1117 printk(KERN_ERR MODULE_NAME 1118 ": Sorry. no mode found for this subsys.\n"); 1119 } 1120 entry->info.var.activate = save_activate; 1121 mutex_lock(&vml_mutex); 1122 } 1123 vmlfb_blank_locked(entry); 1124 list = global_no_mode.next; 1125 } 1126 mutex_unlock(&vml_mutex); 1127 1128 printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n", 1129 subsys->name ? subsys->name : "unknown"); 1130 return 0; 1131 } 1132 1133 EXPORT_SYMBOL_GPL(vmlfb_register_subsys); 1134 1135 void vmlfb_unregister_subsys(struct vml_sys *sys) 1136 { 1137 struct vml_info *entry, *next; 1138 1139 mutex_lock(&vml_mutex); 1140 if (subsys != sys) { 1141 mutex_unlock(&vml_mutex); 1142 return; 1143 } 1144 subsys->restore(subsys); 1145 subsys = NULL; 1146 list_for_each_entry_safe(entry, next, &global_has_mode, head) { 1147 printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n"); 1148 vmlfb_disable_pipe(entry); 1149 list_move_tail(&entry->head, &global_no_mode); 1150 } 1151 mutex_unlock(&vml_mutex); 1152 } 1153 1154 EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys); 1155 1156 module_init(vmlfb_init); 1157 module_exit(vmlfb_cleanup); 1158 1159 MODULE_AUTHOR("Tungsten Graphics"); 1160 MODULE_DESCRIPTION("Initialization of the Vermilion display devices"); 1161 MODULE_VERSION("1.0.0"); 1162 MODULE_LICENSE("GPL"); 1163