diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/cirrusfb.c | 79 |
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 */ |
96 | enum cirrus_board { | 96 | enum 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; |