1 /* $Id: bwtwofb.c,v 1.1.1.1 2005/04/11 02:50:41 jack Exp $
2 * bwtwofb.c: BWtwo frame buffer driver
4 * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
7 * Copyright (C) 1998 Pavel Machek (pavel@ucw.cz)
10 #include <linux/config.h>
11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
15 #include <linux/string.h>
17 #include <linux/tty.h>
18 #include <linux/slab.h>
19 #include <linux/vmalloc.h>
20 #include <linux/delay.h>
21 #include <linux/interrupt.h>
23 #include <linux/init.h>
24 #include <linux/selection.h>
26 #include <video/sbusfb.h>
28 #if !defined(__sparc_v9__) && !defined(__mc68000__)
29 #include <asm/sun4paddr.h>
32 #include <video/fbcon-mfb.h>
34 /* OBio addresses for the bwtwo registers */
35 #define BWTWO_REGISTER_OFFSET 0x400000
41 volatile u8 cursor_start;
42 volatile u8 cursor_end;
43 volatile u8 h_blank_start;
44 volatile u8 h_blank_end;
45 volatile u8 h_sync_start;
46 volatile u8 h_sync_end;
47 volatile u8 comp_sync_end;
48 volatile u8 v_blank_start_high;
49 volatile u8 v_blank_start_low;
50 volatile u8 v_blank_end;
51 volatile u8 v_sync_start;
52 volatile u8 v_sync_end;
53 volatile u8 xfer_holdoff_start;
54 volatile u8 xfer_holdoff_end;
57 /* Status Register Constants */
58 #define BWTWO_SR_RES_MASK 0x70
59 #define BWTWO_SR_1600_1280 0x50
60 #define BWTWO_SR_1152_900_76_A 0x40
61 #define BWTWO_SR_1152_900_76_B 0x60
62 #define BWTWO_SR_ID_MASK 0x0f
63 #define BWTWO_SR_ID_MONO 0x02
64 #define BWTWO_SR_ID_MONO_ECL 0x03
65 #define BWTWO_SR_ID_MSYNC 0x04
66 #define BWTWO_SR_ID_NOCONN 0x0a
68 /* Control Register Constants */
69 #define BWTWO_CTL_ENABLE_INTS 0x80
70 #define BWTWO_CTL_ENABLE_VIDEO 0x40
71 #define BWTWO_CTL_ENABLE_TIMING 0x20
72 #define BWTWO_CTL_ENABLE_CURCMP 0x10
73 #define BWTWO_CTL_XTAL_MASK 0x0C
74 #define BWTWO_CTL_DIVISOR_MASK 0x03
76 /* Status Register Constants */
77 #define BWTWO_STAT_PENDING_INT 0x80
78 #define BWTWO_STAT_MSENSE_MASK 0x70
79 #define BWTWO_STAT_ID_MASK 0x0f
81 static struct sbus_mmap_map bw2_mmap_map[] = {
82 { 0, 0, SBUS_MMAP_FBSIZE(1) },
86 static void bw2_blank (struct fb_info_sbusfb *fb)
91 spin_lock_irqsave(&fb->lock, flags);
92 tmp = sbus_readb(&fb->s.bw2.regs->control);
93 tmp &= ~BWTWO_CTL_ENABLE_VIDEO;
94 sbus_writeb(tmp, &fb->s.bw2.regs->control);
95 spin_unlock_irqrestore(&fb->lock, flags);
98 static void bw2_unblank (struct fb_info_sbusfb *fb)
103 spin_lock_irqsave(&fb->lock, flags);
104 tmp = sbus_readb(&fb->s.bw2.regs->control);
105 tmp |= BWTWO_CTL_ENABLE_VIDEO;
106 sbus_writeb(tmp, &fb->s.bw2.regs->control);
107 spin_unlock_irqrestore(&fb->lock, flags);
110 static void bw2_margins (struct fb_info_sbusfb *fb, struct display *p,
111 int x_margin, int y_margin)
113 p->screen_base += (y_margin - fb->y_margin) *
114 p->line_length + ((x_margin - fb->x_margin) >> 3);
117 static u8 bw2regs_1600[] __initdata = {
118 0x14, 0x8b, 0x15, 0x28, 0x16, 0x03, 0x17, 0x13,
119 0x18, 0x7b, 0x19, 0x05, 0x1a, 0x34, 0x1b, 0x2e,
120 0x1c, 0x00, 0x1d, 0x0a, 0x1e, 0xff, 0x1f, 0x01,
124 static u8 bw2regs_ecl[] __initdata = {
125 0x14, 0x65, 0x15, 0x1e, 0x16, 0x04, 0x17, 0x0c,
126 0x18, 0x5e, 0x19, 0x03, 0x1a, 0xa7, 0x1b, 0x23,
127 0x1c, 0x00, 0x1d, 0x08, 0x1e, 0xff, 0x1f, 0x01,
131 static u8 bw2regs_analog[] __initdata = {
132 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x03, 0x17, 0x13,
133 0x18, 0xb0, 0x19, 0x03, 0x1a, 0xa6, 0x1b, 0x22,
134 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
138 static u8 bw2regs_76hz[] __initdata = {
139 0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f,
140 0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a,
141 0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01,
145 static u8 bw2regs_66hz[] __initdata = {
146 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14,
147 0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24,
148 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
152 static char idstring[60] __initdata = { 0 };
154 char __init *bwtwofb_init(struct fb_info_sbusfb *fb)
156 struct fb_fix_screeninfo *fix = &fb->fix;
157 struct display *disp = &fb->disp;
158 struct fbtype *type = &fb->type;
160 unsigned long phys = sun4_bwtwo_physaddr;
163 unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
165 struct resource *resp;
168 #ifndef FBCON_HAS_MFB
174 res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
175 res.flags = IORESOURCE_IO | (fb->iospace & 0xff);
178 resp = &fb->sbdp->resource[0];
180 if (!fb->s.bw2.regs) {
181 fb->s.bw2.regs = (struct bw2_regs *)
182 sbus_ioremap(resp, BWTWO_REGISTER_OFFSET,
183 sizeof(struct bw2_regs), "bw2 regs");
184 if ((!ARCH_SUN4) && (!prom_getbool(fb->prom_node, "width"))) {
185 /* Ugh, broken PROM didn't initialize us.
186 * Let's deal with this ourselves.
192 status = sbus_readb(&fb->s.bw2.regs->status);
193 mon = status & BWTWO_SR_RES_MASK;
194 switch (status & BWTWO_SR_ID_MASK) {
195 case BWTWO_SR_ID_MONO_ECL:
196 if (mon == BWTWO_SR_1600_1280) {
198 fb->type.fb_width = 1600;
199 fb->type.fb_height = 1280;
204 case BWTWO_SR_ID_MONO:
207 case BWTWO_SR_ID_MSYNC:
208 if (mon == BWTWO_SR_1152_900_76_A ||
209 mon == BWTWO_SR_1152_900_76_B)
214 case BWTWO_SR_ID_NOCONN:
217 #ifndef CONFIG_FB_SUN3
218 prom_printf("bw2: can't handle SR %02x\n",
222 return NULL; /* fool gcc. */
224 for ( ; *p; p += 2) {
225 u8 *regp = &((u8 *)fb->s.bw2.regs)[p[0]];
226 sbus_writeb(p[1], regp);
231 strcpy(fb->info.modename, "BWtwo");
232 strcpy(fix->id, "BWtwo");
233 fix->line_length = fb->var.xres_virtual >> 3;
234 fix->accel = FB_ACCEL_SUN_BWTWO;
236 disp->scrollmode = SCROLL_YREDRAW;
238 if (!disp->screen_base) {
239 disp->screen_base = (char *)
240 sbus_ioremap(resp, 0, type->fb_size, "bw2 ram");
242 disp->screen_base += fix->line_length * fb->y_margin + (fb->x_margin >> 3);
243 fb->dispsw = fbcon_mfb;
244 fix->visual = FB_VISUAL_MONO01;
247 fb->blank = bw2_blank;
248 fb->unblank = bw2_unblank;
250 prom_getproperty(fb->sbdp->prom_node, "address",
251 (char *)&vaddr, sizeof(vaddr));
252 fb->physbase = __get_phys((unsigned long)vaddr);
255 fb->margins = bw2_margins;
256 fb->mmap_map = bw2_mmap_map;
259 sprintf(idstring, "bwtwo at %016lx", phys);
261 sprintf(idstring, "bwtwo at %x.%08lx", fb->iospace, phys);
267 MODULE_LICENSE("GPL");