Commit e30b0dc2 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5

into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
parents ab6671e9 e7f92f43
......@@ -15,12 +15,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_LOG_BUF_SHIFT_17 is not set
# CONFIG_LOG_BUF_SHIFT_16 is not set
CONFIG_LOG_BUF_SHIFT_15=y
# CONFIG_LOG_BUF_SHIFT_14 is not set
# CONFIG_LOG_BUF_SHIFT_13 is not set
# CONFIG_LOG_BUF_SHIFT_12 is not set
CONFIG_LOG_BUF_SHIFT=15
#
......@@ -30,6 +24,7 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
#
......@@ -45,6 +40,7 @@ CONFIG_SMP=y
CONFIG_NR_CPUS=4
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_PROC_INTF=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_US3_FREQ=m
CONFIG_SPARC64=y
CONFIG_HOTPLUG=y
......@@ -89,15 +85,52 @@ CONFIG_WATCHDOG_RIO=m
#
# Graphics support
#
# CONFIG_FB is not set
CONFIG_FB=y
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_BW2 is not set
# CONFIG_FB_CG3 is not set
CONFIG_FB_CG6=y
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_PM3 is not set
CONFIG_FB_SBUS=y
CONFIG_FB_FFB=y
# CONFIG_FB_TCX is not set
# CONFIG_FB_CG14 is not set
# CONFIG_FB_P9100 is not set
# CONFIG_FB_LEO is not set
# CONFIG_FB_PCI is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_PROM_CONSOLE=y
# CONFIG_PROM_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_PCI_CONSOLE=y
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FONT_SUN8x16=y
# CONFIG_FONT_SUN12x22 is not set
CONFIG_FONTS=y
# CONFIG_FONT_8x8 is not set
# CONFIG_FONT_8x16 is not set
# CONFIG_FONT_6x11 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
#
# Serial drivers
......@@ -110,7 +143,7 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_SERIAL_SUNCORE=y
CONFIG_SERIAL_SUNZILOG=y
CONFIG_SERIAL_SUNSU=y
# CONFIG_SERIAL_SUNSAB is not set
CONFIG_SERIAL_SUNSAB=m
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
......@@ -190,7 +223,7 @@ CONFIG_BLK_DEV_ADMA=y
CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
......@@ -198,7 +231,7 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
......@@ -221,9 +254,9 @@ CONFIG_SCSI=y
#
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
CONFIG_CHR_DEV_SG=m
......@@ -320,11 +353,12 @@ CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_XFRM_USER=m
CONFIG_IPV6=m
CONFIG_IPV6_PRIVACY=y
#
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=y
CONFIG_IPV6_SCTP__=m
CONFIG_IP_SCTP=m
# CONFIG_SCTP_ADLER32 is not set
# CONFIG_SCTP_DBG_MSG is not set
......@@ -395,6 +429,7 @@ CONFIG_TUN=m
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
CONFIG_SUNLANCE=y
CONFIG_HAPPYMEAL=y
CONFIG_SUNBMAC=m
......@@ -402,6 +437,7 @@ CONFIG_SUNQE=m
CONFIG_SUNGEM=y
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
#
# Tulip family network device support
......@@ -419,9 +455,11 @@ CONFIG_NET_PCI=y
CONFIG_PCNET32=m
# CONFIG_AMD8111_ETH is not set
CONFIG_ADAPTEC_STARFIRE=m
CONFIG_ADAPTEC_STARFIRE_NAPI=y
CONFIG_B44=m
CONFIG_DGRS=m
CONFIG_EEPRO100=m
# CONFIG_EEPRO100_PIO is not set
CONFIG_E100=m
CONFIG_FEALNX=m
CONFIG_NATSEMI=m
......@@ -940,6 +978,7 @@ CONFIG_BT_USB_ZERO_PACKET=y
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_BCSP_TXCRC=y
CONFIG_BT_HCIVHCI=m
#
......
......@@ -114,6 +114,8 @@ extern void _do_write_unlock(rwlock_t *rw);
extern unsigned long phys_base;
extern unsigned long pfn_base;
extern unsigned int sys_call_table[];
/* used by various drivers */
#ifdef CONFIG_SMP
#ifndef CONFIG_DEBUG_SPINLOCK
......@@ -374,3 +376,6 @@ EXPORT_SYMBOL(do_BUG);
/* for ns8703 */
EXPORT_SYMBOL(ns87303_lock);
/* for solaris compat module */
EXPORT_SYMBOL_GPL(sys_call_table);
......@@ -16,6 +16,7 @@
#include <asm/signal.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/thread_info.h>
#include "conv.h"
......
......@@ -520,7 +520,7 @@ static void happy_meal_tcvr_write(struct happy_meal *hp,
ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value));
/* Welcome to Sun Microsystems, can I take your order please? */
if (!hp->happy_flags & HFLAG_FENABLE)
if (!(hp->happy_flags & HFLAG_FENABLE))
return happy_meal_bb_write(hp, tregs, reg, value);
/* Would you like fries with that? */
......
......@@ -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
......@@ -809,30 +809,30 @@ config FB_SBUS
help
Say Y if you want support for SBUS or UPA based frame buffer device.
config FB_CREATOR
bool "Creator/Creator3D support"
config FB_FFB
bool "Creator/Creator3D/Elite3D support"
depends on FB_SBUS && SPARC64
help
This is the frame buffer device driver for the Creator and Creator3D
graphics boards.
This is the frame buffer device driver for the Creator, Creator3D,
and Elite3D graphics boards.
config FB_TCX
bool "TCX (SS4/SS5 only) support"
depends on FB_SBUS && SPARC32
depends on FB_SBUS
help
This is the frame buffer device driver for the TCX 24/8bit frame
buffer.
config FB_CGFOURTEEN
config FB_CG14
bool "CGfourteen (SX) support"
depends on FB_SBUS && SPARC32
depends on FB_SBUS
help
This is the frame buffer device driver for the CGfourteen frame
buffer on Desktop SPARCsystems with the SX graphics option.
config FB_P9100
bool "P9100 (Sparcbook 3 only) support"
depends on FB_SBUS && SPARC32
depends on FB_SBUS
help
This is the frame buffer device driver for the P9100 card
supported on Sparcbook 3 machines.
......
......@@ -48,14 +48,6 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o cfbfillrect.o cfbcopyarea.o \
obj-$(CONFIG_FB_VIRGE) += virgefb.o
obj-$(CONFIG_FB_G364) += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
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_STI) += stifb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
......@@ -78,6 +70,22 @@ obj-$(CONFIG_FB_E1355) += epson1355fb.o
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_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
obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
cfbfillrect.o
obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
cfbfillrect.o
obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
cfbfillrect.o
# Files generated that shall be removed upon make clean
clean-files := promcon_tbl.c
......
This diff is collapsed.
/* $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 <linux/config.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/selection.h>
#include <video/sbusfb.h>
#include <asm/io.h>
#if !defined(__sparc_v9__) && !defined(__mc68000__)
#include <asm/sun4paddr.h>
#endif
#include <video/fbcon-mfb.h>
/* OBio addresses for the bwtwo registers */
#define BWTWO_REGISTER_OFFSET 0x400000
struct bw2_regs {
struct bt_regs bt;
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
static struct sbus_mmap_map bw2_mmap_map[] = {
{ 0, 0, SBUS_MMAP_FBSIZE(1) },
{ 0, 0, 0 }
};
static int bw2_blank (struct fb_info_sbusfb *fb)
{
unsigned long flags;
u8 tmp;
spin_lock_irqsave(&fb->lock, flags);
tmp = sbus_readb(&fb->s.bw2.regs->control);
tmp &= ~BWTWO_CTL_ENABLE_VIDEO;
sbus_writeb(tmp, &fb->s.bw2.regs->control);
spin_unlock_irqrestore(&fb->lock, flags);
return 0;
}
static int bw2_unblank (struct fb_info_sbusfb *fb)
{
unsigned long flags;
u8 tmp;
spin_lock_irqsave(&fb->lock, flags);
tmp = sbus_readb(&fb->s.bw2.regs->control);
tmp |= BWTWO_CTL_ENABLE_VIDEO;
sbus_writeb(tmp, &fb->s.bw2.regs->control);
spin_unlock_irqrestore(&fb->lock, flags);
return 0;
}
static void bw2_margins (struct fb_info_sbusfb *fb, struct display *p,
int x_margin, int y_margin)
{
fb->info.screen_base += (y_margin - fb->y_margin) *
p->fb_info->fix.line_length + ((x_margin - fb->x_margin) >> 3);
}
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 char idstring[60] __initdata = { 0 };
char __init *bwtwofb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->info.fix;
struct display *disp = &fb->disp;
struct fbtype *type = &fb->type;
#ifdef CONFIG_SUN4
unsigned long phys = sun4_bwtwo_physaddr;
struct resource res;
#else
unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
#endif
struct resource *resp;
unsigned int vaddr;
#ifndef FBCON_HAS_MFB
return NULL;
#endif
#ifdef CONFIG_SUN4
res.start = phys;
res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
res.flags = IORESOURCE_IO | (fb->iospace & 0xff);
resp = &res;
#else
resp = &fb->sbdp->resource[0];
#endif
if (!fb->s.bw2.regs) {
fb->s.bw2.regs = (struct bw2_regs *)
sbus_ioremap(resp, BWTWO_REGISTER_OFFSET,
sizeof(struct bw2_regs), "bw2 regs");
if ((!ARCH_SUN4) && (!prom_getbool(fb->prom_node, "width"))) {
/* Ugh, broken PROM didn't initialize us.
* Let's deal with this ourselves.
*/
u8 status, mon;
u8 *p;
int sizechange = 0;
status = sbus_readb(&fb->s.bw2.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;
fb->type.fb_width = 1600;
fb->type.fb_height = 1280;
sizechange = 1;
} 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 NULL;
default:
#ifndef CONFIG_FB_SUN3
prom_printf("bw2: can't handle SR %02x\n",
status);
prom_halt();
#endif
return NULL; /* fool gcc. */
}
for ( ; *p; p += 2) {
u8 *regp = &((u8 *)fb->s.bw2.regs)[p[0]];
sbus_writeb(p[1], regp);
}
}
}
strcpy(fb->info.modename, "BWtwo");
strcpy(fix->id, "BWtwo");
fix->line_length = fb->info.var.xres_virtual >> 3;
fix->accel = FB_ACCEL_SUN_BWTWO;
disp->scrollmode = SCROLL_YREDRAW;
disp->inverse = 1;
if (!fb->info.screen_base) {
fb->info.screen_base = (char *)
sbus_ioremap(resp, 0, type->fb_size, "bw2 ram");
}
fb->info.screen_base += fix->line_length * fb->y_margin + (fb->x_margin >> 3);
fb->dispsw = fbcon_mfb;
fix->visual = FB_VISUAL_MONO01;
#ifndef CONFIG_SUN4
fb->blank = bw2_blank;
fb->unblank = bw2_unblank;
prom_getproperty(fb->sbdp->prom_node, "address",
(char *)&vaddr, sizeof(vaddr));
fb->physbase = __get_phys((unsigned long)vaddr);
#endif
fb->margins = bw2_margins;
fb->mmap_map = bw2_mmap_map;
#ifdef __sparc_v9__
sprintf(idstring, "bwtwo at %016lx", phys);
#else
sprintf(idstring, "bwtwo at %x.%08lx", fb->iospace, phys);
#endif
return idstring;
}
MODULE_LICENSE("GPL");
......@@ -65,14 +65,14 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
// Single word
if (last)
first &= last;
FB_WRITEL((*src & first) | (FB_READL(dst) & ~first),
FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first),
dst);
} else {
// Multiple destination words
// Leading bits
if (first) {
FB_WRITEL((*src & first) | (FB_READL(dst) &
FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) &
~first), dst);
dst++;
src++;
......@@ -82,21 +82,21 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
// Main chunk
n /= BITS_PER_LONG;
while (n >= 8) {
FB_WRITEL(*src++, dst++);
FB_WRITEL(*src++, dst++);
FB_WRITEL(*src++, dst++);
FB_WRITEL(*src++, dst++);
FB_WRITEL(*src++, dst++);
FB_WRITEL(*src++, dst++);
FB_WRITEL(*src++, dst++);
FB_WRITEL(*src++, dst++);
FB_WRITEL(FB_READL(src++), dst++);
FB_WRITEL(FB_READL(src++), dst++);
FB_WRITEL(FB_READL(src++), dst++);
FB_WRITEL(FB_READL(src++), dst++);
FB_WRITEL(FB_READL(src++), dst++);
FB_WRITEL(FB_READL(src++), dst++);
FB_WRITEL(FB_READL(src++), dst++);
FB_WRITEL(FB_READL(src++), dst++);
n -= 8;
}
while (n--)
FB_WRITEL(*src++, dst++);
FB_WRITEL(FB_READL(src++), dst++);
// Trailing bits
if (last)
FB_WRITEL((*src & last) | (FB_READL(dst) &
FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) &
~last), dst);
}
} else {
......@@ -111,22 +111,22 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
first &= last;
if (shift > 0) {
// Single source word
FB_WRITEL(((*src >> right) & first) |
FB_WRITEL(((FB_READL(src) >> right) & first) |
(FB_READL(dst) & ~first), dst);
} else if (src_idx+n <= BITS_PER_LONG) {
// Single source word
FB_WRITEL(((*src << left) & first) |
FB_WRITEL(((FB_READL(src) << left) & first) |
(FB_READL(dst) & ~first), dst);
} else {
// 2 source words
d0 = *src++;
d1 = *src;
d0 = FB_READL(src++);
d1 = FB_READL(src);
FB_WRITEL(((d0<<left | d1>>right) & first) |
(FB_READL(dst) & ~first), dst);
}
} else {
// Multiple destination words
d0 = *src++;
d0 = FB_READL(src++);
// Leading bits
if (shift > 0) {
// Single source word
......@@ -136,7 +136,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
n -= BITS_PER_LONG-dst_idx;
} else {
// 2 source words
d1 = *src++;
d1 = FB_READL(src++);
FB_WRITEL(((d0<<left | d1>>right) & first) |
(FB_READL(dst) & ~first), dst);
d0 = d1;
......@@ -148,22 +148,22 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
m = n % BITS_PER_LONG;
n /= BITS_PER_LONG;
while (n >= 4) {
d1 = *src++;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
d0 = d1;
d1 = *src++;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
d0 = d1;
d1 = *src++;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
d0 = d1;
d1 = *src++;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
d0 = d1;
n -= 4;
}
while (n--) {
d1 = *src++;
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
d0 = d1;
}
......@@ -177,7 +177,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
dst);
} else {
// 2 source words
d1 = *src;
d1 = FB_READL(src);
FB_WRITEL(((d0<<left | d1>>right) &
last) | (FB_READL(dst) &
~last), dst);
......@@ -220,13 +220,13 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
// Single word
if (last)
first &= last;
FB_WRITEL((*src & first) | (FB_READL(dst) & ~first),
FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first),
dst);
} else {
// Multiple destination words
// Leading bits
if (first) {
FB_WRITEL((*src & first) | (FB_READL(dst) &
FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) &
~first), dst);
dst--;
src--;
......@@ -236,22 +236,22 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
// Main chunk
n /= BITS_PER_LONG;
while (n >= 8) {
FB_WRITEL(*src--, dst--);
FB_WRITEL(*src--, dst--);
FB_WRITEL(*src--, dst--);
FB_WRITEL(*src--, dst--);
FB_WRITEL(*src--, dst--);
FB_WRITEL(*src--, dst--);
FB_WRITEL(*src--, dst--);
FB_WRITEL(*src--, dst--);
FB_WRITEL(FB_READL(src--), dst--);
FB_WRITEL(FB_READL(src--), dst--);
FB_WRITEL(FB_READL(src--), dst--);
FB_WRITEL(FB_READL(src--), dst--);
FB_WRITEL(FB_READL(src--), dst--);
FB_WRITEL(FB_READL(src--), dst--);
FB_WRITEL(FB_READL(src--), dst--);
FB_WRITEL(FB_READL(src--), dst--);
n -= 8;
}
while (n--)
FB_WRITEL(*src--, dst--);
FB_WRITEL(FB_READL(src--), dst--);
// Trailing bits
if (last)
FB_WRITEL((*src & last) | (FB_READL(dst) &
FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) &
~last), dst);
}
} else {
......@@ -266,22 +266,22 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
first &= last;
if (shift < 0) {
// Single source word
FB_WRITEL((*src << left & first) |
FB_WRITEL((FB_READL(src) << left & first) |
(FB_READL(dst) & ~first), dst);
} else if (1+(unsigned long)src_idx >= n) {
// Single source word
FB_WRITEL(((*src >> right) & first) |
FB_WRITEL(((FB_READL(src) >> right) & first) |
(FB_READL(dst) & ~first), dst);
} else {
// 2 source words
d0 = *src--;
d1 = *src;
d0 = FB_READL(src--);
d1 = FB_READL(src);
FB_WRITEL(((d0>>right | d1<<left) & first) |
(FB_READL(dst) & ~first), dst);
}
} else {
// Multiple destination words
d0 = *src--;
d0 = FB_READL(src--);
// Leading bits
if (shift < 0) {
// Single source word
......@@ -291,7 +291,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
n -= dst_idx+1;
} else {
// 2 source words
d1 = *src--;
d1 = FB_READL(src--);
FB_WRITEL(((d0>>right | d1<<left) & first) |
(FB_READL(dst) & ~first), dst);
d0 = d1;
......@@ -303,22 +303,22 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
m = n % BITS_PER_LONG;
n /= BITS_PER_LONG;
while (n >= 4) {
d1 = *src--;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
d0 = d1;
d1 = *src--;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
d0 = d1;
d1 = *src--;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
d0 = d1;
d1 = *src--;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
d0 = d1;
n -= 4;
}
while (n--) {
d1 = *src--;
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
d0 = d1;
}
......@@ -332,7 +332,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
dst);
} else {
// 2 source words
d1 = *src;
d1 = FB_READL(src);
FB_WRITEL(((d0>>right | d1<<left) &
last) | (FB_READL(dst) &
~last), dst);
......@@ -410,8 +410,8 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
dst_idx &= (BYTES_PER_LONG-1);
src += src_idx >> SHIFT_PER_LONG;
src_idx &= (BYTES_PER_LONG-1);
bitcpy_rev((unsigned long*)dst, dst_idx,
(unsigned long *)src, src_idx,
bitcpy_rev(dst, dst_idx,
src, src_idx,
area->width*p->var.bits_per_pixel);
}
} else {
......@@ -420,8 +420,8 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
dst_idx &= (BYTES_PER_LONG-1);
src += src_idx >> SHIFT_PER_LONG;
src_idx &= (BYTES_PER_LONG-1);
bitcpy((unsigned long*)dst, dst_idx,
(unsigned long *)src, src_idx,
bitcpy(dst, dst_idx,
src, src_idx,
area->width*p->var.bits_per_pixel);
dst_idx += next_line*8;
src_idx += next_line*8;
......
......@@ -73,16 +73,11 @@ static u32 cfb_tab32[] = {
0x00000000, 0xffffffff
};
#if BITS_PER_LONG == 32
#define FB_WRITEL fb_writel
#define FB_READL fb_readl
#else
#define FB_WRITEL fb_writeq
#define FB_READL fb_readq
#endif
#if defined (__BIG_ENDIAN)
#define LEFT_POS(bpp) (BITS_PER_LONG - bpp)
#define LEFT_POS(bpp) (32 - bpp)
#define NEXT_POS(pos, bpp) ((pos) -= (bpp))
#define SHIFT_HIGH(val, bits) ((val) >> (bits))
#define SHIFT_LOW(val, bits) ((val) << (bits))
......@@ -94,26 +89,25 @@ static u32 cfb_tab32[] = {
#endif
static inline void color_imageblit(struct fb_image *image, struct fb_info *p,
u8 *dst1, unsigned long start_index,
unsigned long pitch_index)
u8 *dst1, u32 start_index,
u32 pitch_index)
{
/* Draw the penguin */
unsigned long *dst, *dst2, color = 0, val, shift;
u32 *dst, *dst2, color = 0, val, shift;
int i, n, bpp = p->var.bits_per_pixel;
unsigned long null_bits = BITS_PER_LONG - bpp;
u32 null_bits = 32 - bpp;
u32 *palette = (u32 *) p->pseudo_palette;
u8 *src = image->data;
dst2 = (unsigned long *) dst1;
dst2 = (u32 *) dst1;
for (i = image->height; i--; ) {
n = image->width;
dst = (unsigned long *) dst1;
dst = (u32 *) dst1;
shift = 0;
val = 0;
if (start_index) {
unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
start_index));
u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
val = FB_READL(dst) & start_mask;
shift = start_index;
}
......@@ -129,14 +123,14 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p,
FB_WRITEL(val, dst++);
val = (shift == null_bits) ? 0 :
SHIFT_LOW(color,BITS_PER_LONG - shift);
SHIFT_LOW(color, 32 - shift);
}
shift += bpp;
shift &= (BITS_PER_LONG - 1);
shift &= (32 - 1);
src++;
}
if (shift) {
unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
}
......@@ -144,40 +138,39 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p,
if (pitch_index) {
dst2 += p->fix.line_length;
dst1 = (char *) dst2;
(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
(unsigned long) dst1 &= ~(sizeof(u32) - 1);
start_index += pitch_index;
start_index &= BITS_PER_LONG - 1;
start_index &= 32 - 1;
}
}
}
static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
u8 *dst1, unsigned long fgcolor,
unsigned long bgcolor,
unsigned long start_index,
unsigned long pitch_index)
u8 *dst1, u32 fgcolor,
u32 bgcolor,
u32 start_index,
u32 pitch_index)
{
unsigned long shift, color = 0, bpp = p->var.bits_per_pixel;
unsigned long *dst, *dst2, val, pitch = p->fix.line_length;
unsigned long null_bits = BITS_PER_LONG - bpp;
unsigned long spitch = (image->width+7)/8;
u32 shift, color = 0, bpp = p->var.bits_per_pixel;
u32 *dst, *dst2, val, pitch = p->fix.line_length;
u32 null_bits = 32 - bpp;
u32 spitch = (image->width+7)/8;
u8 *src = image->data, *s;
unsigned long i, j, l;
u32 i, j, l;
dst2 = (unsigned long *) dst1;
dst2 = (u32 *) dst1;
for (i = image->height; i--; ) {
shift = val = 0;
l = 8;
j = image->width;
dst = (unsigned long *) dst1;
dst = (u32 *) dst1;
s = src;
/* write leading bits */
if (start_index) {
unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
start_index));
u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
val = FB_READL(dst) & start_mask;
shift = start_index;
}
......@@ -192,16 +185,16 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
if (shift >= null_bits) {
FB_WRITEL(val, dst++);
val = (shift == null_bits) ? 0 :
SHIFT_LOW(color,BITS_PER_LONG - shift);
SHIFT_LOW(color,32 - shift);
}
shift += bpp;
shift &= (BITS_PER_LONG - 1);
shift &= (32 - 1);
if (!l) { l = 8; s++; };
}
/* write trailing bits */
if (shift) {
unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
}
......@@ -211,10 +204,10 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
if (pitch_index) {
dst2 += pitch;
dst1 = (char *) dst2;
(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
(unsigned long) dst1 &= ~(sizeof(u32) - 1);
start_index += pitch_index;
start_index &= BITS_PER_LONG - 1;
start_index &= 32 - 1;
}
}
......@@ -229,14 +222,14 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
* beginning and end of a scanline is dword aligned
*/
static inline void fast_imageblit(struct fb_image *image, struct fb_info *p,
u8 *dst1, unsigned long fgcolor,
unsigned long bgcolor)
u8 *dst1, u32 fgcolor,
u32 bgcolor)
{
unsigned long fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
unsigned long ppw = BITS_PER_LONG/bpp, spitch = (image->width + 7)/8;
unsigned long bit_mask, end_mask, eorx, shift;
u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
u32 bit_mask, end_mask, eorx, shift;
char *s = image->data, *src;
unsigned long *dst;
u32 *dst;
u32 *tab = NULL;
int i, j, k;
......@@ -264,7 +257,7 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p,
k = image->width/ppw;
for (i = image->height; i--; ) {
dst = (unsigned long *) dst1, shift = 8; src = s;
dst = (u32 *) dst1, shift = 8; src = s;
for (j = k; j--; ) {
shift -= ppw;
......@@ -279,8 +272,8 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p,
void cfb_imageblit(struct fb_info *p, struct fb_image *image)
{
unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
int x2, y2, vxres, vyres;
u8 *dst1;
......@@ -304,7 +297,7 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
image->height = y2 - image->dy;
bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
start_index = bitstart & (BITS_PER_LONG - 1);
start_index = bitstart & (32 - 1);
pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
bitstart /= 8;
......@@ -324,8 +317,8 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
bgcolor = image->bg_color;
}
if (BITS_PER_LONG % bpp == 0 && !start_index && !pitch_index &&
((image->width & (BITS_PER_LONG/bpp-1)) == 0) &&
if (32 % bpp == 0 && !start_index && !pitch_index &&
((image->width & (32/bpp-1)) == 0) &&
bpp >= 8 && bpp <= 32)
fast_imageblit(image, p, dst1, fgcolor, bgcolor);
else
......
This diff is collapsed.
/* $Id: cgthreefb.c,v 1.11 2001/09/19 00:04:33 davem Exp $
* cgthreefb.c: CGthree frame buffer driver
*
* 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)
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/selection.h>
#include <video/sbusfb.h>
#include <asm/io.h>
#include <video/fbcon-cfb8.h>
/* Control Register Constants */
#define CG3_CR_ENABLE_INTS 0x80
#define CG3_CR_ENABLE_VIDEO 0x40
#define CG3_CR_ENABLE_TIMING 0x20
#define CG3_CR_ENABLE_CURCMP 0x10
#define CG3_CR_XTAL_MASK 0x0c
#define CG3_CR_DIVISOR_MASK 0x03
/* Status Register Constants */
#define CG3_SR_PENDING_INT 0x80
#define CG3_SR_RES_MASK 0x70
#define CG3_SR_1152_900_76_A 0x40
#define CG3_SR_1152_900_76_B 0x60
#define CG3_SR_ID_MASK 0x0f
#define CG3_SR_ID_COLOR 0x01
#define CG3_SR_ID_MONO 0x02
#define CG3_SR_ID_MONO_ECL 0x03
MODULE_LICENSE("GPL");
enum cg3_type {
CG3_AT_66HZ = 0,
CG3_AT_76HZ,
CG3_RDI
};
struct cg3_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;
};
/* Offset of interesting structures in the OBIO space */
#define CG3_REGS_OFFSET 0x400000UL
#define CG3_RAM_OFFSET 0x800000UL
static struct sbus_mmap_map cg3_mmap_map[] = {
{ CG3_MMAP_OFFSET, CG3_RAM_OFFSET, SBUS_MMAP_FBSIZE(1) },
{ 0, 0, 0 }
};
/* The cg3 palette is loaded with 4 color values at each time */
/* so you end up with: (rgb)(r), (gb)(rg), (b)(rgb), and so on */
#define D4M3(x) ((((x)>>2)<<1) + ((x)>>2)) /* (x/4)*3 */
#define D4M4(x) ((x)&~0x3) /* (x/4)*4 */
static void cg3_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
{
struct bt_regs *bt = &fb->s.cg3.regs->cmap;
unsigned long flags;
u32 *i;
volatile u8 *regp;
int steps;
spin_lock_irqsave(&fb->lock, flags);
i = (((u32 *)fb->color_map) + D4M3(index));
steps = D4M3(index+count-1) - D4M3(index)+3;
regp = (volatile u8 *)&bt->addr;
sbus_writeb(D4M4(index), regp);
while (steps--) {
u32 val = *i++;
sbus_writel(val, &bt->color_map);
}
spin_unlock_irqrestore(&fb->lock, flags);
}
static int cg3_blank (struct fb_info_sbusfb *fb)
{
unsigned long flags;
u8 tmp;
spin_lock_irqsave(&fb->lock, flags);
tmp = sbus_readb(&fb->s.cg3.regs->control);
tmp &= ~CG3_CR_ENABLE_VIDEO;
sbus_writeb(tmp, &fb->s.cg3.regs->control);
spin_unlock_irqrestore(&fb->lock, flags);
return 0;
}
static int cg3_unblank (struct fb_info_sbusfb *fb)
{
unsigned long flags;
u8 tmp;
spin_lock_irqsave(&fb->lock, flags);
tmp = sbus_readb(&fb->s.cg3.regs->control);
tmp |= CG3_CR_ENABLE_VIDEO;
sbus_writeb(tmp, &fb->s.cg3.regs->control);
spin_unlock_irqrestore(&fb->lock, flags);
return 0;
}
static void cg3_margins (struct fb_info_sbusfb *fb, struct display *p,
int x_margin, int y_margin)
{
fb->info.screen_base += (y_margin - fb->y_margin) *
fb->info.fix.line_length + (x_margin - fb->x_margin);
}
static u8 cg3regvals_66hz[] __initdata = { /* 1152 x 900, 66 Hz */
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 u8 cg3regvals_76hz[] __initdata = { /* 1152 x 900, 76 Hz */
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 cg3regvals_rdi[] __initdata = { /* 640 x 480, cgRDI */
0x14, 0x70, 0x15, 0x20, 0x16, 0x08, 0x17, 0x10,
0x18, 0x06, 0x19, 0x02, 0x1a, 0x31, 0x1b, 0x51,
0x1c, 0x06, 0x1d, 0x0c, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x22, 0
};
static u8 *cg3_regvals[] __initdata = {
cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
};
static u_char cg3_dacvals[] __initdata = {
4, 0xff, 5, 0x00, 6, 0x70, 7, 0x00, 0
};
static char idstring[60] __initdata = { 0 };
char __init *cgthreefb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->info.fix;
struct display *disp = &fb->disp;
struct fbtype *type = &fb->type;
struct sbus_dev *sdev = fb->sbdp;
unsigned long phys = sdev->reg_addrs[0].phys_addr;
int cgRDI = strstr(fb->sbdp->prom_name, "cgRDI") != NULL;
#ifndef FBCON_HAS_CFB8
return NULL;
#endif
if (!fb->s.cg3.regs) {
fb->s.cg3.regs = (struct cg3_regs *)
sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
sizeof(struct cg3_regs), "cg3 regs");
if (cgRDI) {
char buffer[40];
char *p;
int ww, hh;
*buffer = 0;
prom_getstring (fb->prom_node, "params", buffer, sizeof(buffer));
if (*buffer) {
ww = simple_strtoul (buffer, &p, 10);
if (ww && *p == 'x') {
hh = simple_strtoul (p + 1, &p, 10);
if (hh && *p == '-') {
if (type->fb_width != ww || type->fb_height != hh) {
type->fb_width = ww;
type->fb_height = hh;
return SBUSFBINIT_SIZECHANGE;
}
}
}
}
}
}
strcpy(fb->info.modename, "CGthree");
strcpy(fix->id, "CGthree");
fix->line_length = fb->info.var.xres_virtual;
fix->accel = FB_ACCEL_SUN_CGTHREE;
disp->scrollmode = SCROLL_YREDRAW;
if (!fb->info.screen_base) {
fb->info.screen_base = (char *)
sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
type->fb_size, "cg3 ram");
}
fb->info.screen_base += fix->line_length * fb->y_margin + fb->x_margin;
fb->dispsw = fbcon_cfb8;
fb->margins = cg3_margins;
fb->loadcmap = cg3_loadcmap;
fb->blank = cg3_blank;
fb->unblank = cg3_unblank;
fb->physbase = phys;
fb->mmap_map = cg3_mmap_map;
#ifdef __sparc_v9__
sprintf(idstring, "%s at %016lx", cgRDI ? "cgRDI" : "cgthree", phys);
#else
sprintf(idstring, "%s at %x.%08lx", cgRDI ? "cgRDI" : "cgthree", fb->iospace, phys);
#endif
if (!prom_getbool(fb->prom_node, "width")) {
/* Ugh, broken PROM didn't initialize us.
* Let's deal with this ourselves.
*/
enum cg3_type type;
u8 *p;
if (cgRDI)
type = CG3_RDI;
else {
u8 status = sbus_readb(&fb->s.cg3.regs->status), mon;
if ((status & CG3_SR_ID_MASK) == CG3_SR_ID_COLOR) {
mon = status & CG3_SR_RES_MASK;
if (mon == CG3_SR_1152_900_76_A ||
mon == CG3_SR_1152_900_76_B)
type = CG3_AT_76HZ;
else
type = CG3_AT_66HZ;
} else {
prom_printf("cgthree: can't handle SR %02x\n",
status);
prom_halt();
return NULL; /* fool gcc. */
}
}
for (p = cg3_regvals[type]; *p; p += 2) {
u8 *regp = &((u8 *)fb->s.cg3.regs)[p[0]];
sbus_writeb(p[1], regp);
}
for (p = cg3_dacvals; *p; p += 2) {
volatile u8 *regp;
regp = (volatile u8 *)&fb->s.cg3.regs->cmap.addr;
sbus_writeb(p[0], regp);
regp = (volatile u8 *)&fb->s.cg3.regs->cmap.control;
sbus_writeb(p[1], regp);
}
}
return idstring;
}
......@@ -103,8 +103,6 @@ extern int hgafb_setup(char*);
extern int matroxfb_init(void);
extern int matroxfb_setup(char*);
extern int hpfb_init(void);
extern int sbusfb_init(void);
extern int sbusfb_setup(char*);
extern int control_init(void);
extern int control_setup(char*);
extern int platinum_init(void);
......@@ -146,6 +144,20 @@ extern int sstfb_init(void);
extern int sstfb_setup(char*);
extern int i810fb_init(void);
extern int i810fb_setup(char*);
extern int ffb_init(void);
extern int ffb_setup(char*);
extern int cg6_init(void);
extern int cg6_setup(char*);
extern int cg3_init(void);
extern int cg3_setup(char*);
extern int bw2_init(void);
extern int bw2_setup(char*);
extern int cg14_init(void);
extern int cg14_setup(char*);
extern int p9100_init(void);
extern int p9100_setup(char*);
extern int tcx_init(void);
extern int tcx_setup(char*);
static struct {
const char *name;
......@@ -153,13 +165,6 @@ static struct {
int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_SBUS
/*
* Sbusfb must be initialized _before_ other frame buffer devices that
* use PCI probing
*/
{ "sbus", sbusfb_init, sbusfb_setup },
#endif
/*
* Chipset specific drivers that use resource management
*/
......@@ -244,6 +249,27 @@ static struct {
#ifdef CONFIG_FB_STI
{ "stifb", stifb_init, stifb_setup },
#endif
#ifdef CONFIG_FB_FFB
{ "ffb", ffb_init, ffb_setup },
#endif
#ifdef CONFIG_FB_CG6
{ "cg6", cg6_init, cg6_setup },
#endif
#ifdef CONFIG_FB_CG3
{ "cg3", cg3_init, cg3_setup },
#endif
#ifdef CONFIG_FB_BW2
{ "bw2", bw2_init, bw2_setup },
#endif
#ifdef CONFIG_FB_CG14
{ "cg14", cg14_init, cg14_setup },
#endif
#ifdef CONFIG_FB_P9100
{ "p9100", p9100_init, p9100_setup },
#endif
#ifdef CONFIG_FB_TCX
{ "tcx", tcx_init, tcx_setup },
#endif
/*
* Generic drivers that are used as fallbacks
......
This diff is collapsed.
/*
* Register information for the Weitek P9100 as found
* on the Tadpole Sparcbook 3 laptops.
*
* From the technical specification document provided by Tadpole.
*
* Derrick J Brashear (shadow@dementia.org)
*/
#ifndef _P9100_H_
#define _P9100_H_
/* P9100 control registers */
#define P9100_SYSCTL_OFF 0x0UL
#define P9100_VIDEOCTL_OFF 0x100UL
#define P9100_VRAMCTL_OFF 0x180UL
#define P9100_RAMDAC_OFF 0x200UL
#define P9100_VIDEOCOPROC_OFF 0x400UL
/* P9100 command registers */
#define P9100_CMD_OFF 0x0UL
/* P9100 framebuffer memory */
#define P9100_FB_OFF 0x0UL
/* 3 bits: 2=8bpp 3=16bpp 5=32bpp 7=24bpp */
#define SYS_CONFIG_PIXELSIZE_SHIFT 26
#define SCREENPAINT_TIMECTL1_ENABLE_VIDEO 0x20 /* 0 = off, 1 = on */
struct p9100_ctrl {
/* Registers for the system control */
__volatile__ __u32 sys_base;
__volatile__ __u32 sys_config;
__volatile__ __u32 sys_intr;
__volatile__ __u32 sys_int_ena;
__volatile__ __u32 sys_alt_rd;
__volatile__ __u32 sys_alt_wr;
__volatile__ __u32 sys_xxx[58];
/* Registers for the video control */
__volatile__ __u32 vid_base;
__volatile__ __u32 vid_hcnt;
__volatile__ __u32 vid_htotal;
__volatile__ __u32 vid_hsync_rise;
__volatile__ __u32 vid_hblank_rise;
__volatile__ __u32 vid_hblank_fall;
__volatile__ __u32 vid_hcnt_preload;
__volatile__ __u32 vid_vcnt;
__volatile__ __u32 vid_vlen;
__volatile__ __u32 vid_vsync_rise;
__volatile__ __u32 vid_vblank_rise;
__volatile__ __u32 vid_vblank_fall;
__volatile__ __u32 vid_vcnt_preload;
__volatile__ __u32 vid_screenpaint_addr;
__volatile__ __u32 vid_screenpaint_timectl1;
__volatile__ __u32 vid_screenpaint_qsfcnt;
__volatile__ __u32 vid_screenpaint_timectl2;
__volatile__ __u32 vid_xxx[15];
/* Registers for the video control */
__volatile__ __u32 vram_base;
__volatile__ __u32 vram_memcfg;
__volatile__ __u32 vram_refresh_pd;
__volatile__ __u32 vram_refresh_cnt;
__volatile__ __u32 vram_raslo_max;
__volatile__ __u32 vram_raslo_cur;
__volatile__ __u32 pwrup_cfg;
__volatile__ __u32 vram_xxx[25];
/* Registers for IBM RGB528 Palette */
__volatile__ __u32 ramdac_cmap_wridx;
__volatile__ __u32 ramdac_palette_data;
__volatile__ __u32 ramdac_pixel_mask;
__volatile__ __u32 ramdac_palette_rdaddr;
__volatile__ __u32 ramdac_idx_lo;
__volatile__ __u32 ramdac_idx_hi;
__volatile__ __u32 ramdac_idx_data;
__volatile__ __u32 ramdac_idx_ctl;
__volatile__ __u32 ramdac_xxx[1784];
};
struct p9100_cmd_parameng {
__volatile__ __u32 parameng_status;
__volatile__ __u32 parameng_bltcmd;
__volatile__ __u32 parameng_quadcmd;
};
#endif /* _P9100_H_ */
/* $id: p9100fb.c,v 1.4 1999/08/18 10:55:01 shadow Exp $
* p9100fb.c: P9100 frame buffer driver
*
* Copyright 1999 Derrick J Brashear (shadow@dementia.org)
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/selection.h>
#include <video/sbusfb.h>
#include <asm/io.h>
#include <video/fbcon-cfb8.h>
#include "p9100.h"
static struct sbus_mmap_map p9100_mmap_map[] = {
#if 0 /* For now, play we're a dumb color fb */
{ P9100_CTL_OFF, 0x38000000, 0x2000 },
{ P9100_CMD_OFF, 0x38002000, 0x2000 },
{ P9100_FB_OFF, 0x38800000, 0x200000 },
{ CG3_MMAP_OFFSET, 0x38800000, SBUS_MMAP_FBSIZE(1) },
#else
{ CG3_MMAP_OFFSET, 0x0, SBUS_MMAP_FBSIZE(1) },
#endif
{ 0, 0, 0 }
};
#define _READCTL(member, out) \
{ \
struct p9100_ctrl *actual; \
actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
out = sbus_readl(&actual-> ## member ); \
}
#define READCTL(member, out) \
{ \
struct p9100_ctrl *enab, *actual; \
actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
out = sbus_readl(&enab-> ## member ); \
out = sbus_readl(&actual-> ## member ); \
}
#define WRITECTL(member, val) \
{ \
u32 __writetmp; \
struct p9100_ctrl *enab, *actual; \
actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
__writetmp = sbus_readl(&enab-> ## member ); \
sbus_writel(val, &actual-> ## member ); \
}
static void p9100_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
{
unsigned long flags;
u32 tmp;
int i;
spin_lock_irqsave(&fb->lock, flags);
_READCTL(pwrup_cfg, tmp);
WRITECTL(ramdac_cmap_wridx, (index << 16));
for (i = index; count--; i++){
_READCTL(pwrup_cfg, tmp);
WRITECTL(ramdac_palette_data, (fb->color_map CM(i,0) << 16));
_READCTL(pwrup_cfg, tmp);
WRITECTL(ramdac_palette_data, (fb->color_map CM(i,1) << 16));
_READCTL(pwrup_cfg, tmp);
WRITECTL(ramdac_palette_data, (fb->color_map CM(i,2) << 16));
}
spin_unlock_irqrestore(&fb->lock, flags);
}
static int p9100_blank (struct fb_info_sbusfb *fb)
{
unsigned long flags;
u32 val;
spin_lock_irqsave(&fb->lock, flags);
READCTL(vid_screenpaint_timectl1, val);
val &= ~ SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
WRITECTL(vid_screenpaint_timectl1, val);
spin_unlock_irqrestore(&fb->lock, flags);
return 0;
}
static int p9100_unblank (struct fb_info_sbusfb *fb)
{
unsigned long flags;
u32 val;
spin_lock_irqsave(&fb->lock, flags);
READCTL(vid_screenpaint_timectl1, val);
val |= SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
WRITECTL(vid_screenpaint_timectl1, val);
spin_unlock_irqrestore(&fb->lock, flags);
return 0;
}
static void p9100_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
{
fb->info.screen_base += (y_margin - fb->y_margin) * p->line_length +
(x_margin - fb->x_margin);
}
static char idstring[60] __initdata = { 0 };
char * __init p9100fb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->fix;
struct display *disp = &fb->disp;
struct fbtype *type = &fb->type;
struct sbus_dev *sdev = fb->sbdp;
unsigned long phys = sdev->reg_addrs[2].phys_addr;
int tmp;
#ifndef FBCON_HAS_CFB8
return NULL;
#endif
/* Control regs: fb->sbdp->reg_addrs[0].phys_addr
* Command regs: fb->sbdp->reg_addrs[1].phys_addr
* Frame buffer: fb->sbdp->reg_addrs[2].phys_addr
*/
if (!fb->s.p9100.ctrl) {
fb->s.p9100.ctrl = (struct p9100_ctrl *)
sbus_ioremap(&sdev->resource[0], 0,
sdev->reg_addrs[0].reg_size, "p9100 ctrl");
}
strcpy(fb->info.modename, "p9100");
strcpy(fix->id, "p9100");
fix->accel = FB_ACCEL_SUN_CGTHREE;
fix->line_length = fb->var.xres_virtual;
disp->scrollmode = SCROLL_YREDRAW;
if (!fb->info.screen_base)
fb->info.screen_base = (char *)
sbus_ioremap(&sdev->resource[2], 0,
type->fb_size, "p9100 ram");
fb->s.p9100.fbmem = (volatile u32 *)fb->info.screen_base;
fb->info.screen_base += fix->line_length * fb->y_margin + fb->x_margin;
READCTL(sys_config, tmp);
switch ((tmp >> SYS_CONFIG_PIXELSIZE_SHIFT) & 7) {
case 7:
type->fb_depth = 24;
break;
case 5:
type->fb_depth = 32;
break;
case 3:
type->fb_depth = 16;
break;
case 2:
type->fb_depth = 8;
break;
default:
printk("p9100: screen depth unknown: 0x%x", tmp);
return NULL;
}
fb->dispsw = fbcon_cfb8;
fb->margins = p9100_margins;
fb->loadcmap = p9100_loadcmap;
fb->blank = p9100_blank;
fb->unblank = p9100_unblank;
fb->physbase = phys;
fb->mmap_map = p9100_mmap_map;
sprintf(idstring, "%s at 0x%x", "p9100",
(unsigned int)fb->info.screen_base);
return idstring;
}
This diff is collapsed.
/* sbuslib.c: Helper library for SBUS framebuffer drivers.
*
* Copyright (C) 2003 David S. Miller (davem@redhat.com)
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/oplib.h>
#include "sbuslib.h"
void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp)
{
memset(var, 0, sizeof(*var));
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;
}
EXPORT_SYMBOL(sbusfb_fill_var);
static unsigned long sbusfb_mmapsize(long size, unsigned long fbsize)
{
if (size == SBUS_MMAP_EMPTY) return 0;
if (size >= 0) return size;
return fbsize * (-size);
}
int sbusfb_mmap_helper(struct sbus_mmap_map *map,
unsigned long physbase,
unsigned long fbsize,
unsigned long iospace,
struct vm_area_struct *vma)
{
unsigned int size, page, r, map_size;
unsigned long map_offset = 0;
unsigned long off;
int i;
size = vma->vm_end - vma->vm_start;
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
return -EINVAL;
off = vma->vm_pgoff << PAGE_SHIFT;
/* To stop the swapper from even considering these pages */
vma->vm_flags |= (VM_SHM | VM_IO | VM_LOCKED);
/* Each page, see which map applies */
for (page = 0; page < size; ){
map_size = 0;
for (i = 0; map[i].size; i++)
if (map[i].voff == off+page) {
map_size = sbusfb_mmapsize(map[i].size, fbsize);
#ifdef __sparc_v9__
#define POFF_MASK (PAGE_MASK|0x1UL)
#else
#define POFF_MASK (PAGE_MASK)
#endif
map_offset = (physbase + map[i].poff) & POFF_MASK;
break;
}
if (!map_size){
page += PAGE_SIZE;
continue;
}
if (page + map_size > size)
map_size = size - page;
r = io_remap_page_range(vma,
vma->vm_start + page,
map_offset, map_size,
vma->vm_page_prot, iospace);
if (r)
return -EAGAIN;
page += map_size;
}
return 0;
}
/* sbuslib.h: SBUS fb helper library interfaces */
#ifndef _SBUSLIB_H
#define _SBUSLIB_H
struct sbus_mmap_map {
unsigned long voff;
unsigned long poff;
unsigned long size;
};
#define SBUS_MMAP_FBSIZE(n) (-n)
#define SBUS_MMAP_EMPTY 0x80000000
extern void sbusfb_fill_var(struct fb_var_screeninfo *var, int prom_node, int bpp);
struct vm_area_struct;
extern int sbusfb_mmap_helper(struct sbus_mmap_map *map,
unsigned long physbase, unsigned long fbsize,
unsigned long iospace,
struct vm_area_struct *vma);
#endif /* _SBUSLIB_H */
This diff is collapsed.
This diff is collapsed.
......@@ -10,6 +10,7 @@
#include <linux/threads.h>
#include <linux/brlock.h>
#include <linux/spinlock.h>
#include <linux/cache.h>
/* entry.S is sensitive to the offsets of these fields */
/* rtrap.S is sensitive to the size of this structure */
......
This diff is collapsed.
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