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

📄 pm3fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * Oxygen VX1 - it appears that setting PM3VideoControl and	 * then PM3RD_SyncControl to the same SYNC settings undoes	 * any net change - they seem to xor together.  Only set the	 * sync options in PM3RD_SyncControl.  --rmk	 */	{		unsigned int video = l_fb_info->current_par->video;		video &= ~(PM3VideoControl_HSYNC_MASK |			   PM3VideoControl_VSYNC_MASK);		video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |			 PM3VideoControl_VSYNC_ACTIVE_HIGH;		PM3_SLOW_WRITE_REG(PM3VideoControl, video);	}	PM3_SLOW_WRITE_REG(PM3VClkCtl,			   (PM3_READ_REG(PM3VClkCtl) & 0xFFFFFFFC));	PM3_SLOW_WRITE_REG(PM3ScreenBase, l_fb_info->current_par->base);	PM3_SLOW_WRITE_REG(PM3ChipConfig,			   (PM3_READ_REG(PM3ChipConfig) & 0xFFFFFFFD));	{		unsigned char m;	/* ClkPreScale */		unsigned char n;	/* ClkFeedBackScale */		unsigned char p;	/* ClkPostScale */		(void)pm3fb_CalculateClock(l_fb_info, l_fb_info->current_par->pixclock, PM3_REF_CLOCK, &m, &n, &p);		DPRINTK(2,			"Pixclock: %d, Pre: %d, Feedback: %d, Post: %d\n",			l_fb_info->current_par->pixclock, (int) m, (int) n,			(int) p);		PM3_WRITE_DAC_REG(PM3RD_DClk0PreScale, m);		PM3_WRITE_DAC_REG(PM3RD_DClk0FeedbackScale, n);		PM3_WRITE_DAC_REG(PM3RD_DClk0PostScale, p);	}	/*	   PM3_WRITE_DAC_REG(PM3RD_IndexControl, 0x00);	 */	/*	   PM3_SLOW_WRITE_REG(PM3RD_IndexControl, 0x00);	 */	if ((l_fb_info->current_par->video & PM3VideoControl_HSYNC_MASK) ==	    PM3VideoControl_HSYNC_ACTIVE_HIGH)		tempsync |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH;	if ((l_fb_info->current_par->video & PM3VideoControl_VSYNC_MASK) ==	    PM3VideoControl_VSYNC_ACTIVE_HIGH)		tempsync |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH;		PM3_WRITE_DAC_REG(PM3RD_SyncControl, tempsync);	DPRINTK(2, "PM3RD_SyncControl: %d\n", tempsync);		if (flatpanel[l_fb_info->board_num])	{		PM3_WRITE_DAC_REG(PM3RD_DACControl, PM3RD_DACControl_BLANK_PEDESTAL_ENABLE);		PM3_WAIT(2);		PM3_WRITE_REG(PM3VSConfiguration, 0x06);		PM3_WRITE_REG(0x5a00, 1 << 14); /* black magic... */		tempmisc = PM3RD_MiscControl_VSB_OUTPUT_ENABLE;	}	else		PM3_WRITE_DAC_REG(PM3RD_DACControl, 0x00);	switch (l_fb_info->current_par->depth) {	case 8:		PM3_WRITE_DAC_REG(PM3RD_PixelSize,				  PM3RD_PixelSize_8_BIT_PIXELS);		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,				  PM3RD_ColorFormat_CI8_COLOR |				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);		tempmisc |= PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;		break;	case 12:		PM3_WRITE_DAC_REG(PM3RD_PixelSize,				  PM3RD_PixelSize_16_BIT_PIXELS);		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,				  PM3RD_ColorFormat_4444_COLOR |				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |				  PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;		break;			case 15:		PM3_WRITE_DAC_REG(PM3RD_PixelSize,				  PM3RD_PixelSize_16_BIT_PIXELS);		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,				  PM3RD_ColorFormat_5551_FRONT_COLOR |				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |				  PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;		break;			case 16:		PM3_WRITE_DAC_REG(PM3RD_PixelSize,				  PM3RD_PixelSize_16_BIT_PIXELS);		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,				  PM3RD_ColorFormat_565_FRONT_COLOR |				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |				  PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;		break;	case 32:		PM3_WRITE_DAC_REG(PM3RD_PixelSize,				  PM3RD_PixelSize_32_BIT_PIXELS);		PM3_WRITE_DAC_REG(PM3RD_ColorFormat,				  PM3RD_ColorFormat_8888_COLOR |				  PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);		tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |			PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;		break;	}	PM3_WRITE_DAC_REG(PM3RD_MiscControl, tempmisc);		PM3_SHOW_CUR_MODE;}static void pm3fb_read_mode(struct pm3fb_info *l_fb_info,			    struct pm3fb_par *curpar){	unsigned long pixsize1, pixsize2, clockused;	unsigned long pre, feedback, post;	DTRACE;	clockused = PM3_READ_REG(PM3VClkCtl);	switch (clockused) {	case 3:		pre = PM3_READ_DAC_REG(PM3RD_DClk3PreScale);		feedback = PM3_READ_DAC_REG(PM3RD_DClk3FeedbackScale);		post = PM3_READ_DAC_REG(PM3RD_DClk3PostScale);		DPRINTK(2,			"DClk3 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,								feedback,								post));		break;	case 2:		pre = PM3_READ_DAC_REG(PM3RD_DClk2PreScale);		feedback = PM3_READ_DAC_REG(PM3RD_DClk2FeedbackScale);		post = PM3_READ_DAC_REG(PM3RD_DClk2PostScale);		DPRINTK(2,			"DClk2 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,								feedback,								post));		break;	case 1:		pre = PM3_READ_DAC_REG(PM3RD_DClk1PreScale);		feedback = PM3_READ_DAC_REG(PM3RD_DClk1FeedbackScale);		post = PM3_READ_DAC_REG(PM3RD_DClk1PostScale);		DPRINTK(2,			"DClk1 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,								feedback,								post));		break;	case 0:		pre = PM3_READ_DAC_REG(PM3RD_DClk0PreScale);		feedback = PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale);		post = PM3_READ_DAC_REG(PM3RD_DClk0PostScale);		DPRINTK(2,			"DClk0 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",			pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,								feedback,								post));		break;	default:		pre = feedback = post = 0;		DPRINTK(1, "Unknowk D clock used : %ld\n", clockused);		break;	}	curpar->pixclock = PM3_SCALE_TO_CLOCK(pre, feedback, post);	pixsize1 =	    PM3ByApertureMode_PIXELSIZE_MASK &	    (PM3_READ_REG(PM3ByAperture1Mode));	pixsize2 =	    PM3ByApertureMode_PIXELSIZE_MASK &	    (PM3_READ_REG(PM3ByAperture2Mode));	DASSERT((pixsize1 == pixsize2),		"pixsize the same in both aperture\n");	if (pixsize1 & PM3ByApertureMode_PIXELSIZE_32BIT)		curpar->depth = 32;	else if (pixsize1 & PM3ByApertureMode_PIXELSIZE_16BIT)	{		curpar->depth = 16;	}	else		curpar->depth = 8;	/* not sure if I need to add one on the next ; it give better result with */	curpar->htotal =	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,			     1 + PM3_READ_REG(PM3HTotal));	curpar->hsend =	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,			     PM3_READ_REG(PM3HsEnd));	curpar->hsstart =	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,			     PM3_READ_REG(PM3HsStart));	curpar->hbend =	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,			     PM3_READ_REG(PM3HbEnd));	curpar->stride =	    pm3fb_Unshiftbpp(l_fb_info, curpar->depth,			     PM3_READ_REG(PM3ScreenStride));	curpar->vtotal = 1 + PM3_READ_REG(PM3VTotal);	curpar->vsend = 1 + PM3_READ_REG(PM3VsEnd);	curpar->vsstart = 1 + PM3_READ_REG(PM3VsStart);	curpar->vbend = PM3_READ_REG(PM3VbEnd);	curpar->video = PM3_READ_REG(PM3VideoControl);	curpar->base = PM3_READ_REG(PM3ScreenBase);	curpar->width = curpar->htotal - curpar->hbend; /* make virtual == displayed resolution */	curpar->height = curpar->vtotal - curpar->vbend;	DPRINTK(2, "Found : %d * %d, %d Khz, stride is %08x\n",		curpar->width, curpar->height, curpar->pixclock,		curpar->stride);}static unsigned long pm3fb_size_memory(struct pm3fb_info *l_fb_info){	unsigned long memsize = 0, tempBypass, i, temp1, temp2;	u16 subvendor, subdevice;	pm3fb_timing_result ptr;	DTRACE;	l_fb_info->fb_size = 64 * 1024 * 1024;	/* pm3 aperture always 64 MB */	pm3fb_mapIO(l_fb_info);	/* temporary map IO */	DASSERT((l_fb_info->vIOBase != NULL),		"IO successfully mapped before mem detect\n");	DASSERT((l_fb_info->v_fb != NULL),		"FB successfully mapped before mem detect\n");	/* card-specific stuff, *before* accessing *any* FB memory */	if ((!pci_read_config_word	     (l_fb_info->dev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor))	    &&	    (!pci_read_config_word	     (l_fb_info->dev, PCI_SUBSYSTEM_ID, &subdevice))) {		i = 0; l_fb_info->board_type = 0;		while ((cardbase[i].cardname[0]) && !(l_fb_info->board_type)) {			if ((cardbase[i].subvendor == subvendor) &&			    (cardbase[i].subdevice == subdevice) &&			    (cardbase[i].func == PCI_FUNC(l_fb_info->dev->devfn))) {				DPRINTK(2, "Card #%ld is an %s\n",					l_fb_info->board_num,					cardbase[i].cardname);				if (cardbase[i].specific_setup)					cardbase[i].specific_setup(l_fb_info);				l_fb_info->board_type = i;			}			i++;		}		if (!l_fb_info->board_type) {			DPRINTK(1, "Card #%ld is an unknown 0x%04x / 0x%04x\n",				l_fb_info->board_num, subvendor, subdevice);		}	} else {		printk(KERN_ERR "pm3fb: Error: pci_read_config_word failed, board #%ld\n",		       l_fb_info->board_num);	}	if (printtimings)		pm3fb_show_cur_timing(l_fb_info);		/* card-specific setup is done, we preserve the final           memory timing for future reference */	if ((ptr = pm3fb_preserve_memory_timings(l_fb_info)) == pm3fb_timing_problem) { /* memory timings were wrong ! oops.... */		return(0);	}		tempBypass = PM3_READ_REG(PM3MemBypassWriteMask);	DPRINTK(2, "PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);	PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xFFFFFFFF);	/* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */	for (i = 0; i < 32; i++) {#ifdef KERNEL_2_2#ifdef MUST_BYTESWAP		writel(__swab32(i * 0x00345678),		       (l_fb_info->v_fb + (i * 1048576)));#else		writel(i * 0x00345678, (l_fb_info->v_fb + (i * 1048576)));#endif		mb();#ifdef MUST_BYTESWAP		temp1 = __swab32(readl((l_fb_info->v_fb + (i * 1048576))));#else		temp1 = readl((l_fb_info->v_fb + (i * 1048576)));#endif#endif	/* KERNEL_2_2 */#if (defined KERNEL_2_4) || (defined KERNEL_2_5)		fb_writel(i * 0x00345678,			  (l_fb_info->v_fb + (i * 1048576)));		mb();		temp1 = fb_readl((l_fb_info->v_fb + (i * 1048576)));#endif /* KERNEL_2_4 or KERNEL_2_5 */		/* Let's check for wrapover, write will fail at 16MB boundary */		if (temp1 == (i * 0x00345678))			memsize = i;		else			break;	}	DPRINTK(2, "First detect pass already got %ld MB\n", memsize + 1);	if (memsize == i) {		for (i = 0; i < 32; i++) {			/* Clear first 32MB ; 0 is 0, no need to byteswap */			writel(0x0000000,			       (l_fb_info->v_fb + (i * 1048576)));			mb();		}		for (i = 32; i < 64; i++) {#ifdef KERNEL_2_2#ifdef MUST_BYTESWAP			writel(__swab32(i * 0x00345678),			       (l_fb_info->v_fb + (i * 1048576)));#else			writel(i * 0x00345678,			       (l_fb_info->v_fb + (i * 1048576)));#endif			mb();#ifdef MUST_BYTESWAP			temp1 =			    __swab32(readl				     ((l_fb_info->v_fb + (i * 1048576))));			temp2 =			    __swab32(readl				     ((l_fb_info->v_fb +				       ((i - 32) * 1048576))));#else			temp1 = readl((l_fb_info->v_fb + (i * 1048576)));			temp2 =			    readl((l_fb_info->v_fb +				   ((i - 32) * 1048576)));#endif#endif /* KERNEL_2_2 */#if (defined KERNEL_2_4) || (defined KERNEL_2_5)			fb_writel(i * 0x00345678,				  (l_fb_info->v_fb + (i * 1048576)));			mb();			temp1 =			    fb_readl((l_fb_info->v_fb + (i * 1048576)));			temp2 =			    fb_readl((l_fb_info->v_fb +				      ((i - 32) * 1048576)));#endif /* KERNEL_2_4 or KERNEL_2_5 */			if ((temp1 == (i * 0x00345678)) && (temp2 == 0))	/* different value, different RAM... */				memsize = i;			else				break;		}	}	DPRINTK(2, "Second detect pass got %ld MB\n", memsize + 1);	PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, tempBypass);	pm3fb_unmapIO(l_fb_info);	memsize = 1048576 * (memsize + 1);	DPRINTK(2, "Returning 0x%08lx bytes\n", memsize);	if (forcesize[l_fb_info->board_num] && ((forcesize[l_fb_info->board_num] * 1048576) != memsize))	{		printk(KERN_WARNING "pm3fb: mismatch between probed (%ld MB) and specified (%hd MB) memory size, using SPECIFIED !\n", memsize, forcesize[l_fb_info->board_num]);		memsize = 1048576 * forcesize[l_fb_info->board_num];

⌨️ 快捷键说明

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