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

📄 valkyriefb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static void set_valkyrie_clock(unsigned char *params){	struct adb_request req;	int i;#ifdef CONFIG_ADB_CUDA	for (i = 0; i < 3; ++i) {		cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,			     0x50, i + 1, params[i]);		while (!req.complete)			cuda_poll();	}#endif}static void __init init_valkyrie(struct fb_info_valkyrie *p){	struct fb_par_valkyrie *par = &p->par;	struct fb_var_screeninfo var;	int j, k;	p->sense = read_valkyrie_sense(p);	printk(KERN_INFO "Monitor sense value = 0x%x, ", p->sense);#ifdef CONFIG_NVRAM	/* Try to pick a video mode out of NVRAM if we have one. */	if (default_vmode == VMODE_NVRAM) {		default_vmode = nvram_read_byte(NV_VMODE);		if (default_vmode <= 0		 || default_vmode > VMODE_MAX		 || !valkyrie_reg_init[default_vmode - 1])			default_vmode = VMODE_CHOOSE;	}	if (default_cmode == CMODE_NVRAM)		default_cmode = nvram_read_byte(NV_CMODE);#endif	if (default_vmode == VMODE_CHOOSE)		default_vmode = mac_map_monitor_sense(p->sense);	if (!valkyrie_reg_init[default_vmode - 1])		default_vmode = VMODE_640_480_67;	/*	 * Reduce the pixel size if we don't have enough VRAM or bandwitdh.	 */	if (default_cmode < CMODE_8	 || default_cmode > CMODE_16	 || valkyrie_reg_init[default_vmode-1]->pitch[default_cmode] == 0	 || valkyrie_vram_reqd(default_vmode, default_cmode) > p->total_vram)		default_cmode = CMODE_8;		printk(KERN_INFO "using video mode %d and color mode %d.\n", default_vmode, default_cmode);	mac_vmode_to_var(default_vmode, default_cmode, &var);	if (valkyrie_var_to_par(&var, par, &p->info)) {	    printk(KERN_ERR "valkyriefb: can't set default video mode\n");	    return ;	}		valkyrie_init_fix(&p->fix, p);	valkyrie_par_to_fix(&p->par, &p->fix, p);	valkyrie_par_to_var(&p->par, &p->var);	valkyrie_init_display(&p->disp);	valkyrie_par_to_display(&p->par, &p->disp, &p->fix, p);	valkyrie_init_info(&p->info, p);	/* Initialize colormap */	for (j = 0; j < 16; j++) {		k = color_table[j];		p->palette[j].red = default_red[k];		p->palette[j].green = default_grn[k];		p->palette[j].blue = default_blu[k];	}		valkyrie_set_var (&var, -1, &p->info);	if (register_framebuffer(&p->info) < 0) {		kfree(p);		return;	}		printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", GET_FB_IDX(p->info.node));	}static void valkyrie_set_par(const struct fb_par_valkyrie *par,			     struct fb_info_valkyrie *p){	struct valkyrie_regvals	*init;	volatile struct valkyrie_regs *valkyrie_regs = p->valkyrie_regs;	int vmode, cmode;		vmode = par->vmode;	cmode = par->cmode;		if (vmode <= 0	 || vmode > VMODE_MAX	 || (init = valkyrie_reg_init[vmode - 1]) == NULL)		panic("valkyrie: display mode %d not supported", vmode);	/* Reset the valkyrie */	out_8(&valkyrie_regs->status.r, 0);	udelay(100);	/* Initialize display timing registers */	out_8(&valkyrie_regs->mode.r, init->mode | 0x80);	out_8(&valkyrie_regs->depth.r, cmode + 3);	set_valkyrie_clock(init->clock_params);	udelay(100);	/* Turn on display */	out_8(&valkyrie_regs->mode.r, init->mode);#ifdef CONFIG_FB_COMPAT_XPMAC	/* And let the world know the truth. */	if (!console_fb_info || console_fb_info == &p->info) {		display_info.height = p->var.yres;		display_info.width = p->var.xres;		display_info.depth = (cmode == CMODE_16) ? 16 : 8;		display_info.pitch = p->fix.line_length;		display_info.mode = vmode;		strncpy(display_info.name, "valkyrie",			sizeof(display_info.name));		display_info.fb_address = p->frame_buffer_phys + 0x1000;		display_info.cmap_adr_address = p->cmap_regs_phys;		display_info.cmap_data_address = p->cmap_regs_phys + 8;		display_info.disp_reg_address = p->valkyrie_regs_phys;		console_fb_info = &p->info;	}#endif /* CONFIG_FB_COMPAT_XPMAC */}int __init valkyriefb_init(void){	struct fb_info_valkyrie	*p;	unsigned long frame_buffer_phys, cmap_regs_phys, flags;#ifdef CONFIG_MAC	if (!MACH_IS_MAC)		return 0;	if (!(mac_bi_data.id == MAC_MODEL_Q630	      /* I'm not sure about this one */	    || mac_bi_data.id == MAC_MODEL_P588))		return 0;	/* Hardcoded addresses... welcome to 68k Macintosh country :-) */	frame_buffer_phys = 0xf9000000;	cmap_regs_phys = 0x50f24000;	flags = IOMAP_NOCACHE_SER; /* IOMAP_WRITETHROUGH?? */#else /* ppc (!CONFIG_MAC) */	struct device_node *dp;	dp = find_devices("valkyrie");	if (dp == 0)		return 0;	if(dp->n_addrs != 1) {		printk(KERN_ERR "expecting 1 address for valkyrie (got %d)", dp->n_addrs);		return 0;	}		frame_buffer_phys = dp->addrs[0].address;	cmap_regs_phys = dp->addrs[0].address+0x304000;	flags = _PAGE_WRITETHRU;#endif /* ppc (!CONFIG_MAC) */	p = kmalloc(sizeof(*p), GFP_ATOMIC);	if (p == 0)		return 0;	memset(p, 0, sizeof(*p));	/* Map in frame buffer and registers */	if (!request_mem_region(frame_buffer_phys, 0x100000, "valkyriefb")) {		kfree(p);		return 0;	}	p->total_vram = 0x100000;	p->frame_buffer_phys  = frame_buffer_phys;	p->frame_buffer = __ioremap(frame_buffer_phys, p->total_vram, flags);	p->cmap_regs_phys = cmap_regs_phys;	p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);	p->valkyrie_regs_phys = cmap_regs_phys+0x6000;	p->valkyrie_regs = ioremap(p->valkyrie_regs_phys, 0x1000);	init_valkyrie(p);	return 0;}/* * Get the monitor sense value. */static int read_valkyrie_sense(struct fb_info_valkyrie *p){	int sense, in;    out_8(&p->valkyrie_regs->msense.r, 0);   /* release all lines */    __delay(20000);    sense = ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x70) << 4;    /* drive each sense line low in turn and collect the other 2 */    out_8(&p->valkyrie_regs->msense.r, 4);   /* drive A low */    __delay(20000);    sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x30);    out_8(&p->valkyrie_regs->msense.r, 2);   /* drive B low */    __delay(20000);    sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x40) >> 3;	sense |= (in & 0x10) >> 2;    out_8(&p->valkyrie_regs->msense.r, 1);   /* drive C low */    __delay(20000);    sense |= ((in = in_8(&p->valkyrie_regs->msense.r)) & 0x60) >> 5;    out_8(&p->valkyrie_regs->msense.r, 7);	return sense;}/* * This routine takes a user-supplied var, * and picks the best vmode/cmode from it. */static int valkyrie_var_to_par(struct fb_var_screeninfo *var,	struct fb_par_valkyrie *par, const struct fb_info *fb_info)/* [bkn] I did a major overhaul of this function. * * Much of the old code was "swiped by jonh from atyfb.c". Because * macmodes has mac_var_to_vmode, I felt that it would be better to * rework this function to use that, instead of reinventing the wheel to * add support for vmode 17. This was reinforced by the fact that * the previously swiped atyfb.c code is no longer there. * * So, I swiped and adapted platinum_var_to_par (from platinumfb.c), replacing * most, but not all, of the old code in the process. One side benefit of * swiping the platinumfb code is that we now have more comprehensible error * messages when a vmode/cmode switch fails. (Most of the error messages are * platinumfb.c, but I added two of my own, and I also changed some commas * into colons to make the messages more consistent with other Linux error * messages.) In addition, I think the new code *might* fix some vmode- * switching oddities, but I'm not sure. * * There may be some more opportunities for cleanup in here, but this is a * good start... */{	int bpp = var->bits_per_pixel;	struct valkyrie_regvals *init;	struct fb_info_valkyrie *p = (struct fb_info_valkyrie *) fb_info;	if(mac_var_to_vmode(var, &par->vmode, &par->cmode) != 0) {		printk(KERN_ERR "valkyrie_var_to_par: %dx%dx%d unsuccessful.\n",var->xres,var->yres,var->bits_per_pixel);		return -EINVAL;	}	/* Check if we know about the wanted video mode */	if(!valkyrie_reg_init[par->vmode-1]) {		printk(KERN_ERR "valkyrie_var_to_par: vmode %d not valid.\n", par->vmode);		return -EINVAL;	}	par->xres = var->xres;	par->yres = var->yres;	par->xoffset = 0;	par->yoffset = 0;	par->vxres = par->xres;	par->vyres = par->yres;		if (var->xres_virtual > var->xres || var->yres_virtual > var->yres		|| var->xoffset != 0 || var->yoffset != 0) {		return -EINVAL;	}	if (bpp <= 8)		par->cmode = CMODE_8;	else if (bpp <= 16)		par->cmode = CMODE_16;	else {		printk(KERN_ERR "valkyrie_var_to_par: cmode %d not supported.\n", par->cmode);		return -EINVAL;	}	init = valkyrie_reg_init[par->vmode-1];	if (init->pitch[par->cmode] == 0) {		printk(KERN_ERR "valkyrie_var_to_par: vmode %d does not support cmode %d.\n", par->vmode, par->cmode);		return -EINVAL;	}	if (valkyrie_vram_reqd(par->vmode, par->cmode) > p->total_vram) {		printk(KERN_ERR "valkyrie_var_to_par: not enough ram for vmode %d, cmode %d.\n", par->vmode, par->cmode);		return -EINVAL;	}	return 0;}static int valkyrie_par_to_var(struct fb_par_valkyrie *par, struct fb_var_screeninfo *var){	return mac_vmode_to_var(par->vmode, par->cmode, var);}static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p){	memset(fix, 0, sizeof(*fix));	strcpy(fix->id, "valkyrie");	fix->mmio_start = p->valkyrie_regs_phys;	fix->mmio_len = sizeof(struct valkyrie_regs);	fix->type = FB_TYPE_PACKED_PIXELS;		fix->type_aux = 0;	fix->ywrapstep = 0;	fix->ypanstep = 0;	fix->xpanstep = 0;	}/* Fix must already be inited above */static void valkyrie_par_to_fix(struct fb_par_valkyrie *par,	struct fb_fix_screeninfo *fix,	struct fb_info_valkyrie *p){	fix->smem_start = p->frame_buffer_phys + 0x1000;#if 1	fix->smem_len = valkyrie_vram_reqd(par->vmode, par->cmode);#else	fix->smem_len = p->total_vram;#endif	fix->visual = (par->cmode == CMODE_8) ?		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;	fix->line_length = par->vxres << par->cmode;		/* ywrapstep, xpanstep, ypanstep */}static void valkyrie_init_display(struct display *disp){	memset(disp, 0, sizeof(*disp));	disp->type = /* fix->type */ FB_TYPE_PACKED_PIXELS;	disp->can_soft_blank = can_soft_blank;	disp->scrollmode = SCROLL_YREDRAW;}static void valkyrie_par_to_display(struct fb_par_valkyrie *par,  struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p){	disp->var = p->var;	disp->screen_base = (char *) p->frame_buffer + 0x1000;	disp->visual = fix->visual;	disp->line_length = fix->line_length;	if(disp->scrollmode != SCROLL_YREDRAW) {		printk(KERN_ERR "Scroll mode not YREDRAW in valkyrie_par_to_display\n");		disp->scrollmode = SCROLL_YREDRAW;	}	switch (par->cmode) {#ifdef FBCON_HAS_CFB8                case CMODE_8:                        disp->dispsw = &fbcon_cfb8;                        break;#endif#ifdef FBCON_HAS_CFB16                case CMODE_16:                        disp->dispsw = &fbcon_cfb16;                        disp->dispsw_data = p->fbcon_cfb16_cmap;                        break;#endif                default:                        disp->dispsw = &fbcon_dummy;                        break;        }}static void __init valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p){	strcpy(info->modename, p->fix.id);	info->node = -1;	/* ??? danj */	info->fbops = &valkyriefb_ops;	info->disp = &p->disp;	strcpy(info->fontname, fontname);	info->changevar = NULL;	info->switch_con = &valkyriefb_switch;	info->updatevar = &valkyriefb_updatevar;	info->blank = &valkyriefb_blank;	info->flags = FBINFO_FLAG_DEFAULT;}/* * Parse user speficied options (`video=valkyriefb:') */int __init valkyriefb_setup(char *options){	char *this_opt;	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!strncmp(this_opt, "font:", 5)) {			char *p;			int i;			p = this_opt + 5;			for (i = 0; i < sizeof(fontname) - 1; i++)				if (!*p || *p == ' ' || *p == ',')					break;			memcpy(fontname, this_opt + 5, i);			fontname[i] = 0;		}		else if (!strncmp(this_opt, "vmode:", 6)) {	    		int vmode = simple_strtoul(this_opt+6, NULL, 0);	    	if (vmode > 0 && vmode <= VMODE_MAX)				default_vmode = vmode;		}		else if (!strncmp(this_opt, "cmode:", 6)) {			int depth = simple_strtoul(this_opt+6, NULL, 0);			switch (depth) {			 case 8:			    default_cmode = CMODE_8;			    break;			 case 15:			 case 16:			    default_cmode = CMODE_16;			    break;			}		}		/* XXX - remove these options once blanking has been tested */		else if (!strncmp(this_opt, "noblank", 7)) {			can_soft_blank = 0;		}		else if (!strncmp(this_opt, "blank", 5)) {			can_soft_blank = 1;		}	}	return 0;}MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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