static void newport_cmap_setrgb(struct newport_devconfig *dc, int index, uint8_t r, uint8_t g, uint8_t b) { rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_2 | REX3_DCBMODE_ENCRSINC | (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) | (CMAP_DCBCRS_ADDRESS_LOW << REX3_DCBMODE_DCBCRS_SHIFT) | (1 << REX3_DCBMODE_CSWIDTH_SHIFT) | (1 << REX3_DCBMODE_CSHOLD_SHIFT) | (1 << REX3_DCBMODE_CSSETUP_SHIFT) | REX3_DCBMODE_SWAPENDIAN); rex3_write(dc, REX3_REG_DCBDATA0, index << 16); rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_3 | (NEWPORT_DCBADDR_CMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) | (CMAP_DCBCRS_PALETTE << REX3_DCBMODE_DCBCRS_SHIFT) | (1 << REX3_DCBMODE_CSWIDTH_SHIFT) | (1 << REX3_DCBMODE_CSHOLD_SHIFT) | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); rex3_write(dc, REX3_REG_DCBDATA0, (r << 24) + (g << 16) + (b << 8)); }
static void newport_setup_hw(struct newport_devconfig *dc) { uint16_t __unused(curp), tmp; int i; uint32_t scratch; /* Get various revisions */ rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_1 | (NEWPORT_DCBADDR_CMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) | (CMAP_DCBCRS_REVISION << REX3_DCBMODE_DCBCRS_SHIFT) | (1 << REX3_DCBMODE_CSWIDTH_SHIFT) | (1 << REX3_DCBMODE_CSHOLD_SHIFT) | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); scratch = vc2_read_ireg(dc, VC2_IREG_CONFIG); dc->dc_vc2rev = (scratch & VC2_IREG_CONFIG_REVISION) >> 5; scratch = rex3_read(dc, REX3_REG_DCBDATA0); dc->dc_boardrev = (scratch >> 28) & 0x07; dc->dc_cmaprev = scratch & 0x07; dc->dc_xmaprev = xmap9_read(dc, XMAP9_DCBCRS_REVISION) & 0x07; dc->dc_depth = ( (dc->dc_boardrev > 1) && (scratch & 0x80)) ? 8 : 24; /* Setup cursor glyph */ curp = vc2_read_ireg(dc, VC2_IREG_CURSOR_ENTRY); /* Setup VC2 to a known state */ tmp = vc2_read_ireg(dc, VC2_IREG_CONTROL) & VC2_CONTROL_INTERLACE; vc2_write_ireg(dc, VC2_IREG_CONTROL, tmp | VC2_CONTROL_DISPLAY_ENABLE | VC2_CONTROL_VTIMING_ENABLE | VC2_CONTROL_DID_ENABLE | VC2_CONTROL_CURSORFUNC_ENABLE /*| VC2_CONTROL_CURSOR_ENABLE*/); /* Setup XMAP9s */ xmap9_write(dc, XMAP9_DCBCRS_CONFIG, XMAP9_CONFIG_8BIT_SYSTEM | XMAP9_CONFIG_RGBMAP_CI); xmap9_write(dc, XMAP9_DCBCRS_CURSOR_CMAP, 0); xmap9_write_mode(dc, 0, XMAP9_MODE_GAMMA_BYPASS | XMAP9_MODE_PIXSIZE_8BPP); xmap9_write(dc, XMAP9_DCBCRS_MODE_SELECT, 0); /* Setup REX3 */ rex3_write(dc, REX3_REG_XYWIN, (4096 << 16) | 4096); rex3_write(dc, REX3_REG_TOPSCAN, 0x3ff); /* XXX Why? XXX */ /* Setup CMAP */ for (i = 0; i < 256; i++) newport_cmap_setrgb(dc, i, rasops_cmap[i * 3], rasops_cmap[i * 3 + 1], rasops_cmap[i * 3 + 2]); }
static void xmap9_write_mode(struct newport_devconfig *dc, uint8_t index, uint32_t mode) { rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_4 | (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) | (XMAP9_DCBCRS_MODE_SETUP << REX3_DCBMODE_DCBCRS_SHIFT) | (3 << REX3_DCBMODE_CSWIDTH_SHIFT) | (2 << REX3_DCBMODE_CSHOLD_SHIFT) | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); rex3_write(dc, REX3_REG_DCBDATA0, (index << 24) | mode); }
static void xmap9_write(struct newport_devconfig *dc, int crs, uint8_t val) { rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_1 | (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) | (crs << REX3_DCBMODE_DCBCRS_SHIFT) | (3 << REX3_DCBMODE_CSWIDTH_SHIFT) | (2 << REX3_DCBMODE_CSHOLD_SHIFT) | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); rex3_write(dc, REX3_REG_DCBDATA0, val << 24); }
static void vc2_write_ireg(struct newport_devconfig *dc, uint8_t ireg, uint16_t val) { rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_3 | REX3_DCBMODE_ENCRSINC | (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) | (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) | REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); rex3_write(dc, REX3_REG_DCBDATA0, (ireg << 24) | (val << 8)); }
static void vc2_write_ram(struct newport_devconfig *dc, uint16_t addr, uint16_t val) { vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr); rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_2 | (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) | (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) | REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); rex3_write(dc, REX3_REG_DCBDATA0, val << 16); }
/**** Helper functions ****/ static void newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2, int y2, uint8_t color) { rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); rex3_write(dc, REX3_REG_COLORI, color); rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1); rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2); }
static void newport_bitblt(struct newport_devconfig *dc, int xs, int ys, int xd, int yd, int wi, int he, int rop) { int xe, ye; uint32_t tmp; rex3_wait_gfifo(dc); if (yd > ys) { /* need to copy bottom up */ ye = ys; yd += he - 1; ys += he - 1; } else ye = ys + he - 1; if (xd > xs) { /* need to copy right to left */ xe = xs; xd += wi - 1; xs += wi - 1; } else xe = xs + wi - 1; rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI | REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED | REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT | REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT | ((rop << 28) & REX3_DRAWMODE1_LOGICOP_MASK)); rex3_write(dc, REX3_REG_XYSTARTI, (xs << REX3_XYSTARTI_XSHIFT) | ys); rex3_write(dc, REX3_REG_XYENDI, (xe << REX3_XYENDI_XSHIFT) | ye); tmp = (yd - ys) & 0xffff; tmp |= (xd - xs) << REX3_XYMOVE_XSHIFT; rex3_write_go(dc, REX3_REG_XYMOVE, tmp); }
static void newport_copy_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2, int y2, int dx, int dy) { uint32_t tmp; rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_SCR2SCR | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1); rex3_write(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2); tmp = (dy - y1) & 0xffff; tmp |= (dx - x1) << REX3_XYMOVE_XSHIFT; rex3_write_go(dc, REX3_REG_XYMOVE, tmp); }
static u_int32_t xmap9_read(struct newport_devconfig *dc, int crs) { rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_1 | (NEWPORT_DCBADDR_XMAP_0 << REX3_DCBMODE_DCBADDR_SHIFT) | (crs << REX3_DCBMODE_DCBCRS_SHIFT) | (3 << REX3_DCBMODE_CSWIDTH_SHIFT) | (2 << REX3_DCBMODE_CSHOLD_SHIFT) | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); return rex3_read(dc, REX3_REG_DCBDATA0); }
static uint16_t vc2_read_ram(struct newport_devconfig *dc, uint16_t addr) { vc2_write_ireg(dc, VC2_IREG_RAM_ADDRESS, addr); rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_2 | (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) | (VC2_DCBCRS_RAM << REX3_DCBMODE_DCBCRS_SHIFT) | REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16); }
static uint16_t vc2_read_ireg(struct newport_devconfig *dc, uint8_t ireg) { rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_1 | REX3_DCBMODE_ENCRSINC | (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) | (VC2_DCBCRS_INDEX << REX3_DCBMODE_DCBCRS_SHIFT) | REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); rex3_write(dc, REX3_REG_DCBDATA0, ireg << 24); rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_2 | REX3_DCBMODE_ENCRSINC | (NEWPORT_DCBADDR_VC2 << REX3_DCBMODE_DCBADDR_SHIFT) | (VC2_DCBCRS_IREG << REX3_DCBMODE_DCBCRS_SHIFT) | REX3_DCBMODE_ENASYNCACK | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); return (uint16_t)(rex3_read(dc, REX3_REG_DCBDATA0) >> 16); }
/**** Helper functions ****/ static void newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2, int y2, uint8_t color) { rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_DOSETUP | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_STOPONY); rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI | REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED | REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT | REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT | REX3_DRAWMODE1_LO_SRC); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); rex3_write(dc, REX3_REG_COLORI, color); rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1); rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2); }
static void newport_putchar(void *c, int row, int col, u_int ch, long attr) { struct rasops_info *ri = c; struct vcons_screen *scr = ri->ri_hw; struct newport_devconfig *dc = scr->scr_cookie; struct wsdisplay_font *font = ri->ri_font; uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) * font->fontheight * font->stride; uint32_t pattern; int i; int x = col * font->fontwidth + ri->ri_xorigin; int y = row * font->fontheight + ri->ri_yorigin; rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE); rex3_write(dc, REX3_REG_DRAWMODE1, REX3_DRAWMODE1_PLANES_CI | REX3_DRAWMODE1_DD_DD8 | REX3_DRAWMODE1_RWPACKED | REX3_DRAWMODE1_HD_HD8 | REX3_DRAWMODE1_COMPARE_LT | REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT | REX3_DRAWMODE1_LO_SRC); rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y); rex3_write(dc, REX3_REG_XYENDI, (x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT); rex3_write(dc, REX3_REG_COLORI, NEWPORT_ATTR_FG(attr)); rex3_write(dc, REX3_REG_COLORBACK, NEWPORT_ATTR_BG(attr)); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); for (i = 0; i < font->fontheight; i++) { /* XXX Works only with font->fontwidth == 8 XXX */ pattern = *bitmap << 24; rex3_write_go(dc, REX3_REG_ZPATTERN, pattern); bitmap += font->stride; } rex3_wait_gfifo(dc); }
static void newport_putchar(void *c, int row, int col, u_int ch, long attr) { struct newport_devconfig *dc = (void *)c; struct wsdisplay_font *font = dc->dc_fontdata; uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) * font->fontheight * font->stride; uint32_t pattern; int i; int x = col * font->fontwidth; int y = row * font->fontheight; rex3_wait_gfifo(dc); rex3_write(dc, REX3_REG_DRAWMODE0, REX3_DRAWMODE0_OPCODE_DRAW | REX3_DRAWMODE0_ADRMODE_BLOCK | REX3_DRAWMODE0_STOPONX | REX3_DRAWMODE0_ENZPATTERN | REX3_DRAWMODE0_ZPOPAQUE); rex3_write(dc, REX3_REG_XYSTARTI, (x << REX3_XYSTARTI_XSHIFT) | y); rex3_write(dc, REX3_REG_XYENDI, (x + font->fontwidth - 1) << REX3_XYENDI_XSHIFT); rex3_write(dc, REX3_REG_COLORI, NEWPORT_ATTR_FG(attr)); rex3_write(dc, REX3_REG_COLORBACK, NEWPORT_ATTR_BG(attr)); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); for (i=0; i<font->fontheight; i++) { /* XXX Works only with font->fontwidth == 8 XXX */ pattern = *bitmap << 24; rex3_write_go(dc, REX3_REG_ZPATTERN, pattern); bitmap += font->stride; } }
static void rex3_write_go(struct newport_devconfig *dc, bus_size_t rexreg, uint32_t val) { rex3_write(dc, rexreg + REX3_REG_GO, val); }