📄 stifb.c
字号:
CRX24_SETUP_RAMDAC(fb); /* replacement for: SETUP_FB(fb, CRX24_OVERLAY_PLANES); */ WRITE_WORD(0x83000300, fb, REG_14); SETUP_HW(fb); WRITE_BYTE(1, fb, REG_16b1); /* XXX: replace by fb_setmem(), smem_start or screen_base ? */ memset_io(fb->fix.smem_start, 0xff, fb->var.yres*fb->fix.line_length); CRX24_SET_OVLY_MASK(fb); SETUP_FB(fb);}#define HYPER_CMAP_TYPE 0#define NGLE_CMAP_INDEXED0_TYPE 0#define NGLE_CMAP_OVERLAY_TYPE 3/* typedef of LUT (Colormap) BLT Control Register */typedef union /* Note assumption that fields are packed left-to-right */{ u32 all; struct { unsigned enable : 1; unsigned waitBlank : 1; unsigned reserved1 : 4; unsigned lutOffset : 10; /* Within destination LUT */ unsigned lutType : 2; /* Cursor, image, overlay */ unsigned reserved2 : 4; unsigned length : 10; } fields;} NgleLutBltCtl;#if 0static NgleLutBltCtlsetNgleLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length){ NgleLutBltCtl lutBltCtl; /* set enable, zero reserved fields */ lutBltCtl.all = 0x80000000; lutBltCtl.fields.length = length; switch (fb->id) { case S9000_ID_A1439A: /* CRX24 */ if (fb->var.bits_per_pixel == 8) { lutBltCtl.fields.lutType = NGLE_CMAP_OVERLAY_TYPE; lutBltCtl.fields.lutOffset = 0; } else { lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE; lutBltCtl.fields.lutOffset = 0 * 256; } break; case S9000_ID_ARTIST: lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE; lutBltCtl.fields.lutOffset = 0 * 256; break; default: lutBltCtl.fields.lutType = NGLE_CMAP_INDEXED0_TYPE; lutBltCtl.fields.lutOffset = 0; break; } /* Offset points to start of LUT. Adjust for within LUT */ lutBltCtl.fields.lutOffset += offsetWithinLut; return lutBltCtl;}#endifstatic NgleLutBltCtlsetHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length) { NgleLutBltCtl lutBltCtl; /* set enable, zero reserved fields */ lutBltCtl.all = 0x80000000; lutBltCtl.fields.length = length; lutBltCtl.fields.lutType = HYPER_CMAP_TYPE; /* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */ if (fb->var.bits_per_pixel == 8) lutBltCtl.fields.lutOffset = 2 * 256; else lutBltCtl.fields.lutOffset = 0 * 256; /* Offset points to start of LUT. Adjust for within LUT */ lutBltCtl.fields.lutOffset += offsetWithinLut; return lutBltCtl;}static void hyperUndoITE(struct stifb_info *fb){ int nFreeFifoSlots = 0; u32 fbAddr; NGLE_LOCK(fb); GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1); WRITE_WORD(0xffffffff, fb, REG_32); /* Write overlay transparency mask so only entry 255 is transparent */ /* Hardware setup for full-depth write to "magic" location */ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7); NGLE_QUICK_SET_DST_BM_ACCESS(fb, BA(IndexedDcd, Otc04, Ots08, AddrLong, BAJustPoint(0), BINovly, BAIndexBase(0))); NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, IBOvals(RopSrc, MaskAddrOffset(0), BitmapExtent08, StaticReg(0), DataDynamic, MaskOtc, BGx(0), FGx(0))); /* Now prepare to write to the "magic" location */ fbAddr = NGLE_LONG_FB_ADDRESS(0, 1532, 0); NGLE_BINC_SET_DSTADDR(fb, fbAddr); NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffff); NGLE_BINC_SET_DSTMASK(fb, 0xffffffff); /* Finally, write a zero to clear the mask */ NGLE_BINC_WRITE32(fb, 0); NGLE_UNLOCK(fb);}static void ngleDepth8_ClearImagePlanes(struct stifb_info *fb){ /* FIXME! */}static void ngleDepth24_ClearImagePlanes(struct stifb_info *fb){ /* FIXME! */}static voidngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg){ int nFreeFifoSlots = 0; u32 packed_dst; u32 packed_len; NGLE_LOCK(fb); GET_FIFO_SLOTS(fb, nFreeFifoSlots, 4); NGLE_QUICK_SET_DST_BM_ACCESS(fb, BA(IndexedDcd, Otc32, OtsIndirect, AddrLong, BAJustPoint(0), BINattr, BAIndexBase(0))); NGLE_QUICK_SET_CTL_PLN_REG(fb, ctlPlaneReg); NGLE_SET_TRANSFERDATA(fb, 0xffffffff); NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, IBOvals(RopSrc, MaskAddrOffset(0), BitmapExtent08, StaticReg(1), DataDynamic, MaskOtc, BGx(0), FGx(0))); packed_dst = 0; packed_len = (fb->var.xres << 16) | fb->var.yres; GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2); NGLE_SET_DSTXY(fb, packed_dst); SET_LENXY_START_RECFILL(fb, packed_len); /* * In order to work around an ELK hardware problem (Buffy doesn't * always flush it's buffers when writing to the attribute * planes), at least 4 pixels must be written to the attribute * planes starting at (X == 1280) and (Y != to the last Y written * by BIF): */ if (fb->id == S9000_ID_A1659A) { /* ELK_DEVICE_ID */ /* It's safe to use scanline zero: */ packed_dst = (1280 << 16); GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2); NGLE_SET_DSTXY(fb, packed_dst); packed_len = (4 << 16) | 1; SET_LENXY_START_RECFILL(fb, packed_len); } /* ELK Hardware Kludge */ /**** Finally, set the Control Plane Register back to zero: ****/ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 1); NGLE_QUICK_SET_CTL_PLN_REG(fb, 0); NGLE_UNLOCK(fb);} static voidngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data){ int nFreeFifoSlots = 0; u32 packed_dst; u32 packed_len; NGLE_LOCK(fb); /* Hardware setup */ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 8); NGLE_QUICK_SET_DST_BM_ACCESS(fb, BA(IndexedDcd, Otc04, Ots08, AddrLong, BAJustPoint(0), BINovly, BAIndexBase(0))); NGLE_SET_TRANSFERDATA(fb, 0xffffffff); /* Write foreground color */ NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, data); NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask); packed_dst = 0; packed_len = (fb->var.xres << 16) | fb->var.yres; NGLE_SET_DSTXY(fb, packed_dst); /* Write zeroes to overlay planes */ NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, IBOvals(RopSrc, MaskAddrOffset(0), BitmapExtent08, StaticReg(0), DataDynamic, MaskOtc, BGx(0), FGx(0))); SET_LENXY_START_RECFILL(fb, packed_len); NGLE_UNLOCK(fb);}static void hyperResetPlanes(struct stifb_info *fb, int enable){ unsigned int controlPlaneReg; NGLE_LOCK(fb); if (IS_24_DEVICE(fb)) if (fb->var.bits_per_pixel == 32) controlPlaneReg = 0x04000F00; else controlPlaneReg = 0x00000F00; /* 0x00000800 should be enought, but lets clear all 4 bits */ else controlPlaneReg = 0x00000F00; /* 0x00000100 should be enought, but lets clear all 4 bits */ switch (enable) { case 1: /* ENABLE */ /* clear screen */ if (IS_24_DEVICE(fb)) ngleDepth24_ClearImagePlanes(fb); else ngleDepth8_ClearImagePlanes(fb); /* Paint attribute planes for default case. * On Hyperdrive, this means all windows using overlay cmap 0. */ ngleResetAttrPlanes(fb, controlPlaneReg); /* clear overlay planes */ ngleClearOverlayPlanes(fb, 0xff, 255); /************************************************** ** Also need to counteract ITE settings **************************************************/ hyperUndoITE(fb); break; case 0: /* DISABLE */ /* clear screen */ if (IS_24_DEVICE(fb)) ngleDepth24_ClearImagePlanes(fb); else ngleDepth8_ClearImagePlanes(fb); ngleResetAttrPlanes(fb, controlPlaneReg); ngleClearOverlayPlanes(fb, 0xff, 0); break; case -1: /* RESET */ hyperUndoITE(fb); ngleResetAttrPlanes(fb, controlPlaneReg); break; } NGLE_UNLOCK(fb);}/* Return pointer to in-memory structure holding ELK device-dependent ROM values. */static void ngleGetDeviceRomData(struct stifb_info *fb){#if 0XXX: FIXME: !!! int *pBytePerLongDevDepData;/* data byte == LSB */ int *pRomTable; NgleDevRomData *pPackedDevRomData; int sizePackedDevRomData = sizeof(*pPackedDevRomData); char *pCard8; int i; char *mapOrigin = NULL; int romTableIdx; pPackedDevRomData = fb->ngle_rom; SETUP_HW(fb); if (fb->id == S9000_ID_ARTIST) { pPackedDevRomData->cursor_pipeline_delay = 4; pPackedDevRomData->video_interleaves = 4; } else { /* Get pointer to unpacked byte/long data in ROM */ pBytePerLongDevDepData = fb->sti->regions[NGLEDEVDEPROM_CRT_REGION]; /* Tomcat supports several resolutions: 1280x1024, 1024x768, 640x480 */ if (fb->id == S9000_ID_TOMCAT) { /* jump to the correct ROM table */ GET_ROMTABLE_INDEX(romTableIdx); while (romTableIdx > 0) { pCard8 = (Card8 *) pPackedDevRomData; pRomTable = pBytePerLongDevDepData; /* Pack every fourth byte from ROM into structure */ for (i = 0; i < sizePackedDevRomData; i++) { *pCard8++ = (Card8) (*pRomTable++); } pBytePerLongDevDepData = (Card32 *) ((Card8 *) pBytePerLongDevDepData + pPackedDevRomData->sizeof_ngle_data); romTableIdx--; } } pCard8 = (Card8 *) pPackedDevRomData; /* Pack every fourth byte from ROM into structure */ for (i = 0; i < sizePackedDevRomData; i++) { *pCard8++ = (Card8) (*pBytePerLongDevDepData++); } } SETUP_FB(fb);#endif}#define HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES 4#define HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE 8#define HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE 10#define HYPERBOWL_MODE2_8_24 15/* HCRX specific boot-time initialization */static void __initSETUP_HCRX(struct stifb_info *fb){ int hyperbowl; int nFreeFifoSlots = 0; if (fb->id != S9000_ID_HCRX) return; /* Initialize Hyperbowl registers */ GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7); if (IS_24_DEVICE(fb)) { hyperbowl = (fb->var.bits_per_pixel == 32) ? HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE : HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE; /* First write to Hyperbowl must happen twice (bug) */ WRITE_WORD(hyperbowl, fb, REG_40); WRITE_WORD(hyperbowl, fb, REG_40); WRITE_WORD(HYPERBOWL_MODE2_8_24, fb, REG_39); WRITE_WORD(0x014c0148, fb, REG_42); /* Set lut 0 to be the direct color */ WRITE_WORD(0x404c4048, fb, REG_43); WRITE_WORD(0x034c0348, fb, REG_44); WRITE_WORD(0x444c4448, fb, REG_45); } else { hyperbowl = HYPERBOWL_MODE_FOR_8_OVER_88_LUT0_NO_TRANSPARENCIES; /* First write to Hyperbowl must happen twice (bug) */ WRITE_WORD(hyperbowl, fb, REG_40); WRITE_WORD(hyperbowl, fb, REG_40); WRITE_WORD(0x00000000, fb, REG_42); WRITE_WORD(0x00000000, fb, REG_43); WRITE_WORD(0x00000000, fb, REG_44); WRITE_WORD(0x444c4048, fb, REG_45); }}/* ------------------- driver specific functions --------------------------- */static intstifb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info){ struct stifb_info *fb = (struct stifb_info *) info; if (regno > 255) return 1; *red = (fb->palette[regno].red<<8) | fb->palette[regno].red; *green = (fb->palette[regno].green<<8) | fb->palette[regno].green; *blue = (fb->palette[regno].blue<<8) | fb->palette[regno].blue; *transp = 0; return 0;}static intstifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info){ struct stifb_info *fb = (struct stifb_info *) info; if (regno > 255) return 1; red >>= 8; green >>= 8; blue >>= 8; if ((fb->palette[regno].red != red) || (fb->palette[regno].green != green) || (fb->palette[regno].blue != blue)) fb->cmap_reload = 1; fb->palette[regno].red = red; fb->palette[regno].green = green; fb->palette[regno].blue = blue; #ifdef FBCON_HAS_CFB32 if (regno < 16 && fb->var.bits_per_pixel == 32) { fb->fbcon_cmap.cfb32[regno] = ((red << 16) | (green << 8) | (blue << 0) | (transp << 24)); }#endif return 0;}static voidstifb_loadcmap(struct stifb_info *fb){ u32 color; int i; if (!fb->cmap_reload) return; START_IMAGE_COLORMAP_ACCESS(fb); for (i = 0; i < 256; i++) { if (fb->var.bits_per_pixel > 8) { color = (i << 16) | (i << 8) | i; } else { if (fb->var.grayscale) { /* gray = 0.30*R + 0.59*G + 0.11*B */ color = ((fb->palette[i].red * 77) + (fb->palette[i].green * 151) + (fb->palette[i].blue * 28)) >> 8; } else { color = ((fb->palette[i].red << 16) | (fb->palette[i].green << 8) | (fb->palette[i].blue)); } } WRITE_IMAGE_COLOR(fb, i, color); } if (fb->id == S9000_ID_HCRX) { NgleLutBltCtl lutBltCtl; lutBltCtl = setHyperLutBltCtl(fb, 0, /* Offset w/i LUT */ 256); /* Load entire LUT */ NGLE_BINC_SET_SRCADDR(fb, NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); /* 0x100 is same as used in WRITE_IMAGE_COLOR() */ START_COLORMAPLOAD(fb, lutBltCtl.all); SETUP_FB(fb); } else { /* cleanup colormap hardware */ FINISH_IMAGE_COLORMAP_ACCESS(fb); } fb->cmap_reload = 0;}static intstifb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ memcpy (fix, &((struct stifb_info *)info)->fix, sizeof (*fix)); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -