~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/video/bwtwofb.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* $Id: bwtwofb.c,v 1.13 2000/02/14 02:50:25 davem Exp $
  2  * bwtwofb.c: BWtwo frame buffer driver
  3  *
  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)
  8  */
  9 
 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>
 16 #include <linux/mm.h>
 17 #include <linux/tty.h>
 18 #include <linux/malloc.h>
 19 #include <linux/vmalloc.h>
 20 #include <linux/delay.h>
 21 #include <linux/interrupt.h>
 22 #include <linux/fb.h>
 23 #include <linux/init.h>
 24 #include <linux/selection.h>
 25 
 26 #include <video/sbusfb.h>
 27 #include <asm/io.h>
 28 #if !defined(__sparc_v9__) && !defined(__mc68000__)
 29 #include <asm/sun4paddr.h>
 30 #endif
 31 
 32 #include <video/fbcon-mfb.h>
 33 
 34 /* OBio addresses for the bwtwo registers */
 35 #define BWTWO_REGISTER_OFFSET 0x400000
 36 
 37 struct bw2_regs {
 38         struct bt_regs          bt;
 39         volatile u8             control;
 40         volatile u8             status;
 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;
 55 };
 56 
 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
 67 
 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
 75 
 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
 80 
 81 static struct sbus_mmap_map bw2_mmap_map[] = {
 82         { 0,                    0,                      SBUS_MMAP_FBSIZE(1) },
 83         { 0,                    0,                      0                   }
 84 };
 85 
 86 static void bw2_blank (struct fb_info_sbusfb *fb)
 87 {
 88         unsigned long flags;
 89         u8 tmp;
 90 
 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);
 96 }
 97 
 98 static void bw2_unblank (struct fb_info_sbusfb *fb)
 99 {
100         unsigned long flags;
101         u8 tmp;
102 
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);
108 }
109 
110 static void bw2_margins (struct fb_info_sbusfb *fb, struct display *p,
111                          int x_margin, int y_margin)
112 {
113         p->screen_base += (y_margin - fb->y_margin) *
114                 p->line_length + ((x_margin - fb->x_margin) >> 3);
115 }
116 
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,
121         0x10, 0x21,     0
122 };
123 
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,
128         0x10, 0x20,     0
129 };
130 
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,
135         0x10, 0x20,     0
136 };
137 
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,
142         0x10, 0x24,     0
143 };
144 
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,
149         0x10, 0x20,     0
150 };
151 
152 static char idstring[60] __initdata = { 0 };
153 
154 char __init *bwtwofb_init(struct fb_info_sbusfb *fb)
155 {
156         struct fb_fix_screeninfo *fix = &fb->fix;
157         struct display *disp = &fb->disp;
158         struct fbtype *type = &fb->type;
159 #ifdef CONFIG_SUN4
160         unsigned long phys = sun4_bwtwo_physaddr;
161         struct resource res;
162 #else
163         unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
164 #endif
165         struct resource *resp;
166         unsigned int vaddr;
167 
168 #ifndef FBCON_HAS_MFB
169         return NULL;
170 #endif
171 
172 #ifdef CONFIG_SUN4
173         res.start = phys;
174         res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
175         res.flags = IORESOURCE_IO | (fb->iospace & 0xff);
176         resp = &res;
177 #else
178         resp = &fb->sbdp->resource[0];
179 #endif
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.
187                          */
188                         u8 status, mon;
189                         u8 *p;
190                         int sizechange = 0;
191 
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) {
197                                                 p = bw2regs_1600;
198                                                 fb->type.fb_width = 1600;
199                                                 fb->type.fb_height = 1280;
200                                                 sizechange = 1;
201                                         } else
202                                                 p = bw2regs_ecl;
203                                         break;
204                                 case BWTWO_SR_ID_MONO:
205                                         p = bw2regs_analog;
206                                         break;
207                                 case BWTWO_SR_ID_MSYNC:
208                                         if (mon == BWTWO_SR_1152_900_76_A ||
209                                             mon == BWTWO_SR_1152_900_76_B)
210                                                 p = bw2regs_76hz;
211                                         else
212                                                 p = bw2regs_66hz;
213                                         break;
214                                 case BWTWO_SR_ID_NOCONN:
215                                         return NULL;
216                                 default:
217 #ifndef CONFIG_FB_SUN3
218                                         prom_printf("bw2: can't handle SR %02x\n",
219                                                     status);
220                                         prom_halt();
221 #endif                                  
222                                         return NULL; /* fool gcc. */
223                         }
224                         for ( ; *p; p += 2) {
225                                 u8 *regp = &((u8 *)fb->s.bw2.regs)[p[0]];
226                                 sbus_writeb(p[1], regp);
227                         }
228                 }
229         }
230 
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;
235         
236         disp->scrollmode = SCROLL_YREDRAW;
237         disp->inverse = 1;
238         if (!disp->screen_base) {
239                 disp->screen_base = (char *)
240                         sbus_ioremap(resp, 0, type->fb_size, "bw2 ram");
241         }
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;
245 
246 #ifndef CONFIG_SUN4
247         fb->blank = bw2_blank;
248         fb->unblank = bw2_unblank;
249 
250         prom_getproperty(fb->sbdp->prom_node, "address",
251                          (char *)&vaddr, sizeof(vaddr));
252         fb->physbase = __get_phys((unsigned long)vaddr);
253 
254 #endif
255         fb->margins = bw2_margins;
256         fb->mmap_map = bw2_mmap_map;
257 
258 #ifdef __sparc_v9__
259         sprintf(idstring, "bwtwo at %016lx", phys);
260 #else   
261         sprintf(idstring, "bwtwo at %x.%08lx", fb->iospace, phys);
262 #endif
263         
264         return idstring;
265 }
266 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.