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

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

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

  1 #include <linux/kernel.h>
  2 #include <linux/errno.h>
  3 #include <linux/string.h>
  4 #include <linux/mm.h>
  5 #include <linux/tty.h>
  6 #include <linux/malloc.h>
  7 #include <linux/delay.h>
  8 #include <linux/interrupt.h>
  9 #include <asm/setup.h>
 10 #include <asm/segment.h>
 11 #include <asm/system.h>
 12 #include <asm/irq.h>
 13 #include <asm/amigahw.h>
 14 #include <asm/amigaints.h>
 15 #include <asm/apollohw.h>
 16 #include <linux/fb.h>
 17 #include <linux/module.h>
 18 #include "dn_accel.h"
 19 #include <video/fbcon.h>
 20 #include <video/fbcon-mfb.h>
 21 
 22 /* apollo video HW definitions */
 23 
 24 /*
 25  * Control Registers.   IOBASE + $x
 26  *
 27  * Note: these are the Memory/IO BASE definitions for a mono card set to the
 28  * alternate address
 29  *
 30  * Control 3A and 3B serve identical functions except that 3A
 31  * deals with control 1 and 3b deals with Color LUT reg.
 32  */
 33 
 34 #define AP_IOBASE       0x3b0          /* Base address of 1 plane board. */
 35 #define AP_STATUS       isaIO2mem(AP_IOBASE+0) /* Status register.  Read */
 36 #define AP_WRITE_ENABLE isaIO2mem(AP_IOBASE+0) /* Write Enable Register Write */
 37 #define AP_DEVICE_ID    isaIO2mem(AP_IOBASE+1) /* Device ID Register. Read */
 38 #define AP_ROP_1        isaIO2mem(AP_IOBASE+2) /* Raster Operation reg. Write Word */
 39 #define AP_DIAG_MEM_REQ isaIO2mem(AP_IOBASE+4) /* Diagnostic Memory Request. Write Word */
 40 #define AP_CONTROL_0    isaIO2mem(AP_IOBASE+8) /* Control Register 0.  Read/Write */
 41 #define AP_CONTROL_1    isaIO2mem(AP_IOBASE+0xa) /* Control Register 1.  Read/Write */
 42 #define AP_CONTROL_3A   isaIO2mem(AP_IOBASE+0xe) /* Control Register 3a. Read/Write */
 43 #define AP_CONTROL_2    isaIO2mem(AP_IOBASE+0xc) /* Control Register 2. Read/Write */
 44 
 45 
 46 #define FRAME_BUFFER_START 0x0FA0000
 47 #define FRAME_BUFFER_LEN 0x40000
 48 
 49 /* CREG 0 */
 50 #define VECTOR_MODE 0x40 /* 010x.xxxx */
 51 #define DBLT_MODE   0x80 /* 100x.xxxx */
 52 #define NORMAL_MODE 0xE0 /* 111x.xxxx */
 53 #define SHIFT_BITS  0x1F /* xxx1.1111 */
 54         /* other bits are Shift value */
 55 
 56 /* CREG 1 */
 57 #define AD_BLT      0x80 /* 1xxx.xxxx */
 58 #define NORMAL      0x80 /* 1xxx.xxxx */   /* What is happening here ?? */
 59 #define INVERSE     0x00 /* 0xxx.xxxx */   /* Clearing this reverses the screen */
 60 #define PIX_BLT     0x00 /* 0xxx.xxxx */
 61 
 62 #define AD_HIBIT        0x40 /* xIxx.xxxx */
 63 
 64 #define ROP_EN          0x10 /* xxx1.xxxx */
 65 #define DST_EQ_SRC      0x00 /* xxx0.xxxx */
 66 #define nRESET_SYNC     0x08 /* xxxx.1xxx */
 67 #define SYNC_ENAB       0x02 /* xxxx.xx1x */
 68 
 69 #define BLANK_DISP      0x00 /* xxxx.xxx0 */
 70 #define ENAB_DISP       0x01 /* xxxx.xxx1 */
 71 
 72 #define NORM_CREG1      (nRESET_SYNC | SYNC_ENAB | ENAB_DISP) /* no reset sync */
 73 
 74 /* CREG 2 */
 75 
 76 /*
 77  * Following 3 defines are common to 1, 4 and 8 plane.
 78  */
 79 
 80 #define S_DATA_1s   0x00 /* 00xx.xxxx */ /* set source to all 1's -- vector drawing */
 81 #define S_DATA_PIX  0x40 /* 01xx.xxxx */ /* takes source from ls-bits and replicates over 16 bits */
 82 #define S_DATA_PLN  0xC0 /* 11xx.xxxx */ /* normal, each data access =16-bits in
 83  one plane of image mem */
 84 
 85 /* CREG 3A/CREG 3B */
 86 #       define RESET_CREG 0x80 /* 1000.0000 */
 87 
 88 /* ROP REG  -  all one nibble */
 89 /*      ********* NOTE : this is used r0,r1,r2,r3 *********** */
 90 #define ROP(r2,r3,r0,r1) ( (U_SHORT)((r0)|((r1)<<4)|((r2)<<8)|((r3)<<12)) )
 91 #define DEST_ZERO               0x0
 92 #define SRC_AND_DEST    0x1
 93 #define SRC_AND_nDEST   0x2
 94 #define SRC                             0x3
 95 #define nSRC_AND_DEST   0x4
 96 #define DEST                    0x5
 97 #define SRC_XOR_DEST    0x6
 98 #define SRC_OR_DEST             0x7
 99 #define SRC_NOR_DEST    0x8
