Commit 8574c79d authored by James Simmons's avatar James Simmons

Several fixes relating to modules. Ported over the vga16fb driver to the new api.

parent 622a411c
...@@ -50,7 +50,7 @@ obj-$(CONFIG_FB_TRIDENT) += tridentfb.o ...@@ -50,7 +50,7 @@ obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
obj-$(CONFIG_FB_S3TRIO) += S3triofb.o obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
obj-$(CONFIG_FB_TGA) += tgafb.o obj-$(CONFIG_FB_TGA) += tgafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VGA16) += vga16fb.o fbcon-vga-planes.o obj-$(CONFIG_FB_VGA16) += vga16fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VIRGE) += virgefb.o obj-$(CONFIG_FB_VIRGE) += virgefb.o
obj-$(CONFIG_FB_G364) += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_G364) += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
......
...@@ -2633,15 +2633,15 @@ void cleanup_module(void) ...@@ -2633,15 +2633,15 @@ void cleanup_module(void)
if (info->screen_base) if (info->screen_base)
iounmap((void *) info->screen_base); iounmap((void *) info->screen_base);
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
if (info->cursor && info->cursor->ram) if (par->cursor && par->cursor->ram)
iounmap(info->cursor->ram); iounmap(par->cursor->ram);
#endif #endif
#endif #endif
if (info->cursor) { if (par->cursor) {
if (info->cursor->timer) if (par->cursor->timer)
kfree(info->cursor->timer); kfree(par->cursor->timer);
kfree(info->cursor); kfree(par->cursor);
} }
#ifdef __sparc__ #ifdef __sparc__
if (par->mmap_map) if (par->mmap_map)
......
...@@ -120,13 +120,13 @@ config FBCON_ADVANCED ...@@ -120,13 +120,13 @@ config FBCON_ADVANCED
config FBCON_ACCEL config FBCON_ACCEL
tristate "Hardware acceleration support" if FBCON_ADVANCED tristate "Hardware acceleration support" if FBCON_ADVANCED
depends on FB depends on FRAMEBUFFER_CONSOLE
default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && !FB_MAC && FB_RIVA!=y && FB_HGA!=y && !FB_OF && FB_SGIVW!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m || FB_HGA=m) default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && !FB_MAC && FB_RIVA!=y && FB_HGA!=y && !FB_OF && FB_SGIVW!=y && FB_VGA16!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m || FB_HGA=m)
default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y || FB_HGA=y) default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y || FB_HGA=y || FB_VGA16)
config FBCON_AFB config FBCON_AFB
tristate "Amiga bitplanes support" if FBCON_ADVANCED tristate "Amiga bitplanes support" if FBCON_ADVANCED
depends on FB depends on FRAMEBUFFER_CONSOLE
default m if !FBCON_ADVANCED && FB_AMIGA=m default m if !FBCON_ADVANCED && FB_AMIGA=m
default y if !FBCON_ADVANCED && FB_AMIGA=y default y if !FBCON_ADVANCED && FB_AMIGA=y
help help
...@@ -135,7 +135,7 @@ config FBCON_AFB ...@@ -135,7 +135,7 @@ config FBCON_AFB
config FBCON_ILBM config FBCON_ILBM
tristate "Amiga interleaved bitplanes support" if FBCON_ADVANCED tristate "Amiga interleaved bitplanes support" if FBCON_ADVANCED
depends on FB depends on FRAMEBUFFER_CONSOLE
default m if !FBCON_ADVANCED && FB_AMIGA=m default m if !FBCON_ADVANCED && FB_AMIGA=m
default y if !FBCON_ADVANCED && FB_AMIGA=y default y if !FBCON_ADVANCED && FB_AMIGA=y
help help
...@@ -144,7 +144,7 @@ config FBCON_ILBM ...@@ -144,7 +144,7 @@ config FBCON_ILBM
config FBCON_IPLAN2P2 config FBCON_IPLAN2P2
tristate "Atari interleaved bitplanes (2 planes) support" if FBCON_ADVANCED tristate "Atari interleaved bitplanes (2 planes) support" if FBCON_ADVANCED
depends on FB depends on FRAMEBUFFER_CONSOLE
default y if !FBCON_ADVANCED && FB_ATARI default y if !FBCON_ADVANCED && FB_ATARI
help help
This is the low level frame buffer console driver for 2 interleaved This is the low level frame buffer console driver for 2 interleaved
...@@ -152,7 +152,7 @@ config FBCON_IPLAN2P2 ...@@ -152,7 +152,7 @@ config FBCON_IPLAN2P2
config FBCON_IPLAN2P4 config FBCON_IPLAN2P4
tristate "Atari interleaved bitplanes (4 planes) support" if FBCON_ADVANCED tristate "Atari interleaved bitplanes (4 planes) support" if FBCON_ADVANCED
depends on FB depends on FRAMEBUFFER_CONSOLE
default y if !FBCON_ADVANCED && FB_ATARI default y if !FBCON_ADVANCED && FB_ATARI
help help
This is the low level frame buffer console driver for 4 interleaved This is the low level frame buffer console driver for 4 interleaved
...@@ -160,7 +160,7 @@ config FBCON_IPLAN2P4 ...@@ -160,7 +160,7 @@ config FBCON_IPLAN2P4
config FBCON_IPLAN2P8 config FBCON_IPLAN2P8
tristate "Atari interleaved bitplanes (8 planes) support" if FBCON_ADVANCED tristate "Atari interleaved bitplanes (8 planes) support" if FBCON_ADVANCED
depends on FB depends on FRAMEBUFFER_CONSOLE
default y if !FBCON_ADVANCED && FB_ATARI default y if !FBCON_ADVANCED && FB_ATARI
help help
This is the low level frame buffer console driver for 8 interleaved This is the low level frame buffer console driver for 8 interleaved
...@@ -169,7 +169,7 @@ config FBCON_IPLAN2P8 ...@@ -169,7 +169,7 @@ config FBCON_IPLAN2P8
# Guess what we need # Guess what we need
config FBCON_STI config FBCON_STI
tristate tristate
depends on !FBCON_ADVANCED && FB_STI depends on !FBCON_ADVANCED && FRAMEBUFFER_CONSOLE && FB_STI
default y default y
config FBCON_FONTWIDTH8_ONLY config FBCON_FONTWIDTH8_ONLY
......
...@@ -844,8 +844,8 @@ vgacon_do_font_op(char *arg, int set, int ch512) ...@@ -844,8 +844,8 @@ vgacon_do_font_op(char *arg, int set, int ch512)
static int static int
vgacon_adjust_height(unsigned fontheight) vgacon_adjust_height(unsigned fontheight)
{ {
int rows, maxscan;
unsigned char ovr, vde, fsr; unsigned char ovr, vde, fsr;
int rows, maxscan, i;
if (fontheight == vga_video_font_height) if (fontheight == vga_video_font_height)
return 0; return 0;
......
...@@ -771,8 +771,8 @@ static devfs_handle_t devfs_handle; ...@@ -771,8 +771,8 @@ static devfs_handle_t devfs_handle;
int int
register_framebuffer(struct fb_info *fb_info) register_framebuffer(struct fb_info *fb_info)
{ {
static int fb_ever_opened[FB_MAX];
#ifdef CONFIG_FRAMEBUFFER_CONSOLE #ifdef CONFIG_FRAMEBUFFER_CONSOLE
static int fb_ever_opened[FB_MAX];
static int first = 1; static int first = 1;
int j; int j;
#endif #endif
...@@ -788,9 +788,9 @@ register_framebuffer(struct fb_info *fb_info) ...@@ -788,9 +788,9 @@ register_framebuffer(struct fb_info *fb_info)
fb_info->node = mk_kdev(FB_MAJOR, i); fb_info->node = mk_kdev(FB_MAJOR, i);
fb_info->currcon = -1; fb_info->currcon = -1;
registered_fb[i] = fb_info; registered_fb[i] = fb_info;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
if (!fb_ever_opened[i]) { if (!fb_ever_opened[i]) {
struct module *owner = fb_info->fbops->owner; struct module *owner = fb_info->fbops->owner;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
/* /*
* We assume initial frame buffer devices can be opened this * We assume initial frame buffer devices can be opened this
* many times * many times
...@@ -813,14 +813,6 @@ register_framebuffer(struct fb_info *fb_info) ...@@ -813,14 +813,6 @@ register_framebuffer(struct fb_info *fb_info)
first = 0; first = 0;
take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
} }
#else
if (owner) {
__MOD_INC_USE_COUNT(owner);
if (fb_info->fbops->fb_open && fb_info->fbops->fb_open(fb_info,0))
__MOD_DEC_USE_COUNT(owner);
}
fb_ever_opened[i] = 1;
}
#endif #endif
sprintf (name_buf, "%d", i); sprintf (name_buf, "%d", i);
fb_info->devfs_handle = fb_info->devfs_handle =
......
...@@ -22,19 +22,16 @@ ...@@ -22,19 +22,16 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
#include <video/fbcon.h>
#include "fbcon-accel.h"
#include "vga.h" #include "vga.h"
#define GRAPHICS_ADDR_REG 0x3ce /* Graphics address register. */ #define GRAPHICS_ADDR_REG VGA_GFX_I /* Graphics address register. */
#define GRAPHICS_DATA_REG 0x3cf /* Graphics data register. */ #define GRAPHICS_DATA_REG VGA_GFX_D /* Graphics data register. */
#define SET_RESET_INDEX 0 /* Set/Reset Register index. */ #define SET_RESET_INDEX VGA_GFX_SR_VALUE /* Set/Reset Register index. */
#define ENABLE_SET_RESET_INDEX 1 /* Enable Set/Reset Register index. */ #define ENABLE_SET_RESET_INDEX VGA_GFX_SR_ENABLE /* Enable Set/Reset Register index. */
#define DATA_ROTATE_INDEX 3 /* Data Rotate Register index. */ #define DATA_ROTATE_INDEX VGA_GFX_DATA_ROTATE /* Data Rotate Register index. */
#define GRAPHICS_MODE_INDEX 5 /* Graphics Mode Register index. */ #define GRAPHICS_MODE_INDEX VGA_GFX_MODE /* Graphics Mode Register index. */
#define BIT_MASK_INDEX 8 /* Bit Mask Register index. */ #define BIT_MASK_INDEX VGA_GFX_BIT_MASK /* Bit Mask Register index. */
#define dac_reg (VGA_PEL_IW) #define dac_reg (VGA_PEL_IW)
#define dac_val (VGA_PEL_D) #define dac_val (VGA_PEL_D)
...@@ -42,6 +39,11 @@ ...@@ -42,6 +39,11 @@
#define VGA_FB_PHYS 0xA0000 #define VGA_FB_PHYS 0xA0000
#define VGA_FB_PHYS_LEN 65536 #define VGA_FB_PHYS_LEN 65536
#define MODE_SKIP4 1
#define MODE_8BPP 2
#define MODE_CFB 4
#define MODE_TEXT 8
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* /*
...@@ -80,7 +82,7 @@ static struct fb_var_screeninfo vga16fb_defined = { ...@@ -80,7 +82,7 @@ static struct fb_var_screeninfo vga16fb_defined = {
.xres_virtual = 640, .xres_virtual = 640,
.yres_virtual = 480, .yres_virtual = 480,
.bits_per_pixel = 4, .bits_per_pixel = 4,
.activate = FB_ACTIVATE_NOW, .activate = FB_ACTIVATE_TEST,
.height = -1, .height = -1,
.width = -1, .width = -1,
.pixclock = 39721, .pixclock = 39721,
...@@ -107,8 +109,6 @@ static struct fb_fix_screeninfo vga16fb_fix __initdata = { ...@@ -107,8 +109,6 @@ static struct fb_fix_screeninfo vga16fb_fix __initdata = {
.accel = FB_ACCEL_NONE .accel = FB_ACCEL_NONE
}; };
static struct display disp;
/* The VGA's weird architecture often requires that we read a byte and /* The VGA's weird architecture often requires that we read a byte and
write a byte to the same location. It doesn't matter *what* byte write a byte to the same location. It doesn't matter *what* byte
we write, however. This is because all the action goes on behind we write, however. This is because all the action goes on behind
...@@ -126,70 +126,90 @@ static inline void rmw(volatile char *p) ...@@ -126,70 +126,90 @@ static inline void rmw(volatile char *p)
writeb(1, p); writeb(1, p);
} }
/* Set the Graphics Mode Register. Bits 0-1 are write mode, bit 3 is /* Set the Graphics Mode Register, and return its previous value.
read mode. */ Bits 0-1 are write mode, bit 3 is read mode. */
static inline void setmode(int mode) static inline int setmode(int mode)
{ {
outb(GRAPHICS_MODE_INDEX, GRAPHICS_ADDR_REG); int oldmode;
outb(mode, GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_ADDR_REG, GRAPHICS_MODE_INDEX);
oldmode = vga_io_r(GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_DATA_REG, mode);
return oldmode;
} }
/* Select the Bit Mask Register. */ /* Select the Bit Mask Register and return its value. */
static inline void selectmask(void) static inline int selectmask(void)
{ {
outb(BIT_MASK_INDEX, GRAPHICS_ADDR_REG); return vga_io_rgfx(BIT_MASK_INDEX);
} }
/* Set the value of the Bit Mask Register. It must already have been /* Set the value of the Bit Mask Register. It must already have been
selected with selectmask(). */ selected with selectmask(). */
static inline void setmask(int mask) static inline void setmask(int mask)
{ {
outb(mask, GRAPHICS_DATA_REG); vga_io_w(GRAPHICS_DATA_REG, mask);
} }
/* Set the Data Rotate Register. Bits 0-2 are rotate count, bits 3-4 /* Set the Data Rotate Register and return its old value.
are logical operation (0=NOP, 1=AND, 2=OR, 3=XOR). */ Bits 0-2 are rotate count, bits 3-4 are logical operation
static inline void setop(int op) (0=NOP, 1=AND, 2=OR, 3=XOR). */
static inline int setop(int op)
{ {
outb(DATA_ROTATE_INDEX, GRAPHICS_ADDR_REG); int oldop;
outb(op, GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_ADDR_REG, DATA_ROTATE_INDEX);
oldop = vga_io_r(GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_DATA_REG, op);
return oldop;
} }
/* Set the Enable Set/Reset Register. The code here always uses value /* Set the Enable Set/Reset Register and return its old value.
0xf for this register. */ The code here always uses value 0xf for thsi register. */
static inline void setsr(int sr) static inline int setsr(int sr)
{ {
outb(ENABLE_SET_RESET_INDEX, GRAPHICS_ADDR_REG); int oldsr;
outb(sr, GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_ADDR_REG, ENABLE_SET_RESET_INDEX);
oldsr = vga_io_r(GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_DATA_REG, sr);
return oldsr;
} }
/* Set the Set/Reset Register. */ /* Set the Set/Reset Register and return its old value. */
static inline void setcolor(int color) static inline int setcolor(int color)
{ {
outb(SET_RESET_INDEX, GRAPHICS_ADDR_REG); int oldcolor;
outb(color, GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_ADDR_REG, SET_RESET_INDEX);
oldcolor = vga_io_r(GRAPHICS_DATA_REG);
vga_io_w(GRAPHICS_DATA_REG, color);
return oldcolor;
}
/* Return the value in the Graphics Address Register. */
static inline int getindex(void)
{
return vga_io_r(GRAPHICS_ADDR_REG);
} }
/* Set the value in the Graphics Address Register. */ /* Set the value in the Graphics Address Register. */
static inline void setindex(int index) static inline void setindex(int index)
{ {
outb(index, GRAPHICS_ADDR_REG); vga_io_w(GRAPHICS_ADDR_REG, index);
} }
static void vga16fb_pan_var(struct fb_info *info, static void vga16fb_pan_var(struct fb_info *info,
struct fb_var_screeninfo *var) struct fb_var_screeninfo *var)
{ {
struct display *p; struct vga16fb_par *par = (struct vga16fb_par *) info->par;
u32 xoffset, pos; u32 xoffset, pos;
p = (info->currcon < 0) ? info->disp : fb_display + info->currcon;
xoffset = var->xoffset; xoffset = var->xoffset;
if (info->var.bits_per_pixel == 8) { if (info->var.bits_per_pixel == 8) {
pos = (info->var.xres_virtual * var->yoffset + xoffset) >> 2; pos = (info->var.xres_virtual * var->yoffset + xoffset) >> 2;
} else if (info->var.bits_per_pixel == 0) { } else if (par->mode & MODE_TEXT) {
int fh = fontheight(p); int fh = 16; // FIXME !!! font height. Fugde for now.
if (!fh) fh = 16;
pos = (info->var.xres_virtual * (var->yoffset / fh) + xoffset) >> 3; pos = (info->var.xres_virtual * (var->yoffset / fh) + xoffset) >> 3;
} else { } else {
if (info->var.nonstd) if (info->var.nonstd)
...@@ -198,8 +218,8 @@ static void vga16fb_pan_var(struct fb_info *info, ...@@ -198,8 +218,8 @@ static void vga16fb_pan_var(struct fb_info *info,
} }
vga_io_wcrt(VGA_CRTC_START_HI, pos >> 8); vga_io_wcrt(VGA_CRTC_START_HI, pos >> 8);
vga_io_wcrt(VGA_CRTC_START_LO, pos & 0xFF); vga_io_wcrt(VGA_CRTC_START_LO, pos & 0xFF);
/* if we support CFB4, then we must! support xoffset with pixel granularity */ /* if we support CFB4, then we must! support xoffset with pixel
/* if someone supports xoffset in bit resolution */ * granularity if someone supports xoffset in bit resolution */
vga_io_r(VGA_IS1_RC); /* reset flip-flop */ vga_io_r(VGA_IS1_RC); /* reset flip-flop */
vga_io_w(VGA_ATT_IW, VGA_ATC_PEL); vga_io_w(VGA_ATT_IW, VGA_ATC_PEL);
if (var->bits_per_pixel == 8) if (var->bits_per_pixel == 8)
...@@ -210,12 +230,6 @@ static void vga16fb_pan_var(struct fb_info *info, ...@@ -210,12 +230,6 @@ static void vga16fb_pan_var(struct fb_info *info,
vga_io_w(VGA_ATT_IW, 0x20); vga_io_w(VGA_ATT_IW, 0x20);
} }
static int vga16fb_update_var(int con, struct fb_info *info)
{
vga16fb_pan_var(info, &info->var);
return 0;
}
static void vga16fb_update_fix(struct fb_info *info) static void vga16fb_update_fix(struct fb_info *info)
{ {
if (info->var.bits_per_pixel == 4) { if (info->var.bits_per_pixel == 4) {
...@@ -243,47 +257,6 @@ static void vga16fb_update_fix(struct fb_info *info) ...@@ -243,47 +257,6 @@ static void vga16fb_update_fix(struct fb_info *info)
} }
} }
static void vga16fb_set_disp(int con, struct fb_info *info)
{
struct display *display;
display = (con < 0) ? info->disp : fb_display + con;
if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR ||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
display->can_soft_blank = info->fbops->fb_blank ? 1 : 0;
display->dispsw_data = NULL;
} else {
display->can_soft_blank = 0;
display->dispsw_data = info->pseudo_palette;
}
display->var = info->var;
vga16fb_update_fix(info);
display->next_line = info->fix.line_length;
display->can_soft_blank = 1;
display->inverse = 0;
switch (info->fix.type) {
case FB_TYPE_VGA_PLANES:
if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
display->dispsw = &fbcon_accel;
} else
#ifdef FBCON_HAS_VGA_PLANES
display->dispsw = &fbcon_vga8_planes;
#endif
break;
#ifdef FBCON_HAS_VGA
case FB_TYPE_TEXT:
display->dispsw = &fbcon_vga;
break;
#endif
default: /* only FB_TYPE_PACKED_PIXELS */
display->dispsw = &fbcon_accel;
break;
}
}
static void vga16fb_clock_chip(struct vga16fb_par *par, static void vga16fb_clock_chip(struct vga16fb_par *par,
unsigned int pixclock, unsigned int pixclock,
const struct fb_info *info, const struct fb_info *info,
...@@ -322,10 +295,6 @@ static void vga16fb_clock_chip(struct vga16fb_par *par, ...@@ -322,10 +295,6 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
#define FAIL(X) return -EINVAL #define FAIL(X) return -EINVAL
#define MODE_SKIP4 1
#define MODE_8BPP 2
#define MODE_CFB 4
#define MODE_TEXT 8
static int vga16fb_check_var(struct fb_var_screeninfo *var, static int vga16fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info) struct fb_info *info)
{ {
...@@ -548,10 +517,13 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var, ...@@ -548,10 +517,13 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var,
} }
#undef FAIL #undef FAIL
static void vga16fb_load_font(struct display* p) { #ifdef FBCON_HAS_VGA
static void vga16fb_load_font(struct display* p)
{
int chars; int chars;
unsigned char* font; unsigned char* font;
unsigned char* dest; unsigned char* dest;
int chars;
if (!p || !p->fontdata) if (!p || !p->fontdata)
return; return;
...@@ -579,11 +551,11 @@ static void vga16fb_load_font(struct display* p) { ...@@ -579,11 +551,11 @@ static void vga16fb_load_font(struct display* p) {
vga_io_wgfx(VGA_GFX_MODE, 0x10); vga_io_wgfx(VGA_GFX_MODE, 0x10);
vga_io_wgfx(VGA_GFX_MISC, 0x06); vga_io_wgfx(VGA_GFX_MISC, 0x06);
} }
#endif
static int vga16fb_set_par(struct fb_info *info) static int vga16fb_set_par(struct fb_info *info)
{ {
struct vga16fb_par *par = (struct vga16fb_par *) info->par; struct vga16fb_par *par = (struct vga16fb_par *) info->par;
struct display *p = (info->currcon < 0) ? info->disp : (fb_display + info->currcon);
u8 gdc[VGA_GFX_C]; u8 gdc[VGA_GFX_C];
u8 seq[VGA_SEQ_C]; u8 seq[VGA_SEQ_C];
u8 atc[VGA_ATT_C]; u8 atc[VGA_ATT_C];
...@@ -637,9 +609,7 @@ static int vga16fb_set_par(struct fb_info *info) ...@@ -637,9 +609,7 @@ static int vga16fb_set_par(struct fb_info *info)
atc[VGA_ATC_COLOR_PAGE] = 0x00; atc[VGA_ATC_COLOR_PAGE] = 0x00;
if (par->mode & MODE_TEXT) { if (par->mode & MODE_TEXT) {
fh = fontheight(p); fh = 16; // FIXME !!! Fudge font height.
if (!fh)
fh = 16;
par->crtc[VGA_CRTC_MAX_SCAN] = (par->crtc[VGA_CRTC_MAX_SCAN] par->crtc[VGA_CRTC_MAX_SCAN] = (par->crtc[VGA_CRTC_MAX_SCAN]
& ~0x1F) | (fh - 1); & ~0x1F) | (fh - 1);
} }
...@@ -689,9 +659,10 @@ static int vga16fb_set_par(struct fb_info *info) ...@@ -689,9 +659,10 @@ static int vga16fb_set_par(struct fb_info *info)
vga_io_wattr(i, atc[i]); vga_io_wattr(i, atc[i]);
} }
#ifdef FBCON_HAS_VGA
if (par->mode & MODE_TEXT) if (par->mode & MODE_TEXT)
vga16fb_load_font(p); vga16fb_load_font(p);
#endif
/* Wait for screen to stabilize. */ /* Wait for screen to stabilize. */
mdelay(50); mdelay(50);
...@@ -699,47 +670,8 @@ static int vga16fb_set_par(struct fb_info *info) ...@@ -699,47 +670,8 @@ static int vga16fb_set_par(struct fb_info *info)
vga_io_r(VGA_IS1_RC); vga_io_r(VGA_IS1_RC);
vga_io_w(VGA_ATT_IW, 0x20); vga_io_w(VGA_ATT_IW, 0x20);
return 0;
}
static int vga16fb_set_var(struct fb_var_screeninfo *var, int con, vga16fb_update_fix(info);
struct fb_info *info)
{
struct display *display;
int err;
if (con < 0)
display = info->disp;
else
display = fb_display + con;
if ((err = vga16fb_check_var(var, info)) != 0)
return err;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
u32 oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldnonstd;
oldxres = info->var.xres;
oldyres = info->var.yres;
oldvxres = info->var.xres_virtual;
oldvyres = info->var.yres_virtual;
oldbpp = info->var.bits_per_pixel;
oldnonstd = info->var.nonstd;
info->var = *var;
if (con == info->currcon)
vga16fb_set_par(info);
vga16fb_set_disp(con, info);
if (oldxres != var->xres ||
oldyres != var->yres ||
oldvxres != var->xres_virtual ||
oldvyres != var->yres_virtual ||
oldbpp != var->bits_per_pixel ||
oldnonstd != var->nonstd) {
if (info->changevar)
info->changevar(con);
}
}
return 0; return 0;
} }
...@@ -782,10 +714,8 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -782,10 +714,8 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (regno >= 256) if (regno >= 256)
return 1; return 1;
if (info->currcon < 0) gray = info->var.grayscale;
gray = info->disp->var.grayscale;
else
gray = fb_display[info->currcon].var.grayscale;
if (gray) { if (gray) {
/* gray = 0.30*R + 0.59*G + 0.11*B */ /* gray = 0.30*R + 0.59*G + 0.11*B */
red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
...@@ -797,14 +727,15 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, ...@@ -797,14 +727,15 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0; return 0;
} }
static int vga16fb_pan_display(struct fb_var_screeninfo *var, int con, static int vga16fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info) struct fb_info *info)
{ {
if (var->xoffset + info->var.xres > info->var.xres_virtual || if (var->xoffset + info->var.xres > info->var.xres_virtual ||
var->yoffset + info->var.yres > info->var.yres_virtual) var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL; return -EINVAL;
if (con == info->currcon)
vga16fb_pan_var(info, var); vga16fb_pan_var(info, var);
info->var.xoffset = var->xoffset; info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset; info->var.yoffset = var->yoffset;
info->var.vmode &= ~FB_VMODE_YWRAP; info->var.vmode &= ~FB_VMODE_YWRAP;
...@@ -968,6 +899,59 @@ static int vga16fb_blank(int blank, struct fb_info *info) ...@@ -968,6 +899,59 @@ static int vga16fb_blank(int blank, struct fb_info *info)
return 0; return 0;
} }
void vga_8planes_fillrect(struct fb_info *info, struct fb_fillrect *rect)
{
char oldindex = getindex();
char oldmode = setmode(0x40);
char oldmask = selectmask();
int line_ofs, height;
char oldop, oldsr;
char *where;
rect->dx /= 4;
where = info->screen_base + rect->dx + rect->dy * info->fix.line_length;
if (rect->rop == ROP_COPY) {
oldop = setop(0);
oldsr = setsr(0);
rect->width /= 4;
line_ofs = info->fix.line_length - rect->width;
setmask(0xff);
height = rect->height;
while (height--) {
int x;
/* we can do memset... */
for (x = rect->width; x > 0; --x) {
writeb(rect->color, where);
where++;
}
where += line_ofs;
}
} else {
char oldcolor = setcolor(0xf);
int y;
oldop = setop(0x18);
oldsr = setsr(0xf);
setmask(0x0F);
for (y = 0; y < rect->height; y++) {
rmw(where);
rmw(where+1);
where += info->fix.line_length;
}
setcolor(oldcolor);
}
setmask(oldmask);
setsr(oldsr);
setop(oldop);
setmode(oldmode);
setindex(oldindex);
}
void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect) void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
{ {
int x, x2, y2, vxres, vyres, width, height, line_ofs; int x, x2, y2, vxres, vyres, width, height, line_ofs;
...@@ -988,6 +972,10 @@ void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect) ...@@ -988,6 +972,10 @@ void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
y2 = y2 < vyres ? y2 : vyres; y2 = y2 < vyres ? y2 : vyres;
rect->width = x2 - rect->dx; rect->width = x2 - rect->dx;
switch (info->fix.type) {
case FB_TYPE_VGA_PLANES:
if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
height = y2 - rect->dy; height = y2 - rect->dy;
width = rect->width/8; width = rect->width/8;
...@@ -1029,6 +1017,69 @@ void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect) ...@@ -1029,6 +1017,69 @@ void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
} }
break; break;
} }
} else
vga_8planes_fillrect(info, rect);
break;
#ifdef FBCON_HAS_VGA
case FB_TYPE_TEXT:
break;
#endif
case FB_TYPE_PACKED_PIXELS:
default:
cfb_fillrect(info, rect);
break;
}
}
void vga_8planes_copyarea(struct fb_info *info, struct fb_copyarea *area)
{
int height, line_ofs, x;
char oldindex = getindex();
char oldmode = setmode(0x41);
char oldop = setop(0);
char oldsr = setsr(0xf);
char *dest, *src;
height = area->height;
area->sx = area->sx / 4;
area->dx = area->dx / 4;
area->width = area->width / 4;
if (area->dy < area->sy || (area->dy == area->sy && area->dx < area->sx)) {
line_ofs = info->fix.line_length - area->width;
dest = info->screen_base + area->dx + area->dy * info->fix.line_length;
src = info->screen_base + area->sx + area->sy * info->fix.line_length;
while (height--) {
for (x = 0; x < area->width; x++) {
readb(src);
writeb(0, dest);
src++;
dest++;
}
src += line_ofs;
dest += line_ofs;
}
} else {
line_ofs = info->fix.line_length - area->width;
dest = info->screen_base + area->dx + area->width + (area->dy + height - 1) * info->fix.line_length;
src = info->screen_base + area->sx + area->width + (area->sy + height - 1) * info->fix.line_length;
while (height--) {
for (x = 0; x < area->width; x++) {
--src;
--dest;
readb(src);
writeb(0, dest);
}
src -= line_ofs;
dest -= line_ofs;
}
}
setsr(oldsr);
setop(oldop);
setmode(oldmode);
setindex(oldindex);
} }
void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area) void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
...@@ -1071,6 +1122,9 @@ void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area) ...@@ -1071,6 +1122,9 @@ void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
(area->sy + area->height) > vyres) (area->sy + area->height) > vyres)
return; return;
switch (info->fix.type) {
case FB_TYPE_VGA_PLANES:
if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
width = area->width/8; width = area->width/8;
height = area->height; height = area->height;
line_ofs = info->fix.line_length - width; line_ofs = info->fix.line_length - width;
...@@ -1106,6 +1160,66 @@ void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area) ...@@ -1106,6 +1160,66 @@ void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
dst -= line_ofs; dst -= line_ofs;
} }
} }
} else
vga_8planes_copyarea(info, area);
break;
#ifdef FBCON_HAS_VGA
case FB_TYPE_TEXT:
break;
#endif
case FB_TYPE_PACKED_PIXELS:
default:
cfb_copyarea(info, area);
break;
}
}
#ifdef __LITTLE_ENDIAN
static unsigned int transl_l[] =
{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
static unsigned int transl_h[] =
{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
#else
#ifdef __BIG_ENDIAN
static unsigned int transl_h[] =
{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
static unsigned int transl_l[] =
{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
#else
#error "Only __BIG_ENDIAN and __LITTLE_ENDIAN are supported in vga-planes"
#endif
#endif
void vga_8planes_imageblit(struct fb_info *info, struct fb_image *image)
{
char oldindex = getindex();
char oldmode = setmode(0x40);
char oldop = setop(0);
char oldsr = setsr(0);
char oldmask = selectmask();
u8 *cdat = image->data;
char *where;
int y;
image->dx /= 4;
where = info->screen_base + image->dx + image->dy * info->fix.line_length;
setmask(0xff);
writeb(image->bg_color, where);
readb(where);
selectmask();
setmask(image->fg_color ^ image->bg_color);
setmode(0x42);
setop(0x18);
for (y = 0; y < image->height; y++, where += info->fix.line_length)
writew(transl_h[cdat[y]&0xF] | transl_l[cdat[y] >> 4], where);
setmask(oldmask);
setsr(oldsr);
setop(oldop);
setmode(oldmode);
setindex(oldindex);
} }
void vga16fb_imageblit(struct fb_info *info, struct fb_image *image) void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
...@@ -1115,6 +1229,9 @@ void vga16fb_imageblit(struct fb_info *info, struct fb_image *image) ...@@ -1115,6 +1229,9 @@ void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
u8 *cdat = image->data; u8 *cdat = image->data;
int y; int y;
switch (info->fix.type) {
case FB_TYPE_VGA_PLANES:
if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
if (par->isVGA) { if (par->isVGA) {
setmode(2); setmode(2);
setop(0); setop(0);
...@@ -1151,15 +1268,24 @@ void vga16fb_imageblit(struct fb_info *info, struct fb_image *image) ...@@ -1151,15 +1268,24 @@ void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
rmw(where); rmw(where);
} }
} }
} else
vga_8planes_imageblit(info, image);
break;
#ifdef FBCON_HAS_VGA
case FB_TYPE_TEXT:
break;
#endif
case FB_TYPE_PACKED_PIXELS:
default:
cfb_imageblit(info, image);
break;
}
} }
static struct fb_ops vga16fb_ops = { static struct fb_ops vga16fb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_set_var = vga16fb_set_var,
.fb_check_var = vga16fb_check_var, .fb_check_var = vga16fb_check_var,
.fb_set_par = vga16fb_set_par, .fb_set_par = vga16fb_set_par,
.fb_get_cmap = gen_get_cmap,
.fb_set_cmap = gen_set_cmap,
.fb_setcolreg = vga16fb_setcolreg, .fb_setcolreg = vga16fb_setcolreg,
.fb_pan_display = vga16fb_pan_display, .fb_pan_display = vga16fb_pan_display,
.fb_blank = vga16fb_blank, .fb_blank = vga16fb_blank,
...@@ -1172,16 +1298,11 @@ int vga16fb_setup(char *options) ...@@ -1172,16 +1298,11 @@ int vga16fb_setup(char *options)
{ {
char *this_opt; char *this_opt;
vga16fb.fontname[0] = '\0';
if (!options || !*options) if (!options || !*options)
return 0; return 0;
while ((this_opt = strsep(&options, ",")) != NULL) { while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt) continue; if (!*this_opt) continue;
if (!strncmp(this_opt, "font:", 5))
strcpy(vga16fb.fontname, this_opt+5);
} }
return 0; return 0;
} }
...@@ -1192,7 +1313,7 @@ int __init vga16fb_init(void) ...@@ -1192,7 +1313,7 @@ int __init vga16fb_init(void)
printk(KERN_DEBUG "vga16fb: initializing\n"); printk(KERN_DEBUG "vga16fb: initializing\n");
/* XXX share VGA_FB_PHYS region with vgacon */ /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
vga16fb.screen_base = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN); vga16fb.screen_base = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
if (!vga16fb.screen_base) { if (!vga16fb.screen_base) {
...@@ -1211,24 +1332,16 @@ int __init vga16fb_init(void) ...@@ -1211,24 +1332,16 @@ int __init vga16fb_init(void)
vga16fb_defined.green.length = i; vga16fb_defined.green.length = i;
vga16fb_defined.blue.length = i; vga16fb_defined.blue.length = i;
/* XXX share VGA I/O region with vgacon and others */
disp.var = vga16fb_defined;
/* name should not depend on EGA/VGA */ /* name should not depend on EGA/VGA */
strcpy(vga16fb.modename, "VGA16 VGA");
vga16fb.changevar = NULL;
vga16fb.node = NODEV; vga16fb.node = NODEV;
vga16fb.fbops = &vga16fb_ops; vga16fb.fbops = &vga16fb_ops;
vga16fb.var = vga16fb_defined; vga16fb.var = vga16fb_defined;
vga16fb.fix = vga16fb_fix; vga16fb.fix = vga16fb_fix;
vga16fb.par = &vga16_par; vga16fb.par = &vga16_par;
vga16fb.disp = &disp; vga16fb.flags = FBINFO_FLAG_DEFAULT;
vga16fb.currcon = -1;
vga16fb.switch_con = gen_switch; i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
vga16fb.updatevar=&vga16fb_update_var; fb_alloc_cmap(&vga16fb.cmap, i, 0);
vga16fb.flags=FBINFO_FLAG_DEFAULT;
vga16fb_set_disp(-1, &vga16fb);
if (register_framebuffer(&vga16fb) < 0) { if (register_framebuffer(&vga16fb) < 0) {
iounmap(vga16fb.screen_base); iounmap(vga16fb.screen_base);
...@@ -1236,7 +1349,7 @@ int __init vga16fb_init(void) ...@@ -1236,7 +1349,7 @@ int __init vga16fb_init(void)
} }
printk(KERN_INFO "fb%d: %s frame buffer device\n", printk(KERN_INFO "fb%d: %s frame buffer device\n",
minor(vga16fb.node), vga16fb.modename); minor(vga16fb.node), vga16fb.fix.id);
return 0; return 0;
} }
......
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