diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2009-03-31 15:25:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 08:59:33 -0700 |
commit | ddb53d48da5b0e691f35e703ac29118747f86c99 (patch) | |
tree | bdf0f4a6f3e74a87e5b2ccb9530f708eed6258d2 /drivers/video | |
parent | ec549a0fdc32171b26677f1ef0b5309faa743362 (diff) |
fbdev: remove cyblafb driver
A tridentfb driver has all the functionality of the cyblafb driver without
the bugs of the latter.
Changes to the tridentfb driver:
- FBINFO_READS_FAST added to the tridentfb. The cyblafb used a blitter
for scrolling which is faster than color expansion on Cyberblade
chipsets. The blitter is slower on a discrete Blade3D core. Use the
blitter for scrolling in the tridentfb only for integrated Blade3D
cores. Now, scrolling speed is about equal for the tridentfb and the
cyblafb.
- a copyright notice addition is done on request of Jani Monoses (the
first author of the tridentfb).
Tested on AGP Blade3D card and PCChips
M787CLR motherboard: VIA C3 cpu +
VT8601 north bridge (aka Cyberblade/i1).
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Cc: "Jani Monoses" <jani@ubuntu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/Kconfig | 28 | ||||
-rw-r--r-- | drivers/video/cyblafb.c | 1683 | ||||
-rw-r--r-- | drivers/video/tridentfb.c | 6 |
3 files changed, 7 insertions, 1710 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index c19f6feb4e5..db7a4f42eda 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1597,30 +1597,6 @@ config FB_VT8623 Driver for CastleRock integrated graphics core in the VIA VT8623 [Apollo CLE266] chipset. -config FB_CYBLA - tristate "Cyberblade/i1 support" - depends on FB && PCI && X86_32 && !64BIT - select FB_CFB_IMAGEBLIT - ---help--- - This driver is supposed to support the Trident Cyberblade/i1 - graphics core integrated in the VIA VT8601A North Bridge, - also known as VIA Apollo PLE133. - - Status: - - Developed, tested and working on EPIA 5000 and EPIA 800. - - Does work reliable on all systems with CRT/LCD connected to - normal VGA ports. - - Should work on systems that do use the internal LCD port, but - this is absolutely not tested. - - Character imageblit, copyarea and rectangle fill are hw accelerated, - ypan scrolling is used by default. - - Please do read <file:Documentation/fb/cyblafb/*>. - - To compile this driver as a module, choose M here: the - module will be called cyblafb. - config FB_TRIDENT tristate "Trident support" depends on FB && PCI @@ -1633,8 +1609,8 @@ config FB_TRIDENT and Blade XP. There are also integrated versions of these chips called CyberXXXX, CyberImage or CyberBlade. These chips are mostly found in laptops - but also on some motherboards. For more information, read - <file:Documentation/fb/tridentfb.txt> + but also on some motherboards including early VIA EPIA motherboards. + For more information, read <file:Documentation/fb/tridentfb.txt> Say Y if you have such a graphics board. diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c deleted file mode 100644 index 9704b73135f..00000000000 --- a/drivers/video/cyblafb.c +++ /dev/null @@ -1,1683 +0,0 @@ -/* - * Frame buffer driver for Trident Cyberblade/i1 graphics core - * - * Copyright 2005 Knut Petersen <Knut_Petersen@t-online.de> - * - * CREDITS: - * tridentfb.c by Jani Monoses - * see files above for further credits - * - */ - -#define CYBLAFB_DEBUG 0 -#define CYBLAFB_KD_GRAPHICS_QUIRK 1 - -#define CYBLAFB_PIXMAPSIZE 8192 - -#include <linux/module.h> -#include <linux/string.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <asm/types.h> -#include <video/cyblafb.h> - -#define VERSION "0.62" - -struct cyblafb_par { - u32 pseudo_pal[16]; - struct fb_ops ops; -}; - -static struct fb_fix_screeninfo cyblafb_fix __devinitdata = { - .id = "CyBla", - .type = FB_TYPE_PACKED_PIXELS, - .xpanstep = 1, - .ypanstep = 1, - .ywrapstep = 1, - .visual = FB_VISUAL_PSEUDOCOLOR, - .accel = FB_ACCEL_NONE, -}; - -static char *mode __devinitdata = NULL; -static int bpp __devinitdata = 8; -static int ref __devinitdata = 75; -static int fp __devinitdata; -static int crt __devinitdata; -static int memsize __devinitdata; - -static int basestride; -static int vesafb; -static int nativex; -static int center; -static int stretch; -static int pciwb = 1; -static int pcirb = 1; -static int pciwr = 1; -static int pcirr = 1; -static int disabled; -static int verbosity; -static int displaytype; - -static void __iomem *io_virt; // iospace virtual memory address - -module_param(mode, charp, 0); -module_param(bpp, int, 0); -module_param(ref, int, 0); -module_param(fp, int, 0); -module_param(crt, int, 0); -module_param(nativex, int, 0); -module_param(center, int, 0); -module_param(stretch, int, 0); -module_param(pciwb, int, 0); -module_param(pcirb, int, 0); -module_param(pciwr, int, 0); -module_param(pcirr, int, 0); -module_param(memsize, int, 0); -module_param(verbosity, int, 0); - -//========================================= -// -// Well, we have to fix the upper layers. -// Until this has been done, we work around -// the bugs. -// -//========================================= - -#if (CYBLAFB_KD_GRAPHICS_QUIRK && CYBLAFB_DEBUG) - if (disabled) { \ - printk("********\n");\ - dump_stack();\ - return val;\ - } - -#elif CYBLAFB_KD_GRAPHICS_QUIRK -#define KD_GRAPHICS_RETURN(val)\ - if (disabled) {\ - return val;\ - } -#else -#define KD_GRAPHICS_RETURN(val) -#endif - -//========================================= -// -// Port access macros for memory mapped io -// -//========================================= - -#define out8(r, v) writeb(v, io_virt + r) -#define out32(r, v) writel(v, io_virt + r) -#define in8(r) readb(io_virt + r) -#define in32(r) readl(io_virt + r) - -//====================================== -// -// Hardware access inline functions -// -//====================================== - -static inline u8 read3X4(u32 reg) -{ - out8(0x3D4, reg); - return in8(0x3D5); -} - -static inline u8 read3C4(u32 reg) -{ - out8(0x3C4, reg); - return in8(0x3C5); -} - -static inline u8 read3CE(u32 reg) -{ - out8(0x3CE, reg); - return in8(0x3CF); -} - -static inline void write3X4(u32 reg, u8 val) -{ - out8(0x3D4, reg); - out8(0x3D5, val); -} - -static inline void write3C4(u32 reg, u8 val) -{ - out8(0x3C4, reg); - out8(0x3C5, val); -} - -static inline void write3CE(u32 reg, u8 val) -{ - out8(0x3CE, reg); - out8(0x3CF, val); -} - -static inline void write3C0(u32 reg, u8 val) -{ - in8(0x3DA); // read to reset index - out8(0x3C0, reg); - out8(0x3C0, val); -} - -//================================================= -// -// Enable memory mapped io and unprotect registers -// -//================================================= - -static void enable_mmio(void) -{ - u8 tmp; - - outb(0x0B, 0x3C4); - inb(0x3C5); // Set NEW mode - outb(SR0E, 0x3C4); // write enable a lot of extended ports - outb(0x80, 0x3C5); - - outb(SR11, 0x3C4); // write enable those extended ports that - outb(0x87, 0x3C5); // are not affected by SR0E_New - - outb(CR1E, 0x3d4); // clear write protect bit for port 0x3c2 - tmp = inb(0x3d5) & 0xBF; - outb(CR1E, 0x3d4); - outb(tmp, 0x3d5); - - outb(CR39, 0x3D4); - outb(inb(0x3D5) | 0x01, 0x3D5); // Enable mmio -} - -//================================================= -// -// Set pixel clock VCLK1 -// - multipliers set elswhere -// - freq in units of 0.01 MHz -// -// Hardware bug: SR18 >= 250 is broken for the -// cyberblade/i1 -// -//================================================= - -static void set_vclk(struct cyblafb_par *par, int freq) -{ - u32 m, n, k; - int f, fi, d, di; - u8 lo = 0, hi = 0; - - d = 2000; - k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3; - for (m = 0; m < 64; m++) - for (n = 0; n < 250; n++) { - fi = (int)(((5864727 * (n + 8)) / - ((m + 2) * (1 << k))) >> 12); - if ((di = abs(fi - freq)) < d) { - d = di; - f = fi; - lo = (u8) n; - hi = (u8) ((k << 6) | m); - } - } - write3C4(SR19, hi); - write3C4(SR18, lo); - if (verbosity > 0) - output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n", - freq / 100, freq % 100, (hi & 0xc0) >> 6, hi & 0x3f, lo); -} - -//================================================ -// -// Cyberblade specific Graphics Engine (GE) setup -// -//================================================ - -static void cyblafb_setup_GE(int pitch, int bpp) -{ - KD_GRAPHICS_RETURN(); - - switch (bpp) { - case 8: - basestride = ((pitch >> 3) << 20) | (0 << 29); - break; - case 15: - basestride = ((pitch >> 3) << 20) | (5 << 29); - break; - case 16: - basestride = ((pitch >> 3) << 20) | (1 << 29); - break; - case 24: - case 32: - basestride = ((pitch >> 3) << 20) | (2 << 29); - break; - } - - write3X4(CR36, 0x90); // reset GE - write3X4(CR36, 0x80); // enable GE - out32(GE24, 1 << 7); // reset all GE pointers by toggling - out32(GE24, 0); // d7 of GE24 - write3X4(CR2D, 0x00); // GE Timinigs, no delays - out32(GE6C, 0); // Pattern and Style, p 129, ok -} - -//===================================================================== -// -// Cyberblade specific syncing -// -// A timeout might be caused by disabled mmio. -// Cause: -// - bit CR39 & 1 == 0 upon return, X trident driver bug -// - kdm bug (KD_GRAPHICS not set on first switch) -// - kernel design flaw (it believes in the correctness -// of kdm/X -// First we try to sync ignoring that problem, as most of the -// time that will succeed immediately and the enable_mmio() -// would only degrade performance. -// -//===================================================================== - -static int cyblafb_sync(struct fb_info *info) -{ - u32 status, i = 100000; - - KD_GRAPHICS_RETURN(0); - - while (((status = in32(GE20)) & 0xFe800000) && i != 0) - i--; - - if (i == 0) { - enable_mmio(); - i = 1000000; - while (((status = in32(GE20)) & 0xFA800000) && i != 0) - i--; - if (i == 0) { - output("GE Timeout, status: %x\n", status); - if (status & 0x80000000) - output("Bresenham Engine : Busy\n"); - if (status & 0x40000000) - output("Setup Engine : Busy\n"); - if (status & 0x20000000) - output("SP / DPE : Busy\n"); - if (status & 0x10000000) - output("Memory Interface : Busy\n"); - if (status & 0x08000000) - output("Com Lst Proc : Busy\n"); - if (status & 0x04000000) - output("Block Write : Busy\n"); - if (status & 0x02000000) - output("Command Buffer : Full\n"); - if (status & 0x01000000) - output("RESERVED : Busy\n"); - if (status & 0x00800000) - output("PCI Write Buffer : Busy\n"); - cyblafb_setup_GE(info->var.xres, - info->var.bits_per_pixel); - } - } - - return 0; -} - -//============================== -// -// Cyberblade specific fillrect -// -//============================== - -static void cyblafb_fillrect(struct fb_info *info, const struct fb_fillrect *fr) -{ - u32 bpp = info->var.bits_per_pixel, col, desty, height; - - KD_GRAPHICS_RETURN(); - - switch (bpp) { - default: - case 8: - col = fr->color; - col |= col << 8; - col |= col << 16; - break; - case 16: - col = ((u32 *) (info->pseudo_palette))[fr->color]; - col |= col << 16; - break; - case 32: - col = ((u32 *) (info->pseudo_palette))[fr->color]; - break; - } - - desty = fr->dy; - height = fr->height; - while (height) { - out32(GEB8, basestride | ((desty * info->var.xres_virtual * - bpp) >> 6)); - out32(GE60, col); - out32(GE48, fr->rop ? 0x66 : ROP_S); - out32(GE44, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2); - out32(GE08, point(fr->dx, 0)); - out32(GE0C, point(fr->dx + fr->width - 1, - height > 4096 ? 4095 : height - 1)); - if (likely(height <= 4096)) - return; - desty += 4096; - height -= 4096; - } -} - -//================================================ -// -// Cyberblade specific copyarea -// -// This function silently assumes that it never -// will be called with width or height exceeding -// 4096. -// -//================================================ - -static void cyblafb_copyarea(struct fb_info *info, const struct fb_copyarea *ca) -{ - u32 s1, s2, d1, d2, direction; - - KD_GRAPHICS_RETURN(); - - s1 = point(ca->sx, 0); - s2 = point(ca->sx + ca->width - 1, ca->height - 1); - d1 = point(ca->dx, 0); - d2 = point(ca->dx + ca->width - 1, ca->height - 1); - - if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx))) - direction = 0; - else - direction = 2; - - out32(GEB8, basestride | ((ca->dy * info->var.xres_virtual * - info->var.bits_per_pixel) >> 6)); - out32(GEC8, basestride | ((ca->sy * info->var.xres_virtual * - info->var.bits_per_pixel) >> 6)); - out32(GE44, 0xa0000000 | 1 << 19 | 1 << 2 | direction); - out32(GE00, direction ? s2 : s1); - out32(GE04, direction ? s1 : s2); - out32(GE08, direction ? d2 : d1); - out32(GE0C, direction ? d1 : d2); -} - -//======================================================================= -// -// Cyberblade specific imageblit -// -// Accelerated for the most usual case, blitting 1 - bit deep -// character images. Everything else is passed to the generic imageblit -// unless it is so insane that it is better to printk an alert. -// -// Hardware bug: _Never_ blit across pixel column 2048, that will lock -// the system. We split those blit requests into three blitting -// operations. -// -//======================================================================= - -static void cyblafb_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - u32 fgcol, bgcol; - u32 *pd = (u32 *) image->data; - u32 bpp = info->var.bits_per_pixel; - - KD_GRAPHICS_RETURN(); - - // Used only for drawing the penguine (image->depth > 1) - if (image->depth != 1) { - cfb_imageblit(info, image); - return; - } - // That should never happen, but it would be fatal - if (image->width == 0 || image->height == 0) { - output("imageblit: width/height 0 detected\n"); - return; - } - - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fgcol = ((u32 *) (info->pseudo_palette))[image->fg_color]; - bgcol = ((u32 *) (info->pseudo_palette))[image->bg_color]; - } else { - fgcol = image->fg_color; - bgcol = image->bg_color; - } - - switch (bpp) { - case 8: - fgcol |= fgcol << 8; - bgcol |= bgcol << 8; - case 16: - fgcol |= fgcol << 16; - bgcol |= bgcol << 16; - default: - break; - } - - out32(GEB8, basestride | ((image->dy * info->var.xres_virtual * - bpp) >> 6)); - out32(GE60, fgcol); - out32(GE64, bgcol); - - if (!(image->dx < 2048 && (image->dx + image->width - 1) >= 2048)) { - u32 dds = ((image->width + 31) >> 5) * image->height; - out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19); - out32(GE08, point(image->dx, 0)); - out32(GE0C, point(image->dx + image->width - 1, - image->height - 1)); - while (dds--) - out32(GE9C, *pd++); - } else { - int i, j; - u32 ddstotal = (image->width + 31) >> 5; - u32 ddsleft = (2048 - image->dx + 31) >> 5; - u32 skipleft = ddstotal - ddsleft; - - out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19); - out32(GE08, point(image->dx, 0)); - out32(GE0C, point(2048 - 1, image->height - 1)); - for (i = 0; i < image->height; i++) { - for (j = 0; j < ddsleft; j++) - out32(GE9C, *pd++); - pd += skipleft; - } - - if (image->dx % 32) { - out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19); - out32(GE08, point(2048, 0)); - if (image->width > ddsleft << 5) - out32(GE0C, point(image->dx + (ddsleft << 5) - - 1, image->height - 1)); - else - out32(GE0C, point(image->dx + image->width - 1, - image->height - 1)); - pd = ((u32 *) image->data) + ddstotal - skipleft - 1; - for (i = 0; i < image->height; i++) { - out32(GE9C, swab32(swab32(*pd) << ((32 - - (image->dx & 31)) & 31))); - pd += ddstotal; - } - } - - if (skipleft) { - out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19); - out32(GE08, point(image->dx + (ddsleft << 5), 0)); - out32(GE0C, point(image->dx + image->width - 1, - image->height - 1)); - pd = (u32 *) image->data; - for (i = 0; i < image->height; i++) { - pd += ddsleft; - for (j = 0; j < skipleft; j++) - out32(GE9C, *pd++); - } - } - } -} - -//========================================================== -// -// Check if video mode is acceptable. We change var->??? if -// video mode is slightly off or return error otherwise. -// info->??? must not be changed! -// -//========================================================== - -static int cyblafb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - int bpp = var->bits_per_pixel; - - // - // we try to support 8, 16, 24 and 32 bpp modes, - // default to 8 - // - // there is a 24 bpp mode, but for now we change requests to 32 bpp - // (This is what tridentfb does ... will be changed in the future) - // - // - if (bpp % 8 != 0 || bpp < 8 || bpp > 32) - bpp = 8; - if (bpp == 24) - bpp = var->bits_per_pixel = 32; - - // - // interlaced modes are broken, fail if one is requested - // - if (var->vmode & FB_VMODE_INTERLACED) - return -EINVAL; - - // - // fail if requested resolution is higher than physical - // flatpanel resolution - // - if ((displaytype == DISPLAY_FP) && nativex && var->xres > nativex) - return -EINVAL; - - // - // we do not allow vclk to exceed 230 MHz. If the requested - // vclk is too high, we default to 200 MHz - // - if ((bpp == 32 ? 200000000 : 100000000) / var->pixclock > 23000) - var->pixclock = (bpp == 32 ? 200000000 : 100000000) / 20000; - - // - // enforce (h|v)sync_len limits - // - var->hsync_len &= ~7; - if(var->hsync_len > 248) - var->hsync_len = 248; - - var->vsync_len &= 15; - - // - // Enforce horizontal and vertical hardware limits. - // 1600x1200 is mentioned as a maximum, but higher resolutions could - // work with slow refresh, small margins and short sync. - // - var->xres &= ~7; - - if (((var->xres + var->left_margin + var->right_margin + - var->hsync_len) > (bpp == 32 ? 2040 : 4088)) || - ((var->yres + var->upper_margin + var->lower_margin + - var->vsync_len) > 2047)) - return -EINVAL; - - if ((var->xres > 1600) || (var->yres > 1200)) - output("Mode %dx%d exceeds documented limits.\n", - var->xres, var->yres); - // - // try to be smart about (x|y)res_virtual problems. - // - if (var->xres > var->xres_virtual) - var->xres_virtual = var->xres; - if (var->yres > var->yres_virtual) - var->yres_virtual = var->yres; - - if (bpp == 8 || bpp == 16) { - if (var->xres_virtual > 4088) - var->xres_virtual = 4088; - } else { - if (var->xres_virtual > 2040) - var->xres_virtual = 2040; - } - var->xres_virtual &= ~7; - while (var->xres_virtual * var->yres_virtual * bpp / 8 > - info->fix.smem_len) { - if (var->yres_virtual > var->yres) - var->yres_virtual--; - else if (var->xres_virtual > var->xres) - var->xres_virtual -= 8; - else - return -EINVAL; - } - - switch (bpp) { - case 8: - var->red.offset = 0; - var->green.offset = 0; - var->blue.offset = 0; - var->red.length = 6; - var->green.length = 6; - var->blue.length = 6; - break; - case 16: - var->red.offset = 11; - var->green.offset = 5; - var->blue.offset = 0; - var->red.length = 5; - var->green.length = 6; - var->blue.length = 5; - break; - case 32: - var->red.offset = 16; - var->green.offset = 8; - var->blue.offset = 0; - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - break; - default: - return -EINVAL; - } - - return 0; -} - -//===================================================================== -// -// Pan the display -// -// The datasheets defines crt start address to be 20 bits wide and -// to be programmed to CR0C, CR0D, CR1E and CR27. Actually there is -// CR2B[5] as an undocumented extension bit. Epia BIOS 2.07 does use -// it, so it is also safe to be used here. BTW: datasheet CR0E on page -// 90 really is CR1E, the real CRE is documented on page 72. -// -// BUT: -// -// As of internal version 0.60 we do not use vga panning any longer. -// Vga panning did not allow us the use of all available video memory -// and thus prevented ywrap scrolling. We do use the "right view" -// register now. -// -// -//===================================================================== - -static int cyblafb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - KD_GRAPHICS_RETURN(0); - - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - out32(GE10, 0x80000000 | ((var->xoffset + (var->yoffset * - var->xres_virtual)) * var->bits_per_pixel / 32)); - return 0; -} - -//============================================ -// -// This will really help in case of a bug ... -// dump most gaphics core registers. -// -//============================================ - -static void regdump(struct cyblafb_par *par) -{ - int i; - - if (verbosity < 2) - return; - - printk("\n"); - for (i = 0; i <= 0xff; i++) { - outb(i, 0x3d4); - printk("CR%02x=%02x ", i, inb(0x3d5)); - if (i % 16 == 15) - printk("\n"); - } - - outb(0x30, 0x3ce); - outb(inb(0x3cf) | 0x40, 0x3cf); - for (i = 0; i <= 0x1f; i++) { - if (i == 0 || (i > 2 && i < 8) || i == 0x10 || i == 0x11 - || i == 0x16) { - outb(i, 0x3d4); - printk("CR%02x=%02x ", i, inb(0x3d5)); - } else - printk("------- "); - if (i % 16 == 15) - printk("\n"); - } - outb(0x30, 0x3ce); - outb(inb(0x3cf) & 0xbf, 0x3cf); - - printk("\n"); - for (i = 0; i <= 0x7f; i++) { - outb(i, 0x3ce); - printk("GR%02x=%02x ", i, inb(0x3cf)); - if (i % 16 == 15) - printk("\n"); - } - - printk("\n"); - for (i = 0; i <= 0xff; i++) { - outb(i, 0x3c4); - printk("SR%02x=%02x ", i, inb(0x3c5)); - if (i % 16 == 15) - printk("\n"); - } - - printk("\n"); - for (i = 0; i <= 0x1F; i++) { - inb(0x3da); // next access is index! - outb(i, 0x3c0); - printk("AR%02x=%02x ", i, inb(0x3c1)); - if (i % 16 == 15) - printk("\n"); - } - printk("\n"); - - inb(0x3DA); // reset internal flag to 3c0 index - outb(0x20, 0x3C0); // enable attr - - return; -} - -//======================================================================= -// -// Save State -// -// This function is called while a switch to KD_TEXT is in progress, -// before any of the other functions are called. -// -//======================================================================= - -static void cyblafb_save_state(struct fb_info *info) -{ - struct cyblafb_par *par = info->par; - if (verbosity > 0) - output("Switching to KD_TEXT\n"); - disabled = 0; - regdump(par); - enable_mmio(); - return; -} - -//======================================================================= -// -// Restore State -// -// This function is called while a switch to KD_GRAPHICS is in progress, -// We have to turn on vga style panning registers again because the -// trident driver of X does not know about GE10. -// -//======================================================================= - -static void cyblafb_restore_state(struct fb_info *info) -{ - if (verbosity > 0) - output("Switching to KD_GRAPHICS\n"); - out32(GE10, 0); - disabled = 1; - return; -} - -//====================================== -// -// Set hardware to requested video mode -// -//====================================== - -static int cyblafb_set_par(struct fb_info *info) -{ - struct cyblafb_par *par = info->par; - u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, - hblankend, preendfetch, vtotal, vdispend, vsyncstart, - vsyncend, vblankstart, vblankend; - struct fb_var_screeninfo *var = &info->var; - int bpp = var->bits_per_pixel; - int i; - - KD_GRAPHICS_RETURN(0); - - if (verbosity > 0) - output("Switching to new mode: " - "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n", - var->xres, var->yres, var->xres_virtual, - var->yres_virtual, var->bits_per_pixel, var->pixclock, - var->left_margin, var->right_margin, var->upper_margin, - var->lower_margin, var->hsync_len, var->vsync_len); - - htotal = (var->xres + var->left_margin + var->right_margin + - var->hsync_len) / 8 - 5; - hdispend = var->xres / 8 - 1; - hsyncstart = (var->xres + var->right_margin) / 8; - hsyncend = var->hsync_len / 8; - hblankstart = hdispend + 1; - hblankend = htotal + 3; // should be htotal + 5, bios does it this way - preendfetch = ((var->xres >> 3) + 1) * ((bpp + 1) >> 3); - - vtotal = var->yres + var->upper_margin + var->lower_margin + - var->vsync_len - 2; - vdispend = var->yres - 1; - vsyncstart = var->yres + var->lower_margin; - vblankstart = var->yres; - vblankend = vtotal; // should be vtotal + 2, but bios does it this way - vsyncend = var->vsync_len; - - enable_mmio(); // necessary! ... check X ... - - write3X4(CR11, read3X4(CR11) & 0x7F); // unlock cr00 .. cr07 - - write3CE(GR30, 8); - - if ((displaytype == DISPLAY_FP) && var->xres < nativex) { - - // stretch or center ? - - out8(0x3C2, 0xEB); - - write3CE(GR30, read3CE(GR30) | 0x81); // shadow mode on - - if (center) { - write3CE(GR52, (read3CE(GR52) & 0x7C) | 0x80); - write3CE(GR53, (read3CE(GR53) & 0x7C) | 0x80); - } else if (stretch) { - write3CE(GR5D, 0); - write3CE(GR52, (read3CE(GR52) & 0x7C) | 1); - write3CE(GR53, (read3CE(GR53) & 0x7C) | 1); - } - - } else { - out8(0x3C2, 0x2B); - write3CE(GR30, 8); - } - - // - // Setup CRxx regs - // - - write3X4(CR00, htotal & 0xFF); - write3X4(CR01, hdispend & 0xFF); - write3X4(CR02, hblankstart & 0xFF); - write3X4(CR03, hblankend & 0x1F); - write3X4(CR04, hsyncstart & 0xFF); - write3X4(CR05, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2)); - write3X4(CR06, vtotal & 0xFF); - write3X4(CR07, (vtotal & 0x100) >> 8 | - (vdispend & 0x100) >> 7 | - (vsyncstart & 0x100) >> 6 | - (vblankstart & 0x100) >> 5 | - 0x10 | - (vtotal & 0x200) >> 4 | - (vdispend & 0x200) >> 3 | (vsyncstart & 0x200) >> 2); - write3X4(CR08, 0); - write3X4(CR09, (vblankstart & 0x200) >> 4 | 0x40 | // FIX !!! - ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0)); - write3X4(CR0A, 0); // Init to some reasonable default - write3X4(CR0B, 0); // Init to some reasonable default - write3X4(CR0C, 0); // Offset 0 - write3X4(CR0D, 0); // Offset 0 - write3X4(CR0E, 0); // Init to some reasonable default - write3X4(CR0F, 0); // Init to some reasonable default - write3X4(CR10, vsyncstart & 0xFF); - write3X4(CR11, (vsyncend & 0x0F)); - write3X4(CR12, vdispend & 0xFF); - write3X4(CR13, ((info->var.xres_virtual * bpp) / (4 * 16)) & 0xFF); - write3X4(CR14, 0x40); // double word mode - write3X4(CR15, vblankstart & 0xFF); - write3X4(CR16, vblankend & 0xFF); - write3X4(CR17, 0xE3); - write3X4(CR18, 0xFF); - // CR19: needed for interlaced modes ... ignore it for now - write3X4(CR1A, 0x07); // Arbitration Control Counter 1 - write3X4(CR1B, 0x07); // Arbitration Control Counter 2 - write3X4(CR1C, 0x07); // Arbitration Control Counter 3 - write3X4(CR1D, 0x00); // Don't know, doesn't hurt ; -) - write3X4(CR1E, (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80); - // CR1F: do not set, contains BIOS info about memsize - write3X4(CR20, 0x20); // enabe wr buf, disable 16bit planar mode - write3X4(CR21, 0x20); // enable linear memory access - // CR22: RO cpu latch readback - // CR23: ??? - // CR24: RO AR flag state - // CR25: RAMDAC rw timing, pclk buffer tristate control ???? - // CR26: ??? - write3X4(CR27, (vdispend & 0x400) >> 6 | - (vsyncstart & 0x400) >> 5 | - (vblankstart & 0x400) >> 4 | - (vtotal & 0x400) >> 3 | - 0x8); - // CR28: ??? - write3X4(CR29, (read3X4(CR29) & 0xCF) | ((((info->var.xres_virtual * - bpp) / (4 * 16)) & 0x300) >> 4)); - write3X4(CR2A, read3X4(CR2A) | 0x40); - write3X4(CR2B, (htotal & 0x100) >> 8 | - (hdispend & 0x100) >> 7 | - // (0x00 & 0x100) >> 6 | hinterlace para bit 8 ??? - (hsyncstart & 0x100) >> 5 | - (hblankstart & 0x100) >> 4); - // CR2C: ??? - // CR2D: initialized in cyblafb_setup_GE() - write3X4(CR2F, 0x92); // conservative, better signal quality - // CR30: reserved - // CR31: reserved - // CR32: reserved - // CR33: reserved - // CR34: disabled in CR36 - // CR35: disabled in CR36 - // CR36: initialized in cyblafb_setup_GE - // CR37: i2c, ignore for now - write3X4(CR38, (bpp == 8) ? 0x00 : // - (bpp == 16) ? 0x05 : // highcolor - (bpp == 24) ? 0x29 : // packed 24bit truecolor - (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus - write3X4(CR39, 0x01 | // MMIO enable - (pcirb ? 0x02 : 0) | // pci read burst enable - (pciwb ? 0x04 : 0)); // pci write burst enable - write3X4(CR55, 0x1F | // pci clocks * 2 for STOP# during 1st data phase - (pcirr ? 0x40 : 0) | // pci read retry enable - (pciwr ? 0x80 : 0)); // pci write retry enable - write3X4(CR56, preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01) | 2 - : 0); - write3X4(CR57, preendfetch >> 8 < 2 ? preendfetch & 0xff : 0); - write3X4(CR58, 0x82); // Bios does this .... don't know more - // - // Setup SRxx regs - // - write3C4(SR00, 3); - write3C4(SR01, 1); //set char clock 8 dots wide - write3C4(SR02, 0x0F); //enable 4 maps needed in chain4 mode - write3C4(SR03, 0); //no character map select - write3C4(SR04, 0x0E); //memory mode: ext mem, even, chain4 - - out8(0x3C4, 0x0b); - in8(0x3C5); // Set NEW mode - write3C4(SR0D, 0x00); // test ... check - - set_vclk(par, (bpp == 32 ? 200000000 : 100000000) - / info->var.pixclock); //SR18, SR19 - - // - // Setup GRxx regs - // - write3CE(GR00, 0x00); // test ... check - write3CE(GR01, 0x00); // test ... check - write3CE(GR02, 0x00); // test ... check - write3CE(GR03, 0x00); // test ... check - write3CE(GR04, 0x00); // test ... check - write3CE(GR05, 0x40); // no CGA compat, allow 256 col - write3CE(GR06, 0x05); // graphics mode - write3CE(GR07, 0x0F); // planes? - write3CE(GR08, 0xFF); // test ... check - write3CE(GR0F, (bpp == 32) ? 0x1A : 0x12); // vclk / 2 if 32bpp, chain4 - write3CE(GR20, 0xC0); // test ... check - write3CE(GR2F, 0xA0); // PCLK = VCLK, no skew, - - // - // Setup ARxx regs - // - for (i = 0; i < 0x10; i++) // set AR00 .. AR0f - write3C0(i, i); - write3C0(AR10, 0x41); // graphics mode and support 256 color modes - write3C0(AR12, 0x0F); // planes - write3C0(AR13, 0); // horizontal pel panning - in8(0x3DA); // reset internal flag to 3c0 index - out8(0x3C0, 0x20); // enable attr - - // - // Setup hidden RAMDAC command register - // - in8(0x3C8); // these reads are - in8(0x3C6); // necessary to - in8(0x3C6); // unmask the RAMDAC - in8(0x3C6); // command reg, otherwise - in8(0x3C6); // we would write the pixelmask reg! - out8(0x3C6, (bpp == 8) ? 0x00 : // 256 colors - (bpp == 15) ? 0x10 : // - (bpp == 16) ? 0x30 : // hicolor - (bpp == 24) ? 0xD0 : // truecolor - (bpp == 32) ? 0xD0 : 0); // truecolor - in8(0x3C8); - - // - // GR31 is not mentioned in the datasheet - // - if (displaytype == DISPLAY_FP) - write3CE(GR31, (read3CE(GR31) & 0x8F) | - ((info->var.yres > 1024) ? 0x50 : - (info->var.yres > 768) ? 0x30 : - (info->var.yres > 600) ? 0x20 : - (info->var.yres > 480) ? 0x10 : 0)); - - info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR - : FB_VISUAL_TRUECOLOR; - info->fix.line_length = info->var.xres_virtual * (bpp >> 3); - info->cmap.len = (bpp == 8) ? 256 : 16; - - // - // init acceleration engine - // - cyblafb_setup_GE(info->var.xres_virtual, info->var.bits_per_pixel); - - // - // Set/clear flags to allow proper scroll mode selection. - // - if (var->xres == var->xres_virtual) - info->flags &= ~FBINFO_HWACCEL_XPAN; - else - info->flags |= FBINFO_HWACCEL_XPAN; - - if (var->yres == var->yres_virtual) - info->flags &= ~FBINFO_HWACCEL_YPAN; - else - info->flags |= FBINFO_HWACCEL_YPAN; - - if (info->fix.smem_len != - var->xres_virtual * var->yres_virtual * bpp / 8) - info->flags &= ~FBINFO_HWACCEL_YWRAP; - else - info->flags |= FBINFO_HWACCEL_YWRAP; - - regdump(par); - - return 0; -} - -//======================== -// -// Set one color register -// -//======================== - -static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) -{ - int bpp = info->var.bits_per_pixel; - - KD_GRAPHICS_RETURN(0); - - if (regno >= info->cmap.len) - return 1; |