diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
---|---|---|
committer | <ralf@linux-mips.org> | 1997-04-29 21:13:14 +0000 |
commit | 19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch) | |
tree | 40b1cb534496a7f1ca0f5c314a523c69f1fee464 /drivers/sbus/char/bwtwo.c | |
parent | 7206675c40394c78a90e74812bbdbf8cf3cca1be (diff) |
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'drivers/sbus/char/bwtwo.c')
-rw-r--r-- | drivers/sbus/char/bwtwo.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/drivers/sbus/char/bwtwo.c b/drivers/sbus/char/bwtwo.c new file mode 100644 index 000000000..be68d09c9 --- /dev/null +++ b/drivers/sbus/char/bwtwo.c @@ -0,0 +1,211 @@ +/* $Id: bwtwo.c,v 1.13 1997/04/14 17:04:55 jj Exp $ + * bwtwo.c: bwtwo console driver + * + * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) + * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) + */ + +#include <linux/kd.h> +#include <linux/tty.h> +#include <linux/malloc.h> +#include <linux/proc_fs.h> + +#include <asm/sbus.h> +#include <asm/io.h> +#include <asm/fbio.h> +#include <asm/pgtable.h> + +#include "../../char/vt_kern.h" +#include "../../char/selection.h" +#include "../../char/console_struct.h" +#include "fb.h" +#include "cg_common.h" + +/* OBio addresses for the bwtwo registers */ +#define BWTWO_REGISTER_OFFSET 0x400000 + +struct bwtwo_regs { + __volatile__ 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 + +/* 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 int +bwtwo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma, + long base, fbinfo_t *fb) +{ + uint size, map_offset, r; + int map_size; + + map_size = size = vma->vm_end - vma->vm_start; + + if (vma->vm_offset & ~PAGE_MASK) + return -ENXIO; + + /* To stop the swapper from even considering these pages */ + vma->vm_flags |= FB_MMAP_VM_FLAGS; + + /* This routine should also map the register if asked for, + * but we don't do that yet. + */ + map_offset = get_phys ((unsigned long) fb->base); + r = io_remap_page_range (vma->vm_start, map_offset, map_size, + vma->vm_page_prot, fb->space); + if (r) return -EAGAIN; + vma->vm_inode = inode; + inode->i_count++; + return 0; +} + +static void +bwtwo_blank (fbinfo_t *fb) +{ + fb->info.bwtwo.regs->control &= ~BWTWO_CTL_ENABLE_VIDEO; +} + +static void +bwtwo_unblank (fbinfo_t *fb) +{ + fb->info.bwtwo.regs->control |= BWTWO_CTL_ENABLE_VIDEO; +} + + +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 +}; + +__initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, u32 bwtwo, int bw2_io, + struct linux_sbus_device *sbdp)) +{ + printk ("bwtwo%d at 0x%8.8x\n", slot, bwtwo); + fb->type.fb_cmsize = 0; + fb->mmap = bwtwo_mmap; + fb->loadcmap = 0; + fb->ioctl = 0; + fb->reset = 0; + fb->blank = bwtwo_blank; + fb->unblank = bwtwo_unblank; + + fb->info.bwtwo.regs = + sparc_alloc_io (bwtwo + BWTWO_REGISTER_OFFSET, + 0, sizeof (struct bwtwo_regs), + "bwtwo_regs", bw2_io, 0); + + if (!prom_getbool(sbdp->prom_node, "width")) { + /* Ugh, broken PROM didn't initialize us. + * Let's deal with this ourselves. + */ + u8 status, mon; + u8 *p; + + status = fb->info.bwtwo.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; + } 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; + default: + prom_printf("bwtwo: can't handle SR %02x\n", + status); + prom_halt(); + return; /* fool gcc. */ + } + for ( ; *p; p += 2) + ((u8 *)fb->info.bwtwo.regs)[p[0]] = p[1]; + } + + if(!fb->base) + fb->base = (unsigned long) sparc_alloc_io(bwtwo, 0, + ((fb->type.fb_depth*fb->type.fb_height*fb->type.fb_width)/8), + "bwtwo_fbase", bw2_io, 0); + + if (slot && sun_prom_console_id != slot) + bwtwo_blank (fb); +} + |