aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/cirrusfb.c216
1 files changed, 41 insertions, 175 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index ebb8ddb0095a..56306658c01e 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -647,31 +647,17 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
647 { -1, -1 } }; 647 { -1, -1 } };
648 648
649 switch (var->bits_per_pixel) { 649 switch (var->bits_per_pixel) {
650 case 0 ... 1: 650 case 1:
651 var->bits_per_pixel = 1;
652 nom = 4; 651 nom = 4;
653 den = 8; 652 den = 8;
654 break; /* 8 pixel per byte, only 1/4th of mem usable */ 653 break; /* 8 pixel per byte, only 1/4th of mem usable */
655 case 2 ... 8: 654 case 8:
656 var->bits_per_pixel = 8; 655 case 16:
657 nom = 1; 656 case 24:
657 case 32:
658 nom = var->bits_per_pixel / 8;
658 den = 1; 659 den = 1;
659 break; /* 1 pixel == 1 byte */ 660 break; /* 1 pixel == 1 byte */
660 case 9 ... 16:
661 var->bits_per_pixel = 16;
662 nom = 2;
663 den = 1;
664 break; /* 2 bytes per pixel */
665 case 17 ... 24:
666 var->bits_per_pixel = 24;
667 nom = 3;
668 den = 1;
669 break; /* 3 bytes per pixel */
670 case 25 ... 32:
671 var->bits_per_pixel = 32;
672 nom = 4;
673 den = 1;
674 break; /* 4 bytes per pixel */
675 default: 661 default:
676 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..." 662 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
677 "color depth not supported.\n", 663 "color depth not supported.\n",
@@ -732,19 +718,15 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
732 case 1: 718 case 1:
733 var->red.offset = 0; 719 var->red.offset = 0;
734 var->red.length = 1; 720 var->red.length = 1;
735 var->green.offset = 0; 721 var->green = var->red;
736 var->green.length = 1; 722 var->blue = var->red;
737 var->blue.offset = 0;
738 var->blue.length = 1;
739 break; 723 break;
740 724
741 case 8: 725 case 8:
742 var->red.offset = 0; 726 var->red.offset = 0;
743 var->red.length = 6; 727 var->red.length = 6;
744 var->green.offset = 0; 728 var->green = var->red;
745 var->green.length = 6; 729 var->blue = var->red;
746 var->blue.offset = 0;
747 var->blue.length = 6;
748 break; 730 break;
749 731
750 case 16: 732 case 16:
@@ -763,20 +745,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
763 break; 745 break;
764 746
765 case 24: 747 case 24:
766 if (isPReP) {
767 var->red.offset = 8;
768 var->green.offset = 16;
769 var->blue.offset = 24;
770 } else {
771 var->red.offset = 16;
772 var->green.offset = 8;
773 var->blue.offset = 0;
774 }
775 var->red.length = 8;
776 var->green.length = 8;
777 var->blue.length = 8;
778 break;
779
780 case 32: 748 case 32:
781 if (isPReP) { 749 if (isPReP) {
782 var->red.offset = 8; 750 var->red.offset = 8;
@@ -828,7 +796,7 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
828{ 796{
829 long freq; 797 long freq;
830 long maxclock; 798 long maxclock;
831 int maxclockidx = 0; 799 int maxclockidx = var->bits_per_pixel >> 3;
832 struct cirrusfb_info *cinfo = info->par; 800 struct cirrusfb_info *cinfo = info->par;
833 int xres, hfront, hsync, hback; 801 int xres, hfront, hsync, hback;
834 int yres, vfront, vsync, vback; 802 int yres, vfront, vsync, vback;
@@ -837,31 +805,18 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
837 case 1: 805 case 1:
838 regs->line_length = var->xres_virtual / 8; 806 regs->line_length = var->xres_virtual / 8;
839 regs->visual = FB_VISUAL_MONO10; 807 regs->visual = FB_VISUAL_MONO10;
840 maxclockidx = 0;
841 break; 808 break;
842 809
843 case 8: 810 case 8:
844 regs->line_length = var->xres_virtual; 811 regs->line_length = var->xres_virtual;
845 regs->visual = FB_VISUAL_PSEUDOCOLOR; 812 regs->visual = FB_VISUAL_PSEUDOCOLOR;
846 maxclockidx = 1;
847 break; 813 break;
848 814
849 case 16: 815 case 16:
850 regs->line_length = var->xres_virtual * 2;
851 regs->visual = FB_VISUAL_DIRECTCOLOR;
852 maxclockidx = 2;
853 break;
854
855 case 24: 816 case 24:
856 regs->line_length = var->xres_virtual * 3;
857 regs->visual = FB_VISUAL_DIRECTCOLOR;
858 maxclockidx = 3;
859 break;
860
861 case 32: 817 case 32:
862 regs->line_length = var->xres_virtual * 4; 818 regs->line_length = var->xres_virtual * maxclockidx;
863 regs->visual = FB_VISUAL_DIRECTCOLOR; 819 regs->visual = FB_VISUAL_DIRECTCOLOR;
864 maxclockidx = 4;
865 break; 820 break;
866 821
867 default: 822 default:
@@ -874,7 +829,7 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
874 regs->type = FB_TYPE_PACKED_PIXELS; 829 regs->type = FB_TYPE_PACKED_PIXELS;
875 830
876 /* convert from ps to kHz */ 831 /* convert from ps to kHz */
877 freq = 1000000000 / var->pixclock; 832 freq = PICOS2KHZ(var->pixclock);
878 833
879 DPRINTK("desired pixclock: %ld kHz\n", freq); 834 DPRINTK("desired pixclock: %ld kHz\n", freq);
880 835
@@ -1213,7 +1168,8 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1213 break; 1168 break;
1214 1169
1215 case BT_PICCOLO: 1170 case BT_PICCOLO:
1216 DPRINTK("(for Piccolo)\n"); 1171 case BT_SPECTRUM:
1172 DPRINTK("(for Piccolo/Spectrum)\n");
1217 /* ### ueberall 0x22? */ 1173 /* ### ueberall 0x22? */
1218 /* ##vorher 1c MCLK select */ 1174 /* ##vorher 1c MCLK select */
1219 vga_wseq(regbase, CL_SEQR1F, 0x22); 1175 vga_wseq(regbase, CL_SEQR1F, 0x22);
@@ -1229,15 +1185,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1229 vga_wseq(regbase, CL_SEQRF, 0xd0); 1185 vga_wseq(regbase, CL_SEQRF, 0xd0);
1230 break; 1186 break;
1231 1187
1232 case BT_SPECTRUM:
1233 DPRINTK("(for Spectrum)\n");
1234 /* ### ueberall 0x22? */
1235 /* ##vorher 1c MCLK select */
1236 vga_wseq(regbase, CL_SEQR1F, 0x22);
1237 /* evtl d0? avoid FIFO underruns..? */
1238 vga_wseq(regbase, CL_SEQRF, 0xb0);
1239 break;
1240
1241 case BT_PICASSO4: 1188 case BT_PICASSO4:
1242 case BT_ALPINE: 1189 case BT_ALPINE:
1243 case BT_GD5480: 1190 case BT_GD5480:
@@ -1306,19 +1253,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1306 break; 1253 break;
1307 1254
1308 case BT_PICCOLO: 1255 case BT_PICCOLO:
1309 /* ### vorher 1c MCLK select */
1310 vga_wseq(regbase, CL_SEQR1F, 0x22);
1311 /* Fast Page-Mode writes */
1312 vga_wseq(regbase, CL_SEQRF, 0xb0);
1313 break;
1314
1315 case BT_PICASSO: 1256 case BT_PICASSO:
1316 /* ### vorher 1c MCLK select */
1317 vga_wseq(regbase, CL_SEQR1F, 0x22);
1318 /* Fast Page-Mode writes */
1319 vga_wseq(regbase, CL_SEQRF, 0xb0);
1320 break;
1321
1322 case BT_SPECTRUM: 1257 case BT_SPECTRUM:
1323 /* ### vorher 1c MCLK select */ 1258 /* ### vorher 1c MCLK select */
1324 vga_wseq(regbase, CL_SEQR1F, 0x22); 1259 vga_wseq(regbase, CL_SEQR1F, 0x22);
@@ -1385,6 +1320,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1385 break; 1320 break;
1386 1321
1387 case BT_PICCOLO: 1322 case BT_PICCOLO:
1323 case BT_SPECTRUM:
1388 vga_wseq(regbase, CL_SEQR7, 0x87); 1324 vga_wseq(regbase, CL_SEQR7, 0x87);
1389 /* Fast Page-Mode writes */ 1325 /* Fast Page-Mode writes */
1390 vga_wseq(regbase, CL_SEQRF, 0xb0); 1326 vga_wseq(regbase, CL_SEQRF, 0xb0);
@@ -1400,14 +1336,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1400 vga_wseq(regbase, CL_SEQR1F, 0x22); 1336 vga_wseq(regbase, CL_SEQR1F, 0x22);
1401 break; 1337 break;
1402 1338
1403 case BT_SPECTRUM:
1404 vga_wseq(regbase, CL_SEQR7, 0x87);
1405 /* Fast Page-Mode writes */
1406 vga_wseq(regbase, CL_SEQRF, 0xb0);
1407 /* MCLK select */
1408 vga_wseq(regbase, CL_SEQR1F, 0x22);
1409 break;
1410
1411 case BT_PICASSO4: 1339 case BT_PICASSO4:
1412 vga_wseq(regbase, CL_SEQR7, 0x27); 1340 vga_wseq(regbase, CL_SEQR7, 0x27);
1413/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ 1341/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
@@ -1473,6 +1401,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1473 break; 1401 break;
1474 1402
1475 case BT_PICCOLO: 1403 case BT_PICCOLO:
1404 case BT_SPECTRUM:
1476 vga_wseq(regbase, CL_SEQR7, 0x85); 1405 vga_wseq(regbase, CL_SEQR7, 0x85);
1477 /* Fast Page-Mode writes */ 1406 /* Fast Page-Mode writes */
1478 vga_wseq(regbase, CL_SEQRF, 0xb0); 1407 vga_wseq(regbase, CL_SEQRF, 0xb0);
@@ -1488,14 +1417,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1488 vga_wseq(regbase, CL_SEQR1F, 0x22); 1417 vga_wseq(regbase, CL_SEQR1F, 0x22);
1489 break; 1418 break;
1490 1419
1491 case BT_SPECTRUM:
1492 vga_wseq(regbase, CL_SEQR7, 0x85);
1493 /* Fast Page-Mode writes */
1494 vga_wseq(regbase, CL_SEQRF, 0xb0);
1495 /* MCLK select */
1496 vga_wseq(regbase, CL_SEQR1F, 0x22);
1497 break;
1498
1499 case BT_PICASSO4: 1420 case BT_PICASSO4:
1500 vga_wseq(regbase, CL_SEQR7, 0x25); 1421 vga_wseq(regbase, CL_SEQR7, 0x25);
1501/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */ 1422/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
@@ -1662,18 +1583,7 @@ static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1662 (green << info->var.green.offset) | 1583 (green << info->var.green.offset) |
1663 (blue << info->var.blue.offset); 1584 (blue << info->var.blue.offset);
1664 1585
1665 switch (info->var.bits_per_pixel) { 1586 cinfo->pseudo_palette[regno] = v;
1666 case 8:
1667 cinfo->pseudo_palette[regno] = v;
1668 break;
1669 case 16:
1670 cinfo->pseudo_palette[regno] = v;
1671 break;
1672 case 24:
1673 case 32:
1674 cinfo->pseudo_palette[regno] = v;
1675 break;
1676 }
1677 return 0; 1587 return 0;
1678 } 1588 }
1679 1589
@@ -1743,12 +1653,8 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1743 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2); 1653 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
1744 1654
1745 /* construct bit 19 of screen start address */ 1655 /* construct bit 19 of screen start address */
1746 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) { 1656 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1747 tmp2 = 0; 1657 vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
1748 if (base & 0x80000)
1749 tmp2 = 0x80;
1750 vga_wcrt(cinfo->regbase, CL_CRT1D, tmp2);
1751 }
1752 1658
1753 /* write pixel panning value to AR33; this does not quite work in 8bpp 1659 /* write pixel panning value to AR33; this does not quite work in 8bpp
1754 * 1660 *
@@ -2139,38 +2045,15 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
2139/* Linux 2.6-style accelerated functions */ 2045/* Linux 2.6-style accelerated functions */
2140/******************************************/ 2046/******************************************/
2141 2047
2142static void cirrusfb_prim_fillrect(struct fb_info *info,
2143 const struct fb_fillrect *region)
2144{
2145 struct cirrusfb_info *cinfo = info->par;
2146 int m; /* bytes per pixel */
2147 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
2148 cinfo->pseudo_palette[region->color] : region->color;
2149
2150 if (info->var.bits_per_pixel == 1) {
2151 cirrusfb_RectFill(cinfo->regbase,
2152 info->var.bits_per_pixel,
2153 region->dx / 8, region->dy,
2154 region->width / 8, region->height,
2155 color,
2156 cinfo->currentmode.line_length);
2157 } else {
2158 m = (info->var.bits_per_pixel + 7) / 8;
2159 cirrusfb_RectFill(cinfo->regbase,
2160 info->var.bits_per_pixel,
2161 region->dx * m, region->dy,
2162 region->width * m, region->height,
2163 color,
2164 cinfo->currentmode.line_length);
2165 }
2166 return;
2167}
2168
2169static void cirrusfb_fillrect(struct fb_info *info, 2048static void cirrusfb_fillrect(struct fb_info *info,
2170 const struct fb_fillrect *region) 2049 const struct fb_fillrect *region)
2171{ 2050{
2172 struct fb_fillrect modded; 2051 struct fb_fillrect modded;
2173 int vxres, vyres; 2052 int vxres, vyres;
2053 struct cirrusfb_info *cinfo = info->par;
2054 int m = info->var.bits_per_pixel;
2055 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
2056 cinfo->pseudo_palette[region->color] : region->color;
2174 2057
2175 if (info->state != FBINFO_STATE_RUNNING) 2058 if (info->state != FBINFO_STATE_RUNNING)
2176 return; 2059 return;
@@ -2193,30 +2076,12 @@ static void cirrusfb_fillrect(struct fb_info *info,
2193 if (modded.dy + modded.height > vyres) 2076 if (modded.dy + modded.height > vyres)
2194 modded.height = vyres - modded.dy; 2077 modded.height = vyres - modded.dy;
2195 2078
2196 cirrusfb_prim_fillrect(info, &modded); 2079 cirrusfb_RectFill(cinfo->regbase,
2197} 2080 info->var.bits_per_pixel,
2198 2081 (region->dx * m) / 8, region->dy,
2199static void cirrusfb_prim_copyarea(struct fb_info *info, 2082 (region->width * m) / 8, region->height,
2200 const struct fb_copyarea *area) 2083 color,
2201{ 2084 cinfo->currentmode.line_length);
2202 struct cirrusfb_info *cinfo = info->par;
2203 int m; /* bytes per pixel */
2204
2205 if (info->var.bits_per_pixel == 1) {
2206 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
2207 area->sx / 8, area->sy,
2208 area->dx / 8, area->dy,
2209 area->width / 8, area->height,
2210 cinfo->currentmode.line_length);
2211 } else {
2212 m = (info->var.bits_per_pixel + 7) / 8;
2213 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
2214 area->sx * m, area->sy,
2215 area->dx * m, area->dy,
2216 area->width * m, area->height,
2217 cinfo->currentmode.line_length);
2218 }
2219 return;
2220} 2085}
2221 2086
2222static void cirrusfb_copyarea(struct fb_info *info, 2087static void cirrusfb_copyarea(struct fb_info *info,
@@ -2224,13 +2089,8 @@ static void cirrusfb_copyarea(struct fb_info *info,
2224{ 2089{
2225 struct fb_copyarea modded; 2090 struct fb_copyarea modded;
2226 u32 vxres, vyres; 2091 u32 vxres, vyres;
2227 2092 struct cirrusfb_info *cinfo = info->par;
2228 modded.sx = area->sx; 2093 int m = info->var.bits_per_pixel;
2229 modded.sy = area->sy;
2230 modded.dx = area->dx;
2231 modded.dy = area->dy;
2232 modded.width = area->width;
2233 modded.height = area->height;
2234 2094
2235 if (info->state != FBINFO_STATE_RUNNING) 2095 if (info->state != FBINFO_STATE_RUNNING)
2236 return; 2096 return;
@@ -2241,6 +2101,7 @@ static void cirrusfb_copyarea(struct fb_info *info,
2241 2101
2242 vxres = info->var.xres_virtual; 2102 vxres = info->var.xres_virtual;
2243 vyres = info->var.yres_virtual; 2103 vyres = info->var.yres_virtual;
2104 memcpy(&modded, area, sizeof(struct fb_copyarea));
2244 2105
2245 if (!modded.width || !modded.height || 2106 if (!modded.width || !modded.height ||
2246 modded.sx >= vxres || modded.sy >= vyres || 2107 modded.sx >= vxres || modded.sy >= vyres ||
@@ -2256,7 +2117,12 @@ static void cirrusfb_copyarea(struct fb_info *info,
2256 if (modded.dy + modded.height > vyres) 2117 if (modded.dy + modded.height > vyres)
2257 modded.height = vyres - modded.dy; 2118 modded.height = vyres - modded.dy;
2258 2119
2259 cirrusfb_prim_copyarea(info, &modded); 2120 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
2121 (area->sx * m) / 8, area->sy,
2122 (area->dx * m) / 8, area->dy,
2123 (area->width * m) / 8, area->height,
2124 cinfo->currentmode.line_length);
2125
2260} 2126}
2261 2127
2262static void cirrusfb_imageblit(struct fb_info *info, 2128static void cirrusfb_imageblit(struct fb_info *info,
@@ -2366,7 +2232,6 @@ static void cirrusfb_pci_unmap(struct fb_info *info)
2366 if (release_io_ports) 2232 if (release_io_ports)
2367 release_region(0x3C0, 32); 2233 release_region(0x3C0, 32);
2368 pci_release_regions(pdev); 2234 pci_release_regions(pdev);
2369 framebuffer_release(info);
2370} 2235}
2371#endif /* CONFIG_PCI */ 2236#endif /* CONFIG_PCI */
2372 2237
@@ -2383,7 +2248,6 @@ static void __devexit cirrusfb_zorro_unmap(struct cirrusfb_info *cinfo)
2383 if (zorro_resource_start(cinfo->zdev) > 0x01000000) 2248 if (zorro_resource_start(cinfo->zdev) > 0x01000000)
2384 iounmap(info->screen_base); 2249 iounmap(info->screen_base);
2385 } 2250 }
2386 framebuffer_release(cinfo->info);
2387} 2251}
2388#endif /* CONFIG_ZORRO */ 2252#endif /* CONFIG_ZORRO */
2389 2253
@@ -2481,6 +2345,7 @@ err_dealloc_cmap:
2481 fb_dealloc_cmap(&info->cmap); 2345 fb_dealloc_cmap(&info->cmap);
2482err_unmap_cirrusfb: 2346err_unmap_cirrusfb:
2483 cinfo->unmap(info); 2347 cinfo->unmap(info);
2348 framebuffer_release(info);
2484 return err; 2349 return err;
2485} 2350}
2486 2351
@@ -2495,6 +2360,7 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info)
2495 fb_dealloc_cmap(&info->cmap); 2360 fb_dealloc_cmap(&info->cmap);
2496 printk("Framebuffer unregistered\n"); 2361 printk("Framebuffer unregistered\n");
2497 cinfo->unmap(info); 2362 cinfo->unmap(info);
2363 framebuffer_release(info);
2498 2364
2499 DPRINTK("EXIT\n"); 2365 DPRINTK("EXIT\n");
2500} 2366}