aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/vt8623fb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:56:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:56:52 -0400
commit4cc4d24efce4672f9b0e7fa27963770ae602998f (patch)
treee69e7209db5500164eedb82c46ea657499b72287 /drivers/video/vt8623fb.c
parentb81a618dcd3ea99de292dbe624f41ca68f464376 (diff)
parent56be1416453c31d32f984328b5193489ab63ffcf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6: (140 commits) MAINTAINERS: de-orphan fbdev. MAINTAINERS: Add file pattern for fb dt bindings. video: Move sm501fb devicetree binding documentation to a better place. fbcon: fix situation where fbcon gets deinitialised and can't reinit. video, sm501: add OF binding to support SM501 video, sm501: add edid and commandline support video, sm501: add I/O functions for use on powerpc video: Fix EDID macros H_SYNC_WIDTH and H_SYNC_OFFSET fbcon: Bugfix soft cursor detection in Tile Blitting video: add missing framebuffer_release in error path video: metronomefb: add __devexit_p around reference to metronomefb_remove video: hecubafb: add __devexit_p around reference to hecubafb_remove drivers:video:aty:radeon_base Fix typo occationally to occasionally atmel_lcdfb: add fb_blank function atmel_lcdfb: implement inverted contrast pwm video: s3c-fb: return proper error if clk_get fails uvesafb,vesafb: create WC or WB PAT-entries video: ffb: fix ffb_probe error path radeonfb: Let hwmon driver probe the "monid" I2C bus fbdev: sh_mobile_lcdc: checking NULL instead of IS_ERR() ...
Diffstat (limited to 'drivers/video/vt8623fb.c')
-rw-r--r--drivers/video/vt8623fb.c157
1 files changed, 91 insertions, 66 deletions
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index a2965ab92cf..f9b3e3dc242 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -121,13 +121,19 @@ MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, d
121 121
122/* ------------------------------------------------------------------------- */ 122/* ------------------------------------------------------------------------- */
123 123
124static void vt8623fb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
125{
126 struct vt8623fb_info *par = info->par;
127
128 svga_tilecursor(par->state.vgabase, info, cursor);
129}
124 130
125static struct fb_tile_ops vt8623fb_tile_ops = { 131static struct fb_tile_ops vt8623fb_tile_ops = {
126 .fb_settile = svga_settile, 132 .fb_settile = svga_settile,
127 .fb_tilecopy = svga_tilecopy, 133 .fb_tilecopy = svga_tilecopy,
128 .fb_tilefill = svga_tilefill, 134 .fb_tilefill = svga_tilefill,
129 .fb_tileblit = svga_tileblit, 135 .fb_tileblit = svga_tileblit,
130 .fb_tilecursor = svga_tilecursor, 136 .fb_tilecursor = vt8623fb_tilecursor,
131 .fb_get_tilemax = svga_get_tilemax, 137 .fb_get_tilemax = svga_get_tilemax,
132}; 138};
133 139
@@ -253,6 +259,7 @@ static void vt8623fb_fillrect(struct fb_info *info, const struct fb_fillrect *re
253 259
254static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock) 260static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
255{ 261{
262 struct vt8623fb_info *par = info->par;
256 u16 m, n, r; 263 u16 m, n, r;
257 u8 regval; 264 u8 regval;
258 int rv; 265 int rv;
@@ -264,18 +271,18 @@ static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)
264 } 271 }
265 272
266 /* Set VGA misc register */ 273 /* Set VGA misc register */
267 regval = vga_r(NULL, VGA_MIS_R); 274 regval = vga_r(par->state.vgabase, VGA_MIS_R);
268 vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); 275 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
269 276
270 /* Set clock registers */ 277 /* Set clock registers */
271 vga_wseq(NULL, 0x46, (n | (r << 6))); 278 vga_wseq(par->state.vgabase, 0x46, (n | (r << 6)));
272 vga_wseq(NULL, 0x47, m); 279 vga_wseq(par->state.vgabase, 0x47, m);
273 280
274 udelay(1000); 281 udelay(1000);
275 282
276 /* PLL reset */ 283 /* PLL reset */
277 svga_wseq_mask(0x40, 0x02, 0x02); 284 svga_wseq_mask(par->state.vgabase, 0x40, 0x02, 0x02);
278 svga_wseq_mask(0x40, 0x00, 0x02); 285 svga_wseq_mask(par->state.vgabase, 0x40, 0x00, 0x02);
279} 286}
280 287
281 288
@@ -285,7 +292,10 @@ static int vt8623fb_open(struct fb_info *info, int user)
285 292
286 mutex_lock(&(par->open_lock)); 293 mutex_lock(&(par->open_lock));
287 if (par->ref_count == 0) { 294 if (par->ref_count == 0) {
295 void __iomem *vgabase = par->state.vgabase;
296
288 memset(&(par->state), 0, sizeof(struct vgastate)); 297 memset(&(par->state), 0, sizeof(struct vgastate));
298 par->state.vgabase = vgabase;
289 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP; 299 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
290 par->state.num_crtc = 0xA2; 300 par->state.num_crtc = 0xA2;
291 par->state.num_seq = 0x50; 301 par->state.num_seq = 0x50;
@@ -373,6 +383,7 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
373static int vt8623fb_set_par(struct fb_info *info) 383static int vt8623fb_set_par(struct fb_info *info)
374{ 384{
375 u32 mode, offset_value, fetch_value, screen_size; 385 u32 mode, offset_value, fetch_value, screen_size;
386 struct vt8623fb_info *par = info->par;
376 u32 bpp = info->var.bits_per_pixel; 387 u32 bpp = info->var.bits_per_pixel;
377 388
378 if (bpp != 0) { 389 if (bpp != 0) {
@@ -414,82 +425,82 @@ static int vt8623fb_set_par(struct fb_info *info)
414 info->var.activate = FB_ACTIVATE_NOW; 425 info->var.activate = FB_ACTIVATE_NOW;
415 426
416 /* Unlock registers */ 427 /* Unlock registers */
417 svga_wseq_mask(0x10, 0x01, 0x01); 428 svga_wseq_mask(par->state.vgabase, 0x10, 0x01, 0x01);
418 svga_wcrt_mask(0x11, 0x00, 0x80); 429 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
419 svga_wcrt_mask(0x47, 0x00, 0x01); 430 svga_wcrt_mask(par->state.vgabase, 0x47, 0x00, 0x01);
420 431
421 /* Device, screen and sync off */ 432 /* Device, screen and sync off */
422 svga_wseq_mask(0x01, 0x20, 0x20); 433 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
423 svga_wcrt_mask(0x36, 0x30, 0x30); 434 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
424 svga_wcrt_mask(0x17, 0x00, 0x80); 435 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
425 436
426 /* Set default values */ 437 /* Set default values */
427 svga_set_default_gfx_regs(); 438 svga_set_default_gfx_regs(par->state.vgabase);
428 svga_set_default_atc_regs(); 439 svga_set_default_atc_regs(par->state.vgabase);
429 svga_set_default_seq_regs(); 440 svga_set_default_seq_regs(par->state.vgabase);
430 svga_set_default_crt_regs(); 441 svga_set_default_crt_regs(par->state.vgabase);
431 svga_wcrt_multi(vt8623_line_compare_regs, 0xFFFFFFFF); 442 svga_wcrt_multi(par->state.vgabase, vt8623_line_compare_regs, 0xFFFFFFFF);
432 svga_wcrt_multi(vt8623_start_address_regs, 0); 443 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, 0);
433 444
434 svga_wcrt_multi(vt8623_offset_regs, offset_value); 445 svga_wcrt_multi(par->state.vgabase, vt8623_offset_regs, offset_value);
435 svga_wseq_multi(vt8623_fetch_count_regs, fetch_value); 446 svga_wseq_multi(par->state.vgabase, vt8623_fetch_count_regs, fetch_value);
436 447
437 /* Clear H/V Skew */ 448 /* Clear H/V Skew */
438 svga_wcrt_mask(0x03, 0x00, 0x60); 449 svga_wcrt_mask(par->state.vgabase, 0x03, 0x00, 0x60);
439 svga_wcrt_mask(0x05, 0x00, 0x60); 450 svga_wcrt_mask(par->state.vgabase, 0x05, 0x00, 0x60);
440 451
441 if (info->var.vmode & FB_VMODE_DOUBLE) 452 if (info->var.vmode & FB_VMODE_DOUBLE)
442 svga_wcrt_mask(0x09, 0x80, 0x80); 453 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
443 else 454 else
444 svga_wcrt_mask(0x09, 0x00, 0x80); 455 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
445 456
446 svga_wseq_mask(0x1E, 0xF0, 0xF0); // DI/DVP bus 457 svga_wseq_mask(par->state.vgabase, 0x1E, 0xF0, 0xF0); // DI/DVP bus
447 svga_wseq_mask(0x2A, 0x0F, 0x0F); // DI/DVP bus 458 svga_wseq_mask(par->state.vgabase, 0x2A, 0x0F, 0x0F); // DI/DVP bus
448 svga_wseq_mask(0x16, 0x08, 0xBF); // FIFO read threshold 459 svga_wseq_mask(par->state.vgabase, 0x16, 0x08, 0xBF); // FIFO read threshold
449 vga_wseq(NULL, 0x17, 0x1F); // FIFO depth 460 vga_wseq(par->state.vgabase, 0x17, 0x1F); // FIFO depth
450 vga_wseq(NULL, 0x18, 0x4E); 461 vga_wseq(par->state.vgabase, 0x18, 0x4E);
451 svga_wseq_mask(0x1A, 0x08, 0x08); // enable MMIO ? 462 svga_wseq_mask(par->state.vgabase, 0x1A, 0x08, 0x08); // enable MMIO ?
452 463
453 vga_wcrt(NULL, 0x32, 0x00); 464 vga_wcrt(par->state.vgabase, 0x32, 0x00);
454 vga_wcrt(NULL, 0x34, 0x00); 465 vga_wcrt(par->state.vgabase, 0x34, 0x00);
455 vga_wcrt(NULL, 0x6A, 0x80); 466 vga_wcrt(par->state.vgabase, 0x6A, 0x80);
456 vga_wcrt(NULL, 0x6A, 0xC0); 467 vga_wcrt(par->state.vgabase, 0x6A, 0xC0);
457 468
458 vga_wgfx(NULL, 0x20, 0x00); 469 vga_wgfx(par->state.vgabase, 0x20, 0x00);
459 vga_wgfx(NULL, 0x21, 0x00); 470 vga_wgfx(par->state.vgabase, 0x21, 0x00);
460 vga_wgfx(NULL, 0x22, 0x00); 471 vga_wgfx(par->state.vgabase, 0x22, 0x00);
461 472
462 /* Set SR15 according to number of bits per pixel */ 473 /* Set SR15 according to number of bits per pixel */
463 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix)); 474 mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix));
464 switch (mode) { 475 switch (mode) {
465 case 0: 476 case 0:
466 pr_debug("fb%d: text mode\n", info->node); 477 pr_debug("fb%d: text mode\n", info->node);
467 svga_set_textmode_vga_regs(); 478 svga_set_textmode_vga_regs(par->state.vgabase);
468 svga_wseq_mask(0x15, 0x00, 0xFE); 479 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
469 svga_wcrt_mask(0x11, 0x60, 0x70); 480 svga_wcrt_mask(par->state.vgabase, 0x11, 0x60, 0x70);
470 break; 481 break;
471 case 1: 482 case 1:
472 pr_debug("fb%d: 4 bit pseudocolor\n", info->node); 483 pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
473 vga_wgfx(NULL, VGA_GFX_MODE, 0x40); 484 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
474 svga_wseq_mask(0x15, 0x20, 0xFE); 485 svga_wseq_mask(par->state.vgabase, 0x15, 0x20, 0xFE);
475 svga_wcrt_mask(0x11, 0x00, 0x70); 486 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
476 break; 487 break;
477 case 2: 488 case 2:
478 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); 489 pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
479 svga_wseq_mask(0x15, 0x00, 0xFE); 490 svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);
480 svga_wcrt_mask(0x11, 0x00, 0x70); 491 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);
481 break; 492 break;
482 case 3: 493 case 3:
483 pr_debug("fb%d: 8 bit pseudocolor\n", info->node); 494 pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
484 svga_wseq_mask(0x15, 0x22, 0xFE); 495 svga_wseq_mask(par->state.vgabase, 0x15, 0x22, 0xFE);
485 break; 496 break;
486 case 4: 497 case 4:
487 pr_debug("fb%d: 5/6/5 truecolor\n", info->node); 498 pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
488 svga_wseq_mask(0x15, 0xB6, 0xFE); 499 svga_wseq_mask(par->state.vgabase, 0x15, 0xB6, 0xFE);
489 break; 500 break;
490 case 5: 501 case 5:
491 pr_debug("fb%d: 8/8/8 truecolor\n", info->node); 502 pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
492 svga_wseq_mask(0x15, 0xAE, 0xFE); 503 svga_wseq_mask(par->state.vgabase, 0x15, 0xAE, 0xFE);
493 break; 504 break;
494 default: 505 default:
495 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n"); 506 printk(KERN_ERR "vt8623fb: unsupported mode - bug\n");
@@ -497,16 +508,16 @@ static int vt8623fb_set_par(struct fb_info *info)
497 } 508 }
498 509
499 vt8623_set_pixclock(info, info->var.pixclock); 510 vt8623_set_pixclock(info, info->var.pixclock);
500 svga_set_timings(&vt8623_timing_regs, &(info->var), 1, 1, 511 svga_set_timings(par->state.vgabase, &vt8623_timing_regs, &(info->var), 1, 1,
501 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1, 512 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
502 1, info->node); 513 1, info->node);
503 514
504 memset_io(info->screen_base, 0x00, screen_size); 515 memset_io(info->screen_base, 0x00, screen_size);
505 516
506 /* Device and screen back on */ 517 /* Device and screen back on */
507 svga_wcrt_mask(0x17, 0x80, 0x80); 518 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
508 svga_wcrt_mask(0x36, 0x00, 0x30); 519 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
509 svga_wseq_mask(0x01, 0x00, 0x20); 520 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
510 521
511 return 0; 522 return 0;
512} 523}
@@ -569,31 +580,33 @@ static int vt8623fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
569 580
570static int vt8623fb_blank(int blank_mode, struct fb_info *info) 581static int vt8623fb_blank(int blank_mode, struct fb_info *info)
571{ 582{
583 struct vt8623fb_info *par = info->par;
584
572 switch (blank_mode) { 585 switch (blank_mode) {
573 case FB_BLANK_UNBLANK: 586 case FB_BLANK_UNBLANK:
574 pr_debug("fb%d: unblank\n", info->node); 587 pr_debug("fb%d: unblank\n", info->node);
575 svga_wcrt_mask(0x36, 0x00, 0x30); 588 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
576 svga_wseq_mask(0x01, 0x00, 0x20); 589 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
577 break; 590 break;
578 case FB_BLANK_NORMAL: 591 case FB_BLANK_NORMAL:
579 pr_debug("fb%d: blank\n", info->node); 592 pr_debug("fb%d: blank\n", info->node);
580 svga_wcrt_mask(0x36, 0x00, 0x30); 593 svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);
581 svga_wseq_mask(0x01, 0x20, 0x20); 594 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
582 break; 595 break;
583 case FB_BLANK_HSYNC_SUSPEND: 596 case FB_BLANK_HSYNC_SUSPEND:
584 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node); 597 pr_debug("fb%d: DPMS standby (hsync off)\n", info->node);
585 svga_wcrt_mask(0x36, 0x10, 0x30); 598 svga_wcrt_mask(par->state.vgabase, 0x36, 0x10, 0x30);
586 svga_wseq_mask(0x01, 0x20, 0x20); 599 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
587 break; 600 break;
588 case FB_BLANK_VSYNC_SUSPEND: 601 case FB_BLANK_VSYNC_SUSPEND:
589 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node); 602 pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node);
590 svga_wcrt_mask(0x36, 0x20, 0x30); 603 svga_wcrt_mask(par->state.vgabase, 0x36, 0x20, 0x30);
591 svga_wseq_mask(0x01, 0x20, 0x20); 604 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
592 break; 605 break;
593 case FB_BLANK_POWERDOWN: 606 case FB_BLANK_POWERDOWN:
594 pr_debug("fb%d: DPMS off (no sync)\n", info->node); 607 pr_debug("fb%d: DPMS off (no sync)\n", info->node);
595 svga_wcrt_mask(0x36, 0x30, 0x30); 608 svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);
596 svga_wseq_mask(0x01, 0x20, 0x20); 609 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
597 break; 610 break;
598 } 611 }
599 612
@@ -603,6 +616,7 @@ static int vt8623fb_blank(int blank_mode, struct fb_info *info)
603 616
604static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 617static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
605{ 618{
619 struct vt8623fb_info *par = info->par;
606 unsigned int offset; 620 unsigned int offset;
607 621
608 /* Calculate the offset */ 622 /* Calculate the offset */
@@ -616,7 +630,7 @@ static int vt8623fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
616 } 630 }
617 631
618 /* Set the offset */ 632 /* Set the offset */
619 svga_wcrt_multi(vt8623_start_address_regs, offset); 633 svga_wcrt_multi(par->state.vgabase, vt8623_start_address_regs, offset);
620 634
621 return 0; 635 return 0;
622} 636}
@@ -647,6 +661,8 @@ static struct fb_ops vt8623fb_ops = {
647 661
648static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 662static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
649{ 663{
664 struct pci_bus_region bus_reg;
665 struct resource vga_res;
650 struct fb_info *info; 666 struct fb_info *info;
651 struct vt8623fb_info *par; 667 struct vt8623fb_info *par;
652 unsigned int memsize1, memsize2; 668 unsigned int memsize1, memsize2;
@@ -705,9 +721,18 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
705 goto err_iomap_2; 721 goto err_iomap_2;
706 } 722 }
707 723
724 bus_reg.start = 0;
725 bus_reg.end = 64 * 1024;
726
727 vga_res.flags = IORESOURCE_IO;
728
729 pcibios_bus_to_resource(dev, &vga_res, &bus_reg);
730
731 par->state.vgabase = (void __iomem *) vga_res.start;
732
708 /* Find how many physical memory there is on card */ 733 /* Find how many physical memory there is on card */
709 memsize1 = (vga_rseq(NULL, 0x34) + 1) >> 1; 734 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;
710 memsize2 = vga_rseq(NULL, 0x39) << 2; 735 memsize2 = vga_rseq(par->state.vgabase, 0x39) << 2;
711 736
712 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2)) 737 if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2))
713 info->screen_size = memsize1 << 20; 738 info->screen_size = memsize1 << 20;