⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dn_cfb8.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
字号:
#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 1struct fb_var_screeninfo dn_fb_predefined[] = {	{ 0, },};static char dn_fb_name[]="Apollo ";/* accel stuff */#define USE_DN_ACCELstatic 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_var\n");	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 supported\n");	return -EINVAL;}static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,			  struct fb_info *info) {	printk("set cmap not supported\n");	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: %p\n",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_init\n");	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: register\n");	err=register_framebuffer(&fb_info);	if(err < 0) {		panic("unable to register apollo frame buffer\n");	} 	/* 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");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -