diff options
Diffstat (limited to 'drivers/video/retz3fb.c')
-rw-r--r-- | drivers/video/retz3fb.c | 567 |
1 files changed, 298 insertions, 269 deletions
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c index 18a410614..82dcc2877 100644 --- a/drivers/video/retz3fb.c +++ b/drivers/video/retz3fb.c @@ -21,6 +21,7 @@ */ +#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -39,6 +40,10 @@ #include <asm/pgtable.h> #include "retz3fb.h" +#include "fbcon.h" +#include "fbcon-cfb8.h" +#include "fbcon-cfb16.h" + /* #define DEBUG if(1) */ #define DEBUG if(0) @@ -54,7 +59,7 @@ #define arraysize(x) (sizeof(x)/sizeof(*(x))) -struct retz3_fb_par { +struct retz3fb_par { int xres; int yres; int xres_vir; @@ -93,7 +98,7 @@ struct display_data { long v_dispend; /* Horizontal Display End */ }; -static struct retz3_fb_par current_par; +static struct retz3fb_par current_par; static int current_par_valid = 0; static int currcon = 0; @@ -114,13 +119,15 @@ static struct fb_hwswitch { /* Display Control */ - int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3_fb_par *par); - int (*decode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); - int (*encode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par); + int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3fb_par *par); + int (*decode_var)(struct fb_var_screeninfo *var, struct retz3fb_par *par); + int (*encode_var)(struct fb_var_screeninfo *var, struct retz3fb_par *par); int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned - int *green, unsigned int *blue, unsigned int *transp); + int *green, unsigned int *blue, unsigned int *transp, + struct fb_info *info); int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int - green, unsigned int blue, unsigned int transp); + green, unsigned int blue, unsigned int transp, + struct fb_info *info); void (*blank)(int blank); } *fbhw; @@ -129,7 +136,7 @@ static struct fb_hwswitch { * Frame Buffer Name */ -static char retz3_fb_name[16] = "RetinaZ3"; +static char retz3fb_name[16] = "RetinaZ3"; static unsigned char retz3_color_table [256][4]; @@ -140,46 +147,6 @@ static volatile unsigned char *z3_regs; /* - * Predefined Video Mode Names - */ - -static char *retz3_fb_modenames[] = { - - /* - * Autodetect (Default) Video Mode - */ - - "default", - - /* - * Predefined Video Modes - */ - - "640x480", /* RetinaZ3 8 bpp */ - "800x600", /* RetinaZ3 8 bpp */ - "1024x768i", - "640x480-16", /* RetinaZ3 16 bpp */ - "640x480-24", /* RetinaZ3 24 bpp */ - - /* - * Dummy Video Modes - */ - - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - - /* - * User Defined Video Modes - * - * This doesn't work yet!! - */ - - "user0", "user1", "user2", "user3", - "user4", "user5", "user6", "user7" -}; - -/* * A small info on how to convert XFree86 timing values into fb * timings - by Frank Neumann: * @@ -217,131 +184,124 @@ under "programs/Xserver/hw/xfree86/doc/modeDB.txt". */ /* - * Predefined Video Mode Definitions + * Predefined Video Modes */ -static struct fb_var_screeninfo retz3_fb_predefined[] = { - - /* - * Autodetect (Default) Video Mode - */ - - { 0, }, - - /* - * Predefined Video Modes - */ - - /* - * NB: it is very important to adjust the pixel-clock to the color-depth. - */ - - { - 640, 480, 640, 480, 0, 0, 8, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - /* - ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 - < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL - */ - { - /* 800 x 600, 8 bpp */ - 800, 600, 800, 600, 0, 0, 8, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2, - FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - /* - ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace - < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL - */ - { - /* 1024 x 768, 8 bpp, interlaced */ - 1024, 768, 1024, 768, 0, 0, 8, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8, - FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED - }, - { - 640, 480, 640, 480, 0, 0, 16, 0, - {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - 640, 480, 640, 480, 0, 0, 24, 0, - {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, - 0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2, - FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - - /* - * Dummy Video Modes - */ - - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, - { 0, }, { 0, }, - - /* - * User Defined Video Modes - */ - - { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, } +static struct fb_videomode retz3fb_predefined[] __initdata = { + /* + * NB: it is very important to adjust the pixel-clock to the color-depth. + */ + + { + "640x480", { /* 640x480, 8 bpp */ + 640, 480, 640, 480, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 38461, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + } + }, + /* + ModeLine "800x600" 36 800 824 896 1024 600 601 603 625 + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + "800x600", { /* 800x600, 8 bpp */ + 800, 600, 800, 600, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 27778, 64, 24, 22, 1, 120, 2, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + } + }, + /* + ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace + < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL + */ + { + "1024x768i", { /* 1024x768, 8 bpp, interlaced */ + 1024, 768, 1024, 768, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 22222, 40, 40, 32, 9, 160, 8, + FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED + } + }, { + "640x480-16", { /* 640x480, 16 bpp */ + 640, 480, 640, 480, 0, 0, 16, 0, + {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 38461/2, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + } + }, { + "640x480-24", { /* 640x480, 24 bpp */ + 640, 480, 640, 480, 0, 0, 24, 0, + {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, + 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 38461/3, 28, 32, 12, 10, 96, 2, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + } + }, }; -#define NUM_TOTAL_MODES arraysize(retz3_fb_predefined) -#define NUM_PREDEF_MODES 5 +#define NUM_TOTAL_MODES arraysize(retz3fb_predefined) +static struct fb_var_screeninfo retz3fb_default; static int z3fb_inverse = 0; -static int z3fb_mode = 0; +static int z3fb_mode __initdata = 0; /* * Interface used by the world */ -void retz3_video_setup(char *options, int *ints); - -static int retz3_fb_open(int fbidx); -static int retz3_fb_release(int fbidx); -static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con); -static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con); -static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con); -static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con); -static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con); -static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con); -static int retz3_fb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, int con); +void retz3fb_setup(char *options, int *ints); + +static int retz3fb_open(struct fb_info *info); +static int retz3fb_release(struct fb_info *info); +static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, + struct fb_info *info); +static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, + struct fb_info *info); +static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, + struct fb_info *info); +static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, + struct fb_info *info); +static int retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, + struct fb_info *info); +static int retz3fb_pan_display(struct fb_var_screeninfo *var, int con, + struct fb_info *info); +static int retz3fb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, int con, + struct fb_info *info); /* * Interface to the low level console driver */ -unsigned long retz3_fb_init(unsigned long mem_start); -static int z3fb_switch(int con); -static int z3fb_updatevar(int con); -static void z3fb_blank(int blank); -static int z3fb_setcmap(struct fb_cmap *cmap, int con); +unsigned long retz3fb_init(unsigned long mem_start); +static int z3fb_switch(int con, struct fb_info *info); +static int z3fb_updatevar(int con, struct fb_info *info); +static void z3fb_blank(int blank, struct fb_info *info); + + +/* + * Text console acceleration + */ + +#ifdef CONFIG_FBCON_CFB8 +static struct display_switch fbcon_retz3_8; +#endif /* * Accelerated Functions used by the low level console driver */ -void retz3_bitblt(struct fb_var_screeninfo *scr, - unsigned short curx, unsigned short cury, unsigned - short destx, unsigned short desty, unsigned short - width, unsigned short height, unsigned short cmd, - unsigned short mask); -void retz3_fill(unsigned short x, unsigned short y, unsigned short - width, unsigned short height, unsigned short mode, - unsigned short color); +static void retz3_bitblt(struct fb_var_screeninfo *scr, + unsigned short curx, unsigned short cury, unsigned + short destx, unsigned short desty, unsigned short + width, unsigned short height, unsigned short cmd, + unsigned short mask); /* * Hardware Specific Routines @@ -349,17 +309,17 @@ void retz3_fill(unsigned short x, unsigned short y, unsigned short static int retz3_init(void); static int retz3_encode_fix(struct fb_fix_screeninfo *fix, - struct retz3_fb_par *par); + struct retz3fb_par *par); static int retz3_decode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par); + struct retz3fb_par *par); static int retz3_encode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par); + struct retz3fb_par *par); static int retz3_getcolreg(unsigned int regno, unsigned int *red, unsigned int *green, unsigned int *blue, - unsigned int *transp); + unsigned int *transp, struct fb_info *info); static int retz3_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, - unsigned int transp); + unsigned int transp, struct fb_info *info); static void retz3_blank(int blank); @@ -367,13 +327,11 @@ static void retz3_blank(int blank); * Internal routines */ -static void retz3_fb_get_par(struct retz3_fb_par *par); -static void retz3_fb_set_par(struct retz3_fb_par *par); +static void retz3fb_get_par(struct retz3fb_par *par); +static void retz3fb_set_par(struct retz3fb_par *par); static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive); -static void do_install_cmap(int con); -/* -static void retz3_fb_set_disp(int con); -*/ +static void do_install_cmap(int con, struct fb_info *info); +static void retz3fb_set_disp(int con, struct fb_info *info); static int get_video_mode(const char *name); @@ -397,7 +355,7 @@ static unsigned short find_fq(unsigned int freq) else if (freq <= 250000000) n2 = 0; else - return(0); + return 0; do { @@ -424,10 +382,12 @@ static unsigned short find_fq(unsigned int freq) static int retz3_set_video(struct fb_var_screeninfo *var, - struct retz3_fb_par *par) + struct retz3fb_par *par) { +#if 0 float freq_f; - long freq; +#endif + unsigned int freq; int xres, hfront, hsync, hback; int yres, vfront, vsync, vback; @@ -478,7 +438,7 @@ static int retz3_set_video(struct fb_var_screeninfo *var, vback = var->upper_margin; } - data.h_total = (hback / 8) + (xres / 8) + data.h_total = (hback / 8) + (xres / 8) + (hfront / 8) + (hsync / 8) - 1 /* + 1 */; data.h_dispend = ((xres + bpp - 1)/ 8) - 1; data.h_bstart = xres / 8 /* + 1 */; @@ -736,8 +696,13 @@ static int retz3_set_video(struct fb_var_screeninfo *var, /* * Convert from ps to Hz. */ +#if 0 freq_f = (1.0/(float)var->pixclock) * 1000000000; - freq = ((long)freq_f) * 1000; + freq = ((unsigned int)freq_f) * 1000; +#else + freq = 2000000000 / var->pixclock; + freq = freq * 500; +#endif best_freq = find_fq(freq); pll_w(0x02, best_freq); @@ -791,7 +756,7 @@ static int retz3_set_video(struct fb_var_screeninfo *var, */ switch (bpp){ case 8: - reg_w(0x83c6, 0x00); + reg_w(0x83c6, 0x00); break; case 16: reg_w(0x83c6, 0x60); @@ -805,7 +770,7 @@ static int retz3_set_video(struct fb_var_screeninfo *var, reg_w(VDAC_ADDRESS, 0x00); - seq_w(SEQ_MAP_MASK, 0x0f ); + seq_w(SEQ_MAP_MASK, 0x0f ); return 0; } @@ -854,8 +819,8 @@ static int retz3_init(void) } #endif - retz3_setcolreg (255, 56, 100, 160, 0); - retz3_setcolreg (254, 0, 0, 0, 0); + retz3_setcolreg (255, 56, 100, 160, 0, NULL /* unused */); + retz3_setcolreg (254, 0, 0, 0, 0, NULL /* unused */); return 0; } @@ -867,11 +832,11 @@ static int retz3_init(void) */ static int retz3_encode_fix(struct fb_fix_screeninfo *fix, - struct retz3_fb_par *par) + struct retz3fb_par *par) { short i; - strcpy(fix->id, retz3_fb_name); + strcpy(fix->id, retz3fb_name); fix->smem_start = (char *)z3_fbmem; fix->smem_len = z3_size; fix->mmio_start = (unsigned char *)z3_regs; @@ -889,6 +854,8 @@ static int retz3_encode_fix(struct fb_fix_screeninfo *fix, fix->ywrapstep = 0; fix->line_length = 0; + fix->accel = FB_ACCEL_NCR77C32BLT; + for (i = 0; i < arraysize(fix->reserved); i++) fix->reserved[i] = 0; @@ -902,7 +869,7 @@ static int retz3_encode_fix(struct fb_fix_screeninfo *fix, */ static int retz3_decode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par) + struct retz3fb_par *par) { par->xres = var->xres; par->yres = var->yres; @@ -934,7 +901,7 @@ static int retz3_decode_var(struct fb_var_screeninfo *var, */ static int retz3_encode_var(struct fb_var_screeninfo *var, - struct retz3_fb_par *par) + struct retz3fb_par *par) { short i; @@ -959,7 +926,7 @@ static int retz3_encode_var(struct fb_var_screeninfo *var, var->height = -1; var->width = -1; - var->accel = FB_ACCEL_RETINAZ3; + var->accel = FB_ACCEL_NCR77C32BLT; var->pixclock = par->pixclock; @@ -987,7 +954,7 @@ static int retz3_encode_var(struct fb_var_screeninfo *var, static int retz3_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, - unsigned int transp) + unsigned int transp, struct fb_info *info) { /* We'll get to this */ @@ -1015,7 +982,7 @@ static int retz3_setcolreg(unsigned int regno, unsigned int red, static int retz3_getcolreg(unsigned int regno, unsigned int *red, unsigned int *green, unsigned int *blue, - unsigned int *transp) + unsigned int *transp, struct fb_info *info) { if (regno > 255) return 1; @@ -1052,11 +1019,11 @@ void retz3_blank(int blank) } -void retz3_bitblt (struct fb_var_screeninfo *var, - unsigned short srcx, unsigned short srcy, unsigned - short destx, unsigned short desty, unsigned short - width, unsigned short height, unsigned short cmd, - unsigned short mask) +static void retz3_bitblt (struct fb_var_screeninfo *var, + unsigned short srcx, unsigned short srcy, + unsigned short destx, unsigned short desty, + unsigned short width, unsigned short height, + unsigned short cmd, unsigned short mask) { volatile unsigned long *acm = (unsigned long *) (z3_mem + ACM_OFFSET); @@ -1129,7 +1096,7 @@ void retz3_bitblt (struct fb_var_screeninfo *var, *(acm + ACM_CONTROL/4) = tmp; tmp = width | (height << 16); - + *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp); *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; @@ -1154,20 +1121,10 @@ void retz3_bitblt (struct fb_var_screeninfo *var, } #if 0 -void retz3_fill (unsigned short x, unsigned short y, unsigned - short width, unsigned short height, - unsigned short mode, unsigned short color) -{ - -} -#endif - - -#if 0 /* * Move cursor to x, y */ -void retz3_MoveCursor (unsigned short x, unsigned short y) +static void retz3_MoveCursor (unsigned short x, unsigned short y) { /* Guess we gotta deal with the cursor at some point */ } @@ -1189,16 +1146,16 @@ static struct fb_hwswitch retz3_switch = { * Fill the hardware's `par' structure. */ -static void retz3_fb_get_par(struct retz3_fb_par *par) +static void retz3fb_get_par(struct retz3fb_par *par) { if (current_par_valid) *par = current_par; else - fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], par); + fbhw->decode_var(&retz3fb_default, par); } -static void retz3_fb_set_par(struct retz3_fb_par *par) +static void retz3fb_set_par(struct retz3fb_par *par) { current_par = *par; current_par_valid = 1; @@ -1208,7 +1165,7 @@ static void retz3_fb_set_par(struct retz3_fb_par *par) static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) { int err, activate; - struct retz3_fb_par par; + struct retz3fb_par par; if ((err = fbhw->decode_var(var, &par))) return err; @@ -1217,7 +1174,7 @@ static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) /* XXX ... what to do about isactive ? */ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive) - retz3_fb_set_par(&par); + retz3fb_set_par(&par); fbhw->encode_var(var, &par); var->activate = activate; @@ -1227,17 +1184,17 @@ static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive) } -static void do_install_cmap(int con) +static void do_install_cmap(int con, struct fb_info *info) { if (con != currcon) return; if (fb_display[con].cmap.len) fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1, - fbhw->setcolreg); + fbhw->setcolreg, info); else - fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel), + fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), &fb_display[con].var, 1, - fbhw->setcolreg); + fbhw->setcolreg, info); } @@ -1245,7 +1202,7 @@ static void do_install_cmap(int con) * Open/Release the frame buffer device */ -static int retz3_fb_open(int fbidx) +static int retz3fb_open(struct fb_info *info) { /* * Nothing, only a usage count for the moment @@ -1255,7 +1212,7 @@ static int retz3_fb_open(int fbidx) return 0; } -static int retz3_fb_release(int fbidx) +static int retz3fb_release(struct fb_info *info) { MOD_DEC_USE_COUNT; return 0; @@ -1266,13 +1223,14 @@ static int retz3_fb_release(int fbidx) * Get the Fixed Part of the Display */ -static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con) +static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, + struct fb_info *info) { - struct retz3_fb_par par; + struct retz3fb_par par; int error = 0; if (con == -1) - retz3_fb_get_par(&par); + retz3fb_get_par(&par); else error = fbhw->decode_var(&fb_display[con].var, &par); return(error ? error : fbhw->encode_fix(fix, &par)); @@ -1283,13 +1241,14 @@ static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con) * Get the User Defined Part of the Display */ -static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con) +static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, + struct fb_info *info) { - struct retz3_fb_par par; + struct retz3fb_par par; int error = 0; if (con == -1) { - retz3_fb_get_par(&par); + retz3fb_get_par(&par); error = fbhw->encode_var(var, &par); } else *var = fb_display[con].var; @@ -1298,7 +1257,7 @@ static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con) #if 1 -static void retz3_fb_set_disp(int con) +static void retz3fb_set_disp(int con, struct fb_info *info) { struct fb_fix_screeninfo fix; struct display *display; @@ -1308,7 +1267,7 @@ static void retz3_fb_set_disp(int con) else display = &disp; /* used during initialization */ - retz3_fb_get_fix(&fix, con); + retz3fb_get_fix(&fix, con, info); if (con == -1) con = 0; @@ -1321,6 +1280,21 @@ static void retz3_fb_set_disp(int con) display->ywrapstep = fix.ywrapstep; display->can_soft_blank = 1; display->inverse = z3fb_inverse; + switch (display->var.bits_per_pixel) { +#ifdef CONFIG_FBCON_CFB8 + case 8: + display->dispsw = &fbcon_retz3_8; + break; +#endif +#ifdef CONFIG_FBCON_CFB16 + case 16: + display->dispsw = &fbcon_cfb16; + break; +#endif + default: + display->dispsw = NULL; + break; + } } #endif @@ -1328,7 +1302,8 @@ static void retz3_fb_set_disp(int con) * Set the User Defined Part of the Display */ -static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) +static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, + struct fb_info *info) { int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp; struct display *display; @@ -1359,7 +1334,7 @@ static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) oldbpp != var->bits_per_pixel) { struct fb_fix_screeninfo fix; - retz3_fb_get_fix(&fix, con); + retz3fb_get_fix(&fix, con, info); display->screen_base = fix.smem_start; display->visual = fix.visual; @@ -1370,8 +1345,23 @@ static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) display->line_length = fix.line_length; display->can_soft_blank = 1; display->inverse = z3fb_inverse; + switch (display->var.bits_per_pixel) { +#ifdef CONFIG_FBCON_CFB8 + case 8: + display->dispsw = &fbcon_retz3_8; + break; +#endif +#ifdef CONFIG_FBCON_CFB16 + case 16: + display->dispsw = &fbcon_cfb16; + break; +#endif + default: + display->dispsw = NULL; + break; + } /* - retz3_fb_set_disp(con); + retz3fb_set_disp(con, info); */ if (fb_info.changevar) (*fb_info.changevar)(con); @@ -1380,7 +1370,7 @@ static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) if (oldbpp != var->bits_per_pixel) { if ((err = fb_alloc_cmap(&display->cmap, 0, 0))) return err; - do_install_cmap(con); + do_install_cmap(con, info); } } return 0; @@ -1391,15 +1381,16 @@ static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con) * Get the Colormap */ -static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) +static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, + struct fb_info *info) { if (con == currcon) /* current console? */ return(fb_get_cmap(cmap, &fb_display[con].var, kspc, - fbhw->getcolreg)); + fbhw->getcolreg, info)); else if (fb_display[con].cmap.len) /* non default colormap? */ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); else - fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel), + fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2); return 0; } @@ -1409,7 +1400,8 @@ static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con) * Set the Colormap */ -static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) +static int retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, + struct fb_info *info) { int err; @@ -1421,7 +1413,7 @@ static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) } if (con == currcon) /* current console? */ return(fb_set_cmap(cmap, &fb_display[con].var, kspc, - fbhw->setcolreg)); + fbhw->setcolreg, info)); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; @@ -1434,7 +1426,8 @@ static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con) * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag */ -static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con) +static int retz3fb_pan_display(struct fb_var_screeninfo *var, int con, + struct fb_info *info) { return -EINVAL; } @@ -1444,21 +1437,22 @@ static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con) * RetinaZ3 Frame Buffer Specific ioctls */ -static int retz3_fb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, int con) +static int retz3fb_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, int con, + struct fb_info *info) { return -EINVAL; } -static struct fb_ops retz3_fb_ops = { - retz3_fb_open, retz3_fb_release, retz3_fb_get_fix, retz3_fb_get_var, - retz3_fb_set_var, retz3_fb_get_cmap, retz3_fb_set_cmap, - retz3_fb_pan_display, retz3_fb_ioctl +static struct fb_ops retz3fb_ops = { + retz3fb_open, retz3fb_release, retz3fb_get_fix, retz3fb_get_var, + retz3fb_set_var, retz3fb_get_cmap, retz3fb_set_cmap, + retz3fb_pan_display, NULL, retz3fb_ioctl }; -__initfunc(void retz3_video_setup(char *options, int *ints)) +__initfunc(void retz3fb_setup(char *options, int *ints)) { char *this_opt; @@ -1467,7 +1461,7 @@ __initfunc(void retz3_video_setup(char *options, int *ints)) if (!options || !*options) return; - for (this_opt = strtok(options, ","); this_opt; + for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")){ if (!strcmp(this_opt, "inverse")) { z3fb_inverse = 1; @@ -1484,14 +1478,14 @@ __initfunc(void retz3_video_setup(char *options, int *ints)) * Initialization */ -__initfunc(unsigned long retz3_fb_init(unsigned long mem_start)) +__initfunc(unsigned long retz3fb_init(unsigned long mem_start)) { int err; unsigned long board_addr, board_size; unsigned int key; const struct ConfigDev *cd; - struct retz3_fb_par par; + struct retz3fb_par par; if (!(key = zorro_find(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, 0, 0))) return mem_start; @@ -1511,43 +1505,38 @@ __initfunc(unsigned long retz3_fb_init(unsigned long mem_start)) z3_size = 0x00400000; /* 4 MB */ - memset ((char*)z3_fbmem, 0, z3_size); - fbhw = &retz3_switch; fbhw->init(); - strcpy(fb_info.modename, retz3_fb_name); + strcpy(fb_info.modename, retz3fb_name); fb_info.changevar = NULL; fb_info.node = -1; - fb_info.fbops = &retz3_fb_ops; - fb_info.fbvar_num = NUM_TOTAL_MODES; - fb_info.fbvar = retz3_fb_predefined; + fb_info.fbops = &retz3fb_ops; fb_info.disp = &disp; fb_info.switch_con = &z3fb_switch; fb_info.updatevar = &z3fb_updatevar; fb_info.blank = &z3fb_blank; - fb_info.setcmap = &z3fb_setcmap; err = register_framebuffer(&fb_info); if (err < 0) return mem_start; if (z3fb_mode == -1) - z3fb_mode = 1; + retz3fb_default = retz3fb_predefined[0].var; - fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], &par); - fbhw->encode_var(&retz3_fb_predefined[0], &par); + fbhw->decode_var(&retz3fb_default, &par); + fbhw->encode_var(&retz3fb_default, &par); - do_fb_set_var(&retz3_fb_predefined[0], 0); - retz3_fb_get_var(&disp.var, -1); + do_fb_set_var(&retz3fb_default, 0); + retz3fb_get_var(&disp.var, -1, &fb_info); - retz3_fb_set_disp(-1); + retz3fb_set_disp(-1, &fb_info); - do_install_cmap(0); + do_install_cmap(0, &fb_info); - printk("%s frame buffer device, using %ldK of video memory\n", - fb_info.modename, z3_size>>10); + printk("fb%d: %s frame buffer device, using %ldK of video memory\n", + GET_FB_IDX(fb_info.node), fb_info.modename, z3_size>>10); /* TODO: This driver cannot be unloaded yet */ MOD_INC_USE_COUNT; @@ -1556,17 +1545,18 @@ __initfunc(unsigned long retz3_fb_init(unsigned long mem_start)) } -static int z3fb_switch(int con) +static int z3fb_switch(int con, struct fb_info *info) { /* Do we have to save the colormap? */ if (fb_display[currcon].cmap.len) fb_get_cmap(&fb_display[currcon].cmap, - &fb_display[currcon].var, 1, fbhw->getcolreg); + &fb_display[currcon].var, 1, fbhw->getcolreg, + info); do_fb_set_var(&fb_display[con].var, 1); currcon = con; /* Install new colormap */ - do_install_cmap(con); + do_install_cmap(con, info); return 0; } @@ -1578,7 +1568,7 @@ static int z3fb_switch(int con) * Since it's called by a kernel driver, no range checking is done. */ -static int z3fb_updatevar(int con) +static int z3fb_updatevar(int con, struct fb_info *info) { return 0; } @@ -1588,33 +1578,23 @@ static int z3fb_updatevar(int con) * Blank the display. */ -static void z3fb_blank(int blank) +static void z3fb_blank(int blank, struct fb_info *info) { fbhw->blank(blank); } /* - * Set the colormap - */ - -static int z3fb_setcmap(struct fb_cmap *cmap, int con) -{ - return(retz3_fb_set_cmap(cmap, 1, con)); -} - - -/* * Get a Video Mode */ -static int get_video_mode(const char *name) +__initfunc(static int get_video_mode(const char *name)) { short i; - for (i = 1; i <= NUM_PREDEF_MODES; i++) - if (!strcmp(name, retz3_fb_modenames[i])){ - retz3_fb_predefined[0] = retz3_fb_predefined[i]; + for (i = 0; i <= NUM_TOTAL_MODES; i++) + if (!strcmp(name, retz3fb_predefined[i].name)){ + retz3fb_default = retz3fb_predefined[i].var; return i; } return -1; @@ -1624,7 +1604,7 @@ static int get_video_mode(const char *name) #ifdef MODULE int init_module(void) { - return(retz3_fb_init(NULL)); + return(retz3fb_init(NULL)); } void cleanup_module(void) @@ -1636,11 +1616,60 @@ void cleanup_module(void) unregister_framebuffer(&fb_info); /* TODO: clean up ... */ } -#endif /* MODULE */ +#endif /* - * Visible symbols for modules + * Text console acceleration */ -EXPORT_SYMBOL(retz3_bitblt); +#ifdef CONFIG_FBCON_CFB8 +static void fbcon_retz3_8_bmove(struct display *p, int sy, int sx, int dy, int dx, + int height, int width) +{ + int fontwidth = p->fontwidth; + + sx *= fontwidth; + dx *= fontwidth; + width *= fontwidth; + + retz3_bitblt(&p->var, + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)dx, + (unsigned short)(dy*p->fontheight), + (unsigned short)width, + (unsigned short)(height*p->fontheight), + Z3BLTcopy, + 0xffff); +} + +static void fbcon_retz3_8_clear(struct vc_data *conp, struct display *p, int + sy, int sx, int height, int width) +{ + unsigned short col; + int fontwidth = p->fontwidth; + + sx *= fontwidth; + width *= fontwidth; + + col = attr_bgcol_ec(p, conp); + col &= 0xff; + col |= (col << 8); + + retz3_bitblt(&p->var, + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)sx, + (unsigned short)(sy*p->fontheight), + (unsigned short)width, + (unsigned short)(height*p->fontheight), + Z3BLTset, + col); +} + +static struct display_switch fbcon_retz3_8 = { + fbcon_cfb8_setup, fbcon_retz3_8_bmove, fbcon_retz3_8_clear, + fbcon_cfb8_putc, fbcon_cfb8_putcs, fbcon_cfb8_revc +}; +#endif |