aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/cirrusfb.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 6603273f4ce5..65a1831ddd0d 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -95,10 +95,10 @@
95/* board types */ 95/* board types */
96enum cirrus_board { 96enum cirrus_board {
97 BT_NONE = 0, 97 BT_NONE = 0,
98 BT_SD64, 98 BT_SD64, /* GD5434 */
99 BT_PICCOLO, 99 BT_PICCOLO, /* GD5426 */
100 BT_PICASSO, 100 BT_PICASSO, /* GD5426 or GD5428 */
101 BT_SPECTRUM, 101 BT_SPECTRUM, /* GD5426 or GD5428 */
102 BT_PICASSO4, /* GD5446 */ 102 BT_PICASSO4, /* GD5446 */
103 BT_ALPINE, /* GD543x/4x */ 103 BT_ALPINE, /* GD543x/4x */
104 BT_GD5480, 104 BT_GD5480,
@@ -488,7 +488,7 @@ static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
488 * the VCLK is double the pixel clock. */ 488 * the VCLK is double the pixel clock. */
489 switch (var->bits_per_pixel) { 489 switch (var->bits_per_pixel) {
490 case 16: 490 case 16:
491 case 32: 491 case 24:
492 if (var->xres <= 800) 492 if (var->xres <= 800)
493 /* Xbh has this type of clock for 32-bit */ 493 /* Xbh has this type of clock for 32-bit */
494 freq /= 2; 494 freq /= 2;
@@ -535,11 +535,11 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
535 var->blue.length = 5; 535 var->blue.length = 5;
536 break; 536 break;
537 537
538 case 32: 538 case 24:
539 if (isPReP) { 539 if (isPReP) {
540 var->red.offset = 8; 540 var->red.offset = 0;
541 var->green.offset = 16; 541 var->green.offset = 8;
542 var->blue.offset = 24; 542 var->blue.offset = 16;
543 } else { 543 } else {
544 var->red.offset = 16; 544 var->red.offset = 16;
545 var->green.offset = 8; 545 var->green.offset = 8;
@@ -670,7 +670,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
670 break; 670 break;
671 671
672 case 16: 672 case 16:
673 case 32: 673 case 24:
674 info->fix.line_length = var->xres_virtual * 674 info->fix.line_length = var->xres_virtual *
675 var->bits_per_pixel >> 3; 675 var->bits_per_pixel >> 3;
676 info->fix.visual = FB_VISUAL_TRUECOLOR; 676 info->fix.visual = FB_VISUAL_TRUECOLOR;
@@ -813,6 +813,9 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
813 vga_wcrt(regbase, CL_CRT1A, tmp); 813 vga_wcrt(regbase, CL_CRT1A, tmp);
814 814
815 freq = PICOS2KHZ(var->pixclock); 815 freq = PICOS2KHZ(var->pixclock);
816 if (cinfo->btype == BT_ALPINE && var->bits_per_pixel == 24)
817 freq *= 3;
818
816 bestclock(freq, &nom, &den, &div); 819 bestclock(freq, &nom, &den, &div);
817 820
818 dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n", 821 dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n",
@@ -1140,16 +1143,16 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1140 1143
1141 /****************************************************** 1144 /******************************************************
1142 * 1145 *
1143 * 32 bpp 1146 * 24 bpp
1144 * 1147 *
1145 */ 1148 */
1146 1149
1147 else if (var->bits_per_pixel == 32) { 1150 else if (var->bits_per_pixel == 24) {
1148 dev_dbg(info->device, "preparing for 32 bit deep display\n"); 1151 dev_dbg(info->device, "preparing for 24 bit deep display\n");
1149 switch (cinfo->btype) { 1152 switch (cinfo->btype) {
1150 case BT_SD64: 1153 case BT_SD64:
1151 /* Extended Sequencer Mode: 256c col. mode */ 1154 /* Extended Sequencer Mode: 256c col. mode */
1152 vga_wseq(regbase, CL_SEQR7, 0xf9); 1155 vga_wseq(regbase, CL_SEQR7, 0xf5);
1153 /* MCLK select */ 1156 /* MCLK select */
1154 vga_wseq(regbase, CL_SEQR1F, 0x1e); 1157 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1155 break; 1158 break;
@@ -1173,11 +1176,11 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1173 1176
1174 case BT_PICASSO4: 1177 case BT_PICASSO4:
1175 case BT_ALPINE: 1178 case BT_ALPINE:
1176 vga_wseq(regbase, CL_SEQR7, 0xa9); 1179 vga_wseq(regbase, CL_SEQR7, 0xa5);
1177 break; 1180 break;
1178 1181
1179 case BT_GD5480: 1182 case BT_GD5480:
1180 vga_wseq(regbase, CL_SEQR7, 0x19); 1183 vga_wseq(regbase, CL_SEQR7, 0x15);
1181 /* We already set SRF and SR1F */ 1184 /* We already set SRF and SR1F */
1182 break; 1185 break;
1183 1186
@@ -1185,8 +1188,8 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1185 case BT_LAGUNAB: 1188 case BT_LAGUNAB:
1186 vga_wseq(regbase, CL_SEQR7, 1189 vga_wseq(regbase, CL_SEQR7,
1187 vga_rseq(regbase, CL_SEQR7) & ~0x01); 1190 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1188 control |= 0x6000; 1191 control |= 0x4000;
1189 format |= 0x3400; 1192 format |= 0x2400;
1190 threshold |= 0x20; 1193 threshold |= 0x20;
1191 break; 1194 break;
1192 1195
@@ -1385,9 +1388,6 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1385 if (info->var.bits_per_pixel == 1) 1388 if (info->var.bits_per_pixel == 1)
1386 vga_wattr(cinfo->regbase, CL_AR33, xpix); 1389 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1387 1390
1388 if (!is_laguna(cinfo))
1389 cirrusfb_WaitBLT(cinfo->regbase);
1390
1391 return 0; 1391 return 0;
1392} 1392}
1393 1393
@@ -1492,22 +1492,18 @@ static void init_vgachip(struct fb_info *info)
1492 /* disable flickerfixer */ 1492 /* disable flickerfixer */
1493 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00); 1493 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1494 mdelay(100); 1494 mdelay(100);
1495 /* from Klaus' NetBSD driver: */
1496 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1497 /* put blitter into 542x compat */
1498 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1499 /* mode */ 1495 /* mode */
1500 vga_wgfx(cinfo->regbase, CL_GR31, 0x00); 1496 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1501 break; 1497 case BT_GD5480: /* fall through */
1502
1503 case BT_GD5480:
1504 /* from Klaus' NetBSD driver: */ 1498 /* from Klaus' NetBSD driver: */
1505 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); 1499 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1500 case BT_ALPINE: /* fall through */
1501 /* put blitter into 542x compat */
1502 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1506 break; 1503 break;
1507 1504
1508 case BT_LAGUNA: 1505 case BT_LAGUNA:
1509 case BT_LAGUNAB: 1506 case BT_LAGUNAB:
1510 case BT_ALPINE:
1511 /* Nothing to do to reset the board. */ 1507 /* Nothing to do to reset the board. */
1512 break; 1508 break;
1513 1509
@@ -1831,10 +1827,13 @@ static void cirrusfb_imageblit(struct fb_info *info,
1831 const struct fb_image *image) 1827 const struct fb_image *image)
1832{ 1828{
1833 struct cirrusfb_info *cinfo = info->par; 1829 struct cirrusfb_info *cinfo = info->par;
1830 unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1834 1831
1835 if (info->state != FBINFO_STATE_RUNNING) 1832 if (info->state != FBINFO_STATE_RUNNING)
1836 return; 1833 return;
1837 if (info->flags & FBINFO_HWACCEL_DISABLED) 1834 /* Alpine acceleration does not work at 24bpp ?!? */
1835 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1 ||
1836 (cinfo->btype == BT_ALPINE && op == 0xc))
1838 cfb_imageblit(info, image); 1837 cfb_imageblit(info, image);
1839 else { 1838 else {
1840 unsigned size = ((image->width + 7) >> 3) * image->height; 1839 unsigned size = ((image->width + 7) >> 3) * image->height;
@@ -1848,15 +1847,22 @@ static void cirrusfb_imageblit(struct fb_info *info,
1848 fg = ((u32 *)(info->pseudo_palette))[image->fg_color]; 1847 fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1849 bg = ((u32 *)(info->pseudo_palette))[image->bg_color]; 1848 bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1850 } 1849 }
1851 cirrusfb_WaitBLT(cinfo->regbase); 1850 if (info->var.bits_per_pixel == 24) {
1852 /* byte rounded scanlines */ 1851 /* clear background first */
1853 vga_wgfx(cinfo->regbase, CL_GR33, 0x00); 1852 cirrusfb_RectFill(cinfo->regbase,
1853 info->var.bits_per_pixel,
1854 (image->dx * m) / 8, image->dy,
1855 (image->width * m) / 8,
1856 image->height,
1857 bg, bg,
1858 info->fix.line_length, 0x40);
1859 }
1854 cirrusfb_RectFill(cinfo->regbase, 1860 cirrusfb_RectFill(cinfo->regbase,
1855 info->var.bits_per_pixel, 1861 info->var.bits_per_pixel,
1856 (image->dx * m) / 8, image->dy, 1862 (image->dx * m) / 8, image->dy,
1857 (image->width * m) / 8, image->height, 1863 (image->width * m) / 8, image->height,
1858 fg, bg, 1864 fg, bg,
1859 info->fix.line_length, 0x04); 1865 info->fix.line_length, op);
1860 memcpy(info->screen_base, image->data, size); 1866 memcpy(info->screen_base, image->data, size);
1861 } 1867 }
1862} 1868}
@@ -2743,9 +2749,12 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2743 vga_wgfx(regbase, CL_GR11, fg_color >> 8); 2749 vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2744 op = 0x90; 2750 op = 0x90;
2745 } 2751 }
2746 if (bits_per_pixel == 32) { 2752 if (bits_per_pixel >= 24) {
2747 vga_wgfx(regbase, CL_GR12, bg_color >> 16); 2753 vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2748 vga_wgfx(regbase, CL_GR13, fg_color >> 16); 2754 vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2755 op = 0xa0;
2756 }
2757 if (bits_per_pixel == 32) {
2749 vga_wgfx(regbase, CL_GR14, bg_color >> 24); 2758 vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2750 vga_wgfx(regbase, CL_GR15, fg_color >> 24); 2759 vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2751 op = 0xb0; 2760 op = 0xb0;