📄 creatorfb.c
字号:
/* $Id: creatorfb.c,v 1.37 2001/10/16 05:44:44 davem Exp $ * creatorfb.c: Creator/Creator3D frame buffer driver * * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) */#include <linux/module.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/selection.h>#include <video/sbusfb.h>#include <asm/upa.h>#define FFB_SFB8R_VOFF 0x00000000#define FFB_SFB8G_VOFF 0x00400000#define FFB_SFB8B_VOFF 0x00800000#define FFB_SFB8X_VOFF 0x00c00000#define FFB_SFB32_VOFF 0x01000000#define FFB_SFB64_VOFF 0x02000000#define FFB_FBC_REGS_VOFF 0x04000000#define FFB_BM_FBC_REGS_VOFF 0x04002000#define FFB_DFB8R_VOFF 0x04004000#define FFB_DFB8G_VOFF 0x04404000#define FFB_DFB8B_VOFF 0x04804000#define FFB_DFB8X_VOFF 0x04c04000#define FFB_DFB24_VOFF 0x05004000#define FFB_DFB32_VOFF 0x06004000#define FFB_DFB422A_VOFF 0x07004000 /* DFB 422 mode write to A */#define FFB_DFB422AD_VOFF 0x07804000 /* DFB 422 mode with line doubling */#define FFB_DFB24B_VOFF 0x08004000 /* DFB 24bit mode write to B */#define FFB_DFB422B_VOFF 0x09004000 /* DFB 422 mode write to B */#define FFB_DFB422BD_VOFF 0x09804000 /* DFB 422 mode with line doubling */#define FFB_SFB16Z_VOFF 0x0a004000 /* 16bit mode Z planes */#define FFB_SFB8Z_VOFF 0x0a404000 /* 8bit mode Z planes */#define FFB_SFB422_VOFF 0x0ac04000 /* SFB 422 mode write to A/B */#define FFB_SFB422D_VOFF 0x0b404000 /* SFB 422 mode with line doubling */#define FFB_FBC_KREGS_VOFF 0x0bc04000#define FFB_DAC_VOFF 0x0bc06000#define FFB_PROM_VOFF 0x0bc08000#define FFB_EXP_VOFF 0x0bc18000#define FFB_SFB8R_POFF 0x04000000UL#define FFB_SFB8G_POFF 0x04400000UL#define FFB_SFB8B_POFF 0x04800000UL#define FFB_SFB8X_POFF 0x04c00000UL#define FFB_SFB32_POFF 0x05000000UL#define FFB_SFB64_POFF 0x06000000UL#define FFB_FBC_REGS_POFF 0x00600000UL#define FFB_BM_FBC_REGS_POFF 0x00600000UL#define FFB_DFB8R_POFF 0x01000000UL#define FFB_DFB8G_POFF 0x01400000UL#define FFB_DFB8B_POFF 0x01800000UL#define FFB_DFB8X_POFF 0x01c00000UL#define FFB_DFB24_POFF 0x02000000UL#define FFB_DFB32_POFF 0x03000000UL#define FFB_FBC_KREGS_POFF 0x00610000UL#define FFB_DAC_POFF 0x00400000UL#define FFB_PROM_POFF 0x00000000UL#define FFB_EXP_POFF 0x00200000UL#define FFB_DFB422A_POFF 0x09000000UL#define FFB_DFB422AD_POFF 0x09800000UL#define FFB_DFB24B_POFF 0x0a000000UL#define FFB_DFB422B_POFF 0x0b000000UL#define FFB_DFB422BD_POFF 0x0b800000UL#define FFB_SFB16Z_POFF 0x0c800000UL#define FFB_SFB8Z_POFF 0x0c000000UL#define FFB_SFB422_POFF 0x0d000000UL#define FFB_SFB422D_POFF 0x0d800000UL/* Draw operations */#define FFB_DRAWOP_DOT 0x00#define FFB_DRAWOP_AADOT 0x01#define FFB_DRAWOP_BRLINECAP 0x02#define FFB_DRAWOP_BRLINEOPEN 0x03#define FFB_DRAWOP_DDLINE 0x04#define FFB_DRAWOP_AALINE 0x05#define FFB_DRAWOP_TRIANGLE 0x06#define FFB_DRAWOP_POLYGON 0x07#define FFB_DRAWOP_RECTANGLE 0x08#define FFB_DRAWOP_FASTFILL 0x09#define FFB_DRAWOP_BCOPY 0x0a#define FFB_DRAWOP_VSCROLL 0x0b/* Pixel processor control *//* Force WID */#define FFB_PPC_FW_DISABLE 0x800000#define FFB_PPC_FW_ENABLE 0xc00000/* Auxiliary clip */#define FFB_PPC_ACE_DISABLE 0x040000#define FFB_PPC_ACE_AUX_SUB 0x080000#define FFB_PPC_ACE_AUX_ADD 0x0c0000/* Depth cue */#define FFB_PPC_DCE_DISABLE 0x020000#define FFB_PPC_DCE_ENABLE 0x030000/* Alpha blend */#define FFB_PPC_ABE_DISABLE 0x008000#define FFB_PPC_ABE_ENABLE 0x00c000/* View clip */#define FFB_PPC_VCE_DISABLE 0x001000#define FFB_PPC_VCE_2D 0x002000#define FFB_PPC_VCE_3D 0x003000/* Area pattern */#define FFB_PPC_APE_DISABLE 0x000800#define FFB_PPC_APE_ENABLE 0x000c00/* Transparent background */#define FFB_PPC_TBE_OPAQUE 0x000200#define FFB_PPC_TBE_TRANSPARENT 0x000300/* Z source */#define FFB_PPC_ZS_VAR 0x000080#define FFB_PPC_ZS_CONST 0x0000c0/* Y source */#define FFB_PPC_YS_VAR 0x000020#define FFB_PPC_YS_CONST 0x000030/* X source */#define FFB_PPC_XS_WID 0x000004#define FFB_PPC_XS_VAR 0x000008#define FFB_PPC_XS_CONST 0x00000c/* Color (BGR) source */#define FFB_PPC_CS_VAR 0x000002#define FFB_PPC_CS_CONST 0x000003#define FFB_ROP_NEW 0x83#define FFB_UCSR_FIFO_MASK 0x00000fff#define FFB_UCSR_FB_BUSY 0x01000000#define FFB_UCSR_RP_BUSY 0x02000000#define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)#define FFB_UCSR_READ_ERR 0x40000000#define FFB_UCSR_FIFO_OVFL 0x80000000#define FFB_UCSR_ALL_ERRORS (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)struct ffb_fbc { /* Next vertex registers */ u32 xxx1[3]; volatile u32 alpha; volatile u32 red; volatile u32 green; volatile u32 blue; volatile u32 depth; volatile u32 y; volatile u32 x; u32 xxx2[2]; volatile u32 ryf; volatile u32 rxf; u32 xxx3[2]; volatile u32 dmyf; volatile u32 dmxf; u32 xxx4[2]; volatile u32 ebyi; volatile u32 ebxi; u32 xxx5[2]; volatile u32 by; volatile u32 bx; u32 dy; u32 dx; volatile u32 bh; volatile u32 bw; u32 xxx6[2]; u32 xxx7[32]; /* Setup unit vertex state register */ volatile u32 suvtx; u32 xxx8[63]; /* Control registers */ volatile u32 ppc; volatile u32 wid; volatile u32 fg; volatile u32 bg; volatile u32 consty; volatile u32 constz; volatile u32 xclip; volatile u32 dcss; volatile u32 vclipmin; volatile u32 vclipmax; volatile u32 vclipzmin; volatile u32 vclipzmax; volatile u32 dcsf; volatile u32 dcsb; volatile u32 dczf; volatile u32 dczb; u32 xxx9; volatile u32 blendc; volatile u32 blendc1; volatile u32 blendc2; volatile u32 fbramitc; volatile u32 fbc; volatile u32 rop; volatile u32 cmp; volatile u32 matchab; volatile u32 matchc; volatile u32 magnab; volatile u32 magnc; volatile u32 fbcfg0; volatile u32 fbcfg1; volatile u32 fbcfg2; volatile u32 fbcfg3; u32 ppcfg; volatile u32 pick; volatile u32 fillmode; volatile u32 fbramwac; volatile u32 pmask; volatile u32 xpmask; volatile u32 ypmask; volatile u32 zpmask; volatile u32 clip0min; volatile u32 clip0max; volatile u32 clip1min; volatile u32 clip1max; volatile u32 clip2min; volatile u32 clip2max; volatile u32 clip3min; volatile u32 clip3max; /* New 3dRAM III support regs */ volatile u32 rawblend2; volatile u32 rawpreblend; volatile u32 rawstencil; volatile u32 rawstencilctl; volatile u32 threedram1; volatile u32 threedram2; volatile u32 passin; volatile u32 rawclrdepth; volatile u32 rawpmask; volatile u32 rawcsrc; volatile u32 rawmatch; volatile u32 rawmagn; volatile u32 rawropblend; volatile u32 rawcmp; volatile u32 rawwac; volatile u32 fbramid; volatile u32 drawop; u32 xxx10[2]; volatile u32 fontlpat; u32 xxx11; volatile u32 fontxy; volatile u32 fontw; volatile u32 fontinc; volatile u32 font; u32 xxx12[3]; volatile u32 blend2; volatile u32 preblend; volatile u32 stencil; volatile u32 stencilctl; u32 xxx13[4]; volatile u32 dcss1; volatile u32 dcss2; volatile u32 dcss3; volatile u32 widpmask; volatile u32 dcs2; volatile u32 dcs3; volatile u32 dcs4; u32 xxx14; volatile u32 dcd2; volatile u32 dcd3; volatile u32 dcd4; u32 xxx15; volatile u32 pattern[32]; u32 xxx16[256]; volatile u32 devid; u32 xxx17[63]; volatile u32 ucsr; u32 xxx18[31]; volatile u32 mer;};static __inline__ void FFBFifo(struct fb_info_sbusfb *fb, int n){ struct ffb_fbc *fbc; int cache = fb->s.ffb.fifo_cache; if (cache - n < 0) { fbc = fb->s.ffb.fbc; do { cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK) - 8; } while (cache - n < 0); } fb->s.ffb.fifo_cache = cache - n;}static __inline__ void FFBWait(struct ffb_fbc *ffb){ int limit = 10000; do { if ((upa_readl(&ffb->ucsr) & FFB_UCSR_ALL_BUSY) == 0) break; if ((upa_readl(&ffb->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) { upa_writel(FFB_UCSR_ALL_ERRORS, &ffb->ucsr); } } while(--limit > 0);}struct ffb_dac { volatile u32 type; volatile u32 value; volatile u32 type2; volatile u32 value2;};static struct sbus_mmap_map ffb_mmap_map[] = { { FFB_SFB8R_VOFF, FFB_SFB8R_POFF, 0x0400000 }, { FFB_SFB8G_VOFF, FFB_SFB8G_POFF, 0x0400000 }, { FFB_SFB8B_VOFF, FFB_SFB8B_POFF, 0x0400000 }, { FFB_SFB8X_VOFF, FFB_SFB8X_POFF, 0x0400000 }, { FFB_SFB32_VOFF, FFB_SFB32_POFF, 0x1000000 }, { FFB_SFB64_VOFF, FFB_SFB64_POFF, 0x2000000 }, { FFB_FBC_REGS_VOFF, FFB_FBC_REGS_POFF, 0x0002000 }, { FFB_BM_FBC_REGS_VOFF, FFB_BM_FBC_REGS_POFF, 0x0002000 }, { FFB_DFB8R_VOFF, FFB_DFB8R_POFF, 0x0400000 }, { FFB_DFB8G_VOFF, FFB_DFB8G_POFF, 0x0400000 }, { FFB_DFB8B_VOFF, FFB_DFB8B_POFF, 0x0400000 }, { FFB_DFB8X_VOFF, FFB_DFB8X_POFF, 0x0400000 }, { FFB_DFB24_VOFF, FFB_DFB24_POFF, 0x1000000 }, { FFB_DFB32_VOFF, FFB_DFB32_POFF, 0x1000000 }, { FFB_FBC_KREGS_VOFF, FFB_FBC_KREGS_POFF, 0x0002000 }, { FFB_DAC_VOFF, FFB_DAC_POFF, 0x0002000 }, { FFB_PROM_VOFF, FFB_PROM_POFF, 0x0010000 }, { FFB_EXP_VOFF, FFB_EXP_POFF, 0x0002000 }, { FFB_DFB422A_VOFF, FFB_DFB422A_POFF, 0x0800000 }, { FFB_DFB422AD_VOFF, FFB_DFB422AD_POFF, 0x0800000 }, { FFB_DFB24B_VOFF, FFB_DFB24B_POFF, 0x1000000 }, { FFB_DFB422B_VOFF, FFB_DFB422B_POFF, 0x0800000 }, { FFB_DFB422BD_VOFF, FFB_DFB422BD_POFF, 0x0800000 }, { FFB_SFB16Z_VOFF, FFB_SFB16Z_POFF, 0x0800000 }, { FFB_SFB8Z_VOFF, FFB_SFB8Z_POFF, 0x0800000 }, { FFB_SFB422_VOFF, FFB_SFB422_POFF, 0x0800000 }, { FFB_SFB422D_VOFF, FFB_SFB422D_POFF, 0x0800000 }, { 0, 0, 0 }};static void ffb_setup(struct display *p){ p->next_line = 8192; p->next_plane = 0;}static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width){ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info; register struct ffb_fbc *fbc = fb->s.ffb.fbc; unsigned long flags; u64 yx, hw; int fg; spin_lock_irqsave(&fb->lock, flags); fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)]; if (fg != fb->s.ffb.fg_cache) { FFBFifo(fb, 5); upa_writel(fg, &fbc->fg); fb->s.ffb.fg_cache = fg; } else FFBFifo(fb, 4); if (fontheightlog(p)) { yx = (u64)sy << (fontheightlog(p) + 32); hw = (u64)height << (fontheightlog(p) + 32); } else { yx = (u64)(sy * fontheight(p)) << 32; hw = (u64)(height * fontheight(p)) << 32; } if (fontwidthlog(p)) { yx += sx << fontwidthlog(p); hw += width << fontwidthlog(p); } else { yx += sx * fontwidth(p); hw += width * fontwidth(p); } upa_writeq(yx + fb->s.ffb.yx_margin, &fbc->by); upa_writeq(hw, &fbc->bh); spin_unlock_irqrestore(&fb->lock, flags);}static void ffb_fill(struct fb_info_sbusfb *fb, struct display *p, int s, int count, unsigned short *boxes){ register struct ffb_fbc *fbc = fb->s.ffb.fbc; unsigned long flags; int fg; spin_lock_irqsave(&fb->lock, flags); fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)]; if (fg != fb->s.ffb.fg_cache) { FFBFifo(fb, 1); upa_writel(fg, &fbc->fg); fb->s.ffb.fg_cache = fg; } while (count-- > 0) { FFBFifo(fb, 4); upa_writel(boxes[1], &fbc->by); upa_writel(boxes[0], &fbc->bx); upa_writel(boxes[3] - boxes[1], &fbc->bh); upa_writel(boxes[2] - boxes[0], &fbc->bw); boxes += 4; } spin_unlock_irqrestore(&fb->lock, flags);}static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx){ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info; register struct ffb_fbc *fbc = fb->s.ffb.fbc; unsigned long flags; int i, xy; u8 *fd; u64 fgbg; spin_lock_irqsave(&fb->lock, flags); if (fontheightlog(p)) { xy = (yy << (16 + fontheightlog(p))); i = ((c & p->charmask) << fontheightlog(p)); } else { xy = ((yy * fontheight(p)) << 16); i = (c & p->charmask) * fontheight(p); } if (fontwidth(p) <= 8) fd = p->fontdata + i; else fd = p->fontdata + (i << 1); if (fontwidthlog(p)) xy += (xx << fontwidthlog(p)) + fb->s.ffb.xy_margin; else xy += (xx * fontwidth(p)) + fb->s.ffb.xy_margin; fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p,c)])) << 32) | ((u32 *)p->dispsw_data)[attr_bgcol(p,c)]; if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) { FFBFifo(fb, 2); upa_writeq(fgbg, &fbc->fg); *(u64 *)&fb->s.ffb.fg_cache = fgbg; } FFBFifo(fb, 2 + fontheight(p)); upa_writel(xy, &fbc->fontxy); upa_writel(fontwidth(p), &fbc->fontw); if (fontwidth(p) <= 8) { for (i = 0; i < fontheight(p); i++) { u32 val = *fd++ << 24; upa_writel(val, &fbc->font); } } else { for (i = 0; i < fontheight(p); i++) { u32 val = *(u16 *)fd << 16; upa_writel(val, &fbc->font); fd += 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -