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

📄 atafb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		hdb_off = (base_off + 16 * plen) + prescale;	}	else {		hde_off = ((128 / var->bits_per_pixel + 2) * plen);		if (hw->ste_mode)			hdb_off = (64 + base_off + (128 / var->bits_per_pixel + 2) * plen)					 + prescale;		else			hdb_off = (base_off + (128 / var->bits_per_pixel + 18) * plen)					 + prescale;	}	/* Right margin includes hsync */	var->left_margin = hdb_off + prescale * ((hw->hdb & 0x1ff) -					   (hw->hdb & 0x200 ? 2+hw->hht : 0));	if (hw->ste_mode || mon_type!=F_MON_VGA)		var->right_margin = prescale * (hw->hht + 2 - hw->hde) - hde_off;	else		/* can't use this in ste_mode, because hbb is +1 off */		var->right_margin = prescale * (hw->hht + 2 - hw->hbb);	var->hsync_len = prescale * (hw->hht + 2 - hw->hss);	/* Lower margin includes vsync */	var->upper_margin = hw->vdb / 2 ;  /* round down to full lines */	var->lower_margin = (hw->vft+1 - hw->vde + 1) / 2; /* round up */	var->vsync_len    = (hw->vft+1 - hw->vss + 1) / 2; /* round up */	if (var->vmode & FB_VMODE_INTERLACED) {		var->upper_margin *= 2;		var->lower_margin *= 2;		var->vsync_len *= 2;	}	else if (var->vmode & FB_VMODE_DOUBLE) {		var->upper_margin = (var->upper_margin + 1) / 2;		var->lower_margin = (var->lower_margin + 1) / 2;		var->vsync_len = (var->vsync_len + 1) / 2;	}	var->pixclock *= plen;	var->left_margin /= plen;	var->right_margin /= plen;	var->hsync_len /= plen;	var->right_margin -= var->hsync_len;	var->lower_margin -= var->vsync_len;	if (screen_base)		var->yoffset=(par->screen_base - screen_base)/linelen;	else		var->yoffset=0;	var->nonstd=0;	/* what is this for? */	var->activate=0;	return 0;}static int f_change_mode = 0;static struct falcon_hw f_new_mode;static int f_pan_display = 0;static void falcon_get_par( struct atafb_par *par ){	unsigned long addr;	struct falcon_hw *hw = &par->hw.falcon;	hw->line_width = shifter_f030.scn_width;	hw->line_offset = shifter_f030.off_next;	hw->st_shift = videl.st_shift & 0x300;	hw->f_shift = videl.f_shift;	hw->vid_control = videl.control;	hw->vid_mode = videl.mode;	hw->sync = shifter.syncmode & 0x1;	hw->xoffset = videl.xoffset & 0xf;	hw->hht = videl.hht;	hw->hbb = videl.hbb;	hw->hbe = videl.hbe;	hw->hdb = videl.hdb;	hw->hde = videl.hde;	hw->hss = videl.hss;	hw->vft = videl.vft;	hw->vbb = videl.vbb;	hw->vbe = videl.vbe;	hw->vdb = videl.vdb;	hw->vde = videl.vde;	hw->vss = videl.vss;	addr = (shifter.bas_hi & 0xff) << 16 |	       (shifter.bas_md & 0xff) << 8  |	       (shifter.bas_lo & 0xff);	par->screen_base = phys_to_virt(addr);	/* derived parameters */	hw->ste_mode = (hw->f_shift & 0x510)==0 && hw->st_shift==0x100;	hw->mono = (hw->f_shift & 0x400) ||	           ((hw->f_shift & 0x510)==0 && hw->st_shift==0x200);}static void falcon_set_par( struct atafb_par *par ){	f_change_mode = 0;	/* only set screen_base if really necessary */	if (current_par.screen_base != par->screen_base)		fbhw->set_screen_base(par->screen_base);	/* Don't touch any other registers if we keep the default resolution */	if (DontCalcRes)		return;	/* Tell vbl-handler to change video mode.	 * We change modes only on next VBL, to avoid desynchronisation	 * (a shift to the right and wrap around by a random number of pixels	 * in all monochrome modes).	 * This seems to work on my Falcon.	 */	f_new_mode = par->hw.falcon;	f_change_mode = 1;}static void falcon_vbl_switcher( int irq, void *dummy, struct pt_regs *fp ){	struct falcon_hw *hw = &f_new_mode;	if (f_change_mode) {		f_change_mode = 0;		if (hw->sync & 0x1) {			/* Enable external pixelclock. This code only for ScreenWonder */			*(volatile unsigned short*)0xffff9202 = 0xffbf;		}		else {			/* Turn off external clocks. Read sets all output bits to 1. */			*(volatile unsigned short*)0xffff9202;		}		shifter.syncmode = hw->sync;		videl.hht = hw->hht;		videl.hbb = hw->hbb;		videl.hbe = hw->hbe;		videl.hdb = hw->hdb;		videl.hde = hw->hde;		videl.hss = hw->hss;		videl.vft = hw->vft;		videl.vbb = hw->vbb;		videl.vbe = hw->vbe;		videl.vdb = hw->vdb;		videl.vde = hw->vde;		videl.vss = hw->vss;		videl.f_shift = 0; /* write enables Falcon palette, 0: 4 planes */		if (hw->ste_mode) {			videl.st_shift = hw->st_shift; /* write enables STE palette */		}		else {			/* IMPORTANT:			 * set st_shift 0, so we can tell the screen-depth if f_shift==0.			 * Writing 0 to f_shift enables 4 plane Falcon mode but			 * doesn't set st_shift. st_shift!=0 (!=4planes) is impossible			 * with Falcon palette.			 */			videl.st_shift = 0;			/* now back to Falcon palette mode */			videl.f_shift = hw->f_shift;		}		/* writing to st_shift changed scn_width and vid_mode */		videl.xoffset = hw->xoffset;		shifter_f030.scn_width = hw->line_width;		shifter_f030.off_next = hw->line_offset;		videl.control = hw->vid_control;		videl.mode = hw->vid_mode;	}	if (f_pan_display) {		f_pan_display = 0;		videl.xoffset = current_par.hw.falcon.xoffset;		shifter_f030.off_next = current_par.hw.falcon.line_offset;	}}static int falcon_pan_display( struct fb_var_screeninfo *var,							   struct atafb_par *par ){	int xoffset;	int bpp = fb_display[currcon].var.bits_per_pixel;	if (bpp == 1)		var->xoffset = up(var->xoffset, 32);	if (bpp != 16)		par->hw.falcon.xoffset = var->xoffset & 15;	else {		par->hw.falcon.xoffset = 0;		var->xoffset = up(var->xoffset, 2);	}	par->hw.falcon.line_offset = bpp *	       	(fb_display[currcon].var.xres_virtual - fb_display[currcon].var.xres) / 16;	if (par->hw.falcon.xoffset)		par->hw.falcon.line_offset -= bpp;	xoffset = var->xoffset - par->hw.falcon.xoffset;	par->screen_base = screen_base +	        (var->yoffset * fb_display[currcon].var.xres_virtual + xoffset) * bpp / 8;	if (fbhw->set_screen_base)		fbhw->set_screen_base (par->screen_base);	else		return -EINVAL; /* shouldn't happen */	f_pan_display = 1;	return 0;}static int falcon_getcolreg( unsigned regno, unsigned *red,				 unsigned *green, unsigned *blue,				 unsigned *transp, struct fb_info *info ){	unsigned long col;		if (regno > 255)		return 1;	/* This works in STE-mode (with 4bit/color) since f030_col-registers	 * hold up to 6bit/color.	 * Even with hicolor r/g/b=5/6/5 bit!	 */	col = f030_col[regno];	*red = (col >> 16) & 0xff00;	*green = (col >> 8) & 0xff00;	*blue = (col << 8) & 0xff00;	*transp = 0;	return 0;}static int falcon_setcolreg( unsigned regno, unsigned red,							 unsigned green, unsigned blue,							 unsigned transp, struct fb_info *info ){	if (regno > 255)		return 1;	f030_col[regno] = (((red & 0xfc00) << 16) |			   ((green & 0xfc00) << 8) |			   ((blue & 0xfc00) >> 8));	if (regno < 16) {		shifter_tt.color_reg[regno] =			(((red & 0xe000) >> 13) | ((red & 0x1000) >> 12) << 8) |			(((green & 0xe000) >> 13) | ((green & 0x1000) >> 12) << 4) |			((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);#ifdef FBCON_HAS_CFB16		fbcon_cfb16_cmap[regno] = ((red & 0xf800) |					   ((green & 0xfc00) >> 5) |					   ((blue & 0xf800) >> 11));#endif	}	return 0;}static int falcon_blank( int blank_mode ){/* ++guenther: we can switch off graphics by changing VDB and VDE, * so VIDEL doesn't hog the bus while saving. * (this may affect usleep()). */	int vdb, vss, hbe, hss;	if (mon_type == F_MON_SM)	/* this doesn't work on SM124 */		return 1;	vdb = current_par.VDB;	vss = current_par.VSS;	hbe = current_par.HBE;	hss = current_par.HSS;	if (blank_mode >= 1) {		/* disable graphics output (this speeds up the CPU) ... */		vdb = current_par.VFT + 1;		/* ... and blank all lines */		hbe = current_par.HHT + 2;	}	/* use VESA suspend modes on VGA monitors */	if (mon_type == F_MON_VGA) {		if (blank_mode == 2 || blank_mode == 4)			vss = current_par.VFT + 1;		if (blank_mode == 3 || blank_mode == 4)			hss = current_par.HHT + 2;	}	videl.vdb = vdb;	videl.vss = vss;	videl.hbe = hbe;	videl.hss = hss;	return 0;} static int falcon_detect( void ){	struct atafb_par par;	unsigned char fhw;	/* Determine connected monitor and set monitor parameters */	fhw = *(unsigned char*)0xffff8006;	mon_type = fhw >> 6 & 0x3;	/* bit 1 of fhw: 1=32 bit ram bus, 0=16 bit */	f030_bus_width = fhw << 6 & 0x80;	switch (mon_type) {	case F_MON_SM:		fb_info.monspecs.vfmin = 70;		fb_info.monspecs.vfmax = 72;		fb_info.monspecs.hfmin = 35713;		fb_info.monspecs.hfmax = 35715;		break;	case F_MON_SC:	case F_MON_TV:		/* PAL...NTSC */		fb_info.monspecs.vfmin = 49; /* not 50, since TOS defaults to 49.9x Hz */		fb_info.monspecs.vfmax = 60;		fb_info.monspecs.hfmin = 15620;		fb_info.monspecs.hfmax = 15755;		break;	}	/* initialize hsync-len */	f25.hsync = h_syncs[mon_type] / f25.t;	f32.hsync = h_syncs[mon_type] / f32.t;	if (fext.t)		fext.hsync = h_syncs[mon_type] / fext.t;	falcon_get_par(&par);	falcon_encode_var(&atafb_predefined[0], &par);	/* Detected mode is always the "autodetect" slot */	return 1;}#endif /* ATAFB_FALCON *//* ------------------- ST(E) specific functions ---------------------- */#ifdef ATAFB_STEstatic int stste_encode_fix( struct fb_fix_screeninfo *fix,							 struct atafb_par *par ){	int mode;	strcpy(fix->id,"Atari Builtin");	fix->smem_start = (unsigned long)real_screen_base;	fix->smem_len = screen_len;	fix->type = FB_TYPE_INTERLEAVED_PLANES;	fix->type_aux = 2;	fix->visual = FB_VISUAL_PSEUDOCOLOR;	mode = par->hw.st.mode & 3;	if (mode == ST_HIGH) {		fix->type = FB_TYPE_PACKED_PIXELS;		fix->type_aux = 0;		fix->visual = FB_VISUAL_MONO10;	}	if (ATARIHW_PRESENT(EXTD_SHIFTER)) {		fix->xpanstep = 16;		fix->ypanstep = 1;	} else {		fix->xpanstep = 0;		fix->ypanstep = 0;	}	fix->ywrapstep = 0;	fix->line_length = 0;	fix->accel = FB_ACCEL_ATARIBLITT;	return 0;}static int stste_decode_var( struct fb_var_screeninfo *var,						  struct atafb_par *par ){	int xres=var->xres;	int yres=var->yres;	int bpp=var->bits_per_pixel;	int linelen;	int yres_virtual = var->yres_virtual;	if (mono_moni) {		if (bpp > 1 || xres > sttt_xres || yres > st_yres)			return -EINVAL;		par->hw.st.mode=ST_HIGH;		xres=sttt_xres;		yres=st_yres;		bpp=1;	} else {		if (bpp > 4 || xres > sttt_xres || yres > st_yres)			return -EINVAL;		if (bpp > 2) {			if (xres > sttt_xres/2 || yres > st_yres/2)				return -EINVAL;			par->hw.st.mode=ST_LOW;			xres=sttt_xres/2;			yres=st_yres/2;			bpp=4;		}		else if (bpp > 1) {			if (xres > sttt_xres || yres > st_yres/2)				return -EINVAL;			par->hw.st.mode=ST_MID;			xres=sttt_xres;			yres=st_yres/2;			bpp=2;		}		else			return -EINVAL;	}	if (yres_virtual <= 0)		yres_virtual = 0;	else if (yres_virtual < yres)		yres_virtual = yres;	if (var->sync & FB_SYNC_EXT)		par->hw.st.sync=(par->hw.st.sync & ~1) | 1;	else		par->hw.st.sync=(par->hw.st.sync & ~1);	linelen=xres*bpp/8;	if (yres_virtual * linelen > screen_len && screen_len)		return -EINVAL;	if (yres * linelen > screen_len && screen_len)		return -EINVAL;	if (var->yoffset + yres > yres_virtual && yres_virtual)		return -EINVAL;	par->yres_virtual = yres_virtual;	par->screen_base=screen_base+ var->yoffset*linelen;	return 0;}static int stste_encode_var( struct fb_var_screeninfo *var,						  struct atafb_par *par ){	int linelen;	memset(var, 0, sizeof(struct fb_var_screeninfo));	var->red.offset=0;	var->red.length = ATARIHW_PRESENT(EXTD_SHIFTER) ? 4 : 3;	var->red.msb_right=0;	var->grayscale=0;	var->pixclock=31041;	var->left_margin=120;		/* these are incorrect */	var->right_margin=100;	var->upper_margin=8;	var->lower_margin=16;	var->hsync_len=140;	var->vsync_len=30;	var->height=-1;	var->width=-1;	if (!(par->hw.st.sync & 1))		var->sync=0;	else		var->sync=FB_SYNC_EXT;	switch (par->hw.st.mode & 3) {	case ST_LOW:		var->xres=sttt_xres/2;		var->yres=st_yres/2;		var->bits_per_pixel=4;		break;	case ST_MID:		var->xres=sttt_xres;		var->yres=st_yres/2;		var->bits_per_pixel=2;		break;	case ST_HIGH:		var->xres=sttt_xres;		var->yres=st_yres;		var->bits_per_pixel=1;		break;	}			var->blue=var->green=var->red;

⌨️ 快捷键说明

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