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

📄 retz3fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* unlock register CRT0..CRT7 */	crt_w(regs, CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20);	/* Zuerst zu schreibende Werte nur per printk ausgeben */	DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total);	crt_w(regs, CRT_HOR_TOTAL, data.h_total & 0xff);	DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend);	crt_w(regs, CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff);	DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart);	crt_w(regs, CRT_START_HOR_BLANK, data.h_bstart & 0xff);	DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32);	crt_w(regs, CRT_END_HOR_BLANK,  0x80 | (data.h_bstop & 0x1f));	DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart);	crt_w(regs, CRT_START_HOR_RETR, data.h_sstart & 0xff);	tmp = (data.h_sstop & 0x1f);	if (data.h_bstop & 0x20)		tmp |= 0x80;	DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp);	crt_w(regs, CRT_END_HOR_RETR, tmp);	DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff);	crt_w(regs, CRT_VER_TOTAL, (data.v_total & 0xff));	tmp = 0x10;  /* LineCompare bit #9 */	if (data.v_total & 256)		tmp |= 0x01;	if (data.v_dispend & 256)		tmp |= 0x02;	if (data.v_sstart & 256)		tmp |= 0x04;	if (data.v_bstart & 256)		tmp |= 0x08;	if (data.v_total & 512)		tmp |= 0x20;	if (data.v_dispend & 512)		tmp |= 0x40;	if (data.v_sstart & 512)		tmp |= 0x80;	DEBUG printk("CRT_OVERFLOW: %d\n", tmp);	crt_w(regs, CRT_OVERFLOW, tmp);	crt_w(regs, CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */	tmp = 0x40; /* LineCompare bit #8 */	if (data.v_bstart & 512)		tmp |= 0x20;	if (var->vmode & FB_VMODE_DOUBLE)		tmp |= 0x80; 	DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp);	crt_w(regs, CRT_MAX_SCAN_LINE, tmp);	crt_w(regs, CRT_CURSOR_START, 0x00);	crt_w(regs, CRT_CURSOR_END, 8 & 0x1f); /* font height */	crt_w(regs, CRT_START_ADDR_HIGH, 0x00);	crt_w(regs, CRT_START_ADDR_LOW, 0x00);	crt_w(regs, CRT_CURSOR_LOC_HIGH, 0x00);	crt_w(regs, CRT_CURSOR_LOC_LOW, 0x00); 	DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff);	crt_w(regs, CRT_START_VER_RETR, (data.v_sstart & 0xff));#if 1	/* 5 refresh cycles per scanline */	DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16);	crt_w(regs, CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20));#else	DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16);	crt_w(regs, CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32));#endif	DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff);	crt_w(regs, CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff));	DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff);	crt_w(regs, CRT_START_VER_BLANK, (data.v_bstart & 0xff));	DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff);	crt_w(regs, CRT_END_VER_BLANK, (data.v_bstop & 0xff));	DEBUG printk("CRT_MODE_CONTROL: 0xe3\n");	crt_w(regs, CRT_MODE_CONTROL, 0xe3);	DEBUG printk("CRT_LINE_COMPARE: 0xff\n");	crt_w(regs, CRT_LINE_COMPARE, 0xff);	tmp = (var->xres_virtual / 8) * (bpp / 8);	crt_w(regs, CRT_OFFSET, tmp);	crt_w(regs, CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */	tmp = 0x20;			/* Enable extended end bits */	if (data.h_total & 0x100)		tmp |= 0x01;	if ((data.h_dispend) & 0x100)		tmp |= 0x02;	if (data.h_bstart & 0x100)		tmp |= 0x04;	if (data.h_sstart & 0x100)		tmp |= 0x08;	if (var->vmode & FB_VMODE_INTERLACED)		tmp |= 0x10; 	DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp);	crt_w(regs, CRT_EXT_HOR_TIMING1, tmp);	tmp = 0x00;	if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100)		tmp |= 0x10;	crt_w(regs, CRT_EXT_START_ADDR, tmp);	tmp = 0x00;	if (data.h_total & 0x200)		tmp |= 0x01;	if ((data.h_dispend) & 0x200)		tmp |= 0x02;	if (data.h_bstart & 0x200)		tmp |= 0x04;	if (data.h_sstart & 0x200)		tmp |= 0x08;	tmp |= ((data.h_bstop & 0xc0) >> 2);	tmp |= ((data.h_sstop & 0x60) << 1);	crt_w(regs, CRT_EXT_HOR_TIMING2, tmp); 	DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp);	tmp = 0x10;			/* Line compare bit 10 */	if (data.v_total & 0x400)		tmp |= 0x01;	if ((data.v_dispend) & 0x400)		tmp |= 0x02;	if (data.v_bstart & 0x400)		tmp |= 0x04;	if (data.v_sstart & 0x400)		tmp |= 0x08;	tmp |= ((data.v_bstop & 0x300) >> 3);	if (data.v_sstop & 0x10)		tmp |= 0x80;	crt_w(regs, CRT_EXT_VER_TIMING, tmp); 	DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp);	crt_w(regs, CRT_MONITOR_POWER, 0x00);	/*	 * Convert from ps to Hz.	 */	freq = 2000000000 / var->pixclock;	freq = freq * 500;	best_freq = find_fq(freq);	pll_w(regs, 0x02, best_freq);	best_freq = find_fq(61000000);	pll_w(regs, 0x0a, best_freq);	pll_w(regs, 0x0e, 0x22);	gfx_w(regs, GFX_SET_RESET, 0x00);	gfx_w(regs, GFX_ENABLE_SET_RESET, 0x00);	gfx_w(regs, GFX_COLOR_COMPARE, 0x00);	gfx_w(regs, GFX_DATA_ROTATE, 0x00);	gfx_w(regs, GFX_READ_MAP_SELECT, 0x00);	gfx_w(regs, GFX_GRAPHICS_MODE, 0x00);	gfx_w(regs, GFX_MISC, 0x05);	gfx_w(regs, GFX_COLOR_XCARE, 0x0f);	gfx_w(regs, GFX_BITMASK, 0xff);	reg_r(regs, ACT_ADDRESS_RESET);	attr_w(regs, ACT_PALETTE0 , 0x00);	attr_w(regs, ACT_PALETTE1 , 0x01);	attr_w(regs, ACT_PALETTE2 , 0x02);	attr_w(regs, ACT_PALETTE3 , 0x03);	attr_w(regs, ACT_PALETTE4 , 0x04);	attr_w(regs, ACT_PALETTE5 , 0x05);	attr_w(regs, ACT_PALETTE6 , 0x06);	attr_w(regs, ACT_PALETTE7 , 0x07);	attr_w(regs, ACT_PALETTE8 , 0x08);	attr_w(regs, ACT_PALETTE9 , 0x09);	attr_w(regs, ACT_PALETTE10, 0x0a);	attr_w(regs, ACT_PALETTE11, 0x0b);	attr_w(regs, ACT_PALETTE12, 0x0c);	attr_w(regs, ACT_PALETTE13, 0x0d);	attr_w(regs, ACT_PALETTE14, 0x0e);	attr_w(regs, ACT_PALETTE15, 0x0f);	reg_r(regs, ACT_ADDRESS_RESET);	attr_w(regs, ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */	attr_w(regs, ACT_OVERSCAN_COLOR, 0x00);	attr_w(regs, ACT_COLOR_PLANE_ENA, 0x0f);	attr_w(regs, ACT_HOR_PEL_PANNING, 0x00);	attr_w(regs, ACT_COLOR_SELECT, 0x00);	reg_r(regs, ACT_ADDRESS_RESET);	reg_w(regs, ACT_DATA, 0x20);	reg_w(regs, VDAC_MASK, 0xff);	/*	 * Extended palette addressing ???	 */	switch (bpp){	case 8:		reg_w(regs, 0x83c6, 0x00);		break;	case 16:		reg_w(regs, 0x83c6, 0x60);		break;	case 24:		reg_w(regs, 0x83c6, 0xe0);		break;	default:		printk(KERN_INFO "Illegal color-depth: %i\n", bpp);	}	reg_w(regs, VDAC_ADDRESS, 0x00);	seq_w(regs, SEQ_MAP_MASK, 0x0f );	return 0;}/* *    This function should fill in the `fix' structure based on the *    values in the `par' structure. */static int retz3_encode_fix(struct fb_info *info,			    struct fb_fix_screeninfo *fix,			    struct retz3fb_par *par){	struct retz3_fb_info *zinfo = retz3info(info);	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id, retz3fb_name);	fix->smem_start = zinfo->physfbmem;	fix->smem_len = zinfo->fbsize;	fix->mmio_start = zinfo->physregs;	fix->mmio_len = 0x00c00000;	fix->type = FB_TYPE_PACKED_PIXELS;	fix->type_aux = 0;	if (par->bpp == 8)		fix->visual = FB_VISUAL_PSEUDOCOLOR;	else		fix->visual = FB_VISUAL_TRUECOLOR;	fix->xpanstep = 0;	fix->ypanstep = 0;	fix->ywrapstep = 0;	fix->line_length = 0;	fix->accel = FB_ACCEL_NCR_77C32BLT;	return 0;}/* *    Get the video params out of `var'. If a value doesn't fit, round *    it up, if it's too big, return -EINVAL. */static int retz3_decode_var(struct fb_var_screeninfo *var,			    struct retz3fb_par *par){	par->xres = var->xres;	par->yres = var->yres;	par->xres_vir = var->xres_virtual;	par->yres_vir = var->yres_virtual;	par->bpp = var->bits_per_pixel;	par->pixclock = var->pixclock;	par->vmode = var->vmode;	par->red = var->red;	par->green = var->green;	par->blue = var->blue;	par->transp = var->transp;	par->left_margin = var->left_margin;	par->right_margin = var->right_margin;	par->upper_margin = var->upper_margin;	par->lower_margin = var->lower_margin;	par->hsync_len = var->hsync_len;	par->vsync_len = var->vsync_len;	if (var->accel_flags & FB_ACCELF_TEXT)	    par->accel = FB_ACCELF_TEXT;	else	    par->accel = 0;	return 0;}/* *    Fill the `var' structure based on the values in `par' and maybe *    other values read out of the hardware. */static int retz3_encode_var(struct fb_var_screeninfo *var,			    struct retz3fb_par *par){	memset(var, 0, sizeof(struct fb_var_screeninfo));	var->xres = par->xres;	var->yres = par->yres;	var->xres_virtual = par->xres_vir;	var->yres_virtual = par->yres_vir;	var->xoffset = 0;	var->yoffset = 0;	var->bits_per_pixel = par->bpp;	var->grayscale = 0;	var->red = par->red;	var->green = par->green;	var->blue = par->blue;	var->transp = par->transp;	var->nonstd = 0;	var->activate = 0;	var->height = -1;	var->width = -1;	var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0;	var->pixclock = par->pixclock;	var->sync = 0;				/* ??? */	var->left_margin = par->left_margin;	var->right_margin = par->right_margin;	var->upper_margin = par->upper_margin;	var->lower_margin = par->lower_margin;	var->hsync_len = par->hsync_len;	var->vsync_len = par->vsync_len;	var->vmode = par->vmode;	return 0;}/* *    Set a single color register. Return != 0 for invalid regno. */static int retz3_setcolreg(unsigned int regno, unsigned int red,			   unsigned int green, unsigned int blue,			   unsigned int transp, struct fb_info *info){	struct retz3_fb_info *zinfo = retz3info(info);	volatile unsigned char *regs = zinfo->regs;	/* We'll get to this */	if (regno > 255)		return 1;	red >>= 10;	green >>= 10;	blue >>= 10;	zinfo->color_table[regno][0] = red;	zinfo->color_table[regno][1] = green;	zinfo->color_table[regno][2] = blue;	reg_w(regs, VDAC_ADDRESS_W, regno);	reg_w(regs, VDAC_DATA, red);	reg_w(regs, VDAC_DATA, green);	reg_w(regs, VDAC_DATA, blue);	return 0;}/* *    Read a single color register and split it into *    colors/transparent. Return != 0 for invalid regno. */static int retz3_getcolreg(unsigned int regno, unsigned int *red,			   unsigned int *green, unsigned int *blue,			   unsigned int *transp, struct fb_info *info){	struct retz3_fb_info *zinfo = retz3info(info);	int t;	if (regno > 255)		return 1;	t       = zinfo->color_table[regno][0];	*red    = (t<<10) | (t<<4) | (t>>2);	t       = zinfo->color_table[regno][1];	*green  = (t<<10) | (t<<4) | (t>>2);	t       = zinfo->color_table[regno][2];	*blue   = (t<<10) | (t<<4) | (t>>2);	*transp = 0;	return 0;}static inline void retz3_busy(struct display *p){	struct retz3_fb_info *zinfo = retz3info(p->fb_info);	volatile unsigned char *acm = zinfo->base + ACM_OFFSET;	unsigned char blt_status;	if (zinfo->blitbusy) {		do{			blt_status = *((acm) + (ACM_START_STATUS + 2));		}while ((blt_status & 1) == 0);		zinfo->blitbusy = 0;	}}static void retz3_bitblt (struct display *p,			  unsigned short srcx, unsigned short srcy,			  unsigned short destx, unsigned short desty,			  unsigned short width, unsigned short height,			  unsigned short cmd, unsigned short mask){	struct fb_var_screeninfo *var = &p->var;	struct retz3_fb_info *zinfo = retz3info(p->fb_info);	volatile unsigned long *acm = (unsigned long *)(zinfo->base + ACM_OFFSET);	unsigned long *pattern = (unsigned long *)(zinfo->fbmem + PAT_MEM_OFF);	unsigned short mod;	unsigned long tmp;	unsigned long pat, src, dst;	int i, xres_virtual = var->xres_virtual;	short bpp = (var->bits_per_pixel & 0xff);	if (bpp < 8)		bpp = 8;	tmp = mask | (mask << 16);	retz3_busy(p);	i = 0;	do{		*pattern++ = tmp;	}while(i++ < bpp/4);	tmp = cmd << 8;	*(acm + ACM_RASTEROP_ROTATION/4) = tmp;	mod = 0xc0c2;	pat = 8 * PAT_MEM_OFF;	dst = bpp * (destx + desty * xres_virtual);	/*	 * Source is not set for clear.	 */	if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) {		src = bpp * (srcx + srcy * xres_virtual);		if (destx > srcx) {			mod &= ~0x8000;			src += bpp * (width - 1);			dst += bpp * (width - 1);			pat += bpp * 2;		}		if (desty > srcy) {			mod &= ~0x4000;			src += bpp * (height - 1) * xres_virtual;			dst += bpp * (height - 1) * xres_virtual;			pat += bpp * 4;		}		*(acm + ACM_SOURCE/4) = cpu_to_le32(src);	}	*(acm + ACM_PATTERN/4) = cpu_to_le32(pat);	*(acm + ACM_DESTINATION/4) = cpu_to_le32(dst);	tmp = mod << 16;	*(acm + ACM_CONTROL/4) = tmp;	tmp  = width | (height << 16);	*(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp);	*(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;	*(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;	zinfo->blitbusy = 1;}#if 0/* * Move cursor to x, y */static void retz3_MoveCursor (unsigned short x, unsigned short y){	/* Guess we gotta deal with the cursor at some point */}#endif/* *    Fill the hardware's `par' structure. */static void retz3fb_get_par(struct fb_info *info, struct retz3fb_par *par){	struct retz3_fb_info *zinfo = retz3info(info);	if (zinfo->current_par_valid)		*par = zinfo->current_par;	else		retz3_decode_var(&retz3fb_default, par);}static void retz3fb_set_par(struct fb_info *info, struct retz3fb_par *par){	struct retz3_fb_info *zinfo = retz3info(info);	zinfo->current_par = *par;	zinfo->current_par_valid = 1;}static int do_fb_set_var(struct fb_info *info,			 struct fb_var_screeninfo *var, int isactive){	int err, activate;	struct retz3fb_par par;	struct retz3_fb_info *zinfo = retz3info(info);	if ((err = retz3_decode_var(var, &par)))		return err;	activate = var->activate;	/* XXX ... what to do about isactive ? */	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)		retz3fb_set_par(info, &par);	retz3_encode_var(var, &par);	var->activate = activate;	retz3_set_video(info, var, &zinfo->current_par);	return 0;}

⌨️ 快捷键说明

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