Commit 0d6e9d9e authored by James Simmons's avatar James Simmons

Port of chipsfb driver to new api. Removed the fontwidth8 option. Let the...

Port of chipsfb driver to new api. Removed the fontwidth8 option. Let the xxxfb_imageblit function handle this. 64 bit m achine fixes.
parent f25be5cb
......@@ -28,11 +28,11 @@ obj-$(CONFIG_FB_ATARI) += atafb.o
obj-$(CONFIG_FB_ATY128) += aty128fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_RADEON) += radeonfb.o
obj-$(CONFIG_FB_NEOMAGIC) += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_IGA) += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblit.o
obj-$(CONFIG_FB_IGA) += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CONTROL) += controlfb.o
obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
obj-$(CONFIG_FB_CT65550) += chipsfb.o
obj-$(CONFIG_FB_CT65550) += chipsfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_ANAKIN) += anakinfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CYBER) += cyberfb.o
......
......@@ -102,10 +102,10 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8
unsigned long start_index, unsigned long pitch_index)
{
/* Draw the penguin */
unsigned long *palette = (unsigned long *) p->pseudo_palette;
unsigned long *dst, *dst2, color = 0, val, shift;
int i, n, bpp = p->var.bits_per_pixel;
unsigned long null_bits = BITS_PER_LONG - bpp;
u32 *palette = (u32 *) p->pseudo_palette;
u8 *src = image->data;
dst2 = (unsigned long *) dst1;
......
......@@ -2,7 +2,7 @@
* drivers/video/chipsfb.c -- frame buffer device for
* Chips & Technologies 65550 chip.
*
* Copyright (C) 1998 Paul Mackerras
* Copyright (C) 1998-2002 Paul Mackerras
*
* This file is derived from the Powermac "chips" driver:
* Copyright (C) 1997 Fabio Riccardi.
......@@ -26,7 +26,6 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/selection.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
......@@ -39,34 +38,11 @@
#include <linux/pmu.h>
#endif
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/macmodes.h>
struct fb_info_chips {
struct fb_info info;
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
struct display disp;
struct {
__u8 red, green, blue;
} palette[256];
struct pci_dev *pdev;
unsigned long frame_buffer_phys;
__u8 *frame_buffer;
unsigned long blitter_regs_phys;
__u32 *blitter_regs;
unsigned long blitter_data_phys;
__u8 *blitter_data;
struct fb_info_chips *next;
#ifdef CONFIG_PMAC_PBOOK
unsigned char *save_framebuffer;
#endif
#ifdef FBCON_HAS_CFB16
u16 fbcon_cfb16_cmap[16];
#endif
};
/*
* Since we access the display with inb/outb to fixed port numbers,
* we can only handle one 6555x chip. -- paulus
*/
static struct fb_info chipsfb_info;
#define write_ind(num, val, ap, dp) do { \
outb((num), (ap)); outb((val), (dp)); \
......@@ -98,9 +74,8 @@ struct fb_info_chips {
inb(0x3da); read_ind(num, var, 0x3c0, 0x3c1); \
} while (0)
static struct fb_info_chips *all_chips;
#ifdef CONFIG_PMAC_PBOOK
static unsigned char *save_framebuffer;
int chips_sleep_notify(struct pmu_sleep_notifier *self, int when);
static struct pmu_sleep_notifier chips_sleep_notifier = {
chips_sleep_notify, SLEEP_LEVEL_VIDEO,
......@@ -112,58 +87,29 @@ static struct pmu_sleep_notifier chips_sleep_notifier = {
*/
int chips_init(void);
static void chips_pci_init(struct pci_dev *dp);
static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int chips_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
static int chips_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
static int chipsfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info);
static int chipsfb_set_par(struct fb_info *info);
static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
static int chipsfb_blank(int blank, struct fb_info *info);
static struct fb_ops chipsfb_ops = {
.owner = THIS_MODULE,
.fb_get_fix = chips_get_fix,
.fb_get_var = chips_get_var,
.fb_set_var = chips_set_var,
.fb_get_cmap = chips_get_cmap,
.fb_set_cmap = gen_set_cmap,
.fb_setcolreg = chipsfb_setcolreg,
.fb_blank = chipsfb_blank,
.owner = THIS_MODULE,
.fb_check_var = chipsfb_check_var,
.fb_set_par = chipsfb_set_par,
.fb_setcolreg = chipsfb_setcolreg,
.fb_blank = chipsfb_blank,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_cursor = soft_cursor,
};
static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
u_int *blue, u_int *transp, struct fb_info *info);
static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp);
static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info)
static int chipsfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct fb_info_chips *cp = (struct fb_info_chips *) info;
*fix = cp->fix;
return 0;
}
static int chips_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
struct fb_info_chips *cp = (struct fb_info_chips *) info;
*var = cp->var;
return 0;
}
static int chips_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
struct fb_info_chips *cp = (struct fb_info_chips *) info;
struct display *disp = (con >= 0)? &fb_display[con]: &cp->disp;
if (var->xres > 800 || var->yres > 600
|| var->xres_virtual > 800 || var->yres_virtual > 600
|| (var->bits_per_pixel != 8 && var->bits_per_pixel != 16)
......@@ -171,198 +117,76 @@ static int chips_set_var(struct fb_var_screeninfo *var, int con,
|| (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
return -EINVAL;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW &&
var->bits_per_pixel != disp->var.bits_per_pixel) {
chips_set_bitdepth(cp, disp, con, var->bits_per_pixel);
}
var->xres = var->xres_virtual = 800;
var->yres = var->yres_virtual = 600;
return 0;
}
static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
static int chipsfb_set_par(struct fb_info *info)
{
if (con == info->currcon) /* current console? */
return fb_get_cmap(cmap, kspc, chipsfb_getcolreg, info);
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);
if (info->var.bits_per_pixel == 16) {
write_cr(0x13, 200); // Set line length (doublewords)
write_xr(0x81, 0x14); // 15 bit (555) color mode
write_xr(0x82, 0x00); // Disable palettes
write_xr(0x20, 0x10); // 16 bit blitter mode
info->fix.line_length = 800*2;
info->fix.visual = FB_VISUAL_TRUECOLOR;
info->var.red.offset = 10;
info->var.green.offset = 5;
info->var.blue.offset = 0;
info->var.red.length = info->var.green.length =
info->var.blue.length = 5;
} else {
/* p->var.bits_per_pixel == 8 */
write_cr(0x13, 100); // Set line length (doublewords)
write_xr(0x81, 0x12); // 8 bit color mode
write_xr(0x82, 0x08); // Graphics gamma enable
write_xr(0x20, 0x00); // 8 bit blitter mode
info->fix.line_length = 800;
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
info->var.red.offset = info->var.green.offset =
info->var.blue.offset = 0;
info->var.red.length = info->var.green.length =
info->var.blue.length = 8;
}
return 0;
}
static int chipsfbcon_switch(int con, struct fb_info *info)
{
struct fb_info_chips *p = (struct fb_info_chips *) info;
int new_bpp, old_bpp;
/* Do we have to save the colormap? */
if (fb_display[info->currcon].cmap.len)
fb_get_cmap(&fb_display[info->currcon].cmap, 1, chipsfb_getcolreg, info);
new_bpp = fb_display[con].var.bits_per_pixel;
old_bpp = fb_display[info->currcon].var.bits_per_pixel;
info->currcon = con;
if (new_bpp != old_bpp)
chips_set_bitdepth(p, &fb_display[con], con, new_bpp);
do_install_cmap(con, info);
return 0;
}
static int chipsfb_updatevar(int con, struct fb_info *info)
{
return 0;
}
static int chipsfb_blank(int blank, struct fb_info *info)
{
struct fb_info_chips *p = (struct fb_info_chips *) info;
int i;
#ifdef CONFIG_PMAC_BACKLIGHT
// used to disable backlight only for blank > 1, but it seems
// useful at blank = 1 too (saves battery, extends backlight life)
if (blank) {
#ifdef CONFIG_PMAC_BACKLIGHT
set_backlight_enable(0);
#endif /* CONFIG_PMAC_BACKLIGHT */
/* get the palette from the chip */
for (i = 0; i < 256; ++i) {
outb(i, 0x3c7);
udelay(1);
p->palette[i].red = inb(0x3c9);
p->palette[i].green = inb(0x3c9);
p->palette[i].blue = inb(0x3c9);
}
for (i = 0; i < 256; ++i) {
outb(i, 0x3c8);
udelay(1);
outb(0, 0x3c9);
outb(0, 0x3c9);
outb(0, 0x3c9);
}
} else {
#ifdef CONFIG_PMAC_BACKLIGHT
set_backlight_enable(1);
set_backlight_enable(!blank);
#endif /* CONFIG_PMAC_BACKLIGHT */
for (i = 0; i < 256; ++i) {
outb(i, 0x3c8);
udelay(1);
outb(p->palette[i].red, 0x3c9);
outb(p->palette[i].green, 0x3c9);
outb(p->palette[i].blue, 0x3c9);
}
}
return 0;
}
static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
u_int *blue, u_int *transp, struct fb_info *info)
{
struct fb_info_chips *p = (struct fb_info_chips *) info;
if (regno > 255)
return 1;
*red = (p->palette[regno].red<<8) | p->palette[regno].red;
*green = (p->palette[regno].green<<8) | p->palette[regno].green;
*blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
*transp = 0;
return 0;
return 1; /* get fb_blank to set the colormap to all black */
}
static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
struct fb_info_chips *p = (struct fb_info_chips *) info;
if (regno > 255)
return 1;
red >>= 8;
green >>= 8;
blue >>= 8;
p->palette[regno].red = red;
p->palette[regno].green = green;
p->palette[regno].blue = blue;
outb(regno, 0x3c8);
udelay(1);
outb(red, 0x3c9);
outb(green, 0x3c9);
outb(blue, 0x3c9);
#ifdef FBCON_HAS_CFB16
if (regno < 16)
p->fbcon_cfb16_cmap[regno] = ((red & 0xf8) << 7)
| ((green & 0xf8) << 2) | ((blue & 0xf8) >> 3);
#endif
return 0;
}
static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp)
{
int err;
struct fb_fix_screeninfo* fix = &p->fix;
struct fb_var_screeninfo* var = &p->var;
if (bpp == 16) {
if (con == p->info.currcon) {
write_cr(0x13, 200); // Set line length (doublewords)
write_xr(0x81, 0x14); // 15 bit (555) color mode
write_xr(0x82, 0x00); // Disable palettes
write_xr(0x20, 0x10); // 16 bit blitter mode
}
fix->line_length = 800*2;
fix->visual = FB_VISUAL_TRUECOLOR;
var->red.offset = 10;
var->green.offset = 5;
var->blue.offset = 0;
var->red.length = var->green.length = var->blue.length = 5;
#ifdef FBCON_HAS_CFB16
disp->dispsw = &fbcon_cfb16;
disp->dispsw_data = p->fbcon_cfb16_cmap;
#else
disp->dispsw = &fbcon_dummy;
#endif
} else if (bpp == 8) {
if (con == p->info.currcon) {
write_cr(0x13, 100); // Set line length (doublewords)
write_xr(0x81, 0x12); // 8 bit color mode
write_xr(0x82, 0x08); // Graphics gamma enable
write_xr(0x20, 0x00); // 8 bit blitter mode
}
fix->line_length = 800;
fix->visual = FB_VISUAL_PSEUDOCOLOR;
var->red.offset = var->green.offset = var->blue.offset = 0;
var->red.length = var->green.length = var->blue.length = 8;
#ifdef FBCON_HAS_CFB8
disp->dispsw = &fbcon_cfb8;
#else
disp->dispsw = &fbcon_dummy;
#endif
}
var->bits_per_pixel = bpp;
disp->line_length = p->fix.line_length;
disp->visual = fix->visual;
disp->var = *var;
if (p->info.changevar)
(*p->info.changevar)(con);
if ((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
return;
do_install_cmap(con, (struct fb_info *)p);
}
struct chips_init_reg {
unsigned char addr;
unsigned char data;
......@@ -473,7 +297,7 @@ static struct chips_init_reg chips_init_xr[] = {
{ 0xa8, 0x00 }
};
static void __init chips_hw_init(struct fb_info_chips *p)
static void __init chips_hw_init(void)
{
int i;
......@@ -492,12 +316,12 @@ static void __init chips_hw_init(struct fb_info_chips *p)
write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
}
static void __init init_chips(struct fb_info_chips *p)
{
int i;
strcpy(p->fix.id, "C&T 65550");
p->fix.smem_start = p->frame_buffer_phys;
static struct fb_fix_screeninfo chipsfb_fix __initdata = {
.id = "C&T 65550",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
.accel = FB_ACCEL_NONE,
.line_length = 800,
// FIXME: Assumes 1MB frame buffer, but 65550 supports 1MB or 2MB.
// * "3500" PowerBook G3 (the original PB G3) has 2MB.
......@@ -506,115 +330,75 @@ static void __init init_chips(struct fb_info_chips *p)
// for a second pair of DRAMs. (Thanks, Apple!)
// * 3400 has 1MB (I think). Don't know if it's expandable.
// -- Tim Seufert
p->fix.smem_len = 0x100000; // 1MB
p->fix.type = FB_TYPE_PACKED_PIXELS;
p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
p->fix.line_length = 800;
p->var.xres = 800;
p->var.yres = 600;
p->var.xres_virtual = 800;
p->var.yres_virtual = 600;
p->var.bits_per_pixel = 8;
p->var.red.length = p->var.green.length = p->var.blue.length = 8;
p->var.height = p->var.width = -1;
p->var.vmode = FB_VMODE_NONINTERLACED;
p->var.pixclock = 10000;
p->var.left_margin = p->var.right_margin = 16;
p->var.upper_margin = p->var.lower_margin = 16;
p->var.hsync_len = p->var.vsync_len = 8;
p->disp.var = p->var;
p->disp.cmap.red = NULL;
p->disp.cmap.green = NULL;
p->disp.cmap.blue = NULL;
p->disp.cmap.transp = NULL;
p->disp.visual = p->fix.visual;
p->disp.type = p->fix.type;
p->disp.type_aux = p->fix.type_aux;
p->disp.line_length = p->fix.line_length;
p->disp.can_soft_blank = 1;
p->disp.dispsw = &fbcon_cfb8;
p->disp.scrollmode = SCROLL_YREDRAW;
strcpy(p->info.modename, p->fix.id);
p->info.node = NODEV;
p->info.fbops = &chipsfb_ops;
p->info.screen_base = p->frame_buffer;
p->info.disp = &p->disp;
p->info.currcon = -1;
p->info.fontname[0] = 0;
p->info.changevar = NULL;
p->info.switch_con = &chipsfbcon_switch;
p->info.updatevar = &chipsfb_updatevar;
p->info.flags = FBINFO_FLAG_DEFAULT;
for (i = 0; i < 16; ++i) {
int j = color_table[i];
p->palette[i].red = default_red[j];
p->palette[i].green = default_grn[j];
p->palette[i].blue = default_blu[j];
}
.smem_len = 0x100000, /* 1MB */
};
if (register_framebuffer(&p->info) < 0) {
kfree(p);
return;
}
static struct fb_var_screeninfo chipsfb_var __initdata = {
.xres = 800,
.yres = 600,
.xres_virtual = 800,
.yres_virtual = 600,
.bits_per_pixel = 8,
.red = { .length = 8 },
.green = { .length = 8 },
.blue = { .length = 8 },
.height = -1,
.width = -1,
.vmode = FB_VMODE_NONINTERLACED,
.pixclock = 10000,
.left_margin = 16,
.right_margin = 16,
.upper_margin = 16,
.lower_margin = 16,
.hsync_len = 8,
.vsync_len = 8,
};
printk("fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
minor(p->info.node), p->fix.smem_len / 1024);
static void __init init_chips(struct fb_info *p, unsigned long addr)
{
p->fix = chipsfb_fix;
p->fix.smem_start = addr;
chips_hw_init(p);
p->var = chipsfb_var;
#ifdef CONFIG_PMAC_PBOOK
if (all_chips == NULL)
pmu_register_sleep_notifier(&chips_sleep_notifier);
#endif /* CONFIG_PMAC_PBOOK */
p->next = all_chips;
all_chips = p;
}
p->node = NODEV;
p->fbops = &chipsfb_ops;
p->flags = FBINFO_FLAG_DEFAULT;
int __init chips_init(void)
{
struct pci_dev *dp = NULL;
fb_alloc_cmap(&p->cmap, 256, 0);
if (register_framebuffer(p) < 0) {
printk(KERN_ERR "C&T 65550 framebuffer failed to register\n");
return;
}
printk(KERN_INFO "fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
minor(p->node), p->fix.smem_len / 1024);
while ((dp = pci_find_device(PCI_VENDOR_ID_CT,
PCI_DEVICE_ID_CT_65550, dp)) != NULL)
if ((dp->class >> 16) == PCI_BASE_CLASS_DISPLAY)
chips_pci_init(dp);
return all_chips? 0: -ENODEV;
chips_hw_init();
}
static void __init chips_pci_init(struct pci_dev *dp)
static int __devinit
chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
{
struct fb_info_chips *p;
struct fb_info *p = &chipsfb_info;
unsigned long addr, size;
unsigned short cmd;
if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
return;
addr = dp->resource[0].start;
size = dp->resource[0].end + 1 - addr;
return -ENODEV;
addr = pci_resource_start(dp, 0);
size = pci_resource_len(dp, 0);
if (addr == 0)
return;
p = kmalloc(sizeof(*p), GFP_ATOMIC);
if (p == 0)
return;
memset(p, 0, sizeof(*p));
if (!request_mem_region(addr, size, "chipsfb")) {
kfree(p);
return;
}
return -ENODEV;
if (p->screen_base != 0)
return -EBUSY;
if (!request_mem_region(addr, size, "chipsfb"))
return -EBUSY;
#ifdef __BIG_ENDIAN
addr += 0x800000; // Use big-endian aperture
#endif
p->pdev = dp;
p->frame_buffer_phys = addr;
p->frame_buffer = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
p->blitter_regs_phys = addr + 0x400000;
p->blitter_regs = ioremap(addr + 0x400000, 0x1000);
p->blitter_data_phys = addr + 0x410000;
p->blitter_data = ioremap(addr + 0x410000, 0x10000);
/* we should use pci_enable_device here, but,
the device doesn't declare its I/O ports in its BARs
......@@ -623,15 +407,68 @@ static void __init chips_pci_init(struct pci_dev *dp)
cmd |= 3; /* enable memory and IO space */
pci_write_config_word(dp, PCI_COMMAND, cmd);
/* Clear the entire framebuffer */
memset(p->frame_buffer, 0, 0x100000);
#ifdef CONFIG_PMAC_BACKLIGHT
/* turn on the backlight */
set_backlight_enable(1);
#endif /* CONFIG_PMAC_BACKLIGHT */
init_chips(p);
p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
if (p->screen_base == NULL) {
release_mem_region(addr, size);
return -ENOMEM;
}
init_chips(p, addr);
#ifdef CONFIG_PMAC_PBOOK
pmu_register_sleep_notifier(&chips_sleep_notifier);
#endif /* CONFIG_PMAC_PBOOK */
/* Clear the entire framebuffer */
memset(p->screen_base, 0, 0x100000);
pci_set_drvdata(dp, p);
return 0;
}
static void __devexit chipsfb_remove(struct pci_dev *dp)
{
struct fb_info *p = pci_get_drvdata(dp);
if (p != &chipsfb_info || p->screen_base == NULL)
return;
unregister_framebuffer(p);
iounmap(p->screen_base);
p->screen_base = NULL;
release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
#ifdef CONFIG_PMAC_PBOOK
pmu_unregister_sleep_notifier(&chips_sleep_notifier);
#endif /* CONFIG_PMAC_PBOOK */
}
static struct pci_device_id chipsfb_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_65550, PCI_ANY_ID, PCI_ANY_ID },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, chipsfb_pci_tbl);
static struct pci_driver chipsfb_driver = {
.name = "chipsfb",
.id_table = chipsfb_pci_tbl,
.probe = chipsfb_pci_init,
.remove = __devexit_p(chipsfb_remove),
};
int __init chips_init(void)
{
return pci_module_init(&chipsfb_driver);
}
static void __exit chipsfb_exit(void)
{
pci_unregister_driver(&chipsfb_driver);
}
#ifdef CONFIG_PMAC_PBOOK
......@@ -642,40 +479,37 @@ static void __init chips_pci_init(struct pci_dev *dp)
int
chips_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
struct fb_info_chips *p;
for (p = all_chips; p != NULL; p = p->next) {
int nb = p->var.yres * p->fix.line_length;
switch (when) {
case PBOOK_SLEEP_REQUEST:
p->save_framebuffer = vmalloc(nb);
if (p->save_framebuffer == NULL)
return PBOOK_SLEEP_REFUSE;
break;
case PBOOK_SLEEP_REJECT:
if (p->save_framebuffer) {
vfree(p->save_framebuffer);
p->save_framebuffer = 0;
}
break;
case PBOOK_SLEEP_NOW:
chipsfb_blank(1, (struct fb_info *)p);
if (p->save_framebuffer)
memcpy(p->save_framebuffer,
p->frame_buffer, nb);
break;
case PBOOK_WAKE:
if (p->save_framebuffer) {
memcpy(p->frame_buffer,
p->save_framebuffer, nb);
vfree(p->save_framebuffer);
p->save_framebuffer = 0;
}
chipsfb_blank(0, (struct fb_info *)p);
break;
struct fb_info *p = &chipsfb_info;
int nb = p->var.yres * p->fix.line_length;
if (p->screen_base == NULL)
return PBOOK_SLEEP_OK;
switch (when) {
case PBOOK_SLEEP_REQUEST:
save_framebuffer = vmalloc(nb);
if (save_framebuffer == NULL)
return PBOOK_SLEEP_REFUSE;
break;
case PBOOK_SLEEP_REJECT:
if (save_framebuffer) {
vfree(save_framebuffer);
save_framebuffer = 0;
}
break;
case PBOOK_SLEEP_NOW:
chipsfb_blank(1, p);
if (save_framebuffer)
memcpy(save_framebuffer, p->screen_base, nb);
break;
case PBOOK_WAKE:
if (save_framebuffer) {
memcpy(p->screen_base, save_framebuffer, nb);
vfree(save_framebuffer);
save_framebuffer = 0;
}
chipsfb_blank(0, p);
break;
}
return PBOOK_SLEEP_OK;
}
......
......@@ -138,15 +138,6 @@ config FBCON_ADVANCED
# Guess what we need
config FONTWIDTH8_ONLY
bool "Support only 8 pixels wide fonts"
depends on FRAMEBUFFER_CONSOLE
help
Answer Y here will make the kernel provide only the 8x8 fonts (these
are the less readable).
If unsure, say N.
config FONT_SUN8x16
bool "Sparc console 8x16 font"
depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
......@@ -155,7 +146,7 @@ config FONT_SUN8x16
config FONT_SUN12x22
bool "Sparc console 12x22 font (not supported by all drivers)"
depends on FRAMEBUFFER_CONSOLE && !FONTWIDTH8_ONLY && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
help
This is the high resolution console font for Sun machines with very
big letters (like the letters used in the SPARC PROM). If the
......@@ -204,7 +195,7 @@ config FONT_8x16
config FONT_6x11
bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
depends on FRAMEBUFFER_CONSOLE && !FONTWIDTH8_ONLY
depends on FRAMEBUFFER_CONSOLE
default y if !SPARC32 && !SPARC64 && !FONTS && MAC
help
Small console font with Macintosh-style high-half glyphs. Some Mac
......
......@@ -799,14 +799,6 @@ static int fbcon_changevar(int con)
p->fontdata = font->data;
}
#ifdef FONTWIDTH8_ONLY
if (!fontwidthvalid(p, vc->vc_font.width)) {
/* ++Geert: changed from panic() to `correct and continue' */
printk(KERN_ERR
"fbcon_set_display: No support for fontwidth %d\n",
vc->vc_font.width);
}
#endif
updatescrollmode(p, vc);
old_cols = vc->vc_cols;
......@@ -949,14 +941,6 @@ static void fbcon_set_display(int con, int init, int logo)
p->fontdata = font->data;
}
#ifdef FONTWIDTH8_ONLY
if (!fontwidthvalid(p, vc->vc_font.width)) {
/* ++Geert: changed from panic() to `correct and continue' */
printk(KERN_ERR
"fbcon_set_display: No support for fontwidth %d\n",
vc->vc_font.width);
}
#endif
updatescrollmode(p, vc);
old_cols = vc->vc_cols;
......@@ -2010,10 +1994,6 @@ static inline int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
u8 *fontdata = p->fontdata;
int i, j;
#ifdef CONFIG_FONTWIDTH8_ONLY
if (fontwidth(p) != 8)
return -EINVAL;
#endif
op->width = vc->vc_font.width;
op->height = vc->vc_font.height;
op->charcount = (p->charmask == 0x1ff) ? 512 : 256;
......@@ -2028,9 +2008,7 @@ static inline int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
data += 32;
fontdata += j;
}
}
#ifndef CONFIG_FONTWIDTH8_ONLY
else if (op->width <= 16) {
} else if (op->width <= 16) {
j = vc->vc_font.height * 2;
for (i = 0; i < op->charcount; i++) {
memcpy(data, fontdata, j);
......@@ -2058,7 +2036,6 @@ static inline int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
fontdata += j;
}
}
#endif
return 0;
}
......@@ -2211,10 +2188,6 @@ static inline int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
int i, k;
u8 *new_data, *data = op->data, *p;
#ifdef CONFIG_FONTWIDTH8_ONLY
if (w != 8)
return -EINVAL;
#endif
if ((w <= 0) || (w > 32)
|| (op->charcount != 256 && op->charcount != 512))
return -EINVAL;
......@@ -2242,9 +2215,7 @@ static inline int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
data += 32;
p += h;
}
}
#ifndef CONFIG_FONTWIDTH8_ONLY
else if (w <= 16) {
} else if (w <= 16) {
h *= 2;
for (i = 0; i < op->charcount; i++) {
memcpy(p, data, h);
......@@ -2270,7 +2241,6 @@ static inline int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
p += h;
}
}
#endif
/* we can do it in u32 chunks because of charcount is 256 or 512, so
font length must be multiple of 256, at least. And 256 is multiple
of 4 */
......
......@@ -51,22 +51,11 @@ extern struct display fb_display[MAX_NR_CONSOLES];
extern char con2fb_map[MAX_NR_CONSOLES];
extern void set_con2fb_map(int unit, int newidx);
#ifdef CONFIG_FONTWIDTH8_ONLY
/* fontwidth w is supported by dispsw */
#define FONTWIDTH(w) (1 << ((8) - 1))
/* fontwidths w1-w2 inclusive are supported by dispsw */
#define FONTWIDTHRANGE(w1,w2) FONTWIDTH(8)
#else
/* fontwidth w is supported by dispsw */
#define FONTWIDTH(w) (1 << ((w) - 1))
/* fontwidths w1-w2 inclusive are supported by dispsw */
#define FONTWIDTHRANGE(w1,w2) (FONTWIDTH(w2+1) - FONTWIDTH(w1))
#endif
/*
* Attribute Decoding
*/
......
......@@ -128,6 +128,40 @@ static struct xxx_par __initdata current_par;
int xxxfb_init(void);
int xxxfb_setup(char*);
/**
* xxxfb_open - Optional function. Called when the framebuffer is
* first accessed.
* @info: frame buffer structure that represents a single frame buffer
* @user: tell us if the userland (value=1) or the console is accessing
* the framebuffer.
*
* This function is the first function called in the framebuffer api.
* Usually you don't need to provide this function. The case where it
* is used is to change from a text mode hardware state to a graphics
* mode state.
*/
static int xxxfb_open(const struct fb_info *info, int user)
{
return 0;
}
/**
* xxxfb_release - Optional function. Called when the framebuffer
* device is closed.
* @info: frame buffer structure that represents a single frame buffer
* @user: tell us if the userland (value=1) or the console is accessing
* the framebuffer.
*
* Thus function is called when we close /dev/fb or the framebuffer
* console system is released. Usually you don't need this function.
* The case where it is usually used is to go from a graphics state
* to a text mode state.
*/
static int xxxfb_release(const struct fb_info *info, int user)
{
return 0;
}
/**
* xxxfb_check_var - Optional function. Validates a var passed in.
* @var: frame buffer variable screen structure
......@@ -143,7 +177,10 @@ int xxxfb_setup(char*);
* off by what the hardware can support then we alter the var PASSED in
* to what we can do. If the hardware doesn't support mode change
* a -EINVAL will be returned by the upper layers. You don't need to
* implement this function then.
* implement this function then. If you hardware doesn't support
* changing the resolution then this function is not needed. In this
* case the driver woudl just provide a var that represents the static
* state the screen is in.
*
* Returns negative errno on error, or zero on success.
*/
......@@ -164,6 +201,7 @@ static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
* fb_info since we are using that data. This means we depend on the
* data in var inside fb_info to be supported by the hardware.
* xxxfb_check_var is always called before xxxfb_set_par to ensure this.
* Again if you can't can't the resolution you don't need this function.
*
*/
static int xxxfb_set_par(struct fb_info *info)
......@@ -175,8 +213,8 @@ static int xxxfb_set_par(struct fb_info *info)
/**
* xxxfb_setcolreg - Optional function. Sets a color register.
* @regno: boolean, 0 copy local, 1 get_user() function
* @red: frame buffer colormap structure
* @regno: Which register in the CLUT we are programming
* @red: The red value which can be up to 16 bits wide
* @green: The green value which can be up to 16 bits wide
* @blue: The blue value which can be up to 16 bits wide.
* @transp: If supported the alpha value which can be up to 16 bits wide.
......@@ -283,12 +321,6 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0;
}
/**
* xxxfb_cursor -
*
* Returns negative errno on error, or zero on success.
*/
/**
* xxxfb_pan_display - NOT a required function. Pans the display.
* @var: frame buffer variable screen structure
......@@ -299,7 +331,6 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
* If the values don't fit, return -EINVAL.
*
* Returns negative errno on error, or zero on success.
*
*/
static int xxxfb_pan_display(struct fb_var_screeninfo *var,
const struct fb_info *info)
......@@ -335,12 +366,9 @@ static int xxxfb_blank(int blank_mode, const struct fb_info *info)
/*
* We provide our own functions if we have hardware acceleration
* or non packed pixel format layouts. If we have no hardware
* acceleration, we use a generic unaccelerated function. If using
* a pack pixel format just use the functions in cfb*.c. Each file
* has one of the three different accel functions we support. You
* can use these functions as fallbacks if hardware unsupported
* action is requested. Also if you have non pack pixel modes and
* non accelerated cards you have to provide your own functions.
* acceleration, we can use a generic unaccelerated function. If using
* a pack pixel format just use the functions in cfb_*.c. Each file
* has one of the three different accel functions we support.
*/
/**
......@@ -349,41 +377,52 @@ static int xxxfb_blank(int blank_mode, const struct fb_info *info)
* Draws a rectangle on the screen.
*
* @info: frame buffer structure that represents a single frame buffer
* @x1: The x and y corrdinates of the upper left hand corner of the
* @y1: area we want to draw to.
* @width: How wide the rectangle is we want to draw.
* @height: How tall the rectangle is we want to draw.
* @color: The color to fill in the rectangle with.
* @rop: The rater operation. We can draw the rectangle with a COPY
* of XOR which provides erasing effect.
* @region: The structure representing the rectangular region we
* wish to draw to.
*
* This drawing operation places/removes a retangle on the screen
* depending on the rastering operation with the value of color which
* is in the current color depth format.
*/
void xxxfb_fillrect(struct fb_info *p, struct fb_fillrect *region)
void xxfb_fillrect(struct fb_info *p, struct fb_fillrect *region)
{
/* Meaning of struct fb_fillrect
*
* @dx: The x and y corrdinates of the upper left hand corner of the
* @dy: area we want to draw to.
* @width: How wide the rectangle is we want to draw.
* @height: How tall the rectangle is we want to draw.
* @color: The color to fill in the rectangle with.
* @rop: The raster operation. We can draw the rectangle with a COPY
* of XOR which provides erasing effect.
*/
}
/**
* xxxfb_copyarea - REQUIRED function. Can use generic routines if
* non acclerated hardware and packed pixel based.
* Copies on area of the screen to another area.
* Copies one area of the screen to another area.
*
* @info: frame buffer structure that represents a single frame buffer
* @sx: The x and y corrdinates of the upper left hand corner of the
* @sy: source area on the screen.
* @width: How wide the rectangle is we want to copy.
* @height: How tall the rectangle is we want to copy.
* @dx: The x and y coordinates of the destination area on the screen.
* @area: Structure providing the data to copy the framebuffer contents
* from one region to another.
*
* This drawing operation copies a rectangular area from one area of the
* screen to another area.
*/
void xxxfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
{
/*
* @dx: The x and y coordinates of the upper left hand corner of the
* @dy: destination area on the screen.
* @width: How wide the rectangle is we want to copy.
* @height: How tall the rectangle is we want to copy.
* @sx: The x and y coordinates of the upper left hand corner of the
* @sy: source area on the screen.
*/
}
/**
* xxxfb_imageblit - REQUIRED function. Can use generic routines if
* non acclerated hardware and packed pixel based.
......@@ -398,9 +437,89 @@ void xxxfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
*/
void xxxfb_imageblit(struct fb_info *p, struct fb_image *image)
{
/*
* @dx: The x and y coordinates of the upper left hand corner of the
* @dy: destination area to place the image on the screen.
* @width: How wide the image is we want to copy.
* @height: How tall the image is we want to copy.
* @fg_color: For mono bitmap images this is color data for
* @bg_color: the foreground and background of the image to
* write directly to the frmaebuffer.
* @depth: How many bits represent a single pixel for this image.
* @data: The actual data used to construct the image on the display.
* @cmap: The colormap used for color images.
*/
}
/* ------------ Hardware Independent Functions ------------ */
/**
* xxxfb_cursor - REQUIRED function. If your hardware lacks support
* for a cursor you can use the default cursor whose
* function is called soft_cursor. It will always
* work since it uses xxxfb_imageblit function which
* is required.
*
* @info: frame buffer structure that represents a single frame buffer
* @cursor: structure defining the cursor to draw.
*
* This operation is used to set or alter the properities of the
* cursor.
*
* Returns negative errno on error, or zero on success.
*/
int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
/*
* @set: Which fields we are altering in struct fb_cursor
* @enable: Disable or enable the cursor
* @rop: The bit operation we want to do.
* @mask: This is the cursor mask bitmap.
* @dest: A image of the area we are going to display the cursor.
* Used internally by the driver.
* @hot: The hot spot.
* @image: The actual data for the cursor image.
*/
}
/**
* xxxfb_rotate - NOT a required function. If your hardware
* supports rotation the whole screen then
* you would provide a hook for this.
*
* @info: frame buffer structure that represents a single frame buffer
* @angle: The angle we rotate the screen.
*
* This operation is used to set or alter the properities of the
* cursor.
*/
void xxxfb_rotate(struct fb_info *info, int angle)
{
}
/**
* xxxfb_poll - NOT a required function. The purpose of this
* function is to provide a way for some process
* to wait until a specific hardware event occurs
* for the framebuffer device.
*
* @info: frame buffer structure that represents a single frame buffer
* @wait: poll table where we store process that await a event.
*/
void xxxfb_poll(struct fb_info *info, poll_table *wait)
{
}
/**
* xxxfb_sync - NOT a required function. Normally the accel engine
* for a graphics card take a specific amount of time.
* Often we have to wait for the accelerator to finish
* its operation before we can write to the framebuffer
* so we can have consistant display output.
*
* @info: frame buffer structure that represents a single frame buffer
*/
void xxxfb_sync(struct fb_info *info)
{
}
/*
* Initialization
......@@ -480,39 +599,32 @@ int __init xxxfb_setup(char *options)
/* Parse user speficied options (`video=xxxfb:') */
}
/* ------------------------------------------------------------------------- */
/*
* Frame buffer operations
*/
/* If all you need is that - just don't define ->fb_open */
static int xxxfb_open(const struct fb_info *info, int user)
{
return 0;
}
/* If all you need is that - just don't define ->fb_release */
static int xxxfb_release(const struct fb_info *info, int user)
{
return 0;
}
static struct fb_ops xxxfb_ops = {
.owner = THIS_MODULE,
.fb_open = xxxfb_open, /* only if you need it to do something */
.fb_release = xxxfb_release, /* only if you need it to do something */
.fb_open = xxxfb_open,
.fb_read = xxxfb_read,
.fb_write = xxxfb_write,
.fb_release = xxxfb_release,
.fb_check_var = xxxfb_check_var,
.fb_set_par = xxxfb_set_par, /* optional */
.fb_set_par = xxxfb_set_par,
.fb_setcolreg = xxxfb_setcolreg,
.fb_blank = xxxfb_blank, /* optional */
.fb_pan_display = xxxfb_pan_display, /* optional */
.fb_fillrect = xxxfb_fillrect,
.fb_copyarea = xxxfb_copyarea,
.fb_imageblit = xxxfb_imageblit,
.fb_ioctl = xxxfb_ioctl, /* optional */
.fb_mmap = xxxfb_mmap, /* optional */
.fb_blank = xxxfb_blank,
.fb_pan_display = xxxfb_pan_display,
.fb_fillrect = xxxfb_fillrect, /* Needed !!! */
.fb_copyarea = xxxfb_copyarea, /* Needed !!! */
.fb_imageblit = xxxfb_imageblit, /* Needed !!! */
.fb_cursor = xxxfb_cursor, /* Needed !!! */
.fb_rotate = xxxfb_rotate,
.fb_poll = xxxfb_poll,
.fb_sync = xxxfb_sync,
.fb_ioctl = xxxfb_ioctl,
.fb_mmap = xxxfb_mmap,
};
/* ------------------------------------------------------------------------- */
......
......@@ -1222,11 +1222,13 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
info->pseudo_palette = (void *)(default_par + 1);
info->flags = FBINFO_FLAG_DEFAULT;
#ifndef MODULE
if (!mode_option)
mode_option = "640x480@60";
err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
if (!err || err == 4)
#endif
info->var = tdfx_var;
size = (info->var.bits_per_pixel == 8) ? 256 : 16;
......
......@@ -416,6 +416,7 @@ struct fb_info {
#define fb_writeb sbus_writeb
#define fb_writew sbus_writew
#define fb_writel sbus_writel
#define fb_writeq sbus_writeq
#define fb_memset sbus_memset_io
#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__)
......@@ -426,6 +427,9 @@ struct fb_info {
#define fb_writeb __raw_writeb
#define fb_writew __raw_writew
#define fb_writel __raw_writel
#if defined(__alpha__) || defined(__hppa__) || defined(__ia64__)
#define fb_writeq __raw_writeq
#endif
#define fb_memset memset_io
#else
......
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