Commit 81ad954b authored by Russell King's avatar Russell King

[ARM] Update Cyber2000fb driver for new fbcon API

This cset updates cyber2000fb (used on NetWinders) to the new
fbcon API, and adds cfbfillrect, cfbcopyarea and cfbimgblt
objects when building cyber2000fb.
parent 4db5d54e
...@@ -31,7 +31,7 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o cfbfillrect.o cfbcopyarea.o cfbim ...@@ -31,7 +31,7 @@ obj-$(CONFIG_FB_CT65550) += chipsfb.o cfbfillrect.o cfbcopyarea.o cfbim
obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CYBER) += cyberfb.o obj-$(CONFIG_FB_CYBER) += cyberfb.o
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o cfbimgblt.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o cfbimgblt.o
obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
......
...@@ -55,12 +55,6 @@ ...@@ -55,12 +55,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include "cyber2000fb.h" #include "cyber2000fb.h"
struct cfb_info { struct cfb_info {
...@@ -147,167 +141,114 @@ cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb) ...@@ -147,167 +141,114 @@ cyber2000_seqw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
/* /*
* Hardware Cyber2000 Acceleration * Hardware Cyber2000 Acceleration
*/ */
static void cyber2000_accel_wait(struct cfb_info *cfb)
{
int count = 100000;
while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
if (!count--) {
debug_printf("accel_wait timed out\n");
cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
return;
}
udelay(1);
}
}
static void cyber2000_accel_setup(struct display *display)
{
struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
cfb->dispsw->setup(display);
}
static void static void
cyber2000_accel_bmove(struct display *display, int sy, int sx, int dy, int dx, cyber2000fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
int height, int width)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
struct fb_var_screeninfo *var = &display->var; unsigned long dst, col;
u_long src, dst;
u_int fh, fw, cmd = CO_CMD_L_PATTERN_FGCOL;
fw = fontwidth(display);
sx *= fw;
dx *= fw;
width *= fw;
width -= 1;
if (sx < dx) {
sx += width;
dx += width;
cmd |= CO_CMD_L_INC_LEFT;
}
fh = fontheight(display);
sy *= fh;
dy *= fh;
height *= fh;
height -= 1;
if (sy < dy) { if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
sy += height; cfb_fillrect(info, rect);
dy += height; return;
cmd |= CO_CMD_L_INC_UP;
} }
src = sx + sy * var->xres_virtual; cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
dst = dx + dy * var->xres_virtual; cyber2000fb_writew(rect->width - 1, CO_REG_PIXWIDTH, cfb);
cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb);
cyber2000_accel_wait(cfb); col = rect->color;
cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb); if (cfb->fb.var.bits_per_pixel > 8)
cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb); col = ((u32 *)cfb->fb.pseudo_palette)[col];
cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb); cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb);
if (var->bits_per_pixel == 24) { dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual;
if (cfb->fb.var.bits_per_pixel == 24) {
cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
dst *= 3; dst *= 3;
src *= 3;
} }
cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb); cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
cyber2000fb_writew(CO_CMD_H_FGSRCMAP|CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb);
} }
static void static void
cyber2000_accel_clear(struct vc_data *conp, struct display *display, int sy, cyber2000fb_copyarea(struct fb_info *info, struct fb_copyarea *region)
int sx, int height, int width)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
struct fb_var_screeninfo *var = &display->var; unsigned int cmd = CO_CMD_L_PATTERN_FGCOL;
u_long dst; unsigned long src, dst;
u_int fw, fh;
u32 bgx = attr_bgcol_ec(display, conp);
fw = fontwidth(display); if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
fh = fontheight(display); cfb_copyarea(info, region);
return;
}
if (region->sx < region->dx) {
region->sx += region->width - 1;
region->dx += region->width - 1;
cmd |= CO_CMD_L_INC_LEFT;
}
dst = sx * fw + sy * var->xres_virtual * fh; if (region->sy < region->dy) {
width = width * fw - 1; region->sy += region->height - 1;
height = height * fh - 1; region->dy += region->height - 1;
cmd |= CO_CMD_L_INC_UP;
}
cyber2000_accel_wait(cfb); cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb); cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb);
cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb); cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb);
cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb);
if (var->bits_per_pixel == 24) { src = region->sx + region->sy * cfb->fb.var.xres_virtual;
dst = region->dx + region->dy * cfb->fb.var.xres_virtual;
if (cfb->fb.var.bits_per_pixel == 24) {
cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb); cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
src *= 3;
dst *= 3; dst *= 3;
} }
cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
if (var->bits_per_pixel == 16)
bgx = ((u16 *)display->dispsw_data)[bgx];
else if (var->bits_per_pixel >= 24)
bgx = ((u32 *)display->dispsw_data)[bgx];
cyber2000fb_writel(bgx, CO_REG_FGCOLOUR, cfb);
cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb); cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb); cyber2000fb_writew(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb); cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb); cyber2000fb_writew(CO_CMD_H_FGSRCMAP | CO_CMD_H_BLITTER,
} CO_REG_CMD_H, cfb);
static void
cyber2000_accel_putc(struct vc_data *conp, struct display *display, int c,
int yy, int xx)
{
struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
cyber2000_accel_wait(cfb);
cfb->dispsw->putc(conp, display, c, yy, xx);
} }
static void static void
cyber2000_accel_putcs(struct vc_data *conp, struct display *display, cyber2000fb_imageblit(struct fb_info *info, struct fb_image *image)
const unsigned short *s, int count, int yy, int xx)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
cyber2000_accel_wait(cfb); // if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
cfb->dispsw->putcs(conp, display, s, count, yy, xx); cfb_imageblit(info, image);
return;
// }
} }
static void cyber2000_accel_revc(struct display *display, int xx, int yy) static int cyber2000fb_sync(struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)display->fb_info; struct cfb_info *cfb = (struct cfb_info *)info;
int count = 100000;
cyber2000_accel_wait(cfb);
cfb->dispsw->revc(display, xx, yy);
}
static void if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT))
cyber2000_accel_clear_margins(struct vc_data *conp, struct display *display, return 0;
int bottom_only)
{
struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
cfb->dispsw->clear_margins(conp, display, bottom_only); while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
if (!count--) {
debug_printf("accel_wait timed out\n");
cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
break;
}
udelay(1);
}
return 0;
} }
static struct display_switch fbcon_cyber_accel = { /*
.setup = cyber2000_accel_setup, * ===========================================================================
.bmove = cyber2000_accel_bmove, */
.clear = cyber2000_accel_clear,
.putc = cyber2000_accel_putc,
.putcs = cyber2000_accel_putcs,
.revc = cyber2000_accel_revc,
.clear_margins = cyber2000_accel_clear_margins,
.fontwidthmask = FONTWIDTH(8)|FONTWIDTH(16)
};
static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf) static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf)
{ {
...@@ -324,7 +265,7 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -324,7 +265,7 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info) u_int transp, struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)info; struct cfb_info *cfb = (struct cfb_info *)info;
struct fb_var_screeninfo *var = &cfb->display->var; struct fb_var_screeninfo *var = &cfb->fb.var;
u32 pseudo_val; u32 pseudo_val;
int ret = 1; int ret = 1;
...@@ -332,7 +273,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -332,7 +273,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
default: default:
return 1; return 1;
#ifdef FBCON_HAS_CFB8
/* /*
* Pseudocolour: * Pseudocolour:
* 8 8 * 8 8
...@@ -359,7 +299,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -359,7 +299,6 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
cyber2000fb_writeb(green, 0x3c9, cfb); cyber2000fb_writeb(green, 0x3c9, cfb);
cyber2000fb_writeb(blue, 0x3c9, cfb); cyber2000fb_writeb(blue, 0x3c9, cfb);
return 0; return 0;
#endif
/* /*
* Direct colour: * Direct colour:
...@@ -455,13 +394,8 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -455,13 +394,8 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/* /*
* Now set our pseudo palette for the CFB16/24/32 drivers. * Now set our pseudo palette for the CFB16/24/32 drivers.
*/ */
if (regno < 16) { if (regno < 16)
if (var->bits_per_pixel == 16)
((u16 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
else
((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val; ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
ret = 0;
}
return ret; return ret;
} }
...@@ -800,20 +734,16 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb, ...@@ -800,20 +734,16 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
} }
/* /*
* Decode the info required for the hardware. * Set the User Defined Part of the Display
* This involves the PLL parameters for the dot clock,
* CRTC registers, and accelerator settings.
*/ */
static int static int
cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
struct par_info *hw)
{ {
struct cfb_info *cfb = (struct cfb_info *)info;
struct par_info hw;
unsigned int mem; unsigned int mem;
int err; int err;
hw->width = var->xres_virtual;
hw->ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
var->transp.msb_right = 0; var->transp.msb_right = 0;
var->red.msb_right = 0; var->red.msb_right = 0;
var->green.msb_right = 0; var->green.msb_right = 0;
...@@ -822,10 +752,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -822,10 +752,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
#ifdef FBCON_HAS_CFB8 #ifdef FBCON_HAS_CFB8
case 8: /* PSEUDOCOLOUR, 256 */ case 8: /* PSEUDOCOLOUR, 256 */
hw->co_pixfmt = CO_PIXFMT_8BPP;
hw->pitch = hw->width >> 3;
hw->extseqmisc = EXT_SEQ_MISC_8;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 0; var->red.offset = 0;
...@@ -838,13 +764,8 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -838,13 +764,8 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
#endif #endif
#ifdef FBCON_HAS_CFB16 #ifdef FBCON_HAS_CFB16
case 16:/* DIRECTCOLOUR, 64k or 32k */ case 16:/* DIRECTCOLOUR, 64k or 32k */
hw->co_pixfmt = CO_PIXFMT_16BPP;
hw->pitch = hw->width >> 2;
switch (var->green.length) { switch (var->green.length) {
case 6: /* RGB565, 64k */ case 6: /* RGB565, 64k */
hw->extseqmisc = EXT_SEQ_MISC_16_RGB565;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 11; var->red.offset = 11;
...@@ -857,8 +778,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -857,8 +778,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
default: default:
case 5: /* RGB555, 32k */ case 5: /* RGB555, 32k */
hw->extseqmisc = EXT_SEQ_MISC_16_RGB555;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 10; var->red.offset = 10;
...@@ -870,8 +789,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -870,8 +789,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
break; break;
case 4: /* RGB444, 4k + transparency? */ case 4: /* RGB444, 4k + transparency? */
hw->extseqmisc = EXT_SEQ_MISC_16_RGB444;
var->transp.offset = 12; var->transp.offset = 12;
var->transp.length = 4; var->transp.length = 4;
var->red.offset = 8; var->red.offset = 8;
...@@ -886,12 +803,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -886,12 +803,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
#endif #endif
#ifdef FBCON_HAS_CFB24 #ifdef FBCON_HAS_CFB24
case 24:/* TRUECOLOUR, 16m */ case 24:/* TRUECOLOUR, 16m */
hw->co_pixfmt = CO_PIXFMT_24BPP;
hw->width *= 3;
hw->pitch = hw->width >> 3;
hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
hw->extseqmisc = EXT_SEQ_MISC_24_RGB888;
var->transp.offset = 0; var->transp.offset = 0;
var->transp.length = 0; var->transp.length = 0;
var->red.offset = 16; var->red.offset = 16;
...@@ -904,11 +815,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -904,11 +815,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
#endif #endif
#ifdef FBCON_HAS_CFB32 #ifdef FBCON_HAS_CFB32
case 32:/* TRUECOLOUR, 16m */ case 32:/* TRUECOLOUR, 16m */
hw->co_pixfmt = CO_PIXFMT_32BPP;
hw->pitch = hw->width >> 1;
hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
hw->extseqmisc = EXT_SEQ_MISC_32;
var->transp.offset = 24; var->transp.offset = 24;
var->transp.length = 8; var->transp.length = 8;
var->red.offset = 16; var->red.offset = 16;
...@@ -933,127 +839,107 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb, ...@@ -933,127 +839,107 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
if (var->xres > var->xres_virtual) if (var->xres > var->xres_virtual)
var->xres = var->xres_virtual; var->xres = var->xres_virtual;
err = cyber2000fb_decode_clock(hw, cfb, var); err = cyber2000fb_decode_clock(&hw, cfb, var);
if (err) if (err)
return err; return err;
err = cyber2000fb_decode_crtc(hw, cfb, var); err = cyber2000fb_decode_crtc(&hw, cfb, var);
if (err) if (err)
return err; return err;
hw->width -= 1;
hw->fetch = hw->pitch;
if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
hw->fetch <<= 1;
hw->fetch += 1;
return 0; return 0;
} }
/* static int cyber2000fb_set_par(struct fb_info *info)
* Set the User Defined Part of the Display
*/
static int
cyber2000fb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)info; struct cfb_info *cfb = (struct cfb_info *)info;
struct display *display; struct fb_var_screeninfo *var = &cfb->fb.var;
struct par_info hw; struct par_info hw;
int err, chgvar; unsigned int mem;
/*
* CONUPDATE and SMOOTH_XPAN are equal. However,
* SMOOTH_XPAN is only used internally by fbcon.
*/
if (var->vmode & FB_VMODE_CONUPDATE) {
var->vmode |= FB_VMODE_YWRAP;
var->xoffset = cfb->display->var.xoffset;
var->yoffset = cfb->display->var.yoffset;
}
err = cyber2000fb_decode_var(var, cfb, &hw); hw.width = var->xres_virtual;
if (err) hw.ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
return err;
if (var->activate & FB_ACTIVATE_TEST) switch (var->bits_per_pixel) {
return 0; case 8:
hw.co_pixfmt = CO_PIXFMT_8BPP;
hw.pitch = hw.width >> 3;
hw.extseqmisc = EXT_SEQ_MISC_8;
break;
if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) case 16:
return -EINVAL; hw.co_pixfmt = CO_PIXFMT_16BPP;
hw.pitch = hw.width >> 2;
if (con < 0) { switch (var->green.length) {
display = cfb->fb.disp; case 6: /* RGB565, 64k */
} else { hw.extseqmisc = EXT_SEQ_MISC_16_RGB565;
display = fb_display + con; break;
case 5: /* RGB555, 32k */
hw.extseqmisc = EXT_SEQ_MISC_16_RGB555;
break;
case 4: /* RGB444, 4k + transparency? */
hw.extseqmisc = EXT_SEQ_MISC_16_RGB444;
break;
default:
BUG();
} }
case 24:/* TRUECOLOUR, 16m */
hw.co_pixfmt = CO_PIXFMT_24BPP;
hw.width *= 3;
hw.pitch = hw.width >> 3;
hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
hw.extseqmisc = EXT_SEQ_MISC_24_RGB888;
break;
chgvar = cfb->fb.var.xres != var->xres || case 32:/* TRUECOLOUR, 16m */
cfb->fb.var.yres != var->yres || hw.co_pixfmt = CO_PIXFMT_32BPP;
cfb->fb.var.xres_virtual != var->xres_virtual || hw.pitch = hw.width >> 1;
cfb->fb.var.yres_virtual != var->yres_virtual || hw.ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
cfb->fb.var.bits_per_pixel != var->bits_per_pixel; hw.extseqmisc = EXT_SEQ_MISC_32;
break;
if (memcmp(&cfb->fb.var.red, &var->red, sizeof(var->red)) ||
memcmp(&cfb->fb.var.green, &var->green, sizeof(var->green)) ||
memcmp(&cfb->fb.var.blue, &var->blue, sizeof(var->blue)))
chgvar = 1;
if (con >= 0 && chgvar == 0)
return 0;
if (con < 0) default:
chgvar = 0; BUG();
}
/* /*
* If we are setting all the virtual consoles, also set the * Sigh, this is absolutely disgusting, but caused by
* defaults used to create new consoles. * the way the fbcon developers want to separate out
* the "checking" and the "setting" of the video mode.
*
* If the mode is not suitable for the hardware here,
* we can't prevent it being set by returning an error.
*
* In theory, since NetWinders contain just one VGA card,
* we should never end up hitting this problem.
*/ */
err = var->activate; BUG_ON(cyber2000fb_decode_clock(&hw, cfb, var) != 0);
var->activate = FB_ACTIVATE_NOW; BUG_ON(cyber2000fb_decode_crtc(&hw, cfb, var) != 0);
if (err & FB_ACTIVATE_ALL)
cfb->fb.disp->var = *var; hw.width -= 1;
hw.fetch = hw.pitch;
if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
hw.fetch <<= 1;
hw.fetch += 1;
cfb->fb.var = *var;
cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
switch (var->bits_per_pixel) { /*
#ifdef FBCON_HAS_CFB8 * Same here - if the size of the video mode exceeds the
case 8: /* PSEUDOCOLOUR, 256 */ * available RAM, we can't prevent this mode being set.
cfb->dispsw = &fbcon_cfb8; *
display->dispsw_data = NULL; * In theory, since NetWinders contain just one VGA card,
break; * we should never end up hitting this problem.
#endif */
#ifdef FBCON_HAS_CFB16 mem = cfb->fb.fix.line_length * var->yres_virtual;
case 16:/* DIRECTCOLOUR */ BUG_ON(mem > cfb->fb.fix.smem_len);
cfb->dispsw = &fbcon_cfb16;
display->dispsw_data = cfb->fb.pseudo_palette;
break;
#endif
#ifdef FBCON_HAS_CFB24
case 24:/* TRUECOLOUR, 16m */
cfb->dispsw = &fbcon_cfb24;
display->dispsw_data = cfb->fb.pseudo_palette;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:/* TRUECOLOUR, 16m */
cfb->dispsw = &fbcon_cfb32;
display->dispsw_data = cfb->fb.pseudo_palette;
break;
#endif
default:/* in theory this should never happen */
printk(KERN_WARNING "%s: no support for %dbpp\n",
cfb->fb.fix.id, var->bits_per_pixel);
cfb->dispsw = &fbcon_dummy;
break;
}
/* /*
* 8bpp displays are always pseudo colour. * 8bpp displays are always pseudo colour. 16bpp and above
* 16bpp and above are direct colour or true colour, depending * are direct colour or true colour, depending on whether
* on whether the RAMDAC palettes are bypassed. (Direct colour * the RAMDAC palettes are bypassed. (Direct colour has
* has palettes, true colour does not.) * palettes, true colour does not.)
*/ */
if (var->bits_per_pixel == 8) if (var->bits_per_pixel == 8)
cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
...@@ -1062,20 +948,8 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -1062,20 +948,8 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con,
else else
cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR; cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
if (var->accel_flags & FB_ACCELF_TEXT && cfb->dispsw != &fbcon_dummy)
display->dispsw = &fbcon_cyber_accel;
else
display->dispsw = cfb->dispsw;
display->can_soft_blank = 1;
display->inverse = 0;
cyber2000fb_set_timing(cfb, &hw); cyber2000fb_set_timing(cfb, &hw);
cyber2000fb_update_start(cfb, var); cyber2000fb_update_start(cfb, var);
fb_set_cmap(&cfb->fb.cmap, 1, &cfb->fb);
if (chgvar && cfb->fb.changevar)
cfb->fb.changevar(con);
return 0; return 0;
} }
...@@ -1085,85 +959,22 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -1085,85 +959,22 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con,
* Pan or Wrap the Display * Pan or Wrap the Display
*/ */
static int static int
cyber2000fb_pan_display(struct fb_var_screeninfo *var, int con, cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
struct fb_info *info)
{ {
struct cfb_info *cfb = (struct cfb_info *)info; struct cfb_info *cfb = (struct cfb_info *)info;
u_int y_bottom;
y_bottom = var->yoffset;
if (!(var->vmode & FB_VMODE_YWRAP))
y_bottom += var->yres;
if (var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
if (y_bottom > cfb->display->var.yres_virtual)
return -EINVAL;
if (cyber2000fb_update_start(cfb, var)) if (cyber2000fb_update_start(cfb, var))
return -EINVAL; return -EINVAL;
cfb->display->var.xoffset = var->xoffset; cfb->fb.var.xoffset = var->xoffset;
cfb->display->var.yoffset = var->yoffset; cfb->fb.var.yoffset = var->yoffset;
if (var->vmode & FB_VMODE_YWRAP) { if (var->vmode & FB_VMODE_YWRAP) {
cfb->display->var.vmode |= FB_VMODE_YWRAP; cfb->fb.var.vmode |= FB_VMODE_YWRAP;
} else { } else {
cfb->display->var.vmode &= ~FB_VMODE_YWRAP; cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
}
return 0;
}
/*
* Update the `var' structure (called by fbcon.c)
*
* This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
* Since it's called by a kernel driver, no range checking is done.
*/
static int cyber2000fb_updatevar(int con, struct fb_info *info)
{
struct cfb_info *cfb = (struct cfb_info *)info;
return cyber2000fb_update_start(cfb, &fb_display[con].var);
}
static int cyber2000fb_switch(int con, struct fb_info *info)
{
struct cfb_info *cfb = (struct cfb_info *)info;
struct display *display = cfb->display;
struct fb_cmap *cmap;
if (display) {
/*
* Save the old colormap and video mode.
*/
if (display->cmap.len)
fb_copy_cmap(&cfb->fb.cmap, &display->cmap, 0);
} }
cfb->display = display = fb_display + con;
/*
* Install the new colormap and change the video mode. By default,
* fbcon sets all the colormaps and video modes to the default
* values at bootup.
*
* Really, we want to set the colourmap size depending on the
* depth of the new video mode. For now, we leave it at its
* default 256 entry.
*/
if (display->cmap.len)
cmap = &display->cmap;
else
cmap = fb_default_cmap(1 << display->var.bits_per_pixel);
fb_copy_cmap(cmap, &cfb->fb.cmap, 0);
display->var.activate = FB_ACTIVATE_NOW;
cyber2000fb_set_var(&display->var, con, &cfb->fb);
return 0; return 0;
} }
...@@ -1243,12 +1054,16 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) ...@@ -1243,12 +1054,16 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
static struct fb_ops cyber2000fb_ops = { static struct fb_ops cyber2000fb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_set_var = cyber2000fb_set_var, .fb_check_var = cyber2000fb_check_var,
.fb_get_cmap = gen_get_cmap, .fb_set_par = cyber2000fb_set_par,
.fb_set_cmap = gen_set_cmap,
.fb_setcolreg = cyber2000fb_setcolreg, .fb_setcolreg = cyber2000fb_setcolreg,
.fb_pan_display = cyber2000fb_pan_display,
.fb_blank = cyber2000fb_blank, .fb_blank = cyber2000fb_blank,
.fb_pan_display = cyber2000fb_pan_display,
.fb_fillrect = cyber2000fb_fillrect,
.fb_copyarea = cyber2000fb_copyarea,
.fb_imageblit = cyber2000fb_imageblit,
.fb_cursor = soft_cursor,
.fb_sync = cyber2000fb_sync,
}; };
/* /*
...@@ -1295,7 +1110,7 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb) ...@@ -1295,7 +1110,7 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb)
void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var) void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
{ {
memcpy(var, &cfb->display->var, sizeof(struct fb_var_screeninfo)); memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
} }
/* /*
...@@ -1313,8 +1128,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx) ...@@ -1313,8 +1128,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
info->info = int_cfb_info; info->info = int_cfb_info;
strncpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name)); strncpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name));
MOD_INC_USE_COUNT;
} }
return int_cfb_info != NULL; return int_cfb_info != NULL;
...@@ -1325,7 +1138,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx) ...@@ -1325,7 +1138,6 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
*/ */
void cyber2000fb_detach(int idx) void cyber2000fb_detach(int idx)
{ {
MOD_DEC_USE_COUNT;
} }
EXPORT_SYMBOL(cyber2000fb_attach); EXPORT_SYMBOL(cyber2000fb_attach);
...@@ -1411,13 +1223,13 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) ...@@ -1411,13 +1223,13 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
{ {
struct cfb_info *cfb; struct cfb_info *cfb;
cfb = kmalloc(sizeof(struct cfb_info) + sizeof(struct display) + cfb = kmalloc(sizeof(struct cfb_info) +
sizeof(u32) * 16, GFP_KERNEL); sizeof(u32) * 16, GFP_KERNEL);
if (!cfb) if (!cfb)
return NULL; return NULL;
memset(cfb, 0, sizeof(struct cfb_info) + sizeof(struct display)); memset(cfb, 0, sizeof(struct cfb_info));
cfb->id = id; cfb->id = id;
...@@ -1467,17 +1279,10 @@ cyberpro_alloc_fb_info(unsigned int id, char *name) ...@@ -1467,17 +1279,10 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
cfb->fb.var.width = -1; cfb->fb.var.width = -1;
cfb->fb.var.accel_flags = FB_ACCELF_TEXT; cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
strcpy(cfb->fb.modename, cfb->fb.fix.id);
strcpy(cfb->fb.fontname, default_font);
cfb->fb.fbops = &cyber2000fb_ops; cfb->fb.fbops = &cyber2000fb_ops;
cfb->fb.changevar = NULL;
cfb->fb.switch_con = cyber2000fb_switch;
cfb->fb.updatevar = cyber2000fb_updatevar;
cfb->fb.flags = FBINFO_FLAG_DEFAULT; cfb->fb.flags = FBINFO_FLAG_DEFAULT;
cfb->fb.node = NODEV; cfb->fb.node = NODEV;
cfb->fb.disp = (struct display *)(cfb + 1); cfb->fb.pseudo_palette = (void *)(cfb + 1);
cfb->fb.pseudo_palette = (void *)(cfb->fb.disp + 1);
fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0); fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
...@@ -1575,7 +1380,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) ...@@ -1575,7 +1380,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
if (cfb->fb.var.yres_virtual < cfb->fb.var.yres) if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
cfb->fb.var.yres_virtual = cfb->fb.var.yres; cfb->fb.var.yres_virtual = cfb->fb.var.yres;
cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb); // fb_set_var(&cfb->fb.var, -1, &cfb->fb);
/* /*
* Calculate the hsync and vsync frequencies. Note that * Calculate the hsync and vsync frequencies. Note that
...@@ -1614,8 +1419,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb) ...@@ -1614,8 +1419,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
* Restore the old video mode and the palette. * Restore the old video mode and the palette.
* We also need to tell fbcon to redraw the console. * We also need to tell fbcon to redraw the console.
*/ */
cfb->fb.var.activate = FB_ACTIVATE_NOW; cyber2000fb_set_par(&cfb->fb);
cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb);
} }
#ifdef CONFIG_ARCH_SHARK #ifdef CONFIG_ARCH_SHARK
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment