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

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

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

  1 /* $Id: cgfourteenfb.c,v 1.8 2000/08/29 07:01:56 davem Exp $
  2  * cgfourteenfb.c: CGfourteen frame buffer driver
  3  *
  4  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
  5  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
  6  */
  7 
  8 #include <linux/module.h>
  9 #include <linux/sched.h>
 10 #include <linux/kernel.h>
 11 #include <linux/errno.h>
 12 #include <linux/string.h>
 13 #include <linux/mm.h>
 14 #include <linux/tty.h>
 15 #include <linux/malloc.h>
 16 #include <linux/vmalloc.h>
 17 #include <linux/delay.h>
 18 #include <linux/interrupt.h>
 19 #include <linux/fb.h>
 20 #include <linux/init.h>
 21 #include <linux/selection.h>
 22 
 23 #include <video/sbusfb.h>
 24 #include <asm/io.h>
 25 #include <asm/pgtable.h>
 26 #include <asm/uaccess.h>
 27 
 28 #include <video/fbcon-cfb8.h>
 29 
 30 #define CG14_MCR_INTENABLE_SHIFT        7
 31 #define CG14_MCR_INTENABLE_MASK         0x80
 32 #define CG14_MCR_VIDENABLE_SHIFT        6
 33 #define CG14_MCR_VIDENABLE_MASK         0x40
 34 #define CG14_MCR_PIXMODE_SHIFT          4
 35 #define CG14_MCR_PIXMODE_MASK           0x30
 36 #define CG14_MCR_TMR_SHIFT              2
 37 #define CG14_MCR_TMR_MASK               0x0c
 38 #define CG14_MCR_TMENABLE_SHIFT         1
 39 #define CG14_MCR_TMENABLE_MASK          0x02
 40 #define CG14_MCR_RESET_SHIFT            0
 41 #define CG14_MCR_RESET_MASK             0x01
 42 #define CG14_REV_REVISION_SHIFT         4
 43 #define CG14_REV_REVISION_MASK          0xf0
 44 #define CG14_REV_IMPL_SHIFT             0
 45 #define CG14_REV_IMPL_MASK              0x0f
 46 #define CG14_VBR_FRAMEBASE_SHIFT        12
 47 #define CG14_VBR_FRAMEBASE_MASK         0x00fff000
 48 #define CG14_VMCR1_SETUP_SHIFT          0
 49 #define CG14_VMCR1_SETUP_MASK           0x000001ff
 50 #define CG14_VMCR1_VCONFIG_SHIFT        9
 51 #define CG14_VMCR1_VCONFIG_MASK         0x00000e00
 52 #define CG14_VMCR2_REFRESH_SHIFT        0
 53 #define CG14_VMCR2_REFRESH_MASK         0x00000001
 54 #define CG14_VMCR2_TESTROWCNT_SHIFT     1
 55 #define CG14_VMCR2_TESTROWCNT_MASK      0x00000002
 56 #define CG14_VMCR2_FBCONFIG_SHIFT       2
 57 #define CG14_VMCR2_FBCONFIG_MASK        0x0000000c
 58 #define CG14_VCR_REFRESHREQ_SHIFT       0
 59 #define CG14_VCR_REFRESHREQ_MASK        0x000003ff
 60 #define CG14_VCR1_REFRESHENA_SHIFT      10
 61 #define CG14_VCR1_REFRESHENA_MASK       0x00000400
 62 #define CG14_VCA_CAD_SHIFT              0
 63 #define CG14_VCA_CAD_MASK               0x000003ff
 64 #define CG14_VCA_VERS_SHIFT             10
 65 #define CG14_VCA_VERS_MASK              0x00000c00
 66 #define CG14_VCA_RAMSPEED_SHIFT         12
 67 #define CG14_VCA_RAMSPEED_MASK          0x00001000
 68 #define CG14_VCA_8MB_SHIFT              13
 69 #define CG14_VCA_8MB_MASK               0x00002000
 70 
 71 #define CG14_MCR_PIXMODE_8              0
 72 #define CG14_MCR_PIXMODE_16             2
 73 #define CG14_MCR_PIXMODE_32             3
 74 
 75 struct cg14_regs{
 76         volatile u8 mcr;        /* Master Control Reg */
 77         volatile u8 ppr;        /* Packed Pixel Reg */
 78         volatile u8 tms[2];     /* Test Mode Status Regs */
 79         volatile u8 msr;        /* Master Status Reg */
 80         volatile u8 fsr;        /* Fault Status Reg */
 81         volatile u8 rev;        /* Revision & Impl */
 82         volatile u8 ccr;        /* Clock Control Reg */
 83         volatile u32 tmr;       /* Test Mode Read Back */
 84         volatile u8 mod;        /* Monitor Operation Data Reg */
 85         volatile u8 acr;        /* Aux Control */
 86         u8 xxx0[6];
 87         volatile u16 hct;       /* Hor Counter */
 88         volatile u16 vct;       /* Vert Counter */
 89         volatile u16 hbs;       /* Hor Blank Start */
 90         volatile u16 hbc;       /* Hor Blank Clear */
 91         volatile u16 hss;       /* Hor Sync Start */
 92         volatile u16 hsc;       /* Hor Sync Clear */
 93         volatile u16 csc;       /* Composite Sync Clear */
 94         volatile u16 vbs;       /* Vert Blank Start */
 95         volatile u16 vbc;       /* Vert Blank Clear */
 96         volatile u16 vss;       /* Vert Sync Start */
 97         volatile u16 vsc;       /* Vert Sync Clear */
 98         volatile u16 xcs;
 99         volatile u16 xcc;
100         volatile u16 fsa;       /* Fault Status Address */
101         volatile u16 adr;       /* Address Registers */
102         u8 xxx1[0xce];
103         volatile u8 pcg[0x100]; /* Pixel Clock Generator */
104         volatile u32 vbr;       /* Frame Base Row */
105         volatile u32 vmcr;      /* VBC Master Control */
106         volatile u32 vcr;       /* VBC refresh */
107         volatile u32 vca;       /* VBC Config */
108 };
109 
110 #define CG14_CCR_ENABLE 0x04
111 #define CG14_CCR_SELECT 0x02    /* HW/Full screen */
112 
113 struct cg14_cursor {
114         volatile u32 cpl0[32];  /* Enable plane 0 */
115         volatile u32 cpl1[32];  /* Color selection plane */
116         volatile u8 ccr;        /* Cursor Control Reg */
117         u8 xxx0[3];
118         volatile u16 cursx;     /* Cursor x,y position */
119         volatile u16 cursy;     /* Cursor x,y position */
120         volatile u32 color0;
121         volatile u32 color1;
122         u32 xxx1[0x1bc];
123         volatile u32 cpl0i[32]; /* Enable plane 0 autoinc */
124         volatile u32 cpl1i[32]; /* Color selection autoinc */
125 };
126 
127 struct cg14_dac {
128         volatile u8 addr;       /* Address Register */
129         u8 xxx0[255];
130         volatile u8 glut;       /* Gamma table */
131         u8 xxx1[255];
132         volatile u8 select;     /* Register Select */
133         u8 xxx2[255];
134         volatile u8 mode;       /* Mode Register */
135 };
136 
137 struct cg14_xlut{
138         volatile u8 x_xlut [256];
139         volatile u8 x_xlutd [256];
140         u8 xxx0[0x600];
141         volatile u8 x_xlut_inc [256];
142         volatile u8 x_xlutd_inc [256];
143 };
144 
145 /* Color look up table (clut) */
146 /* Each one of these arrays hold the color lookup table (for 256
147  * colors) for each MDI page (I assume then there should be 4 MDI
148  * pages, I still wonder what they are.  I have seen NeXTStep split
149  * the screen in four parts, while operating in 24 bits mode.  Each
150  * integer holds 4 values: alpha value (transparency channel, thanks
151  * go to John Stone (johns@umr.edu) from OpenBSD), red, green and blue
152  *
153  * I currently use the clut instead of the Xlut
154  */
155 struct cg14_clut {
156         u32 c_clut [256];
157         u32 c_clutd [256];    /* i wonder what the 'd' is for */
158         u32 c_clut_inc [256];
159         u32 c_clutd_inc [256];
160 };
161 
162 static struct sbus_mmap_map cg14_mmap_map[] __initdata = {
163         { CG14_REGS,            0x80000000,             0x1000              },
164         { CG14_XLUT,            0x80003000,             0x1000              },
165         { CG14_CLUT1,           0x80004000,             0x1000              },
166         { CG14_CLUT2,           0x80005000,             0x1000              },
167         { CG14_CLUT3,           0x80006000,             0x1000              },
168         { CG3_MMAP_OFFSET - 
169           0x7000,               0x80000000,             0x7000              },
170         { CG3_MMAP_OFFSET,      0x00000000,             SBUS_MMAP_FBSIZE(1) },
171         { MDI_CURSOR_MAP,       0x80001000,             0x1000              },
172         { MDI_CHUNKY_BGR_MAP,   0x01000000,             0x400000            },
173         { MDI_PLANAR_X16_MAP,   0x02000000,             0x200000            },
174         { MDI_PLANAR_C16_MAP,   0x02800000,             0x200000            },
175         { MDI_PLANAR_X32_MAP,   0x03000000,             0x100000            },
176         { MDI_PLANAR_B32_MAP,   0x03400000,             0x100000            },
177         { MDI_PLANAR_G32_MAP,   0x03800000,             0x100000            },
178         { MDI_PLANAR_R32_MAP,   0x03c00000,             0x100000            },
179         { 0,                    0,                      0                   }
180 };
181 
182 static void cg14_loadcmap (struct fb_info_sbusfb *fb, struct display *p,
183                            int index, int count)
184 {
185         struct cg14_clut *clut = fb->s.cg14.clut;
186         unsigned long flags;
187                 
188         spin_lock_irqsave(&fb->lock, flags);
189         for (; count--; index++) {
190                 u32 val;
191 
192                 val = ((fb->color_map CM(index,2) << 16) |
193                        (fb->color_map CM(index,1) << 8) |
194                        (fb->color_map CM(index,0)));
195                 sbus_writel(val, &clut->c_clut[index]);
196         }
197         spin_unlock_irqrestore(&fb->lock, flags);
198 }
199 
200 static void cg14_margins (struct fb_info_sbusfb *fb, struct display *p,
201                           int x_margin, int y_margin)
202 {
203         p->screen_base += (y_margin - fb->y_margin) *
204                 p->line_length + (x_margin - fb->x_margin);
205 }
206 
207 static void cg14_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
208 {
209         struct cg14_cursor *cur = fb->s.cg14.cursor;
210         unsigned long flags;
211         
212         spin_lock_irqsave(&fb->lock, flags);
213         sbus_writel(((red[0]) | (green[0] << 8) | (blue[0] << 16)), &cur->color0);
214         sbus_writel(((red[1]) | (green[1] << 8) | (blue[1] << 16)), &cur->color1);
215         spin_unlock_irqrestore(&fb->lock, flags);
216 }
217 
218 /* Set cursor shape */
219 static void cg14_setcurshape (struct fb_info_sbusfb *fb)
220 {
221         struct cg14_cursor *cur = fb->s.cg14.cursor;
222         unsigned long flags;
223         int i;
224 
225         spin_lock_irqsave(&fb->lock, flags);
226         for (i = 0; i < 32; i++){
227                 sbus_writel(fb->cursor.bits[0][i], &cur->cpl0[i]);
228                 sbus_writel(fb->cursor.bits[1][i], &cur->cpl1[i]);
229         }
230         spin_unlock_irqrestore(&fb->lock, flags);
231 }
232 
233 /* Load cursor information */
234 static void cg14_setcursor (struct fb_info_sbusfb *fb)
235 {
236         struct cg_cursor *c = &fb->cursor;
237         struct cg14_cursor *cur = fb->s.cg14.cursor;
238         unsigned long flags;
239                 
240         spin_lock_irqsave(&fb->lock, flags);
241         if (c->enable) {
242                 u8 tmp = sbus_readb(&cur->ccr);
243 
244                 tmp |= CG14_CCR_ENABLE;
245                 sbus_writeb(tmp, &cur->ccr);
246         }
247         sbus_writew(((c->cpos.fbx - c->chot.fbx) & 0xfff), &cur->cursx);
248         sbus_writew(((c->cpos.fby - c->chot.fby) & 0xfff), &cur->cursy);
249         spin_unlock_irqrestore(&fb->lock, flags);
250 }
251 
252 static void cg14_switch_from_graph (struct fb_info_sbusfb *fb)
253 {
254         unsigned long flags;
255 
256         spin_lock_irqsave(&fb->lock, flags);
257 
258         /* Set the 8-bpp mode */
259         if (fb->open && fb->mmaped){
260                 volatile char *mcr = &fb->s.cg14.regs->mcr;
261                 char tmp;
262                                         
263                 fb->s.cg14.mode = 8;
264                 tmp = sbus_readb(mcr);
265                 tmp &= ~(CG14_MCR_PIXMODE_MASK);
266                 sbus_writeb(tmp, mcr);
267         }
268         spin_unlock_irqrestore(&fb->lock, flags);
269 }
270 
271 static void cg14_reset (struct fb_info_sbusfb *fb)
272 {
273         volatile char *mcr = &fb->s.cg14.regs->mcr;
274         unsigned long flags;
275         char tmp;
276                 
277         spin_lock_irqsave(&fb->lock, flags);
278         tmp = sbus_readb(mcr);
279         tmp &= ~(CG14_MCR_PIXMODE_MASK);
280         sbus_writeb(tmp, mcr);
281         spin_unlock_irqrestore(&fb->lock, flags);
282 }
283 
284 static int cg14_ioctl (struct fb_info_sbusfb *fb, unsigned int cmd, unsigned long arg)
285 {
286         volatile char *mcr = &fb->s.cg14.regs->mcr;
287         struct mdi_cfginfo *mdii;
288         unsigned long flags;
289         int mode, ret = 0;
290         char tmp;
291                 
292         switch (cmd) {
293         case MDI_RESET:
294                 spin_lock_irqsave(&fb->lock, flags);
295                 tmp = sbus_readb(mcr);
296                 tmp &= ~CG14_MCR_PIXMODE_MASK;
297                 sbus_writeb(tmp, mcr);
298                 spin_unlock_irqrestore(&fb->lock, flags);
299                 break;
300         case MDI_GET_CFGINFO:
301                 mdii = (struct mdi_cfginfo *)arg;
302                 if (put_user(FBTYPE_MDICOLOR, &mdii->mdi_type) ||
303                     __put_user(fb->type.fb_height, &mdii->mdi_height) ||
304                     __put_user(fb->type.fb_width, &mdii->mdi_width) ||
305                     __put_user(fb->s.cg14.mode, &mdii->mdi_mode) ||
306                     __put_user(72, &mdii->mdi_pixfreq) || /* FIXME */
307                     __put_user(fb->s.cg14.ramsize, &mdii->mdi_size))
308                         return -EFAULT;
309                 break;
310         case MDI_SET_PIXELMODE:
311                 if (get_user(mode, (int *)arg))
312                         return -EFAULT;
313 
314                 spin_lock_irqsave(&fb->lock, flags);
315                 tmp = sbus_readb(mcr);
316                 switch (mode){
317                 case MDI_32_PIX:
318                         tmp = (tmp & ~CG14_MCR_PIXMODE_MASK) |
319                                 (CG14_MCR_PIXMODE_32 << CG14_MCR_PIXMODE_SHIFT);
320                         break;
321                 case MDI_16_PIX:
322                         tmp = (tmp & ~CG14_MCR_PIXMODE_MASK) | 0x20;
323                         break;
324                 case MDI_8_PIX:
325                         tmp = (tmp & ~CG14_MCR_PIXMODE_MASK);
326                         break;
327                 default:
328                         ret = -ENOSYS;
329                         break;
330                 };
331                 if (ret == 0) {
332                         sbus_writeb(tmp, mcr);
333                         fb->s.cg14.mode = mode;
334                 }
335                 spin_unlock_irqrestore(&fb->lock, flags);
336                 break;
337         default:
338                 ret = -EINVAL;
339         };
340 
341         return ret;
342 }
343 
344 static unsigned long __init get_phys(unsigned long addr)
345 {
346         return __get_phys(addr);
347 }
348 
349 static int __init get_iospace(unsigned long addr)
350 {
351         return __get_iospace(addr);
352 }
353 
354 static char idstring[60] __initdata = { 0 };
355 
356 char __init *cgfourteenfb_init(struct fb_info_sbusfb *fb)
357 {
358         struct fb_fix_screeninfo *fix = &fb->fix;
359         struct display *disp = &fb->disp;
360         struct fbtype *type = &fb->type;
361         unsigned long rphys, phys;
362         u32 bases[6];
363         int is_8mb, i;
364 
365 #ifndef FBCON_HAS_CFB8
366         return NULL;
367 #endif
368         prom_getproperty (fb->prom_node, "address", (char *) &bases[0], 8);
369         if (!bases[0]) {
370                 printk("cg14 not mmaped\n");
371                 return NULL;
372         }
373         if (get_iospace(bases[0]) != get_iospace(bases[1])) {
374                 printk("Ugh. cg14 iospaces don't match\n");
375                 return NULL;
376         }
377         fb->physbase = phys = get_phys(bases[1]);
378         rphys = get_phys(bases[0]);
379         fb->iospace = get_iospace(bases[0]);
380         fb->s.cg14.regs = (struct cg14_regs *)(unsigned long)bases[0];
381         fb->s.cg14.clut = (void *)((unsigned long)bases[0]+CG14_CLUT1);
382         fb->s.cg14.cursor = (void *)((unsigned long)bases[0]+CG14_CURSORREGS);
383         disp->screen_base = (char *)bases[1];
384         
385         /* CG14_VCA_8MB_MASK is not correctly set on the 501-2482
386          * VSIMM, so we read the memory size from the PROM
387          */
388         prom_getproperty(fb->prom_node, "reg", (char *) &bases[0], 24);
389         is_8mb = bases[5] == 0x800000;
390 
391         fb->mmap_map = kmalloc(sizeof(cg14_mmap_map), GFP_KERNEL);
392         if (!fb->mmap_map)
393                 return NULL;
394 
395         for (i = 0; ; i++) {
396                 fb->mmap_map[i].voff = cg14_mmap_map[i].voff;
397                 fb->mmap_map[i].poff = (cg14_mmap_map[i].poff & 0x80000000) ?
398                                        (cg14_mmap_map[i].poff & 0x7fffffff) + rphys - phys :
399                                        cg14_mmap_map[i].poff;
400                 fb->mmap_map[i].size = cg14_mmap_map[i].size;
401                 if (is_8mb && fb->mmap_map[i].size >= 0x100000 &&
402                     fb->mmap_map[i].size <= 0x400000)
403                         fb->mmap_map[i].size <<= 1;
404                 if (!cg14_mmap_map[i].size)
405                         break;
406         }
407 
408         strcpy(fb->info.modename, "CGfourteen");
409         strcpy(fix->id, "CGfourteen");
410         fix->line_length = fb->var.xres_virtual;
411         fix->accel = FB_ACCEL_SUN_CG14;
412         
413         disp->scrollmode = SCROLL_YREDRAW;
414         disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
415         fb->dispsw = fbcon_cfb8;
416         
417         type->fb_depth = 24;
418         fb->emulations[1] = FBTYPE_SUN3COLOR;
419 
420         fb->margins = cg14_margins;
421         fb->loadcmap = cg14_loadcmap;
422         fb->setcursor = cg14_setcursor;
423         fb->setcursormap = cg14_setcursormap;
424         fb->setcurshape = cg14_setcurshape;
425         fb->reset = cg14_reset;
426         fb->switch_from_graph = cg14_switch_from_graph;
427         fb->ioctl = cg14_ioctl;
428 
429         fb->s.cg14.mode = 8;
430         fb->s.cg14.ramsize = (is_8mb) ? 0x800000 : 0x400000;
431         
432         cg14_reset(fb);
433         
434         sprintf(idstring, "cgfourteen at %x.%08lx, %dMB, rev=%d, impl=%d", fb->iospace, phys,
435                 is_8mb ? 8 : 4, fb->s.cg14.regs->rev >> 4, fb->s.cg14.regs->rev & 0xf);
436         
437         return idstring;
438 }
439 

~ [ 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.