📄 mq200fb.c
字号:
/* save cursor images */ image = fb_info->regions.v_fb + CURSOR_OFFSET; for (i = 0; i < 2; i++) { int j; for (j = 0; j < 256; j++, image += 4) cursor_images[i][j] = readl(image); } spin_unlock_irqrestore(&fb_info->lock, flags); already_created = 1; } else { int i; /* restore cursor images */ image = fb_info->regions.v_fb + CURSOR_OFFSET; spin_lock_irqsave(&fb_info->lock, flags); for (i = 0; i < 2; i++) { int j; for (j = 0; j < 256; j++, image += 4) writel(cursor_images[i][j], image); } spin_unlock_irqrestore(&fb_info->lock, flags); }}/**** * turn on hardware cursor. */static voidenable_cursor(struct mq200fb_info* fb_info){ unsigned long flags; union gc00r gc00r; spin_lock_irqsave(&fb_info->lock, flags); gc00r.whole = readl(GC00R(fb_info)); if (gc00r.part.hc_enbl == 0) { set_cursor_shape(fb_info); gc00r.part.hc_enbl = 1; writel(gc00r.whole, GC00R(fb_info)); } spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * turn off hardware cursor. */static voiddisable_cursor(struct mq200fb_info* fb_info){ unsigned long flags; union gc00r gc00r; spin_lock_irqsave(&fb_info->lock, flags); gc00r.whole = readl(GC00R(fb_info)); if (gc00r.part.hc_enbl == 1) { gc00r.part.hc_enbl = 0; writel(gc00r.whole, GC00R(fb_info)); } spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * Set current window's cursor position. * * [RETURN] * 1: when cursor position has been moved. */static intset_cursor_pos(const struct mq200fb_info* fb_info, unsigned x, /* horizontal pos in pixels */ unsigned y) /* vertical pos in pixels */{ int ret; unsigned long flags; union gc10r gc10r; spin_lock_irqsave(&fb_info->lock, flags); gc10r.whole = readl(GC10R(fb_info)); if (gc10r.part.hc1s == x && gc10r.part.vc1s == y) ret = 0; else { gc10r.whole = 0; gc10r.part.hc1s = x; gc10r.part.vc1s = y; writel(gc10r.whole, GC10R(fb_info)); ret = 1; } spin_unlock_irqrestore(&fb_info->lock, flags); return ret;}/**** * blink cursor. */static voidcursor_timer_handler(unsigned long data){ unsigned long flags; struct mq200fb_info* fb_info = (struct mq200fb_info*)data; union gc11r gc11r; spin_lock_irqsave(&fb_info->lock, flags); gc11r.whole = readl(GC11R(fb_info)); if (gc11r.part.hc1sa == CURSOR_OFFSET >> 10) gc11r.part.hc1sa += 1; else gc11r.part.hc1sa = CURSOR_OFFSET >> 10; writel(gc11r.whole, GC11R(fb_info)); spin_unlock_irqrestore(&fb_info->lock, flags); add_cursor_timer(&fb_info->cursor_info);}static voidget_color_palette(const struct mq200fb_info* fb_info, unsigned indx, unsigned* red, unsigned* green, unsigned* blue){ unsigned long flags; union c1xxr c1xxr; spin_lock_irqsave(&fb_info->lock, flags); c1xxr.whole = readl(C1xxR(fb_info, indx)); spin_unlock_irqrestore(&fb_info->lock, flags); *red = c1xxr.part.red; *green = c1xxr.part.green; *blue = c1xxr.part.blue;}static voidset_color_palette(const struct mq200fb_info* fb_info, unsigned indx, unsigned red, unsigned green, unsigned blue){ unsigned long flags; union c1xxr c1xxr; c1xxr.whole = 0; c1xxr.part.red = red; c1xxr.part.green = green; c1xxr.part.blue = blue; spin_lock_irqsave(&fb_info->lock, flags); writel(c1xxr.whole, C1xxR(fb_info, indx)); spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * enable CRT DAC. */static voidenable_dac(const struct mq200fb_info* fb_info){ unsigned long flags; union gc01r gc01r; spin_lock_irqsave(&fb_info->lock, flags); gc01r.whole = readl(GC01R(fb_info)); gc01r.part.dac_enbl = 1; writel(gc01r.whole, GC01R(fb_info)); spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * disable CRT DAC. */static voiddisable_dac(const struct mq200fb_info* fb_info, unsigned sync_mode) /* specify SYNC that output while DAC is disabled */{ unsigned long flags; union gc01r gc01r; spin_lock_irqsave(&fb_info->lock, flags); gc01r.whole = readl(GC01R(fb_info)); gc01r.part.dac_enbl = 0; gc01r.part.hsync_out = (sync_mode & WITH_HSYNC) != 0; gc01r.part.vsync_out = (sync_mode & WITH_VSYNC) != 0; writel(gc01r.whole, GC01R(fb_info)); spin_unlock_irqrestore(&fb_info->lock, flags);}/**** * Return true if command FIFO . */static int __inline__is_enough_cmd_fifo(const struct mq200fb_info* fb_info, int num){ union cc01r cc01r; cc01r.whole = readl(CC01R(fb_info)); return cc01r.part.cmd_fifo >= num;}/**** * */static int __inline__is_enough_src_fifo(const struct mq200fb_info* fb_info, int num){ union cc01r cc01r; cc01r.whole = readl(CC01R(fb_info)); return cc01r.part.src_fifo >= num;}/**** * wait until command FIFO space is enough. */static voidwait_cmd_fifo(const struct mq200fb_info* fb_info, int num){ int i; for (i = 0; i < 0x00100000; i++) if (is_enough_cmd_fifo(fb_info, num)) return; printk(CHIPNAME ": Command FIFO is full.\n");}/**** * */static voidwait_src_fifo(const struct mq200fb_info* fb_info, int num){ int i; for (i = 0; i < 0x00100000; i++) if (is_enough_src_fifo(fb_info, num)) return; printk(CHIPNAME ": Source FIFO is full.\n");}/**************************************************************** * Frame buffer operations *//**** * rectangle fill (solid fill) */static voidge_rect_fill(const struct mq200fb_info* fb_info, int x, int y, int width, int height, u32 bgcol){ unsigned long flags; union ge01r ge01r; union ge02r ge02r; union ge00r ge00r; ge01r.whole = 0; ge01r.bitblt.width = width; ge01r.bitblt.height = height; ge02r.whole = 0; ge02r.window.dst_x = x; ge02r.window.dst_y = y; ge00r.whole = 0; ge00r.part.rop = ROP_PATCOPY; ge00r.part.cmd_typ = 2; /* BitBLT */ ge00r.part.mon_ptn = 1; ge00r.part.sol_col = 1; wait_cmd_fifo(fb_info, 4); spin_lock_irqsave(&fb_info->lock, flags); writel(ge01r.whole, GE01R(fb_info)); writel(ge02r.whole, GE02R(fb_info)); writel(bgcol, GE42R(fb_info)); writel(ge00r.whole, GE00R(fb_info)); spin_unlock_irqrestore(&fb_info->lock, flags);}#if 0/**** * bitblt screen to screen. */static voidge_bitblt_scr_to_scr(const struct mq200fb_info* fb_info, int src_x, int src_y, int dst_x, int dst_y, int width, int height){ unsigned long flags; union ge00r ge00r; union ge01r ge01r; union ge02r ge02r; union ge03r ge03r; ge01r.whole = 0; ge01r.bitblt.width = width; ge01r.bitblt.height = height; ge02r.whole = 0; ge02r.window.dst_x = dst_x; ge02r.window.dst_y = dst_y; ge03r.whole = 0; ge03r.window.src_x = src_x; ge03r.window.src_y = src_y; ge00r.whole = 0; ge00r.part.rop = ROP_SRCCOPY; ge00r.part.cmd_typ = 2; /* BitBLT */ if (src_x >= dst_x) { if (src_y < dst_y) ge00r.part.y_dir = 1; } else if (src_y >= dst_y) ge00r.part.x_dir = 1; else { ge00r.part.x_dir = 1; ge00r.part.y_dir = 1; } wait_cmd_fifo(fb_info, 4); spin_lock_irqsave(&fb_info->lock, flags); writel(ge01r.whole, GE01R(fb_info)); writel(ge02r.whole, GE02R(fb_info)); writel(ge03r.whole, GE03R(fb_info)); writel(ge00r.whole, GE00R(fb_info)); spin_unlock_irqrestore(&fb_info->lock, flags);}#endif/**** * draw mono text image. */static voidge_bitblt_char(const struct mq200fb_info* fb_info, int dst_x, int dst_y, u8* image, int width, int height, u32 fgcol, u32 bgcol) /* foreground and background color */{ unsigned long flags; int i; union ge00r ge00r; union ge01r ge01r; union ge02r ge02r; union ge09r ge09r; int offset = ((u32)image & 0x3) * 8; ge01r.whole = 0; ge01r.bitblt.width = width; ge01r.bitblt.height = height; ge02r.whole = 0; ge02r.window.dst_x = dst_x; ge02r.window.dst_y = dst_y; ge09r.whole = 0; ge09r.pack_mono.strt_bit = offset; ge09r.pack_mono.amount = 0; ge09r.pack_mono.bit_spc = 0; ge00r.whole = 0; ge00r.part.rop = ROP_SRCCOPY; ge00r.part.cmd_typ = 2; /* bitblt */ ge00r.part.src_mem = 1; ge00r.part.mon_src = 1; ge00r.part.mod_sel = 1; /* packed mode */ wait_cmd_fifo(fb_info, 6); spin_lock_irqsave(&fb_info->lock, flags); writel(ge01r.whole, GE01R(fb_info)); writel(ge02r.whole, GE02R(fb_info)); writel(fgcol, GE07R(fb_info)); writel(bgcol, GE08R(fb_info)); writel(ge09r.whole, GE09R(fb_info)); writel(ge00r.whole, GE00R(fb_info)); /* ---- */ for (i = 0; i < height; i += 4) { u32 src_data = *(u32*)(image + i); wait_src_fifo(fb_info, 8); writel(src_data, PSF(fb_info)); } spin_unlock_irqrestore(&fb_info->lock, flags);}/**************************************************************** * Hardware Independent Functions. *//**** * Initialization * * [RETURN] * 0: success * minus: fail */int __initmq200fb_init(void){#if 0 int irqval;#endif memset(&mq200fb_info, 0, sizeof mq200fb_info); mq200fb_info.current_par = mq200fb_options.par; if (! mq200fb_conf(&mq200fb_info)) return -ENXIO; mq200_reset(&mq200fb_info); mq200fb_info.disp.scrollmode = SCROLL_YNOMOVE; mq200fb_info.gen.parsize = sizeof(struct mq200fb_par); mq200fb_info.gen.fbhw = &mq200_switch; strcpy(mq200fb_info.gen.info.modename, CHIPNAME); mq200fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT; mq200fb_info.gen.info.fbops = &mq200fb_ops; mq200fb_info.gen.info.disp = &mq200fb_info.disp; strcpy(mq200fb_info.gen.info.fontname, mq200fb_options.font); mq200fb_info.gen.info.switch_con = &fbgen_switch; mq200fb_info.gen.info.updatevar = &fbgen_update_var; mq200fb_info.gen.info.blank = &fbgen_blank; spin_lock_init(&mq200fb_info.lock); fbgen_get_var(&mq200fb_info.disp.var, -1, &mq200fb_info.gen.info); fbgen_do_set_var(&mq200fb_info.disp.var, 1, &mq200fb_info.gen); fbgen_set_disp(-1, &mq200fb_info.gen); fbgen_install_cmap(0, &mq200fb_info.gen); if (register_framebuffer(&mq200fb_info.gen.info) < 0) { printk(KERN_ERR DEVICE_DRIVER_NAME ": unable to register.\n"); return -EINVAL; } printk( KERN_INFO "fb%d: %s, using %uK of video memory.\n", GET_FB_IDX(mq200fb_info.gen.info.node), CHIPNAME, (u32)(mq200fb_info.regions.fb_size >> 10) );#if 0 if ((irqval = request_irq(MQ200_IRQ, mq200_interrupt, 0, CHIPNAME, NULL)) != 0) { printk(CHIPNAME ": unable to get IRQ %d (irqval=%d).\n", MQ200_IRQ, irqval); return -EAGAIN; } mq200_enable_irq(&mq200fb_info);#endif return 0;}/**** * Cleanup */void mq200fb_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 mq200fb_setup(char *options){ /* Parse user speficied options (`video=mq200fb:') */ return 0;}/**** * add cursor timer to timer_list. */static voidadd_cursor_timer(struct mq200fb_cursor_info* cursor_info){ cursor_info->timer.expires = jiffies + CURSOR_BLINK_RATE; add_timer(&cursor_info->timer);}/**************************************************************** * Modularization */#ifdef MODULEintinit_module(void){ return mq200fb_init();}void cleanup_module(void){ mq200fb_cleanup(void);}#endif /* MODULE *//* * Local variables: * c-basic-offset: 4 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -