Commit 8ccb8c60 authored by James Simmons's avatar James Simmons

Removed fbcon-vga.c and the old fbgen code. Ported over the SgiVW,...

Removed fbcon-vga.c and the old fbgen code. Ported over the SgiVW, OpenFirmware fbdev driver and started the Mach64 fbdev driver to the new api. A few simple typos as well.
parent 8f1c76f6
...@@ -720,8 +720,3 @@ CONFIG_FBCON_HGA ...@@ -720,8 +720,3 @@ CONFIG_FBCON_HGA
This is the low level frame buffer console driver for Hercules mono This is the low level frame buffer console driver for Hercules mono
graphics cards. graphics cards.
CONFIG_FBCON_VGA
This is the low level frame buffer console driver for VGA text mode;
it is used by frame buffer device drivers that support VGA text
mode.
...@@ -228,7 +228,6 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -228,7 +228,6 @@ if [ "$CONFIG_FB" = "y" ]; then
tristate ' Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8 tristate ' Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
# tristate ' Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16 # tristate ' Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16
tristate ' VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES tristate ' VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES
tristate ' VGA characters/attributes support' CONFIG_FBCON_VGA
tristate ' HGA monochrome support (EXPERIMENTAL)' CONFIG_FBCON_HGA tristate ' HGA monochrome support (EXPERIMENTAL)' CONFIG_FBCON_HGA
else else
# Guess what we need # Guess what we need
...@@ -256,7 +255,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -256,7 +255,7 @@ if [ "$CONFIG_FB" = "y" ]; then
fi fi
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \ if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
"$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \ "$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PM3" = "y" -o \ "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
...@@ -265,13 +264,12 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -265,13 +264,12 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \ "$CONFIG_FB_P9100" = "y" ]; then
"$CONFIG_FB_SGIVW" = "y" ]; then
define_tristate CONFIG_FBCON_CFB8 y define_tristate CONFIG_FBCON_CFB8 y
else else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
"$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \ "$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PM3" = "m" -o \ "$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
...@@ -280,8 +278,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -280,8 +278,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ "$CONFIG_FB_P9100" = "m" ]; then
"$CONFIG_FB_SGIVW" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m define_tristate CONFIG_FBCON_CFB8 m
fi fi
fi fi
...@@ -293,8 +290,8 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -293,8 +290,8 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_PM3" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then "$CONFIG_FB_PM3" = "y" ]; then
define_tristate CONFIG_FBCON_CFB16 y define_tristate CONFIG_FBCON_CFB16 y
else else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
...@@ -305,8 +302,8 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -305,8 +302,8 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \ "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_CYBER2000" = "y" ]; then "$CONFIG_FB_SIS" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m define_tristate CONFIG_FBCON_CFB16 m
fi fi
fi fi
...@@ -333,8 +330,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -333,8 +330,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "y" -o \ "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_RADEON" = "y" ]; then
"$CONFIG_FB_RADEON" = "y" ]; then
define_tristate CONFIG_FBCON_CFB32 y define_tristate CONFIG_FBCON_CFB32 y
else else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
...@@ -343,8 +339,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -343,8 +339,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \ "$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
"$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ "$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_RADEON" = "m" ]; then
"$CONFIG_FB_SGIVW" = "m" ]; then
define_tristate CONFIG_FBCON_CFB32 m define_tristate CONFIG_FBCON_CFB32 m
fi fi
fi fi
...@@ -357,13 +352,15 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -357,13 +352,15 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \ "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
"$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \ "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
"$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ "$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
"$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_SGIVW" = "y" ]; then
define_tristate CONFIG_FBCON_ACCEL y define_tristate CONFIG_FBCON_ACCEL y
else else
if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \ if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
"$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ "$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
"$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \ "$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" ]; then "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" ]; then
define_tristate CONFIG_FBCON_ACCEL m define_tristate CONFIG_FBCON_ACCEL m
fi fi
fi fi
......
...@@ -56,7 +56,7 @@ obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbi ...@@ -56,7 +56,7 @@ obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbi
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
obj-$(CONFIG_FB_SGIVW) += sgivwfb.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o obj-$(CONFIG_FB_3DFX) += tdfxfb.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
obj-$(CONFIG_FB_HP300) += hpfb.o cfbfillrect.o cfbimgblt.o obj-$(CONFIG_FB_HP300) += hpfb.o cfbfillrect.o cfbimgblt.o
...@@ -115,7 +115,6 @@ obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o ...@@ -115,7 +115,6 @@ obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o
obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o
obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o
obj-$(CONFIG_FBCON_VGA) += fbcon-vga.o
obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
obj-$(CONFIG_FBCON_STI) += fbcon-sti.o obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
......
/* /*
* ATI Frame Buffer Device Driver Core Definitions * ATI Frame Buffer Device Driver Core Definitions
*/ */
...@@ -89,19 +88,14 @@ struct aty_cursor { ...@@ -89,19 +88,14 @@ struct aty_cursor {
struct fb_info_aty { struct fb_info_aty {
struct fb_info fb_info; struct fb_info fb_info;
struct fb_info_aty *next; struct fb_info_aty *next;
unsigned long ati_regbase_phys;
unsigned long ati_regbase; unsigned long ati_regbase;
unsigned long frame_buffer_phys;
unsigned long frame_buffer;
unsigned long clk_wr_offset; unsigned long clk_wr_offset;
struct pci_mmap_map *mmap_map; struct pci_mmap_map *mmap_map;
struct aty_cursor *cursor; struct aty_cursor *cursor;
struct aty_cmap_regs *aty_cmap_regs; struct aty_cmap_regs *aty_cmap_regs;
struct { u8 red, green, blue, pad; } palette[256];
struct atyfb_par default_par; struct atyfb_par default_par;
struct atyfb_par current_par; struct atyfb_par current_par;
u32 features; u32 features;
u32 total_vram;
u32 ref_clk_per; u32 ref_clk_per;
u32 pll_per; u32 pll_per;
u32 mclk_per; u32 mclk_per;
...@@ -110,19 +104,7 @@ struct fb_info_aty { ...@@ -110,19 +104,7 @@ struct fb_info_aty {
u8 mem_refresh_rate; u8 mem_refresh_rate;
const struct aty_dac_ops *dac_ops; const struct aty_dac_ops *dac_ops;
const struct aty_pll_ops *pll_ops; const struct aty_pll_ops *pll_ops;
struct display disp;
struct display_switch dispsw; struct display_switch dispsw;
union {
#ifdef FBCON_HAS_CFB16
u16 cfb16[16];
#endif
#ifdef FBCON_HAS_CFB24
u32 cfb24[16];
#endif
#ifdef FBCON_HAS_CFB32
u32 cfb32[16];
#endif
} fbcon_cmap;
u8 blitter_may_be_busy; u8 blitter_may_be_busy;
#ifdef __sparc__ #ifdef __sparc__
u8 mmaped; u8 mmaped;
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
#include <video/fbcon-cfb24.h> #include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h> #include <video/fbcon-cfb32.h>
#include "mach64.h" #include <video/mach64.h>
#include "atyfb.h" #include "atyfb.h"
#ifdef __powerpc__ #ifdef __powerpc__
...@@ -133,6 +133,15 @@ struct pci_mmap_map { ...@@ -133,6 +133,15 @@ struct pci_mmap_map {
unsigned long prot_mask; unsigned long prot_mask;
}; };
static struct fb_fix_screeninfo atyfb_fix __initdata = {
id: "ATY Mach64",
type: FB_TYPE_PACKED_PIXELS,
visual: FB_VISUAL_PSEUDOCOLOR,
xpanstep: 1,
ypanstep: 1,
ywrapstep: 1,
accel: FB_ACCEL_NONE,
};
/* /*
* Frame buffer device API * Frame buffer device API
...@@ -151,10 +160,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -151,10 +160,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
static int atyfb_pan_display(struct fb_var_screeninfo *var, int con, static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *fb); struct fb_info *fb);
static int atyfb_blank(int blank, struct fb_info *fb); static int atyfb_blank(int blank, struct fb_info *fb);
static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, int con, struct fb_info *info); u_long arg, int con, struct fb_info *info);
#ifdef __sparc__ #ifdef __sparc__
...@@ -168,7 +173,6 @@ static int atyfb_rasterimg(struct fb_info *info, int start); ...@@ -168,7 +173,6 @@ static int atyfb_rasterimg(struct fb_info *info, int start);
* Interface to the low level console driver * Interface to the low level console driver
*/ */
static int atyfbcon_switch(int con, struct fb_info *fb);
static int atyfbcon_updatevar(int con, struct fb_info *fb); static int atyfbcon_updatevar(int con, struct fb_info *fb);
/* /*
...@@ -203,8 +207,6 @@ static int encode_fix(struct fb_fix_screeninfo *fix, ...@@ -203,8 +207,6 @@ static int encode_fix(struct fb_fix_screeninfo *fix,
const struct fb_info_aty *info); const struct fb_info_aty *info);
static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info, static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
int bpp, int accel); int bpp, int accel);
static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *fb);
#ifdef CONFIG_PPC #ifdef CONFIG_PPC
static int read_aty_sense(const struct fb_info_aty *info); static int read_aty_sense(const struct fb_info_aty *info);
#endif #endif
...@@ -226,8 +228,8 @@ static struct fb_ops atyfb_ops = { ...@@ -226,8 +228,8 @@ static struct fb_ops atyfb_ops = {
fb_get_fix: atyfb_get_fix, fb_get_fix: atyfb_get_fix,
fb_get_var: atyfb_get_var, fb_get_var: atyfb_get_var,
fb_set_var: atyfb_set_var, fb_set_var: atyfb_set_var,
fb_get_cmap: atyfb_get_cmap, fb_get_cmap: gen_get_cmap,
fb_set_cmap: atyfb_set_cmap, fb_set_cmap: gen_set_cmap,
fb_setcolreg: atyfb_setcolreg, fb_setcolreg: atyfb_setcolreg,
fb_pan_display: atyfb_pan_display, fb_pan_display: atyfb_pan_display,
fb_blank: atyfb_blank, fb_blank: atyfb_blank,
...@@ -362,6 +364,8 @@ static char ram_wram[] __initdata = "WRAM"; ...@@ -362,6 +364,8 @@ static char ram_wram[] __initdata = "WRAM";
static char ram_off[] __initdata = "OFF"; static char ram_off[] __initdata = "OFF";
static char ram_resv[] __initdata = "RESV"; static char ram_resv[] __initdata = "RESV";
static u32 pseudo_palette[17];
#ifdef CONFIG_FB_ATY_GX #ifdef CONFIG_FB_ATY_GX
static char *aty_gx_ram[8] __initdata = { static char *aty_gx_ram[8] __initdata = {
ram_dram, ram_vram, ram_vram, ram_dram, ram_dram, ram_vram, ram_vram, ram_dram,
...@@ -552,7 +556,7 @@ static int aty_var_to_crtc(const struct fb_info_aty *info, ...@@ -552,7 +556,7 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
} else } else
FAIL("invalid bpp"); FAIL("invalid bpp");
if (vxres*vyres*bpp/8 > info->total_vram) if (vxres*vyres*bpp/8 > info->fb_info.fix.smem_len)
FAIL("not enough video RAM"); FAIL("not enough video RAM");
if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
...@@ -796,7 +800,7 @@ static void atyfb_set_par(const struct atyfb_par *par, ...@@ -796,7 +800,7 @@ static void atyfb_set_par(const struct atyfb_par *par,
aty_init_engine(par, info); aty_init_engine(par, info);
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
btext_update_display(info->frame_buffer_phys, btext_update_display(info->fb_info.fix.smem_start,
(((par->crtc.h_tot_disp>>16) & 0xff)+1)*8, (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8,
((par->crtc.v_tot_disp>>16) & 0x7ff)+1, ((par->crtc.v_tot_disp>>16) & 0x7ff)+1,
par->crtc.bpp, par->crtc.bpp,
...@@ -922,7 +926,7 @@ static int atyfb_release(struct fb_info *info, int user) ...@@ -922,7 +926,7 @@ static int atyfb_release(struct fb_info *info, int user)
else else
var.accel_flags |= FB_ACCELF_TEXT; var.accel_flags |= FB_ACCELF_TEXT;
if (var.yres == var.yres_virtual) { if (var.yres == var.yres_virtual) {
u32 vram = (fb->total_vram - (PAGE_SIZE << 2)); u32 vram = (fb->fb_info.fix.smem_len - (PAGE_SIZE << 2));
var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.yres_virtual = ((vram * 8) / var.bits_per_pixel) /
var.xres_virtual; var.xres_virtual;
if (var.yres_virtual < var.yres) if (var.yres_virtual < var.yres)
...@@ -946,30 +950,11 @@ static int encode_fix(struct fb_fix_screeninfo *fix, ...@@ -946,30 +950,11 @@ static int encode_fix(struct fb_fix_screeninfo *fix,
memset(fix, 0, sizeof(struct fb_fix_screeninfo)); memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, atyfb_name); strcpy(fix->id, atyfb_name);
fix->smem_start = info->frame_buffer_phys; fix->smem_start = info->fb_info.fix.smem_start;
fix->smem_len = (u32)info->total_vram; fix->smem_len = info->fb_info.fix.smem_len;
fix->mmio_start = info->fb_info.fix.mmio_start;
/* fix->mmio_len = info->fb_info.fix.mmio_len;
* Reg Block 0 (CT-compatible block) is at ati_regbase_phys fix->accel = info->fb_info.fix.accel;
* Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400
*/
if (M64_HAS(GX)) {
fix->mmio_start = info->ati_regbase_phys;
fix->mmio_len = 0x400;
fix->accel = FB_ACCEL_ATI_MACH64GX;
} else if (M64_HAS(CT)) {
fix->mmio_start = info->ati_regbase_phys;
fix->mmio_len = 0x400;
fix->accel = FB_ACCEL_ATI_MACH64CT;
} else if (M64_HAS(VT)) {
fix->mmio_start = info->ati_regbase_phys-0x400;
fix->mmio_len = 0x800;
fix->accel = FB_ACCEL_ATI_MACH64VT;
} else /* if (M64_HAS(GT)) */ {
fix->mmio_start = info->ati_regbase_phys-0x400;
fix->mmio_len = 0x800;
fix->accel = FB_ACCEL_ATI_MACH64GT;
}
fix->type = FB_TYPE_PACKED_PIXELS; fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0; fix->type_aux = 0;
fix->line_length = par->crtc.vxres*par->crtc.bpp/8; fix->line_length = par->crtc.vxres*par->crtc.bpp/8;
...@@ -1033,21 +1018,21 @@ static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info, ...@@ -1033,21 +1018,21 @@ static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
case 16: case 16:
info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16; info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;
disp->dispsw = &info->dispsw; disp->dispsw = &info->dispsw;
disp->dispsw_data = info->fbcon_cmap.cfb16; disp->dispsw_data = info->fb_info.pseudo_palette;
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB24 #ifdef FBCON_HAS_CFB24
case 24: case 24:
info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24; info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;
disp->dispsw = &info->dispsw; disp->dispsw = &info->dispsw;
disp->dispsw_data = info->fbcon_cmap.cfb24; disp->dispsw_data = info->fb_info.pseudo_palette;
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB32 #ifdef FBCON_HAS_CFB32
case 32: case 32:
info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32; info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;
disp->dispsw = &info->dispsw; disp->dispsw = &info->dispsw;
disp->dispsw_data = info->fbcon_cmap.cfb32; disp->dispsw_data = info->fb_info.pseudo_palette;
break; break;
#endif #endif
default: default:
...@@ -1100,7 +1085,6 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -1100,7 +1085,6 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_fix_screeninfo fix; struct fb_fix_screeninfo fix;
encode_fix(&fix, &par, info); encode_fix(&fix, &par, info);
fb->screen_base = (char *)info->frame_buffer;
display->visual = fix.visual; display->visual = fix.visual;
display->type = fix.type; display->type = fix.type;
display->type_aux = fix.type_aux; display->type_aux = fix.type_aux;
...@@ -1157,51 +1141,6 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, int con, ...@@ -1157,51 +1141,6 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
return 0; return 0;
} }
/*
* Get the Colormap
*/
static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
return fb_get_cmap(cmap, kspc, atyfb_getcolreg, info);
else if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
else {
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
}
return 0;
}
/*
* Set the Colormap
*/
static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
int err;
struct display *disp;
if (con >= 0)
disp = &fb_display[con];
else
disp = info->disp;
if (!disp->cmap.len) { /* no colormap allocated? */
int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
return err;
}
if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
return fb_set_cmap(cmap, kspc, info);
else
fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
return 0;
}
#ifdef DEBUG #ifdef DEBUG
#define ATYIO_CLKR 0x41545900 /* ATY\00 */ #define ATYIO_CLKR 0x41545900 /* ATY\00 */
#define ATYIO_CLKW 0x41545901 /* ATY\01 */ #define ATYIO_CLKW 0x41545901 /* ATY\01 */
...@@ -1248,7 +1187,7 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, ...@@ -1248,7 +1187,7 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
fbtyp.fb_height = info->current_par.crtc.vyres; fbtyp.fb_height = info->current_par.crtc.vyres;
fbtyp.fb_depth = info->current_par.crtc.bpp; fbtyp.fb_depth = info->current_par.crtc.bpp;
fbtyp.fb_cmsize = disp->cmap.len; fbtyp.fb_cmsize = disp->cmap.len;
fbtyp.fb_size = info->total_vram; fbtyp.fb_size = info->fb_info.fix.smem_len;
if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp))) if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp)))
return -EFAULT; return -EFAULT;
break; break;
...@@ -1344,8 +1283,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file, ...@@ -1344,8 +1283,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
/* To stop the swapper from even considering these pages. */ /* To stop the swapper from even considering these pages. */
vma->vm_flags |= (VM_SHM | VM_LOCKED); vma->vm_flags |= (VM_SHM | VM_LOCKED);
if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) || if (((vma->vm_pgoff == 0) && (size == fb->fb_info.fix.smem_len)) ||
((off == fb->total_vram) && (size == PAGE_SIZE))) ((off == fb->fb_info.fix.smem_len) && (size == PAGE_SIZE)))
off += 0x8000000000000000UL; off += 0x8000000000000000UL;
vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */ vma->vm_pgoff = off >> PAGE_SHIFT; /* propagate off changes */
...@@ -1630,7 +1569,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) ...@@ -1630,7 +1569,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
/* Backup fb content */ /* Backup fb content */
if (info->save_framebuffer) if (info->save_framebuffer)
memcpy_fromio(info->save_framebuffer, memcpy_fromio(info->save_framebuffer,
(void *)info->frame_buffer, nb); (void *)info->fb_info.screen_base, nb);
/* Blank display and LCD */ /* Blank display and LCD */
atyfb_blank(VESA_POWERDOWN+1, (struct fb_info *)info); atyfb_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
...@@ -1644,7 +1583,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when) ...@@ -1644,7 +1583,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
/* Restore fb content */ /* Restore fb content */
if (info->save_framebuffer) { if (info->save_framebuffer) {
memcpy_toio((void *)info->frame_buffer, memcpy_toio((void *)info->fb_info.screen_base,
info->save_framebuffer, nb); info->save_framebuffer, nb);
vfree(info->save_framebuffer); vfree(info->save_framebuffer);
info->save_framebuffer = 0; info->save_framebuffer = 0;
...@@ -1715,15 +1654,13 @@ static struct fb_info_aty *fb_list = NULL; ...@@ -1715,15 +1654,13 @@ static struct fb_info_aty *fb_list = NULL;
static int __init aty_init(struct fb_info_aty *info, const char *name) static int __init aty_init(struct fb_info_aty *info, const char *name)
{ {
u32 chip_id; u32 chip_id, i;
u32 i;
int j, k;
struct fb_var_screeninfo var; struct fb_var_screeninfo var;
struct display *disp; struct display *disp;
u16 type; u16 type;
u8 rev; u8 rev;
const char *chipname = NULL, *ramname = NULL, *xtal; const char *chipname = NULL, *ramname = NULL, *xtal;
int pll, mclk, gtb_memsize; int j, pll, mclk, gtb_memsize;
#if defined(CONFIG_PPC) #if defined(CONFIG_PPC)
int sense; int sense;
#endif #endif
...@@ -1843,80 +1780,101 @@ static int __init aty_init(struct fb_info_aty *info, const char *name) ...@@ -1843,80 +1780,101 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
if (gtb_memsize) if (gtb_memsize)
switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
case MEM_SIZE_512K: case MEM_SIZE_512K:
info->total_vram = 0x80000; info->fb_info.fix.smem_len = 0x80000;
break; break;
case MEM_SIZE_1M: case MEM_SIZE_1M:
info->total_vram = 0x100000; info->fb_info.fix.smem_len = 0x100000;
break; break;
case MEM_SIZE_2M_GTB: case MEM_SIZE_2M_GTB:
info->total_vram = 0x200000; info->fb_info.fix.smem_len = 0x200000;
break; break;
case MEM_SIZE_4M_GTB: case MEM_SIZE_4M_GTB:
info->total_vram = 0x400000; info->fb_info.fix.smem_len = 0x400000;
break; break;
case MEM_SIZE_6M_GTB: case MEM_SIZE_6M_GTB:
info->total_vram = 0x600000; info->fb_info.fix.smem_len = 0x600000;
break; break;
case MEM_SIZE_8M_GTB: case MEM_SIZE_8M_GTB:
info->total_vram = 0x800000; info->fb_info.fix.smem_len = 0x800000;
break; break;
default: default:
info->total_vram = 0x80000; info->fb_info.fix.smem_len = 0x80000;
} }
else else
switch (i & MEM_SIZE_ALIAS) { switch (i & MEM_SIZE_ALIAS) {
case MEM_SIZE_512K: case MEM_SIZE_512K:
info->total_vram = 0x80000; info->fb_info.fix.smem_len = 0x80000;
break; break;
case MEM_SIZE_1M: case MEM_SIZE_1M:
info->total_vram = 0x100000; info->fb_info.fix.smem_len = 0x100000;
break; break;
case MEM_SIZE_2M: case MEM_SIZE_2M:
info->total_vram = 0x200000; info->fb_info.fix.smem_len = 0x200000;
break; break;
case MEM_SIZE_4M: case MEM_SIZE_4M:
info->total_vram = 0x400000; info->fb_info.fix.smem_len = 0x400000;
break; break;
case MEM_SIZE_6M: case MEM_SIZE_6M:
info->total_vram = 0x600000; info->fb_info.fix.smem_len = 0x600000;
break; break;
case MEM_SIZE_8M: case MEM_SIZE_8M:
info->total_vram = 0x800000; info->fb_info.fix.smem_len = 0x800000;
break; break;
default: default:
info->total_vram = 0x80000; info->fb_info.fix.smem_len = 0x80000;
} }
if (M64_HAS(MAGIC_VRAM_SIZE)) { if (M64_HAS(MAGIC_VRAM_SIZE)) {
if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000) if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000)
info->total_vram += 0x400000; info->fb_info.fix.smem_len += 0x400000;
} }
if (default_vram) { if (default_vram) {
info->total_vram = default_vram*1024; info->fb_info.fix.smem_len = default_vram*1024;
i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS); i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
if (info->total_vram <= 0x80000) if (info->fb_info.fix.smem_len <= 0x80000)
i |= MEM_SIZE_512K; i |= MEM_SIZE_512K;
else if (info->total_vram <= 0x100000) else if (info->fb_info.fix.smem_len <= 0x100000)
i |= MEM_SIZE_1M; i |= MEM_SIZE_1M;
else if (info->total_vram <= 0x200000) else if (info->fb_info.fix.smem_len <= 0x200000)
i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M; i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
else if (info->total_vram <= 0x400000) else if (info->fb_info.fix.smem_len <= 0x400000)
i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M; i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
else if (info->total_vram <= 0x600000) else if (info->fb_info.fix.smem_len <= 0x600000)
i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M; i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
else else
i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M; i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
aty_st_le32(MEM_CNTL, i, info); aty_st_le32(MEM_CNTL, i, info);
} }
/*
* Reg Block 0 (CT-compatible block) is at mmio_start
* Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
*/
if (M64_HAS(GX)) {
info->fb_info.fix.mmio_len = 0x400;
info->fb_info.fix.accel = FB_ACCEL_ATI_MACH64GX;
} else if (M64_HAS(CT)) {
info->fb_info.fix.mmio_len = 0x400;
info->fb_info.fix.accel = FB_ACCEL_ATI_MACH64CT;
} else if (M64_HAS(VT)) {
info->fb_info.fix.mmio_start =- 0x400;
info->fb_info.fix.mmio_len = 0x800;
info->fb_info.fix.accel = FB_ACCEL_ATI_MACH64VT;
} else /* if (M64_HAS(GT)) */ {
info->fb_info.fix.mmio_start =- 0x400;
info->fb_info.fix.mmio_len = 0x800;
info->fb_info.fix.accel = FB_ACCEL_ATI_MACH64GT;
}
if (default_pll) if (default_pll)
pll = default_pll; pll = default_pll;
if (default_mclk) if (default_mclk)
mclk = default_mclk; mclk = default_mclk;
printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n", printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20), info->fb_info.fix.smem_len == 0x80000 ? 512 : (info->fb_info.fix.smem_len >> 20),
info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk); info->fb_info.fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
if (mclk < 44) if (mclk < 44)
info->mem_refresh_rate = 0; /* 000 = 10 Mhz - 43 Mhz */ info->mem_refresh_rate = 0; /* 000 = 10 Mhz - 43 Mhz */
...@@ -1959,23 +1917,24 @@ static int __init aty_init(struct fb_info_aty *info, const char *name) ...@@ -1959,23 +1917,24 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
* FIXME: we should use the auxiliary aperture instead so we can access * FIXME: we should use the auxiliary aperture instead so we can access
* the full 8 MB of video RAM on 8 MB boards * the full 8 MB of video RAM on 8 MB boards
*/ */
if (info->total_vram == 0x800000 || if (info->fb_info.fix.smem_len == 0x800000 ||
(info->bus_type == ISA && info->total_vram == 0x400000)) (info->bus_type == ISA && info->fb_info.fix.smem_len == 0x400000))
info->total_vram -= GUI_RESERVE; info->fb_info.fix.smem_len -= GUI_RESERVE;
/* Clear the video memory */ /* Clear the video memory */
fb_memset((void *)info->frame_buffer, 0, info->total_vram); fb_memset((void *)info->fb_info.screen_base, 0, info->fb_info.fix.smem_len);
disp = &info->disp; disp = info->fb_info.disp;
strcpy(info->fb_info.modename, atyfb_name); strcpy(info->fb_info.modename, atyfb_name);
info->fb_info.node = NODEV; info->fb_info.node = NODEV;
info->fb_info.fbops = &atyfb_ops; info->fb_info.fbops = &atyfb_ops;
info->fb_info.disp = disp; info->fb_info.disp = disp;
info->fb_info.pseudo_palette = pseudo_palette;
info->fb_info.currcon = -1; info->fb_info.currcon = -1;
strcpy(info->fb_info.fontname, fontname); strcpy(info->fb_info.fontname, fontname);
info->fb_info.changevar = NULL; info->fb_info.changevar = NULL;
info->fb_info.switch_con = &atyfbcon_switch; info->fb_info.switch_con = gen_switch;
info->fb_info.updatevar = &atyfbcon_updatevar; info->fb_info.updatevar = &atyfbcon_updatevar;
info->fb_info.flags = FBINFO_FLAG_DEFAULT; info->fb_info.flags = FBINFO_FLAG_DEFAULT;
...@@ -2058,7 +2017,7 @@ static int __init aty_init(struct fb_info_aty *info, const char *name) ...@@ -2058,7 +2017,7 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
var.accel_flags |= FB_ACCELF_TEXT; var.accel_flags |= FB_ACCELF_TEXT;
if (var.yres == var.yres_virtual) { if (var.yres == var.yres_virtual) {
u32 vram = (info->total_vram - (PAGE_SIZE << 2)); u32 vram = (info->fb_info.fix.smem_len - (PAGE_SIZE << 2));
var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual; var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
if (var.yres_virtual < var.yres) if (var.yres_virtual < var.yres)
var.yres_virtual = var.yres; var.yres_virtual = var.yres;
...@@ -2072,12 +2031,6 @@ static int __init aty_init(struct fb_info_aty *info, const char *name) ...@@ -2072,12 +2031,6 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
#ifdef __sparc__ #ifdef __sparc__
atyfb_save_palette(&info->fb_info, 0); atyfb_save_palette(&info->fb_info, 0);
#endif #endif
for (j = 0; j < 16; j++) {
k = color_table[j];
info->palette[j].red = default_red[k];
info->palette[j].green = default_grn[k];
info->palette[j].blue = default_blu[k];
}
#ifdef CONFIG_FB_ATY_CT #ifdef CONFIG_FB_ATY_CT
if (curblink && M64_HAS(INTEGRATED)) { if (curblink && M64_HAS(INTEGRATED)) {
...@@ -2088,6 +2041,9 @@ static int __init aty_init(struct fb_info_aty *info, const char *name) ...@@ -2088,6 +2041,9 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
} }
} }
#endif /* CONFIG_FB_ATY_CT */ #endif /* CONFIG_FB_ATY_CT */
info->fb_info.var = var;
fb_alloc_cmap(&info->fb_info.cmap, 256, 0);
atyfb_set_var(&var, -1, &info->fb_info); atyfb_set_var(&var, -1, &info->fb_info);
...@@ -2134,12 +2090,14 @@ int __init atyfb_init(void) ...@@ -2134,12 +2090,14 @@ int __init atyfb_init(void)
if (i < 0) if (i < 0)
continue; continue;
info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC); info = kmalloc(sizeof(struct fb_info_aty) + sizeof(struct display), GFP_ATOMIC);
if (!info) { if (!info) {
printk("atyfb_init: can't alloc fb_info_aty\n"); printk("atyfb_init: can't alloc fb_info_aty\n");
return -ENXIO; return -ENXIO;
} }
memset(info, 0, sizeof(struct fb_info_aty)); memset(info, 0, sizeof(struct fb_info_aty) + sizeof(struct display));
info->fb_info.disp = (struct display *) (info + 1);
rp = &pdev->resource[0]; rp = &pdev->resource[0];
if (rp->flags & IORESOURCE_IO) if (rp->flags & IORESOURCE_IO)
...@@ -2158,13 +2116,13 @@ int __init atyfb_init(void) ...@@ -2158,13 +2116,13 @@ int __init atyfb_init(void)
* Map memory-mapped registers. * Map memory-mapped registers.
*/ */
info->ati_regbase = addr + 0x7ffc00UL; info->ati_regbase = addr + 0x7ffc00UL;
info->ati_regbase_phys = addr + 0x7ffc00UL; info->fb_info.fix.mmio_start = addr + 0x7ffc00UL;
/* /*
* Map in big-endian aperture. * Map in big-endian aperture.
*/ */
info->frame_buffer = (unsigned long) addr + 0x800000UL; info->fb_info.screen_base = (unsigned long) addr + 0x800000UL;
info->frame_buffer_phys = addr + 0x800000UL; info->fb_info.fix.smem_start = addr + 0x800000UL;
/* /*
* Figure mmap addresses from PCI config space. * Figure mmap addresses from PCI config space.
...@@ -2358,9 +2316,9 @@ int __init atyfb_init(void) ...@@ -2358,9 +2316,9 @@ int __init atyfb_init(void)
} }
#else /* __sparc__ */ #else /* __sparc__ */
info->ati_regbase_phys = 0x7ff000 + addr; info->fb_info.fix.mmio_start = 0x7ff000 + addr;
info->ati_regbase = (unsigned long) info->ati_regbase = (unsigned long)
ioremap(info->ati_regbase_phys, 0x1000); ioremap(info->fb_info.fix.mmio_start, 0x1000);
if(!info->ati_regbase) { if(!info->ati_regbase) {
kfree(info); kfree(info);
...@@ -2368,7 +2326,7 @@ int __init atyfb_init(void) ...@@ -2368,7 +2326,7 @@ int __init atyfb_init(void)
return -ENOMEM; return -ENOMEM;
} }
info->ati_regbase_phys += 0xc00; info->fb_info.fix.mmio_start += 0xc00;
info->ati_regbase += 0xc00; info->ati_regbase += 0xc00;
/* /*
...@@ -2387,10 +2345,10 @@ int __init atyfb_init(void) ...@@ -2387,10 +2345,10 @@ int __init atyfb_init(void)
#endif #endif
/* Map in frame buffer */ /* Map in frame buffer */
info->frame_buffer_phys = addr; info->fb_info.fix.smem_start = addr;
info->frame_buffer = (unsigned long)ioremap(addr, 0x800000); info->fb_info.screen_base = (char*)ioremap(addr, 0x800000);
if(!info->frame_buffer) { if(!info->fb_info.screen_base) {
kfree(info); kfree(info);
release_mem_region(res_start, res_size); release_mem_region(res_start, res_size);
return -ENXIO; return -ENXIO;
...@@ -2414,11 +2372,11 @@ int __init atyfb_init(void) ...@@ -2414,11 +2372,11 @@ int __init atyfb_init(void)
* Add /dev/fb mmap values. * Add /dev/fb mmap values.
*/ */
info->mmap_map[0].voff = 0x8000000000000000UL; info->mmap_map[0].voff = 0x8000000000000000UL;
info->mmap_map[0].poff = info->frame_buffer & PAGE_MASK; info->mmap_map[0].poff = info->fb_info.screen_base & PAGE_MASK;
info->mmap_map[0].size = info->total_vram; info->mmap_map[0].size = info->fb_info.fix.smem_len;
info->mmap_map[0].prot_mask = _PAGE_CACHE; info->mmap_map[0].prot_mask = _PAGE_CACHE;
info->mmap_map[0].prot_flag = _PAGE_E; info->mmap_map[0].prot_flag = _PAGE_E;
info->mmap_map[1].voff = info->mmap_map[0].voff + info->total_vram; info->mmap_map[1].voff = info->mmap_map[0].voff + info->fb_info.fix.smem_len;
info->mmap_map[1].poff = info->ati_regbase & PAGE_MASK; info->mmap_map[1].poff = info->ati_regbase & PAGE_MASK;
info->mmap_map[1].size = PAGE_SIZE; info->mmap_map[1].size = PAGE_SIZE;
info->mmap_map[1].prot_mask = _PAGE_CACHE; info->mmap_map[1].prot_mask = _PAGE_CACHE;
...@@ -2458,10 +2416,10 @@ int __init atyfb_init(void) ...@@ -2458,10 +2416,10 @@ int __init atyfb_init(void)
* Map the video memory (physical address given) to somewhere in the * Map the video memory (physical address given) to somewhere in the
* kernel address space. * kernel address space.
*/ */
info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]); info->fb_info.screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
info->frame_buffer_phys = info->frame_buffer; /* Fake! */ info->fb_info.fix.smem_start = info->fb_info.screen_base; /* Fake! */
info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul; info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
info->ati_regbase_phys = info->ati_regbase; /* Fake! */ info->fb_info.fix.mmio_start = info->ati_regbase; /* Fake! */
aty_st_le32(CLOCK_CNTL, 0x12345678, info); aty_st_le32(CLOCK_CNTL, 0x12345678, info);
clock_r = aty_ld_le32(CLOCK_CNTL, info); clock_r = aty_ld_le32(CLOCK_CNTL, info);
...@@ -2596,41 +2554,21 @@ static int __init store_video_par(char *video_str, unsigned char m64_num) ...@@ -2596,41 +2554,21 @@ static int __init store_video_par(char *video_str, unsigned char m64_num)
} }
#endif /* CONFIG_ATARI */ #endif /* CONFIG_ATARI */
static int atyfbcon_switch(int con, struct fb_info *fb) /*
{
struct fb_info_aty *info = (struct fb_info_aty *)fb;
struct atyfb_par par;
/* Do we have to save the colormap? */
if (fb_display[fb->currcon].cmap.len)
fb_get_cmap(&fb_display[fb->currcon].cmap, 1, atyfb_getcolreg, fb);
#ifdef CONFIG_FB_ATY_CT #ifdef CONFIG_FB_ATY_CT
/* Erase HW Cursor */ * Erase HW Cursor *
if (info->cursor && (fb->currcon >= 0)) if (info->cursor && (fb->currcon >= 0))
atyfb_cursor(&fb_display[fb->currcon], CM_ERASE, atyfb_cursor(&fb_display[fb->currcon], CM_ERASE,
info->cursor->pos.x, info->cursor->pos.y); info->cursor->pos.x, info->cursor->pos.y);
#endif /* CONFIG_FB_ATY_CT */ #endif * CONFIG_FB_ATY_CT *
fb->currcon = con;
atyfb_decode_var(&fb_display[con].var, &par, info);
atyfb_set_par(&par, info);
atyfb_set_dispsw(&fb_display[con], info, par.crtc.bpp,
par.accel_flags & FB_ACCELF_TEXT);
/* Install new colormap */
do_install_cmap(con, fb);
#ifdef CONFIG_FB_ATY_CT #ifdef CONFIG_FB_ATY_CT
/* Install hw cursor */ * Install hw cursor *
if (info->cursor) { if (info->cursor) {
aty_set_cursor_color(info); aty_set_cursor_color(info);
aty_set_cursor_shape(info); aty_set_cursor_shape(info);
} }
#endif /* CONFIG_FB_ATY_CT */ #endif * CONFIG_FB_ATY_CT */
return 1;
}
/* /*
* Blank the display. * Blank the display.
...@@ -2673,27 +2611,6 @@ static int atyfb_blank(int blank, struct fb_info *fb) ...@@ -2673,27 +2611,6 @@ static int atyfb_blank(int blank, struct fb_info *fb)
return 0; return 0;
} }
/*
* Read a single color register and split it into
* colors/transparent. Return != 0 for invalid regno.
*/
static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *fb)
{
struct fb_info_aty *info = (struct fb_info_aty *)fb;
if (regno > 255)
return 1;
*red = (info->palette[regno].red<<8) | info->palette[regno].red;
*green = (info->palette[regno].green<<8) | info->palette[regno].green;
*blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
*transp = 0;
return 0;
}
/* /*
* Set a single color register. The values supplied are already * Set a single color register. The values supplied are already
* rounded down to the hardware's capabilities (according to the * rounded down to the hardware's capabilities (according to the
...@@ -2711,9 +2628,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -2711,9 +2628,6 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
red >>= 8; red >>= 8;
green >>= 8; green >>= 8;
blue >>= 8; blue >>= 8;
info->palette[regno].red = red;
info->palette[regno].green = green;
info->palette[regno].blue = blue;
i = aty_ld_8(DAC_CNTL, info) & 0xfc; i = aty_ld_8(DAC_CNTL, info) & 0xfc;
if (M64_HAS(EXTRA_BRIGHT)) if (M64_HAS(EXTRA_BRIGHT))
i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt*/ i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt*/
...@@ -2728,20 +2642,18 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, ...@@ -2728,20 +2642,18 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
switch (info->current_par.crtc.bpp) { switch (info->current_par.crtc.bpp) {
#ifdef FBCON_HAS_CFB16 #ifdef FBCON_HAS_CFB16
case 16: case 16:
info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | ((u16 *) (info->fb_info.pseudo_palette))[regno] = (regno << 10) | (regno << 5) | regno;
regno;
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB24 #ifdef FBCON_HAS_CFB24
case 24: case 24:
info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | ((u32 *) (info->fb_info.pseudo_palette))[regno] = (regno << 16) | (regno << 8) | regno;
regno;
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB32 #ifdef FBCON_HAS_CFB32
case 32: case 32:
i = (regno << 8) | regno; i = (regno << 8) | regno;
info->fbcon_cmap.cfb32[regno] = (i << 16) | i; ((u32 *) (info->fb_info.pseudo_palette))[regno] = (i << 16) | i;
break; break;
#endif #endif
} }
...@@ -2815,8 +2727,8 @@ void cleanup_module(void) ...@@ -2815,8 +2727,8 @@ void cleanup_module(void)
#ifndef __sparc__ #ifndef __sparc__
if (info->ati_regbase) if (info->ati_regbase)
iounmap((void *)info->ati_regbase); iounmap((void *)info->ati_regbase);
if (info->frame_buffer) if (info->fb_info.screen_base)
iounmap((void *)info->frame_buffer); iounmap((void *)info->fb_info.screen_base);
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
if (info->cursor && info->cursor->ram) if (info->cursor && info->cursor->ram)
iounmap(info->cursor->ram); iounmap(info->cursor->ram);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <video/fbcon-cfb24.h> #include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h> #include <video/fbcon-cfb32.h>
#include "mach64.h" #include <video/mach64.h>
#include "atyfb.h" #include "atyfb.h"
/* /*
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <video/fbcon.h> #include <video/fbcon.h>
#include "mach64.h" #include <video/mach64.h>
#include "atyfb.h" #include "atyfb.h"
...@@ -73,7 +73,7 @@ static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp, ...@@ -73,7 +73,7 @@ static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
/* fifo_off<<6 */ /* fifo_off<<6 */
fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(3<<6); fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(3<<6);
if (info->total_vram > 1*1024*1024) { if (info->fb_info.fix.smem_len > 1*1024*1024) {
if (info->ram_type >= SDRAM) { if (info->ram_type >= SDRAM) {
/* >1 MB SDRAM */ /* >1 MB SDRAM */
dsp_loop_latency += 8; dsp_loop_latency += 8;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <asm/fbio.h> #include <asm/fbio.h>
#endif #endif
#include "mach64.h" #include <video/mach64.h>
#include "atyfb.h" #include "atyfb.h"
...@@ -242,18 +242,18 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb) ...@@ -242,18 +242,18 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
memset(cursor->timer, 0, sizeof(*cursor->timer)); memset(cursor->timer, 0, sizeof(*cursor->timer));
cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE; cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
fb->total_vram -= PAGE_SIZE; fb->fb_info.fix.smem_len -= PAGE_SIZE;
cursor->offset = fb->total_vram; cursor->offset = fb->fb_info.fix.smem_len;
#ifdef __sparc__ #ifdef __sparc__
addr = fb->frame_buffer - 0x800000 + cursor->offset; addr = fb->fb_info.screen_base - 0x800000 + cursor->offset;
cursor->ram = (u8 *)addr; cursor->ram = (u8 *)addr;
#else #else
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
addr = fb->frame_buffer_phys - 0x800000 + cursor->offset; addr = fb->fb_info.fix.smem_start - 0x800000 + cursor->offset;
cursor->ram = (u8 *)ioremap(addr, 1024); cursor->ram = (u8 *)ioremap(addr, 1024);
#else #else
addr = fb->frame_buffer + cursor->offset; addr = (unsigned long) fb->fb_info.screen_base + cursor->offset;
cursor->ram = (u8 *)addr; cursor->ram = (u8 *)addr;
#endif #endif
#endif #endif
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <video/fbcon.h> #include <video/fbcon.h>
#include "mach64.h" #include <video/mach64.h>
#include "atyfb.h" #include "atyfb.h"
/* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */ /* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
......
/*
* linux/drivers/video/fbcon-vga.c -- Low level frame buffer operations for
* VGA characters/attributes
*
* Created 28 Mar 1998 by Geert Uytterhoeven
* Monochrome attributes added May 1998 by Andrew Apted
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/io.h>
#include <video/fbcon.h>
#include <video/fbcon-vga.h>
/*
* VGA screen access
*/
static inline void vga_writew(u16 val, u16 *addr)
{
#ifdef __powerpc__
st_le16(addr, val);
#else
writew(val, (unsigned long)addr);
#endif /* !__powerpc__ */
}
static inline u16 vga_readw(u16 *addr)
{
#ifdef __powerpc__
return ld_le16(addr);
#else
return readw((unsigned long)addr);
#endif /* !__powerpc__ */
}
static inline void vga_memsetw(void *s, u16 c, unsigned int count)
{
u16 *addr = (u16 *)s;
while (count) {
count--;
vga_writew(c, addr++);
}
}
static inline void vga_memmovew(u16 *to, u16 *from, unsigned int count)
{
if (to < from) {
while (count) {
count--;
vga_writew(vga_readw(from++), to++);
}
} else {
from += count;
to += count;
while (count) {
count--;
vga_writew(vga_readw(--from), --to);
}
}
}
/*
* VGA characters/attributes
*/
static inline u16 fbcon_vga_attr(struct display *p,
unsigned short s)
{
/* Underline and reverse-video are mutually exclusive on MDA.
* Since reverse-video is used for cursors and selected areas,
* it takes precedence.
*/
return (attr_reverse(p, s) ? 0x7000 :
(attr_underline(p, s) ? 0x0100 : 0x0700)) |
(attr_bold(p, s) ? 0x0800 : 0) |
(attr_blink(p, s) ? 0x8000 : 0);
}
void fbcon_vga_setup(struct display *p)
{
p->next_line = p->line_length;
p->next_plane = 0;
}
void fbcon_vga_bmove(struct display *p, int sy, int sx, int dy, int dx,
int height, int width)
{
u16 *src, *dst;
int rows;
if (sx == 0 && dx == 0 && width == p->next_line/2) {
src = (u16 *)(p->fb_info->screen_base+sy*p->next_line);
dst = (u16 *)(p->fb_info->screen_base+dy*p->next_line);
vga_memmovew(dst, src, height*width);
} else if (dy < sy || (dy == sy && dx < sx)) {
src = (u16 *)(p->fb_info->screen_base+sy*p->next_line+sx*2);
dst = (u16 *)(p->fb_info->screen_base+dy*p->next_line+dx*2);
for (rows = height; rows-- ;) {
vga_memmovew(dst, src, width);
src += p->next_line/2;
dst += p->next_line/2;
}
} else {
src = (u16 *)(p->fb_info->screen_base+(sy+height-1)*p->next_line+sx*2);
dst = (u16 *)(p->fb_info->screen_base+(dy+height-1)*p->next_line+dx*2);
for (rows = height; rows-- ;) {
vga_memmovew(dst, src, width);
src -= p->next_line/2;
dst -= p->next_line/2;
}
}
}
void fbcon_vga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int height, int width)
{
u16 *dest = (u16 *)(p->fb_info->screen_base+sy*p->next_line+sx*2);
int rows;
if (sx == 0 && width*2 == p->next_line)
vga_memsetw(dest, conp->vc_video_erase_char, height*width);
else
for (rows = height; rows-- ; dest += p->next_line/2)
vga_memsetw(dest, conp->vc_video_erase_char, width);
}
void fbcon_vga_putc(struct vc_data *conp, struct display *p, int c, int y,
int x)
{
u16 *dst = (u16 *)(p->fb_info->screen_base+y*p->next_line+x*2);
if (conp->vc_can_do_color)
vga_writew(c, dst);
else
vga_writew(fbcon_vga_attr(p, c) | (c & 0xff), dst);
}
void fbcon_vga_putcs(struct vc_data *conp, struct display *p,
const unsigned short *s, int count, int y, int x)
{
u16 *dst = (u16 *)(p->fb_info->screen_base+y*p->next_line+x*2);
u16 sattr;
if (conp->vc_can_do_color)
while (count--)
vga_writew(scr_readw(s++), dst++);
else {
sattr = fbcon_vga_attr(p, scr_readw(s));
while (count--)
vga_writew(sattr | ((int) (scr_readw(s++)) & 0xff), dst++);
}
}
void fbcon_vga_revc(struct display *p, int x, int y)
{
u16 *dst = (u16 *)(p->fb_info->screen_base+y*p->next_line+x*2);
u16 val = vga_readw(dst);
val = (val & 0x88ff) | ((val<<4) & 0x7000) | ((val>>4) & 0x0700);
vga_writew(val, dst);
}
/*
* `switch' for the low level operations
*/
struct display_switch fbcon_vga = {
setup: fbcon_vga_setup,
bmove: fbcon_vga_bmove,
clear: fbcon_vga_clear,
putc: fbcon_vga_putc,
putcs: fbcon_vga_putcs,
revc: fbcon_vga_revc,
fontwidthmask: FONTWIDTH(8)
};
#ifdef MODULE
MODULE_LICENSE("GPL");
int init_module(void)
{
return 0;
}
void cleanup_module(void)
{}
#endif /* MODULE */
/*
* Visible symbols for modules
*/
EXPORT_SYMBOL(fbcon_vga);
EXPORT_SYMBOL(fbcon_vga_setup);
EXPORT_SYMBOL(fbcon_vga_bmove);
EXPORT_SYMBOL(fbcon_vga_clear);
EXPORT_SYMBOL(fbcon_vga_putc);
EXPORT_SYMBOL(fbcon_vga_putcs);
EXPORT_SYMBOL(fbcon_vga_revc);
...@@ -30,133 +30,18 @@ ...@@ -30,133 +30,18 @@
#include <video/fbcon-cfb32.h> #include <video/fbcon-cfb32.h>
#include "fbcon-accel.h" #include "fbcon-accel.h"
/* ---- `Generic' versions of the frame buffer device operations ----------- */
/**
* fbgen_get_fix - get fixed part of display
* @fix: fb_fix_screeninfo structure
* @con: virtual console number
* @info: frame buffer info structure
*
* Get the fixed information part of the display and place it
* into @fix for virtual console @con on device @info.
*
* Returns negative errno on error, or zero on success.
*
*/
int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
{
struct fb_info_gen *info2 = (struct fb_info_gen *)info;
struct fbgen_hwswitch *fbhw = info2->fbhw;
char par[info2->parsize];
if (con == -1)
fbhw->get_par(&par, info2);
else {
int err;
if ((err = fbhw->decode_var(&fb_display[con].var, &par, info2)))
return err;
}
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
return fbhw->encode_fix(fix, &par, info2);
}
int gen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) int gen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
{ {
*fix = info->fix; *fix = info->fix;
return 0; return 0;
} }
/**
* fbgen_get_var - get user defined part of display
* @var: fb_var_screeninfo structure
* @con: virtual console number
* @info: frame buffer info structure
*
* Get the user defined part of the display and place it into @var
* for virtual console @con on device @info.
*
* Returns negative errno on error, or zero for success.
*
*/
int fbgen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
struct fb_info_gen *info2 = (struct fb_info_gen *)info;
struct fbgen_hwswitch *fbhw = info2->fbhw;
char par[info2->parsize];
if (con == -1) {
fbhw->get_par(&par, info2);
fbhw->encode_var(var, &par, info2);
} else
*var = fb_display[con].var;
return 0;
}
int gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) int gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{ {
*var = info->var; *var = info->var;
return 0; return 0;
} }
/**
* fbgen_set_var - set the user defined part of display
* @var: fb_var_screeninfo user defined part of the display
* @con: virtual console number
* @info: frame buffer info structure
*
* Set the user defined part of the display as dictated by @var
* for virtual console @con on device @info.
*
* Returns negative errno on error, or zero for success.
*
*/
int fbgen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
struct fb_info_gen *info2 = (struct fb_info_gen *)info;
int err;
int oldxres, oldyres, oldbpp, oldxres_virtual, oldyres_virtual, oldyoffset;
struct fb_bitfield oldred, oldgreen, oldblue;
if ((err = fbgen_do_set_var(var, con == info->currcon, info2)))
return err;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
oldxres = fb_display[con].var.xres;
oldyres = fb_display[con].var.yres;
oldxres_virtual = fb_display[con].var.xres_virtual;
oldyres_virtual = fb_display[con].var.yres_virtual;
oldbpp = fb_display[con].var.bits_per_pixel;
oldred = fb_display[con].var.red;
oldgreen = fb_display[con].var.green;
oldblue = fb_display[con].var.blue;
oldyoffset = fb_display[con].var.yoffset;
fb_display[con].var = *var;
if (oldxres != var->xres || oldyres != var->yres ||
oldxres_virtual != var->xres_virtual ||
oldyres_virtual != var->yres_virtual ||
oldbpp != var->bits_per_pixel ||
(!(memcmp(&oldred, &(var->red), sizeof(struct fb_bitfield)))) ||
(!(memcmp(&oldgreen, &(var->green), sizeof(struct fb_bitfield)))) ||
(!(memcmp(&oldblue, &(var->blue), sizeof(struct fb_bitfield)))) ||
oldyoffset != var->yoffset) {
fbgen_set_disp(con, info2);
if (info->changevar)
(*info->changevar)(con);
if ((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
return err;
do_install_cmap(con, info);
}
}
var->activate = 0;
return 0;
}
int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{ {
int err; int err;
...@@ -191,75 +76,12 @@ int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) ...@@ -191,75 +76,12 @@ int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
return 0; return 0;
} }
/**
* fbgen_get_cmap - get the colormap
* @cmap: frame buffer colormap structure
* @kspc: boolean, 0 copy local, 1 put_user() function
* @con: virtual console number
* @info: frame buffer info structure
*
* Gets the colormap for virtual console @con and places it into
* @cmap for device @info.
*
* Returns negative errno on error, or zero for success.
*
*/
int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
struct fb_info_gen *info2 = (struct fb_info_gen *)info;
struct fbgen_hwswitch *fbhw = info2->fbhw;
if (con == info->currcon) /* current console ? */
return fb_get_cmap(cmap, kspc, 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 {
int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
}
return 0;
}
int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) int gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
{ {
fb_copy_cmap (&info->cmap, cmap, kspc ? 0 : 2); fb_copy_cmap (&info->cmap, cmap, kspc ? 0 : 2);
return 0; return 0;
} }
/**
* fbgen_set_cmap - set the colormap
* @cmap: frame buffer colormap structure
* @kspc: boolean, 0 copy local, 1 get_user() function
* @con: virtual console number
* @info: frame buffer info structure
*
* Sets the colormap @cmap for virtual console @con on
* device @info.
*
* Returns negative errno on error, or zero for success.
*
*/
int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
int err;
if (!fb_display[con].cmap.len) { /* no colormap allocated ? */
int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
return err;
}
if (con == info->currcon) /* current console ? */
return fb_set_cmap(cmap, kspc, info);
else
fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
return 0;
}
int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con, int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info) struct fb_info *info)
{ {
...@@ -285,21 +107,6 @@ int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con, ...@@ -285,21 +107,6 @@ int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
return err; return err;
} }
/**
* fbgen_pan_display - pan or wrap the display
* @var: frame buffer user defined part of display
* @con: virtual console number
* @info: frame buffer info structure
*
* Pan or wrap virtual console @con for device @info.
*
* This call looks only at xoffset, yoffset and the
* FB_VMODE_YWRAP flag in @var.
*
* Returns negative errno on error, or zero for success.
*
*/
int fbgen_pan_display(struct fb_var_screeninfo *var, int con, int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info) struct fb_info *info)
{ {
...@@ -334,84 +141,6 @@ int fbgen_pan_display(struct fb_var_screeninfo *var, int con, ...@@ -334,84 +141,6 @@ int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
/* ---- Helper functions --------------------------------------------------- */ /* ---- Helper functions --------------------------------------------------- */
/**
* fbgen_do_set_var - change the video mode
* @var: frame buffer user defined part of display
* @isactive: boolean, 0 inactive, 1 active
* @info: generic frame buffer info structure
*
* Change the video mode settings for device @info. If @isactive
* is non-zero, the changes will be activated immediately.
*
* Return negative errno on error, or zero for success.
*
*/
int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
struct fb_info_gen *info)
{
struct fbgen_hwswitch *fbhw = info->fbhw;
int err, activate;
char par[info->parsize];
if ((err = fbhw->decode_var(var, &par, info)))
return err;
activate = var->activate;
if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive)
fbhw->set_par(&par, info);
fbhw->encode_var(var, &par, info);
var->activate = activate;
return 0;
}
/**
* fbgen_set_disp - set generic display
* @con: virtual console number
* @info: generic frame buffer info structure
*
* Sets a display on virtual console @con for device @info.
*
*/
void fbgen_set_disp(int con, struct fb_info_gen *info)
{
struct fbgen_hwswitch *fbhw = info->fbhw;
struct fb_fix_screeninfo fix;
char par[info->parsize];
struct display *display;
if (con >= 0)
display = &fb_display[con];
else
display = info->info.disp; /* used during initialization */
if (con == -1)
fbhw->get_par(&par, info);
else
fbhw->decode_var(&fb_display[con].var, &par, info);
memset(&fix, 0, sizeof(struct fb_fix_screeninfo));
fbhw->encode_fix(&fix, &par, info);
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
display->ypanstep = fix.ypanstep;
display->ywrapstep = fix.ywrapstep;
display->line_length = fix.line_length;
if (info->fbhw->blank || fix.visual == FB_VISUAL_PSEUDOCOLOR ||
fix.visual == FB_VISUAL_DIRECTCOLOR)
display->can_soft_blank = 1;
else
display->can_soft_blank = 0;
fbhw->set_disp(&par, display, info);
#if 0 /* FIXME: generic inverse is not supported yet */
display->inverse = (fix.visual == FB_VISUAL_MONO01 ? !inverse : inverse);
#else
display->inverse = fix.visual == FB_VISUAL_MONO01;
#endif
}
void gen_set_disp(int con, struct fb_info *info) void gen_set_disp(int con, struct fb_info *info)
{ {
struct display *display = (con < 0) ? info->disp : (fb_display + con); struct display *display = (con < 0) ? info->disp : (fb_display + con);
...@@ -476,33 +205,6 @@ void do_install_cmap(int con, struct fb_info *info) ...@@ -476,33 +205,6 @@ void do_install_cmap(int con, struct fb_info *info)
} }
} }
/**
* fbgen_update_var - update user defined part of display
* @con: virtual console number
* @info: frame buffer info structure
*
* Updates the user defined part of the display ('var'
* structure) on virtual console @con for device @info.
* This function is called by fbcon.c.
*
* Returns negative errno on error, or zero for success.
*
*/
int fbgen_update_var(int con, struct fb_info *info)
{
struct fb_info_gen *info2 = (struct fb_info_gen *)info;
struct fbgen_hwswitch *fbhw = info2->fbhw;
int err;
if (fbhw->pan_display) {
if ((err = fbhw->pan_display(&fb_display[con].var, info2)))
return err;
}
return 0;
}
int gen_update_var(int con, struct fb_info *info) int gen_update_var(int con, struct fb_info *info)
{ {
struct display *disp = (con < 0) ? info->disp : (fb_display + con); struct display *disp = (con < 0) ? info->disp : (fb_display + con);
...@@ -520,35 +222,6 @@ int gen_update_var(int con, struct fb_info *info) ...@@ -520,35 +222,6 @@ int gen_update_var(int con, struct fb_info *info)
return 0; return 0;
} }
/**
* fbgen_switch - switch to a different virtual console.
* @con: virtual console number
* @info: frame buffer info structure
*
* Switch to virtuall console @con on device @info.
*
* Returns zero.
*
*/
int fbgen_switch(int con, struct fb_info *info)
{
struct fb_info_gen *info2 = (struct fb_info_gen *)info;
struct fbgen_hwswitch *fbhw = info2->fbhw;
/* Do we have to save the colormap ? */
if (fb_display[info->currcon].cmap.len)
fb_get_cmap(&fb_display[info->currcon].cmap, 1, fbhw->getcolreg,
&info2->info);
fbgen_do_set_var(&fb_display[con].var, 1, info2);
info->currcon = con;
/* Install new colormap */
do_install_cmap(con, info);
return 0;
}
int gen_switch(int con, struct fb_info *info) int gen_switch(int con, struct fb_info *info)
{ {
struct display *disp; struct display *disp;
...@@ -622,24 +295,15 @@ int fbgen_blank(int blank, struct fb_info *info) ...@@ -622,24 +295,15 @@ int fbgen_blank(int blank, struct fb_info *info)
} }
/* generic frame buffer operations */ /* generic frame buffer operations */
EXPORT_SYMBOL(fbgen_get_fix);
EXPORT_SYMBOL(gen_get_fix); EXPORT_SYMBOL(gen_get_fix);
EXPORT_SYMBOL(fbgen_get_var);
EXPORT_SYMBOL(gen_get_var); EXPORT_SYMBOL(gen_get_var);
EXPORT_SYMBOL(fbgen_set_var);
EXPORT_SYMBOL(gen_set_var); EXPORT_SYMBOL(gen_set_var);
EXPORT_SYMBOL(fbgen_get_cmap);
EXPORT_SYMBOL(gen_get_cmap); EXPORT_SYMBOL(gen_get_cmap);
EXPORT_SYMBOL(fbgen_set_cmap);
EXPORT_SYMBOL(gen_set_cmap); EXPORT_SYMBOL(gen_set_cmap);
EXPORT_SYMBOL(fbgen_pan_display); EXPORT_SYMBOL(fbgen_pan_display);
/* helper functions */ /* helper functions */
EXPORT_SYMBOL(fbgen_do_set_var);
EXPORT_SYMBOL(fbgen_set_disp);
EXPORT_SYMBOL(do_install_cmap); EXPORT_SYMBOL(do_install_cmap);
EXPORT_SYMBOL(fbgen_update_var);
EXPORT_SYMBOL(gen_update_var); EXPORT_SYMBOL(gen_update_var);
EXPORT_SYMBOL(fbgen_switch);
EXPORT_SYMBOL(gen_switch); EXPORT_SYMBOL(gen_switch);
EXPORT_SYMBOL(fbgen_blank); EXPORT_SYMBOL(fbgen_blank);
......
...@@ -132,7 +132,7 @@ extern int pmagbafb_init(void); ...@@ -132,7 +132,7 @@ extern int pmagbafb_init(void);
extern int pmagbbfb_init(void); extern int pmagbbfb_init(void);
extern void maxinefb_init(void); extern void maxinefb_init(void);
extern int tx3912fb_init(void); extern int tx3912fb_init(void);
extern int tx3912fb_setup(char*); extern void tx3912fb_setup(char*);
extern int radeonfb_init(void); extern int radeonfb_init(void);
extern int radeonfb_setup(char*); extern int radeonfb_setup(char*);
extern int e1355fb_init(void); extern int e1355fb_init(void);
......
...@@ -34,67 +34,42 @@ ...@@ -34,67 +34,42 @@
#endif #endif
#include <video/fbcon.h> #include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb32.h>
#include <video/macmodes.h> #include <video/macmodes.h>
/* Supported palette hacks */ /* Supported palette hacks */
enum { enum {
cmap_unknown, cmap_unknown,
cmap_m64, /* ATI Mach64 */ cmap_m64, /* ATI Mach64 */
cmap_r128, /* ATI Rage128 */ cmap_r128, /* ATI Rage128 */
cmap_M3A, /* ATI Rage Mobility M3 Head A */ cmap_M3A, /* ATI Rage Mobility M3 Head A */
cmap_M3B, /* ATI Rage Mobility M3 Head B */ cmap_M3B, /* ATI Rage Mobility M3 Head B */
cmap_radeon, /* ATI Radeon */ cmap_radeon, /* ATI Radeon */
cmap_gxt2000, /* IBM GXT2000 */ cmap_gxt2000, /* IBM GXT2000 */
}; };
struct fb_info_offb { struct offb_par {
struct fb_info info; volatile unsigned char *cmap_adr;
struct fb_fix_screeninfo fix; volatile unsigned char *cmap_data;
struct fb_var_screeninfo var; int cmap_type;
struct display disp; int blanked;
struct { u_char red, green, blue, pad; } palette[256];
volatile unsigned char *cmap_adr;
volatile unsigned char *cmap_data;
int cmap_type;
int blanked;
union {
#ifdef FBCON_HAS_CFB16
u16 cfb16[16];
#endif
#ifdef FBCON_HAS_CFB32
u32 cfb32[16];
#endif
} fbcon_cmap;
}; };
struct offb_par default_par;
#ifdef __powerpc__ #ifdef __powerpc__
#define mach_eieio() eieio() #define mach_eieio() eieio()
#else #else
#define mach_eieio() do {} while (0) #define mach_eieio() do {} while (0)
#endif #endif
/* /*
* Interface used by the world * Interface used by the world
*/ */
int offb_init(void); int offb_init(void);
static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int offb_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
static int offb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int offb_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);
static int offb_blank(int blank, struct fb_info *info); static int offb_blank(int blank, struct fb_info *info);
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
...@@ -102,147 +77,101 @@ extern boot_infos_t *boot_infos; ...@@ -102,147 +77,101 @@ extern boot_infos_t *boot_infos;
#endif #endif
static void offb_init_nodriver(struct device_node *); static void offb_init_nodriver(struct device_node *);
static void offb_init_fb(const char *name, const char *full_name, int width, static void offb_init_fb(const char *name, const char *full_name,
int height, int depth, int pitch, unsigned long address, int width, int height, int depth, int pitch,
struct device_node *dp); unsigned long address, struct device_node *dp);
/*
* Interface to the low level console driver
*/
static int offbcon_switch(int con, struct fb_info *info);
static int offbcon_updatevar(int con, struct fb_info *info);
/*
* Internal routines
*/
static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *info);
static struct fb_ops offb_ops = { static struct fb_ops offb_ops = {
owner: THIS_MODULE, owner: THIS_MODULE,
fb_get_fix: offb_get_fix, fb_get_fix: gen_get_fix,
fb_get_var: offb_get_var, fb_get_var: gen_get_var,
fb_set_var: offb_set_var, fb_set_var: gen_set_var,
fb_get_cmap: offb_get_cmap, fb_get_cmap: gen_get_cmap,
fb_set_cmap: offb_set_cmap, fb_set_cmap: gen_set_cmap,
fb_setcolreg: offb_setcolreg, fb_setcolreg: offb_setcolreg,
fb_blank: offb_blank, fb_blank: offb_blank,
fb_fillrect: cfb_fillrect,
fb_copyarea: cfb_copyarea,
fb_imageblit: cfb_imageblit,
}; };
/* /*
* Get the Fixed Part of the Display * Set a single color register. The values supplied are already
*/ * rounded down to the hardware's capabilities (according to the
* entries in the var structure). Return != 0 for invalid regno.
static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info)
{
struct fb_info_offb *info2 = (struct fb_info_offb *)info;
memcpy(fix, &info2->fix, sizeof(struct fb_fix_screeninfo));
return 0;
}
/*
* Get the User Defined Part of the Display
*/
static int offb_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
struct fb_info_offb *info2 = (struct fb_info_offb *)info;
memcpy(var, &info2->var, sizeof(struct fb_var_screeninfo));
return 0;
}
/*
* Set the User Defined Part of the Display
*/
static int offb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
struct display *display;
unsigned int oldbpp = 0;
int err;
int activate = var->activate;
struct fb_info_offb *info2 = (struct fb_info_offb *)info;
if (con >= 0)
display = &fb_display[con];
else
display = &info2->disp; /* used during initialization */
if (var->xres > info2->var.xres || var->yres > info2->var.yres ||
var->xres_virtual > info2->var.xres_virtual ||
var->yres_virtual > info2->var.yres_virtual ||
var->bits_per_pixel > info2->var.bits_per_pixel ||
var->nonstd ||
(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
return -EINVAL;
memcpy(var, &info2->var, sizeof(struct fb_var_screeninfo));
if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
oldbpp = display->var.bits_per_pixel;
display->var = *var;
}
if ((oldbpp != var->bits_per_pixel) || (display->cmap.len == 0)) {
if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
return err;
do_install_cmap(con, info);
}
return 0;
}
/*
* Get the Colormap
*/ */
static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con, static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
struct fb_info *info) u_int transp, struct fb_info *info)
{ {
struct fb_info_offb *info2 = (struct fb_info_offb *)info; struct offb_par *par = (struct offb_par *) info->par;
if (con == info->currcon && !info2->blanked) /* current console? */ if (!par->cmap_adr || regno > 255)
return fb_get_cmap(cmap, kspc, offb_getcolreg, info); return 1;
if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); red >>= 8;
else green >>= 8;
{ blue >>= 8;
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2); switch (par->cmap_type) {
} case cmap_m64:
return 0; *par->cmap_adr = regno;
} mach_eieio();
*par->cmap_data = red;
/* mach_eieio();
* Set the Colormap *par->cmap_data = green;
*/ mach_eieio();
*par->cmap_data = blue;
mach_eieio();
break;
case cmap_M3A:
/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
out_le32((unsigned *) (par->cmap_adr + 0x58),
in_le32((unsigned *) (par->cmap_adr +
0x58)) & ~0x20);
case cmap_r128:
/* Set palette index & data */
out_8(par->cmap_adr + 0xb0, regno);
out_le32((unsigned *) (par->cmap_adr + 0xb4),
(red << 16 | green << 8 | blue));
break;
case cmap_M3B:
/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
out_le32((unsigned *) (par->cmap_adr + 0x58),
in_le32((unsigned *) (par->cmap_adr +
0x58)) | 0x20);
/* Set palette index & data */
out_8(par->cmap_adr + 0xb0, regno);
out_le32((unsigned *) (par->cmap_adr + 0xb4),
(red << 16 | green << 8 | blue));
break;
case cmap_radeon:
/* Set palette index & data (could be smarter) */
out_8(par->cmap_adr + 0xb0, regno);
out_le32((unsigned *) (par->cmap_adr + 0xb4),
(red << 16 | green << 8 | blue));
break;
case cmap_gxt2000:
out_le32((unsigned *) par->cmap_adr + regno,
(red << 16 | green << 8 | blue));
break;
}
static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con, if (regno < 16)
struct fb_info *info) switch (info->var.bits_per_pixel) {
{ case 16:
struct fb_info_offb *info2 = (struct fb_info_offb *)info; ((u16 *) (info->pseudo_palette))[regno] =
int err; (regno << 10) | (regno << 5) | regno;
break;
if (!info2->cmap_adr) case 32:
return -ENOSYS; {
int i = (regno << 8) | regno;
if (!fb_display[con].cmap.len) { /* no colormap allocated? */ ((u32 *) (info->pseudo_palette))[regno] =
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256; (i << 16) | i;
if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0))) break;
return err; }
} }
if (con == info->currcon && !info2->blanked) /* current console? */ return 0;
return fb_set_cmap(cmap, kspc, info);
else
fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
return 0;
} }
/* /*
...@@ -251,62 +180,69 @@ static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con, ...@@ -251,62 +180,69 @@ static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
static int offb_blank(int blank, struct fb_info *info) static int offb_blank(int blank, struct fb_info *info)
{ {
struct fb_info_offb *info2 = (struct fb_info_offb *)info; struct offb_par *par = (struct offb_par *) info->par;
int i, j; int i, j;
if (!info2->cmap_adr) if (!par->cmap_adr)
return 0;
if (!par->blanked)
if (!blank)
return 0;
par->blanked = blank;
if (blank)
for (i = 0; i < 256; i++) {
switch (par->cmap_type) {
case cmap_m64:
*par->cmap_adr = i;
mach_eieio();
for (j = 0; j < 3; j++) {
*par->cmap_data = 0;
mach_eieio();
}
break;
case cmap_M3A:
/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
out_le32((unsigned *) (par->cmap_adr +
0x58),
in_le32((unsigned *) (par->
cmap_adr +
0x58)) &
~0x20);
case cmap_r128:
/* Set palette index & data */
out_8(par->cmap_adr + 0xb0, i);
out_le32((unsigned *) (par->cmap_adr +
0xb4), 0);
break;
case cmap_M3B:
/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
out_le32((unsigned *) (par->cmap_adr +
0x58),
in_le32((unsigned *) (par->
cmap_adr +
0x58)) |
0x20);
/* Set palette index & data */
out_8(par->cmap_adr + 0xb0, i);
out_le32((unsigned *) (par->cmap_adr +
0xb4), 0);
break;
case cmap_radeon:
out_8(par->cmap_adr + 0xb0, i);
out_le32((unsigned *) (par->cmap_adr +
0xb4), 0);
break;
case cmap_gxt2000:
out_le32((unsigned *) par->cmap_adr + i,
0);
break;
}
} else
fb_set_cmap(&info->cmap, 1, info);
return 0; return 0;
if (!info2->blanked) {
if (!blank)
return 0;
if (fb_display[info->currcon].cmap.len)
fb_get_cmap(&fb_display[info->currcon].cmap, 1, offb_getcolreg,info);
}
info2->blanked = blank;
if (blank)
for (i = 0; i < 256; i++) {
switch(info2->cmap_type) {
case cmap_m64:
*info2->cmap_adr = i;
mach_eieio();
for (j = 0; j < 3; j++) {
*info2->cmap_data = 0;
mach_eieio();
}
break;
case cmap_M3A:
/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
out_le32((unsigned *)(info2->cmap_adr + 0x58),
in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
case cmap_r128:
/* Set palette index & data */
out_8(info2->cmap_adr + 0xb0, i);
out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
break;
case cmap_M3B:
/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
out_le32((unsigned *)(info2->cmap_adr + 0x58),
in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
/* Set palette index & data */
out_8(info2->cmap_adr + 0xb0, i);
out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
break;
case cmap_radeon:
out_8(info2->cmap_adr + 0xb0, i);
out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
break;
case cmap_gxt2000:
out_le32((unsigned *)info2->cmap_adr + i, 0);
break;
}
}
else
do_install_cmap(info->currcon, info);
return 0;
} }
/* /*
...@@ -315,477 +251,311 @@ static int offb_blank(int blank, struct fb_info *info) ...@@ -315,477 +251,311 @@ static int offb_blank(int blank, struct fb_info *info)
int __init offb_init(void) int __init offb_init(void)
{ {
struct device_node *dp; struct device_node *dp;
unsigned int dpy; unsigned int dpy;
#ifdef CONFIG_BOOTX_TEXT #ifdef CONFIG_BOOTX_TEXT
struct device_node *displays = find_type_devices("display"); struct device_node *displays = find_type_devices("display");
struct device_node *macos_display = NULL; struct device_node *macos_display = NULL;
/* If we're booted from BootX... */ /* If we're booted from BootX... */
if (prom_num_displays == 0 && boot_infos != 0) { if (prom_num_displays == 0 && boot_infos != 0) {
unsigned long addr = (unsigned long) boot_infos->dispDeviceBase; unsigned long addr =
/* find the device node corresponding to the macos display */ (unsigned long) boot_infos->dispDeviceBase;
for (dp = displays; dp != NULL; dp = dp->next) { /* find the device node corresponding to the macos display */
int i; for (dp = displays; dp != NULL; dp = dp->next) {
/* int i;
* Grrr... It looks like the MacOS ATI driver /*
* munges the assigned-addresses property (but * Grrr... It looks like the MacOS ATI driver
* the AAPL,address value is OK). * munges the assigned-addresses property (but
*/ * the AAPL,address value is OK).
if (strncmp(dp->name, "ATY,", 4) == 0 && dp->n_addrs == 1) { */
unsigned int *ap = (unsigned int *) if (strncmp(dp->name, "ATY,", 4) == 0
get_property(dp, "AAPL,address", NULL); && dp->n_addrs == 1) {
if (ap != NULL) { unsigned int *ap =
dp->addrs[0].address = *ap; (unsigned int *) get_property(dp,
dp->addrs[0].size = 0x01000000; "AAPL,address",
NULL);
if (ap != NULL) {
dp->addrs[0].address = *ap;
dp->addrs[0].size = 0x01000000;
}
}
/*
* The LTPro on the Lombard powerbook has no addresses
* on the display nodes, they are on their parent.
*/
if (dp->n_addrs == 0
&& device_is_compatible(dp, "ATY,264LTPro")) {
int na;
unsigned int *ap = (unsigned int *)
get_property(dp, "AAPL,address", &na);
if (ap != 0)
for (na /= sizeof(unsigned int);
na > 0; --na, ++ap)
if (*ap <= addr
&& addr <
*ap + 0x1000000)
goto foundit;
}
/*
* See if the display address is in one of the address
* ranges for this display.
*/
for (i = 0; i < dp->n_addrs; ++i) {
if (dp->addrs[i].address <= addr
&& addr <
dp->addrs[i].address +
dp->addrs[i].size)
break;
}
if (i < dp->n_addrs) {
foundit:
printk(KERN_INFO "MacOS display is %s\n",
dp->full_name);
macos_display = dp;
break;
}
} }
}
/*
* The LTPro on the Lombard powerbook has no addresses
* on the display nodes, they are on their parent.
*/
if (dp->n_addrs == 0 && device_is_compatible(dp, "ATY,264LTPro")) {
int na;
unsigned int *ap = (unsigned int *)
get_property(dp, "AAPL,address", &na);
if (ap != 0)
for (na /= sizeof(unsigned int); na > 0; --na, ++ap)
if (*ap <= addr && addr < *ap + 0x1000000)
goto foundit;
}
/*
* See if the display address is in one of the address
* ranges for this display.
*/
for (i = 0; i < dp->n_addrs; ++i) {
if (dp->addrs[i].address <= addr
&& addr < dp->addrs[i].address + dp->addrs[i].size)
break;
}
if (i < dp->n_addrs) {
foundit:
printk(KERN_INFO "MacOS display is %s\n", dp->full_name);
macos_display = dp;
break;
}
}
/* initialize it */ /* initialize it */
offb_init_fb(macos_display? macos_display->name: "MacOS display", offb_init_fb(macos_display ? macos_display->
macos_display? macos_display->full_name: "MacOS display", name : "MacOS display",
boot_infos->dispDeviceRect[2], macos_display ? macos_display->
boot_infos->dispDeviceRect[3], full_name : "MacOS display",
boot_infos->dispDeviceDepth, boot_infos->dispDeviceRect[2],
boot_infos->dispDeviceRowBytes, addr, NULL); boot_infos->dispDeviceRect[3],
} boot_infos->dispDeviceDepth,
boot_infos->dispDeviceRowBytes, addr, NULL);
}
#endif #endif
for (dpy = 0; dpy < prom_num_displays; dpy++) { for (dpy = 0; dpy < prom_num_displays; dpy++) {
if ((dp = find_path_device(prom_display_paths[dpy]))) if ((dp = find_path_device(prom_display_paths[dpy])))
offb_init_nodriver(dp); offb_init_nodriver(dp);
} }
return 0; return 0;
} }
static void __init offb_init_nodriver(struct device_node *dp) static void __init offb_init_nodriver(struct device_node *dp)
{ {
int *pp, i; int *pp, i;
unsigned int len; unsigned int len;
int width = 640, height = 480, depth = 8, pitch; int width = 640, height = 480, depth = 8, pitch;
unsigned *up, address; unsigned *up, address;
if ((pp = (int *)get_property(dp, "depth", &len)) != NULL if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
&& len == sizeof(int)) && len == sizeof(int))
depth = *pp; depth = *pp;
if ((pp = (int *)get_property(dp, "width", &len)) != NULL if ((pp = (int *) get_property(dp, "width", &len)) != NULL
&& len == sizeof(int)) && len == sizeof(int))
width = *pp; width = *pp;
if ((pp = (int *)get_property(dp, "height", &len)) != NULL if ((pp = (int *) get_property(dp, "height", &len)) != NULL
&& len == sizeof(int)) && len == sizeof(int))
height = *pp; height = *pp;
if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL
&& len == sizeof(int)) { && len == sizeof(int)) {
pitch = *pp; pitch = *pp;
if (pitch == 1) if (pitch == 1)
pitch = 0x1000; pitch = 0x1000;
} else } else
pitch = width; pitch = width;
if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL
&& len == sizeof(unsigned)) && len == sizeof(unsigned))
address = (u_long)*up; address = (u_long) * up;
else { else {
for (i = 0; i < dp->n_addrs; ++i) for (i = 0; i < dp->n_addrs; ++i)
if (dp->addrs[i].size >= pitch*height*depth/8) if (dp->addrs[i].size >=
break; pitch * height * depth / 8)
if (i >= dp->n_addrs) { break;
printk(KERN_ERR "no framebuffer address found for %s\n", dp->full_name); if (i >= dp->n_addrs) {
return; printk(KERN_ERR
} "no framebuffer address found for %s\n",
dp->full_name);
address = (u_long)dp->addrs[i].address; return;
}
/* kludge for valkyrie */ address = (u_long) dp->addrs[i].address;
if (strcmp(dp->name, "valkyrie") == 0)
address += 0x1000;
}
offb_init_fb(dp->name, dp->full_name, width, height, depth,
pitch, address, dp);
}
static void __init offb_init_fb(const char *name, const char *full_name, /* kludge for valkyrie */
int width, int height, int depth, if (strcmp(dp->name, "valkyrie") == 0)
int pitch, unsigned long address, address += 0x1000;
struct device_node *dp)
{
int i;
struct fb_fix_screeninfo *fix;
struct fb_var_screeninfo *var;
struct display *disp;
struct fb_info_offb *info;
unsigned long res_start = address;
unsigned long res_size = pitch*height*depth/8;
if (!request_mem_region(res_start, res_size, "offb"))
return;
printk(KERN_INFO "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
width, height, name, address, depth, pitch);
if (depth != 8 && depth != 16 && depth != 32) {
printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth);
release_mem_region(res_start, res_size);
return;
}
info = kmalloc(sizeof(struct fb_info_offb), GFP_ATOMIC);
if (info == 0) {
release_mem_region(res_start, res_size);
return;
}
memset(info, 0, sizeof(*info));
fix = &info->fix;
var = &info->var;
disp = &info->disp;
strcpy(fix->id, "OFfb ");
strncat(fix->id, name, sizeof(fix->id));
fix->id[sizeof(fix->id)-1] = '\0';
var->xres = var->xres_virtual = width;
var->yres = var->yres_virtual = height;
fix->line_length = pitch;
fix->smem_start = address;
fix->smem_len = pitch * height;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
info->cmap_type = cmap_unknown;
if (depth == 8)
{
/* XXX kludge for ati */
if (dp && !strncmp(name, "ATY,Rage128", 11)) {
unsigned long regbase = dp->addrs[2].address;
info->cmap_adr = ioremap(regbase, 0x1FFF);
info->cmap_type = cmap_r128;
} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
|| !strncmp(name, "ATY,RageM3p12A", 14))) {
unsigned long regbase = dp->parent->addrs[2].address;
info->cmap_adr = ioremap(regbase, 0x1FFF);
info->cmap_type = cmap_M3A;
} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
unsigned long regbase = dp->parent->addrs[2].address;
info->cmap_adr = ioremap(regbase, 0x1FFF);
info->cmap_type = cmap_M3B;
} else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
unsigned long regbase = dp->addrs[1].address;
info->cmap_adr = ioremap(regbase, 0x1FFF);
info->cmap_type = cmap_radeon;
} else if (!strncmp(name, "ATY,", 4)) {
unsigned long base = address & 0xff000000UL;
info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
info->cmap_data = info->cmap_adr + 1;
info->cmap_type = cmap_m64;
} else if (device_is_compatible(dp, "pci1014,b7")) {
unsigned long regbase = dp->addrs[0].address;
info->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
info->cmap_type = cmap_gxt2000;
} }
fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR offb_init_fb(dp->name, dp->full_name, width, height, depth,
: FB_VISUAL_STATIC_PSEUDOCOLOR; pitch, address, dp);
}
else
fix->visual = /*info->cmap_adr ? FB_VISUAL_DIRECTCOLOR
: */FB_VISUAL_TRUECOLOR;
var->xoffset = var->yoffset = 0;
var->bits_per_pixel = depth;
switch (depth) {
case 8:
var->bits_per_pixel = 8;
var->red.offset = 0;
var->red.length = 8;
var->green.offset = 0;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
case 16: /* RGB 555 */
var->bits_per_pixel = 16;
var->red.offset = 10;
var->red.length = 5;
var->green.offset = 5;
var->green.length = 5;
var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break;
case 32: /* RGB 888 */
var->bits_per_pixel = 32;
var->red.offset = 16;
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 24;
var->transp.length = 8;
break;
}
var->red.msb_right = var->green.msb_right = var->blue.msb_right = var->transp.msb_right = 0;
var->grayscale = 0;
var->nonstd = 0;
var->activate = 0;
var->height = var->width = -1;
var->pixclock = 10000;
var->left_margin = var->right_margin = 16;
var->upper_margin = var->lower_margin = 16;
var->hsync_len = var->vsync_len = 8;
var->sync = 0;
var->vmode = FB_VMODE_NONINTERLACED;
disp->var = *var;
disp->cmap.start = 0;
disp->cmap.len = 0;
disp->cmap.red = NULL;
disp->cmap.green = NULL;
disp->cmap.blue = NULL;
disp->cmap.transp = NULL;
disp->visual = fix->visual;
disp->type = fix->type;
disp->type_aux = fix->type_aux;
disp->ypanstep = 0;
disp->ywrapstep = 0;
disp->line_length = fix->line_length;
disp->can_soft_blank = info->cmap_adr ? 1 : 0;
disp->inverse = 0;
switch (depth) {
#ifdef FBCON_HAS_CFB8
case 8:
disp->dispsw = &fbcon_cfb8;
break;
#endif
#ifdef FBCON_HAS_CFB16
case 16:
disp->dispsw = &fbcon_cfb16;
disp->dispsw_data = info->fbcon_cmap.cfb16;
for (i = 0; i < 16; i++)
if (fix->visual == FB_VISUAL_TRUECOLOR)
info->fbcon_cmap.cfb16[i] =
(((default_blu[i] >> 3) & 0x1f) << 10) |
(((default_grn[i] >> 3) & 0x1f) << 5) |
((default_red[i] >> 3) & 0x1f);
else
info->fbcon_cmap.cfb16[i] =
(i << 10) | (i << 5) | i;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:
disp->dispsw = &fbcon_cfb32;
disp->dispsw_data = info->fbcon_cmap.cfb32;
for (i = 0; i < 16; i++)
if (fix->visual == FB_VISUAL_TRUECOLOR)
info->fbcon_cmap.cfb32[i] =
(default_blu[i] << 16) |
(default_grn[i] << 8) |
default_red[i];
else
info->fbcon_cmap.cfb32[i] =
(i << 16) | (i << 8) | i;
break;
#endif
default:
disp->dispsw = &fbcon_dummy;
}
disp->scrollmode = SCROLL_YREDRAW;
strcpy(info->info.modename, "OFfb ");
strncat(info->info.modename, full_name, sizeof(info->info.modename));
info->info.node = NODEV;
info->info.fbops = &offb_ops;
info->info.screen_base = ioremap(address, fix->smem_len);
info->info.disp = disp;
info->info.currcon = -1;
info->info.fontname[0] = '\0';
info->info.changevar = NULL;
info->info.switch_con = &offbcon_switch;
info->info.updatevar = &offbcon_updatevar;
info->info.flags = FBINFO_FLAG_DEFAULT;
for (i = 0; i < 16; i++) {
int j = color_table[i];
info->palette[i].red = default_red[j];
info->palette[i].green = default_grn[j];
info->palette[i].blue = default_blu[j];
}
offb_set_var(var, -1, &info->info);
if (register_framebuffer(&info->info) < 0) {
kfree(info);
release_mem_region(res_start, res_size);
return;
}
printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
GET_FB_IDX(info->info.node), full_name);
}
static int offbcon_switch(int con, struct fb_info *info)
{
struct fb_info_offb *info2 = (struct fb_info_offb *)info;
/* Do we have to save the colormap? */
if (fb_display[info->currcon].cmap.len && !info2->blanked)
fb_get_cmap(&fb_display[info->currcon].cmap, 1, offb_getcolreg, info);
info->currcon = con;
/* Install new colormap */
do_install_cmap(con, info);
return 0;
}
/*
* Update the `var' structure (called by fbcon.c)
*/
static int offbcon_updatevar(int con, struct fb_info *info)
{
/* Nothing */
return 0;
} }
/* static void __init offb_init_fb(const char *name, const char *full_name,
* Read a single color register and split it into int width, int height, int depth,
* colors/transparent. Return != 0 for invalid regno. int pitch, unsigned long address,
*/ struct device_node *dp)
static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *info)
{ {
struct fb_info_offb *info2 = (struct fb_info_offb *)info; unsigned long res_size = pitch * height * depth / 8;
struct offb_par *par = &default_par;
if (!info2->cmap_adr || regno > 255) unsigned long res_start = address;
return 1; struct fb_fix_screeninfo *fix;
struct fb_var_screeninfo *var;
*red = (info2->palette[regno].red<<8) | info2->palette[regno].red; struct fb_info *info;
*green = (info2->palette[regno].green<<8) | info2->palette[regno].green; int i;
*blue = (info2->palette[regno].blue<<8) | info2->palette[regno].blue;
*transp = 0; if (!request_mem_region(res_start, res_size, "offb"))
return 0; return;
}
printk(KERN_INFO
"Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
/* width, height, name, address, depth, pitch);
* Set a single color register. The values supplied are already if (depth != 8 && depth != 16 && depth != 32) {
* rounded down to the hardware's capabilities (according to the printk(KERN_ERR "%s: can't use depth = %d\n", full_name,
* entries in the var structure). Return != 0 for invalid regno. depth);
*/ release_mem_region(res_start, res_size);
return;
}
static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, info =
u_int transp, struct fb_info *info) kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
{ sizeof(u32) * 17, GFP_ATOMIC);
struct fb_info_offb *info2 = (struct fb_info_offb *)info; if (info == 0) {
release_mem_region(res_start, res_size);
if (!info2->cmap_adr || regno > 255) return;
return 1; }
memset(info, 0, sizeof(*info));
red >>= 8;
green >>= 8; fix = &info->fix;
blue >>= 8; var = &info->var;
info2->palette[regno].red = red; strcpy(fix->id, "OFfb ");
info2->palette[regno].green = green; strncat(fix->id, name, sizeof(fix->id));
info2->palette[regno].blue = blue; fix->id[sizeof(fix->id) - 1] = '\0';
switch(info2->cmap_type) { var->xres = var->xres_virtual = width;
case cmap_m64: var->yres = var->yres_virtual = height;
*info2->cmap_adr = regno; fix->line_length = pitch;
mach_eieio();
*info2->cmap_data = red; fix->smem_start = address;
mach_eieio(); fix->smem_len = pitch * height;
*info2->cmap_data = green; fix->type = FB_TYPE_PACKED_PIXELS;
mach_eieio(); fix->type_aux = 0;
*info2->cmap_data = blue;
mach_eieio(); par->cmap_type = cmap_unknown;
break; if (depth == 8) {
case cmap_M3A: /* XXX kludge for ati */
/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */ if (dp && !strncmp(name, "ATY,Rage128", 11)) {
out_le32((unsigned *)(info2->cmap_adr + 0x58), unsigned long regbase = dp->addrs[2].address;
in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20); par->cmap_adr = ioremap(regbase, 0x1FFF);
case cmap_r128: par->cmap_type = cmap_r128;
/* Set palette index & data */ } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
out_8(info2->cmap_adr + 0xb0, regno); || !strncmp(name, "ATY,RageM3p12A", 14))) {
out_le32((unsigned *)(info2->cmap_adr + 0xb4), unsigned long regbase =
(red << 16 | green << 8 | blue)); dp->parent->addrs[2].address;
break; par->cmap_adr = ioremap(regbase, 0x1FFF);
case cmap_M3B: par->cmap_type = cmap_M3A;
/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */ } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
out_le32((unsigned *)(info2->cmap_adr + 0x58), unsigned long regbase =
in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20); dp->parent->addrs[2].address;
/* Set palette index & data */ par->cmap_adr = ioremap(regbase, 0x1FFF);
out_8(info2->cmap_adr + 0xb0, regno); par->cmap_type = cmap_M3B;
out_le32((unsigned *)(info2->cmap_adr + 0xb4), } else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
(red << 16 | green << 8 | blue)); unsigned long regbase = dp->addrs[1].address;
break; par->cmap_adr = ioremap(regbase, 0x1FFF);
case cmap_radeon: par->cmap_type = cmap_radeon;
/* Set palette index & data (could be smarter) */ } else if (!strncmp(name, "ATY,", 4)) {
out_8(info2->cmap_adr + 0xb0, regno); unsigned long base = address & 0xff000000UL;
out_le32((unsigned *)(info2->cmap_adr + 0xb4), par->cmap_adr =
(red << 16 | green << 8 | blue)); ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
break; par->cmap_data = info->cmap_adr + 1;
case cmap_gxt2000: par->cmap_type = cmap_m64;
out_le32((unsigned *)info2->cmap_adr + regno, } else if (device_is_compatible(dp, "pci1014,b7")) {
(red << 16 | green << 8 | blue)); unsigned long regbase = dp->addrs[0].address;
break; par->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
} par->cmap_type = cmap_gxt2000;
}
if (regno < 16) fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
switch (info2->var.bits_per_pixel) { : FB_VISUAL_STATIC_PSEUDOCOLOR;
#ifdef FBCON_HAS_CFB16 } else
case 16: fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR
info2->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno; : */ FB_VISUAL_TRUECOLOR;
var->xoffset = var->yoffset = 0;
var->bits_per_pixel = depth;
switch (depth) {
case 8:
var->bits_per_pixel = 8;
var->red.offset = 0;
var->red.length = 8;
var->green.offset = 0;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break; break;
#endif case 16: /* RGB 555 */
#ifdef FBCON_HAS_CFB32 var->bits_per_pixel = 16;
case 32: var->red.offset = 10;
{ var->red.length = 5;
int i = (regno << 8) | regno; var->green.offset = 5;
info2->fbcon_cmap.cfb32[regno] = (i << 16) | i; var->green.length = 5;
var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break; break;
} case 32: /* RGB 888 */
#endif var->bits_per_pixel = 32;
} var->red.offset = 16;
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 24;
var->transp.length = 8;
break;
}
var->red.msb_right = var->green.msb_right = var->blue.msb_right =
var->transp.msb_right = 0;
var->grayscale = 0;
var->nonstd = 0;
var->activate = 0;
var->height = var->width = -1;
var->pixclock = 10000;
var->left_margin = var->right_margin = 16;
var->upper_margin = var->lower_margin = 16;
var->hsync_len = var->vsync_len = 8;
var->sync = 0;
var->vmode = FB_VMODE_NONINTERLACED;
strcpy(fix->id, "OFfb ");
strncat(fix->id, full_name, sizeof(fix->id));
strcpy(info->modename, fix->id);
info->node = NODEV;
info->fbops = &offb_ops;
info->screen_base = ioremap(address, fix->smem_len);
info->par = par;
info->disp = (struct display *) (info + 1);
info->pseudo_palette = (void *) (info->disp + 1);
info->currcon = -1;
info->fontname[0] = '\0';
info->changevar = NULL;
info->switch_con = gen_switch;
info->updatevar = gen_update_var;
info->flags = FBINFO_FLAG_DEFAULT;
fb_alloc_cmap(&info->cmap, 256, 0);
gen_set_disp(-1, info);
if (register_framebuffer(info) < 0) {
kfree(info);
release_mem_region(res_start, res_size);
return;
}
return 0; printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
GET_FB_IDX(info->info.node), full_name);
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -27,18 +27,15 @@ ...@@ -27,18 +27,15 @@
#include <asm/mtrr.h> #include <asm/mtrr.h>
#include <video/fbcon.h> #include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb32.h>
#define INCLUDE_TIMING_TABLE_DATA #define INCLUDE_TIMING_TABLE_DATA
#define DBE_REG_BASE regs #define DBE_REG_BASE regs
#include "sgivwfb.h" #include <video/sgivw.h>
struct sgivwfb_par { struct sgivw_par {
struct fb_var_screeninfo var; asregs *regs;
u_long timing_num; u32 cmap_fifo;
int valid; u_long timing_num;
}; };
/* /*
...@@ -49,113 +46,109 @@ struct sgivwfb_par { ...@@ -49,113 +46,109 @@ struct sgivwfb_par {
*/ */
/* set by arch/i386/kernel/setup.c */ /* set by arch/i386/kernel/setup.c */
u_long sgivwfb_mem_phys; u_long sgivwfb_mem_phys;
u_long sgivwfb_mem_size; u_long sgivwfb_mem_size;
static asregs *regs;
static struct fb_info fb_info; static struct fb_info fb_info;
static struct { u_char red, green, blue, pad; } palette[256]; static struct sgivw_par default_par;
static char sgivwfb_name[16] = "SGI Vis WS FB"; static int ypan = 0;
static u32 cmap_fifo; static int ywrap = 0;
static int ypan = 0;
static int ywrap = 0; static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
id: "SGI Vis WS FB",
type: FB_TYPE_PACKED_PIXELS,
visual: FB_VISUAL_PSEUDOCOLOR,
mmio_start: DBE_REG_PHYS,
mmio_len: DBE_REG_SIZE,
accel_flags: FB_ACCEL_NONE
};
static struct fb_var_screeninfo sgivwfb_var __initdata = {
/* 640x480, 8 bpp */
xres: 640,
yres: 480,
xres_virtual: 640,
yres_virtual: 480,
bits_per_pixel: 8,
red: {0, 8, 0},
green: {0, 8, 0},
blue: {0, 8, 0},
height: -1,
width: -1,
pixclock: 20000,
left_margin: 64,
right_margin: 64,
upper_margin: 32,
lower_margin: 32,
hsync_len: 64,
vsync_len: 2,
vmode: FB_VMODE_NONINTERLACED
};
/* console related variables */ /* console related variables */
static struct display disp; static struct display disp;
static union {
#ifdef FBCON_HAS_CFB16
u16 cfb16[16];
#endif
#ifdef FBCON_HAS_CFB32
u32 cfb32[16];
#endif
} fbcon_cmap;
static struct sgivwfb_par par_current = {
{ /* var (screeninfo) */
/* 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, 0, 20000, 64, 64, 32, 32, 64, 2,
0, FB_VMODE_NONINTERLACED
},
0, /* timing_num */
0 /* par not activated */
};
/* /*
* Interface used by the world * Interface used by the world
*/ */
int sgivwfb_setup(char*); int sgivwfb_init(void);
int sgivwfb_setup(char *);
static int sgivwfb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info); static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
static int sgivwfb_get_var(struct fb_var_screeninfo *var, int con, static int sgivwfb_set_par(struct fb_info *info);
struct fb_info *info); static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con, u_int blue, u_int transp,
struct fb_info *info); struct fb_info *info);
static int sgivwfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
static int sgivwfb_mmap(struct fb_info *info, struct file *file, static int sgivwfb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma); struct vm_area_struct *vma);
static struct fb_ops sgivwfb_ops = { static struct fb_ops sgivwfb_ops = {
owner: THIS_MODULE, owner: THIS_MODULE,
fb_get_fix: sgivwfb_get_fix, fb_get_fix: gen_get_fix,
fb_get_var: sgivwfb_get_var, fb_get_var: gen_get_var,
fb_set_var: sgivwfb_set_var, fb_set_var: gen_set_var,
fb_get_cmap: sgivwfb_get_cmap, fb_get_cmap: gen_get_cmap,
fb_set_cmap: gen_set_cmap, fb_set_cmap: gen_set_cmap,
fb_check_var: sgivwfb_check_var,
fb_set_par: sgivwfb_set_par,
fb_setcolreg: sgivwfb_setcolreg, fb_setcolreg: sgivwfb_setcolreg,
fb_fillrect: cfb_fillrect,
fb_copyarea: cfb_copyarea,
fb_imageblit: cfb_imageblit,
fb_mmap: sgivwfb_mmap, fb_mmap: sgivwfb_mmap,
}; };
/*
* Interface to the low level console driver
*/
int sgivwfb_init(void);
static int sgivwfbcon_switch(int con, struct fb_info *info);
static int sgivwfbcon_updatevar(int con, struct fb_info *info);
/* /*
* Internal routines * Internal routines
*/ */
static u_long get_line_length(int xres_virtual, int bpp); static u_long get_line_length(int xres_virtual, int bpp);
static unsigned long bytes_per_pixel(int bpp); static unsigned long bytes_per_pixel(int bpp);
static void activate_par(struct sgivwfb_par *par);
static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
struct fb_var_screeninfo *var);
static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *info);
static unsigned long get_line_length(int xres_virtual, int bpp) static unsigned long get_line_length(int xres_virtual, int bpp)
{ {
return(xres_virtual * bytes_per_pixel(bpp)); return (xres_virtual * bytes_per_pixel(bpp));
} }
static unsigned long bytes_per_pixel(int bpp) static unsigned long bytes_per_pixel(int bpp)
{ {
unsigned long length; unsigned long length;
switch (bpp) { switch (bpp) {
case 8: case 8:
length = 1; length = 1;
break; break;
case 16: case 16:
length = 2; length = 2;
break; break;
case 32: case 32:
length = 4; length = 4;
break; break;
default: default:
printk(KERN_INFO "sgivwfb: unsupported bpp=%d\n", bpp); printk(KERN_INFO "sgivwfb: unsupported bpp=%d\n", bpp);
length = 0; length = 0;
break; break;
} }
return(length); return (length);
} }
/* /*
...@@ -168,360 +161,476 @@ static unsigned long bytes_per_pixel(int bpp) ...@@ -168,360 +161,476 @@ static unsigned long bytes_per_pixel(int bpp)
static void dbe_TurnOffDma(void) static void dbe_TurnOffDma(void)
{ {
int i; int i;
unsigned int readVal; unsigned int readVal;
// Check to see if things are already turned off: // Check to see if things are already turned off:
// 1) Check to see if dbe is not using the internal dotclock. // 1) Check to see if dbe is not using the internal dotclock.
// 2) Check to see if the xy counter in dbe is already off. // 2) Check to see if the xy counter in dbe is already off.
DBE_GETREG(ctrlstat, readVal); DBE_GETREG(ctrlstat, readVal);
if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2) if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2)
return; return;
DBE_GETREG(vt_xy, readVal); DBE_GETREG(vt_xy, readVal);
if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1)
return; return;
// Otherwise, turn off dbe // Otherwise, turn off dbe
DBE_GETREG(ovr_control, readVal); DBE_GETREG(ovr_control, readVal);
SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0); SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0);
DBE_SETREG(ovr_control, readVal); DBE_SETREG(ovr_control, readVal);
udelay(1000); udelay(1000);
DBE_GETREG(frm_control, readVal); DBE_GETREG(frm_control, readVal);
SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0); SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0);
DBE_SETREG(frm_control, readVal); DBE_SETREG(frm_control, readVal);
udelay(1000); udelay(1000);
DBE_GETREG(did_control, readVal); DBE_GETREG(did_control, readVal);
SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0); SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0);
DBE_SETREG(did_control, readVal); DBE_SETREG(did_control, readVal);
udelay(1000); udelay(1000);
// XXX HACK: // XXX HACK:
// //
// This was necessary for GBE--we had to wait through two // This was necessary for GBE--we had to wait through two
// vertical retrace periods before the pixel DMA was // vertical retrace periods before the pixel DMA was
// turned off for sure. I've left this in for now, in // turned off for sure. I've left this in for now, in
// case dbe needs it. // case dbe needs it.
for (i = 0; i < 10000; i++) for (i = 0; i < 10000; i++) {
{ DBE_GETREG(frm_inhwctrl, readVal);
DBE_GETREG(frm_inhwctrl, readVal); if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) ==
if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) == 0) 0)
udelay(10); udelay(10);
else else {
{ DBE_GETREG(ovr_inhwctrl, readVal);
DBE_GETREG(ovr_inhwctrl, readVal); if (GET_DBE_FIELD
if (GET_DBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0) (OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
udelay(10); udelay(10);
else else {
{ DBE_GETREG(did_inhwctrl, readVal);
DBE_GETREG(did_inhwctrl, readVal); if (GET_DBE_FIELD
if (GET_DBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, readVal) == 0) (DID_INHWCTRL, DID_DMA_ENABLE,
udelay(10); readVal) == 0)
else udelay(10);
break; else
} break;
} }
} }
}
} }
/* /*
* Set the hardware according to 'par'. * Set the User Defined Part of the Display. Again if par use it to get
* real video mode.
*/ */
static void activate_par(struct sgivwfb_par *par) static int sgivwfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{ {
int i,j, htmp, temp; int err, activate = var->activate;
u32 readVal, outputVal; struct dbe_timing_info *timing;
int wholeTilesX, maxPixelsPerTileX; u_long line_length;
int frmWrite1, frmWrite2, frmWrite3b; u_long min_mode;
dbe_timing_info_t *currentTiming; /* Current Video Timing */ int req_dot;
int xpmax, ypmax; // Monitor resolution int test_mode;
int bytesPerPixel; // Bytes per pixel
/*
currentTiming = &dbeVTimings[par->timing_num]; * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
bytesPerPixel = bytes_per_pixel(par->var.bits_per_pixel); * as FB_VMODE_SMOOTH_XPAN is only used internally
xpmax = currentTiming->width; */
ypmax = currentTiming->height;
if (var->vmode & FB_VMODE_CONUPDATE) {
/* dbe_InitGraphicsBase(); */ var->vmode |= FB_VMODE_YWRAP;
/* Turn on dotclock PLL */ var->xoffset = display->var.xoffset;
DBE_SETREG(ctrlstat, 0x20000000); var->yoffset = display->var.yoffset;
}
dbe_TurnOffDma();
/* XXX FIXME - forcing var's */
/* dbe_CalculateScreenParams(); */ var->xoffset = 0;
maxPixelsPerTileX = 512/bytesPerPixel; var->yoffset = 0;
wholeTilesX = xpmax/maxPixelsPerTileX;
if (wholeTilesX*maxPixelsPerTileX < xpmax) /* Limit bpp to 8, 16, and 32 */
wholeTilesX++; if (var->bits_per_pixel <= 8)
var->bits_per_pixel = 8;
printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n", else if (var->bits_per_pixel <= 16)
maxPixelsPerTileX, wholeTilesX); var->bits_per_pixel = 16;
else if (var->bits_per_pixel <= 32)
/* dbe_InitGammaMap(); */ var->bits_per_pixel = 32;
udelay(10); else
return -EINVAL;
for (i = 0; i < 256; i++)
{ var->grayscale = 0; /* No grayscale for now */
DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8));
} /* determine valid resolution and timing */
for (min_mode = 0; min_mode < DBE_VT_SIZE; min_mode++) {
/* dbe_TurnOn(); */ if (dbeVTimings[min_mode].width >= var->xres &&
DBE_GETREG(vt_xy, readVal); dbeVTimings[min_mode].height >= var->yres)
if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) break;
{ }
DBE_SETREG(vt_xy, 0x00000000);
udelay(1); if (min_mode == DBE_VT_SIZE)
} return -EINVAL; /* Resolution to high */
else
dbe_TurnOffDma(); /* XXX FIXME - should try to pick best refresh rate */
/* for now, pick closest dot-clock within 3MHz */
/* dbe_Initdbe(); */ req_dot = PICOS2KHZ(var->pixclock);
for (i = 0; i < 256; i++) printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n",
{ var->pixclock, req_dot);
for (j = 0; j < 100; j++) test_mode = min_mode;
{ while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
DBE_GETREG(cm_fifo, readVal); if (dbeVTimings[test_mode].cfreq + 3000 > req_dot)
if (readVal != 0x00000000) break;
break; test_mode++;
else }
udelay(10); if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
} test_mode--;
min_mode = test_mode;
// DBE_ISETREG(cmap, i, 0x00000000); timing = &dbeVTimings[min_mode];
DBE_ISETREG(cmap, i, (i<<8)|(i<<16)|(i<<24)); printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n",
} timing->cfreq);
/* dbe_InitFramebuffer(); */ /* Adjust virtual resolution, if necessary */
frmWrite1 = 0; if (var->xres > var->xres_virtual || (!ywrap && !ypan))
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1, wholeTilesX); var->xres_virtual = var->xres;
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0); if (var->yres > var->yres_virtual || (!ywrap && !ypan))
var->yres_virtual = var->yres;
switch(bytesPerPixel)
{ /*
case 1: * Memory limit
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, DBE_FRM_DEPTH_8); */
break; line_length =
case 2: get_line_length(var->xres_virtual, var->bits_per_pixel);
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, DBE_FRM_DEPTH_16); if (line_length * var->yres_virtual > sgivwfb_mem_size)
break; return -ENOMEM; /* Virtual resolution to high */
case 4:
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, DBE_FRM_DEPTH_32); switch (var->bits_per_pixel) {
break; case 8:
} var->red.offset = 0;
var->red.length = 8;
frmWrite2 = 0; var->green.offset = 0;
SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax); var->green.length = 8;
var->blue.offset = 0;
// Tell dbe about the framebuffer location and type var->blue.length = 8;
// XXX What format is the FRM_TILE_PTR?? 64K aligned address? var->transp.offset = 0;
frmWrite3b = 0; var->transp.length = 0;
SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b, sgivwfb_mem_phys>>9); break;
SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1); case 16: /* RGBA 5551 */
SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1); var->red.offset = 11;
var->red.length = 5;
/* Initialize DIDs */ var->green.offset = 6;
var->green.length = 5;
outputVal = 0; var->blue.offset = 1;
switch(bytesPerPixel) var->blue.length = 5;
{ var->transp.offset = 0;
case 1: var->transp.length = 0;
SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8); break;
break; case 32: /* RGB 8888 */
case 2: var->red.offset = 0;
SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5); var->red.length = 8;
break; var->green.offset = 8;
case 4: var->green.length = 8;
SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8); var->blue.offset = 16;
break; var->blue.length = 8;
} var->transp.offset = 24;
SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH); var->transp.length = 8;
break;
for (i = 0; i < 32; i++) }
{ var->red.msb_right = 0;
DBE_ISETREG(mode_regs, i, outputVal); var->green.msb_right = 0;
} var->blue.msb_right = 0;
var->transp.msb_right = 0;
/* dbe_InitTiming(); */
DBE_SETREG(vt_intr01, 0xffffffff); /* set video timing information */
DBE_SETREG(vt_intr23, 0xffffffff); var->pixclock = KHZ2PICOS(timing->cfreq);
var->left_margin = timing->htotal - timing->hsync_end;
DBE_GETREG(dotclock, readVal); var->right_margin = timing->hsync_start - timing->width;
DBE_SETREG(dotclock, readVal & 0xffff); var->upper_margin = timing->vtotal - timing->vsync_end;
var->lower_margin = timing->vsync_start - timing->height;
DBE_SETREG(vt_xymax, 0x00000000); var->hsync_len = timing->hsync_end - timing->hsync_start;
outputVal = 0; var->vsync_len = timing->vsync_end - timing->vsync_start;
SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal, currentTiming->vsync_start);
SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal, currentTiming->vsync_end); /* Ouch. This breaks the rules but timing_num is only important if you
DBE_SETREG(vt_vsync, outputVal); * change a video mode */
outputVal = 0; par->timing_num = min_mode;
SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal, currentTiming->hsync_start);
SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal, currentTiming->hsync_end); printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
DBE_SETREG(vt_hsync, outputVal); var->xres, var->yres, var->bits_per_pixel);
outputVal = 0; printk(KERN_INFO " vxres=%d vyres=%d\n", var->xres_virtual,
SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal, currentTiming->vblank_start); var->yres_virtual);
SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal, currentTiming->vblank_end); return 0;
DBE_SETREG(vt_vblank, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal, currentTiming->hblank_start);
SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal, currentTiming->hblank_end-3);
DBE_SETREG(vt_hblank, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal, currentTiming->vblank_start);
SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal, currentTiming->vblank_end);
DBE_SETREG(vt_vcmap, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal, currentTiming->hblank_start);
SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal, currentTiming->hblank_end-3);
DBE_SETREG(vt_hcmap, outputVal);
outputVal = 0;
temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
if (temp > 0)
temp = -temp;
SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32)temp);
if (currentTiming->hblank_end >= 20)
SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
currentTiming->hblank_end - 20);
else
SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
currentTiming->htotal - (20 - currentTiming->hblank_end));
DBE_SETREG(did_start_xy, outputVal);
outputVal = 0;
SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal, (u32)(temp+1));
if (currentTiming->hblank_end >= DBE_CRS_MAGIC)
SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
currentTiming->hblank_end - DBE_CRS_MAGIC);
else
SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
currentTiming->htotal - (DBE_CRS_MAGIC - currentTiming->hblank_end));
DBE_SETREG(crs_start_xy, outputVal);
outputVal = 0;
SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32)temp);
SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
currentTiming->hblank_end - 4);
DBE_SETREG(vc_start_xy, outputVal);
DBE_SETREG(frm_size_tile, frmWrite1);
DBE_SETREG(frm_size_pixel, frmWrite2);
outputVal = 0;
SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m-1);
SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n-1);
SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);
SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);
DBE_SETREG(dotclock, outputVal);
udelay(11*1000);
DBE_SETREG(vt_vpixen, 0xffffff);
DBE_SETREG(vt_hpixen, 0xffffff);
outputVal = 0;
SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);
SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);
DBE_SETREG(vt_xymax, outputVal);
outputVal = frmWrite1;
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);
DBE_SETREG(frm_size_tile, outputVal);
DBE_SETREG(frm_size_tile, frmWrite1);
outputVal = 0;
SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);
DBE_SETREG(ovr_width_tile, outputVal);
DBE_SETREG(ovr_width_tile, 0);
DBE_SETREG(frm_control, frmWrite3b);
DBE_SETREG(did_control, 0);
// Wait for dbe to take frame settings
for (i=0; i<100000; i++)
{
DBE_GETREG(frm_inhwctrl, readVal);
if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) != 0)
break;
else
udelay(1);
}
if (i==100000)
printk(KERN_INFO "sgivwfb: timeout waiting for frame DMA enable.\n");
outputVal = 0;
htmp = currentTiming->hblank_end - 19;
if (htmp < 0)
htmp += currentTiming->htotal; /* allow blank to wrap around */
SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);
SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,
((htmp + currentTiming->width - 2) % currentTiming->htotal));
DBE_SETREG(vt_hpixen, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,
currentTiming->vblank_start);
SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,
currentTiming->vblank_end);
DBE_SETREG(vt_vpixen, outputVal);
// Turn off mouse cursor
regs->crs_ctl = 0;
// XXX What's this section for??
DBE_GETREG(ctrlstat, readVal);
readVal &= 0x02000000;
if (readVal != 0)
{
DBE_SETREG(ctrlstat, 0x30000000);
}
}
static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
struct fb_var_screeninfo *var)
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, sgivwfb_name);
fix->smem_start = sgivwfb_mem_phys;
fix->smem_len = sgivwfb_mem_size;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
switch (var->bits_per_pixel) {
case 8:
fix->visual = FB_VISUAL_PSEUDOCOLOR;
break;
default:
fix->visual = FB_VISUAL_TRUECOLOR;
break;
}
fix->ywrapstep = ywrap;
fix->xpanstep = 0;
fix->ypanstep = ypan;
fix->line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
fix->mmio_start = DBE_REG_PHYS;
fix->mmio_len = DBE_REG_SIZE;
} }
/* /*
* Read a single color register and split it into * Set the hardware according to 'par'.
* colors/transparent. Return != 0 for invalid regno.
*/ */
static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, static int sgivwfb_set_par(struct fb_info *info)
u_int *transp, struct fb_info *info)
{ {
if (regno > 255) struct sgivw_par *par = info->par;
return 1; int i, j, htmp, temp;
u32 readVal, outputVal;
*red = palette[regno].red << 8; int wholeTilesX, maxPixelsPerTileX;
*green = palette[regno].green << 8; int frmWrite1, frmWrite2, frmWrite3b;
*blue = palette[regno].blue << 8; dbe_timing_info_t *currentTiming; /* Current Video Timing */
*transp = 0; int xpmax, ypmax; // Monitor resolution
return 0; int bytesPerPixel; // Bytes per pixel
currentTiming = &dbeVTimings[par->timing_num];
bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel);
xpmax = currentTiming->width;
ypmax = currentTiming->height;
/* dbe_InitGraphicsBase(); */
/* Turn on dotclock PLL */
DBE_SETREG(ctrlstat, 0x20000000);
dbe_TurnOffDma();
/* dbe_CalculateScreenParams(); */
maxPixelsPerTileX = 512 / bytesPerPixel;
wholeTilesX = xpmax / maxPixelsPerTileX;
if (wholeTilesX * maxPixelsPerTileX < xpmax)
wholeTilesX++;
printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
maxPixelsPerTileX, wholeTilesX);
/* dbe_InitGammaMap(); */
udelay(10);
for (i = 0; i < 256; i++) {
DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8));
}
/* dbe_TurnOn(); */
DBE_GETREG(vt_xy, readVal);
if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) {
DBE_SETREG(vt_xy, 0x00000000);
udelay(1);
} else
dbe_TurnOffDma();
/* dbe_Initdbe(); */
for (i = 0; i < 256; i++) {
for (j = 0; j < 100; j++) {
DBE_GETREG(cm_fifo, readVal);
if (readVal != 0x00000000)
break;
else
udelay(10);
}
// DBE_ISETREG(cmap, i, 0x00000000);
DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24));
}
/* dbe_InitFramebuffer(); */
frmWrite1 = 0;
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1,
wholeTilesX);
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);
switch (bytesPerPixel) {
case 1:
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
DBE_FRM_DEPTH_8);
break;
case 2:
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
DBE_FRM_DEPTH_16);
break;
case 4:
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
DBE_FRM_DEPTH_32);
break;
}
frmWrite2 = 0;
SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax);
// Tell dbe about the framebuffer location and type
// XXX What format is the FRM_TILE_PTR?? 64K aligned address?
frmWrite3b = 0;
SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b,
sgivwfb_mem_phys >> 9);
SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);
SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);
/* Initialize DIDs */
outputVal = 0;
switch (bytesPerPixel) {
case 1:
SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
break;
case 2:
SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
break;
case 4:
SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
break;
}
SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);
for (i = 0; i < 32; i++) {
DBE_ISETREG(mode_regs, i, outputVal);
}
/* dbe_InitTiming(); */
DBE_SETREG(vt_intr01, 0xffffffff);
DBE_SETREG(vt_intr23, 0xffffffff);
DBE_GETREG(dotclock, readVal);
DBE_SETREG(dotclock, readVal & 0xffff);
DBE_SETREG(vt_xymax, 0x00000000);
outputVal = 0;
SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal,
currentTiming->vsync_start);
SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal,
currentTiming->vsync_end);
DBE_SETREG(vt_vsync, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal,
currentTiming->hsync_start);
SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal,
currentTiming->hsync_end);
DBE_SETREG(vt_hsync, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal,
currentTiming->vblank_start);
SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal,
currentTiming->vblank_end);
DBE_SETREG(vt_vblank, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal,
currentTiming->hblank_start);
SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal,
currentTiming->hblank_end - 3);
DBE_SETREG(vt_hblank, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal,
currentTiming->vblank_start);
SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal,
currentTiming->vblank_end);
DBE_SETREG(vt_vcmap, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal,
currentTiming->hblank_start);
SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal,
currentTiming->hblank_end - 3);
DBE_SETREG(vt_hcmap, outputVal);
outputVal = 0;
temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
if (temp > 0)
temp = -temp;
SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp);
if (currentTiming->hblank_end >= 20)
SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
currentTiming->hblank_end - 20);
else
SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,
currentTiming->htotal - (20 -
currentTiming->
hblank_end));
DBE_SETREG(did_start_xy, outputVal);
outputVal = 0;
SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal,
(u32) (temp + 1));
if (currentTiming->hblank_end >= DBE_CRS_MAGIC)
SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
currentTiming->hblank_end - DBE_CRS_MAGIC);
else
SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,
currentTiming->htotal - (DBE_CRS_MAGIC -
currentTiming->
hblank_end));
DBE_SETREG(crs_start_xy, outputVal);
outputVal = 0;
SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp);
SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
currentTiming->hblank_end - 4);
DBE_SETREG(vc_start_xy, outputVal);
DBE_SETREG(frm_size_tile, frmWrite1);
DBE_SETREG(frm_size_pixel, frmWrite2);
outputVal = 0;
SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1);
SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1);
SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);
SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);
DBE_SETREG(dotclock, outputVal);
udelay(11 * 1000);
DBE_SETREG(vt_vpixen, 0xffffff);
DBE_SETREG(vt_hpixen, 0xffffff);
outputVal = 0;
SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);
SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);
DBE_SETREG(vt_xymax, outputVal);
outputVal = frmWrite1;
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);
DBE_SETREG(frm_size_tile, outputVal);
DBE_SETREG(frm_size_tile, frmWrite1);
outputVal = 0;
SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);
DBE_SETREG(ovr_width_tile, outputVal);
DBE_SETREG(ovr_width_tile, 0);
DBE_SETREG(frm_control, frmWrite3b);
DBE_SETREG(did_control, 0);
// Wait for dbe to take frame settings
for (i = 0; i < 100000; i++) {
DBE_GETREG(frm_inhwctrl, readVal);
if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) !=
0)
break;
else
udelay(1);
}
if (i == 100000)
printk(KERN_INFO
"sgivwfb: timeout waiting for frame DMA enable.\n");
outputVal = 0;
htmp = currentTiming->hblank_end - 19;
if (htmp < 0)
htmp += currentTiming->htotal; /* allow blank to wrap around */
SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);
SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,
((htmp + currentTiming->width -
2) % currentTiming->htotal));
DBE_SETREG(vt_hpixen, outputVal);
outputVal = 0;
SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,
currentTiming->vblank_start);
SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,
currentTiming->vblank_end);
DBE_SETREG(vt_vpixen, outputVal);
// Turn off mouse cursor
par->regs->crs_ctl = 0;
// XXX What's this section for??
DBE_GETREG(ctrlstat, readVal);
readVal &= 0x02000000;
if (readVal != 0) {
DBE_SETREG(ctrlstat, 0x30000000);
}
return 0;
} }
/* /*
...@@ -530,307 +639,64 @@ static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, ...@@ -530,307 +639,64 @@ static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
* entries in the var structure). Return != 0 for invalid regno. * entries in the var structure). Return != 0 for invalid regno.
*/ */
static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
u_int transp, struct fb_info *info) u_int blue, u_int transp,
struct fb_info *info)
{ {
if (regno > 255) struct sgivw_par *par = (struct sgivw_par *) info->par;
return 1;
red >>= 8;
green >>= 8;
blue >>= 8;
palette[regno].red = red;
palette[regno].green = green;
palette[regno].blue = blue;
/* wait for the color map FIFO to have a free entry */
while (cmap_fifo == 0)
cmap_fifo = regs->cm_fifo;
regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
cmap_fifo--; /* assume FIFO is filling up */
return 0;
}
/* ---------------------------------------------------- */ if (regno > 255)
return 1;
red >>= 8;
green >>= 8;
blue >>= 8;
/* /* wait for the color map FIFO to have a free entry */
* Get the Fixed Part of the Display while (par->cmap_fifo == 0)
*/ par->cmap_fifo = par->regs->cm_fifo;
static int sgivwfb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info)
{
struct fb_var_screeninfo *var;
if (con == -1)
var = &par_current.var;
else
var = &fb_display[con].var;
sgivwfb_encode_fix(fix, var);
return 0;
}
/* par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
* Get the User Defined Part of the Display. If a real par get it form there par->cmap_fifo--; /* assume FIFO is filling up */
*/ return 0;
static int sgivwfb_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
if (con == -1)
*var = par_current.var;
else
*var = fb_display[con].var;
return 0;
}
/*
* Set the User Defined Part of the Display. Again if par use it to get
* real video mode.
*/
static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
int err, activate = var->activate;
int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
u_long line_length;
u_long min_mode;
int req_dot;
int test_mode;
struct dbe_timing_info *timing;
struct display *display;
if (con >= 0)
display = &fb_display[con];
else
display = &disp; /* used during initialization */
/*
* FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
* as FB_VMODE_SMOOTH_XPAN is only used internally
*/
if (var->vmode & FB_VMODE_CONUPDATE) {
var->vmode |= FB_VMODE_YWRAP;
var->xoffset = display->var.xoffset;
var->yoffset = display->var.yoffset;
}
/* XXX FIXME - forcing var's */
var->xoffset = 0;
var->yoffset = 0;
/* Limit bpp to 8, 16, and 32 */
if (var->bits_per_pixel <= 8)
var->bits_per_pixel = 8;
else if (var->bits_per_pixel <= 16)
var->bits_per_pixel = 16;
else if (var->bits_per_pixel <= 32)
var->bits_per_pixel = 32;
else
return -EINVAL;
var->grayscale = 0; /* No grayscale for now */
/* determine valid resolution and timing */
for (min_mode=0; min_mode<DBE_VT_SIZE; min_mode++) {
if (dbeVTimings[min_mode].width >= var->xres &&
dbeVTimings[min_mode].height >= var->yres)
break;
}
if (min_mode == DBE_VT_SIZE)
return -EINVAL; /* Resolution to high */
/* XXX FIXME - should try to pick best refresh rate */
/* for now, pick closest dot-clock within 3MHz*/
#error "Floating point not allowed in kernel"
req_dot = (int)((1.0e3/1.0e6) / (1.0e-12 * (float)var->pixclock));
printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n", var->pixclock,
req_dot);
test_mode=min_mode;
while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
if (dbeVTimings[test_mode].cfreq+3000 > req_dot)
break;
test_mode++;
}
if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
test_mode--;
min_mode = test_mode;
timing = &dbeVTimings[min_mode];
printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
/* Adjust virtual resolution, if necessary */
if (var->xres > var->xres_virtual || (!ywrap && !ypan))
var->xres_virtual = var->xres;
if (var->yres > var->yres_virtual || (!ywrap && !ypan))
var->yres_virtual = var->yres;
/*
* Memory limit
*/
line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
if (line_length*var->yres_virtual > sgivwfb_mem_size)
return -ENOMEM; /* Virtual resolution to high */
switch (var->bits_per_pixel)
{
case 8:
var->red.offset = 0;
var->red.length = 8;
var->green.offset = 0;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
case 16: /* RGBA 5551 */
var->red.offset = 11;
var->red.length = 5;
var->green.offset = 6;
var->green.length = 5;
var->blue.offset = 1;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break;
case 32: /* RGB 8888 */
var->red.offset = 0;
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
var->blue.offset = 16;
var->blue.length = 8;
var->transp.offset = 24;
var->transp.length = 8;
break;
}
var->red.msb_right = 0;
var->green.msb_right = 0;
var->blue.msb_right = 0;
var->transp.msb_right = 0;
/* set video timing information */
var->pixclock = (__u32)(1.0e+9/(float)timing->cfreq);
var->left_margin = timing->htotal - timing->hsync_end;
var->right_margin = timing->hsync_start - timing->width;
var->upper_margin = timing->vtotal - timing->vsync_end;
var->lower_margin = timing->vsync_start - timing->height;
var->hsync_len = timing->hsync_end - timing->hsync_start;
var->vsync_len = timing->vsync_end - timing->vsync_start;
if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
oldxres = display->var.xres;
oldyres = display->var.yres;
oldvxres = display->var.xres_virtual;
oldvyres = display->var.yres_virtual;
oldbpp = display->var.bits_per_pixel;
display->var = *var;
par_current.var = *var;
par_current.timing_num = min_mode;
if (oldxres != var->xres || oldyres != var->yres ||
oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
oldbpp != var->bits_per_pixel || !par_current.valid) {
struct fb_fix_screeninfo fix;
printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
var->xres, var->yres, var->bits_per_pixel);
printk(KERN_INFO " vxres=%d vyres=%d\n",
var->xres_virtual, var->yres_virtual);
activate_par(&par_current);
sgivwfb_encode_fix(&fix, var);
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
display->ypanstep = fix.ypanstep;
display->ywrapstep = fix.ywrapstep;
display->line_length = fix.line_length;
display->can_soft_blank = 1;
display->inverse = 0;
if (oldbpp != var->bits_per_pixel || !par_current.valid) {
if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
return err;
do_install_cmap(con, info);
}
switch (var->bits_per_pixel) {
#ifdef FBCON_HAS_CFB8
case 8:
display->dispsw = &fbcon_cfb8;
break;
#endif
#ifdef FBCON_HAS_CFB16
case 16:
display->dispsw = &fbcon_cfb16;
display->dispsw_data = fbcon_cmap.cfb16;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:
display->dispsw = &fbcon_cfb32;
display->dispsw_data = fbcon_cmap.cfb32;
break;
#endif
default:
display->dispsw = &fbcon_dummy;
break;
}
par_current.valid = 1;
if (fb_info.changevar)
(*fb_info.changevar)(con);
}
}
return 0;
}
/*
* Get the Colormap
*/
static int sgivwfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
if (con == info->currcon) /* current console? */
return fb_get_cmap(cmap, kspc, sgivwfb_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(1<<fb_display[con].var.bits_per_pixel),
cmap, kspc ? 0 : 2);
return 0;
} }
static int sgivwfb_mmap(struct fb_info *info, struct file *file, static int sgivwfb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma) struct vm_area_struct *vma)
{ {
unsigned long size = vma->vm_end - vma->vm_start; unsigned long size = vma->vm_end - vma->vm_start;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
return -EINVAL; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
if (offset+size > sgivwfb_mem_size) return -EINVAL;
return -EINVAL; if (offset + size > sgivwfb_mem_size)
offset += sgivwfb_mem_phys; return -EINVAL;
pgprot_val(vma->vm_page_prot) = pgprot_val(vma->vm_page_prot) | _PAGE_PCD; offset += sgivwfb_mem_phys;
vma->vm_flags |= VM_IO; pgprot_val(vma->vm_page_prot) =
if (remap_page_range(vma, vma->vm_start, offset, size, vma->vm_page_prot)) pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
return -EAGAIN; vma->vm_flags |= VM_IO;
vma->vm_file = file; if (remap_page_range
printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", offset, vma->vm_start); (vma, vma->vm_start, offset, size, vma->vm_page_prot))
return 0; return -EAGAIN;
vma->vm_file = file;
printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
offset, vma->vm_start);
return 0;
} }
int __init sgivwfb_setup(char *options) int __init sgivwfb_setup(char *options)
{ {
char *this_opt; char *this_opt;
fb_info.fontname[0] = '\0'; fb_info.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 (!strncmp(this_opt, "font:", 5)) if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5); strcpy(fb_info.fontname, this_opt + 5);
} }
return 0; return 0;
} }
/* /*
...@@ -838,75 +704,67 @@ int __init sgivwfb_setup(char *options) ...@@ -838,75 +704,67 @@ int __init sgivwfb_setup(char *options)
*/ */
int __init sgivwfb_init(void) int __init sgivwfb_init(void)
{ {
printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n", printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
sgivwfb_mem_phys, sgivwfb_mem_size/1024); sgivwfb_mem_phys, sgivwfb_mem_size / 1024);
regs = (asregs*)ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE); default_par.regs = (asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
if (!regs) { if (!default_par.regs) {
printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n"); printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
goto fail_ioremap_regs; goto fail_ioremap_regs;
} }
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
mtrr_add((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1); mtrr_add((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size,
MTRR_TYPE_WRCOMB, 1);
#endif #endif
strcpy(fb_info.modename, sgivwfb_name); sgivwfb_fix.smem_start = sgivwfb_mem_phys;
fb_info.changevar = NULL; sgivwfb_fix.smem_len = sgivwfb_mem_size;
fb_info.node = NODEV; sgivwfb_fix.ywrapstep = ywrap;
fb_info.fbops = &sgivwfb_ops; sgivwfb_fix.ypanstep = ypan;
fb_info.disp = &disp;
fb_info.currcon = -1; strcpy(fb_info.modename, sgivwfb_fix.id);
fb_info.switch_con = &sgivwfbcon_switch; fb_info.changevar = NULL;
fb_info.updatevar = &sgivwfbcon_updatevar; fb_info.node = NODEV;
fb_info.flags = FBINFO_FLAG_DEFAULT; fb_info.fix = sgivwfb_fix;
fb_info.var = sgivwfb_var;
fb_info.screen_base = ioremap_nocache((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size); fb_info.fbops = &sgivwfb_ops;
if (!fb_info.screen_base) { fb_info.pseudo_palette = pseudo_palette;
printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n"); fb_info.par = &default_par;
goto fail_ioremap_fbmem; fb_info.disp = &disp;
} fb_info.currcon = -1;
fb_info.switch_con = gen_switch;
/* turn on default video mode */ fb_info.updatevar = gen_update_var;
sgivwfb_set_var(&par_current.var, -1, &fb_info); fb_info.flags = FBINFO_FLAG_DEFAULT;
if (register_framebuffer(&fb_info) < 0) { fb_info.screen_base =
printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n"); ioremap_nocache((unsigned long) sgivwfb_mem_phys,
goto fail_register_framebuffer; sgivwfb_mem_size);
} if (!fb_info.screen_base) {
printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
printk(KERN_INFO "fb%d: Virtual frame buffer device, using %ldK of video memory\n", goto fail_ioremap_fbmem;
GET_FB_IDX(fb_info.node), sgivwfb_mem_size>>10); }
return 0; /* turn on default video mode */
gen_set_var(&fb_info->var, -1, &fb_info);
fail_register_framebuffer:
iounmap((char*)fb_info.screen_base); if (register_framebuffer(&fb_info) < 0) {
fail_ioremap_fbmem: printk(KERN_ERR
iounmap(regs); "sgivwfb: couldn't register framebuffer\n");
fail_ioremap_regs: goto fail_register_framebuffer;
return -ENXIO; }
}
printk(KERN_INFO
static int sgivwfbcon_switch(int con, struct fb_info *info) "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
{ GET_FB_IDX(fb_info.node), sgivwfb_mem_size >> 10);
/* Do we have to save the colormap? */
if (fb_display[info->currcon].cmap.len) return 0;
fb_get_cmap(&fb_display[info->currcon].cmap, 1, sgivwfb_getcolreg, info);
fail_register_framebuffer:
info->currcon = con; iounmap((char *) fb_info.screen_base);
/* Install new colormap */ fail_ioremap_fbmem:
do_install_cmap(con, info); iounmap(default_par.regs);
return 0; fail_ioremap_regs:
} return -ENXIO;
/*
* Update the `var' structure (called by fbcon.c)
*/
static int sgivwfbcon_updatevar(int con, struct fb_info *info)
{
/* Nothing */
return 0;
} }
#ifdef MODULE #ifdef MODULE
...@@ -914,15 +772,15 @@ MODULE_LICENSE("GPL"); ...@@ -914,15 +772,15 @@ MODULE_LICENSE("GPL");
int init_module(void) int init_module(void)
{ {
return sgivwfb_init(); return sgivwfb_init();
} }
void cleanup_module(void) void cleanup_module(void)
{ {
unregister_framebuffer(&fb_info); unregister_framebuffer(&fb_info);
dbe_TurnOffDma(); dbe_TurnOffDma();
iounmap(regs); iounmap(regs);
iounmap(&fb_info.screen_base); iounmap(&fb_info.screen_base);
} }
#endif /* MODULE */ #endif /* MODULE */
...@@ -325,7 +325,7 @@ int __init tx3912fb_init(void) ...@@ -325,7 +325,7 @@ int __init tx3912fb_init(void)
return 0; return 0;
} }
int __init tx3912fb_setup(char *options) void __init tx3912fb_setup(char *options)
{ {
char *this_opt; char *this_opt;
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
static struct fb_var_screeninfo vesafb_defined = { static struct fb_var_screeninfo vesafb_defined __initdata = {
activate: FB_ACTIVATE_NOW, activate: FB_ACTIVATE_NOW,
height: -1, height: -1,
width: -1, width: -1,
...@@ -43,7 +43,7 @@ static struct fb_var_screeninfo vesafb_defined = { ...@@ -43,7 +43,7 @@ static struct fb_var_screeninfo vesafb_defined = {
vmode: FB_VMODE_NONINTERLACED, vmode: FB_VMODE_NONINTERLACED,
}; };
static struct fb_fix_screeninfo vesafb_fix = { static struct fb_fix_screeninfo vesafb_fix __initdata = {
id: "VESA VGA", id: "VESA VGA",
type: FB_TYPE_PACKED_PIXELS, type: FB_TYPE_PACKED_PIXELS,
accel: FB_ACCEL_NONE, accel: FB_ACCEL_NONE,
......
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