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

📄 pm3fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	  t_3DLabsOxygenVX1	},	{ "3DLabs Oxygen VX1 AGP", PCI_VENDOR_ID_3DLABS, 0x0125, 0, NULL, NULL },	{ "3DLabs Oxygen VX1-16 AGP", PCI_VENDOR_ID_3DLABS, 0x0140, 0, NULL, NULL },	{ "3DLabs Oxygen VX1-1600SW PCI", PCI_VENDOR_ID_3DLABS, 0x0800, 0, NULL, NULL },	{ "\0", 0x0, 0x0, 0, NULL, NULL }};/* ********************************** *//* ***** card-specific function ***** *//* ********************************** */static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info){       /* the appian j2000 require more initialization of the second head */	/* l_fb_info must point to the _second_ head of the J2000 */		DTRACE;	l_fb_info->memt = t_AppianJeronimo2000[0].memt; /* 32 MB, first and only j2000 ? */		pm3fb_write_memory_timings(l_fb_info);}/* *************************************** *//* ***** permedia3-specific function ***** *//* *************************************** */static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info){	l_fb_info->memt.caps = PM3_READ_REG(PM3LocalMemCaps);	l_fb_info->memt.timings = PM3_READ_REG(PM3LocalMemTimings);	l_fb_info->memt.control = PM3_READ_REG(PM3LocalMemControl);	l_fb_info->memt.refresh = PM3_READ_REG(PM3LocalMemRefresh);	l_fb_info->memt.powerdown = PM3_READ_REG(PM3LocalMemPowerDown);	if ((l_fb_info->memt.caps == PM3FB_UNKNOWN_TIMING_VALUE) ||	    (l_fb_info->memt.timings == PM3FB_UNKNOWN_TIMING_VALUE) ||	    (l_fb_info->memt.control == PM3FB_UNKNOWN_TIMING_VALUE) ||	    (l_fb_info->memt.refresh == PM3FB_UNKNOWN_TIMING_VALUE) ||	    (l_fb_info->memt.powerdown == PM3FB_UNKNOWN_TIMING_VALUE))	{		printk(KERN_ERR "pm3fb: invalid memory timings in permedia3 board #%ld\n", l_fb_info->board_num);		return(pm3fb_try_memory_timings(l_fb_info));	}	return(pm3fb_timing_ok);}static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info){	if (cardbase[l_fb_info->board_type].c_memt)	{		int i = 0, done = 0;		while (!done)		{			if ((cardbase[l_fb_info->board_type].c_memt[i].memsize == l_fb_info->fb_size)			    || !(cardbase[l_fb_info->board_type].c_memt[i].memsize))			{ /* will use the 0-sized timings by default */				done = 1;				l_fb_info->memt = cardbase[l_fb_info->board_type].c_memt[i].memt;				printk(KERN_WARNING  "pm3fb: trying to use predefined memory timings for permedia3 board #%ld (%s, %ld MB)\n",				       l_fb_info->board_num,				       cardbase[l_fb_info->board_type].cardname,				       cardbase[l_fb_info->board_type].c_memt[i].memsize);				pm3fb_write_memory_timings(l_fb_info);				return(pm3fb_timing_retry);			}			i++;		}	} else		return(pm3fb_timing_problem);	return(pm3fb_timing_ok);}static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info){	unsigned char m, n, p;	unsigned long clockused;		PM3_SLOW_WRITE_REG(PM3LocalMemCaps, l_fb_info->memt.caps);	PM3_SLOW_WRITE_REG(PM3LocalMemTimings, l_fb_info->memt.timings);	PM3_SLOW_WRITE_REG(PM3LocalMemControl, l_fb_info->memt.control);	PM3_SLOW_WRITE_REG(PM3LocalMemRefresh, l_fb_info->memt.refresh);	PM3_SLOW_WRITE_REG(PM3LocalMemPowerDown, l_fb_info->memt.powerdown);	clockused =	    pm3fb_CalculateClock(l_fb_info, 2 * 105000, PM3_REF_CLOCK, &m,				 &n, &p);	PM3_WRITE_DAC_REG(PM3RD_KClkPreScale, m);	PM3_WRITE_DAC_REG(PM3RD_KClkFeedbackScale, n);	PM3_WRITE_DAC_REG(PM3RD_KClkPostScale, p);	PM3_WRITE_DAC_REG(PM3RD_KClkControl,			  PM3RD_KClkControl_STATE_RUN |			  PM3RD_KClkControl_SOURCE_PLL |			  PM3RD_KClkControl_ENABLE);	PM3_WRITE_DAC_REG(PM3RD_MClkControl,			  PM3RD_MClkControl_STATE_RUN |			  PM3RD_MClkControl_SOURCE_KCLK |			  PM3RD_MClkControl_ENABLE);	PM3_WRITE_DAC_REG(PM3RD_SClkControl,			  PM3RD_SClkControl_STATE_RUN |			  PM3RD_SClkControl_SOURCE_PCLK |			  PM3RD_SClkControl_ENABLE);}static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info,					unsigned long r){	DASSERT((l_fb_info->vIOBase != (unsigned char *) (-1)),		"l_fb_info->vIOBase mapped in read dac reg\n");	PM3_SET_INDEX(r);	mb();	return (PM3_READ_REG(PM3RD_IndexedData));}/* Calculating various clock parameter */static unsigned long pm3fb_CalculateClock(struct pm3fb_info *l_fb_info, unsigned long reqclock,	/* In kHz units */					  unsigned long refclock,	/* In kHz units */					  unsigned char *prescale,	/* ClkPreScale */					  unsigned char *feedback,	/* ClkFeedBackScale */					  unsigned char *postscale					  /* ClkPostScale */ ){	int f, pre, post;	unsigned long freq;	long freqerr = 1000;	unsigned long actualclock = 0;	DTRACE;	for (f = 1; f < 256; f++) {		for (pre = 1; pre < 256; pre++) {			for (post = 0; post < 5; post++) {				freq =				    ((2 * refclock * f) /				     (pre * (1 << post)));				if ((reqclock > freq - freqerr)				    && (reqclock < freq + freqerr)) {					freqerr =					    (reqclock >					     freq) ? reqclock -					    freq : freq - reqclock;					*feedback = f;					*prescale = pre;					*postscale = post;					actualclock = freq;				}			}		}	}	return (actualclock);}static int pm3fb_Shiftbpp(struct pm3fb_info *l_fb_info,			  unsigned long depth, int v){	DTRACE;		switch (depth) {	case 8:		return (v >> 4);	case 12:	case 15:	case 16:		return (v >> 3);	case 32:		return (v >> 2);	}	DPRINTK(1, "Unsupported depth %ld\n", depth);	return (0);}static int pm3fb_Unshiftbpp(struct pm3fb_info *l_fb_info,			    unsigned long depth, int v){	DTRACE;	switch (depth) {	case 8:		return (v << 4);	case 12:		case 15:	case 16:		return (v << 3);	case 32:		return (v << 2);	}	DPRINTK(1, "Unsupported depth %ld\n", depth);	return (0);}static void pm3fb_mapIO(struct pm3fb_info *l_fb_info){	DTRACE;	l_fb_info->vIOBase =	    ioremap((unsigned long) l_fb_info->pIOBase, PM3_REGS_SIZE);	l_fb_info->v_fb =	    ioremap((unsigned long) l_fb_info->p_fb, l_fb_info->fb_size);	DPRINTK(2, "IO mapping : IOBase %lx / %lx, fb %lx / %lx\n",		(unsigned long) l_fb_info->pIOBase,		(unsigned long) l_fb_info->vIOBase,		(unsigned long) l_fb_info->p_fb,		(unsigned long) l_fb_info->v_fb);}static void pm3fb_unmapIO(struct pm3fb_info *l_fb_info){	DTRACE;	iounmap(l_fb_info->vIOBase);	iounmap(l_fb_info->v_fb);	l_fb_info->vIOBase = (unsigned char *) -1;	l_fb_info->v_fb = (unsigned char *) -1;}#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)static void pm3fb_show_cur_mode(struct pm3fb_info *l_fb_info){	DPRINTK(2, "PM3Aperture0: 0x%08x\n", PM3_READ_REG(PM3Aperture0));	DPRINTK(2, "PM3Aperture1: 0x%08x\n", PM3_READ_REG(PM3Aperture1));	DPRINTK(2, "PM3ByAperture1Mode: 0x%08x\n",		PM3_READ_REG(PM3ByAperture1Mode));	DPRINTK(2, "PM3ByAperture2Mode: 0x%08x\n",		PM3_READ_REG(PM3ByAperture2Mode));	DPRINTK(2, "PM3ChipConfig: 0x%08x\n", PM3_READ_REG(PM3ChipConfig));	DPRINTK(2, "PM3FIFODis: 0x%08x\n", PM3_READ_REG(PM3FIFODis));	DPRINTK(2, "PM3HTotal: 0x%08x\n", PM3_READ_REG(PM3HTotal));	DPRINTK(2, "PM3HbEnd: 0x%08x\n", PM3_READ_REG(PM3HbEnd));	DPRINTK(2, "PM3HgEnd: 0x%08x\n", PM3_READ_REG(PM3HgEnd));	DPRINTK(2, "PM3HsEnd: 0x%08x\n", PM3_READ_REG(PM3HsEnd));	DPRINTK(2, "PM3HsStart: 0x%08x\n", PM3_READ_REG(PM3HsStart));	DPRINTK(2, "PM3MemBypassWriteMask: 0x%08x\n",		PM3_READ_REG(PM3MemBypassWriteMask));	DPRINTK(2, "PM3RD_IndexControl: 0x%08x\n",		PM3_READ_REG(PM3RD_IndexControl));	DPRINTK(2, "PM3ScreenBase: 0x%08x\n", PM3_READ_REG(PM3ScreenBase));	DPRINTK(2, "PM3ScreenStride: 0x%08x\n",		PM3_READ_REG(PM3ScreenStride));	DPRINTK(2, "PM3VClkCtl: 0x%08x\n", PM3_READ_REG(PM3VClkCtl));	DPRINTK(2, "PM3VTotal: 0x%08x\n", PM3_READ_REG(PM3VTotal));	DPRINTK(2, "PM3VbEnd: 0x%08x\n", PM3_READ_REG(PM3VbEnd));	DPRINTK(2, "PM3VideoControl: 0x%08x\n",		PM3_READ_REG(PM3VideoControl));	DPRINTK(2, "PM3VsEnd: 0x%08x\n", PM3_READ_REG(PM3VsEnd));	DPRINTK(2, "PM3VsStart: 0x%08x\n", PM3_READ_REG(PM3VsStart));	DPRINTK(2, "PM3RD_ColorFormat: %ld\n",		PM3_READ_DAC_REG(PM3RD_ColorFormat));	DPRINTK(2, "PM3RD_DACControl: %ld\n",		PM3_READ_DAC_REG(PM3RD_DACControl));	DPRINTK(2, "PM3RD_DClk0FeedbackScale: %ld\n",		PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale));	DPRINTK(2, "PM3RD_DClk0PostScale: %ld\n",		PM3_READ_DAC_REG(PM3RD_DClk0PostScale));	DPRINTK(2, "PM3RD_DClk0PreScale: %ld\n",		PM3_READ_DAC_REG(PM3RD_DClk0PreScale));	DPRINTK(2, "[not set] PM3RD_IndexControl: %ld\n",		PM3_READ_DAC_REG(PM3RD_IndexControl));	DPRINTK(2, "PM3RD_MiscControl: %ld\n",		PM3_READ_DAC_REG(PM3RD_MiscControl));	DPRINTK(2, "PM3RD_PixelSize: %ld\n",		PM3_READ_DAC_REG(PM3RD_PixelSize));	DPRINTK(2, "PM3RD_SyncControl: %ld\n",		PM3_READ_DAC_REG(PM3RD_SyncControl));}#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2) */static void pm3fb_show_cur_timing(struct pm3fb_info *l_fb_info){	u16 subvendor, subdevice;	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))) {		/* well, nothing... */	} else {		subvendor = subdevice = (u16)-1;	}	printk(KERN_INFO "pm3fb: memory timings for board #%ld (subvendor: 0x%hx, subdevice: 0x%hx)\n", l_fb_info->board_num, subvendor, subdevice);	printk(KERN_INFO " PM3LocalMemCaps: 0x%08x\n",	       PM3_READ_REG(PM3LocalMemCaps));	printk(KERN_INFO " PM3LocalMemTimings: 0x%08x\n",	       PM3_READ_REG(PM3LocalMemTimings));	printk(KERN_INFO " PM3LocalMemControl: 0x%08x\n",	       PM3_READ_REG(PM3LocalMemControl));	printk(KERN_INFO " PM3LocalMemRefresh: 0x%08x\n",	       PM3_READ_REG(PM3LocalMemRefresh));	printk(KERN_INFO " PM3LocalMemPowerDown: 0x%08x\n",	       PM3_READ_REG(PM3LocalMemPowerDown));}/* write the mode to registers */static void pm3fb_write_mode(struct pm3fb_info *l_fb_info){	char tempsync = 0x00, tempmisc = 0x00;	DTRACE;	PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xffffffff);	PM3_SLOW_WRITE_REG(PM3Aperture0, 0x00000000);	PM3_SLOW_WRITE_REG(PM3Aperture1, 0x00000000);	PM3_SLOW_WRITE_REG(PM3FIFODis, 0x00000007);	PM3_SLOW_WRITE_REG(PM3HTotal,			   pm3fb_Shiftbpp(l_fb_info,					  l_fb_info->current_par->depth,					  l_fb_info->current_par->htotal -					  1));	PM3_SLOW_WRITE_REG(PM3HsEnd,			   pm3fb_Shiftbpp(l_fb_info,					  l_fb_info->current_par->depth,					  l_fb_info->current_par->hsend));	PM3_SLOW_WRITE_REG(PM3HsStart,			   pm3fb_Shiftbpp(l_fb_info,					  l_fb_info->current_par->depth,					  l_fb_info->current_par->					  hsstart));	PM3_SLOW_WRITE_REG(PM3HbEnd,			   pm3fb_Shiftbpp(l_fb_info,					  l_fb_info->current_par->depth,					  l_fb_info->current_par->hbend));	PM3_SLOW_WRITE_REG(PM3HgEnd,			   pm3fb_Shiftbpp(l_fb_info,					  l_fb_info->current_par->depth,					  l_fb_info->current_par->hbend));	PM3_SLOW_WRITE_REG(PM3ScreenStride,			   pm3fb_Shiftbpp(l_fb_info,					  l_fb_info->current_par->depth,					  l_fb_info->current_par->stride));	PM3_SLOW_WRITE_REG(PM3VTotal, l_fb_info->current_par->vtotal - 1);	PM3_SLOW_WRITE_REG(PM3VsEnd, l_fb_info->current_par->vsend - 1);	PM3_SLOW_WRITE_REG(PM3VsStart,			   l_fb_info->current_par->vsstart - 1);	PM3_SLOW_WRITE_REG(PM3VbEnd, l_fb_info->current_par->vbend);	switch (l_fb_info->current_par->depth) {	case 8:		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,				   PM3ByApertureMode_PIXELSIZE_8BIT);		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,				   PM3ByApertureMode_PIXELSIZE_8BIT);		break;	case 12:	case 15:	case 16:#ifndef __BIG_ENDIAN		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,				   PM3ByApertureMode_PIXELSIZE_16BIT);		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,				   PM3ByApertureMode_PIXELSIZE_16BIT);#else		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,				   PM3ByApertureMode_PIXELSIZE_16BIT |				   PM3ByApertureMode_BYTESWAP_BADC);		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,				   PM3ByApertureMode_PIXELSIZE_16BIT |				   PM3ByApertureMode_BYTESWAP_BADC);#endif /* ! __BIG_ENDIAN */		break;	case 32:#ifndef __BIG_ENDIAN		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,				   PM3ByApertureMode_PIXELSIZE_32BIT);		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,				   PM3ByApertureMode_PIXELSIZE_32BIT);#else		PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,				   PM3ByApertureMode_PIXELSIZE_32BIT |				   PM3ByApertureMode_BYTESWAP_DCBA);		PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,				   PM3ByApertureMode_PIXELSIZE_32BIT |				   PM3ByApertureMode_BYTESWAP_DCBA);#endif /* ! __BIG_ENDIAN */		break;	default:		DPRINTK(1, "Unsupported depth %d\n",			l_fb_info->current_par->depth);		break;	}	/*

⌨️ 快捷键说明

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