Commit 48c329e906f834711906ab4b0986ea0e857aff16

Authored by Krzysztof Helt
Committed by Linus Torvalds
1 parent c4dec3962d

cirrusfb: various improvements

Various improvements to the code:
- kill a structure with only one
  field: multiplexing and use the
  field directly
- move the cirrusfb_ops structure
  down the file to kill forward
  declarations
- move cirrusfb_init() to kill
  forward declaration
- kill register loads done already
  in the init_vgachip()
- kill assigments done by higher
  layer in the cirrusfb_pan_display()
- do not overwrite line pitch bit in
  the CL_CRT1D register
- kill btype variables if they were
  used only once or twice
- add cpu_relax() in the busy waiting
  loop

The fix to the CL_CRT1D register handling makess the 1024x768 32bpp mode
work.  Previously, only lower resolution modes have worked with 32bpp.

Signed-off-by: Krzysztof Helt <krzysztof.h1@poczta.fm>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 58 additions and 144 deletions Side-by-side Diff

drivers/video/cirrusfb.c
... ... @@ -313,10 +313,6 @@
313 313 };
314 314 #endif /* CONFIG_ZORRO */
315 315  
316   -struct cirrusfb_regs {
317   - int multiplexing;
318   -};
319   -
320 316 #ifdef CIRRUSFB_DEBUG
321 317 enum cirrusfb_dbg_reg_class {
322 318 CRT,
... ... @@ -331,7 +327,7 @@
331 327 enum cirrus_board btype;
332 328 unsigned char SFR; /* Shadow of special function register */
333 329  
334   - struct cirrusfb_regs currentmode;
  330 + int multiplexing;
335 331 int blank_mode;
336 332 u32 pseudo_palette[16];
337 333  
338 334  
339 335  
... ... @@ -345,44 +341,9 @@
345 341 /**** BEGIN PROTOTYPES ******************************************************/
346 342  
347 343 /*--- Interface used by the world ------------------------------------------*/
348   -static int cirrusfb_init(void);
349   -#ifndef MODULE
350   -static int cirrusfb_setup(char *options);
351   -#endif
352   -
353   -static int cirrusfb_open(struct fb_info *info, int user);
354   -static int cirrusfb_release(struct fb_info *info, int user);
355   -static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
356   - unsigned blue, unsigned transp,
357   - struct fb_info *info);
358   -static int cirrusfb_check_var(struct fb_var_screeninfo *var,
359   - struct fb_info *info);
360   -static int cirrusfb_set_par(struct fb_info *info);
361 344 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
362 345 struct fb_info *info);
363   -static int cirrusfb_blank(int blank_mode, struct fb_info *info);
364   -static void cirrusfb_fillrect(struct fb_info *info,
365   - const struct fb_fillrect *region);
366   -static void cirrusfb_copyarea(struct fb_info *info,
367   - const struct fb_copyarea *area);
368   -static void cirrusfb_imageblit(struct fb_info *info,
369   - const struct fb_image *image);
370 346  
371   -/* function table of the above functions */
372   -static struct fb_ops cirrusfb_ops = {
373   - .owner = THIS_MODULE,
374   - .fb_open = cirrusfb_open,
375   - .fb_release = cirrusfb_release,
376   - .fb_setcolreg = cirrusfb_setcolreg,
377   - .fb_check_var = cirrusfb_check_var,
378   - .fb_set_par = cirrusfb_set_par,
379   - .fb_pan_display = cirrusfb_pan_display,
380   - .fb_blank = cirrusfb_blank,
381   - .fb_fillrect = cirrusfb_fillrect,
382   - .fb_copyarea = cirrusfb_copyarea,
383   - .fb_imageblit = cirrusfb_imageblit,
384   -};
385   -
386 347 /*--- Internal routines ----------------------------------------------------*/
387 348 static void init_vgachip(struct fb_info *info);
388 349 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
... ... @@ -587,7 +548,6 @@
587 548 }
588 549  
589 550 static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
590   - struct cirrusfb_regs *regs,
591 551 struct fb_info *info)
592 552 {
593 553 long freq;
... ... @@ -628,7 +588,7 @@
628 588 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
629 589  
630 590 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
631   - regs->multiplexing = 0;
  591 + cinfo->multiplexing = 0;
632 592  
633 593 /* If the frequency is greater than we can support, we might be able
634 594 * to use multiplexing for the video mode */
... ... @@ -636,7 +596,7 @@
636 596 switch (cinfo->btype) {
637 597 case BT_ALPINE:
638 598 case BT_GD5480:
639   - regs->multiplexing = 1;
  599 + cinfo->multiplexing = 1;
640 600 break;
641 601  
642 602 default:
... ... @@ -691,7 +651,6 @@
691 651 {
692 652 struct cirrusfb_info *cinfo = info->par;
693 653 struct fb_var_screeninfo *var = &info->var;
694   - struct cirrusfb_regs regs;
695 654 u8 __iomem *regbase = cinfo->regbase;
696 655 unsigned char tmp;
697 656 int err;
... ... @@ -709,7 +668,7 @@
709 668  
710 669 init_vgachip(info);
711 670  
712   - err = cirrusfb_decode_var(var, &regs, info);
  671 + err = cirrusfb_decode_var(var, info);
713 672 if (err) {
714 673 /* should never happen */
715 674 dev_dbg(info->device, "mode change aborted. invalid var.\n");
... ... @@ -753,7 +712,7 @@
753 712 vsyncend /= 2;
754 713 vdispend /= 2;
755 714 }
756   - if (regs.multiplexing) {
  715 + if (cinfo->multiplexing) {
757 716 htotal /= 2;
758 717 hsyncstart /= 2;
759 718 hsyncend /= 2;
... ... @@ -964,7 +923,7 @@
964 923 case BT_ALPINE:
965 924 case BT_GD5480:
966 925 vga_wseq(regbase, CL_SEQR7,
967   - regs.multiplexing ?
  926 + cinfo->multiplexing ?
968 927 bi->sr07_1bpp_mux : bi->sr07_1bpp);
969 928 break;
970 929  
... ... @@ -1018,7 +977,7 @@
1018 977  
1019 978 /* pixel mask: pass-through for first plane */
1020 979 WGen(cinfo, VGA_PEL_MSK, 0x01);
1021   - if (regs.multiplexing)
  980 + if (cinfo->multiplexing)
1022 981 /* hidden dac reg: 1280x1024 */
1023 982 WHDR(cinfo, 0x4a);
1024 983 else
... ... @@ -1047,7 +1006,7 @@
1047 1006 case BT_ALPINE:
1048 1007 case BT_GD5480:
1049 1008 vga_wseq(regbase, CL_SEQR7,
1050   - regs.multiplexing ?
  1009 + cinfo->multiplexing ?
1051 1010 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1052 1011 break;
1053 1012  
1054 1013  
... ... @@ -1101,18 +1060,12 @@
1101 1060  
1102 1061 /* mode register: 256 color mode */
1103 1062 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1104   - /* pixel mask: pass-through all planes */
1105   - WGen(cinfo, VGA_PEL_MSK, 0xff);
1106   - if (regs.multiplexing)
  1063 + if (cinfo->multiplexing)
1107 1064 /* hidden dac reg: 1280x1024 */
1108 1065 WHDR(cinfo, 0x4a);
1109 1066 else
1110 1067 /* hidden dac: nothing */
1111 1068 WHDR(cinfo, 0);
1112   - /* memory mode: chain4, ext. memory */
1113   - vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1114   - /* plane mask: enable writing to all 4 planes */
1115   - vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1116 1069 }
1117 1070  
1118 1071 /******************************************************
1119 1072  
... ... @@ -1177,18 +1130,12 @@
1177 1130  
1178 1131 /* mode register: 256 color mode */
1179 1132 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1180   - /* pixel mask: pass-through all planes */
1181   - WGen(cinfo, VGA_PEL_MSK, 0xff);
1182 1133 #ifdef CONFIG_PCI
1183 1134 WHDR(cinfo, 0xc1); /* Copy Xbh */
1184 1135 #elif defined(CONFIG_ZORRO)
1185 1136 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1186 1137 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1187 1138 #endif
1188   - /* memory mode: chain4, ext. memory */
1189   - vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1190   - /* plane mask: enable writing to all 4 planes */
1191   - vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1192 1139 }
1193 1140  
1194 1141 /******************************************************
1195 1142  
... ... @@ -1253,14 +1200,8 @@
1253 1200  
1254 1201 /* mode register: 256 color mode */
1255 1202 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1256   - /* pixel mask: pass-through all planes */
1257   - WGen(cinfo, VGA_PEL_MSK, 0xff);
1258 1203 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1259 1204 WHDR(cinfo, 0xc5);
1260   - /* memory mode: chain4, ext. memory */
1261   - vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1262   - /* plane mask: enable writing to all 4 planes */
1263   - vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1264 1205 }
1265 1206  
1266 1207 /******************************************************
1267 1208  
1268 1209  
... ... @@ -1309,48 +1250,13 @@
1309 1250 }
1310 1251  
1311 1252  
1312   - /* text cursor location high */
1313   - vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
1314   - /* text cursor location low */
1315   - vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
1316   - /* underline row scanline = at very bottom */
1317   - vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
1318   -
1319   - /* controller mode */
1320   - vga_wattr(regbase, VGA_ATC_MODE, 1);
1321   - /* overscan (border) color */
1322   - vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
1323   - /* color plane enable */
1324   - vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
1325 1253 /* pixel panning */
1326 1254 vga_wattr(regbase, CL_AR33, 0);
1327   - /* color select */
1328   - vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
1329 1255  
1330 1256 /* [ EGS: SetOffset(); ] */
1331 1257 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1332 1258 AttrOn(cinfo);
1333 1259  
1334   - /* set/reset register */
1335   - vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
1336   - /* set/reset enable */
1337   - vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
1338   - /* color compare */
1339   - vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
1340   - /* data rotate */
1341   - vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
1342   - /* read map select */
1343   - vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
1344   - /* miscellaneous register */
1345   - vga_wgfx(regbase, VGA_GFX_MISC, 1);
1346   - /* color don't care */
1347   - vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
1348   - /* bit mask */
1349   - vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
1350   -
1351   - /* graphics cursor attributes: nothing special */
1352   - vga_wseq(regbase, CL_SEQR12, 0x0);
1353   -
1354 1260 if (cinfo->btype == BT_LAGUNA) {
1355 1261 /* no tiles */
1356 1262 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
... ... @@ -1369,8 +1275,6 @@
1369 1275 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1370 1276 dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1371 1277  
1372   - cinfo->currentmode = regs;
1373   -
1374 1278 /* pan to requested offset */
1375 1279 cirrusfb_pan_display(var, info);
1376 1280  
... ... @@ -1443,9 +1347,6 @@
1443 1347 if (var->vmode & FB_VMODE_YWRAP)
1444 1348 return -EINVAL;
1445 1349  
1446   - info->var.xoffset = var->xoffset;
1447   - info->var.yoffset = var->yoffset;
1448   -
1449 1350 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1450 1351 yoffset = var->yoffset;
1451 1352  
... ... @@ -1480,8 +1381,11 @@
1480 1381 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1481 1382  
1482 1383 /* construct bit 19 of screen start address */
1483   - if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1484   - vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
  1384 + if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
  1385 + tmp = vga_rcrt(cinfo->regbase, CL_CRT1D) & ~0x80;
  1386 + tmp |= (base >> 12) & 0x80;
  1387 + vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
  1388 + }
1485 1389  
1486 1390 /* write pixel panning value to AR33; this does not quite work in 8bpp
1487 1391 *
... ... @@ -1670,8 +1574,8 @@
1670 1574 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1671 1575 /* character map select: doesn't even matter in gx mode */
1672 1576 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1673   - /* memory mode: chain-4, no odd/even, ext. memory */
1674   - vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
  1577 + /* memory mode: chain4, ext. memory */
  1578 + vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1675 1579  
1676 1580 /* controller-internal base address of video memory */
1677 1581 if (bi->init_sr07)
... ... @@ -1784,7 +1688,6 @@
1784 1688 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1785 1689 /* Color Plane enable: Enable all 4 planes */
1786 1690 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1787   -/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
1788 1691 /* Color Select: - */
1789 1692 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1790 1693  
... ... @@ -2063,6 +1966,21 @@
2063 1966 }
2064 1967 #endif /* CONFIG_ZORRO */
2065 1968  
  1969 +/* function table of the above functions */
  1970 +static struct fb_ops cirrusfb_ops = {
  1971 + .owner = THIS_MODULE,
  1972 + .fb_open = cirrusfb_open,
  1973 + .fb_release = cirrusfb_release,
  1974 + .fb_setcolreg = cirrusfb_setcolreg,
  1975 + .fb_check_var = cirrusfb_check_var,
  1976 + .fb_set_par = cirrusfb_set_par,
  1977 + .fb_pan_display = cirrusfb_pan_display,
  1978 + .fb_blank = cirrusfb_blank,
  1979 + .fb_fillrect = cirrusfb_fillrect,
  1980 + .fb_copyarea = cirrusfb_copyarea,
  1981 + .fb_imageblit = cirrusfb_imageblit,
  1982 +};
  1983 +
2066 1984 static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2067 1985 {
2068 1986 struct cirrusfb_info *cinfo = info->par;
2069 1987  
2070 1988  
... ... @@ -2111,12 +2029,9 @@
2111 2029 {
2112 2030 struct cirrusfb_info *cinfo = info->par;
2113 2031 int err;
2114   - enum cirrus_board btype;
2115 2032  
2116   - btype = cinfo->btype;
2117   -
2118 2033 /* sanity checks */
2119   - assert(btype != BT_NONE);
  2034 + assert(cinfo->btype != BT_NONE);
2120 2035  
2121 2036 /* set all the vital stuff */
2122 2037 cirrusfb_set_fbinfo(info);
... ... @@ -2132,7 +2047,7 @@
2132 2047  
2133 2048 info->var.activate = FB_ACTIVATE_NOW;
2134 2049  
2135   - err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
  2050 + err = cirrusfb_decode_var(&info->var, info);
2136 2051 if (err < 0) {
2137 2052 /* should never happen */
2138 2053 dev_dbg(info->device,
... ... @@ -2174,7 +2089,6 @@
2174 2089 {
2175 2090 struct cirrusfb_info *cinfo;
2176 2091 struct fb_info *info;
2177   - enum cirrus_board btype;
2178 2092 unsigned long board_addr, board_size;
2179 2093 int ret;
2180 2094  
2181 2095  
... ... @@ -2192,11 +2106,11 @@
2192 2106 }
2193 2107  
2194 2108 cinfo = info->par;
2195   - cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
  2109 + cinfo->btype = (enum cirrus_board) ent->driver_data;
2196 2110  
2197 2111 dev_dbg(info->device,
2198 2112 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2199   - (unsigned long long)pdev->resource[0].start, btype);
  2113 + (unsigned long long)pdev->resource[0].start, cinfo->btype);
2200 2114 dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2201 2115 (unsigned long long)pdev->resource[1].start);
2202 2116  
... ... @@ -2219,7 +2133,7 @@
2219 2133 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2220 2134 board_addr, info->fix.mmio_start);
2221 2135  
2222   - board_size = (btype == BT_GD5480) ?
  2136 + board_size = (cinfo->btype == BT_GD5480) ?
2223 2137 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2224 2138  
2225 2139 ret = pci_request_regions(pdev, "cirrusfb");
2226 2140  
... ... @@ -2425,28 +2339,7 @@
2425 2339 };
2426 2340 #endif /* CONFIG_ZORRO */
2427 2341  
2428   -static int __init cirrusfb_init(void)
2429   -{
2430   - int error = 0;
2431   -
2432 2342 #ifndef MODULE
2433   - char *option = NULL;
2434   -
2435   - if (fb_get_options("cirrusfb", &option))
2436   - return -ENODEV;
2437   - cirrusfb_setup(option);
2438   -#endif
2439   -
2440   -#ifdef CONFIG_ZORRO
2441   - error |= zorro_register_driver(&cirrusfb_zorro_driver);
2442   -#endif
2443   -#ifdef CONFIG_PCI
2444   - error |= pci_register_driver(&cirrusfb_pci_driver);
2445   -#endif
2446   - return error;
2447   -}
2448   -
2449   -#ifndef MODULE
2450 2343 static int __init cirrusfb_setup(char *options)
2451 2344 {
2452 2345 char *this_opt;
... ... @@ -2477,6 +2370,27 @@
2477 2370 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2478 2371 MODULE_LICENSE("GPL");
2479 2372  
  2373 +static int __init cirrusfb_init(void)
  2374 +{
  2375 + int error = 0;
  2376 +
  2377 +#ifndef MODULE
  2378 + char *option = NULL;
  2379 +
  2380 + if (fb_get_options("cirrusfb", &option))
  2381 + return -ENODEV;
  2382 + cirrusfb_setup(option);
  2383 +#endif
  2384 +
  2385 +#ifdef CONFIG_ZORRO
  2386 + error |= zorro_register_driver(&cirrusfb_zorro_driver);
  2387 +#endif
  2388 +#ifdef CONFIG_PCI
  2389 + error |= pci_register_driver(&cirrusfb_pci_driver);
  2390 +#endif
  2391 + return error;
  2392 +}
  2393 +
2480 2394 static void __exit cirrusfb_exit(void)
2481 2395 {
2482 2396 #ifdef CONFIG_PCI
... ... @@ -2683,7 +2597,7 @@
2683 2597 {
2684 2598 /* now busy-wait until we're done */
2685 2599 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2686   - /* do nothing */ ;
  2600 + cpu_relax();
2687 2601 }
2688 2602  
2689 2603 /*******************************************************************