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

📄 tridentfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	bmove:		trident_bmove,	clear:		trident_16bpp_clear,	putc:		fbcon_cfb16_putc,	putcs:		fbcon_cfb16_putcs,	revc:		fbcon_cfb16_revc,	clear_margins:	fbcon_cfb16_clear_margins,	fontwidthmask:	FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)};#endif#ifdef FBCON_HAS_CFB32static void trident_32bpp_clear (struct vc_data *conp, struct display *p,				int sy, int sx, int height, int width){	int c;	c = ((u32*)p->dispsw_data)[attr_bgcol_ec(p,conp)];	trident_clear_helper(c,p,sy,sx,height,width);}static struct display_switch trident_32bpp = {	setup:		fbcon_cfb32_setup,	bmove:		trident_bmove,	clear:		trident_32bpp_clear,	putc:		fbcon_cfb32_putc,	putcs:		fbcon_cfb32_putcs,	revc:		fbcon_cfb32_revc,	clear_margins:	fbcon_cfb32_clear_margins,	fontwidthmask:	FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)};#endif/* * Hardware access functions */static inline unsigned char read3X4(int reg){	writeb(reg, fb_info.io_virt + CRT + 4);	return readb(fb_info.io_virt + CRT + 5);}static inline void write3X4(int reg, unsigned char val){	writeb(reg, fb_info.io_virt + CRT + 4);	writeb(val, fb_info.io_virt + CRT + 5);}static inline unsigned char read3C4(int reg){	t_outb(reg, 0x3C4);	return t_inb(0x3C5);}static inline void write3C4(int reg, unsigned char val){	t_outb(reg, 0x3C4);	t_outb(val, 0x3C5);}static inline unsigned char read3CE(int reg){	t_outb(reg, 0x3CE);	return t_inb(0x3CF);}static inline void writeAttr(int reg, unsigned char val){	readb(fb_info.io_virt + CRT + 0x0A);	//flip-flop to index	t_outb(reg, 0x3C0);	t_outb(val, 0x3C0);}static inline unsigned char readAttr(int reg){	readb(fb_info.io_virt + CRT + 0x0A);	//flip-flop to index	t_outb(reg, 0x3C0);	return t_inb(0x3C1);}static inline void write3CE(int reg, unsigned char val){	t_outb(reg, 0x3CE);	t_outb(val, 0x3CF);}#define bios_reg(reg) 	write3CE(BiosReg, reg)#if 0static inline void unprotect_all(void){	outb(Protection, 0x3C4);	outb(0x92, 0x3C5);}#endifstatic inline void enable_mmio(void){	/* Goto New Mode */	outb(0x0B, 0x3C4);	inb(0x3C5);	/* Unprotect registers */	outb(NewMode1, 0x3C4);	outb(0x80, 0x3C5);  	/* Enable MMIO */	outb(PCIReg, 0x3D4); 	outb(inb(0x3D5) | 0x01, 0x3D5);}#define crtc_unlock()	write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)/*  Return flat panel's maximum x resolution */static int __init get_nativex(void){	int x,y,tmp;	if (nativex)		return nativex;       	tmp = (read3CE(VertStretch) >> 4) & 3;	switch (tmp) {		case 0: x = 1280; y = 1024; break;		case 2: x = 1024; y = 768;  break;		case 3: x = 800;  y = 600;  break; 		case 4: x = 1400; y = 1050; break;		case 1: 		default:x = 640;  y = 480;  break;	}	output("%dx%d flat panel found\n", x, y);	return x;}/* Set pitch */static void set_lwidth(int width){	write3X4(Offset, width & 0xFF);	write3X4(AddColReg, (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >>4));}/* For resolutions smaller than FP resolution stretch */static void screen_stretch(void){	write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 1);	write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 1);}/* For resolutions smaller than FP resolution center */static void screen_center(void){	bios_reg(0);		// no stretch	write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 0x80);	write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 0x80);}/* Address of first shown pixel in display memory */static void set_screen_start(int base){	write3X4(StartAddrLow, base & 0xFF);	write3X4(StartAddrHigh, (base & 0xFF00) >> 8);	write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11));	write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));}/* Use 20.12 fixed-point for NTSC value and frequency calculation */#define calc_freq(n,m,k)  ( ((unsigned long)0xE517 * (n+8) / ((m+2)*(1<<k))) >> 12 )/* Set dotclock frequency */static void set_vclk(int freq){	int m,n,k;	int f,fi,d,di;	unsigned char lo=0,hi=0;	d = 20;	for(k = 2;k>=0;k--)	for(m = 0;m<63;m++)	for(n = 0;n<128;n++) {		fi = calc_freq(n,m,k);		if ((di = abs(fi - freq)) < d) {			d = di;			f = fi;			lo = n;			hi = (k<<6) | m;		}	}	if (chip3D) {		write3C4(ClockHigh,hi);		write3C4(ClockLow,lo);	} else {		outb(lo,0x43C8);		outb(hi,0x43C9);	}	debug("VCLK = %X %X\n",hi,lo);}/* Set number of lines for flat panels*/static void set_number_of_lines(int lines){	int tmp = read3CE(CyberEnhance) & 0x8F;	if (lines > 768)		tmp |= 0x30;	else if (lines > 600)		tmp |= 0x20;	else if (lines > 480)		tmp |= 0x10;	write3CE(CyberEnhance, tmp);}/* * If we see that FP is active we assume we have one. * Otherwise we have a CRT display.User can override. */static unsigned int __init get_displaytype(void){	if (fp)		return DISPLAY_FP;	if (crt)		return DISPLAY_CRT;	return (read3CE(FPConfig) & 0x10)?DISPLAY_FP:DISPLAY_CRT;}/* Try detecting the video memory size */static unsigned int __init get_memsize(void){	unsigned char tmp, tmp2;	unsigned int k;	/* If memory size provided by user */	if (memsize)		k = memsize * Kb;	else	switch (chip_id) {		case CYBER9525DVD:    k = 2560 * Kb; break;		default:			tmp = read3X4(SPR) & 0x0F;			switch (tmp) {				case 0x01: k = 512;     break;				case 0x02: k = 6 * Mb;  break; /* XP */				case 0x03: k = 1 * Mb;  break;				case 0x04: k = 8 * Mb;  break;				case 0x06: k = 10 * Mb; break; /* XP */				case 0x07: k = 2 * Mb;  break;				case 0x08: k = 12 * Mb; break; /* XP */				case 0x0A: k = 14 * Mb; break; /* XP */				case 0x0C: k = 16 * Mb; break; /* XP */				case 0x0E:                     /* XP */  					tmp2 = read3C4(0xC1);					switch (tmp2) {						case 0x00: k = 20 * Mb; break;						case 0x01: k = 24 * Mb; break;						case 0x10: k = 28 * Mb; break;						case 0x11: k = 32 * Mb; break;						default:   k = 1 * Mb;  break;					}				break;					case 0x0F: k = 4 * Mb; break;				default:   k = 1 * Mb;			}	}	k -= memdiff * Kb;	output("framebuffer size = %d Kb\n", k/Kb);	return k;}/* Fill in fix */static int trident_encode_fix(struct fb_fix_screeninfo *fix,				  const void *par,				  struct fb_info_gen *info){	struct tridentfb_info * i = (struct tridentfb_info *)info;	struct tridentfb_par * p = (struct tridentfb_par *)par;	debug("enter\n");	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id,tridentfb_name);	fix->smem_start = i->fbmem;	fix->smem_len = i->memsize;	fix->type = FB_TYPE_PACKED_PIXELS;	fix->type_aux = 0;	fix->visual = p->bpp==8 ? FB_VISUAL_PSEUDOCOLOR:FB_VISUAL_TRUECOLOR;	fix->xpanstep = fix->ywrapstep = 0;	fix->ypanstep = 1;	fix->line_length = p->linelength;	fix->mmio_start = 0;	fix->mmio_len = 0;	fix->accel = FB_ACCEL_NONE;	debug("exit\n");	return 0;}/* Fill in par from var */static int trident_decode_var(const struct fb_var_screeninfo *var,				  void *par,				  struct fb_info_gen *info){	struct tridentfb_par * p = (struct tridentfb_par *)par;	struct tridentfb_info * i = (struct tridentfb_info *)info;	int vres,vfront,vback,vsync;	debug("enter\n");	p->var = *var;	p->bpp = var->bits_per_pixel;	if (p->bpp == 24 )		p->bpp = 32;	p->linelength = var->xres_virtual * p->bpp/8;	switch (p->bpp) {		case 8:			p->var.red.offset = 0;			p->var.green.offset = 0;			p->var.blue.offset = 0;			p->var.red.length = 6;			p->var.green.length = 6;			p->var.blue.length = 6;			break;		case 16:			p->var.red.offset = 11;			p->var.green.offset = 5;			p->var.blue.offset = 0;			p->var.red.length = 5;			p->var.green.length = 6;			p->var.blue.length = 5;			break;		case 32:			p->var.red.offset = 16;			p->var.green.offset = 8;			p->var.blue.offset = 0;			p->var.red.length = 8;			p->var.green.length = 8;			p->var.blue.length = 8;			break;		default:			return -EINVAL;	}	/* convert from picoseconds to MHz */	p->vclk = 1000000/var->pixclock;	if (p->bpp == 32)		p->vclk *=2;	p->hres = var->xres;	vres = p->vres = var->yres;	/* See if requested resolution is larger than flat panel */	if (p->hres > i->nativex && flatpanel) {		return -EINVAL;	}	/* See if requested resolution fits in available memory */	if (p->hres * p->vres * p->bpp/8 > i->memsize) {		return -EINVAL;	}	vfront = var->upper_margin;	vback =	var->lower_margin;	vsync =	var->vsync_len;	/* Compute horizontal and vertical VGA CRTC timing values */	if (var->vmode & FB_VMODE_INTERLACED) {		vres /= 2;		vfront /=2;		vback /=2;		vsync /=2;	}	if (var->vmode & FB_VMODE_DOUBLE) {		vres *= 2;		vfront *=2;		vback *=2;		vsync *=2;	}	p->htotal = (p->hres + var->left_margin + var->right_margin + var->hsync_len)/8 - 10;	p->hdispend = p->hres/8 - 1;	p->hsyncstart = (p->hres + var->right_margin)/8;	p->hsyncend = var->hsync_len/8;	p->hblankstart = p->hdispend + 1;	p->hblankend = p->htotal + 5;	p->vtotal = vres + vfront + vback + vsync - 2;	p->vdispend = vres - 1;	p->vsyncstart = vres + vback;	p->vsyncend = vsync;	p->vblankstart = vres;	p->vblankend = p->vtotal + 2;	debug("exit\n");	return 0;}/* Fill in var from info */static int trident_encode_var(struct fb_var_screeninfo *var,				  const void *par,				  struct fb_info_gen *info){	struct tridentfb_par * p = (struct tridentfb_par *)par;	debug("enter\n");	*var = p->var;	var->bits_per_pixel = p->bpp;	debug("exit\n");	return 0;}/* Fill in par from hardware */static void trident_get_par(void *par, struct fb_info_gen *info){	struct tridentfb_par * p = (struct tridentfb_par *)par;	struct tridentfb_info * i = (struct tridentfb_info *)info;	debug("enter\n");	*p = i->currentmode;	debug("exit\n");}/* Pan the display */static int trident_pan_display(const struct fb_var_screeninfo *var,				   struct fb_info_gen *info){	unsigned int offset;	struct tridentfb_info * i = (struct tridentfb_info *)info;	debug("enter\n");	offset = (var->xoffset + (var->yoffset * var->xres))			* var->bits_per_pixel/32;	i->currentmode.var.xoffset = var->xoffset;	i->currentmode.var.yoffset = var->yoffset;	set_screen_start(offset);	debug("exit\n");	return 0;}/* Set the hardware from par */static void trident_set_par(const void *par, struct fb_info_gen *info){	struct tridentfb_par * p = (struct tridentfb_par *)par;	struct tridentfb_info * i = (struct tridentfb_info *)info;	unsigned char tmp;	debug("enter\n");	i->currentmode = *p;	enable_mmio();	crtc_unlock();	write3CE(CyberControl,8);	if (flatpanel && p->hres < i->nativex) {		/*		 * on flat panels with native size larger		 * than requested resolution decide whether		 * we stretch or center		 */		t_outb(0xEB,0x3C2);		write3CE(CyberControl,0x81);		if (center) 			screen_center();		else if (stretch)			screen_stretch();	} else {		t_outb(0x2B,0x3C2);		write3CE(CyberControl,8);	}	/* vertical timing values */	write3X4(CRTVTotal, p->vtotal & 0xFF);	write3X4(CRTVDispEnd, p->vdispend & 0xFF);	write3X4(CRTVSyncStart, p->vsyncstart & 0xFF);	write3X4(CRTVSyncEnd, (p->vsyncend & 0x0F));	write3X4(CRTVBlankStart, p->vblankstart & 0xFF);	write3X4(CRTVBlankEnd, 0/*p->vblankend & 0xFF*/);	/* horizontal timing values */	write3X4(CRTHTotal, p->htotal & 0xFF);	write3X4(CRTHDispEnd, p->hdispend & 0xFF);	write3X4(CRTHSyncStart, p->hsyncstart & 0xFF);	write3X4(CRTHSyncEnd, (p->hsyncend & 0x1F) | ((p->hblankend & 0x20)<<2));	write3X4(CRTHBlankStart, p->hblankstart & 0xFF);	write3X4(CRTHBlankEnd, 0/*(p->hblankend & 0x1F)*/);	/* higher bits of vertical timing values */	tmp = 0x10;	if (p->vtotal & 0x100) tmp |= 0x01;	if (p->vdispend & 0x100) tmp |= 0x02;	if (p->vsyncstart & 0x100) tmp |= 0x04;	if (p->vblankstart & 0x100) tmp |= 0x08;	if (p->vtotal & 0x200) tmp |= 0x20;

⌨️ 快捷键说明

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