📄 epson1356fb.c
字号:
}#ifdef SHADOW_FRAME_BUFFER/* * Write BLT the shadow frame buffer to the real fb (timerfunc) */static voiddo_write_shadow_fb(unsigned long ptr){ blt_info_t blt; struct fb_info_e1356 *info = (struct fb_info_e1356*)ptr; struct fb_info* fb = &info->fb_info; struct e1356fb_par* par = &info->current_par; u32 stride = par->width_virt * par->Bpp; unsigned long j_start = jiffies; blt.src_x = blt.src_y = 0; blt.attribute = 0; blt.dst_width = par->width; blt.dst_height = par->height; blt.dst_y = fb->var.yoffset; blt.dst_x = fb->var.xoffset; blt.operation = BLT_WRITE_ROP; blt.rop = 0x0c; // ROP: destination = source blt.src = (u16*)(info->shadow.fb + blt.dst_x * par->Bpp + blt.dst_y * stride); doBlt(par, info, &blt); info->shadow.timer.expires = jiffies+HZ/2; add_timer(&info->shadow.timer); //DPRINTK("delta jiffies = %ld\n", jiffies - j_start);}#endif/* ------------------------------------------------------------------------- * Hardware independent part, interface to the world * ------------------------------------------------------------------------- */static voide1356_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only){ blt_info_t blt; unsigned int cw=fontwidth(p); unsigned int ch=fontheight(p); unsigned int rw=p->var.xres % cw; unsigned int bh=p->var.yres % ch; unsigned int rs=p->var.xres - rw; unsigned int bs=p->var.yres - bh; //DPRINTK("\n"); if (!bottom_only && rw) { blt.dst_x = p->var.xoffset+rs; blt.dst_y = p->var.yoffset; blt.dst_height = p->var.yres; blt.dst_width = rw; blt.attribute = 0; blt.fg_color = 0; blt.operation = BLT_SOLID_FILL; doBlt (&fb_info.current_par, &fb_info, &blt); } if (bh) { blt.dst_x = p->var.xoffset; blt.dst_y = p->var.yoffset+bs; blt.dst_height = bh; blt.dst_width = rs; blt.attribute = 0; blt.fg_color = 0; blt.operation = BLT_SOLID_FILL; doBlt (&fb_info.current_par, &fb_info, &blt); }}static voide1356_cfbX_bmove(struct display* p, int sy, int sx, int dy, int dx, int height, int width){ blt_info_t blt; //DPRINTK("(%d,%d) to (%d,%d) size (%d,%d)\n", sx,sy,dx,dy,width,height); blt.src_x = fontwidth_x8(p)*sx; blt.src_y = fontheight(p)*sy; blt.dst_x = fontwidth_x8(p)*dx; blt.dst_y = fontheight(p)*dy; blt.src_height = blt.dst_height = fontheight(p)*height; blt.src_width = blt.dst_width = fontwidth_x8(p)*width; blt.attribute = 0; blt.rop = 0x0c; /* * The move BLT routine will actually decide between a pos/neg * move BLT. This is just so that the BLT dispatcher knows to * call the move BLT routine. */ blt.operation = BLT_MOVE_POS_ROP; doBlt (&fb_info.current_par, &fb_info, &blt);}static voide1356_cfb8_putc(struct vc_data* conp, struct display* p, int c, int yy,int xx){ blt_info_t blt; u32 fgx,bgx; u32 fw = fontwidth_x8(p); u32 fh = fontheight(p); u16 cs = (u16)c; fgx = attr_fgcol(p, c); bgx = attr_bgcol(p, c); blt.src_x = blt.src_y = 0; blt.attribute = 0; blt.dst_width = fw; blt.dst_height = fh; blt.dst_y = yy * fh; blt.dst_x = xx * fw; blt.bg_color = bgx; blt.fg_color = fgx; blt.operation = BLT_COLOR_EXP; blt.src = fb_info.putcs_buffer; fill_putcs_buffer(p, &blt, &cs, 1); doBlt(&fb_info.current_par, &fb_info, &blt);}static voide1356_cfb16_putc(struct vc_data* conp, struct display* p, int c, int yy,int xx){ blt_info_t blt; u32 fgx,bgx; u32 fw = fontwidth_x8(p); u32 fh = fontheight(p); u16 cs = (u16)c; fgx = ((u16*)p->dispsw_data)[attr_fgcol(p,c)]; bgx = ((u16*)p->dispsw_data)[attr_bgcol(p,c)]; blt.src_x = blt.src_y = 0; blt.attribute = 0; blt.dst_width = fw; blt.dst_height = fh; blt.dst_y = yy * fh; blt.dst_x = xx * fw; blt.bg_color = bgx; blt.fg_color = fgx; blt.operation = BLT_COLOR_EXP; blt.src = fb_info.putcs_buffer; fill_putcs_buffer(p, &blt, &cs, 1); doBlt(&fb_info.current_par, &fb_info, &blt);}static voide1356_cfb8_putcs(struct vc_data* conp, struct display* p, const unsigned short *s,int count,int yy,int xx){ blt_info_t blt; u32 fgx,bgx; u32 fw = fontwidth_x8(p); u32 fh = fontheight(p); //DPRINTK("\n"); fgx=attr_fgcol(p, *s); bgx=attr_bgcol(p, *s); blt.src_x = blt.src_y = 0; blt.attribute = 0; blt.dst_width = count * fw; blt.dst_height = fh; blt.dst_y = yy * fh; blt.dst_x = xx * fw; blt.bg_color = bgx; blt.fg_color = fgx; blt.operation = BLT_COLOR_EXP; blt.src = fb_info.putcs_buffer; fill_putcs_buffer(p, &blt, s, count); doBlt(&fb_info.current_par, &fb_info, &blt);}static voide1356_cfb16_putcs(struct vc_data* conp, struct display* p, const unsigned short *s,int count,int yy,int xx){ blt_info_t blt; u32 fgx,bgx; u32 fw = fontwidth_x8(p); u32 fh = fontheight(p); //DPRINTK("\n"); fgx=((u16*)p->dispsw_data)[attr_fgcol(p,*s)]; bgx=((u16*)p->dispsw_data)[attr_bgcol(p,*s)]; blt.src_x = blt.src_y = 0; blt.attribute = 0; blt.dst_width = count * fw; blt.dst_height = fh; blt.dst_y = yy * fh; blt.dst_x = xx * fw; blt.bg_color = bgx; blt.fg_color = fgx; blt.operation = BLT_COLOR_EXP; blt.src = fb_info.putcs_buffer; fill_putcs_buffer(p, &blt, s, count); doBlt(&fb_info.current_par, &fb_info, &blt);}static voide1356_cfb8_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width){ blt_info_t blt; u32 bg = attr_bgcol_ec(p,conp); //DPRINTK("(%d,%d) size (%d,%d)\n", sx,sy,width,height); blt.dst_x = fontwidth_x8(p)*sx; blt.dst_y = fontheight(p)*sy; blt.dst_height = fontheight(p)*height; blt.dst_width = fontwidth_x8(p)*width; blt.attribute = 0; blt.fg_color = bg; blt.operation = BLT_SOLID_FILL; doBlt (&fb_info.current_par, &fb_info, &blt);}static voide1356_cfb16_clear(struct vc_data* conp, struct display* p, int sy, int sx, int height, int width){ blt_info_t blt; u32 bg = ((u16*)p->dispsw_data)[attr_bgcol_ec(p,conp)]; //DPRINTK("(%d,%d) size (%d,%d)\n", sx,sy,width,height); blt.dst_x = fontwidth_x8(p)*sx; blt.dst_y = fontheight(p)*sy; blt.dst_height = fontheight(p)*height; blt.dst_width = fontwidth_x8(p)*width; blt.attribute = 0; blt.fg_color = bg; blt.operation = BLT_SOLID_FILL; doBlt (&fb_info.current_par, &fb_info, &blt);}static voide1356_cfbX_revc(struct display *p, int xx, int yy){ // not used if h/w cursor //DPRINTK("\n");}static voide1356_cfbX_cursor(struct display *p, int mode, int x, int y) { unsigned long flags; struct fb_info_e1356 *info=(struct fb_info_e1356 *)p->fb_info; reg_inkcurs_t* inkcurs = (IS_PANEL(info->fix.disp_type)) ? info->reg.lcd_inkcurs : info->reg.crttv_inkcurs; //DPRINTK("\n"); if (mode == CM_ERASE) { if (info->cursor.state != CM_ERASE) { spin_lock_irqsave(&info->cursor.lock,flags); info->cursor.state = CM_ERASE; del_timer(&(info->cursor.timer)); writeb(0x00, &inkcurs->ctrl); spin_unlock_irqrestore(&info->cursor.lock,flags); } return; } if ((p->conp->vc_cursor_type & CUR_HWMASK) != info->cursor.type) e1356fb_createcursor(p); x *= fontwidth_x8(p); y *= fontheight(p); x -= p->var.xoffset; y -= p->var.yoffset; spin_lock_irqsave(&info->cursor.lock,flags); if ((x != info->cursor.x) || (y != info->cursor.y) || (info->cursor.redraw)) { info->cursor.x = x; info->cursor.y = y; info->cursor.redraw = 0; writeb(0x01, &inkcurs->ctrl); writew(x, &inkcurs->x_pos0); writew(y, &inkcurs->y_pos0); /* fix cursor color - XFree86 forgets to restore it properly */ writeb(0x00, &inkcurs->blue0); writeb(0x00, &inkcurs->green0); writeb(0x00, &inkcurs->red0); writeb(0x1f, &inkcurs->blue1); writeb(0x3f, &inkcurs->green1); writeb(0x1f, &inkcurs->red1); } info->cursor.state = CM_DRAW; mod_timer(&info->cursor.timer, jiffies+HZ/2); spin_unlock_irqrestore(&info->cursor.lock,flags);}#ifdef FBCON_HAS_CFB8static struct display_switch fbcon_e1356_8 = { setup: fbcon_cfb8_setup, bmove: e1356_cfbX_bmove, clear: e1356_cfb8_clear, putc: e1356_cfb8_putc, putcs: e1356_cfb8_putcs, revc: e1356_cfbX_revc, cursor: e1356_cfbX_cursor, clear_margins: e1356_cfbX_clear_margins, fontwidthmask: FONTWIDTHRANGE(6,16)};#endif#ifdef FBCON_HAS_CFB16static struct display_switch fbcon_e1356_16 = { setup: fbcon_cfb16_setup, bmove: e1356_cfbX_bmove, clear: e1356_cfb16_clear, putc: e1356_cfb16_putc, putcs: e1356_cfb16_putcs, revc: e1356_cfbX_revc, cursor: e1356_cfbX_cursor, clear_margins: e1356_cfbX_clear_margins, fontwidthmask: FONTWIDTHRANGE(6,16)};#endif/* ------------------------------------------------------------------------- */static voide1356fb_set_par(const struct e1356fb_par* par, struct fb_info_e1356* info){ reg_dispcfg_t* dispcfg=NULL; reg_dispmode_t* dispmode=NULL; u8* pclk_cfg=NULL; u8 width, hndp=0, hsync_start=0, hsync_width=0; u8 vndp, vsync_start, vsync_width=0, display_mode; u8 main_display_mode=0; u16 height, addr_offset; int disp_type = info->fix.disp_type; DPRINTK("%dx%d-%dbpp @ %d Hz, %d kHz hsync\n", par->width, par->height, par->bpp, par->vsync_freq, (((2*par->hsync_freq)/1000)+1)/2);#ifdef E1356FB_VERBOSE_DEBUG dump_par(par);#endif info->current_par = *par; width = (par->width >> 3) - 1; display_mode = (par->bpp == 8) ? 0x03 : 0x05; addr_offset = (par->width_virt * par->Bpp) / 2; vsync_start = (disp_type == DISP_TYPE_LCD) ? 0 : par->vsync_start - 1; height = par->height - 1; vndp = par->vert_ndp - 1; switch (disp_type) { case DISP_TYPE_LCD: dispcfg = info->reg.lcd_cfg; dispmode = info->reg.lcd_mode; pclk_cfg = &info->reg.clk_cfg->lcd_pclk_cfg; hndp = (par->horiz_ndp >> 3) - 1; hsync_start = 0; hsync_width = par->hsync_pol ? 0x00 : 0x80; vsync_width = par->vsync_pol ? 0x00 : 0x80; main_display_mode = 0x01; break; case DISP_TYPE_TFT: dispcfg = info->reg.lcd_cfg; dispmode = info->reg.lcd_mode; pclk_cfg = &info->reg.clk_cfg->lcd_pclk_cfg; hndp = (par->horiz_ndp >> 3) - 1; hsync_start = (par->bpp == 8) ? (par->hsync_start - 4) >> 3 : (par->hsync_start - 6) >> 3; hsync_width = (par->hsync_pol ? 0x80 : 0x00) | ((par->hsync_width >> 3) - 1); vsync_width = (par->vsync_pol ? 0x80 : 0x00) | (par->vsync_width - 1); main_display_mode = 0x01; break; case DISP_TYPE_CRT: dispcfg = info->reg.crttv_cfg; dispmode = info->reg.crttv_mode; pclk_cfg = &info->reg.clk_cfg->crttv_pclk_cfg; hndp = (par->horiz_ndp >> 3) - 1; hsync_start = (par->bpp == 8) ? (par->hsync_start - 3) >> 3 : (par->hsync_start - 5) >> 3; hsync_width = (par->hsync_pol ? 0x80 : 0x00) | ((par->hsync_width >> 3) - 1); vsync_width = (par->vsync_pol ? 0x80 : 0x00) | (par->vsync_width - 1); main_display_mode = 0x02; break; case DISP_TYPE_NTSC: case DISP_TYPE_PAL: dispcfg = info->reg.crttv_cfg; dispmode = info->reg.crttv_mode; pclk_cfg = &info->reg.clk_cfg->crttv_pclk_cfg; hndp = (disp_type == DISP_TYPE_PAL) ? (par->horiz_ndp - 7) >> 3 : (par->horiz_ndp - 6) >> 3; hsync_start = (par->bpp == 8) ? (par->hsync_start + 7) >> 3 : (par->hsync_start + 5) >> 3; hsync_width = 0; vsync_width = 0; main_display_mode = (info->fix.tv_filt & TV_FILT_FLICKER) ? 0x06 : 0x04; break; } // Blast the regs! // note: reset panning/scrolling (set start-addr and // pixel pan regs to 0). Panning is handled by pan_display. e1356_engine_wait_complete(info->reg.bitblt); // disable display while initializing writeb(0, &info->reg.misc->disp_mode); writeb(par->ipclk.pixclk_bits, pclk_cfg); writeb(width, &dispcfg->hdw); writeb(hndp, &dispcfg->hndp); writeb(hsync_start, &dispcfg->hsync_start); writeb(hsync_width, &dispcfg->hsync_pulse); writew(height, &dispcfg->vdh0); writeb(vndp, &dispcfg->vndp); writeb(vsync_start, &dispcfg->vsync_start); writeb(vsync_width, &dispcfg->vsync_pulse); writeb(display_mode, &dispmode->disp_mode); if (info->fix.mmunalign && info->mmaped) writeb(1, &dispmode->start_addr0); else writeb(0, &dispmode->start_addr0); writeb(0, &dispmode->start_addr1); writeb(0, &dispmode->start_addr2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -