au1200fb.c

来自「Linux环境下视频显示卡设备的驱动程序源代码」· C语言 代码 · 共 1,922 行 · 第 1/4 页

C
1,922
字号
		.mode_backlight	= 0x00000000,		.mode_auxpll		= 6, /* 72MHz AUXPLL */		.device_init		= NULL,		.device_shutdown	= NULL,		1024, 1024,		768, 768,	},	[4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */		.name = "XVGA_1280x1024",		.monspecs = {			.modedb = NULL,			.modedb_len = 0,			.hfmin = 30000,			.hfmax = 70000,			.vfmin = 60,			.vfmax = 60,			.dclkmin = 6000000,			.dclkmax = 28000000,			.input = FB_DISP_RGB,		},		.mode_screen		= 0x27fbff80,		.mode_horztiming	= 0x00cdb2c7,		.mode_verttiming	= 0x00600002,		.mode_clkcontrol	= 0x000A0000, /* /1 */		.mode_pwmdiv		= 0x00000000,		.mode_pwmhi		= 0x00000000,		.mode_outmask	= 0x00FFFFFF,		.mode_fifoctrl	= 0x2f2f2f2f,		.mode_toyclksrc	= 0x00000004, /* AUXPLL directly */		.mode_backlight	= 0x00000000,		.mode_auxpll		= 10, /* 120MHz AUXPLL */		.device_init		= NULL,		.device_shutdown	= NULL,		1280, 1280,		1024, 1024,	},	[5] = { /* Samsung 1024x768 TFT */		.name = "Samsung_1024x768_TFT",		.monspecs = {			.modedb = NULL,			.modedb_len = 0,			.hfmin = 30000,			.hfmax = 70000,			.vfmin = 60,			.vfmax = 60,			.dclkmin = 6000000,			.dclkmax = 28000000,			.input = FB_DISP_RGB,		},		.mode_screen		= 0x1ffaff80,		.mode_horztiming	= 0x018cc677,		.mode_verttiming	= 0x00241217,		.mode_clkcontrol	= 0x00000000, /* SCB 0x1 /4=24Mhz */		.mode_pwmdiv		= 0x8000063f, /* SCB 0x0 */		.mode_pwmhi		= 0x03400000, /* SCB 0x0 */		.mode_outmask	= 0x00FFFFFF,		.mode_fifoctrl	= 0x2f2f2f2f,		.mode_toyclksrc	= 0x00000004, /* AUXPLL directly */		.mode_backlight	= 0x00000000,		.mode_auxpll		= 8, /* 96MHz AUXPLL */		.device_init		= board_au1200fb_panel_init,		.device_shutdown	= board_au1200fb_panel_shutdown,		1024, 1024,		768, 768,	},	[6] = { /* Toshiba 640x480 TFT */		.name = "Toshiba_640x480_TFT",		.monspecs = {			.modedb = NULL,			.modedb_len = 0,			.hfmin = 30000,			.hfmax = 70000,			.vfmin = 60,			.vfmax = 60,			.dclkmin = 6000000,			.dclkmax = 28000000,			.input = FB_DISP_RGB,		},		.mode_screen		= LCD_SCREEN_SX_N(640) |			LCD_SCREEN_SY_N(480),		.mode_horztiming	= LCD_HORZTIMING_HPW_N(96) |			LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),		.mode_verttiming	= LCD_VERTTIMING_VPW_N(2) |			LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),		.mode_clkcontrol	= 0x00000000, /* /4=24Mhz */		.mode_pwmdiv		= 0x8000063f,		.mode_pwmhi		= 0x03400000,		.mode_outmask	= 0x00fcfcfc,		.mode_fifoctrl	= 0x2f2f2f2f,		.mode_toyclksrc	= 0x00000004, /* AUXPLL directly */		.mode_backlight	= 0x00000000,		.mode_auxpll		= 8, /* 96MHz AUXPLL */		.device_init		= board_au1200fb_panel_init,		.device_shutdown	= board_au1200fb_panel_shutdown,		640, 480,		640, 480,	},	[7] = { /* Sharp 320x240 TFT */		.name = "Sharp_320x240_TFT",		.monspecs = {			.modedb = NULL,			.modedb_len = 0,			.hfmin = 12500,			.hfmax = 20000,			.vfmin = 38,			.vfmax = 81,			.dclkmin = 4500000,			.dclkmax = 6800000,			.input = FB_DISP_RGB,		},		.mode_screen		= LCD_SCREEN_SX_N(320) |			LCD_SCREEN_SY_N(240),		.mode_horztiming	= LCD_HORZTIMING_HPW_N(60) |			LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),		.mode_verttiming	= LCD_VERTTIMING_VPW_N(2) |			LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),		.mode_clkcontrol	= LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/		.mode_pwmdiv		= 0x8000063f,		.mode_pwmhi		= 0x03400000,		.mode_outmask	= 0x00fcfcfc,		.mode_fifoctrl	= 0x2f2f2f2f,		.mode_toyclksrc	= 0x00000004, /* AUXPLL directly */		.mode_backlight	= 0x00000000,		.mode_auxpll		= 8, /* 96MHz AUXPLL */		.device_init		= board_au1200fb_panel_init,		.device_shutdown	= board_au1200fb_panel_shutdown,		320, 320,		240, 240,	},	[8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */		.name = "Toppoly_TD070WGCB2",		.monspecs = {			.modedb = NULL,			.modedb_len = 0,			.hfmin = 30000,			.hfmax = 70000,			.vfmin = 60,			.vfmax = 60,			.dclkmin = 6000000,			.dclkmax = 28000000,			.input = FB_DISP_RGB,		},		.mode_screen		= LCD_SCREEN_SX_N(856) |			LCD_SCREEN_SY_N(480),		.mode_horztiming	= LCD_HORZTIMING_HND2_N(43) |			LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),		.mode_verttiming	= LCD_VERTTIMING_VND2_N(20) |			LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),		.mode_clkcontrol	= 0x00020001, /* /4=24Mhz */		.mode_pwmdiv		= 0x8000063f,		.mode_pwmhi		= 0x03400000,		.mode_outmask	= 0x00fcfcfc,		.mode_fifoctrl	= 0x2f2f2f2f,		.mode_toyclksrc	= 0x00000004, /* AUXPLL directly */		.mode_backlight	= 0x00000000,		.mode_auxpll		= 8, /* 96MHz AUXPLL */		.device_init		= board_au1200fb_panel_init,		.device_shutdown	= board_au1200fb_panel_shutdown,		856, 856,		480, 480,	},};#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))/********************************************************************/#ifdef CONFIG_PMstatic int set_brightness(unsigned int brightness){	unsigned int hi1, divider;	/* limit brightness pwm duty to >= 30/1600 */	if (brightness < 30) {		brightness = 30;	}	divider = (lcd->pwmdiv & 0x3FFFF) + 1;	hi1 = (lcd->pwmhi >> 16) + 1;	hi1 = (((brightness & 0xFF) + 1) * divider >> 8);	lcd->pwmhi &= 0xFFFF;	lcd->pwmhi |= (hi1 << 16);	return brightness;}#endif /* CONFIG_PM */static int winbpp (unsigned int winctrl1){	int bits = 0;	/* how many bits are needed for each pixel format */	switch (winctrl1 & LCD_WINCTRL1_FRM) {	case LCD_WINCTRL1_FRM_1BPP:		bits = 1;		break;	case LCD_WINCTRL1_FRM_2BPP:		bits = 2;		break;	case LCD_WINCTRL1_FRM_4BPP:		bits = 4;		break;	case LCD_WINCTRL1_FRM_8BPP:		bits = 8;		break;	case LCD_WINCTRL1_FRM_12BPP:	case LCD_WINCTRL1_FRM_16BPP655:	case LCD_WINCTRL1_FRM_16BPP565:	case LCD_WINCTRL1_FRM_16BPP556:	case LCD_WINCTRL1_FRM_16BPPI1555:	case LCD_WINCTRL1_FRM_16BPPI5551:	case LCD_WINCTRL1_FRM_16BPPA1555:	case LCD_WINCTRL1_FRM_16BPPA5551:		bits = 16;		break;	case LCD_WINCTRL1_FRM_24BPP:	case LCD_WINCTRL1_FRM_32BPP:		bits = 32;		break;	}	return bits;}static int fbinfo2index (struct fb_info *fb_info){	int i;	for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {		if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))			return i;	}	printk("au1200fb: ERROR: fbinfo2index failed!\n");	return -1;}static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,	int xpos, int ypos){	uint32 winctrl0, winctrl1, winenable, fb_offset = 0;	int xsz, ysz;	/* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */	winctrl0 = lcd->window[plane].winctrl0;	winctrl1 = lcd->window[plane].winctrl1;	winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);	winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);	/* Check for off-screen adjustments */	xsz = win->w[plane].xres;	ysz = win->w[plane].yres;	if ((xpos + win->w[plane].xres) > panel->Xres) {		/* Off-screen to the right */		xsz = panel->Xres - xpos; /* off by 1 ??? */		/*printk("off screen right\n");*/	}	if ((ypos + win->w[plane].yres) > panel->Yres) {		/* Off-screen to the bottom */		ysz = panel->Yres - ypos; /* off by 1 ??? */		/*printk("off screen bottom\n");*/	}	if (xpos < 0) {		/* Off-screen to the left */		xsz = win->w[plane].xres + xpos;		fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);		xpos = 0;		/*printk("off screen left\n");*/	}	if (ypos < 0) {		/* Off-screen to the top */		ysz = win->w[plane].yres + ypos;		/* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */		ypos = 0;		/*printk("off screen top\n");*/	}	/* record settings */	win->w[plane].xpos = xpos;	win->w[plane].ypos = ypos;	xsz -= 1;	ysz -= 1;	winctrl0 |= (xpos << 21);	winctrl0 |= (ypos << 10);	winctrl1 |= (xsz << 11);	winctrl1 |= (ysz << 0);	/* Disable the window while making changes, then restore WINEN */	winenable = lcd->winenable & (1 << plane);	au_sync();	lcd->winenable &= ~(1 << plane);	lcd->window[plane].winctrl0 = winctrl0;	lcd->window[plane].winctrl1 = winctrl1;	lcd->window[plane].winbuf0 =	lcd->window[plane].winbuf1 = fbdev->fb_phys;	lcd->window[plane].winbufctrl = 0; /* select winbuf0 */	lcd->winenable |= winenable;	au_sync();	return 0;}static void au1200_setpanel (struct panel_settings *newpanel){	/*	 * Perform global setup/init of LCD controller	 */	uint32 winenable;	/* Make sure all windows disabled */	winenable = lcd->winenable;	lcd->winenable = 0;	au_sync();	/*	 * Ensure everything is disabled before reconfiguring	 */	if (lcd->screen & LCD_SCREEN_SEN) {		/* Wait for vertical sync period */		lcd->intstatus = LCD_INT_SS;		while ((lcd->intstatus & LCD_INT_SS) == 0) {			au_sync();		}		lcd->screen &= ~LCD_SCREEN_SEN;	/*disable the controller*/		do {			lcd->intstatus = lcd->intstatus; /*clear interrupts*/			au_sync();		/*wait for controller to shut down*/		} while ((lcd->intstatus & LCD_INT_SD) == 0);		/* Call shutdown of current panel (if up) */		/* this must occur last, because if an external clock is driving		    the controller, the clock cannot be turned off before first			shutting down the controller.		 */		if (panel->device_shutdown != NULL)			panel->device_shutdown();	}	/* Newpanel == NULL indicates a shutdown operation only */	if (newpanel == NULL)		return;	panel = newpanel;	printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);	/*	 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)	 */	if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))	{		uint32 sys_clksrc;		au_writel(panel->mode_auxpll, SYS_AUXPLL);		sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f;		sys_clksrc |= panel->mode_toyclksrc;		au_writel(sys_clksrc, SYS_CLKSRC);	}	/*	 * Configure panel timings	 */	lcd->screen = panel->mode_screen;	lcd->horztiming = panel->mode_horztiming;	lcd->verttiming = panel->mode_verttiming;	lcd->clkcontrol = panel->mode_clkcontrol;	lcd->pwmdiv = panel->mode_pwmdiv;	lcd->pwmhi = panel->mode_pwmhi;	lcd->outmask = panel->mode_outmask;	lcd->fifoctrl = panel->mode_fifoctrl;	au_sync();	/* fixme: Check window settings to make sure still valid	 * for new geometry */#if 0	au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);	au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);	au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);	au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);#endif	lcd->winenable = winenable;	/*	 * Re-enable screen now that it is configured	 */	lcd->screen |= LCD_SCREEN_SEN;	au_sync();	/* Call init of panel */	if (panel->device_init != NULL) panel->device_init();	/* FIX!!!! not appropriate on panel change!!! Global setup/init */	lcd->intenable = 0;	lcd->intstatus = ~0;	lcd->backcolor = win->mode_backcolor;	/* Setup Color Key - FIX!!! */	lcd->colorkey = win->mode_colorkey;	lcd->colorkeymsk = win->mode_colorkeymsk;	/* Setup HWCursor - FIX!!! Need to support this eventually */	lcd->hwc.cursorctrl = 0;	lcd->hwc.cursorpos = 0;	lcd->hwc.cursorcolor0 = 0;	lcd->hwc.cursorcolor1 = 0;	lcd->hwc.cursorcolor2 = 0;	lcd->hwc.cursorcolor3 = 0;#if 0#define D(X) printk("%25s: %08X\n", #X, X)	D(lcd->screen);	D(lcd->horztiming);	D(lcd->verttiming);	D(lcd->clkcontrol);	D(lcd->pwmdiv);	D(lcd->pwmhi);	D(lcd->outmask);	D(lcd->fifoctrl);	D(lcd->window[0].winctrl0);	D(lcd->window[0].winctrl1);	D(lcd->window[0].winctrl2);	D(lcd->window[0].winbuf0);	D(lcd->window[0].winbuf1);	D(lcd->window[0].winbufctrl);	D(lcd->window[1].winctrl0);	D(lcd->window[1].winctrl1);	D(lcd->window[1].winctrl2);	D(lcd->window[1].winbuf0);	D(lcd->window[1].winbuf1);	D(lcd->window[1].winbufctrl);	D(lcd->window[2].winctrl0);	D(lcd->window[2].winctrl1);	D(lcd->window[2].winctrl2);	D(lcd->window[2].winbuf0);	D(lcd->window[2].winbuf1);	D(lcd->window[2].winbufctrl);	D(lcd->window[3].winctrl0);	D(lcd->window[3].winctrl1);	D(lcd->window[3].winctrl2);	D(lcd->window[3].winbuf0);	D(lcd->window[3].winbuf1);	D(lcd->window[3].winbufctrl);	D(lcd->winenable);	D(lcd->intenable);	D(lcd->intstatus);	D(lcd->backcolor);	D(lcd->winenable);	D(lcd->colorkey);    D(lcd->colorkeymsk);	D(lcd->hwc.cursorctrl);	D(lcd->hwc.cursorpos);	D(lcd->hwc.cursorcolor0);	D(lcd->hwc.cursorcolor1);	D(lcd->hwc.cursorcolor2);	D(lcd->hwc.cursorcolor3);#endif}static void au1200_setmode(struct au1200fb_device *fbdev){	int plane = fbdev->plane;	/* Window/plane setup */	lcd->window[plane].winctrl1 = ( 0		| LCD_WINCTRL1_PRI_N(plane)		| win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */		) ;	au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);	lcd->window[plane].winctrl2 = ( 0		| LCD_WINCTRL2_CKMODE_00

⌨️ 快捷键说明

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