📄 ep93xxfb.c
字号:
DPRINTK("Default framebuffer is 16bpp 565."); fb_info.var.bits_per_pixel = 16; fb_info.var.red.length = 5; fb_info.var.blue.length = 5; fb_info.var.green.length = 6; fb_info.var.transp.length = 0; fb_info.var.red.offset = 11; fb_info.var.green.offset = 5; fb_info.var.blue.offset = 0; fb_info.var.transp.offset = 0; fb_info.fix.visual = FB_VISUAL_TRUECOLOR; fb_info.pseudo_palette = mypar.palette; mypar.bits_per_pixel = 16;#endif // CONFIG_FB_EP93XX_16BPP //TBD wierd to have a flag which has meaning when call set_var //TBD be copied into fb_info? this is more a parameter than //TBD some state to keep track of. fb_info.var.activate = FB_ACTIVATE_NOW; fb_info.var.height = 640; //TBD unknown fb_info.var.width = 480; //TBD unknown // // Set the default timing information. // fb_info.var.left_margin = TimingValues[mode].HFrontPorch; fb_info.var.right_margin = TimingValues[mode].HBackPorch; fb_info.var.upper_margin = TimingValues[mode].VFrontPorch; fb_info.var.lower_margin = TimingValues[mode].VBackPorch; fb_info.var.hsync_len = TimingValues[mode].HSyncWidth; fb_info.var.vsync_len = TimingValues[mode].VSyncWidth; fb_info.var.sync = 0; fb_info.var.vmode = FB_VMODE_NONINTERLACED; fb_info.fix.smem_start = (__u32) mypar.p_screen_base; // physical fb_info.fix.smem_len = (__u32) mypar.screen_size; //TBD in bytes fb_info.fix.mmio_start = RASTER_BASE - IO_BASE_VIRT + IO_BASE_PHYS;#ifdef CONFIG_EP93XX_GRAPHICS fb_info.fix.mmio_len = 0x00020000;#else fb_info.fix.mmio_len = 0x00010000;#endif fb_info.fix.type = FB_TYPE_PACKED_PIXELS; fb_info.fix.line_length = fb_info.var.xres_virtual * fb_info.var.bits_per_pixel/8; // stride in bytes fb_info.monspecs = monspecs; // copies structure fb_info.fbops = &ep93xxfb_ops; fb_info.screen_base = mypar.v_screen_base; fb_info.disp = &global_disp; fb_info.changevar = NULL; fb_info.switch_con = ep93xxfb_switch; fb_info.updatevar = ep93xxfb_updatevar; //TBD why not NULL? fb_info.blank = ep93xxfb_blank; // // Save the current TimingValues for later use in Configuration routine. // fb_info.par = &TimingValues[mode]; mypar.screen_size = FB_MAX_MEM_SIZE; // not a particular mode mypar.palette_size = MAX_PALETTE_NUM_ENTRIES; // not a particular mode mypar.montype = 1; //TBD why not 0 since single entry? mypar.currcon = 0; //TBD is this right? // these are also set by set_var mypar.visual = FB_VISUAL_PSEUDOCOLOR;}//=============================================================================// MapFramebuffer//=============================================================================// Allocates the memory for the frame buffer. This buffer is remapped into a// non-cached, non-buffered, memory region to allow 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 MapFramebuffer(void){ // // Make sure that we don't allocate the buffer twice. // if (mypar.p_screen_base != 0) return(-EINVAL); // // Allocate the Frame buffer and map it while we are at it. // Save the Physical address of the Frame buffer in p_screen_base. // mypar.v_screen_base = consistent_alloc(GFP_KERNEL, FB_MAPPED_MEM_SIZE, &mypar.p_screen_base); if ( mypar.v_screen_base == 0) return(-ENOMEM); return 0;}//=============================================================================// ConfigureRaster()://=============================================================================// Configures LCD Controller based on entries in var parameter.//// Note: palette is setup elsewhere.//=============================================================================static intConfigureRaster(struct fb_var_screeninfo *var, DisplayTimingValues *pTimingValues){ u_long flags, ulVIDEOATTRIBS; unsigned int total, uiDevCfg; unsigned int uiPADDR, uiPADR; DPRINTK("activating\n"); /* Disable interrupts and save status */ local_irq_save(flags); // disable interrupts and save flags DPRINTK("Configuring %dx%dx%dbpp\n",var->xres, var->yres, var->bits_per_pixel); // Setup video mode according to var values. // Remember to unlock total, startstop, and linecarry registers. // Disable the video and outputs while changing the video mode. outl( 0, VIDEOATTRIBS ); if (pTimingValues->RasterConfigure) pTimingValues->RasterConfigure(pTimingValues); else { total = var->vsync_len + var->upper_margin + var->yres + var->lower_margin - 1; RasterSetLocked(VLINESTOTAL, total); RasterSetLocked(VSYNCSTRTSTOP, total - var->lower_margin + ((total - (var->lower_margin + var->vsync_len)) << 16)); RasterSetLocked(VACTIVESTRTSTOP, var->yres-1 + (total << 16)); // Reverse start/stop since N_VBLANK output // unblanked same as active RasterSetLocked(VBLANKSTRTSTOP, var->yres-1 + (total << 16)); RasterSetLocked(VCLKSTRTSTOP, total + (total << 16)); // // Now configure the Horizontal timings. // total = var->hsync_len + var->left_margin + var->xres + var->right_margin - 1; RasterSetLocked(HCLKSTOTAL,total); RasterSetLocked(HSYNCSTRTSTOP, total + ((total - var->hsync_len) << 16)); RasterSetLocked(HACTIVESTRTSTOP, total - var->hsync_len - var->left_margin + ((var->right_margin - 1) << 16)); RasterSetLocked(HBLANKSTRTSTOP, total - var->hsync_len - var->left_margin + ((var->right_margin - 1) << 16)); RasterSetLocked(HCLKSTRTSTOP, total + (total << 16)); RasterSetLocked(LINECARRY, 0); // // Now that everything else is setup, enable video and outputs // // Invert Clock, enable outputs and VSYNC,HSYNC,BLANK active low // Invert means pixel output data changes on falling edge of clock, to // provide setup time for the video DAC to latch data on rising edge. // RasterSetLocked(VIDEOATTRIBS, VIDEOATTRIBS_INVCLK | VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_DATAEN); } // // Configure the Frame Buffer size. // outl( (unsigned int)mypar.p_screen_base, VIDSCRNPAGE ); outl( var->yres, SCRNLINES ); // // Set up the Line size. // total = var->xres * var->bits_per_pixel / 32; outl( (total - 1), LINELENGTH ); outl( total, VLINESTEP ); if (var->bits_per_pixel == 8) // // 8bpp framebuffer, color LUT and convert to 18bpp on pixel bus. // outl( (0x8 | PIXELMODE_P_8BPP | PIXELMODE_C_LUT), PIXELMODE ); else if (var->bits_per_pixel == 16) // // 16bpp framebuffer and convert to 18bpp on pixel bus. // outl( 0x8 | PIXELMODE_P_16BPP | ((PIXELMODE_C_565)<<(PIXELMODE_C_SHIFT)), PIXELMODE ); // // TODO this is more HACKING! // TODO add configurable framebuffer location and side-band option. // uiDevCfg = inl(SYSCON_DEVCFG); SysconSetLocked(SYSCON_DEVCFG, (uiDevCfg | SYSCON_DEVCFG_RasOnP3) ); // // TODO add code to calculate this not just slam it in there. // SysconSetLocked(SYSCON_VIDDIV, pTimingValues->VDiv); // // Enable Raster and make sure that frame buffer chip select is specfied // since this field is not readable. // ulVIDEOATTRIBS = inl(VIDEOATTRIBS) & ~VIDEOATTRIBS_SDSEL_MASK;#ifdef CONFIG_ARCH_EP93XX_SDCSN0 ulVIDEOATTRIBS |= 0 << VIDEOATTRIBS_SDSEL_SHIFT;#endif#ifdef CONFIG_ARCH_EP93XX_SDCSN1 ulVIDEOATTRIBS |= 1 << VIDEOATTRIBS_SDSEL_SHIFT;#endif#ifdef CONFIG_ARCH_EP93XX_SDCSN2 ulVIDEOATTRIBS |= 2 << VIDEOATTRIBS_SDSEL_SHIFT;#endif#ifdef CONFIG_ARCH_EP93XX_SDCSN3 ulVIDEOATTRIBS |= 3 << VIDEOATTRIBS_SDSEL_SHIFT;#endif RasterSetLocked(VIDEOATTRIBS, ulVIDEOATTRIBS | VIDEOATTRIBS_EN); // // Turn on the LCD. //#if defined(CONFIG_ARCH_EDB9307) || defined(CONFIG_ARCH_EDB9312) || \ defined(CONFIG_ARCH_EDB9315) if (mode == 1) { uiPADDR = inl(GPIO_PADDR) | 0x2; outl( uiPADDR, GPIO_PADDR ); uiPADR = inl(GPIO_PADR) | 0x2; outl( uiPADR, GPIO_PADR ); }#endif // // Restore interrupt status // local_irq_restore(flags); return 0;}/* * ep93xxfb_blank(): * TBD not implemented */static voidep93xxfb_blank(int blank, struct fb_info *info){}//=============================================================================// ep93xxfb_switch()://=============================================================================// Change to the specified console. Palette and video mode are changed to the// console's stored parameters.////=============================================================================static int ep93xxfb_switch(int con, struct fb_info *info){ DPRINTK("con=%d info->modename=%s\n", con, info->modename); if (mypar.visual != FB_VISUAL_TRUECOLOR) { struct fb_cmap *cmap; if (mypar.currcon >= 0) { // Get the colormap for the selected console cmap = &fb_display[mypar.currcon].cmap; if (cmap->len) fb_get_cmap(cmap, 1, ep93xxfb_getcolreg, info); } } mypar.currcon = con; fb_display[con].var.activate = FB_ACTIVATE_NOW; DPRINTK("fb_display[%d].var.activate=%x\n", con, fb_display[con].var.activate); ep93xxfb_set_var(&fb_display[con].var, con, info); return 0;}//=============================================================================// ep93xxfb_init(void)//=============================================================================//=============================================================================int __init ep93xxfb_init(void){ int ret; DPRINTK("Entering: ep93xxfb_init.\n"); // // Allocate and map video buffer // if ((ret = MapFramebuffer()) != 0) { DPRINTK("Leaving: ep93xxfb_init FAILED %08x.", ret); return ret; } // // Initialize the Framebuffer Info structure. // ep93xxfb_init_fbinfo(); // // Check and adjust var and set it active. // TBD is this okay to pass in fb_info.var or // TBD does it cause some aliasing problem? // TBD can set var fail? // ep93xxfb_set_var(&fb_info.var, -1, &fb_info); register_framebuffer(&fb_info);#ifdef CONFIG_EP93XX_GRAPHICS outl(0x00000000, BLOCKCTRL); request_irq(IRQ_GRAPHICS, ep93xxfb_irq_handler, SA_INTERRUPT, "graphics",NULL);#endif DPRINTK("Leaving: ep93xxfb_init."); return 0;}__init intep93xxfb_setup(char *options){ char *opt; if (!options || !*options) return 0; while ((opt = strsep(&options, ",")) != NULL) { if (!*opt) continue; if (strncmp(opt, "font=", 5) == 0) { strncpy(default_font_storage, opt + 5, sizeof(default_font_storage)); default_font = default_font_storage; continue; } if (strncmp(opt, "mode=lcd", 8) == 0) { mode = 1; continue; } if (strncmp(opt, "mode=crt", 8) == 0) { mode = 0; continue; } if (strncmp(opt, "mode=tv", 7) == 0) { mode = 3; continue; } if (strncmp(opt, "overscan=on", 11) == 0) { overscan = 1; continue; } if (strncmp(opt, "overscan=off", 12) == 0) { overscan = 0; continue; } printk (KERN_ERR "ep93xxfb: unknown parameter: %s\n", opt); } return 0;}//=============================================================================// Conexant_CX25871//=============================================================================// Timing and screen configuration for the Conexant CX25871.//=============================================================================static int Conexant_CX25871(DisplayTimingValues *pTimingValues){ unsigned int uiTemp; // // By name it Initializes the CX25871 to 640x480 NTSC. // InitializeCX25871For640x480NTSC(); // // Disable the Raster Engine. // RasterSetLocked(VIDEOATTRIBS, 0); // // Configure the Raster to use external clock for pixel clock. // uiTemp = inl(SYSCON_DEVCFG); SysconSetLocked(SYSCON_DEVCFG, (uiTemp | SYSCON_DEVCFG_EXVC) ); if (overscan) { // // Configure the Vertical Timing. // RasterSetLocked(VLINESTOTAL, 0x20c); RasterSetLocked(VSYNCSTRTSTOP, 0x01ff0204); RasterSetLocked(VBLANKSTRTSTOP, 0x000001E0); RasterSetLocked(VACTIVESTRTSTOP, 0x000001E0); RasterSetLocked(VCLKSTRTSTOP,0x07FF01E0); // // Configure the Horizontal Timing. // RasterSetLocked(HCLKSTOTAL, 0x307); RasterSetLocked(HSYNCSTRTSTOP, 0x02c00307); RasterSetLocked(HBLANKSTRTSTOP,0x00100290); RasterSetLocked(HACTIVESTRTSTOP,0x00100290); RasterSetLocked(HCLKSTRTSTOP, 0x07ff0290); } else { // // Configure the Vertical Timing. // RasterSetLocked(VLINESTOTAL, 0x0257); RasterSetLocked(VSYNCSTRTSTOP, 0x01FF022C); RasterSetLocked(VBLANKSTRTSTOP, 0x000001E0); RasterSetLocked(VACTIVESTRTSTOP, 0x000001E0); RasterSetLocked(VCLKSTRTSTOP,0x07FF01E0); // // Configure the Horizontal Timing. // RasterSetLocked(HCLKSTOTAL, 0x30F); RasterSetLocked(HSYNCSTRTSTOP, 0x02c0030f); RasterSetLocked(HBLANKSTRTSTOP,0x000f028f); RasterSetLocked(HACTIVESTRTSTOP,0x000f028f); RasterSetLocked(HCLKSTRTSTOP, 0x07ff028f); } RasterSetLocked(LINECARRY, 0); // // Enable the Data and Sync outputs only.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -