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