sa1100fb.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,857 行 · 第 1/4 页
C
1,857 行
.xres = 640, .yres = 480, .hsync_len = 4, .vsync_len = 3, .left_margin = 2, .upper_margin = 0, .right_margin = 1, .lower_margin = 0, .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas, .lccr3 = LCCR3_ACBsDiv(512),};#endif#ifdef CONFIG_SA1100_OMNIMETERstatic struct sa1100fb_mach_info omnimeter_info __initdata = { .pixclock = 0, .bpp = 4, .xres = 480, .yres = 320, .hsync_len = 1, .vsync_len = 1, .left_margin = 10, .upper_margin = 0, .right_margin = 10, .lower_margin = 0, .cmap_greyscale = 1, .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, .lccr0 = LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_8PixMono, .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(255) | LCCR3_PixClkDiv(44),#error FIXME: fix pixclock, ACBsDiv /* * FIXME: I think ACBsDiv is wrong above - should it be 512 (disabled)? * - rmk */};#endif#ifdef CONFIG_SA1100_PANGOLINstatic struct sa1100fb_mach_info pangolin_info __initdata = { .pixclock = 341521, .bpp = 16, .xres = 800, .yres = 600, .hsync_len = 64, .vsync_len = 7, .left_margin = 160, .upper_margin = 7, .right_margin = 24, .lower_margin = 1, .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsCntOff,};#endif#ifdef CONFIG_SA1100_STORK#if STORK_TFT /* ie the NEC TFT *//* * pixclock is ps per clock. say 72Hz, 800x600 clocks => (1/72)/(800*600) * = 28935 and a bit * NB likely to be increased to ease bus timings wrt pcmcia interface */static struct sa1100fb_mach_info stork_tft_info __initdata = { .pixclock = 28935, .bpp = 16, .xres = 640, .yres = 480, .hsync_len = 64, .vsync_len = 2, .left_margin = 48, .upper_margin = 12, .right_margin = 48, .lower_margin = 31, .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsCntOff,};static struct sa1100fb_rgb stork_tft_rgb_16 = { .red = { .offset = 11, .length = 5, }, .green = { .offset = 5, .length = 6, }, .blue = { .offset = 0, .length = 5, }, .transp = { .offset = 0, .length = 0, },};#else /* Kyocera DSTN */static struct sa1100fb_mach_info stork_dstn_info __initdata = { .pixclock = 0, .bpp = 16, .xres = 640, .yres = 480, .hsync_len = 2, .vsync_len = 2, .left_margin = 2, .upper_margin = 0, .right_margin = 2, .lower_margin = 0, .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT , .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas,#error Fixme .lccr3 = 0xff00 | 0x18 /* ought to be 0x14 but DMA isn't up to that as yet */};static struct sa1100fb_rgb stork_dstn_rgb_16 = { .red = { .offset = 8, .length = 4, }, .green = { .offset = 4, .length = 4, }, .blue = { .offset = 0, .length = 4, }, .transp = { .offset = 0, .length = 0, },};#endif#endif#ifdef CONFIG_SA1100_PT_SYSTEM3/* * 648 x 480 x 8bpp x 75Hz Dual Panel Color STN Display * * pixclock = 1/( 640*3/8*240 ), [pixclock]=1e-12s=ps * 3 due to r,g,b lines * 8 due to 8 bit data bus * 640 due to 640 pixels per line * 240 = 480/2 due to dual panel display * =>4.32Mhz => 231481E-12s */static struct sa1100fb_mach_info system3_info __initdata = { .pixclock = 231481, .bpp = 8, .xres = 640, .yres = 480, .hsync_len = 2, .vsync_len = 2, .left_margin = 2, .upper_margin = 0, .right_margin = 2, .lower_margin = 0, .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, .lccr0 = LCCR0_Color | LCCR0_Dual | LCCR0_Pas, .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),};#endif#ifdef CONFIG_SA1100_XP860static struct sa1100fb_mach_info xp860_info __initdata = { .pixclock = 0, .bpp = 8, .xres = 1024, .yres = 768, .hsync_len = 3, .vsync_len = 3, .left_margin = 3, .upper_margin = 2, .right_margin = 2, .lower_margin = 1, .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_PixClkDiv(6),};#endifstatic struct sa1100fb_mach_info * __initsa1100fb_get_machine_info(struct sa1100fb_info *fbi){ struct sa1100fb_mach_info *inf = NULL; /* * R G B T * default {11,5}, { 5,6}, { 0,5}, { 0,0} * h3600 {12,4}, { 7,4}, { 1,4}, { 0,0} * freebird { 8,4}, { 4,4}, { 0,4}, {12,4} */#ifdef CONFIG_SA1100_ASSABET if (machine_is_assabet()) {#ifndef ASSABET_PAL_VIDEO inf = &lq039q2ds54_info;#else inf = &pal_info;#endif }#endif#ifdef CONFIG_SA1100_H3100 if (machine_is_h3100()) { inf = &h3100_info; }#endif#ifdef CONFIG_SA1100_H3600 if (machine_is_h3600()) { inf = &h3600_info; fbi->rgb[RGB_16] = &h3600_rgb_16; }#endif#ifdef CONFIG_SA1100_H3800 if (machine_is_h3800()) { inf = &h3800_info; }#endif#ifdef CONFIG_SA1100_BRUTUS if (machine_is_brutus()) { inf = &brutus_info; }#endif#ifdef CONFIG_SA1100_COLLIE if (machine_is_collie()) { inf = &collie_info; }#endif#ifdef CONFIG_SA1100_FREEBIRD if (machine_is_freebird()) { inf = &freebird_info; fbi->rgb[RGB_16] = &freebird_rgb16; }#endif#ifdef CONFIG_SA1100_GRAPHICSCLIENT if (machine_is_graphicsclient()) { inf = &graphicsclient_info; }#endif#ifdef CONFIG_SA1100_HUW_WEBPANEL if (machine_is_huw_webpanel()) { inf = &huw_webpanel_info; }#endif#ifdef CONFIG_SA1100_LART if (machine_is_lart()) {#ifdef LART_GREY_LCD inf = &lart_grey_info;#endif#ifdef LART_COLOR_LCD inf = &lart_color_info;#endif#ifdef LART_VIDEO_OUT inf = &lart_video_info;#endif#ifdef LART_KIT01_LCD inf = &lart_kit01_info;#endif }#endif#ifdef CONFIG_SA1100_OMNIMETER if (machine_is_omnimeter()) { inf = &omnimeter_info; }#endif#ifdef CONFIG_SA1100_PANGOLIN if (machine_is_pangolin()) { inf = &pangolin_info; }#endif#ifdef CONFIG_SA1100_PT_SYSTEM3 if (machine_is_pt_system3()) { inf = &system3_info; }#endif#ifdef CONFIG_SA1100_SHANNON if (machine_is_shannon()) { inf = &shannon_info; }#endif#ifdef CONFIG_SA1100_STORK if (machine_is_stork()) {#if STORK_TFT inf = &stork_tft_info; fbi->rgb[RGB_16] = &stork_tft_rgb_16;#else inf = &stork_dstn_info; fbi->rgb[RGB_16] = &stork_dstn_rgb_16;#endif }#endif#ifdef CONFIG_SA1100_XP860 if (machine_is_xp860()) { inf = &xp860_info; }#endif return inf;}static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *);static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state);static inline void sa1100fb_schedule_work(struct sa1100fb_info *fbi, u_int state){ unsigned long flags; local_irq_save(flags); /* * We need to handle two requests being made at the same time. * There are two important cases: * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) * We must perform the unblanking, which will do our REENABLE for us. * 2. When we are blanking, but immediately unblank before we have * blanked. We do the "REENABLE" thing here as well, just to be sure. */ if (fbi->task_state == C_ENABLE && state == C_REENABLE) state = (u_int) -1; if (fbi->task_state == C_DISABLE && state == C_ENABLE) state = C_REENABLE; if (state != (u_int)-1) { fbi->task_state = state; schedule_work(&fbi->task); } local_irq_restore(flags);}static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf){ chan &= 0xffff; chan >>= 16 - bf->length; return chan << bf->offset;}/* * Convert bits-per-pixel to a hardware palette PBS value. */static inline u_int palette_pbs(struct fb_var_screeninfo *var){ int ret = 0; switch (var->bits_per_pixel) { case 4: ret = 0 << 12; break; case 8: ret = 1 << 12; break; case 16: ret = 2 << 12; break; } return ret;}static intsa1100fb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; u_int val, ret = 1; if (regno < fbi->palette_size) { val = ((red >> 4) & 0xf00); val |= ((green >> 8) & 0x0f0); val |= ((blue >> 12) & 0x00f); if (regno == 0) val |= palette_pbs(&fbi->fb.var); fbi->palette_cpu[regno] = val; ret = 0; } return ret;}static intsa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){ struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; unsigned int val; int ret = 1; /* * If inverse mode was selected, invert all the colours * rather than the register number. The register number * is what you poke into the framebuffer to produce the * colour you requested. */ if (fbi->cmap_inverse) { red = 0xffff - red; green = 0xffff - green; blue = 0xffff - blue; } /* * If greyscale is true, then we convert the RGB value * to greyscale no mater what visual we are using. */ if (fbi->fb.var.grayscale) red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16; switch (fbi->fb.fix.visual) { case FB_VISUAL_TRUECOLOR: /* * 12 or 16-bit True Colour. We encode the RGB value * according to the RGB bitfield information. */ if (regno < 16) { u32 *pal = fbi->fb.pseudo_palette; val = chan_to_field(red, &fbi->fb.var.red); val |= chan_to_field(green, &fbi->fb.var.green); val |= chan_to_field(blue, &fbi->fb.var.blue); pal[regno] = val; ret = 0; } break; case FB_VISUAL_STATIC_PSEUDOCOLOR: case FB_VISUAL_PSEUDOCOLOR: ret = sa1100fb_setpalettereg(regno, red, green, blue, trans, info); break; } return ret;}/* * sa1100fb_display_dma_period() * Calculate the minimum period (in picoseconds) between two DMA * requests for the LCD controller. If we hit this, it means we're * doing nothing but LCD DMA. */static unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var){ /* * Period = pixclock * bits_per_byte * bytes_per_transfer * / memory_bits_per_pixel; */ return var->pixclock * 8 * 16 / var->bits_per_pixel;}/* * sa1100fb_check_var(): * Round up in the following order: bits_per_pixel, xres, * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, * bitfields, horizontal timing, vertical timing. */static intsa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){ struct sa1100fb_info *fbi = (struct sa1100fb_info *)info; int rgbidx; if (var->xres < MIN_XRES) var->xres = MIN_XRES; if (var->yres < MIN_YRES) var->yres = MIN_YRES; if (var->xres > fbi->max_xres) var->xres = fbi->max_xres; if (var->yres > fbi->max_yres) var->yres = fbi->max_yres; var->xres_virtual = max(var->xres_virtual, var->xres); var->yres_virtual = max(var->yres_virtual, var->yres); DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); switch (var->bits_per_pixel) { case 4: rgbidx = RGB_8; break; case 8: rgbidx = RGB_8; break; case 16: rgbidx = RGB_16; break; default: return -EINVAL; } /* * Copy the RGB parameters for this display * from the machine specific parameters. */ var->red = fbi->rgb[rgbidx]->red; var->green = fbi->rgb[rgbidx]->green; var->blue = fbi->rgb[rgbidx]->blue; var->transp = fbi->rgb[rgbidx]->transp; DPRINTK("RGBT length = %d:%d:%d:%d\n", var->red.length, var->green.length, var->blue.length, var->transp.length); DPRINTK("RGBT offset = %d:%d:%d:%d\n", var->red.offset, var->green.offset, var->blue.offset, var->transp.offset);#ifdef CONFIG_CPU_FREQ printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n", sa1100fb_display_dma_period(var), cpufreq_get(smp_processor_id()));#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?