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

📄 clgenfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			_par->var.blue.offset = 0;		}		_par->var.red.length = 5;		_par->var.green.length = 5;		_par->var.blue.length = 5;		break;	case 24:		_par->line_length = _par->var.xres_virtual * 3;		_par->visual = FB_VISUAL_DIRECTCOLOR;		if(isPReP) {			_par->var.red.offset = 8;			_par->var.green.offset = 16;			_par->var.blue.offset = 24;		} else {			_par->var.red.offset = 16;			_par->var.green.offset = 8;			_par->var.blue.offset = 0;		}		_par->var.red.length = 8;		_par->var.green.length = 8;		_par->var.blue.length = 8;		break;	case 32:		_par->line_length = _par->var.xres_virtual * 4;		_par->visual = FB_VISUAL_DIRECTCOLOR;		if(isPReP) {			_par->var.red.offset = 8;			_par->var.green.offset = 16;			_par->var.blue.offset = 24;		} else {			_par->var.red.offset = 16;			_par->var.green.offset = 8;			_par->var.blue.offset = 0;		}		_par->var.red.length = 8;		_par->var.green.length = 8;		_par->var.blue.length = 8;		break;	default:		DPRINTK("Unsupported bpp size: %d\n", _par->var.bits_per_pixel);		assert (FALSE);		/* should never occur */		break;	}	_par->var.red.msb_right =	    _par->var.green.msb_right =	    _par->var.blue.msb_right =	    _par->var.transp.offset =	    _par->var.transp.length =	    _par->var.transp.msb_right = 0;	_par->type = FB_TYPE_PACKED_PIXELS;	/* convert from ps to kHz */	freq = 1000000000 / var->pixclock;	DPRINTK ("desired pixclock: %ld kHz\n", freq);	if (IS_7548(fb_info))		maxclock = 80100;	else		maxclock = clgen_board_info[fb_info->btype].maxclock;	_par->multiplexing = 0;	/* If the frequency is greater than we can support, we might be able	 * to use multiplexing for the video mode */	if (freq > maxclock) {		switch (fb_info->btype) {		case BT_ALPINE:		case BT_GD5480:			_par->multiplexing = 1;			break;		default:			printk (KERN_WARNING "clgen: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock);			DPRINTK ("EXIT - return -EINVAL\n");			return -EINVAL;		}	}#if 0	/* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where	 * the VCLK is double the pixel clock. */	switch (var->bits_per_pixel) {	case 16:	case 32:		if (_par->HorizRes <= 800)			freq /= 2;	/* Xbh has this type of clock for 32-bit */		break;	}#endif	bestclock (freq, &_par->freq, &_par->nom, &_par->den, &_par->div,		   maxclock);	_par->mclk = clgen_get_mclk (freq, _par->var.bits_per_pixel, &_par->divMCLK);	xres = _par->var.xres;	hfront = _par->var.right_margin;	hsync = _par->var.hsync_len;	hback = _par->var.left_margin;	yres = _par->var.yres;	vfront = _par->var.lower_margin;	vsync = _par->var.vsync_len;	vback = _par->var.upper_margin;	if (_par->var.vmode & FB_VMODE_DOUBLE) {		yres *= 2;		vfront *= 2;		vsync *= 2;		vback *= 2;	} else if (_par->var.vmode & FB_VMODE_INTERLACED) {		yres = (yres + 1) / 2;		vfront = (vfront + 1) / 2;		vsync = (vsync + 1) / 2;		vback = (vback + 1) / 2;	}	_par->HorizRes = xres;	_par->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;	_par->HorizDispEnd = xres / 8 - 1;	_par->HorizBlankStart = xres / 8;	_par->HorizBlankEnd = _par->HorizTotal + 5;	/* does not count with "-5" */	_par->HorizSyncStart = (xres + hfront) / 8 + 1;	_par->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;	_par->VertRes = yres;	_par->VertTotal = yres + vfront + vsync + vback - 2;	_par->VertDispEnd = yres - 1;	_par->VertBlankStart = yres;	_par->VertBlankEnd = _par->VertTotal;	_par->VertSyncStart = yres + vfront - 1;	_par->VertSyncEnd = yres + vfront + vsync - 1;	if (_par->VertRes >= 1024) {		_par->VertTotal /= 2;		_par->VertSyncStart /= 2;		_par->VertSyncEnd /= 2;		_par->VertDispEnd /= 2;	}	if (_par->multiplexing) {		_par->HorizTotal /= 2;		_par->HorizSyncStart /= 2;		_par->HorizSyncEnd /= 2;		_par->HorizDispEnd /= 2;	}	if (_par->VertRes >= 1280) {		printk (KERN_WARNING "clgen: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n");		DPRINTK ("EXIT - EINVAL error\n");		return -EINVAL;	}	DPRINTK ("EXIT\n");	return 0;}static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,			     struct fb_info_gen *info){	DPRINTK ("ENTER\n");	*var = ((struct clgenfb_par *) par)->var;	DPRINTK ("EXIT\n");	return 0;}/* get current video mode */static void clgen_get_par (void *par, struct fb_info_gen *info){	struct clgenfb_par *_par = (struct clgenfb_par *) par;	struct clgenfb_info *_info = (struct clgenfb_info *) info;	DPRINTK ("ENTER\n");	*_par = _info->currentmode;	DPRINTK ("EXIT\n");}static void clgen_set_mclk (const struct clgenfb_info *fb_info, int val, int div){	assert (fb_info != NULL);	if (div == 2) {		/* VCLK = MCLK/2 */		unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);		vga_wseq (fb_info->regs, CL_SEQR1E, old | 0x1);		vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));	} else if (div == 1) {		/* VCLK = MCLK */		unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);		vga_wseq (fb_info->regs, CL_SEQR1E, old & ~0x1);		vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));	} else {		vga_wseq (fb_info->regs, CL_SEQR1F, val & 0x3f);	}}/*************************************************************************	clgen_set_par()	actually writes the values for a new video mode into the hardware,**************************************************************************/static void clgen_set_par (const void *par, struct fb_info_gen *info){	unsigned char tmp;	int offset = 0;	struct clgenfb_par *_par = (struct clgenfb_par *) par;	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;	const struct clgen_board_info_rec *bi;	DPRINTK ("ENTER\n");	DPRINTK ("Requested mode: %dx%dx%d\n",	       _par->var.xres, _par->var.yres, _par->var.bits_per_pixel);	DPRINTK ("pixclock: %d\n", _par->var.pixclock);	bi = &clgen_board_info[fb_info->btype];	/* unlock register VGA_CRTC_H_TOTAL..CRT7 */	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20);	/* previously: 0x00) */	/* if debugging is enabled, all parameters get output before writing */	DPRINTK ("CRT0: %ld\n", _par->HorizTotal);	vga_wcrt (fb_info->regs, VGA_CRTC_H_TOTAL, _par->HorizTotal);	DPRINTK ("CRT1: %ld\n", _par->HorizDispEnd);	vga_wcrt (fb_info->regs, VGA_CRTC_H_DISP, _par->HorizDispEnd);	DPRINTK ("CRT2: %ld\n", _par->HorizBlankStart);	vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_START, _par->HorizBlankStart);	DPRINTK ("CRT3: 128+%ld\n", _par->HorizBlankEnd % 32);	/*  + 128: Compatible read */	vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_END, 128 + (_par->HorizBlankEnd % 32));	DPRINTK ("CRT4: %ld\n", _par->HorizSyncStart);	vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_START, _par->HorizSyncStart);	tmp = _par->HorizSyncEnd % 32;	if (_par->HorizBlankEnd & 32)		tmp += 128;	DPRINTK ("CRT5: %d\n", tmp);	vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_END, tmp);	DPRINTK ("CRT6: %ld\n", _par->VertTotal & 0xff);	vga_wcrt (fb_info->regs, VGA_CRTC_V_TOTAL, (_par->VertTotal & 0xff));	tmp = 16;		/* LineCompare bit #9 */	if (_par->VertTotal & 256)		tmp |= 1;	if (_par->VertDispEnd & 256)		tmp |= 2;	if (_par->VertSyncStart & 256)		tmp |= 4;	if (_par->VertBlankStart & 256)		tmp |= 8;	if (_par->VertTotal & 512)		tmp |= 32;	if (_par->VertDispEnd & 512)		tmp |= 64;	if (_par->VertSyncStart & 512)		tmp |= 128;	DPRINTK ("CRT7: %d\n", tmp);	vga_wcrt (fb_info->regs, VGA_CRTC_OVERFLOW, tmp);	tmp = 0x40;		/* LineCompare bit #8 */	if (_par->VertBlankStart & 512)		tmp |= 0x20;	if (_par->var.vmode & FB_VMODE_DOUBLE)		tmp |= 0x80;	DPRINTK ("CRT9: %d\n", tmp);	vga_wcrt (fb_info->regs, VGA_CRTC_MAX_SCAN, tmp);	DPRINTK ("CRT10: %ld\n", _par->VertSyncStart & 0xff);	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_START, (_par->VertSyncStart & 0xff));	DPRINTK ("CRT11: 64+32+%ld\n", _par->VertSyncEnd % 16);	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, (_par->VertSyncEnd % 16 + 64 + 32));	DPRINTK ("CRT12: %ld\n", _par->VertDispEnd & 0xff);	vga_wcrt (fb_info->regs, VGA_CRTC_V_DISP_END, (_par->VertDispEnd & 0xff));	DPRINTK ("CRT15: %ld\n", _par->VertBlankStart & 0xff);	vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_START, (_par->VertBlankStart & 0xff));	DPRINTK ("CRT16: %ld\n", _par->VertBlankEnd & 0xff);	vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_END, (_par->VertBlankEnd & 0xff));	DPRINTK ("CRT18: 0xff\n");	vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0xff);	tmp = 0;	if (_par->var.vmode & FB_VMODE_INTERLACED)		tmp |= 1;	if (_par->HorizBlankEnd & 64)		tmp |= 16;	if (_par->HorizBlankEnd & 128)		tmp |= 32;	if (_par->VertBlankEnd & 256)		tmp |= 64;	if (_par->VertBlankEnd & 512)		tmp |= 128;	DPRINTK ("CRT1a: %d\n", tmp);	vga_wcrt (fb_info->regs, CL_CRT1A, tmp);	/* set VCLK0 */	/* hardware RefClock: 14.31818 MHz */	/* formula: VClk = (OSC * N) / (D * (1+P)) */	/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */	vga_wseq (fb_info->regs, CL_SEQRB, _par->nom);	tmp = _par->den << 1;	if (_par->div != 0)		tmp |= 1;	if ((fb_info->btype == BT_SD64) ||	    (fb_info->btype == BT_ALPINE) ||	    (fb_info->btype == BT_GD5480))		tmp |= 0x80;	/* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */	DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp);	vga_wseq (fb_info->regs, CL_SEQR1B, tmp);	if (_par->VertRes >= 1024)		/* 1280x1024 */		vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc7);	else		/* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit		 * address wrap, no compat. */		vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3);/* HAEH?        vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20);  * previously: 0x00  unlock VGA_CRTC_H_TOTAL..CRT7 */	/* don't know if it would hurt to also program this if no interlaced */	/* mode is used, but I feel better this way.. :-) */	if (_par->var.vmode & FB_VMODE_INTERLACED)		vga_wcrt (fb_info->regs, VGA_CRTC_REGS, _par->HorizTotal / 2);	else		vga_wcrt (fb_info->regs, VGA_CRTC_REGS, 0x00);	/* interlace control */	vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0);	/* adjust horizontal/vertical sync type (low/high) */	tmp = 0x03;		/* enable display memory & CRTC I/O address for color mode */	if (_par->var.sync & FB_SYNC_HOR_HIGH_ACT)		tmp |= 0x40;	if (_par->var.sync & FB_SYNC_VERT_HIGH_ACT)		tmp |= 0x80;	WGen (fb_info, VGA_MIS_W, tmp);	vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0);	/* Screen A Preset Row-Scan register */	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0);	/* text cursor on and start line */	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 31);	/* text cursor end line */	/******************************************************	 *	 * 1 bpp	 *	 */	/* programming for different color depths */	if (_par->var.bits_per_pixel == 1) {		DPRINTK ("clgen: preparing for 1 bit deep display\n");		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0);	/* mode register */		/* SR07 */		switch (fb_info->btype) {		case BT_SD64:		case BT_PICCOLO:		case BT_PICASSO:		case BT_SPECTRUM:		case BT_PICASSO4:		case BT_ALPINE:		case BT_GD5480:			DPRINTK (" (for GD54xx)\n");			vga_wseq (fb_info->regs, CL_SEQR7,				  _par->multiplexing ?				  	bi->sr07_1bpp_mux : bi->sr07_1bpp);			break;		case BT_LAGUNA:			DPRINTK (" (for GD546x)\n");			vga_wseq (fb_info->regs, CL_SEQR7,				vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);			break;		default:			printk (KERN_WARNING "clgen: unknown Board\n");			break;		}		/* Extended Sequencer Mode */		switch (fb_info->btype) {		case BT_SD64:			/* setting the SEQRF on SD64 is not necessary (only during init) */			DPRINTK ("(for SD64)\n");			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1a);		/*  MCLK select */			break;		case BT_PICCOLO:			DPRINTK ("(for Piccolo)\n");/* ### ueberall 0x22? */			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 1c MCLK select */			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* evtl d0 bei 1 bit? avoid FIFO underruns..? */			break;		case BT_PICASSO:			DPRINTK ("(for Picasso)\n");			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 22 MCLK select */			vga_wseq (fb_info->regs, CL_SEQRF, 0xd0);	/* ## vorher d0 avoid FIFO underruns..? */			break;		case BT_SPECTRUM:			DPRINTK ("(for Spectrum)\n");/* ### ueberall 0x22? */			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 1c MCLK select */			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* evtl d0? avoid FIFO underruns..? */			break;		case BT_PICASSO4:		case BT_ALPINE:		case BT_GD5480:		case BT_LAGUNA:			DPRINTK (" (for GD54xx)\n");			/* do nothing */			break;		default:			printk (KERN_WARNING "clgen: unknown Board\n");			break;		}		WGen (fb_info, VGA_PEL_MSK, 0x01);	/* pixel mask: pass-through for first plane */		if (_par->multiplexing)			WHDR (fb_info, 0x4a);	/* hidden dac reg: 1280x1024 */		else			WHDR (fb_info, 0);	/* hidden dac: nothing */		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x06);	/* memory mode: odd/even, ext. memory */		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0x01);	/* plane mask: only write to first plane */		offset = _par->var.xres_virtual / 16;	}	/******************************************************	 *	 * 8 bpp	 *	 */	else if (_par->var.bits_per_pixel == 8) {		DPRINTK ("clgen: preparing for 8 bit deep display\n");		switch (fb_info->btype) {		case BT_SD64:		case BT_PICCOLO:		case BT_PICASSO:

⌨️ 快捷键说明

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