100 #define SRC_XNOR_DEST   0x9
101 #define nDEST                   0xA
102 #define SRC_OR_nDEST    0xB
103 #define nSRC                    0xC
104 #define nSRC_OR_DEST    0xD
105 #define SRC_NAND_DEST   0xE
106 #define DEST_ONE                0xF
107 
108 #define SWAP(A) ((A>>8) | ((A&0xff) <<8))
109 
110 #if 0
111 #define outb(a,d) *(char *)(a)=(d)
112 #define outw(a,d) *(unsigned short *)a=d
113 #endif
114 
115 
116 /* frame buffer operations */
117 
118 static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con, 
119                          struct fb_info *info);
120 static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
121                          struct fb_info *info);
122 static int dn_fb_set_var(struct fb_var_screeninfo *var, int isactive,
123                          struct fb_info *info);
124 static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
125                           struct fb_info *info);
126 static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
127                           struct fb_info *info);
128 
129 static int dnfbcon_switch(int con,struct fb_info *info);
130 static int dnfbcon_updatevar(int con,struct fb_info *info);
131 static void dnfbcon_blank(int blank,struct fb_info *info);
132 
133 static void dn_fb_set_disp(int con,struct fb_info *info);
134 
135 static struct display disp[MAX_NR_CONSOLES];
136 static struct fb_info fb_info;
137 static struct fb_ops dn_fb_ops = {
138         owner:          THIS_MODULE,
139         fb_get_fix:     dn_fb_get_fix,
140         fb_get_var:     dn_fb_get_var,
141         fb_set_var:     dn_fb_set_var,
142         fb_get_cmap:    dn_fb_get_cmap,
143         fb_set_cmap:    dn_fb_set_cmap,
144 };
145 
146 static int currcon=0;
147 
148 #define NUM_TOTAL_MODES 1
149 struct fb_var_screeninfo dn_fb_predefined[] = {
150 
151         { 0, },
152 
153 };
154 
155 static char dn_fb_name[]="Apollo ";
156 
157 /* accel stuff */
158 #define USE_DN_ACCEL
159 
160 static struct display_switch dispsw_apollofb;
161 
162 static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con,
163                          struct fb_info *info) {
164 
165         strcpy(fix->id,"Apollo Mono");
166         fix->smem_start=(FRAME_BUFFER_START+IO_BASE);
167         fix->smem_len=FRAME_BUFFER_LEN;
168         fix->type=FB_TYPE_PACKED_PIXELS;
169         fix->type_aux=0;
170         fix->visual=FB_VISUAL_MONO10;
171         fix->xpanstep=0;
172         fix->ypanstep=0;
173         fix->ywrapstep=0;
174         fix->line_length=256;
175 
176         return 0;
177 
178 }
179         
180 static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
181                          struct fb_info *info) {
182                 
183         var->xres=1280;
184         var->yres=1024;
185         var->xres_virtual=2048;
186         var->yres_virtual=1024;
187         var->xoffset=0;
188         var->yoffset=0;
189         var->bits_per_pixel=1;
190         var->grayscale=0;
191         var->nonstd=0;
192         var->activate=0;
193         var->height=-1;
194         var->width=-1;
195         var->pixclock=0;
196         var->left_margin=0;
197         var->right_margin=0;
198         var->hsync_len=0;
199         var->vsync_len=0;
200         var->sync=0;
201         var->vmode=FB_VMODE_NONINTERLACED;
202 
203         return 0;
204 
205 }
206 
207 static int dn_fb_set_var(struct fb_var_screeninfo *var, int con,
208                          struct fb_info *info) {
209 
210         printk("fb_set_var\n");
211         if(var->xres!=1280) 
212                 return -EINVAL;
213         if(var->yres!=1024)
214                 return -EINVAL;
215         if(var->xres_virtual!=2048)
216                 return -EINVAL;
217         if(var->yres_virtual!=1024)
218                 return -EINVAL;
219         if(var->xoffset!=0)
220                 return -EINVAL;
221         if(var->yoffset!=0)
222                 return -EINVAL;
223         if(var->bits_per_pixel!=1)
224                 return -EINVAL;
225         if(var->grayscale!=0)
226                 return -EINVAL;
227         if(var->nonstd!=0)
228                 return -EINVAL;
229         if(var->activate!=0)
230                 return -EINVAL;
231         if(var->pixclock!=0)
232                 return -EINVAL;
233         if(var->left_margin!=0)
234                 return -EINVAL;
235         if(var->right_margin!=0)
236                 return -EINVAL;
237         if(var->hsync_len!=0)
238                 return -EINVAL;
239         if(var->vsync_len!=0)
240                 return -EINVAL;
241         if(var->sync!=0)
242                 return -EINVAL;
243         if(var->vmode!=FB_VMODE_NONINTERLACED)
244                 return -EINVAL;
245 
246         return 0;
247 
248 }
249 
250 static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
251                           struct fb_info *info) {
252 
253         printk("get cmap not supported\n");
254 
255         return -EINVAL;
256 }
257 
258 static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
259                           struct fb_info *info) {
260 
261         printk("set cmap not supported\n");
262 
263         return -EINVAL;
264 
265 }
266 
267 static void dn_fb_set_disp(int con, struct fb_info *info) {
268 
269   struct fb_fix_screeninfo fix;
270   struct display *display;
271   
272   dn_fb_get_fix(&fix,con, info);
273 
274   if (con>=0)
275         display=&fb_display[con];
276   else
277         display=&disp[0];
278 
279   if(con==-1) 
280     con=0;
281 
282    display->screen_base = (u_char *)fix.smem_start;
283    display->visual = fix.visual;
284    display->type = fix.type;
285    display->type_aux = fix.type_aux;
286    display->ypanstep = fix.ypanstep;
287    display->ywrapstep = fix.ywrapstep;
288    display->can_soft_blank = 1;
289    display->inverse = 0;
290    display->line_length = fix.line_length;
291 #ifdef FBCON_HAS_MFB
292    display->dispsw = &fbcon_mfb;
293 #else
294    display->dispsw=&fbcon_dummy;
295 #endif
296 
297 }
298   
299 unsigned long __init dnfb_init(unsigned long mem_start) {
300 
301         int err;
302        
303 
304         fb_info.changevar=NULL;
305         strcpy(&fb_info.modename[0],dn_fb_name);
306         fb_info.fontname[0]=0;
307         fb_info.disp=disp;
308         fb_info.switch_con=&dnfbcon_switch;
309         fb_info.updatevar=&dnfbcon_updatevar;
310         fb_info.blank=&dnfbcon_blank;   
311         fb_info.node = -1;
312         fb_info.fbops = &dn_fb_ops;
313         
314         dn_fb_get_var(&disp[0].var,0, &fb_info);
315 
316         dn_fb_set_disp(-1, &fb_info);
317         
318         err=register_framebuffer(&fb_info);
319         if(err < 0) {
320                 panic("unable to register apollo frame buffer\n");
321         }
322  
323         /* now we have registered we can safely setup the hardware */
324 
325         outb(RESET_CREG,  AP_CONTROL_3A);
326         outw(0x0,  AP_WRITE_ENABLE);
327         outb(NORMAL_MODE, AP_CONTROL_0); 
328         outb((AD_BLT | DST_EQ_SRC | NORM_CREG1),  AP_CONTROL_1);
329         outb(S_DATA_PLN,  AP_CONTROL_2);
330         outw(SWAP(0x3), AP_ROP_1);
331 
332         printk("apollo frame buffer alive and kicking !\n");
333 
334 
335         return mem_start;
336 
337 }       
338 
339         
340 static int dnfbcon_switch(int con,  struct fb_info *info) { 
341 
342         currcon=con;
343         
344         return 0;
345 
346 }
347 
348 static int dnfbcon_updatevar(int con,  struct fb_info *info) {
349 
350         return 0;
351 
352 }
353 
354 static void dnfbcon_blank(int blank,  struct fb_info *info) {
355 
356         if(blank)  {
357                 outb(0x0,  AP_CONTROL_3A);
358         }
359         else {
360                 outb(0x1,  AP_CONTROL_3A);
361         }
362 
363         return ;
364 
365 }
366 
367 void dn_bitblt(struct display *p,int x_src,int y_src, int x_dest, int y_dest,
368                int x_count, int y_count) {
369 
370         int incr,y_delta,pre_read=0,x_end,x_word_count;
371         ushort *src,dummy;
372         uint start_mask,end_mask,dest;
373         short i,j;
374 
375         incr=(y_dest<=y_src) ? 1 : -1 ;
376 
377         src=(ushort *)(p->screen_base+ y_src*p->next_line+(x_src >> 4));
378         dest=y_dest*(p->next_line >> 1)+(x_dest >> 4);
379         
380         if(incr>0) {
381                 y_delta=(p->next_line*8)-x_src-x_count;
382                 x_end=x_dest+x_count-1;
383                 x_word_count=(x_end>>4) - (x_dest >> 4) + 1;
384                 start_mask=0xffff0000 >> (x_dest & 0xf);
385                 end_mask=0x7ffff >> (x_end & 0xf);
386                 outb((((x_dest & 0xf) - (x_src &0xf))  % 16)|(0x4 << 5),AP_CONTROL_0);
387                 if((x_dest & 0xf) < (x_src & 0xf))
388                         pre_read=1;
389         }
390         else {
391                 y_delta=-((p->next_line*8)-x_src-x_count);
392                 x_end=x_dest-x_count+1;
393                 x_word_count=(x_dest>>4) - (x_end >> 4) + 1;
394                 start_mask=0x7ffff >> (x_dest & 0xf);
395                 end_mask=0xffff0000 >> (x_end & 0xf);
396                 outb(((-((x_src & 0xf) - (x_dest &0xf))) % 16)|(0x4 << 5),AP_CONTROL_0);
397                 if((x_dest & 0xf) > (x_src & 0xf))
398                         pre_read=1;
399         }
400 
401         for(i=0;i<y_count;i++) {
402 
403                 outb(0xc | (dest >> 16), AP_CONTROL_3A);
404                         
405                 if(pre_read) {
406                         dummy=*src;
407                         src+=incr;
408                 }
409 
410                 if(x_word_count) {
411                         outb(start_mask,AP_WRITE_ENABLE);
412                         *src=dest;
413                         src+=incr;
414                         dest+=incr;
415                         outb(0,AP_WRITE_ENABLE);
416 
417                         for(j=1;j<(x_word_count-1);j++) {
418                                 *src=dest;
419                                 src+=incr;      
420                                 dest+=incr;
421                         }
422 
423                         outb(start_mask,AP_WRITE_ENABLE);
424                         *src=dest;
425                         dest+=incr;
426                         src+=incr;
427                 }
428                 else {
429                         outb(start_mask | end_mask, AP_WRITE_ENABLE);
430                         *src=dest;
431                         dest+=incr;
432                         src+=incr;
433                 }
434                 src+=(y_delta/16);
435                 dest+=(y_delta/16);
436         }
437         outb(NORMAL_MODE,AP_CONTROL_0);
438 }
439 
440 static void bmove_apollofb(struct display *p, int sy, int sx, int dy, int dx,
441                       int height, int width)
442 {
443 
444     int fontheight,fontwidth;
445 
446     fontheight=fontheight(p);
447     fontwidth=fontwidth(p);
448 
449 #ifdef USE_DN_ACCEL
450     dn_bitblt(p,sx,sy*fontheight,dx,dy*fontheight,width*fontwidth,
451               height*fontheight);
452 #else
453     u_char *src, *dest;
454     u_int rows;
455 
456     if (sx == 0 && dx == 0 && width == p->next_line) {
457         src = p->screen_base+sy*fontheight*width;
458         dest = p->screen_base+dy*fontheight*width;
459         mymemmove(dest, src, height*fontheight*width);
460     } else if (dy <= sy) {
461         src = p->screen_base+sy*fontheight*next_line+sx;
462         dest = p->screen_base+dy*fontheight*next_line+dx;
463         for (rows = height*fontheight; rows--;) {
464             mymemmove(dest, src, width);
465             src += p->next_line;
466             dest += p->next_line;
467         }
468     } else {
469         src = p->screen_base+((sy+height)*fontheight-1)*p->next_line+sx;
470         dest = p->screen_base+((dy+height)*fontheight-1)*p->next_line+dx;
471         for (rows = height*fontheight; rows--;) {
472             mymemmove(dest, src, width);
473             src -= p->next_line;
474             dest -= p->next_line;
475         }
476     }
477 #endif
478 }
479 
480 static void clear_apollofb(struct vc_data *conp, struct display *p, int sy, int sx,
481                       int height, int width)
482 {
483         fbcon_mfb_clear(conp,p,sy,sx,height,width);
484 }
485 
486 static void putc_apollofb(struct vc_data *conp, struct display *p, int c, int yy,
487                      int xx)
488 {
489         fbcon_mfb_putc(conp,p,c,yy,xx);
490 }
491 
492 static void putcs_apollofb(struct vc_data *conp, struct display *p, const char *s,
493                       int count, int yy, int xx)
494 {
495         fbcon_mfb_putcs(conp,p,s,count,yy,xx);
496 }
497 
498 static void rev_char_apollofb(struct display *p, int xx, int yy)
499 {
500         fbcon_mfb_revc(p,xx,yy);
501 }
502 
503 static struct display_switch dispsw_apollofb = {
504     setup:              fbcon_mfb_setup,
505     bmove:              bmove_apollofb,
506     clear:              clear_apollofb,
507     putc:               putc_apollofb,
508     putcs:              putcs_apollofb,
509     revc:               rev_char_apollofb,
510     fontwidthmask:      FONTWIDTH(8)
511 };
512 

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