📄 s3c44b0xfb.c
字号:
* Fill in a pointer to appropriate low level text console operations (and * optionally a pointer to help data) for the video mode `par' of your * video hardware. These can be generic software routines, or hardware * accelerated routines specifically tailored for your hardware. * If you don't have any appropriate operations, you must fill in a * pointer to dummy operations, and there will be no text output. */ disp->screen_base = info->info.screen_base; /* add -- luhzl */ disp->dispsw = &fbcon_cfb4; /* add -- luzhl */ disp->dispsw_data = NULL; /* add -- luzhl */ return;}#endifstatic void s3c44b0xfb_init_lcd_controller( struct known_lcd_panels *p_lcd){ u32 helpvalue = 0, pagewidth=0, offsize = 0; u16 hozval = 0; u8 modesel = 0; /*---------------------------------*/ /* set LCDSADDR1 to zero to disable the LCD controller */ /*---------------------------------*/ outl(helpvalue, S3C44B0X_LCDCON1); /*---------------------------------*/ /* set LCDSADDR1 */ /*---------------------------------*/ helpvalue = 0; switch(p_lcd->bpp) { case 1: modesel = 0; break; case 2: modesel = 1; break; case 4: modesel = 2; break; case 8: modesel = 3; break; default: modesel = 0; } helpvalue |= (modesel & 0x03)<<27; /* MODESEL value */ /* mod -- luzhl */ /* helpvalue |= ((fb_info.fb_phys & 0x0FC00000) >> 1); *//* LCDBANK addr. */ /* helpvalue |= ((fb_info.gen.info.var.xoffset + (fb_info.gen.info.var.yoffset*fb_info.gen.info.var.xres_virtual)) & 0xFFFFF) >> 1; */ /* add -- luzhl */ helpvalue |= (fb_info.fb_phys & 0x0FC00000) >> 1; helpvalue |= ((fb_info.fb_phys /*+ ((fb_info.gen.info.var.xres_virtual * fb_info.gen.info.var.yres_virtual * fb_info.gen.info.var.bits_per_pixel) >> 3)*/) & 0x01FFFFF) >> 1; outl(helpvalue, S3C44B0X_LCDSADDR1); /*---------------------------------*/ /* set LCDSADDR2 */ /*---------------------------------*/ helpvalue = 0; helpvalue |= (p_lcd->bswp &0x1) << 29; /* BSWP */ helpvalue |= (p_lcd->mval) << 21; /* MVAL */ pagewidth = (p_lcd->width * p_lcd->bpp) >> 4; offsize = ((fb_info.gen.info.var.xres_virtual * p_lcd->bpp) >> 4) - pagewidth; /* mod -- luzhl */ /* helpvalue |= (((((fb_info.gen.info.var.xoffset + (fb_info.gen.info.var.yoffset*fb_info.gen.info.var.xres_virtual)) & 0xFFFFF) >> 1) + (pagewidth + offsize) * (p_lcd->lineval +1)) & 0xFFFFF); */ /* LCDBASEL */ /* add -- luzhl */ helpvalue |= ((((fb_info.fb_phys /*+ ((fb_info.gen.info.var.xres_virtual * fb_info.gen.info.var.yres_virtual * fb_info.gen.info.var.bits_per_pixel) >> 3)*/) & 0x01FFFFF) >> 1) + (pagewidth + offsize) * (p_lcd->lineval +1)) & 0xFFFFF; /* LCDBASEL */ outl(helpvalue, S3C44B0X_LCDSADDR2); /*---------------------------------*/ /* set LCDSADDR3 */ /*---------------------------------*/ helpvalue = 0; helpvalue |= (pagewidth & 0x1FF); helpvalue |= (offsize & 0x7FF) << 9; outl(helpvalue, S3C44B0X_LCDSADDR3); /*---------------------------------*/ /* set LCDCON2 */ /*---------------------------------*/ helpvalue = 0; helpvalue |= (p_lcd->lineblank & 0x3FF) << 21; helpvalue |= (p_lcd->hozval & 0x3FF) << 10; helpvalue |= (p_lcd->lineval & 0x3FF); outl(helpvalue, S3C44B0X_LCDCON2); /*---------------------------------*/ /* set LCDCON3 */ /*---------------------------------*/ outb((p_lcd->selfref & 0x1), S3C44B0X_LCDCON3); /*---------------------------------*/ /* set REDLUT */ /*---------------------------------*/ outl(0xECA86420, S3C44B0X_REDLUT); /*---------------------------------*/ /* set GREENLUT */ /*---------------------------------*/ outl(0xECA86420, S3C44B0X_GREENLUT); /*---------------------------------*/ /* set BLUELUT */ /*---------------------------------*/ outl(0x0000F840, S3C44B0X_BLUELUT); /*---------------------------------*/ /* set LCDCON1 (also enables the LCD controller) */ /*---------------------------------*/ helpvalue = ((p_lcd->clkval&0x3FF) << 12); helpvalue |= ((((p_lcd->wlh >> 2)-1) & 0x03) << 10); /* map the wlh value and shift 10 left */ helpvalue |= ((((p_lcd->wdly >> 2)-1) & 0x03) << 8); /* map the wdly value and shift 8 left */ helpvalue |= ((p_lcd->mmode & 0x01) << 7); helpvalue |= (p_lcd->dismode << 5); /* DISMODE */ helpvalue |= ((p_lcd->invclk&0x01) << 4); helpvalue |= ((p_lcd->invline&0x01) << 3); helpvalue |= ((p_lcd->invframe&0x01) << 2); helpvalue |= ((p_lcd->invvd&0x01) << 1); helpvalue |= 1; /* enables the display */ outl(helpvalue, S3C44B0X_LCDCON1); /* switch display on by setting special port */ if(p_lcd->disp_on_ctrl_reg) { helpvalue = inl(p_lcd->disp_on_ctrl_reg); helpvalue &= ~p_lcd->disp_on_ctrl_reg_mask; helpvalue |= p_lcd->disp_on_ctrl_reg_value; outl(helpvalue, p_lcd->disp_on_ctrl_reg); /* set disp_on port to enable */ } if(p_lcd->disp_on_port) { helpvalue = inl(p_lcd->disp_on_port); helpvalue &= ~p_lcd->disp_on_mask; helpvalue |= p_lcd->disp_on_val; outl(helpvalue, p_lcd->disp_on_port); /* enable display */ }}/* ------------ Interfaces to hardware functions ------------ */struct fbgen_hwswitch s3c44b0xfb_switch = { s3c44b0xfb_detect, s3c44b0xfb_encode_fix, s3c44b0xfb_decode_var, s3c44b0xfb_encode_var, s3c44b0xfb_get_par, s3c44b0xfb_set_par, s3c44b0xfb_getcolreg, s3c44b0xfb_setcolreg, s3c44b0xfb_pan_display, s3c44b0xfb_blank, NULL//s3c44b0xfb_set_disp /* NULL */ /* mod -- luzhl */};/* ------------ Hardware Independent Functions ------------ */ /* * Initialization */int __init s3c44b0xfb_init(void){ struct known_lcd_panels *p_lcd; int num_panels; /* number of known LCD panels */ int i; //char *fbuf; /* add -- luzhl */ printk("S3C44B0X framebuffer init\n"); if( (bootloader == 0) && (panel_name == NULL) ) { printk("S3C44B0X framebuffer driver error: No panel name specified and bootloader settings shall not be used\n"); return -EINVAL; } if(bootloader) { printk("S3C44B0X framebuffer driver error: Using of bootloader settings not yet implemented\n"); return 0; /* FIXME read out the parms from the controller and store them into the structs */ } num_panels = sizeof(panels)/sizeof(struct known_lcd_panels); /* Get the panel name, everything else is fixed */ for (i=0; i<num_panels; i++) { if (!strcmp(panel_name, panels[i].lcd_panel_name)) { s3c44b0x_lcd_index = i; panel_valid = 1; break; } } if(!panel_valid) { printk("S3C44B0X framebuffer driver error: Invalid panel name selected\n"); return -EINVAL; } p_lcd = &panels[s3c44b0x_lcd_index];/* add luzhl */ //fbuf = kmalloc((p_lcd->width * p_lcd->height * p_lcd->bpp) >> 3, GFP_KERNEL);// if(!fbuf) // return -ENOMEM; memset(&fb_info.gen, 0, sizeof(fb_info.gen)); fb_info.gen.fbhw = &s3c44b0xfb_switch; sprintf(fb_info.gen.info.modename, "%dx%dx%d",p_lcd->width,p_lcd->height,p_lcd->bpp); fb_info.gen.parsize = sizeof(struct s3c44b0xfb_par); fb_info.gen.info.screen_base = S3C44B0X_FB_ADDRESS; /* add -- luzhl */ fb_info.gen.info.changevar = NULL; fb_info.gen.info.node = -1; fb_info.gen.info.fbops = &s3c44b0xfb_ops; fb_info.gen.info.disp = NULL; /* mod -- luzhl */ /* NULL; */ /* not needed ?? */ fb_info.gen.info.switch_con = NULL; fb_info.gen.info.updatevar = NULL; fb_info.gen.info.blank = &s3c44b0xfb_gen_blank; fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT; /* This should give a reasonable default video mode */ //fbgen_get_var(&disp.var, -1, &fb_info.gen.info); /* mod -- luzhl */ //fbgen_do_set_var(&disp.var, 1, &fb_info.gen); /* mod -- luzhl */ //fbgen_set_disp(-1, &fb_info.gen); /* mod -- luzhl */ //fbgen_install_cmap(0, &fb_info.gen); /* mod -- luzhl */ /********************************************** * file the var struct inside the current_par struct **********************************************/ memset(¤t_par.var, 0, sizeof(current_par.var)); current_par.var.xres = p_lcd->width; current_par.var.yres = p_lcd->height; current_par.var.xres_virtual = p_lcd->width; current_par.var.yres_virtual = p_lcd->height; current_par.var.bits_per_pixel = p_lcd->bpp; current_par.var.grayscale = (p_lcd->bpp == 8)? 0 : 1; if(p_lcd->bpp == 1) { current_par.var.blue.length = 1; } else if(p_lcd->bpp == 2) { current_par.var.blue.length = 2; } else if(p_lcd->bpp == 4) { current_par.var.blue.length = 4; } else if(p_lcd->bpp == 8) { current_par.var.red.offset = 5; current_par.var.red.length = 3; current_par.var.green.offset = 2; current_par.var.green.length = 3; current_par.var.blue.length = 2; } current_par_valid = 1; /* * Allocate LCD framebuffer from system memory */ fb_info.fb_size = (p_lcd->width * p_lcd->height * p_lcd->bpp) >> 3; /* FIXME align it to 4 MB */ fb_info.fb_phys = S3C44B0X_FB_ADDRESS; fb_info.fb_virt_start = fb_info.fb_phys; current_par.line_length = (p_lcd->width * p_lcd->bpp) >> 3; /* fill the var element of fb_info.gen.info */ memcpy(&fb_info.gen.info.var, ¤t_par.var, sizeof(struct fb_var_screeninfo)); /* fill the fix element of fb_info.gen.info */ s3c44b0xfb_encode_fix(&fb_info.gen.info.fix, ¤t_par, &fb_info.gen); if (register_framebuffer(&fb_info.gen.info) < 0) { /* mod -- luzhl */ // kfree(fbuf); return -EINVAL; } printk(KERN_INFO "fb%d: %08x: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node), S3C44B0X_FB_ADDRESS, fb_info.gen.info.modename); /********************************************* * set framebuffer memory to zero *********************************************/ memset((void*)fb_info.fb_phys, 0, fb_info.fb_size); /********************************************* * init the lcd controller *********************************************/ s3c44b0xfb_init_lcd_controller(p_lcd); /* uncomment this if your driver cannot be unloaded */ /* MOD_INC_USE_COUNT; */ printk("S3C44B0X framebuffer driver: Init ready\n"); return 0;} /* * Cleanup */void s3c44b0xfb_cleanup(struct fb_info *info){ /* * If your driver supports multiple boards, you should unregister and * clean up all instances. */ unregister_framebuffer(info);} /* * Setup */int __init s3c44b0xfb_setup(char *options){ return 0;}/* ------------------------------------------------------------------------- */ /* * Frame buffer operations *//* If all you need is that - just don't define ->fb_open */static int s3c44b0xfb_open(struct fb_info *info, int user){ return 0;}/* If all you need is that - just don't define ->fb_release */static int s3c44b0xfb_release(struct fb_info *info, int user){ return 0;} /* * In most cases the `generic' routines (fbgen_*) should be satisfactory. * However, you're free to fill in your own replacements. */static struct fb_ops s3c44b0xfb_ops = { owner: THIS_MODULE, fb_open: s3c44b0xfb_open, /* only if you need it to do something */ fb_release: s3c44b0xfb_release, /* only if you need it to do something */ fb_get_fix: fbgen_get_fix, fb_get_var: fbgen_get_var, fb_set_var: fbgen_set_var, fb_get_cmap: fbgen_get_cmap, fb_set_cmap: fbgen_set_cmap, fb_pan_display: fbgen_pan_display, fb_ioctl: NULL, /* optional */};/* ------------------------------------------------------------------------- */ /* * Modularization */#ifdef MODULEMODULE_LICENSE("GPL");int init_module(void){ return s3c44b0xfb_init();}void cleanup_module(void){ s3c44b0xfb_cleanup(&fb_info.gen.info);}#endif /* MODULE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -