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

📄 sa1100fb.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		par->palette_size = 0; 		break;#endif	default:		return -EINVAL;	}	palette_mem_size = SA1100_PALETTE_MEM_SIZE(par->bits_per_pixel);	palette_mem_phys = (u_long)VideoMemRegion_phys + PAGE_SIZE - palette_mem_size;	par->p_palette_base = (u_short *)palette_mem_phys;        par->v_palette_base = (u_short *)((u_long)VideoMemRegion + PAGE_SIZE - palette_mem_size);	par->p_screen_base  = (u_char *)((u_long)VideoMemRegion_phys + PAGE_SIZE); 	par->v_screen_base  = (u_char *)((u_long)VideoMemRegion      + PAGE_SIZE); 	DPRINTK("p_palette_base = 0x%08lx\n",(u_long)par->p_palette_base);	DPRINTK("v_palette_base = 0x%08lx\n",(u_long)par->v_palette_base);	DPRINTK("palette_size = 0x%08lx\n",(u_long)par->palette_size);	DPRINTK("palette_mem_size = 0x%08lx\n",(u_long)palette_mem_size);	DPRINTK("p_screen_base  = 0x%08lx\n",(u_long)par->p_screen_base);	DPRINTK("v_screen_base  = 0x%08lx\n",(u_long)par->v_screen_base);	DPRINTK("VideoMemRegion = 0x%08lx\n",(u_long)VideoMemRegion);	DPRINTK("VideoMemRegion_phys = 0x%08lx\n",(u_long)VideoMemRegion_phys);	return 0;}static intsa1100fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){	struct sa1100fb_par par;        DPRINTK("con=%d\n", con);	if (con == -1) {		sa1100fb_get_par(&par);		sa1100fb_encode_var(var, &par);	} else		*var = fb_display[con].var;	return 0;}/* * sa1100fb_set_var(): *	Set the user defined part of the display for the specified console */static intsa1100fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){	struct display *display;	int err, chgvar = 0;	struct sa1100fb_par par;	if (con >= 0)		display = &fb_display[con]; /* Display settings for console */	else		display = &global_disp;     /* Default display settings */	/* Decode var contents into a par structure, adjusting any */	/* out of range values. */	if ((err = sa1100fb_decode_var(var, &par)))		return err;	// Store adjusted par values into var structure	sa1100fb_encode_var(var, &par);       	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)		return 0;	else if (((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) && 		 ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NXTOPEN))		return -EINVAL;	if (con >= 0) {		if ((display->var.xres != var->xres) ||		    (display->var.yres != var->yres) ||		    (display->var.xres_virtual != var->xres_virtual) ||		    (display->var.yres_virtual != var->yres_virtual) ||		    (display->var.sync != var->sync)                 ||                    (display->var.bits_per_pixel != var->bits_per_pixel) ||		    (memcmp(&display->var.red, &var->red, sizeof(var->red))) ||		    (memcmp(&display->var.green, &var->green, sizeof(var->green))) ||		    (memcmp(&display->var.blue, &var->blue, sizeof(var->blue)))) 			chgvar = 1;	}	display->var = *var;	display->screen_base	= par.v_screen_base;	display->visual		= par.visual;	display->type		= FB_TYPE_PACKED_PIXELS;	display->type_aux	= 0;	display->ypanstep	= 0;	display->ywrapstep	= 0;	display->line_length	= 	display->next_line      = (var->xres * var->bits_per_pixel) / 8;	display->can_soft_blank	= 1;	display->inverse	= 0;	switch (display->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB4        case 4:		display->dispsw = &fbcon_cfb4;		break;#endif#ifdef FBCON_HAS_CFB8	case 8: 		display->dispsw = &fbcon_cfb8;		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		display->dispsw = &fbcon_cfb16;		break;#endif	default:		display->dispsw = &fbcon_dummy;		break;	}	/* If the console has changed and the console has defined */	/* a changevar function, call that function. */	if (chgvar && info && info->changevar)		info->changevar(con);        /* If the current console is selected and it's not truecolor, 	 *  update the palette 	 */	if ((con == current_par.currcon) &&	    (current_par.visual != FB_VISUAL_TRUECOLOR)) {		struct fb_cmap *cmap;				current_par = par;		if (display->cmap.len)			cmap = &display->cmap;		else			cmap = fb_default_cmap(current_par.palette_size);		fb_set_cmap(cmap, 1, sa1100fb_setcolreg, info);	}	/* If the current console is selected, activate the new var. */	if (con == current_par.currcon)		sa1100fb_activate_var(var);		return 0;}static intsa1100fb_updatevar(int con, struct fb_info *info){	DPRINTK("entered\n");	return 0;}static intsa1100fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){	struct display *display;	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id, SA1100_NAME);	if (con >= 0)	{		DPRINTK("Using console specific display for con=%d\n",con);		display = &fb_display[con];  /* Display settings for console */	}	else		display = &global_disp;      /* Default display settings */	fix->smem_start	 = (unsigned long)current_par.p_screen_base;	fix->smem_len	 = current_par.screen_size;	fix->type	 = display->type;	fix->type_aux	 = display->type_aux;	fix->xpanstep	 = 0;	fix->ypanstep	 = display->ypanstep;	fix->ywrapstep	 = display->ywrapstep;	fix->visual	 = display->visual;	fix->line_length = display->line_length;	fix->accel	 = FB_ACCEL_NONE;	return 0;}static void__init sa1100fb_init_fbinfo(void){	strcpy(fb_info.modename, SA1100_NAME);	strcpy(fb_info.fontname, "Acorn8x8");	fb_info.node		= -1;	fb_info.flags		= FBINFO_FLAG_DEFAULT;	fb_info.fbops		= &sa1100fb_ops;        fb_info.monspecs	= monspecs;	fb_info.disp		= &global_disp;	fb_info.changevar	= NULL;	fb_info.switch_con	= sa1100fb_switch;	fb_info.updatevar	= sa1100fb_updatevar;	fb_info.blank		= sa1100fb_blank;	/*	 * setup initial parameters	 */	memset(&init_var, 0, sizeof(init_var));	init_var.transp.length	= 0;	init_var.nonstd		= 0;	init_var.activate	= FB_ACTIVATE_NOW;	init_var.xoffset	= 0;	init_var.yoffset	= 0;	init_var.height		= -1;	init_var.width		= -1;	init_var.vmode		= FB_VMODE_NONINTERLACED;	if (machine_is_assabet()) {		current_par.max_xres	= 320;		current_par.max_yres	= 240;		current_par.max_bpp	= 16;		init_var.red.length	= 5;						init_var.green.length	= 6;		init_var.blue.length	= 5;		init_var.grayscale	= 0;		init_var.sync		= 0;		init_var.pixclock	= 171521;	} else if (machine_is_cerf()) {		current_par.max_xres	= 320;		current_par.max_yres	= 240;		current_par.max_bpp	= 8;		init_var.red.length	= 4;						init_var.green.length	= 4;		init_var.blue.length	= 4;		init_var.grayscale	= 0;		init_var.sync		= 0;		init_var.pixclock	= 171521;	} else if (machine_is_bitsy()) {		current_par.max_xres	= 320;		current_par.max_yres	= 240;		current_par.max_bpp	= 16;		init_var.red.length	= 4;		init_var.green.length	= 4;		init_var.blue.length	= 4;		init_var.red.offset	= 12;		init_var.green.offset	= 7;		init_var.blue.offset	= 1;		init_var.grayscale	= 0;	} else if (machine_is_brutus()) {		current_par.max_xres	= 320;		current_par.max_yres	= 240;		current_par.max_bpp	= 8;		init_var.red.length	= 4;						init_var.green		= init_var.red;		init_var.blue		= init_var.red;		init_var.sync		= 0;	} else if (machine_is_lart()) {		current_par.max_xres	= 320;		current_par.max_yres	= 240;		current_par.max_bpp	= 4;		init_var.red.length	= 4;						init_var.green		= init_var.red;		init_var.blue		= init_var.red;		init_var.grayscale	= 1;		init_var.pixclock	= 150000;			init_var.sync		= 0;	} else if (machine_is_penny()) {		current_par.max_xres	= 640;		current_par.max_yres	= 480;		current_par.max_bpp	= 8;		init_var.red.length	= 4;						init_var.green		= init_var.red;		init_var.blue		= init_var.red;		init_var.sync		= 0;	} else if (machine_is_thinclient() || machine_is_graphicsclient()) {		current_par.max_xres	= 640;		current_par.max_yres	= 480;		current_par.max_bpp	= 8;		init_var.red.length	= 4;						init_var.green		= init_var.red;		init_var.blue		= init_var.red;		init_var.sync		= 0;	} else if (machine_is_tifon()) {		current_par.max_xres	= 640;		current_par.max_yres	= 200;		current_par.max_bpp	= 4;		current_par.inv_4bpp	= 1;		init_var.red.length	= 4;						init_var.green		= init_var.red;		init_var.blue		= init_var.red;		init_var.grayscale	= 1;	        init_var.pixclock	= 150000;		        init_var.left_margin	= 20;	        init_var.right_margin	= 255;	        init_var.upper_margin	= 20;	        init_var.lower_margin	= 0;	        init_var.hsync_len	= 2;	        init_var.vsync_len	= 1;		init_var.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT;		init_var.vmode		= 0;	} else if (machine_is_xp860()) {		current_par.max_xres	= 1024;		current_par.max_yres	= 768;		current_par.max_bpp	= 8;		init_var.red.length	= 4;		init_var.green		= init_var.red;		init_var.blue		= init_var.red;		init_var.hsync_len	= 4;		init_var.left_margin	= 3;		init_var.right_margin	= 2;		init_var.vsync_len	= 3;		init_var.upper_margin	= 2;		init_var.lower_margin	= 1;			}	current_par.p_palette_base	= NULL;	current_par.v_palette_base	= NULL;	current_par.p_screen_base	= NULL;	current_par.v_screen_base	= NULL;	current_par.palette_size	= MAX_PALETTE_NUM_ENTRIES;	current_par.screen_size		= MAX_PIXEL_MEM_SIZE;	current_par.montype		= -1;	current_par.currcon		= -1;	current_par.allow_modeset	=  1;	current_par.controller_state	= LCD_MODE_DISABLED;	init_var.xres			= current_par.max_xres;	init_var.yres			= current_par.max_yres;	init_var.xres_virtual		= init_var.xres;	init_var.yres_virtual		= init_var.yres;	init_var.bits_per_pixel		= current_par.max_bpp;			}/* * sa1100fb_map_video_memory(): *      Allocates the DRAM memory for the frame buffer.  This buffer is   *	remapped into a non-cached, non-buffered, memory region to   *      allow palette and pixel writes to occur without flushing the  *      cache.  Once this area is remapped, all virtual memory *      access to the video memory should occur at the new region. */static int__init sa1100fb_map_video_memory(void){	u_int  required_pages;	u_int  extra_pages;	u_int  order;        struct page *page;        char   *allocated_region;	if (VideoMemRegion != NULL)		return -EINVAL;	DPRINTK("-1-");	/* Find order required to allocate enough memory for framebuffer */	required_pages = ALLOCATED_FB_MEM_SIZE >> PAGE_SHIFT;        for (order = 0 ; required_pages >> order ; order++) {;}        extra_pages = (1 << order) - required_pages;        if ((allocated_region =              (char *)__get_free_pages(GFP_KERNEL | GFP_DMA, order)) == NULL)           return -ENOMEM;        VideoMemRegion = (u_char *)allocated_region + (extra_pages << PAGE_SHIFT);         VideoMemRegion_phys = (u_char *)__virt_to_phys((u_long)VideoMemRegion);	/* Free all pages that we don't need but were given to us because */	/* __get_free_pages() works on powers of 2. */	for (;extra_pages;extra_pages--)          free_page((u_int)allocated_region + ((extra_pages-1) << PAGE_SHIFT));        /* Set reserved flag for fb memory to allow it to be remapped into */        /* user space by the common fbmem driver using remap_page_range(). */	for(page = virt_to_page(VideoMemRegion); 	    page < virt_to_page(VideoMemRegion + ALLOCATED_FB_MEM_SIZE); page++)	  mem_map_reserve(page);	/* Remap the fb memory to a non-buffered, non-cached region */	VideoMemRegion = (u_char *)__ioremap((u_long)VideoMemRegion_phys,					     ALLOCATED_FB_MEM_SIZE,					     L_PTE_PRESENT  |					     L_PTE_YOUNG    |					     L_PTE_DIRTY    |					     L_PTE_WRITE);	return (VideoMemRegion == NULL ? -EINVAL : 0);}static const int frequency[16] = {	59000000,        73700000,        88500000,        103200000,        118000000,        132700000,        147500000,        162200000,        176900000,        191700000,        206400000, 	230000000,	245000000,	260000000,	275000000,	290000000};static inline int get_pcd(unsigned int pixclock){	unsigned int pcd = 0;	if (machine_is_tifon()) {		pcd = frequency[PPCR &0xf] / 1000;		pcd *= pixclock/1000;		pcd = pcd / 10000000 * 12;		/* the last multiplication by 1.2 is to handle */		/* sync problems */	}	if (machine_is_assabet()) {		pcd = frequency[PPCR & 0xf] / 1000;		pcd *= pixclock / 1000;		pcd = pcd / 1000000;		pcd++; /* make up for integer math truncations */	}	return pcd;}/* * sa1100fb_activate_var(): *	Configures LCD Controller based on entries in var parameter.  Settings are       *      only written to the controller if changes were made.   */static intsa1100fb_activate_var(struct fb_var_screeninfo *var){						       	u_long	flags;	int pcd = get_pcd(var->pixclock);	DPRINTK("Configuring  SA1100 LCD\n");	if (current_par.p_palette_base == NULL)		return -EINVAL;	DPRINTK("activating\n");	/* Disable interrupts and save status */	local_irq_save(flags);		// disable the interrupts and save flags	/* Reset the LCD Controller's DMA address if it has changed */  	lcd_shadow.dbar1 = (Address)current_par.p_palette_base;	lcd_shadow.dbar2 = (Address)(current_par.p_screen_base + (current_par.xres * current_par.yres * current_par.bits_per_pixel / 8 / 2));

⌨️ 快捷键说明

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