This patch (re) introduces support for the CG3 driver on Sun3, and for
BW2 on Sun3x. It applies cleanly to both the m68k CVS tree and the
vanilla tree.
Signed-off-by: Sam Creasey <[EMAIL PROTECTED]>
Index: linux-2.6.20/drivers/video/Kconfig
===================================================================
RCS file: /home/linux-m68k/cvsroot/linux/drivers/video/Kconfig,v
retrieving revision 1.12
diff -u -r1.12 Kconfig
--- linux-2.6.20/drivers/video/Kconfig 8 Feb 2007 02:48:52 -0000 1.12
+++ linux-2.6.20/drivers/video/Kconfig 3 Apr 2007 14:25:29 -0000
@@ -622,7 +622,13 @@
config FB_SUN3
bool "Sun3 framebuffer support"
- depends on (FB = y) && (SUN3 || SUN3X) && BROKEN
+ depends on (FB = y) && (SUN3 || SUN3X)
+ help
+ Support framebuffer devices on Sun3/3x. Note that if you say yes
+ here, any framebuffer drivers you select MUST be installed in the
+ target system, or be disabled on the command line. (e.g. if you
+ don't have a bw2, include video=bw2fb:off. If you don't have
+ a cg3, include video=cg3fb:off.)
config FB_SBUS
bool "SBUS and UPA framebuffers"
@@ -632,7 +638,7 @@
config FB_BW2
bool "BWtwo support"
- depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+ depends on (FB = y) && ((SPARC && FB_SBUS) || (SUN3X && FB_SUN3))
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -641,7 +647,7 @@
config FB_CG3
bool "CGthree support"
- depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+ depends on (FB = y) && ((SPARC && FB_SBUS) || (SUN3 && FB_SUN3))
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -650,7 +656,7 @@
config FB_CG6
bool "CGsix (GX,TurboGX) support"
- depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+ depends on (FB = y) && (SPARC && FB_SBUS)
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
Index: linux-2.6.20/drivers/video/Makefile
===================================================================
RCS file: /home/linux-m68k/cvsroot/linux/drivers/video/Makefile,v
retrieving revision 1.32
diff -u -r1.32 Makefile
--- linux-2.6.20/drivers/video/Makefile 8 Feb 2007 02:48:52 -0000 1.32
+++ linux-2.6.20/drivers/video/Makefile 3 Apr 2007 14:25:29 -0000
@@ -76,7 +76,6 @@
obj-$(CONFIG_FB_HP300) += hpfb.o
obj-$(CONFIG_FB_G364) += g364fb.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o
-obj-$(CONFIG_FB_SUN3) += sun3fb.o
obj-$(CONFIG_FB_HIT) += hitfb.o
obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
@@ -107,6 +106,7 @@
obj-$(CONFIG_FB_IMAC) += imacfb.o
obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o
obj-$(CONFIG_FB_OF) += offb.o
+obj-$(CONFIG_FB_SUN3) += p4lib.o
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
Index: linux-2.6.20/drivers/video/bw2.c
===================================================================
RCS file: /home/linux-m68k/cvsroot/linux/drivers/video/bw2.c,v
retrieving revision 1.1.1.12
diff -u -r1.1.1.12 bw2.c
--- linux-2.6.20/drivers/video/bw2.c 8 Feb 2007 00:40:09 -0000 1.1.1.12
+++ linux-2.6.20/drivers/video/bw2.c 3 Apr 2007 14:25:29 -0000
@@ -20,18 +20,29 @@
#include <asm/io.h>
#include <asm/oplib.h>
+#ifndef CONFIG_FB_SUN3
#include <asm/prom.h>
#include <asm/of_device.h>
+#endif
#include <asm/fbio.h>
#include "sbuslib.h"
+#ifdef CONFIG_FB_SUN3
+#ifdef CONFIG_SUN3
+#include <asm/sun3mmu.h>
+#endif
+#include <asm/machines.h>
+#include <asm/idprom.h>
+#include <asm/sbus.h>
+#include "p4lib.h"
+#endif
/*
* Local functions.
*/
-
+#ifndef CONFIG_FB_SUN3
static int bw2_blank(int, struct fb_info *);
-
+#endif
static int bw2_mmap(struct fb_info *, struct vm_area_struct *);
static int bw2_ioctl(struct fb_info *, unsigned int, unsigned long);
@@ -41,7 +52,11 @@
static struct fb_ops bw2_ops = {
.owner = THIS_MODULE,
+#ifdef CONFIG_FB_SUN3
+ .fb_blank = NULL,
+#else
.fb_blank = bw2_blank,
+#endif
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
@@ -53,7 +68,18 @@
};
/* OBio addresses for the bwtwo registers */
+#ifdef CONFIG_FB_SUN3
+/* sun3 series */
+#define BWTWO_OBMEM_ADDR 0x1f000000
+#define BWTWO_OBMEM_ADDR_50 0x00100000
+#define BWTWO_OBMEM_ADDR_P4 0x1f300000
+#define BWTWO_OBMEM_ADDR_3X 0x50300000
+/* is this true for 3/50? */
+#define BWTWO_FB_OFFSET 0x100000
+#define BWTWO_OBMEM_HIGHRES_60 0x1f1c0000
+#else
#define BWTWO_REGISTER_OFFSET 0x400000
+#endif
struct bt_regs {
u32 addr;
@@ -108,8 +134,11 @@
struct bw2_par {
spinlock_t lock;
+#ifdef CONFIG_FB_SUN3
+ volatile u32 *regs;
+#else
struct bw2_regs __iomem *regs;
-
+#endif
u32 flags;
#define BW2_FLAG_BLANKED 0x00000001
@@ -118,6 +147,7 @@
unsigned long fbsize;
};
+#ifndef CONFIG_FB_SUN3
/**
* bw2_blank - Optional function. Blanks the display.
* @blank_mode: the blank mode we want.
@@ -156,6 +186,7 @@
return 0;
}
+#endif
static struct sbus_mmap_map bw2_mmap_map[] = {
{
@@ -199,6 +230,17 @@
info->fix.accel = FB_ACCEL_SUN_BWTWO;
}
+struct all_info {
+ struct fb_info info;
+ struct bw2_par par;
+};
+/* CONFIG_FB_SUN3 has a different implementation for the remaining
+ functions, since:
+ 1) No OpenProm
+ 2) Fixed frequency
+ 3) No support for multiple BWtwo's */
+#ifndef CONFIG_FB_SUN3
+
static u8 bw2regs_1600[] __initdata = {
0x14, 0x8b, 0x15, 0x28, 0x16, 0x03, 0x17, 0x13,
0x18, 0x7b, 0x19, 0x05, 0x1a, 0x34, 0x1b, 0x2e,
@@ -279,11 +321,6 @@
}
}
-struct all_info {
- struct fb_info info;
- struct bw2_par par;
-};
-
static int __devinit bw2_init_one(struct of_device *op)
{
struct device_node *dp = op->node;
@@ -397,6 +434,187 @@
return of_unregister_driver(&bw2_driver);
}
+#else /* !CONFIG_FB_SUN3 */
+
+static struct all_info *bw2_all = NULL;
+
+static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
+ int *linebytes)
+{
+ int highres = 0;
+
+ if(idprom->id_machtype == (SM_SUN3|SM_3_260))
+ /* the 3/260 is allegedly always highres */
+ highres = 1;
+ if(idprom->id_machtype == (SM_SUN3|SM_3_60)) {
+#ifdef CONFIG_SUN3
+ /* we won't hit this unless running on a sun3 anyway */
+ volatile u32 *reg;
+ u32 il
+
+ reg = sun3_ioremap(BW2_OBMEM_HIGHRES_60, sizeof(u32),
+ SUN3_PAGE_TYPE_MEMORY);
+ i = *reg;
+ iounmap(reg);
+ if((i != -1) && (i& 0x80) == 0)
+ highres = 1;
+#endif
+ }
+
+ if(highres) {
+ info->var.xres = info->var.xres_virtual = 1600;
+ info->var.yres = info->var.yres_virtual = 1280;
+ *linebytes = 1600 / 8;
+ }
+}
+
+
+static int __devinit bw2_init_one(unsigned long phys_addr)
+{
+ struct all_info *all;
+ int linebytes, err, id;
+ unsigned long tmp;
+ all = kzalloc(sizeof(*all), GFP_KERNEL);
+ if (!all)
+ return -ENOMEM;
+
+ spin_lock_init(&all->par.lock);
+
+ all->par.physbase = phys_addr;
+
+#ifdef CONFIG_SUN3
+ all->par.regs = sun3_ioremap(phys_addr, sizeof(u32),
+ SUN3_PAGE_TYPE_MEMORY);
+#else
+ all->par.regs = ioremap_nocache(phys_addr, sizeof(u32));
+#endif
+ /* look for the p4 register, or assume we're OBIO if it's not found */
+ id = p4fb_get_id(all->par.regs);
+ printk("bwtwo: p4id %08x\n", id);
+
+ /* mutable memory address, probably save to say we've got an onboard fb
*/
+ if(id == -1) {
+ iounmap((void *)all->par.regs);
+ /* only currently supported on sun3. Perhaps someday sun4. */
+ if((idprom->id_machtype & SM_ARCH_MASK) != SM_SUN3) {
+ kfree(all);
+ return -ENODEV;
+ }
+
+ p4fb_fill_var(&all->info.var, NULL, 1);
+ bw2_do_default_mode(&all->par, &all->info, &linebytes);
+ } else {
+ if(id != P4_ID_BW2) {
+ kfree(all);
+ iounmap((void *)all->par.regs);
+ return -ENODEV;
+ }
+
+ p4fb_fill_var(&all->info.var, (volatile u32 *)all->par.regs, 1);
+ }
+
+ linebytes = all->info.var.xres / 8;
+
+ all->info.var.red.length = all->info.var.green.length =
+ all->info.var.blue.length = all->info.var.bits_per_pixel;
+ all->info.var.red.offset = all->info.var.green.offset =
+ all->info.var.blue.offset = 0;
+
+ all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+
+ all->info.flags = FBINFO_DEFAULT;
+ all->info.fbops = &bw2_ops;
+
+ if(id == -1) {
+#ifdef CONFIG_SUN3
+ all->info.screen_base = sun3_ioremap(phys_addr,
+ all->par.fbsize,
+ SUN3_PAGE_TYPE_MEMORY);
+#else
+ all->info.screen_base = ioremap(phys_addr,
+ all->par.fbsize);
+#endif
+ } else {
+#ifdef CONFIG_SUN3
+ all->info.screen_base = sun3_ioremap(phys_addr +
BWTWO_FB_OFFSET,
+ all->par.fbsize,
+ SUN3_PAGE_TYPE_MEMORY);
+#else
+ all->info.screen_base = ioremap(phys_addr + BWTWO_FB_OFFSET,
+ all->par.fbsize);
+#endif
+ }
+
+ p4fb_video_enable(all->par.regs);
+
+ all->info.par = &all->par;
+
+ bw2_init_fix(&all->info, linebytes);
+
+ err= register_framebuffer(&all->info);
+ if (err < 0) {
+ iounmap((void *)all->par.regs);
+ iounmap((void *)all->info.screen_base);
+ kfree(all);
+ return err;
+ }
+
+ bw2_all = all;
+
+ printk("%s: bwtwo at %lx\n",
+ all->info.fix.id, all->par.physbase);
+
+ return 0;
+}
+
+static int __init bw2_init(void)
+{
+ if(fb_get_options("bw2fb", NULL))
+ return -ENODEV;
+
+ if(bw2_all != NULL)
+ return -ENODEV;
+
+ /* currently only sun3/80 P4 is supported/tested */
+ switch(idprom->id_machtype) {
+ case SM_SUN3X|SM_3_80:
+ case SM_SUN3X|SM_3_460:
+ return bw2_init_one(BWTWO_OBMEM_ADDR_3X);
+
+ case SM_SUN3|SM_3_50:
+ return bw2_init_one(BWTWO_OBMEM_ADDR_50);
+
+ case SM_SUN3|SM_3_160:
+ case SM_SUN3|SM_3_260:
+ case SM_SUN3|SM_3_110:
+ case SM_SUN3|SM_3_60:
+ return bw2_init_one(BWTWO_OBMEM_ADDR);
+ default:
+ break;
+ }
+
+ return -ENODEV;
+
+}
+
+static void __exit bw2_exit(void)
+{
+ struct all_info *all = bw2_all;
+ if(bw2_all == NULL)
+ return;
+
+ unregister_framebuffer(&all->info);
+
+ iounmap((void *)all->par.regs);
+ iounmap((void *)all->info.screen_base);
+
+ kfree(all);
+
+ bw2_all = NULL;
+
+ return;
+}
+#endif /* CONFIG_FB_SUN3 */
module_init(bw2_init);
module_exit(bw2_exit);
Index: linux-2.6.20/drivers/video/cg3.c
===================================================================
RCS file: /home/linux-m68k/cvsroot/linux/drivers/video/cg3.c,v
retrieving revision 1.1.1.12
diff -u -r1.1.1.12 cg3.c
--- linux-2.6.20/drivers/video/cg3.c 8 Feb 2007 00:39:41 -0000 1.1.1.12
+++ linux-2.6.20/drivers/video/cg3.c 3 Apr 2007 14:25:29 -0000
@@ -20,12 +20,24 @@
#include <asm/io.h>
#include <asm/oplib.h>
+#ifndef CONFIG_FB_SUN3
#include <asm/prom.h>
#include <asm/of_device.h>
+#endif
#include <asm/fbio.h>
#include "sbuslib.h"
+#ifdef CONFIG_FB_SUN3
+#ifdef CONFIG_SUN3
+#include <asm/sun3mmu.h>
+#endif
+#include <asm/machines.h>
+#include <asm/idprom.h>
+#include <asm/sbus.h>
+#include "p4lib.h"
+#endif
+
/*
* Local functions.
*/
@@ -108,8 +120,16 @@
};
/* Offset of interesting structures in the OBIO space */
-#define CG3_REGS_OFFSET 0x400000UL
-#define CG3_RAM_OFFSET 0x800000UL
+#ifdef CONFIG_SUN3
+#define CGFOUR_OBMEM_ADDR_60 0x1f000000
+#define CGFOUR_OBMEM_ADDR_110 0x1f300000
+#define CG3_REGS_OFFSET (-0x100000)
+#define CG3_RAM_OFFSET 0x500000UL
+#else
+#define CG3_REGS_OFFSET 0x400000UL
+#define CG3_RAM_OFFSET 0x800000UL
+#endif
+
struct cg3_par {
spinlock_t lock;
@@ -251,6 +271,18 @@
* Initialisation
*/
+struct all_info {
+ struct fb_info info;
+ struct cg3_par par;
+};
+
+
+/* CONFIG_FB_SUN3 has a different implementation for the remaining
+ functions, since:
+ 1) No OpenProm
+ 2) Fixed frequency
+ 3) No support for multiple CGthree's */
+#ifndef CONFIG_FB_SUN3
static void
cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
{
@@ -352,13 +384,9 @@
regp = (u8 __iomem *)&par->regs->cmap.control;
sbus_writeb(p[1], regp);
}
+
}
-struct all_info {
- struct fb_info info;
- struct cg3_par par;
-};
-
static int __devinit cg3_init_one(struct of_device *op)
{
struct device_node *dp = op->node;
@@ -427,8 +455,8 @@
dev_set_drvdata(&op->dev, all);
- printk("%s: cg3 at %lx:%lx\n",
- dp->full_name, all->par.which_io, all->par.physbase);
+ printk("%s: cg3 at %lx\n",
+ dp->full_name, all->par.physbase);
return 0;
}
@@ -488,6 +516,172 @@
of_unregister_driver(&cg3_driver);
}
+#else /* !CONFIG_FB_SUN3 */
+static void
+cg3_init_fix(struct fb_info *info, int linebytes)
+{
+
+ strcpy(info->fix.id, "SUN3 CG3");
+
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ info->fix.line_length = linebytes;
+
+ info->fix.accel = FB_ACCEL_SUN_CGTHREE;
+}
+static void cg3_do_default_mode(struct cg3_par *par)
+{
+ /* kick up the sun3 -- 66hz prom mode only */
+ /* this also turns off the overlay in case it's really a cg4 */
+
+ par->regs->cmap.addr = 4;
+ par->regs->cmap.control = 0xff;
+ par->regs->cmap.addr = 5;
+ par->regs->cmap.control = 0;
+ par->regs->cmap.addr = 6;
+ par->regs->cmap.control = 0x40;
+ par->regs->cmap.addr = 7;
+ par->regs->cmap.control = 0;
+
+}
+
+/* The Sun3 version of this driver only supports one cgthree.
+ This really isn't an issue, because it also only supports
+ the 3/60 OBIO cg3, and not vme cards (of which there could be more
+ than one) */
+static struct all_info *cg3_all = NULL;
+
+static int __devinit cg3_init_one(unsigned long phys_addr)
+{
+ struct all_info *all;
+ int linebytes, err;
+ volatile u32 *p4reg = NULL;
+
+ all = kzalloc(sizeof(*all), GFP_KERNEL);
+ if (!all)
+ return -ENOMEM;
+
+ spin_lock_init(&all->par.lock);
+
+ all->par.physbase = phys_addr;
+
+#if 0
+ /* it would be nice to use p4 registers here, but it appears
+ * some P4 framebuffers don't actually have useful data.
+ * So we just plod along regardless */
+ p4reg = sun3_ioremap(all->par.physbase, sizeof(u32),
+ SUN3_PAGE_TYPE_MEMORY);
+ id = p4fb_get_id(p4reg);
+ printk("cg3: p4id %08x\n", *p4reg);
+
+ if(id != P4_ID_CG4) {
+ iounmap((void *)p4reg);
+ kfree(all);
+ return -ENODEV;
+ }
+
+#endif
+ p4fb_fill_var(&all->info.var, p4reg, 8);
+ if(p4reg != NULL)
+ iounmap((void *)p4reg);
+
+ all->info.var.red.length = 8;
+ all->info.var.green.length = 8;
+ all->info.var.blue.length = 8;
+ linebytes = all->info.var.xres;
+
+ all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+
+ all->par.regs = (struct cg3_regs *)
+ sun3_ioremap(all->par.physbase + CG3_REGS_OFFSET,
+ sizeof(struct cg3_regs), SUN3_PAGE_TYPE_MEMORY);
+
+
+ all->info.flags = FBINFO_DEFAULT;
+ all->info.fbops = &cg3_ops;
+ all->info.screen_base = (char *)
+ sun3_ioremap(all->par.physbase + CG3_RAM_OFFSET,
+ all->par.fbsize, SUN3_PAGE_TYPE_MEMORY);
+ all->info.par = &all->par;
+
+ cg3_blank(0, &all->info);
+
+ cg3_do_default_mode(&all->par);
+
+ if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+ kfree(all);
+ return -ENOMEM;
+ }
+
+ fb_set_cmap(&all->info.cmap, &all->info);
+
+ cg3_init_fix(&all->info, linebytes);
+
+ err = register_framebuffer(&all->info);
+ if (err < 0) {
+ fb_dealloc_cmap(&all->info.cmap);
+ iounmap(all->par.regs);
+ iounmap(all->info.screen_base);
+ kfree(all);
+ return err;
+ }
+
+ cg3_all = all;
+
+ printk("%s: cg3 at %lx\n",
+ all->info.fix.id, all->par.physbase);
+
+ return 0;
+}
+
+static int __init cg3_init(void)
+{
+ if (fb_get_options("cg3fb", NULL))
+ return -ENODEV;
+
+ if(cg3_all != NULL)
+ return -ENODEV;
+
+ /* currently only sun3/60 P4 is supported/tested */
+ switch(idprom->id_machtype) {
+ case SM_SUN3|SM_3_60:
+ return cg3_init_one(CGFOUR_OBMEM_ADDR_60);
+
+ case SM_SUN3|SM_3_110:
+ /* 3/110 is a guess, no 3/110 to test on */
+ return cg3_init_one(CGFOUR_OBMEM_ADDR_110);
+
+ default:
+ break;
+ }
+
+ return -ENODEV;
+}
+
+static void __exit cg3_exit(void)
+{
+ struct all_info *all = cg3_all;
+
+ if(cg3_all == NULL)
+ return;
+
+ unregister_framebuffer(&all->info);
+ fb_dealloc_cmap(&all->info.cmap);
+
+ iounmap(all->par.regs);
+ iounmap(all->info.screen_base);
+
+ kfree(all);
+
+ cg3_all = NULL;
+
+ return;
+
+}
+
+#endif /* CONFIG_FB_SUN3 */
+
module_init(cg3_init);
module_exit(cg3_exit);
Index: linux-2.6.20/drivers/video/p4lib.c
===================================================================
RCS file: linux-2.6.20/drivers/video/p4lib.c
diff -N linux-2.6.20/drivers/video/p4lib.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6.20/drivers/video/p4lib.c 3 Apr 2007 14:25:29 -0000
@@ -0,0 +1,107 @@
+/* p4lib.c: Helper library for Sun P4 framebuffer drivers
+ *
+ * Copyright (C) 2007 Sam Creasey ([EMAIL PROTECTED])
+ */
+
+#include <linux/compat.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <linux/fb.h>
+
+#include "p4lib.h"
+
+int p4fb_get_id(volatile u32 *p4reg)
+{
+
+#ifdef CONFIG_SUN3
+ /* this code makes the 3x cry, and it can't have onboard fb anyway */
+ u32 x, old;
+
+ /* attempt to read the id bit back from the p4 register, if
+ * we're able to modify the value, conclude there's no p4
+ * device there. This should enable us to determine if we're
+ * dealing with, for example, a builtin bw2 or a p4 bw2. */
+
+ old = *p4reg;
+ x = old & ~P4_CTRL_RESET;
+
+ *p4reg = x ^ P4_ID_MASK;
+ if((*p4reg ^ x) & P4_ID_MASK) {
+ /* we managed to change the type bits, not a p4 port */
+ *p4reg = old;
+ return -1;
+ }
+#endif
+ return ((*p4reg) & P4_ID_MASK) >> P4_ID_SHIFT;
+}
+
+int p4fb_get_res(volatile u32 *p4reg)
+{
+ return ((*p4reg) & P4_RES_MASK) >> P4_RES_SHIFT;
+}
+
+void p4fb_video_enable(volatile u32 *p4reg)
+{
+ u32 x;
+
+ x = *p4reg;
+ x &= ~(P4_CTRL_VIDEO_EN | P4_CTRL_INT);
+ x |= P4_CTRL_VIDEO_EN;
+ *p4reg = x;
+
+}
+
+/* This function basically assumes that p4fb_get_id returns a sane
+ * value for this card/instance. If this was not true, calling with
+ * NULL for p4reg will return the defaults */
+void p4fb_fill_var(struct fb_var_screeninfo *var, volatile u32 *p4reg, int bpp)
+{
+ memset(var, 0, sizeof(*var));
+
+ if(p4reg == NULL) {
+ var->xres = 1152;
+ var->yres = 900;
+ } else {
+ switch(p4fb_get_res(p4reg)) {
+ case P4_RES_1600X1280:
+ var->xres = 1600;
+ var->yres = 1280;
+ break;
+ case P4_RES_1152X900:
+ var->xres = 1152;
+ var->yres = 900;
+ break;
+ case P4_RES_1024X1024:
+ var->xres = 1024;
+ var->yres = 1024;
+ break;
+ case P4_RES_1280X1024:
+ var->xres = 1280;
+ var->yres = 1024;
+ break;
+ case P4_RES_1440X1440:
+ var->xres = 1440;
+ var->yres = 1400;
+ break;
+ case P4_RES_640X480:
+ var->xres = 640;
+ var->yres = 480;
+ break;
+ default:
+ /* this may or may not be the right thing to
+ * do here, but plod on anyway */
+ var->xres = 1152;
+ var->yres = 900;
+ break;
+ }
+ }
+
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+ var->bits_per_pixel = bpp;
+}
+
+EXPORT_SYMBOL(p4fb_get_id);
+EXPORT_SYMBOL(p4fb_get_res);
+EXPORT_SYMBOL(p4fb_fill_var);
Index: linux-2.6.20/drivers/video/p4lib.h
===================================================================
RCS file: linux-2.6.20/drivers/video/p4lib.h
diff -N linux-2.6.20/drivers/video/p4lib.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6.20/drivers/video/p4lib.h 3 Apr 2007 14:25:29 -0000
@@ -0,0 +1,56 @@
+/* p4lib.h: helper functions for p4 framebuffers */
+
+#ifndef _P4LIB_H
+#define _P4LIB_H
+
+/* register defintions applicable to p4 framebuffers found on some
+ Sun3/3x machines (and some Sun4 machines, though these are not
+ currently supported or tested). These machines have a single 32bit
+ register at the start of the p4 address space.
+
+ The format of this register is as follows:
+
+ bit 31 : unused
+ bits 30-28: type
+ bits 27-24: resolution
+ bits 23-8: unused
+ bits 7-0: status/control
+
+ The CG8 may break this format, if that turns out to be true, I'll
+ fix once I have a CG8 to test against...
+*/
+
+/* control register, lower 8bits */
+#define P4_CTRL_DIAG 0x80 /* ??? */
+#define P4_CTRL_RBCLR 0x40 /* ??? */
+#define P4_CTRL_VIDEO_EN 0x20 /* enable video */
+#define P4_CTRL_SYNC 0x10 /* ??? */
+#define P4_CTRL_VTRACE 0x08 /* ??? */
+#define P4_CTRL_INT 0x04 /* read: int pending, write: clear int */
+#define P4_CTRL_INT_EN 0x02 /* enable interrupts */
+#define P4_CTRL_RESET 0x01 /* reset */
+
+/* framebuffer identification -- bits 31-28 */
+#define P4_ID_MASK 0x70000000
+#define P4_ID_SHIFT 24
+#define P4_ID_BW2 0x00
+#define P4_ID_CG4 0x40 /* supported in linux as a cg3 */
+#define P4_ID_CG6 0x60
+
+/* framebuffer resolution - bits 27-24 */
+#define P4_RES_MASK 0x0f000000
+#define P4_RES_SHIFT 24
+#define P4_RES_1600X1280 0x00
+#define P4_RES_1152X900 0x01 /* only tested resolution */
+#define P4_RES_1024X1024 0x02
+#define P4_RES_1280X1024 0x03
+#define P4_RES_1440X1440 0x04
+#define P4_RES_640X480 0x05
+
+/* actual helper functions */
+extern int p4fb_get_id(volatile u32 *p4reg);
+extern int p4fb_get_res(volatile u32 *p4reg);
+extern void p4fb_video_enable(volatile u32 *p4reg);
+extern void p4fb_fill_var(struct fb_var_screeninfo *var, volatile u32 *p4reg,
int bpp);
+
+#endif /* P4LIB_H */
Index: linux-2.6.20/drivers/video/sbuslib.c
===================================================================
RCS file: /home/linux-m68k/cvsroot/linux/drivers/video/sbuslib.c,v
retrieving revision 1.1.1.11
diff -u -r1.1.1.11 sbuslib.c
--- linux-2.6.20/drivers/video/sbuslib.c 18 Jun 2006 15:08:12 -0000
1.1.1.11
+++ linux-2.6.20/drivers/video/sbuslib.c 3 Apr 2007 14:25:29 -0000
@@ -13,6 +13,10 @@
#include <asm/oplib.h>
#include <asm/fbio.h>
+#if defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
+#include <asm/uaccess.h>
+#endif
+
#include "sbuslib.h"
void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp)
@@ -21,6 +25,7 @@
var->xres = prom_getintdefault(prom_node, "width", 1152);
var->yres = prom_getintdefault(prom_node, "height", 900);
+
var->xres_virtual = var->xres;
var->yres_virtual = var->yres;
var->bits_per_pixel = bpp;
@@ -80,12 +85,20 @@
}
if (page + map_size > size)
map_size = size - page;
+#if !defined(CONFIG_FB_SUN3)
r = io_remap_pfn_range(vma,
vma->vm_start + page,
MK_IOSPACE_PFN(iospace,
map_offset >> PAGE_SHIFT),
map_size,
vma->vm_page_prot);
+#else
+ r = io_remap_pfn_range(vma,
+ vma->vm_start + page,
+ map_offset, map_size,
+ vma->vm_page_prot);
+#endif
+
if (r)
return -EAGAIN;
page += map_size;
Index: linux-2.6.20/drivers/video/sun3fb.c
===================================================================
RCS file: linux-2.6.20/drivers/video/sun3fb.c
diff -N linux-2.6.20/drivers/video/sun3fb.c
--- linux-2.6.20/drivers/video/sun3fb.c 23 Sep 2006 17:01:27 -0000 1.1.1.9
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,702 +0,0 @@
-/*
- * linux/drivers/video/sun3fb.c -- Frame buffer driver for Sun3
- *
- * (C) 1998 Thomas Bogendoerfer
- *
- * This driver is bases on sbusfb.c, which is
- *
- * Copyright (C) 1998 Jakub Jelinek
- *
- * This driver is partly based on the Open Firmware console driver
- *
- * Copyright (C) 1997 Geert Uytterhoeven
- *
- * and SPARC console subsystem
- *
- * Copyright (C) 1995 Peter Zaitcev ([EMAIL PROTECTED])
- * Copyright (C) 1995-1997 David S. Miller ([EMAIL PROTECTED])
- * Copyright (C) 1995-1996 Miguel de Icaza ([EMAIL PROTECTED])
- * Copyright (C) 1996 Dave Redman ([EMAIL PROTECTED])
- * Copyright (C) 1996-1998 Jakub Jelinek ([EMAIL PROTECTED])
- * Copyright (C) 1996 Eddie C. Dost ([EMAIL PROTECTED])
- *
- * 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/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/selection.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kd.h>
-#include <linux/vt_kern.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h> /* io_remap_page_range() */
-
-#ifdef CONFIG_SUN3
-#include <asm/oplib.h>
-#include <asm/machines.h>
-#include <asm/idprom.h>
-
-#define CGFOUR_OBMEM_ADDR 0x1f300000
-#define BWTWO_OBMEM_ADDR 0x1f000000
-#define BWTWO_OBMEM50_ADDR 0x00100000
-
-#endif
-#ifdef CONFIG_SUN3X
-#include <asm/sun3x.h>
-#endif
-#include <video/sbusfb.h>
-
-#define DEFAULT_CURSOR_BLINK_RATE (2*HZ/5)
-
-#define CURSOR_SHAPE 1
-#define CURSOR_BLINK 2
-
-#define mymemset(x,y) memset(x,0,y)
-
- /*
- * Interface used by the world
- */
-
-int sun3fb_init(void);
-void sun3fb_setup(char *options);
-
-static char fontname[40] __initdata = { 0 };
-static int curblink __initdata = 1;
-
-static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int sun3fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int sun3fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
-static int sun3fb_blank(int blank, struct fb_info *info);
-static void sun3fb_cursor(struct display *p, int mode, int x, int y);
-static void sun3fb_clear_margin(struct display *p, int s);
-
- /*
- * Interface to the low level console driver
- */
-
-static int sun3fbcon_switch(int con, struct fb_info *info);
-static int sun3fbcon_updatevar(int con, struct fb_info *info);
-
- /*
- * Internal routines
- */
-
-static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
-
-static struct fb_ops sun3fb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = sun3fb_get_fix,
- .fb_get_var = sun3fb_get_var,
- .fb_set_var = sun3fb_set_var,
- .fb_get_cmap = sun3fb_get_cmap,
- .fb_set_cmap = sun3fb_set_cmap,
- .fb_setcolreg = sun3fb_setcolreg,
- .fb_blank = sun3fb_blank,
-};
-
-static void sun3fb_clear_margin(struct display *p, int s)
-{
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- return;
-
- if (fb->switch_from_graph)
- (*fb->switch_from_graph)(fb);
- if (fb->fill) {
- unsigned short rects [16];
-
- rects [0] = 0;
- rects [1] = 0;
- rects [2] = fb->var.xres_virtual;
- rects [3] = fb->y_margin;
- rects [4] = 0;
- rects [5] = fb->y_margin;
- rects [6] = fb->x_margin;
- rects [7] = fb->var.yres_virtual;
- rects [8] = fb->var.xres_virtual - fb->x_margin;
- rects [9] = fb->y_margin;
- rects [10] = fb->var.xres_virtual;
- rects [11] = fb->var.yres_virtual;
- rects [12] = fb->x_margin;
- rects [13] = fb->var.yres_virtual - fb->y_margin;
- rects [14] = fb->var.xres_virtual - fb->x_margin;
- rects [15] = fb->var.yres_virtual;
- (*fb->fill)(fb, p, s, 4, rects);
- } else {
- unsigned char *fb_base = fb->info.screen_base, *q;
- int skip_bytes = fb->y_margin * fb->var.xres_virtual;
- int scr_size = fb->var.xres_virtual * fb->var.yres_virtual;
- int h, he, incr, size;
-
- he = fb->var.yres;
- if (fb->var.bits_per_pixel == 1) {
- fb_base -= (skip_bytes + fb->x_margin) / 8;
- skip_bytes /= 8;
- scr_size /= 8;
- mymemset (fb_base, skip_bytes - fb->x_margin / 8);
- mymemset (fb_base + scr_size - skip_bytes +
fb->x_margin / 8, skip_bytes - fb->x_margin / 8);
- incr = fb->var.xres_virtual / 8;
- size = fb->x_margin / 8 * 2;
- for (q = fb_base + skip_bytes - fb->x_margin / 8, h = 0;
- h <= he; q += incr, h++)
- mymemset (q, size);
- } else {
- fb_base -= (skip_bytes + fb->x_margin);
- memset (fb_base, attr_bgcol(p,s), skip_bytes -
fb->x_margin);
- memset (fb_base + scr_size - skip_bytes + fb->x_margin,
attr_bgcol(p,s), skip_bytes - fb->x_margin);
- incr = fb->var.xres_virtual;
- size = fb->x_margin * 2;
- for (q = fb_base + skip_bytes - fb->x_margin, h = 0;
- h <= he; q += incr, h++)
- memset (q, attr_bgcol(p,s), size);
- }
- }
-}
-
-static void sun3fb_disp_setup(struct display *p)
-{
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- if (fb->setup)
- fb->setup(p);
- sun3fb_clear_margin(p, 0);
-}
-
- /*
- * Get the Fixed Part of the Display
- */
-
-static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- memcpy(fix, &fb->fix, sizeof(struct fb_fix_screeninfo));
- return 0;
-}
-
- /*
- * Get the User Defined Part of the Display
- */
-
-static int sun3fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
- return 0;
-}
-
- /*
- * Set the User Defined Part of the Display
- */
-
-static int sun3fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (var->xres > fb->var.xres || var->yres > fb->var.yres ||
- var->xres_virtual > fb->var.xres_virtual ||
- var->yres_virtual > fb->var.yres_virtual ||
- var->bits_per_pixel != fb->var.bits_per_pixel ||
- var->nonstd ||
- (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
- return -EINVAL;
- memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
- return 0;
-}
-
- /*
- * Hardware cursor
- */
-
-static unsigned char hw_cursor_cmap[2] = { 0, 0xff };
-
-static void
-sun3fb_cursor_timer_handler(unsigned long dev_addr)
-{
- struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)dev_addr;
-
- if (!fb->setcursor) return;
-
- if (fb->cursor.mode & CURSOR_BLINK) {
- fb->cursor.enable ^= 1;
- fb->setcursor(fb);
- }
-
- fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate;
- add_timer(&fb->cursor.timer);
-}
-
-static void sun3fb_cursor(struct display *p, int mode, int x, int y)
-{
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- switch (mode) {
- case CM_ERASE:
- fb->cursor.mode &= ~CURSOR_BLINK;
- fb->cursor.enable = 0;
- (*fb->setcursor)(fb);
- break;
-
- case CM_MOVE:
- case CM_DRAW:
- if (fb->cursor.mode & CURSOR_SHAPE) {
- fb->cursor.size.fbx = fontwidth(p);
- fb->cursor.size.fby = fontheight(p);
- fb->cursor.chot.fbx = 0;
- fb->cursor.chot.fby = 0;
- fb->cursor.enable = 1;
- memset (fb->cursor.bits, 0, sizeof (fb->cursor.bits));
- fb->cursor.bits[0][fontheight(p) - 2] = (0xffffffff <<
(32 - fontwidth(p)));
- fb->cursor.bits[1][fontheight(p) - 2] = (0xffffffff <<
(32 - fontwidth(p)));
- fb->cursor.bits[0][fontheight(p) - 1] = (0xffffffff <<
(32 - fontwidth(p)));
- fb->cursor.bits[1][fontheight(p) - 1] = (0xffffffff <<
(32 - fontwidth(p)));
- (*fb->setcursormap) (fb, hw_cursor_cmap,
hw_cursor_cmap, hw_cursor_cmap);
- (*fb->setcurshape) (fb);
- }
- fb->cursor.mode = CURSOR_BLINK;
- if (fontwidthlog(p))
- fb->cursor.cpos.fbx = (x << fontwidthlog(p)) +
fb->x_margin;
- else
- fb->cursor.cpos.fbx = (x * fontwidth(p)) + fb->x_margin;
- if (fontheightlog(p))
- fb->cursor.cpos.fby = (y << fontheightlog(p)) +
fb->y_margin;
- else
- fb->cursor.cpos.fby = (y * fontheight(p)) +
fb->y_margin;
- (*fb->setcursor)(fb);
- break;
- }
-}
-
- /*
- * Get the Colormap
- */
-
-static int sun3fb_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, sun3fb_getcolreg, info);
- else if (fb_display[con].cmap.len) /* non default colormap? */
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
-
fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc
? 0 : 2);
- return 0;
-}
-
- /*
- * Set the Colormap
- */
-
-static int sun3fb_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? */
- if ((err = fb_alloc_cmap(&fb_display[con].cmap,
1<<fb_display[con].var.bits_per_pixel, 0)))
- return err;
- }
- if (con == info->currcon) { /* current console? */
- err = fb_set_cmap(cmap, kspc, info);
- if (!err) {
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (fb->loadcmap)
- (*fb->loadcmap)(fb, &fb_display[con],
cmap->start, cmap->len);
- }
- return err;
- } else
- fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
- return 0;
-}
-
- /*
- * Setup: parse used options
- */
-
-void __init sun3fb_setup(char *options)
-{
- char *p;
-
- for (p = options;;) {
- if (!strncmp(p, "font=", 5)) {
- int i;
-
- for (i = 0; i < sizeof(fontname) - 1; i++)
- if (p[i+5] == ' ' || !p[i+5])
- break;
- memcpy(fontname, p+5, i);
- fontname[i] = 0;
- } else if (!strncmp(p, "noblink", 7))
- curblink = 0;
- while (*p && *p != ' ' && *p != ',') p++;
- if (*p != ',') break;
- p++;
- }
-
- return;
-}
-
-static int sun3fbcon_switch(int con, struct fb_info *info)
-{
- int x_margin, y_margin;
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
- int lastconsole;
-
- /* Do we have to save the colormap? */
- if (fb_display[info->currcon].cmap.len)
- fb_get_cmap(&fb_display[info->currcon].cmap, 1,
sun3fb_getcolreg, info);
-
- if (info->display_fg) {
- lastconsole = info->display_fg->vc_num;
- if (lastconsole != con &&
- (fontwidth(&fb_display[lastconsole]) !=
fontwidth(&fb_display[con]) ||
- fontheight(&fb_display[lastconsole]) !=
fontheight(&fb_display[con])))
- fb->cursor.mode |= CURSOR_SHAPE;
- }
- x_margin = (fb_display[con].var.xres_virtual -
fb_display[con].var.xres) / 2;
- y_margin = (fb_display[con].var.yres_virtual -
fb_display[con].var.yres) / 2;
- if (fb->margins)
- fb->margins(fb, &fb_display[con], x_margin, y_margin);
- if (fb->graphmode || fb->x_margin != x_margin || fb->y_margin !=
y_margin) {
- fb->x_margin = x_margin; fb->y_margin = y_margin;
- sun3fb_clear_margin(&fb_display[con], 0);
- }
- info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con, info);
- return 0;
-}
-
- /*
- * Update the `var' structure (called by fbcon.c)
- */
-
-static int sun3fbcon_updatevar(int con, struct fb_info *info)
-{
- /* Nothing */
- return 0;
-}
-
- /*
- * Blank the display.
- */
-
-static int sun3fb_blank(int blank, struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (blank && fb->blank)
- return fb->blank(fb);
- else if (!blank && fb->unblank)
- return fb->unblank(fb);
- return 0;
-}
-
- /*
- * Read a single color register and split it into
- * colors/transparent. Return != 0 for invalid regno.
- */
-
-static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (!fb->color_map || regno > 255)
- return 1;
- *red = (fb->color_map CM(regno, 0)<<8) | fb->color_map CM(regno, 0);
- *green = (fb->color_map CM(regno, 1)<<8) | fb->color_map CM(regno, 1);
- *blue = (fb->color_map CM(regno, 2)<<8) | fb->color_map CM(regno, 2);
- *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 sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (!fb->color_map || regno > 255)
- return 1;
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- fb->color_map CM(regno, 0) = red;
- fb->color_map CM(regno, 1) = green;
- fb->color_map CM(regno, 2) = blue;
- return 0;
-}
-
-static int sun3fb_set_font(struct display *p, int width, int height)
-{
- int w = p->var.xres_virtual, h = p->var.yres_virtual;
- int depth = p->var.bits_per_pixel;
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
- int x_margin, y_margin;
-
- if (depth > 8) depth = 8;
- x_margin = (w % width) / 2;
- y_margin = (h % height) / 2;
-
- p->var.xres = w - 2*x_margin;
- p->var.yres = h - 2*y_margin;
-
- fb->cursor.mode |= CURSOR_SHAPE;
-
- if (fb->margins)
- fb->margins(fb, p, x_margin, y_margin);
- if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
- fb->x_margin = x_margin; fb->y_margin = y_margin;
- sun3fb_clear_margin(p, 0);
- }
-
- return 1;
-}
-
-void sun3fb_palette(int enter)
-{
- int i;
- struct display *p;
-
- for (i = 0; i < MAX_NR_CONSOLES; i++) {
- p = &fb_display[i];
- if (p->dispsw && p->dispsw->setup == sun3fb_disp_setup &&
- p->fb_info->display_fg &&
- p->fb_info->display_fg->vc_num == i) {
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- if (fb->restore_palette) {
- if (enter)
- fb->restore_palette(fb);
- else if (vc_cons[i].d->vc_mode != KD_GRAPHICS)
-
vc_cons[i].d->vc_sw->con_set_palette(vc_cons[i].d, color_table);
- }
- }
- }
-}
-
- /*
- * Initialisation
- */
-static int __init sun3fb_init_fb(int fbtype, unsigned long addr)
-{
- static struct sbus_dev sdb;
- struct fb_fix_screeninfo *fix;
- struct fb_var_screeninfo *var;
- struct display *disp;
- struct fb_info_sbusfb *fb;
- struct fbtype *type;
- int linebytes, w, h, depth;
- char *p = NULL;
-
- fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC);
- if (!fb)
- return -ENOMEM;
-
- memset(fb, 0, sizeof(struct fb_info_sbusfb));
- fix = &fb->fix;
- var = &fb->var;
- disp = &fb->disp;
- type = &fb->type;
-
- sdb.reg_addrs[0].phys_addr = addr;
- fb->sbdp = &sdb;
-
- type->fb_type = fbtype;
-
- type->fb_height = h = 900;
- type->fb_width = w = 1152;
-sizechange:
- type->fb_depth = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8;
- linebytes = w * depth / 8;
- type->fb_size = PAGE_ALIGN((linebytes) * h);
-/*
- fb->x_margin = (w & 7) / 2;
- fb->y_margin = (h & 15) / 2;
-*/
- fb->x_margin = fb->y_margin = 0;
-
- var->xres_virtual = w;
- var->yres_virtual = h;
- var->xres = w - 2*fb->x_margin;
- var->yres = h - 2*fb->y_margin;
-
- var->bits_per_pixel = depth;
- var->height = var->width = -1;
- var->pixclock = 10000;
- var->vmode = FB_VMODE_NONINTERLACED;
- var->red.length = var->green.length = var->blue.length = 8;
-
- fix->line_length = linebytes;
- fix->smem_len = type->fb_size;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
-
- fb->info.fbops = &sun3fb_ops;
- fb->info.disp = disp;
- fb->info.currcon = -1;
- strcpy(fb->info.fontname, fontname);
- fb->info.changevar = NULL;
- fb->info.switch_con = &sun3fbcon_switch;
- fb->info.updatevar = &sun3fbcon_updatevar;
- fb->info.flags = FBINFO_FLAG_DEFAULT;
-
- fb->cursor.hwsize.fbx = 32;
- fb->cursor.hwsize.fby = 32;
-
- if (depth > 1 && !fb->color_map) {
- if((fb->color_map = kmalloc(256 * 3, GFP_ATOMIC))==NULL)
- return -ENOMEM;
- }
-
- switch(fbtype) {
-#ifdef CONFIG_FB_CGSIX
- case FBTYPE_SUNFAST_COLOR:
- p = cgsixfb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_BWTWO
- case FBTYPE_SUN2BW:
- p = bwtwofb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_CGTHREE
- case FBTYPE_SUN4COLOR:
- case FBTYPE_SUN3COLOR:
- type->fb_size = 0x100000;
- p = cgthreefb_init(fb); break;
-#endif
- }
- fix->smem_start = (unsigned long)fb->info.screen_base; // FIXME
-
- if (!p) {
- kfree(fb);
- return -ENODEV;
- }
-
- if (p == SBUSFBINIT_SIZECHANGE)
- goto sizechange;
-
- disp->dispsw = &fb->dispsw;
- if (fb->setcursor) {
- fb->dispsw.cursor = sun3fb_cursor;
- if (curblink) {
- fb->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE;
- init_timer(&fb->cursor.timer);
- fb->cursor.timer.expires = jiffies +
fb->cursor.blink_rate;
- fb->cursor.timer.data = (unsigned long)fb;
- fb->cursor.timer.function = sun3fb_cursor_timer_handler;
- add_timer(&fb->cursor.timer);
- }
- }
- fb->cursor.mode = CURSOR_SHAPE;
- fb->dispsw.set_font = sun3fb_set_font;
- fb->setup = fb->dispsw.setup;
- fb->dispsw.setup = sun3fb_disp_setup;
- fb->dispsw.clear_margins = NULL;
-
- disp->var = *var;
- disp->visual = fix->visual;
- disp->type = fix->type;
- disp->type_aux = fix->type_aux;
- disp->line_length = fix->line_length;
-
- if (fb->blank)
- disp->can_soft_blank = 1;
-
- sun3fb_set_var(var, -1, &fb->info);
-
- if (register_framebuffer(&fb->info) < 0) {
- kfree(fb);
- return -EINVAL;
- }
- printk("fb%d: %s\n", fb->info.node, p);
-
- return 0;
-}
-
-
-int __init sun3fb_init(void)
-{
- extern int con_is_present(void);
- unsigned long addr;
- char p4id;
-
- if (!con_is_present()) return -ENODEV;
-#ifdef CONFIG_SUN3
- switch(*(romvec->pv_fbtype))
- {
- case FBTYPE_SUN2BW:
- addr = 0xfe20000;
- return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
- case FBTYPE_SUN3COLOR:
- case FBTYPE_SUN4COLOR:
- if(idprom->id_machtype != (SM_SUN3|SM_3_60)) {
- printk("sun3fb: cgthree/four only supported on 3/60\n");
- return -ENODEV;
- }
-
- addr = CGFOUR_OBMEM_ADDR;
- return sun3fb_init_fb(*(romvec->pv_fbtype), addr);
- default:
- printk("sun3fb: unsupported framebuffer\n");
- return -ENODEV;
- }
-#else
- addr = SUN3X_VIDEO_BASE;
- p4id = *(char *)SUN3X_VIDEO_P4ID;
-
- p4id = (p4id == 0x45) ? p4id : (p4id & 0xf0);
- switch (p4id) {
- case 0x00:
- return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
-#if 0 /* not yet */
- case 0x40:
- return sun3fb_init_fb(FBTYPE_SUN4COLOR, addr);
- break;
- case 0x45:
- return sun3fb_init_fb(FBTYPE_SUN8COLOR, addr);
- break;
-#endif
- case 0x60:
- return sun3fb_init_fb(FBTYPE_SUNFAST_COLOR, addr);
- }
-#endif
-
- return -ENODEV;
-}
-
-MODULE_LICENSE("GPL");
-
To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html