From 57b55f79cf948142372a36c7f92d4a416b28e8ea Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 26 Feb 2003 20:33:18 -0800 Subject: [PATCH] [FRAMEBUFFER]: Convert bw2, cg6, and cg3 drivers to new APIs. --- drivers/video/Kconfig | 6 +- drivers/video/Makefile | 9 +- drivers/video/bw2.c | 448 +++++++++++++++++++++ drivers/video/bwtwofb.c | 269 ------------- drivers/video/cg3.c | 507 +++++++++++++++++++++++ drivers/video/cg6.c | 793 ++++++++++++++++++++++++++++++++++++ drivers/video/cgsixfb.c | 824 -------------------------------------- drivers/video/cgthreefb.c | 286 ------------- drivers/video/fbmem.c | 15 + 9 files changed, 1771 insertions(+), 1386 deletions(-) create mode 100644 drivers/video/bw2.c delete mode 100644 drivers/video/bwtwofb.c create mode 100644 drivers/video/cg3.c create mode 100644 drivers/video/cg6.c delete mode 100644 drivers/video/cgsixfb.c delete mode 100644 drivers/video/cgthreefb.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 39edc0c2b2e40..9e5516a88cd67 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -376,19 +376,19 @@ config FB_SUN3 bool "Sun3 framebuffer support" depends on FB && (SUN3 || SUN3X) -config FB_BWTWO +config FB_BW2 bool "BWtwo support" depends on FB && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) help This is the frame buffer device driver for the BWtwo frame buffer. -config FB_CGTHREE +config FB_CG3 bool "CGthree support" depends on FB && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) help This is the frame buffer device driver for the CGthree frame buffer. -config FB_CGSIX +config FB_CG6 bool "CGsix (GX,TurboGX) support" depends on FB && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) help diff --git a/drivers/video/Makefile b/drivers/video/Makefile index b5fb29910e69d..6c8f5603783ba 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -71,16 +71,17 @@ obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_VOODOO1) += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o # One by one these are being converted over to the new APIs -#obj-$(CONFIG_FB_CREATOR) += creatorfb.o sbusfb.o -#obj-$(CONFIG_FB_CGSIX) += cgsixfb.o sbusfb.o -#obj-$(CONFIG_FB_BWTWO) += bwtwofb.o sbusfb.o -#obj-$(CONFIG_FB_CGTHREE) += cgthreefb.o sbusfb.o #obj-$(CONFIG_FB_TCX) += tcxfb.o sbusfb.o #obj-$(CONFIG_FB_CGFOURTEEN) += cgfourteenfb.o sbusfb.o #obj-$(CONFIG_FB_P9100) += p9100fb.o sbusfb.o #obj-$(CONFIG_FB_LEO) += leofb.o sbusfb.o obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o cfbimgblt.o cfbcopyarea.o +obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o cfbimgblt.o cfbcopyarea.o +obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o cfbimgblt.o cfbcopyarea.o \ + cfbfillrect.o +obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o cfbimgblt.o cfbcopyarea.o \ + cfbfillrect.o # Files generated that shall be removed upon make clean clean-files := promcon_tbl.c diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c new file mode 100644 index 0000000000000..fd6da67b84964 --- /dev/null +++ b/drivers/video/bw2.c @@ -0,0 +1,448 @@ +/* bw2.c: BWTWO frame buffer driver + * + * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) + * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) + * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) + * + * Driver layout based loosely on tgafb.c, see that file for credits. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_SPARC32 +#include +#endif + +#include "sbuslib.h" + +/* + * Local functions. + */ + +static int bw2_check_var(struct fb_var_screeninfo *, struct fb_info *); +static int bw2_set_par(struct fb_info *); +static int bw2_blank(int, struct fb_info *); + +static int bw2_mmap(struct fb_info *, struct file *, struct vm_area_struct *); + +/* + * Frame buffer operations + */ + +static struct fb_ops bw2_ops = { + .owner = THIS_MODULE, + .fb_check_var = bw2_check_var, + .fb_set_par = bw2_set_par, + .fb_blank = bw2_blank, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_mmap = bw2_mmap, + .fb_cursor = soft_cursor, +}; + +/* OBio addresses for the bwtwo registers */ +#define BWTWO_REGISTER_OFFSET 0x400000 + +struct bt_regs { + volatile u32 addr; + volatile u32 color_map; + volatile u32 control; + volatile u32 cursor; +}; + +struct bw2_regs { + struct bt_regs cmap; + volatile u8 control; + volatile u8 status; + volatile u8 cursor_start; + volatile u8 cursor_end; + volatile u8 h_blank_start; + volatile u8 h_blank_end; + volatile u8 h_sync_start; + volatile u8 h_sync_end; + volatile u8 comp_sync_end; + volatile u8 v_blank_start_high; + volatile u8 v_blank_start_low; + volatile u8 v_blank_end; + volatile u8 v_sync_start; + volatile u8 v_sync_end; + volatile u8 xfer_holdoff_start; + volatile u8 xfer_holdoff_end; +}; + +/* Status Register Constants */ +#define BWTWO_SR_RES_MASK 0x70 +#define BWTWO_SR_1600_1280 0x50 +#define BWTWO_SR_1152_900_76_A 0x40 +#define BWTWO_SR_1152_900_76_B 0x60 +#define BWTWO_SR_ID_MASK 0x0f +#define BWTWO_SR_ID_MONO 0x02 +#define BWTWO_SR_ID_MONO_ECL 0x03 +#define BWTWO_SR_ID_MSYNC 0x04 +#define BWTWO_SR_ID_NOCONN 0x0a + +/* Control Register Constants */ +#define BWTWO_CTL_ENABLE_INTS 0x80 +#define BWTWO_CTL_ENABLE_VIDEO 0x40 +#define BWTWO_CTL_ENABLE_TIMING 0x20 +#define BWTWO_CTL_ENABLE_CURCMP 0x10 +#define BWTWO_CTL_XTAL_MASK 0x0C +#define BWTWO_CTL_DIVISOR_MASK 0x03 + +/* Status Register Constants */ +#define BWTWO_STAT_PENDING_INT 0x80 +#define BWTWO_STAT_MSENSE_MASK 0x70 +#define BWTWO_STAT_ID_MASK 0x0f + +struct bw2_par { + spinlock_t lock; + struct bw2_regs *regs; + + u32 flags; +#define BW2_FLAG_BLANKED 0x00000001 + + unsigned long physbase; + unsigned long fbsize; + + struct sbus_dev *sdev; + struct list_head list; +}; + +/** + * bw2_check_var - Optional function. Validates a var passed in. + * @var: frame buffer variable screen structure + * @info: frame buffer structure that represents a single frame buffer + */ +static int bw2_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + if (var->bits_per_pixel != 8) + return -EINVAL; + + if (var->xres_virtual != var->xres || var->yres_virtual != var->yres) + return -EINVAL; + if (var->nonstd) + return -EINVAL; + if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) + return -EINVAL; + + if (var->xres != info->var.xres || var->yres != info->var.yres) + return -EINVAL; + + return 0; +} + +/** + * bw2_set_par - Optional function. Alters the hardware state. + * @info: frame buffer structure that represents a single frame buffer + */ +static int +bw2_set_par(struct fb_info *info) +{ + return 0; +} + +/** + * bw2_blank - Optional function. Blanks the display. + * @blank_mode: the blank mode we want. + * @info: frame buffer structure that represents a single frame buffer + */ +static int +bw2_blank(int blank, struct fb_info *info) +{ + struct bw2_par *par = (struct bw2_par *) info->par; + struct bw2_regs *regs = par->regs; + unsigned long flags; + u8 val; + + spin_lock_irqsave(&par->lock, flags); + + switch (blank) { + case 0: /* Unblanking */ + val = sbus_readb(®s->control); + val |= BWTWO_CTL_ENABLE_VIDEO; + sbus_writeb(val, ®s->control); + par->flags &= ~BW2_FLAG_BLANKED; + break; + + case 1: /* Normal blanking */ + case 2: /* VESA blank (vsync off) */ + case 3: /* VESA blank (hsync off) */ + case 4: /* Poweroff */ + val = sbus_readb(®s->control); + val &= ~BWTWO_CTL_ENABLE_VIDEO; + sbus_writeb(val, ®s->control); + par->flags |= BW2_FLAG_BLANKED; + break; + } + + spin_unlock_irqrestore(&par->lock, flags); + + return 0; +} + +static struct sbus_mmap_map bw2_mmap_map[] = { + { 0, 0, SBUS_MMAP_FBSIZE(1) }, + { 0, 0, 0 } +}; + +static int bw2_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) +{ + struct bw2_par *par = (struct bw2_par *)info->par; + + return sbusfb_mmap_helper(bw2_mmap_map, + par->physbase, par->fbsize, + (par->sdev ? + par->sdev->reg_addrs[0].which_io : + 0), + vma); +} + +/* + * Initialisation + */ + +static void +bw2_init_fix(struct fb_info *info, int linebytes) +{ + strncpy(info->fix.id, "bwtwo", sizeof(info->fix.id) - 1); + info->fix.id[sizeof(info->fix.id)-1] = 0; + + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_MONO01; + + info->fix.line_length = linebytes; + + info->fix.accel = FB_ACCEL_SUN_BWTWO; +} + +static u8 bw2regs_1600[] __initdata = { + 0x14, 0x8b, 0x15, 0x28, 0x16, 0x03, 0x17, 0x13, + 0x18, 0x7b, 0x19, 0x05, 0x1a, 0x34, 0x1b, 0x2e, + 0x1c, 0x00, 0x1d, 0x0a, 0x1e, 0xff, 0x1f, 0x01, + 0x10, 0x21, 0 +}; + +static u8 bw2regs_ecl[] __initdata = { + 0x14, 0x65, 0x15, 0x1e, 0x16, 0x04, 0x17, 0x0c, + 0x18, 0x5e, 0x19, 0x03, 0x1a, 0xa7, 0x1b, 0x23, + 0x1c, 0x00, 0x1d, 0x08, 0x1e, 0xff, 0x1f, 0x01, + 0x10, 0x20, 0 +}; + +static u8 bw2regs_analog[] __initdata = { + 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x03, 0x17, 0x13, + 0x18, 0xb0, 0x19, 0x03, 0x1a, 0xa6, 0x1b, 0x22, + 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01, + 0x10, 0x20, 0 +}; + +static u8 bw2regs_76hz[] __initdata = { + 0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f, + 0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a, + 0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01, + 0x10, 0x24, 0 +}; + +static u8 bw2regs_66hz[] __initdata = { + 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14, + 0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24, + 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01, + 0x10, 0x20, 0 +}; + +static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info, + int *linebytes) +{ + u8 status, mon; + u8 *p; + + status = sbus_readb(&par->regs->status); + mon = status & BWTWO_SR_RES_MASK; + switch (status & BWTWO_SR_ID_MASK) { + case BWTWO_SR_ID_MONO_ECL: + if (mon == BWTWO_SR_1600_1280) { + p = bw2regs_1600; + info->var.xres = info->var.xres_virtual = 1600; + info->var.yres = info->var.yres_virtual = 1280; + *linebytes = 1600 / 8; + } else + p = bw2regs_ecl; + break; + + case BWTWO_SR_ID_MONO: + p = bw2regs_analog; + break; + + case BWTWO_SR_ID_MSYNC: + if (mon == BWTWO_SR_1152_900_76_A || + mon == BWTWO_SR_1152_900_76_B) + p = bw2regs_76hz; + else + p = bw2regs_66hz; + break; + + case BWTWO_SR_ID_NOCONN: + return; + + default: + prom_printf("bw2: can't handle SR %02x\n", + status); + prom_halt(); + } + for ( ; *p; p += 2) { + u8 *regp = &((u8 *)par->regs)[p[0]]; + sbus_writeb(p[1], regp); + } +} + +struct all_info { + struct fb_info info; + struct bw2_par par; + struct list_head list; +}; +static LIST_HEAD(bw2_list); + +static void bw2_init_one(struct sbus_dev *sdev) +{ + struct all_info *all; + struct resource *resp; +#ifdef CONFIG_SUN4 + struct resource res; +#endif + int linebytes; + + all = kmalloc(sizeof(*all), GFP_KERNEL); + if (!all) { + printk(KERN_ERR "bw2: Cannot allocate memory.\n"); + return; + } + memset(all, 0, sizeof(*all)); + + INIT_LIST_HEAD(&all->list); + + spin_lock_init(&all->par.lock); + all->par.sdev = sdev; + +#ifdef CONFIG_SUN4 + if (!sdev) { + all->par.physbase = sun4_bwtwo_physaddr; + res.start = sun4_bwtwo_physaddr; + res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1; + res.flags = IORESOURCE_IO; + resp = &res; + all->info.var.xres = all->info.var.xres_virtual = 1152; + all->info.var.yres = all->info.var.yres_virtual = 900; + all->info.bits_per_pixel = 1; + linebytes = 1152 / 8; + } else +#else + { + if (!sdev) + BUG(); + all->par.physbase = sdev->reg_addrs[0].phys_addr; + resp = &sdev->resource[0]; + sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1); + linebytes = prom_getintdefault(sdev->prom_node, "linebytes", + all->info.var.xres); + } +#endif + + all->par.regs = (struct bw2_regs *) + sbus_ioremap(resp, BWTWO_REGISTER_OFFSET, + sizeof(struct bw2_regs), "bw2 regs"); + + if (sdev && !prom_getbool(sdev->prom_node, "width")) + bw2_do_default_mode(&all->par, &all->info, &linebytes); + + all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); + + all->info.node = NODEV; + all->info.flags = FBINFO_FLAG_DEFAULT; + all->info.fbops = &bw2_ops; +#if defined(CONFIG_SPARC32) + if (sdev) + all->info.screen_base = (char *) + prom_getintdefault(sdev->prom_node, "address", 0); +#endif + if (!all->info.screen_base) + all->info.screen_base = (char *) + sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram"); + all->info.currcon = -1; + all->info.par = &all->par; + + bw2_blank(0, &all->info); + + bw2_set_par(&all->info); + bw2_init_fix(&all->info, linebytes); + + if (register_framebuffer(&all->info) < 0) { + printk(KERN_ERR "bw2: Could not register framebuffer.\n"); + kfree(all); + return; + } + + list_add(&all->list, &bw2_list); + + printk("bw2: bwtwo at %lx:%lx\n", + (long) (sdev ? sdev->reg_addrs[0].which_io : 0), + (long) all->par.physbase); +} + +int __init bw2_init(void) +{ + struct sbus_bus *sbus; + struct sbus_dev *sdev; + +#ifdef CONFIG_SUN4 + bw2_init_one(NULL); +#endif + for_all_sbusdev(sdev, sbus) { + if (!strcmp(sdev->prom_name, "bwtwo")) + bw2_init_one(sdev); + } + + return 0; +} + +void __exit bw2_exit(void) +{ + struct list_head *pos, *tmp; + + list_for_each_safe(pos, tmp, &bw2_list) { + struct all_info *all = list_entry(pos, typeof(*all), list); + + unregister_framebuffer(&all->info); + kfree(all); + } +} + +int __init +bw2_setup(char *arg) +{ + /* No cmdline options yet... */ + return 0; +} + +#ifdef MODULE +module_init(bw2_init); +module_exit(bw2_exit); +#endif + +MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets"); +MODULE_AUTHOR("David S. Miller "); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/bwtwofb.c b/drivers/video/bwtwofb.c deleted file mode 100644 index 6bb31d6be2c95..0000000000000 --- a/drivers/video/bwtwofb.c +++ /dev/null @@ -1,269 +0,0 @@ -/* $Id: bwtwofb.c,v 1.15 2001/09/19 00:04:33 davem Exp $ - * bwtwofb.c: BWtwo frame buffer driver - * - * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) - * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 1998 Pavel Machek (pavel@ucw.cz) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include