dn_cfb8.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:14k
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/string.h>
- #include <linux/mm.h>
- #include <linux/tty.h>
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <asm/setup.h>
- #include <asm/segment.h>
- #include <asm/system.h>
- #include <asm/irq.h>
- #include <asm/amigahw.h>
- #include <asm/amigaints.h>
- #include <asm/apollohw.h>
- #include <linux/fb.h>
- #include <linux/module.h>
- #include "dn_accel.h"
- #include "fbcon.h"
- #include "fbcon-mfb.h"
- /* apollo video HW definitions */
- /*
- * Control Registers. IOBASE + $x
- *
- * Note: these are the Memory/IO BASE definitions for a mono card set to the
- * alternate address
- *
- * Control 3A and 3B serve identical functions except that 3A
- * deals with control 1 and 3b deals with Color LUT reg.
- */
- #define AP_IOBASE 0x3d0 /* Base address of 1 plane board. */
- #define AP_STATUS isaIO2mem(AP_IOBASE+0) /* Status register. Read */
- #define AP_WRITE_ENABLE isaIO2mem(AP_IOBASE+0) /* Write Enable Register Write */
- #define AP_DEVICE_ID isaIO2mem(AP_IOBASE+1) /* Device ID Register. Read */
- #define AP_ROP_0 isaIO2mem(AP_IOBASE+2) /* Raster Operation reg. Write Word */
- #define AP_ROP_1 isaIO2mem(AP_IOBASE+4) /* Raster Operation reg. Write Word */
- #define AP_DIAG_MEM_REQ isaIO2mem(AP_IOBASE+6) /* Diagnostic Memory Request. Write Word */
- #define AP_CONTROL_0 isaIO2mem(AP_IOBASE+8) /* Control Register 0. Read/Write */
- #define AP_LUT_DATA isaIO2mem(AP_IOBASE+9) /* Control Register 0. Read/Write */
- #define AP_CONTROL_1 isaIO2mem(AP_IOBASE+0xa) /* Control Register 1. Read/Write */
- #define AP_LUT_CONTROL isaIO2mem(AP_IOBASE+0xb) /* Control Register 1. Read/Write */
- #define AP_CONTROL_2A isaIO2mem(AP_IOBASE+0xc) /* Control Register 2. Read/Write */
- #define AP_CONTROL_2B isaIO2mem(AP_IOBASE+0xd) /* Control Register 2. Read/Write */
- #define AP_CONTROL_3A isaIO2mem(AP_IOBASE+0xe) /* Control Register 3a. Read/Write */
- #define AP_CONTROL_3B isaIO2mem(AP_IOBASE+0xf) /* Control Register 3a. Read/Write */
- #define FRAME_BUFFER_START 0x0A0000
- #define FRAME_BUFFER_LEN 0x20000
- /* CREG 0 */
- #define VECTOR_MODE 0x40 /* 010x.xxxx */
- #define DBLT_MODE 0x80 /* 100x.xxxx */
- #define NORMAL_MODE 0xE0 /* 111x.xxxx */
- #define SHIFT_BITS 0x1F /* xxx1.1111 */
- /* other bits are Shift value */
- /* CREG 1 */
- #define AD_BLT 0x80 /* 1xxx.xxxx */
- #define ROP_EN 0x10 /* xxx1.xxxx */
- #define DST_EQ_SRC 0x00 /* xxx0.xxxx */
- #define nRESET_SYNC 0x08 /* xxxx.1xxx */
- #define SYNC_ENAB 0x02 /* xxxx.xx1x */
- #define BLANK_DISP 0x00 /* xxxx.xxx0 */
- #define ENAB_DISP 0x01 /* xxxx.xxx1 */
- #define NORM_CREG1 (nRESET_SYNC | SYNC_ENAB | ENAB_DISP) /* no reset sync */
- /* CREG 2B */
- /*
- * Following 3 defines are common to 1, 4 and 8 plane.
- */
- #define S_DATA_1s 0x00 /* 00xx.xxxx */ /* set source to all 1's -- vector drawing */
- #define S_DATA_PIX 0x40 /* 01xx.xxxx */ /* takes source from ls-bits and replicates over 16 bits */
- #define S_DATA_PLN 0xC0 /* 11xx.xxxx */ /* normal, each data access =16-bits in
- one plane of image mem */
- /* CREG 3A/CREG 3B */
- # define RESET_CREG 0x80 /* 1000.0000 */
- /* ROP REG - all one nibble */
- /* ********* NOTE : this is used r0,r1,r2,r3 *********** */
- #define ROP(r2,r3,r0,r1) ( (U_SHORT)((r0)|((r1)<<4)|((r2)<<8)|((r3)<<12)) )
- #define DEST_ZERO 0x0
- #define SRC_AND_DEST 0x1
- #define SRC_AND_nDEST 0x2
- #define SRC 0x3
- #define nSRC_AND_DEST 0x4
- #define DEST 0x5
- #define SRC_XOR_DEST 0x6
- #define SRC_OR_DEST 0x7
- #define SRC_NOR_DEST 0x8
- #define SRC_XNOR_DEST 0x9
- #define nDEST 0xA
- #define SRC_OR_nDEST 0xB
- #define nSRC 0xC
- #define nSRC_OR_DEST 0xD
- #define SRC_NAND_DEST 0xE
- #define DEST_ONE 0xF
- #define SWAP(A) ((A>>8) | ((A&0xff) <<8))
- /* frame buffer operations */
- static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
- static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
- static int dn_fb_set_var(struct fb_var_screeninfo *var, int isactive,
- struct fb_info *info);
- static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
- struct fb_info *info);
- static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
- struct fb_info *info);
- static int dnfbcon_switch(int con,struct fb_info *info);
- static int dnfbcon_updatevar(int con,struct fb_info *info);
- static void dnfbcon_blank(int blank,struct fb_info *info);
- static void dn_fb_set_disp(int con,struct fb_info *info);
- static struct display disp[MAX_NR_CONSOLES];
- static struct fb_info fb_info;
- static struct fb_ops dn_fb_ops = {
- owner: THIS_MODULE,
- fb_get_fix: dn_fb_get_fix,
- fb_get_var: dn_fb_get_var,
- fb_set_var: dn_fb_set_var,
- fb_get_cmap: dn_fb_get_cmap,
- fb_set_cmap: dn_fb_set_cmap,
- };
- static int currcon=0;
- #define NUM_TOTAL_MODES 1
- struct fb_var_screeninfo dn_fb_predefined[] = {
- { 0, },
- };
- static char dn_fb_name[]="Apollo ";
- /* accel stuff */
- #define USE_DN_ACCEL
- static struct display_switch dispsw_apollofb;
- static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info) {
- strcpy(fix->id,"Apollo Color8");
- fix->smem_start=(char*)(FRAME_BUFFER_START+IO_BASE);
- fix->smem_len=FRAME_BUFFER_LEN;
- fix->type=FB_TYPE_PACKED_PIXELS;
- fix->type_aux=0;
- fix->visual=FB_VISUAL_MONO10;
- fix->xpanstep=0;
- fix->ypanstep=0;
- fix->ywrapstep=0;
- fix->line_length=128;
- return 0;
- }
-
- static int dn_fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info) {
-
- var->xres=1024;
- var->yres=800;
- var->xres_virtual=1024;
- var->yres_virtual=1024;
- var->xoffset=0;
- var->yoffset=0;
- var->bits_per_pixel=1;
- var->grayscale=0;
- var->nonstd=0;
- var->activate=0;
- var->height=-1;
- var->width=-1;
- var->pixclock=0;
- var->left_margin=0;
- var->right_margin=0;
- var->hsync_len=0;
- var->vsync_len=0;
- var->sync=0;
- var->vmode=FB_VMODE_NONINTERLACED;
- return 0;
- }
- static int dn_fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info) {
- printk("fb_set_varn");
- if(var->xres!=1024)
- return -EINVAL;
- if(var->yres!=800)
- return -EINVAL;
- if(var->xres_virtual!=1024)
- return -EINVAL;
- if(var->yres_virtual!=1024)
- return -EINVAL;
- if(var->xoffset!=0)
- return -EINVAL;
- if(var->yoffset!=0)
- return -EINVAL;
- if(var->bits_per_pixel!=1)
- return -EINVAL;
- if(var->grayscale!=0)
- return -EINVAL;
- if(var->nonstd!=0)
- return -EINVAL;
- if(var->activate!=0)
- return -EINVAL;
- if(var->pixclock!=0)
- return -EINVAL;
- if(var->left_margin!=0)
- return -EINVAL;
- if(var->right_margin!=0)
- return -EINVAL;
- if(var->hsync_len!=0)
- return -EINVAL;
- if(var->vsync_len!=0)
- return -EINVAL;
- if(var->sync!=0)
- return -EINVAL;
- if(var->vmode!=FB_VMODE_NONINTERLACED)
- return -EINVAL;
- return 0;
- }
- static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
- struct fb_info *info) {
- printk("get cmap not supportedn");
- return -EINVAL;
- }
- static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
- struct fb_info *info) {
- printk("set cmap not supportedn");
- return -EINVAL;
- }
- static void dn_fb_set_disp(int con, struct fb_info *info) {
- struct fb_fix_screeninfo fix;
- dn_fb_get_fix(&fix,con, info);
- if(con==-1)
- con=0;
- disp[con].screen_base = (u_char *)fix.smem_start;
- printk("screenbase: %pn",fix.smem_start);
- disp[con].visual = fix.visual;
- disp[con].type = fix.type;
- disp[con].type_aux = fix.type_aux;
- disp[con].ypanstep = fix.ypanstep;
- disp[con].ywrapstep = fix.ywrapstep;
- disp[con].can_soft_blank = 1;
- disp[con].inverse = 0;
- disp[con].line_length = fix.line_length;
- disp[con].dispsw = &dispsw_apollofb;
- }
-
- unsigned long dn_fb_init(unsigned long mem_start) {
- int err;
-
- printk("dn_fb_initn");
- fb_info.changevar=NULL;
- strcpy(&fb_info.modename[0],dn_fb_name);
- fb_info.fontname[0]=0;
- fb_info.disp=disp;
- fb_info.switch_con=&dnfbcon_switch;
- fb_info.updatevar=&dnfbcon_updatevar;
- fb_info.blank=&dnfbcon_blank;
- fb_info.node = -1;
- fb_info.fbops = &dn_fb_ops;
-
- printk("dn_fb_init: registern");
- err=register_framebuffer(&fb_info);
- if(err < 0) {
- panic("unable to register apollo frame buffern");
- }
-
- /* now we have registered we can safely setup the hardware */
- outb(RESET_CREG, AP_CONTROL_3A);
- outb(RESET_CREG, AP_CONTROL_3B);
- outw(0x0, AP_WRITE_ENABLE);
- outb(NORMAL_MODE, AP_CONTROL_0);
- outb((AD_BLT | DST_EQ_SRC | NORM_CREG1), AP_CONTROL_1);
- outb(0, AP_CONTROL_2A);
- outb(S_DATA_PLN, AP_CONTROL_2B);
- outw(SWAP(0x3), AP_ROP_1);
- printk("apollo frame buffer alive and kicking !n");
- dn_fb_get_var(&disp[0].var,0, &fb_info);
- dn_fb_set_disp(-1, &fb_info);
- return mem_start;
- }
-
- static int dnfbcon_switch(int con, struct fb_info *info) {
- currcon=con;
-
- return 0;
- }
- static int dnfbcon_updatevar(int con, struct fb_info *info) {
- return 0;
- }
- static void dnfbcon_blank(int blank, struct fb_info *info) {
- if(blank) {
- outb(0x0, AP_CONTROL_3A);
- }
- else {
- outb(0x1, AP_CONTROL_3A);
- }
- return ;
- }
- void dn_bitblt(struct display *p,int x_src,int y_src, int x_dest, int y_dest,
- int x_count, int y_count) {
- int incr,y_delta,pre_read=0,x_end,x_word_count;
- ushort *src,dummy;
- uint start_mask,end_mask,dest;
- short i,j;
- incr=(y_dest<=y_src) ? 1 : -1 ;
- src=(ushort *)(p->screen_base+ y_src*p->next_line+(x_src >> 4));
- dest=y_dest*(p->next_line >> 1)+(x_dest >> 4);
-
- if(incr>0) {
- y_delta=(p->next_line*8)-x_src-x_count;
- x_end=x_dest+x_count-1;
- x_word_count=(x_end>>4) - (x_dest >> 4) + 1;
- start_mask=0xffff0000 >> (x_dest & 0xf);
- end_mask=0x7ffff >> (x_end & 0xf);
- outb((((x_dest & 0xf) - (x_src &0xf)) % 16)|(0x4 << 5),AP_CONTROL_0);
- if((x_dest & 0xf) < (x_src & 0xf))
- pre_read=1;
- }
- else {
- y_delta=-((p->next_line*8)-x_src-x_count);
- x_end=x_dest-x_count+1;
- x_word_count=(x_dest>>4) - (x_end >> 4) + 1;
- start_mask=0x7ffff >> (x_dest & 0xf);
- end_mask=0xffff0000 >> (x_end & 0xf);
- outb(((-((x_src & 0xf) - (x_dest &0xf))) % 16)|(0x4 << 5),AP_CONTROL_0);
- if((x_dest & 0xf) > (x_src & 0xf))
- pre_read=1;
- }
- for(i=0;i<y_count;i++) {
-
- if(pre_read) {
- dummy=*src;
- src+=incr;
- }
- if(x_word_count) {
- outb(start_mask,AP_WRITE_ENABLE);
- *src=dest;
- src+=incr;
- dest+=incr;
- outb(0,AP_WRITE_ENABLE);
- for(j=1;j<(x_word_count-1);j++) {
- *src=dest;
- src+=incr;
- dest+=incr;
- }
- outb(start_mask,AP_WRITE_ENABLE);
- *src=dest;
- dest+=incr;
- src+=incr;
- }
- else {
- outb(start_mask | end_mask, AP_WRITE_ENABLE);
- *src=dest;
- dest+=incr;
- src+=incr;
- }
- src+=(y_delta/16);
- dest+=(y_delta/16);
- }
- outb(NORMAL_MODE,AP_CONTROL_0);
- }
- static void bmove_apollofb(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
- {
- #ifdef USE_DN_ACCEL
- dn_bitblt(p,sx,sy*p->fontheight,dx,dy*p->fontheight,width*p->fontwidth,
- height*p->fontheight);
- #else
- u_char *src, *dest;
- u_int rows;
- if (sx == 0 && dx == 0 && width == p->next_line) {
- src = p->screen_base+sy*p->fontheight*width;
- dest = p->screen_base+dy*p->fontheight*width;
- mymemmove(dest, src, height*p->fontheight*width);
- } else if (dy <= sy) {
- src = p->screen_base+sy*p->fontheight*p->next_line+sx;
- dest = p->screen_base+dy*p->fontheight*p->next_line+dx;
- for (rows = height*p->fontheight; rows--;) {
- mymemmove(dest, src, width);
- src += p->next_line;
- dest += p->next_line;
- }
- } else {
- src = p->screen_base+((sy+height)*p->fontheight-1)*p->next_line+sx;
- dest = p->screen_base+((dy+height)*p->fontheight-1)*p->next_line+dx;
- for (rows = height*p->fontheight; rows--;) {
- mymemmove(dest, src, width);
- src -= p->next_line;
- dest -= p->next_line;
- }
- }
- #endif
- }
- static void clear_apollofb(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
- {
- u_char *dest;
- u_int rows;
- dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
- if (sx == 0 && width == p->next_line)
- if (attr_reverse(p,conp))
- mymemset(dest, height*p->fontheight*width);
- else
- mymemclear(dest, height*p->fontheight*width);
- else
- for (rows = height*p->fontheight; rows--; dest += p->next_line)
- if (attr_reverse(p,conp))
- mymemset(dest, width);
- else
- mymemclear_small(dest, width);
- }
- static void putc_apollofb(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
- {
- u_char *dest, *cdat;
- u_int rows, bold, revs, underl;
- u_char d;
- c &= 0xff;
- dest = p->screen_base+yy*p->fontheight*p->next_line+xx;
- cdat = p->fontdata+c*p->fontheight;
- bold = attr_bold(p,conp);
- revs = attr_reverse(p,conp);
- underl = attr_underline(p,conp);
- for (rows = p->fontheight; rows--; dest += p->next_line) {
- d = *cdat++;
- if (underl && !rows)
- d = 0xff;
- else if (bold)
- d |= d>>1;
- if (revs)
- d = ~d;
- *dest = d;
- }
- }
- static void putcs_apollofb(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
- {
- u_char *dest, *dest0, *cdat;
- u_int rows, bold, revs, underl;
- u_char c, d;
- dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
- bold = attr_bold(p,conp);
- revs = attr_reverse(p,conp);
- underl = attr_underline(p,conp);
- while (count--) {
- c = scr_readw(s++);
- dest = dest0++;
- cdat = p->fontdata+c*p->fontheight;
- for (rows = p->fontheight; rows--; dest += p->next_line) {
- d = *cdat++;
- if (underl && !rows)
- d = 0xff;
- else if (bold)
- d |= d>>1;
- if (revs)
- d = ~d;
- *dest = d;
- }
- }
- }
- static void rev_char_apollofb(struct display *p, int xx, int yy)
- {
- u_char *dest;
- u_int rows;
- dest = p->screen_base+yy*p->fontheight*p->next_line+xx;
- for (rows = p->fontheight; rows--; dest += p->next_line)
- *dest = ~*dest;
- }
- static struct display_switch dispsw_apollofb = {
- setup: fbcon_mfb_setup,
- bmove: bmove_apollofb,
- clear: clear_apollofb,
- putc: putc_apollofb,
- putcs: putcs_apollofb,
- revc: rev_char_apollofb,
- fontwidthmask: FONTWIDTH(8)
- };
- MODULE_LICENSE("GPL");