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
This is the low level frame buffer console driver for Hercules mono
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
tristate ' Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
# tristate ' Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16
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
else
# Guess what we need
......@@ -256,7 +255,7 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "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_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
......@@ -265,13 +264,12 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_SGIVW" = "y" ]; then
"$CONFIG_FB_P9100" = "y" ]; then
define_tristate CONFIG_FBCON_CFB8 y
else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "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_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
......@@ -280,8 +278,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" ]; then
"$CONFIG_FB_P9100" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m
fi
fi
......@@ -293,8 +290,8 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_PM3" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_PM3" = "y" ]; then
define_tristate CONFIG_FBCON_CFB16 y
else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
......@@ -305,8 +302,8 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_CYBER2000" = "y" ]; then
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_SIS" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m
fi
fi
......@@ -333,8 +330,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_RADEON" = "y" ]; then
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_RADEON" = "y" ]; then
define_tristate CONFIG_FBCON_CFB32 y
else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
......@@ -343,8 +339,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
"$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" ]; then
"$CONFIG_FB_PM3" = "m" -o "$CONFIG_FB_RADEON" = "m" ]; then
define_tristate CONFIG_FBCON_CFB32 m
fi
fi
......@@ -357,13 +352,15 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
"$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "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
else
if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
"$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "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
fi
fi
......
......@@ -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_CYBER) += cyberfb.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_MAC) += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_HP300) += hpfb.o cfbfillrect.o cfbimgblt.o
......@@ -115,7 +115,6 @@ obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o
obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.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_STI) += fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
......
/*
* ATI Frame Buffer Device Driver Core Definitions
*/
......@@ -89,19 +88,14 @@ struct aty_cursor {
struct fb_info_aty {
struct fb_info fb_info;
struct fb_info_aty *next;
unsigned long ati_regbase_phys;
unsigned long ati_regbase;
unsigned long frame_buffer_phys;
unsigned long frame_buffer;
unsigned long clk_wr_offset;
struct pci_mmap_map *mmap_map;
struct aty_cursor *cursor;
struct aty_cmap_regs *aty_cmap_regs;
struct { u8 red, green, blue, pad; } palette[256];
struct atyfb_par default_par;
struct atyfb_par current_par;
u32 features;
u32 total_vram;
u32 ref_clk_per;
u32 pll_per;
u32 mclk_per;
......@@ -110,19 +104,7 @@ struct fb_info_aty {
u8 mem_refresh_rate;
const struct aty_dac_ops *dac_ops;
const struct aty_pll_ops *pll_ops;
struct display disp;
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;
#ifdef __sparc__
u8 mmaped;
......
......@@ -71,7 +71,7 @@
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include "mach64.h"
#include <video/mach64.h>
#include "atyfb.h"
#ifdef __powerpc__
......@@ -133,6 +133,15 @@ struct pci_mmap_map {
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
......@@ -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,
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,
u_long arg, int con, struct fb_info *info);
#ifdef __sparc__
......@@ -168,7 +173,6 @@ static int atyfb_rasterimg(struct fb_info *info, int start);
* 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);
/*
......@@ -203,8 +207,6 @@ static int encode_fix(struct fb_fix_screeninfo *fix,
const struct fb_info_aty *info);
static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
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
static int read_aty_sense(const struct fb_info_aty *info);
#endif
......@@ -226,8 +228,8 @@ static struct fb_ops atyfb_ops = {
fb_get_fix: atyfb_get_fix,
fb_get_var: atyfb_get_var,
fb_set_var: atyfb_set_var,
fb_get_cmap: atyfb_get_cmap,
fb_set_cmap: atyfb_set_cmap,
fb_get_cmap: gen_get_cmap,
fb_set_cmap: gen_set_cmap,
fb_setcolreg: atyfb_setcolreg,
fb_pan_display: atyfb_pan_display,
fb_blank: atyfb_blank,
......@@ -362,6 +364,8 @@ static char ram_wram[] __initdata = "WRAM";
static char ram_off[] __initdata = "OFF";
static char ram_resv[] __initdata = "RESV";
static u32 pseudo_palette[17];
#ifdef CONFIG_FB_ATY_GX
static char *aty_gx_ram[8] __initdata = {
ram_dram, ram_vram, ram_vram, ram_dram,
......@@ -552,7 +556,7 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
} else
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");
if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
......@@ -796,7 +800,7 @@ static void atyfb_set_par(const struct atyfb_par *par,
aty_init_engine(par, info);
#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.v_tot_disp>>16) & 0x7ff)+1,
par->crtc.bpp,
......@@ -922,7 +926,7 @@ static int atyfb_release(struct fb_info *info, int user)
else
var.accel_flags |= FB_ACCELF_TEXT;
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.xres_virtual;
if (var.yres_virtual < var.yres)
......@@ -946,30 +950,11 @@ static int encode_fix(struct fb_fix_screeninfo *fix,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, atyfb_name);
fix->smem_start = info->frame_buffer_phys;
fix->smem_len = (u32)info->total_vram;
/*
* Reg Block 0 (CT-compatible block) is at ati_regbase_phys
* 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->smem_start = info->fb_info.fix.smem_start;
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;
fix->accel = info->fb_info.fix.accel;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
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,
case 16:
info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;
disp->dispsw = &info->dispsw;
disp->dispsw_data = info->fbcon_cmap.cfb16;
disp->dispsw_data = info->fb_info.pseudo_palette;
break;
#endif
#ifdef FBCON_HAS_CFB24
case 24:
info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;
disp->dispsw = &info->dispsw;
disp->dispsw_data = info->fbcon_cmap.cfb24;
disp->dispsw_data = info->fb_info.pseudo_palette;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:
info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;
disp->dispsw = &info->dispsw;
disp->dispsw_data = info->fbcon_cmap.cfb32;
disp->dispsw_data = info->fb_info.pseudo_palette;
break;
#endif
default:
......@@ -1100,7 +1085,6 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_fix_screeninfo fix;
encode_fix(&fix, &par, info);
fb->screen_base = (char *)info->frame_buffer;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
......@@ -1157,51 +1141,6 @@ static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
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
#define ATYIO_CLKR 0x41545900 /* ATY\00 */
#define ATYIO_CLKW 0x41545901 /* ATY\01 */
......@@ -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_depth = info->current_par.crtc.bpp;
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)))
return -EFAULT;
break;
......@@ -1344,8 +1283,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
/* To stop the swapper from even considering these pages. */
vma->vm_flags |= (VM_SHM | VM_LOCKED);
if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) ||
((off == fb->total_vram) && (size == PAGE_SIZE)))
if (((vma->vm_pgoff == 0) && (size == fb->fb_info.fix.smem_len)) ||
((off == fb->fb_info.fix.smem_len) && (size == PAGE_SIZE)))
off += 0x8000000000000000UL;
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)
/* Backup fb content */
if (info->save_framebuffer)
memcpy_fromio(info->save_framebuffer,
(void *)info->frame_buffer, nb);
(void *)info->fb_info.screen_base, nb);
/* Blank display and LCD */
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)
/* Restore fb content */
if (info->save_framebuffer) {
memcpy_toio((void *)info->frame_buffer,
memcpy_toio((void *)info->fb_info.screen_base,
info->save_framebuffer, nb);
vfree(info->save_framebuffer);
info->save_framebuffer = 0;
......@@ -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)
{
u32 chip_id;
u32 i;
int j, k;
u32 chip_id, i;
struct fb_var_screeninfo var;
struct display *disp;
u16 type;
u8 rev;
const char *chipname = NULL, *ramname = NULL, *xtal;
int pll, mclk, gtb_memsize;
int j, pll, mclk, gtb_memsize;
#if defined(CONFIG_PPC)
int sense;
#endif
......@@ -1843,80 +1780,101 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
if (gtb_memsize)
switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
case MEM_SIZE_512K:
info->total_vram = 0x80000;
info->fb_info.fix.smem_len = 0x80000;
break;
case MEM_SIZE_1M:
info->total_vram = 0x100000;
info->fb_info.fix.smem_len = 0x100000;
break;
case MEM_SIZE_2M_GTB:
info->total_vram = 0x200000;
info->fb_info.fix.smem_len = 0x200000;
break;
case MEM_SIZE_4M_GTB:
info->total_vram = 0x400000;
info->fb_info.fix.smem_len = 0x400000;
break;
case MEM_SIZE_6M_GTB:
info->total_vram = 0x600000;
info->fb_info.fix.smem_len = 0x600000;
break;
case MEM_SIZE_8M_GTB:
info->total_vram = 0x800000;
info->fb_info.fix.smem_len = 0x800000;
break;
default:
info->total_vram = 0x80000;
info->fb_info.fix.smem_len = 0x80000;
}
else
switch (i & MEM_SIZE_ALIAS) {
case MEM_SIZE_512K:
info->total_vram = 0x80000;
info->fb_info.fix.smem_len = 0x80000;
break;
case MEM_SIZE_1M:
info->total_vram = 0x100000;
info->fb_info.fix.smem_len = 0x100000;
break;
case MEM_SIZE_2M:
info->total_vram = 0x200000;
info->fb_info.fix.smem_len = 0x200000;
break;
case MEM_SIZE_4M:
info->total_vram = 0x400000;
info->fb_info.fix.smem_len = 0x400000;
break;
case MEM_SIZE_6M:
info->total_vram = 0x600000;
info->fb_info.fix.smem_len = 0x600000;
break;
case MEM_SIZE_8M:
info->total_vram = 0x800000;
info->fb_info.fix.smem_len = 0x800000;
break;
default:
info->total_vram = 0x80000;
info->fb_info.fix.smem_len = 0x80000;
}
if (M64_HAS(MAGIC_VRAM_SIZE)) {
if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000)
info->total_vram += 0x400000;
info->fb_info.fix.smem_len += 0x400000;
}
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);
if (info->total_vram <= 0x80000)
if (info->fb_info.fix.smem_len <= 0x80000)
i |= MEM_SIZE_512K;
else if (info->total_vram <= 0x100000)
else if (info->fb_info.fix.smem_len <= 0x100000)
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;
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;
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;
else
i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
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)
pll = default_pll;
if (default_mclk)
mclk = default_mclk;
printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20),
info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
info->fb_info.fix.smem_len == 0x80000 ? 512 : (info->fb_info.fix.smem_len >> 20),
info->fb_info.fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
if (mclk < 44)
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)
* FIXME: we should use the auxiliary aperture instead so we can access
* the full 8 MB of video RAM on 8 MB boards
*/
if (info->total_vram == 0x800000 ||
(info->bus_type == ISA && info->total_vram == 0x400000))
info->total_vram -= GUI_RESERVE;
if (info->fb_info.fix.smem_len == 0x800000 ||
(info->bus_type == ISA && info->fb_info.fix.smem_len == 0x400000))
info->fb_info.fix.smem_len -= GUI_RESERVE;
/* 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);
info->fb_info.node = NODEV;
info->fb_info.fbops = &atyfb_ops;
info->fb_info.disp = disp;
info->fb_info.pseudo_palette = pseudo_palette;
info->fb_info.currcon = -1;
strcpy(info->fb_info.fontname, fontname);
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.flags = FBINFO_FLAG_DEFAULT;
......@@ -2058,7 +2017,7 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
var.accel_flags |= FB_ACCELF_TEXT;
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;
if (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)
#ifdef __sparc__
atyfb_save_palette(&info->fb_info, 0);
#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
if (curblink && M64_HAS(INTEGRATED)) {
......@@ -2088,6 +2041,9 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
}
}
#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);
......@@ -2134,12 +2090,14 @@ int __init atyfb_init(void)
if (i < 0)
continue;
info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
info = kmalloc(sizeof(struct fb_info_aty) + sizeof(struct display), GFP_ATOMIC);
if (!info) {
printk("atyfb_init: can't alloc fb_info_aty\n");
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];
if (rp->flags & IORESOURCE_IO)
......@@ -2158,13 +2116,13 @@ int __init atyfb_init(void)
* Map memory-mapped registers.
*/
info->ati_regbase = addr + 0x7ffc00UL;
info->ati_regbase_phys = addr + 0x7ffc00UL;
info->fb_info.fix.mmio_start = addr + 0x7ffc00UL;
/*
* Map in big-endian aperture.
*/
info->frame_buffer = (unsigned long) addr + 0x800000UL;
info->frame_buffer_phys = addr + 0x800000UL;
info->fb_info.screen_base = (unsigned long) addr + 0x800000UL;
info->fb_info.fix.smem_start = addr + 0x800000UL;
/*
* Figure mmap addresses from PCI config space.
......@@ -2358,9 +2316,9 @@ int __init atyfb_init(void)
}
#else /* __sparc__ */
info->ati_regbase_phys = 0x7ff000 + addr;
info->fb_info.fix.mmio_start = 0x7ff000 + addr;
info->ati_regbase = (unsigned long)
ioremap(info->ati_regbase_phys, 0x1000);
ioremap(info->fb_info.fix.mmio_start, 0x1000);
if(!info->ati_regbase) {
kfree(info);
......@@ -2368,7 +2326,7 @@ int __init atyfb_init(void)
return -ENOMEM;
}
info->ati_regbase_phys += 0xc00;
info->fb_info.fix.mmio_start += 0xc00;
info->ati_regbase += 0xc00;
/*
......@@ -2387,10 +2345,10 @@ int __init atyfb_init(void)
#endif
/* Map in frame buffer */
info->frame_buffer_phys = addr;
info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
info->fb_info.fix.smem_start = addr;
info->fb_info.screen_base = (char*)ioremap(addr, 0x800000);
if(!info->frame_buffer) {
if(!info->fb_info.screen_base) {
kfree(info);
release_mem_region(res_start, res_size);
return -ENXIO;
......@@ -2414,11 +2372,11 @@ int __init atyfb_init(void)
* Add /dev/fb mmap values.
*/
info->mmap_map[0].voff = 0x8000000000000000UL;
info->mmap_map[0].poff = info->frame_buffer & PAGE_MASK;
info->mmap_map[0].size = info->total_vram;
info->mmap_map[0].poff = info->fb_info.screen_base & PAGE_MASK;
info->mmap_map[0].size = info->fb_info.fix.smem_len;
info->mmap_map[0].prot_mask = _PAGE_CACHE;
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].size = PAGE_SIZE;
info->mmap_map[1].prot_mask = _PAGE_CACHE;
......@@ -2458,10 +2416,10 @@ int __init atyfb_init(void)
* Map the video memory (physical address given) to somewhere in the
* kernel address space.
*/
info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
info->frame_buffer_phys = info->frame_buffer; /* Fake! */
info->fb_info.screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
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_phys = info->ati_regbase; /* Fake! */
info->fb_info.fix.mmio_start = info->ati_regbase; /* Fake! */
aty_st_le32(CLOCK_CNTL, 0x12345678, 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)
}
#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
/* Erase HW Cursor */
* Erase HW Cursor *
if (info->cursor && (fb->currcon >= 0))
atyfb_cursor(&fb_display[fb->currcon], CM_ERASE,
info->cursor->pos.x, info->cursor->pos.y);
#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);
#endif * CONFIG_FB_ATY_CT *
#ifdef CONFIG_FB_ATY_CT
/* Install hw cursor */
* Install hw cursor *
if (info->cursor) {
aty_set_cursor_color(info);
aty_set_cursor_shape(info);
}
#endif /* CONFIG_FB_ATY_CT */
return 1;
}
#endif * CONFIG_FB_ATY_CT */
/*
* Blank the display.
......@@ -2673,27 +2611,6 @@ static int atyfb_blank(int blank, struct fb_info *fb)
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
* 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,
red >>= 8;
green >>= 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;
if (M64_HAS(EXTRA_BRIGHT))
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,
switch (info->current_par.crtc.bpp) {
#ifdef FBCON_HAS_CFB16
case 16:
info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
regno;
((u16 *) (info->fb_info.pseudo_palette))[regno] = (regno << 10) | (regno << 5) | regno;
break;
#endif
#ifdef FBCON_HAS_CFB24
case 24:
info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
regno;
((u32 *) (info->fb_info.pseudo_palette))[regno] = (regno << 16) | (regno << 8) | regno;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:
i = (regno << 8) | regno;
info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
((u32 *) (info->fb_info.pseudo_palette))[regno] = (i << 16) | i;
break;
#endif
}
......@@ -2815,8 +2727,8 @@ void cleanup_module(void)
#ifndef __sparc__
if (info->ati_regbase)
iounmap((void *)info->ati_regbase);
if (info->frame_buffer)
iounmap((void *)info->frame_buffer);
if (info->fb_info.screen_base)
iounmap((void *)info->fb_info.screen_base);
#ifdef __BIG_ENDIAN
if (info->cursor && info->cursor->ram)
iounmap(info->cursor->ram);
......
......@@ -13,7 +13,7 @@
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include "mach64.h"
#include <video/mach64.h>
#include "atyfb.h"
/*
......
......@@ -9,7 +9,7 @@
#include <video/fbcon.h>
#include "mach64.h"
#include <video/mach64.h>
#include "atyfb.h"
......@@ -73,7 +73,7 @@ static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
/* fifo_off<<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) {
/* >1 MB SDRAM */
dsp_loop_latency += 8;
......
......@@ -18,7 +18,7 @@
#include <asm/fbio.h>
#endif
#include "mach64.h"
#include <video/mach64.h>
#include "atyfb.h"
......@@ -242,18 +242,18 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
memset(cursor->timer, 0, sizeof(*cursor->timer));
cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
fb->total_vram -= PAGE_SIZE;
cursor->offset = fb->total_vram;
fb->fb_info.fix.smem_len -= PAGE_SIZE;
cursor->offset = fb->fb_info.fix.smem_len;
#ifdef __sparc__
addr = fb->frame_buffer - 0x800000 + cursor->offset;
addr = fb->fb_info.screen_base - 0x800000 + cursor->offset;
cursor->ram = (u8 *)addr;
#else
#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);
#else
addr = fb->frame_buffer + cursor->offset;
addr = (unsigned long) fb->fb_info.screen_base + cursor->offset;
cursor->ram = (u8 *)addr;
#endif
#endif
......
......@@ -11,7 +11,7 @@
#include <video/fbcon.h>
#include "mach64.h"
#include <video/mach64.h>
#include "atyfb.h"
/* 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 @@
#include <video/fbcon-cfb32.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)
{
*fix = info->fix;
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)
{
*var = info->var;
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 err;
......@@ -191,75 +76,12 @@ int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
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)
{
fb_copy_cmap (&info->cmap, cmap, kspc ? 0 : 2);
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,
struct fb_info *info)
{
......@@ -285,21 +107,6 @@ int gen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
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,
struct fb_info *info)
{
......@@ -334,84 +141,6 @@ int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
/* ---- 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)
{
struct display *display = (con < 0) ? info->disp : (fb_display + con);
......@@ -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)
{
struct display *disp = (con < 0) ? info->disp : (fb_display + con);
......@@ -520,35 +222,6 @@ int gen_update_var(int con, struct fb_info *info)
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)
{
struct display *disp;
......@@ -622,24 +295,15 @@ int fbgen_blank(int blank, struct fb_info *info)
}
/* generic frame buffer operations */
EXPORT_SYMBOL(fbgen_get_fix);
EXPORT_SYMBOL(gen_get_fix);
EXPORT_SYMBOL(fbgen_get_var);
EXPORT_SYMBOL(gen_get_var);
EXPORT_SYMBOL(fbgen_set_var);
EXPORT_SYMBOL(gen_set_var);
EXPORT_SYMBOL(fbgen_get_cmap);
EXPORT_SYMBOL(gen_get_cmap);
EXPORT_SYMBOL(fbgen_set_cmap);
EXPORT_SYMBOL(gen_set_cmap);
EXPORT_SYMBOL(fbgen_pan_display);
/* helper functions */
EXPORT_SYMBOL(fbgen_do_set_var);
EXPORT_SYMBOL(fbgen_set_disp);
EXPORT_SYMBOL(do_install_cmap);
EXPORT_SYMBOL(fbgen_update_var);
EXPORT_SYMBOL(gen_update_var);
EXPORT_SYMBOL(fbgen_switch);
EXPORT_SYMBOL(gen_switch);
EXPORT_SYMBOL(fbgen_blank);
......
......@@ -132,7 +132,7 @@ extern int pmagbafb_init(void);
extern int pmagbbfb_init(void);
extern void maxinefb_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_setup(char*);
extern int e1355fb_init(void);
......
......@@ -34,9 +34,6 @@
#endif
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb32.h>
#include <video/macmodes.h>
/* Supported palette hacks */
......@@ -50,49 +47,27 @@ enum {
cmap_gxt2000, /* IBM GXT2000 */
};
struct fb_info_offb {
struct fb_info info;
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
struct display disp;
struct { u_char red, green, blue, pad; } palette[256];
struct offb_par {
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__
#define mach_eieio() eieio()
#else
#define mach_eieio() do {} while (0)
#endif
/*
* Interface used by the world
*/
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,
u_int transp, struct fb_info *info);
static int offb_blank(int blank, struct fb_info *info);
......@@ -102,146 +77,100 @@ extern boot_infos_t *boot_infos;
#endif
static void offb_init_nodriver(struct device_node *);
static void offb_init_fb(const char *name, const char *full_name, int width,
int height, int depth, int pitch, 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 void offb_init_fb(const char *name, const char *full_name,
int width, int height, int depth, int pitch,
unsigned long address, struct device_node *dp);
static struct fb_ops offb_ops = {
owner: THIS_MODULE,
fb_get_fix: offb_get_fix,
fb_get_var: offb_get_var,
fb_set_var: offb_set_var,
fb_get_cmap: offb_get_cmap,
fb_set_cmap: offb_set_cmap,
fb_get_fix: gen_get_fix,
fb_get_var: gen_get_var,
fb_set_var: gen_set_var,
fb_get_cmap: gen_get_cmap,
fb_set_cmap: gen_set_cmap,
fb_setcolreg: offb_setcolreg,
fb_blank: offb_blank,
fb_fillrect: cfb_fillrect,
fb_copyarea: cfb_copyarea,
fb_imageblit: cfb_imageblit,
};
/*
* Get the Fixed Part of the Display
*/
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
* 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_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
static int offb_setcolreg(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;
memcpy(var, &info2->var, sizeof(struct fb_var_screeninfo));
return 0;
}
struct offb_par *par = (struct offb_par *) info->par;
if (!par->cmap_adr || regno > 255)
return 1;
/*
* Set the User Defined Part of the Display
*/
red >>= 8;
green >>= 8;
blue >>= 8;
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);
switch (par->cmap_type) {
case cmap_m64:
*par->cmap_adr = regno;
mach_eieio();
*par->cmap_data = red;
mach_eieio();
*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;
}
return 0;
}
/*
* Get the Colormap
*/
static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
struct fb_info_offb *info2 = (struct fb_info_offb *)info;
if (con == info->currcon && !info2->blanked) /* current console? */
return fb_get_cmap(cmap, kspc, offb_getcolreg, info);
if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
else
if (regno < 16)
switch (info->var.bits_per_pixel) {
case 16:
((u16 *) (info->pseudo_palette))[regno] =
(regno << 10) | (regno << 5) | regno;
break;
case 32:
{
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
int i = (regno << 8) | regno;
((u32 *) (info->pseudo_palette))[regno] =
(i << 16) | i;
break;
}
return 0;
}
/*
* Set the Colormap
*/
static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
struct fb_info_offb *info2 = (struct fb_info_offb *)info;
int err;
if (!info2->cmap_adr)
return -ENOSYS;
if (!fb_display[con].cmap.len) { /* no colormap allocated? */
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
return err;
}
if (con == info->currcon && !info2->blanked) /* current console? */
return fb_set_cmap(cmap, kspc, info);
else
fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
return 0;
}
......@@ -251,61 +180,68 @@ static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
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;
if (!info2->cmap_adr)
if (!par->cmap_adr)
return 0;
if (!info2->blanked) {
if (!par->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;
par->blanked = blank;
if (blank)
for (i = 0; i < 256; i++) {
switch(info2->cmap_type) {
switch (par->cmap_type) {
case cmap_m64:
*info2->cmap_adr = i;
*par->cmap_adr = i;
mach_eieio();
for (j = 0; j < 3; j++) {
*info2->cmap_data = 0;
*par->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);
out_le32((unsigned *) (par->cmap_adr +
0x58),
in_le32((unsigned *) (par->
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);
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 *)(info2->cmap_adr + 0x58),
in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
out_le32((unsigned *) (par->cmap_adr +
0x58),
in_le32((unsigned *) (par->
cmap_adr +
0x58)) |
0x20);
/* Set palette index & data */
out_8(info2->cmap_adr + 0xb0, i);
out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
out_8(par->cmap_adr + 0xb0, i);
out_le32((unsigned *) (par->cmap_adr +
0xb4), 0);
break;
case cmap_radeon:
out_8(info2->cmap_adr + 0xb0, i);
out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
out_8(par->cmap_adr + 0xb0, i);
out_le32((unsigned *) (par->cmap_adr +
0xb4), 0);
break;
case cmap_gxt2000:
out_le32((unsigned *)info2->cmap_adr + i, 0);
out_le32((unsigned *) par->cmap_adr + i,
0);
break;
}
}
else
do_install_cmap(info->currcon, info);
} else
fb_set_cmap(&info->cmap, 1, info);
return 0;
}
......@@ -323,7 +259,8 @@ int __init offb_init(void)
/* If we're booted from BootX... */
if (prom_num_displays == 0 && boot_infos != 0) {
unsigned long addr = (unsigned long) boot_infos->dispDeviceBase;
unsigned long addr =
(unsigned long) boot_infos->dispDeviceBase;
/* find the device node corresponding to the macos display */
for (dp = displays; dp != NULL; dp = dp->next) {
int i;
......@@ -332,9 +269,12 @@ int __init offb_init(void)
* 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 *)
get_property(dp, "AAPL,address", NULL);
if (strncmp(dp->name, "ATY,", 4) == 0
&& dp->n_addrs == 1) {
unsigned int *ap =
(unsigned int *) get_property(dp,
"AAPL,address",
NULL);
if (ap != NULL) {
dp->addrs[0].address = *ap;
dp->addrs[0].size = 0x01000000;
......@@ -345,13 +285,17 @@ int __init offb_init(void)
* 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")) {
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)
for (na /= sizeof(unsigned int);
na > 0; --na, ++ap)
if (*ap <= addr
&& addr <
*ap + 0x1000000)
goto foundit;
}
......@@ -361,20 +305,25 @@ int __init offb_init(void)
*/
for (i = 0; i < dp->n_addrs; ++i) {
if (dp->addrs[i].address <= addr
&& addr < dp->addrs[i].address + dp->addrs[i].size)
&& 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);
printk(KERN_INFO "MacOS display is %s\n",
dp->full_name);
macos_display = dp;
break;
}
}
/* initialize it */
offb_init_fb(macos_display? macos_display->name: "MacOS display",
macos_display? macos_display->full_name: "MacOS display",
offb_init_fb(macos_display ? macos_display->
name : "MacOS display",
macos_display ? macos_display->
full_name : "MacOS display",
boot_infos->dispDeviceRect[2],
boot_infos->dispDeviceRect[3],
boot_infos->dispDeviceDepth,
......@@ -397,35 +346,38 @@ static void __init offb_init_nodriver(struct device_node *dp)
int width = 640, height = 480, depth = 8, pitch;
unsigned *up, address;
if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
if ((pp = (int *) get_property(dp, "depth", &len)) != NULL
&& len == sizeof(int))
depth = *pp;
if ((pp = (int *)get_property(dp, "width", &len)) != NULL
if ((pp = (int *) get_property(dp, "width", &len)) != NULL
&& len == sizeof(int))
width = *pp;
if ((pp = (int *)get_property(dp, "height", &len)) != NULL
if ((pp = (int *) get_property(dp, "height", &len)) != NULL
&& len == sizeof(int))
height = *pp;
if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL
&& len == sizeof(int)) {
pitch = *pp;
if (pitch == 1)
pitch = 0x1000;
} else
pitch = width;
if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
if ((up = (unsigned *) get_property(dp, "address", &len)) != NULL
&& len == sizeof(unsigned))
address = (u_long)*up;
address = (u_long) * up;
else {
for (i = 0; i < dp->n_addrs; ++i)
if (dp->addrs[i].size >= pitch*height*depth/8)
if (dp->addrs[i].size >=
pitch * height * depth / 8)
break;
if (i >= dp->n_addrs) {
printk(KERN_ERR "no framebuffer address found for %s\n", dp->full_name);
printk(KERN_ERR
"no framebuffer address found for %s\n",
dp->full_name);
return;
}
address = (u_long)dp->addrs[i].address;
address = (u_long) dp->addrs[i].address;
/* kludge for valkyrie */
if (strcmp(dp->name, "valkyrie") == 0)
......@@ -441,26 +393,30 @@ static void __init offb_init_fb(const char *name, const char *full_name,
int pitch, unsigned long address,
struct device_node *dp)
{
int i;
unsigned long res_size = pitch * height * depth / 8;
struct offb_par *par = &default_par;
unsigned long res_start = address;
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;
struct fb_info *info;
int i;
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",
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);
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);
info =
kmalloc(sizeof(struct fb_info) + sizeof(struct display) +
sizeof(u32) * 17, GFP_ATOMIC);
if (info == 0) {
release_mem_region(res_start, res_size);
return;
......@@ -469,11 +425,10 @@ static void __init offb_init_fb(const char *name, const char *full_name,
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';
fix->id[sizeof(fix->id) - 1] = '\0';
var->xres = var->xres_virtual = width;
var->yres = var->yres_virtual = height;
......@@ -484,43 +439,44 @@ static void __init offb_init_fb(const char *name, const char *full_name,
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
info->cmap_type = cmap_unknown;
if (depth == 8)
{
par->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;
par->cmap_adr = ioremap(regbase, 0x1FFF);
par->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;
unsigned long regbase =
dp->parent->addrs[2].address;
par->cmap_adr = ioremap(regbase, 0x1FFF);
par->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;
unsigned long regbase =
dp->parent->addrs[2].address;
par->cmap_adr = ioremap(regbase, 0x1FFF);
par->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;
par->cmap_adr = ioremap(regbase, 0x1FFF);
par->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;
par->cmap_adr =
ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
par->cmap_data = info->cmap_adr + 1;
par->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;
par->cmap_adr = ioremap(regbase + 0x6000, 0x1000);
par->cmap_type = cmap_gxt2000;
}
fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_STATIC_PSEUDOCOLOR;
}
else
fix->visual = /*info->cmap_adr ? FB_VISUAL_DIRECTCOLOR
: */FB_VISUAL_TRUECOLOR;
} else
fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR
: */ FB_VISUAL_TRUECOLOR;
var->xoffset = var->yoffset = 0;
var->bits_per_pixel = depth;
......@@ -559,7 +515,8 @@ static void __init offb_init_fb(const char *name, const char *full_name,
var->transp.length = 8;
break;
}
var->red.msb_right = var->green.msb_right = var->blue.msb_right = var->transp.msb_right = 0;
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;
......@@ -571,85 +528,27 @@ static void __init offb_init_fb(const char *name, const char *full_name,
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) {
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;
......@@ -659,133 +558,4 @@ static void __init offb_init_fb(const char *name, const char *full_name,
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;
}
/*
* Read a single color register and split it into
* colors/transparent. Return != 0 for invalid regno.
*/
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;
if (!info2->cmap_adr || regno > 255)
return 1;
*red = (info2->palette[regno].red<<8) | info2->palette[regno].red;
*green = (info2->palette[regno].green<<8) | info2->palette[regno].green;
*blue = (info2->palette[regno].blue<<8) | info2->palette[regno].blue;
*transp = 0;
return 0;
}
/*
* 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_setcolreg(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;
if (!info2->cmap_adr || regno > 255)
return 1;
red >>= 8;
green >>= 8;
blue >>= 8;
info2->palette[regno].red = red;
info2->palette[regno].green = green;
info2->palette[regno].blue = blue;
switch(info2->cmap_type) {
case cmap_m64:
*info2->cmap_adr = regno;
mach_eieio();
*info2->cmap_data = red;
mach_eieio();
*info2->cmap_data = green;
mach_eieio();
*info2->cmap_data = blue;
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, regno);
out_le32((unsigned *)(info2->cmap_adr + 0xb4),
(red << 16 | green << 8 | blue));
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, regno);
out_le32((unsigned *)(info2->cmap_adr + 0xb4),
(red << 16 | green << 8 | blue));
break;
case cmap_radeon:
/* Set palette index & data (could be smarter) */
out_8(info2->cmap_adr + 0xb0, regno);
out_le32((unsigned *)(info2->cmap_adr + 0xb4),
(red << 16 | green << 8 | blue));
break;
case cmap_gxt2000:
out_le32((unsigned *)info2->cmap_adr + regno,
(red << 16 | green << 8 | blue));
break;
}
if (regno < 16)
switch (info2->var.bits_per_pixel) {
#ifdef FBCON_HAS_CFB16
case 16:
info2->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:
{
int i = (regno << 8) | regno;
info2->fbcon_cmap.cfb32[regno] = (i << 16) | i;
break;
}
#endif
}
return 0;
}
MODULE_LICENSE("GPL");
......@@ -27,18 +27,15 @@
#include <asm/mtrr.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 DBE_REG_BASE regs
#include "sgivwfb.h"
#include <video/sgivw.h>
struct sgivwfb_par {
struct fb_var_screeninfo var;
struct sgivw_par {
asregs *regs;
u32 cmap_fifo;
u_long timing_num;
int valid;
};
/*
......@@ -52,88 +49,84 @@ struct sgivwfb_par {
u_long sgivwfb_mem_phys;
u_long sgivwfb_mem_size;
static asregs *regs;
static struct fb_info fb_info;
static struct { u_char red, green, blue, pad; } palette[256];
static char sgivwfb_name[16] = "SGI Vis WS FB";
static u32 cmap_fifo;
static struct sgivw_par default_par;
static int ypan = 0;
static int ywrap = 0;
/* console related variables */
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 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 sgivwfb_par par_current = {
{ /* var (screeninfo) */
static struct fb_var_screeninfo sgivwfb_var __initdata = {
/* 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 */
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 */
static struct display disp;
/*
* 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_get_var(struct fb_var_screeninfo *var, int con,
static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
static int sgivwfb_set_par(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_set_var(struct fb_var_screeninfo *var, int con,
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,
struct vm_area_struct *vma);
static struct fb_ops sgivwfb_ops = {
owner: THIS_MODULE,
fb_get_fix: sgivwfb_get_fix,
fb_get_var: sgivwfb_get_var,
fb_set_var: sgivwfb_set_var,
fb_get_cmap: sgivwfb_get_cmap,
fb_get_fix: gen_get_fix,
fb_get_var: gen_get_var,
fb_set_var: gen_set_var,
fb_get_cmap: gen_get_cmap,
fb_set_cmap: gen_set_cmap,
fb_check_var: sgivwfb_check_var,
fb_set_par: sgivwfb_set_par,
fb_setcolreg: sgivwfb_setcolreg,
fb_fillrect: cfb_fillrect,
fb_copyarea: cfb_copyarea,
fb_imageblit: cfb_imageblit,
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
*/
static u_long get_line_length(int xres_virtual, 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)
{
return(xres_virtual * bytes_per_pixel(bpp));
return (xres_virtual * bytes_per_pixel(bpp));
}
static unsigned long bytes_per_pixel(int bpp)
......@@ -155,7 +148,7 @@ static unsigned long bytes_per_pixel(int bpp)
length = 0;
break;
}
return(length);
return (length);
}
/*
......@@ -205,20 +198,21 @@ static void dbe_TurnOffDma(void)
// turned off for sure. I've left this in for now, in
// case dbe needs it.
for (i = 0; i < 10000; i++)
{
for (i = 0; i < 10000; i++) {
DBE_GETREG(frm_inhwctrl, readVal);
if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) == 0)
if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) ==
0)
udelay(10);
else
{
else {
DBE_GETREG(ovr_inhwctrl, readVal);
if (GET_DBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
if (GET_DBE_FIELD
(OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0)
udelay(10);
else
{
else {
DBE_GETREG(did_inhwctrl, readVal);
if (GET_DBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, readVal) == 0)
if (GET_DBE_FIELD
(DID_INHWCTRL, DID_DMA_ENABLE,
readVal) == 0)
udelay(10);
else
break;
......@@ -227,12 +221,153 @@ static void dbe_TurnOffDma(void)
}
}
/*
* Set the User Defined Part of the Display. Again if par use it to get
* real video mode.
*/
static int sgivwfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
int err, activate = var->activate;
struct dbe_timing_info *timing;
u_long line_length;
u_long min_mode;
int req_dot;
int test_mode;
/*
* 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 */
req_dot = PICOS2KHZ(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 = KHZ2PICOS(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;
/* Ouch. This breaks the rules but timing_num is only important if you
* change a video mode */
par->timing_num = min_mode;
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);
return 0;
}
/*
* Set the hardware according to 'par'.
*/
static void activate_par(struct sgivwfb_par *par)
static int sgivwfb_set_par(struct fb_info *info)
{
int i,j, htmp, temp;
struct sgivw_par *par = info->par;
int i, j, htmp, temp;
u32 readVal, outputVal;
int wholeTilesX, maxPixelsPerTileX;
int frmWrite1, frmWrite2, frmWrite3b;
......@@ -241,7 +376,7 @@ static void activate_par(struct sgivwfb_par *par)
int bytesPerPixel; // Bytes per pixel
currentTiming = &dbeVTimings[par->timing_num];
bytesPerPixel = bytes_per_pixel(par->var.bits_per_pixel);
bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel);
xpmax = currentTiming->width;
ypmax = currentTiming->height;
......@@ -252,9 +387,9 @@ static void activate_par(struct sgivwfb_par *par)
dbe_TurnOffDma();
/* dbe_CalculateScreenParams(); */
maxPixelsPerTileX = 512/bytesPerPixel;
wholeTilesX = xpmax/maxPixelsPerTileX;
if (wholeTilesX*maxPixelsPerTileX < xpmax)
maxPixelsPerTileX = 512 / bytesPerPixel;
wholeTilesX = xpmax / maxPixelsPerTileX;
if (wholeTilesX * maxPixelsPerTileX < xpmax)
wholeTilesX++;
printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
......@@ -263,26 +398,21 @@ static void activate_par(struct sgivwfb_par *par)
/* dbe_InitGammaMap(); */
udelay(10);
for (i = 0; i < 256; i++)
{
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)
{
if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) {
DBE_SETREG(vt_xy, 0x00000000);
udelay(1);
}
else
} else
dbe_TurnOffDma();
/* dbe_Initdbe(); */
for (i = 0; i < 256; i++)
{
for (j = 0; j < 100; j++)
{
for (i = 0; i < 256; i++) {
for (j = 0; j < 100; j++) {
DBE_GETREG(cm_fifo, readVal);
if (readVal != 0x00000000)
break;
......@@ -291,24 +421,27 @@ static void activate_par(struct sgivwfb_par *par)
}
// DBE_ISETREG(cmap, i, 0x00000000);
DBE_ISETREG(cmap, i, (i<<8)|(i<<16)|(i<<24));
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_WIDTH_TILE, frmWrite1,
wholeTilesX);
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);
switch(bytesPerPixel)
{
switch (bytesPerPixel) {
case 1:
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, DBE_FRM_DEPTH_8);
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);
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);
SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,
DBE_FRM_DEPTH_32);
break;
}
......@@ -318,15 +451,15 @@ static void activate_par(struct sgivwfb_par *par)
// 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_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)
{
switch (bytesPerPixel) {
case 1:
SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
break;
......@@ -339,8 +472,7 @@ static void activate_par(struct sgivwfb_par *par)
}
SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);
for (i = 0; i < 32; i++)
{
for (i = 0; i < 32; i++) {
DBE_ISETREG(mode_regs, i, outputVal);
}
......@@ -353,28 +485,40 @@ static void activate_par(struct sgivwfb_par *par)
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);
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);
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);
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);
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);
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);
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;
......@@ -382,27 +526,32 @@ static void activate_par(struct sgivwfb_par *par)
if (temp > 0)
temp = -temp;
SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32)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));
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));
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));
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_STARTY, outputVal, (u32) temp);
SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,
currentTiming->hblank_end - 4);
DBE_SETREG(vc_start_xy, outputVal);
......@@ -411,13 +560,13 @@ static void activate_par(struct sgivwfb_par *par)
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, 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);
udelay(11 * 1000);
DBE_SETREG(vt_vpixen, 0xffffff);
DBE_SETREG(vt_hpixen, 0xffffff);
......@@ -441,17 +590,18 @@ static void activate_par(struct sgivwfb_par *par)
DBE_SETREG(did_control, 0);
// Wait for dbe to take frame settings
for (i=0; i<100000; i++)
{
for (i = 0; i < 100000; i++) {
DBE_GETREG(frm_inhwctrl, readVal);
if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) != 0)
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");
if (i == 100000)
printk(KERN_INFO
"sgivwfb: timeout waiting for frame DMA enable.\n");
outputVal = 0;
htmp = currentTiming->hblank_end - 19;
......@@ -459,7 +609,8 @@ static void activate_par(struct sgivwfb_par *par)
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));
((htmp + currentTiming->width -
2) % currentTiming->htotal));
DBE_SETREG(vt_hpixen, outputVal);
outputVal = 0;
......@@ -470,57 +621,15 @@ static void activate_par(struct sgivwfb_par *par)
DBE_SETREG(vt_vpixen, outputVal);
// Turn off mouse cursor
regs->crs_ctl = 0;
par->regs->crs_ctl = 0;
// XXX What's this section for??
DBE_GETREG(ctrlstat, readVal);
readVal &= 0x02000000;
if (readVal != 0)
{
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
* colors/transparent. Return != 0 for invalid regno.
*/
static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *info)
{
if (regno > 255)
return 1;
*red = palette[regno].red << 8;
*green = palette[regno].green << 8;
*blue = palette[regno].blue << 8;
*transp = 0;
return 0;
}
......@@ -530,271 +639,24 @@ 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.
*/
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_setcolreg(u_int regno, u_int red, u_int green,
u_int blue, u_int transp,
struct fb_info *info)
{
struct sgivw_par *par = (struct sgivw_par *) info->par;
if (regno > 255)
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;
}
/* ---------------------------------------------------- */
/*
* Get the Fixed Part of the Display
*/
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;
}
while (par->cmap_fifo == 0)
par->cmap_fifo = par->regs->cm_fifo;
/*
* Get the User Defined Part of the Display. If a real par get it form there
*/
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);
par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
par->cmap_fifo--; /* assume FIFO is filling up */
return 0;
}
......@@ -803,17 +665,21 @@ static int sgivwfb_mmap(struct fb_info *info, struct file *file,
{
unsigned long size = vma->vm_end - vma->vm_start;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
return -EINVAL;
if (offset+size > sgivwfb_mem_size)
if (offset + size > sgivwfb_mem_size)
return -EINVAL;
offset += sgivwfb_mem_phys;
pgprot_val(vma->vm_page_prot) = pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
pgprot_val(vma->vm_page_prot) =
pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
vma->vm_flags |= VM_IO;
if (remap_page_range(vma, vma->vm_start, offset, size, vma->vm_page_prot))
if (remap_page_range
(vma, vma->vm_start, offset, size, vma->vm_page_prot))
return -EAGAIN;
vma->vm_file = file;
printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", offset, vma->vm_start);
printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
offset, vma->vm_start);
return 0;
}
......@@ -828,7 +694,7 @@ int __init sgivwfb_setup(char *options)
while ((this_opt = strsep(&options, ",")) != NULL) {
if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
strcpy(fb_info.fontname, this_opt + 5);
}
return 0;
}
......@@ -839,76 +705,68 @@ int __init sgivwfb_setup(char *options)
int __init sgivwfb_init(void)
{
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);
if (!regs) {
default_par.regs = (asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
if (!default_par.regs) {
printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
goto fail_ioremap_regs;
}
#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
strcpy(fb_info.modename, sgivwfb_name);
sgivwfb_fix.smem_start = sgivwfb_mem_phys;
sgivwfb_fix.smem_len = sgivwfb_mem_size;
sgivwfb_fix.ywrapstep = ywrap;
sgivwfb_fix.ypanstep = ypan;
strcpy(fb_info.modename, sgivwfb_fix.id);
fb_info.changevar = NULL;
fb_info.node = NODEV;
fb_info.fix = sgivwfb_fix;
fb_info.var = sgivwfb_var;
fb_info.fbops = &sgivwfb_ops;
fb_info.pseudo_palette = pseudo_palette;
fb_info.par = &default_par;
fb_info.disp = &disp;
fb_info.currcon = -1;
fb_info.switch_con = &sgivwfbcon_switch;
fb_info.updatevar = &sgivwfbcon_updatevar;
fb_info.switch_con = gen_switch;
fb_info.updatevar = gen_update_var;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.screen_base = ioremap_nocache((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size);
fb_info.screen_base =
ioremap_nocache((unsigned long) sgivwfb_mem_phys,
sgivwfb_mem_size);
if (!fb_info.screen_base) {
printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");
goto fail_ioremap_fbmem;
}
/* turn on default video mode */
sgivwfb_set_var(&par_current.var, -1, &fb_info);
gen_set_var(&fb_info->var, -1, &fb_info);
if (register_framebuffer(&fb_info) < 0) {
printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
printk(KERN_ERR
"sgivwfb: couldn't register framebuffer\n");
goto fail_register_framebuffer;
}
printk(KERN_INFO "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), sgivwfb_mem_size>>10);
printk(KERN_INFO
"fb%d: Virtual frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), sgivwfb_mem_size >> 10);
return 0;
fail_register_framebuffer:
iounmap((char*)fb_info.screen_base);
iounmap((char *) fb_info.screen_base);
fail_ioremap_fbmem:
iounmap(regs);
iounmap(default_par.regs);
fail_ioremap_regs:
return -ENXIO;
}
static int sgivwfbcon_switch(int con, struct fb_info *info)
{
/* Do we have to save the colormap? */
if (fb_display[info->currcon].cmap.len)
fb_get_cmap(&fb_display[info->currcon].cmap, 1, sgivwfb_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 sgivwfbcon_updatevar(int con, struct fb_info *info)
{
/* Nothing */
return 0;
}
#ifdef MODULE
MODULE_LICENSE("GPL");
......
......@@ -325,7 +325,7 @@ int __init tx3912fb_init(void)
return 0;
}
int __init tx3912fb_setup(char *options)
void __init tx3912fb_setup(char *options)
{
char *this_opt;
......
......@@ -32,7 +32,7 @@
/* --------------------------------------------------------------------- */
static struct fb_var_screeninfo vesafb_defined = {
static struct fb_var_screeninfo vesafb_defined __initdata = {
activate: FB_ACTIVATE_NOW,
height: -1,
width: -1,
......@@ -43,7 +43,7 @@ static struct fb_var_screeninfo vesafb_defined = {
vmode: FB_VMODE_NONINTERLACED,
};
static struct fb_fix_screeninfo vesafb_fix = {
static struct fb_fix_screeninfo vesafb_fix __initdata = {
id: "VESA VGA",
type: FB_TYPE_PACKED_PIXELS,
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