aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/cirrusfb.c195
1 files changed, 74 insertions, 121 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 12f45520e5d3..bab713b63a0c 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -432,6 +432,53 @@ static int cirrusfb_check_mclk(struct fb_info *info, long freq)
432 return 0; 432 return 0;
433} 433}
434 434
435static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
436 struct fb_info *info)
437{
438 long freq;
439 long maxclock;
440 struct cirrusfb_info *cinfo = info->par;
441 unsigned maxclockidx = var->bits_per_pixel >> 3;
442
443 /* convert from ps to kHz */
444 freq = PICOS2KHZ(var->pixclock);
445
446 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
447
448 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
449 cinfo->multiplexing = 0;
450
451 /* If the frequency is greater than we can support, we might be able
452 * to use multiplexing for the video mode */
453 if (freq > maxclock) {
454 switch (cinfo->btype) {
455 case BT_ALPINE:
456 case BT_GD5480:
457 cinfo->multiplexing = 1;
458 break;
459
460 default:
461 dev_err(info->device,
462 "Frequency greater than maxclock (%ld kHz)\n",
463 maxclock);
464 return -EINVAL;
465 }
466 }
467#if 0
468 /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
469 * the VCLK is double the pixel clock. */
470 switch (var->bits_per_pixel) {
471 case 16:
472 case 32:
473 if (var->xres <= 800)
474 /* Xbh has this type of clock for 32-bit */
475 freq /= 2;
476 break;
477 }
478#endif
479 return 0;
480}
481
435static int cirrusfb_check_var(struct fb_var_screeninfo *var, 482static int cirrusfb_check_var(struct fb_var_screeninfo *var,
436 struct fb_info *info) 483 struct fb_info *info)
437{ 484{
@@ -449,7 +496,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
449 496
450 case 8: 497 case 8:
451 var->red.offset = 0; 498 var->red.offset = 0;
452 var->red.length = 6; 499 var->red.length = 8;
453 var->green = var->red; 500 var->green = var->red;
454 var->blue = var->red; 501 var->blue = var->red;
455 break; 502 break;
@@ -513,7 +560,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
513 return -EINVAL; 560 return -EINVAL;
514 } 561 }
515 562
516
517 if (var->xoffset < 0) 563 if (var->xoffset < 0)
518 var->xoffset = 0; 564 var->xoffset = 0;
519 if (var->yoffset < 0) 565 if (var->yoffset < 0)
@@ -544,80 +590,9 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
544 return -EINVAL; 590 return -EINVAL;
545 } 591 }
546 592
547 return 0; 593 if (cirrusfb_check_pixclock(var, info))
548} 594 return -EINVAL;
549
550static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
551 struct fb_info *info)
552{
553 long freq;
554 long maxclock;
555 int maxclockidx = var->bits_per_pixel >> 3;
556 struct cirrusfb_info *cinfo = info->par;
557
558 switch (var->bits_per_pixel) {
559 case 1:
560 info->fix.line_length = var->xres_virtual / 8;
561 info->fix.visual = FB_VISUAL_MONO10;
562 break;
563
564 case 8:
565 info->fix.line_length = var->xres_virtual;
566 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
567 break;
568
569 case 16:
570 case 32:
571 info->fix.line_length = var->xres_virtual * maxclockidx;
572 info->fix.visual = FB_VISUAL_TRUECOLOR;
573 break;
574
575 default:
576 dev_dbg(info->device,
577 "Unsupported bpp size: %d\n", var->bits_per_pixel);
578 assert(false);
579 /* should never occur */
580 break;
581 }
582
583 info->fix.type = FB_TYPE_PACKED_PIXELS;
584
585 /* convert from ps to kHz */
586 freq = PICOS2KHZ(var->pixclock);
587
588 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
589
590 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
591 cinfo->multiplexing = 0;
592
593 /* If the frequency is greater than we can support, we might be able
594 * to use multiplexing for the video mode */
595 if (freq > maxclock) {
596 switch (cinfo->btype) {
597 case BT_ALPINE:
598 case BT_GD5480:
599 cinfo->multiplexing = 1;
600 break;
601 595
602 default:
603 dev_err(info->device,
604 "Frequency greater than maxclock (%ld kHz)\n",
605 maxclock);
606 return -EINVAL;
607 }
608 }
609#if 0
610 /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
611 * the VCLK is double the pixel clock. */
612 switch (var->bits_per_pixel) {
613 case 16:
614 case 32:
615 if (var->xres <= 800)
616 /* Xbh has this type of clock for 32-bit */
617 freq /= 2;
618 break;
619 }
620#endif
621 return 0; 596 return 0;
622} 597}
623 598
@@ -653,7 +628,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
653 struct fb_var_screeninfo *var = &info->var; 628 struct fb_var_screeninfo *var = &info->var;
654 u8 __iomem *regbase = cinfo->regbase; 629 u8 __iomem *regbase = cinfo->regbase;
655 unsigned char tmp; 630 unsigned char tmp;
656 int err;
657 int pitch; 631 int pitch;
658 const struct cirrusfb_board_info_rec *bi; 632 const struct cirrusfb_board_info_rec *bi;
659 int hdispend, hsyncstart, hsyncend, htotal; 633 int hdispend, hsyncstart, hsyncend, htotal;
@@ -664,16 +638,28 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
664 638
665 dev_dbg(info->device, "Requested mode: %dx%dx%d\n", 639 dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
666 var->xres, var->yres, var->bits_per_pixel); 640 var->xres, var->yres, var->bits_per_pixel);
667 dev_dbg(info->device, "pixclock: %d\n", var->pixclock);
668 641
669 init_vgachip(info); 642 switch (var->bits_per_pixel) {
643 case 1:
644 info->fix.line_length = var->xres_virtual / 8;
645 info->fix.visual = FB_VISUAL_MONO10;
646 break;
670 647
671 err = cirrusfb_decode_var(var, info); 648 case 8:
672 if (err) { 649 info->fix.line_length = var->xres_virtual;
673 /* should never happen */ 650 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
674 dev_dbg(info->device, "mode change aborted. invalid var.\n"); 651 break;
675 return -EINVAL; 652
653 case 16:
654 case 32:
655 info->fix.line_length = var->xres_virtual *
656 var->bits_per_pixel >> 3;
657 info->fix.visual = FB_VISUAL_TRUECOLOR;
658 break;
676 } 659 }
660 info->fix.type = FB_TYPE_PACKED_PIXELS;
661
662 init_vgachip(info);
677 663
678 bi = &cirrusfb_board_info[cinfo->btype]; 664 bi = &cirrusfb_board_info[cinfo->btype];
679 665
@@ -873,9 +859,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
873 * address wrap, no compat. */ 859 * address wrap, no compat. */
874 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3); 860 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
875 861
876/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
877 * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
878
879 /* don't know if it would hurt to also program this if no interlaced */ 862 /* don't know if it would hurt to also program this if no interlaced */
880 /* mode is used, but I feel better this way.. :-) */ 863 /* mode is used, but I feel better this way.. :-) */
881 if (var->vmode & FB_VMODE_INTERLACED) 864 if (var->vmode & FB_VMODE_INTERLACED)
@@ -883,8 +866,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
883 else 866 else
884 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ 867 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
885 868
886 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
887
888 /* adjust horizontal/vertical sync type (low/high) */ 869 /* adjust horizontal/vertical sync type (low/high) */
889 /* enable display memory & CRTC I/O address for color mode */ 870 /* enable display memory & CRTC I/O address for color mode */
890 tmp = 0x03; 871 tmp = 0x03;
@@ -896,8 +877,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
896 tmp |= 0xc; 877 tmp |= 0xc;
897 WGen(cinfo, VGA_MIS_W, tmp); 878 WGen(cinfo, VGA_MIS_W, tmp);
898 879
899 /* Screen A Preset Row-Scan register */
900 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
901 /* text cursor on and start line */ 880 /* text cursor on and start line */
902 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0); 881 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
903 /* text cursor end line */ 882 /* text cursor end line */
@@ -1248,7 +1227,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1248 dev_dbg(info->device, "CRT1e: %d\n", tmp); 1227 dev_dbg(info->device, "CRT1e: %d\n", tmp);
1249 } 1228 }
1250 1229
1251
1252 /* pixel panning */ 1230 /* pixel panning */
1253 vga_wattr(regbase, CL_AR33, 0); 1231 vga_wattr(regbase, CL_AR33, 0);
1254 1232
@@ -1274,9 +1252,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1274 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp); 1252 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1275 dev_dbg(info->device, "CL_SEQR1: %d\n", tmp); 1253 dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1276 1254
1277 /* pan to requested offset */
1278 cirrusfb_pan_display(var, info);
1279
1280#ifdef CIRRUSFB_DEBUG 1255#ifdef CIRRUSFB_DEBUG
1281 cirrusfb_dbg_reg_dump(info, NULL); 1256 cirrusfb_dbg_reg_dump(info, NULL);
1282#endif 1257#endif
@@ -1332,8 +1307,7 @@ static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1332static int cirrusfb_pan_display(struct fb_var_screeninfo *var, 1307static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1333 struct fb_info *info) 1308 struct fb_info *info)
1334{ 1309{
1335 int xoffset = 0; 1310 int xoffset;
1336 int yoffset = 0;
1337 unsigned long base; 1311 unsigned long base;
1338 unsigned char tmp, xpix; 1312 unsigned char tmp, xpix;
1339 struct cirrusfb_info *cinfo = info->par; 1313 struct cirrusfb_info *cinfo = info->par;
@@ -1347,9 +1321,8 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1347 return -EINVAL; 1321 return -EINVAL;
1348 1322
1349 xoffset = var->xoffset * info->var.bits_per_pixel / 8; 1323 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1350 yoffset = var->yoffset;
1351 1324
1352 base = yoffset * info->fix.line_length + xoffset; 1325 base = var->yoffset * info->fix.line_length + xoffset;
1353 1326
1354 if (info->var.bits_per_pixel == 1) { 1327 if (info->var.bits_per_pixel == 1) {
1355 /* base is already correct */ 1328 /* base is already correct */
@@ -1363,10 +1336,8 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1363 cirrusfb_WaitBLT(cinfo->regbase); 1336 cirrusfb_WaitBLT(cinfo->regbase);
1364 1337
1365 /* lower 8 + 8 bits of screen start address */ 1338 /* lower 8 + 8 bits of screen start address */
1366 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 1339 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
1367 (unsigned char) (base & 0xff)); 1340 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
1368 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
1369 (unsigned char) (base >> 8));
1370 1341
1371 /* 0xf2 is %11110010, exclude tmp bits */ 1342 /* 0xf2 is %11110010, exclude tmp bits */
1372 tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2; 1343 tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
@@ -1544,10 +1515,6 @@ static void init_vgachip(struct fb_info *info)
1544 1515
1545 /* FullBandwidth (video off) and 8/9 dot clock */ 1516 /* FullBandwidth (video off) and 8/9 dot clock */
1546 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); 1517 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1547 /* polarity (-/-), disable access to display memory,
1548 * VGA_CRTC_START_HI base address: color
1549 */
1550 WGen(cinfo, VGA_MIS_W, 0xc1);
1551 1518
1552 /* "magic cookie" - doesn't make any sense to me.. */ 1519 /* "magic cookie" - doesn't make any sense to me.. */
1553/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */ 1520/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
@@ -1614,10 +1581,6 @@ static void init_vgachip(struct fb_info *info)
1614 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); 1581 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1615 /* Text cursor end: - */ 1582 /* Text cursor end: - */
1616 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); 1583 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1617 /* Screen start address high: 0 */
1618 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1619 /* Screen start address low: 0 */
1620 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1621 /* text cursor location high: 0 */ 1584 /* text cursor location high: 0 */
1622 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); 1585 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1623 /* text cursor location low: 0 */ 1586 /* text cursor location low: 0 */
@@ -1625,10 +1588,6 @@ static void init_vgachip(struct fb_info *info)
1625 1588
1626 /* Underline Row scanline: - */ 1589 /* Underline Row scanline: - */
1627 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); 1590 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1628 /* mode control: timing enable, byte mode, no compat modes */
1629 vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1630 /* Line Compare: not needed */
1631 vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1632 /* ### add 0x40 for text modes with > 30 MHz pixclock */ 1591 /* ### add 0x40 for text modes with > 30 MHz pixclock */
1633 /* ext. display controls: ext.adr. wrap */ 1592 /* ext. display controls: ext.adr. wrap */
1634 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); 1593 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
@@ -1697,12 +1656,6 @@ static void init_vgachip(struct fb_info *info)
1697 1656
1698 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ 1657 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1699 1658
1700 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1701 /* polarity (-/-), enable display mem,
1702 * VGA_CRTC_START_HI i/o base = color
1703 */
1704 WGen(cinfo, VGA_MIS_W, 0xc3);
1705
1706 /* BLT Start/status: Blitter reset */ 1659 /* BLT Start/status: Blitter reset */
1707 vga_wgfx(cinfo->regbase, CL_GR31, 0x04); 1660 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1708 /* - " - : "end-of-reset" */ 1661 /* - " - : "end-of-reset" */
@@ -2052,7 +2005,7 @@ static int __devinit cirrusfb_register(struct fb_info *info)
2052 2005
2053 info->var.activate = FB_ACTIVATE_NOW; 2006 info->var.activate = FB_ACTIVATE_NOW;
2054 2007
2055 err = cirrusfb_decode_var(&info->var, info); 2008 err = cirrusfb_check_var(&info->var, info);
2056 if (err < 0) { 2009 if (err < 0) {
2057 /* should never happen */ 2010 /* should never happen */
2058 dev_dbg(info->device, 2011 dev_dbg(info->device,