Module Name: src Committed By: macallan Date: Fri May 10 23:21:42 UTC 2019
Modified Files: src/sys/arch/sgimips/gio: newport.c Log Message: general overhaul, in no particular order: - use MIPS_PHYS_TO_KSEG1() - get rid of duplicated rasops_allocattr() and _mapchar() methods - use rasops_init() - support fonts that aren't 8x16 - use fastclear mode for rectangle fills - don't mess with XMAP9's config register - initialize all 32 XMAP9 mode registers, just in case - make newport_fill_rectangle() use x, y, wi, he like everyone else - use R3G3B2 palette in preparation for alpha font support To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/arch/sgimips/gio/newport.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sgimips/gio/newport.c diff -u src/sys/arch/sgimips/gio/newport.c:1.19 src/sys/arch/sgimips/gio/newport.c:1.20 --- src/sys/arch/sgimips/gio/newport.c:1.19 Tue Aug 25 02:09:18 2015 +++ src/sys/arch/sgimips/gio/newport.c Fri May 10 23:21:42 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: newport.c,v 1.19 2015/08/25 02:09:18 macallan Exp $ */ +/* $NetBSD: newport.c,v 1.20 2019/05/10 23:21:42 macallan Exp $ */ /* * Copyright (c) 2003 Ilpo Ruotsalainen @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.19 2015/08/25 02:09:18 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: newport.c,v 1.20 2019/05/10 23:21:42 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -73,7 +73,6 @@ struct newport_devconfig { int dc_font; struct wsscreen_descr *dc_screen; - struct wsdisplay_font *dc_fontdata; int dc_mode; struct vcons_data dc_vd; }; @@ -87,13 +86,11 @@ CFATTACH_DECL_NEW(newport, sizeof(struct /* textops */ static void newport_cursor(void *, int, int, int); static void newport_cursor_dummy(void *, int, int, int); -static int newport_mapchar(void *, int, unsigned int *); static void newport_putchar(void *, int, int, u_int, long); static void newport_copycols(void *, int, int, int, int); static void newport_erasecols(void *, int, int, int, long); static void newport_copyrows(void *, int, int, int); static void newport_eraserows(void *, int, int, long); -static int newport_allocattr(void *, int, int, int, long *); static void newport_init_screen(void *, struct vcons_screen *, int, long *); @@ -107,22 +104,10 @@ static struct wsdisplay_accessops newpor .mmap = newport_mmap, }; -static struct wsdisplay_emulops newport_textops = { - .cursor = newport_cursor_dummy, - .mapchar = newport_mapchar, - .putchar = newport_putchar, - .copycols = newport_copycols, - .erasecols = newport_erasecols, - .copyrows = newport_copyrows, - .eraserows = newport_eraserows, - .allocattr = newport_allocattr -}; - static struct wsscreen_descr newport_screen = { .name = "default", .ncols = 160, .nrows = 64, - .textops = &newport_textops, .fontwidth = 8, .fontheight = 16, .capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE @@ -141,11 +126,7 @@ static struct vcons_screen newport_conso static struct newport_devconfig newport_console_dc; static int newport_is_console = 0; -#define NEWPORT_ATTR_ENCODE(fg,bg) (((fg) << 8) | (bg)) -#define NEWPORT_ATTR_BG(a) ((a) & 0xff) -#define NEWPORT_ATTR_FG(a) (((a) >> 8) & 0xff) - -extern const u_char rasops_cmap[768]; +uint8_t our_cmap[768]; /**** Low-level hardware register groveling functions ****/ static void @@ -273,9 +254,19 @@ xmap9_write(struct newport_devconfig *dc rex3_write(dc, REX3_REG_DCBDATA0, val << 24); } +static inline void +xmap9_wait(struct newport_devconfig *dc) +{ + do {} while (xmap9_read(dc, XMAP9_DCBCRS_FIFOAVAIL) == 0); +} + static void xmap9_write_mode(struct newport_devconfig *dc, uint8_t index, uint32_t mode) { + volatile uint32_t junk; + /* wait for FIFO if needed */ + xmap9_wait(dc); + rex3_write(dc, REX3_REG_DCBMODE, REX3_DCBMODE_DW_4 | (NEWPORT_DCBADDR_XMAP_BOTH << REX3_DCBMODE_DCBADDR_SHIFT) | @@ -284,30 +275,40 @@ xmap9_write_mode(struct newport_devconfi (2 << REX3_DCBMODE_CSHOLD_SHIFT) | (1 << REX3_DCBMODE_CSSETUP_SHIFT)); + xmap9_wait(dc); + rex3_write(dc, REX3_REG_DCBDATA0, (index << 24) | mode); + junk = rex3_read(dc, REX3_REG_DCBDATA0); + __USE(junk); } /**** Helper functions ****/ static void -newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int x2, - int y2, uint8_t color) +newport_fill_rectangle(struct newport_devconfig *dc, int x1, int y1, int wi, + int he, uint32_t color) { + int x2 = x1 + wi - 1; + int y2 = y1 + he - 1; + 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_CLIPMODE, 0x1e00); rex3_write(dc, REX3_REG_DRAWMODE1, - REX3_DRAWMODE1_PLANES_CI | + REX3_DRAWMODE1_PLANES_RGB | 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_RGBMODE | + REX3_DRAWMODE1_FASTCLEAR | REX3_DRAWMODE1_LO_SRC); rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); - rex3_write(dc, REX3_REG_COLORI, color); + rex3_write(dc, REX3_REG_COLORVRAM, color); rex3_write(dc, REX3_REG_XYSTARTI, (x1 << REX3_XYSTARTI_XSHIFT) | y1); rex3_write_go(dc, REX3_REG_XYENDI, (x2 << REX3_XYENDI_XSHIFT) | y2); @@ -430,7 +431,7 @@ newport_get_resolution(struct newport_de } static void -newport_setup_hw(struct newport_devconfig *dc) +newport_setup_hw(struct newport_devconfig *dc, int depth) { uint16_t __unused(curp), tmp; int i; @@ -467,25 +468,74 @@ newport_setup_hw(struct newport_devconfi VC2_CONTROL_CURSORFUNC_ENABLE /*| VC2_CONTROL_CURSOR_ENABLE*/); - /* Setup XMAP9s */ - xmap9_write(dc, XMAP9_DCBCRS_CONFIG, - XMAP9_CONFIG_8BIT_SYSTEM | XMAP9_CONFIG_RGBMAP_CI); + /* disable all clipping */ + rex3_write(dc, REX3_REG_CLIPMODE, 0x1e00); + /* Setup XMAP9s */ 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]); + if (depth == 8) { + + for (i = 0; i < 32; i++) { + xmap9_write_mode(dc, i, + XMAP9_MODE_GAMMA_BYPASS | + XMAP9_MODE_PIXSIZE_8BPP | XMAP9_MODE_PIXMODE_RGB2); + } + 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 */ + uint8_t ctmp; + for (i = 0; i < 256; i++) { + ctmp = i & 0xe0; + /* + * replicate bits so 0xe0 maps to a red value of 0xff + * in order to make white look actually white + */ + ctmp |= (ctmp >> 3) | (ctmp >> 6); + our_cmap[i * 3] = ctmp; + + ctmp = (i & 0x1c) << 3; + ctmp |= (ctmp >> 3) | (ctmp >> 6); + our_cmap[i * 3 + 1] = ctmp; + + ctmp = (i & 0x03) << 6; + ctmp |= ctmp >> 2; + ctmp |= ctmp >> 4; + our_cmap[i * 3 + 2] = ctmp; + + newport_cmap_setrgb(dc, i, our_cmap[i * 3], + our_cmap[i * 3 + 1], our_cmap[i * 3 + 2]); + } + /* Write a ramp into RGB2 cmap */ + for (i = 0; i < 256; i++) + newport_cmap_setrgb(dc, 0x1f00 + i, i, i, i); + } else { + uint8_t dcbcfg; + + dcbcfg = xmap9_read(dc, XMAP9_DCBCRS_CONFIG); + aprint_debug("dcbcfg: %02x\n", dcbcfg); + dcbcfg &= 0x3c; + xmap9_write(dc, XMAP9_DCBCRS_CONFIG, dcbcfg | XMAP9_CONFIG_RGBMAP_2); + + for (i = 0; i < 32; i++) { + xmap9_write_mode(dc, i, + XMAP9_MODE_GAMMA_BYPASS | + XMAP9_MODE_PIXSIZE_24BPP | + XMAP9_MODE_PIXMODE_RGB2); + } + + /* Setup REX3 */ + rex3_write(dc, REX3_REG_XYWIN, (4096 << 16) | 4096); + rex3_write(dc, REX3_REG_TOPSCAN, 0x3ff); /* XXX Why? XXX */ + + /* Write a ramp into RGB2 cmap */ + for (i = 0; i < 256; i++) + newport_cmap_setrgb(dc, 0x1f00 + i, i, i, i); + } } /**** Attach routines ****/ @@ -504,11 +554,11 @@ newport_match(device_t parent, struct cf return 1; if (platform.badaddr( - (void *)(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI), + (void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr + NEWPORT_REX3_OFFSET + REX3_REG_XSTARTI), sizeof(uint32_t))) return 0; if (platform.badaddr( - (void *)(ga->ga_ioh + NEWPORT_REX3_OFFSET + REX3_REG_XSTART), + (void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr + NEWPORT_REX3_OFFSET + REX3_REG_XSTART), sizeof(uint32_t))) return 0; @@ -532,21 +582,18 @@ newport_attach_common(struct newport_dev dc->dc_st = ga->ga_iot; dc->dc_sh = ga->ga_ioh; - wsfont_init(); - - dc->dc_font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R, - WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP); - if (dc->dc_font < 0) - panic("newport_attach_common: no suitable fonts"); - - if (wsfont_lock(dc->dc_font, &dc->dc_fontdata)) - panic("newport_attach_common: unable to lock font data"); - - newport_setup_hw(dc); + newport_setup_hw(dc, 8); newport_get_resolution(dc); newport_fill_rectangle(dc, 0, 0, dc->dc_xres, dc->dc_yres, 0); + +#ifdef NEWPORT_DEBUG + int i; + for (i = 0; i < 256; i++) + newport_fill_rectangle(dc, 10, i * 3 + 10, 500, 2, i); + delay(10000000); +#endif dc->dc_screen = &newport_screen; dc->dc_mode = WSDISPLAYIO_MODE_EMUL; @@ -588,8 +635,6 @@ newport_attach(device_t parent, device_t 1, &defattr); sc->sc_dc->dc_screen->textops = &newport_console_screen.scr_ri.ri_ops; - memcpy(&newport_textops, &newport_console_screen.scr_ri.ri_ops, - sizeof(struct wsdisplay_emulops)); vcons_replay_msgbuf(&newport_console_screen); } wa.scrdata = &newport_screenlist; @@ -603,7 +648,7 @@ int newport_cnattach(struct gio_attach_args *ga) { struct rasops_info *ri = &newport_console_screen.scr_ri; - long defattr = NEWPORT_ATTR_ENCODE(WSCOL_WHITE, WSCOL_BLACK); + long defattr = 0x000f0000; if (!newport_match(NULL, NULL, ga)) { return ENXIO; @@ -611,28 +656,28 @@ newport_cnattach(struct gio_attach_args newport_attach_common(&newport_console_dc, ga); - newport_screen.ncols = newport_console_dc.dc_xres / 8; - newport_screen.nrows = newport_console_dc.dc_yres / 16; - ri->ri_hw = &newport_console_screen; ri->ri_depth = newport_console_dc.dc_depth; ri->ri_width = newport_console_dc.dc_xres; ri->ri_height = newport_console_dc.dc_yres; ri->ri_stride = newport_console_dc.dc_xres; /* XXX */ - ri->ri_flg = RI_CENTER | RI_FULLCLEAR; + ri->ri_flg = RI_CENTER | RI_NO_AUTO | RI_FULLCLEAR | RI_8BIT_IS_RGB; + rasops_init(ri, 0, 0); + ri->ri_caps = WSSCREEN_WSCOLORS; + rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight, + ri->ri_width / ri->ri_font->fontwidth); ri->ri_ops.copyrows = newport_copyrows; ri->ri_ops.eraserows = newport_eraserows; ri->ri_ops.copycols = newport_copycols; ri->ri_ops.erasecols = newport_erasecols; ri->ri_ops.cursor = newport_cursor_dummy; - ri->ri_ops.mapchar = newport_mapchar; ri->ri_ops.putchar = newport_putchar; - ri->ri_ops.allocattr = newport_allocattr; - ri->ri_font = newport_console_dc.dc_fontdata; + newport_screen.textops = &ri->ri_ops; + newport_screen.ncols = ri->ri_cols; + newport_screen.nrows = ri->ri_rows; newport_console_screen.scr_cookie = &newport_console_dc; wsdisplay_cnattach(&newport_screen, ri, 0, 0, defattr); - newport_is_console = 1; return 0; @@ -645,13 +690,11 @@ newport_init_screen(void *cookie, struct struct newport_devconfig *dc = cookie; struct rasops_info *ri = &scr->scr_ri; - ri->ri_depth = dc->dc_depth; + ri->ri_depth = 8; ri->ri_width = dc->dc_xres; ri->ri_height = dc->dc_yres; ri->ri_stride = dc->dc_xres; /* XXX */ - ri->ri_flg = RI_CENTER; - - /*&ri->ri_bits = (char *)sc->sc_fb.fb_pixels;*/ + ri->ri_flg = RI_CENTER | RI_FULLCLEAR | RI_8BIT_IS_RGB; rasops_init(ri, 0, 0); ri->ri_caps = WSSCREEN_WSCOLORS; @@ -665,9 +708,7 @@ newport_init_screen(void *cookie, struct ri->ri_ops.copycols = newport_copycols; ri->ri_ops.erasecols = newport_erasecols; ri->ri_ops.cursor = newport_cursor; - ri->ri_ops.mapchar = newport_mapchar; ri->ri_ops.putchar = newport_putchar; - ri->ri_ops.allocattr = newport_allocattr; } /**** wsdisplay textops ****/ @@ -706,39 +747,13 @@ newport_cursor(void *c, int on, int row, } } -static int -newport_mapchar(void *c, int ch, unsigned int *cp) -{ - struct rasops_info *ri = c; - struct vcons_screen *scr = ri->ri_hw; - struct newport_devconfig *dc = scr->scr_cookie; - - if (dc->dc_fontdata->encoding != WSDISPLAY_FONTENC_ISO) { - ch = wsfont_map_unichar(dc->dc_fontdata, ch); - - if (ch < 0) - goto fail; - } - - if (ch < dc->dc_fontdata->firstchar || - ch >= dc->dc_fontdata->firstchar + dc->dc_fontdata->numchars) - goto fail; - - *cp = ch; - return 5; - -fail: - *cp = ' '; - return 0; -} - 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; + struct wsdisplay_font *font = PICK_FONT(ri, ch); uint8_t *bitmap = (u_int8_t *)font->data + (ch - font->firstchar) * font->fontheight * font->stride; uint32_t pattern; @@ -760,24 +775,36 @@ newport_putchar(void *c, int row, int co REX3_DRAWMODE1_COMPARE_LT | REX3_DRAWMODE1_COMPARE_EQ | REX3_DRAWMODE1_COMPARE_GT | + /*REX3_DRAWMODE1_RGBMODE |*/ 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_COLORI, ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff); + rex3_write(dc, REX3_REG_COLORBACK, ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff); - rex3_write(dc, REX3_REG_WRMASK, 0xffffffff); + rex3_write(dc, REX3_REG_WRMASK, 0xff); - 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); + if (font->stride == 1) { + for (i = 0; i < font->fontheight; i++) { + pattern = *bitmap << 24; + + rex3_write_go(dc, REX3_REG_ZPATTERN, pattern); + + bitmap++; + } + } else { + uint16_t *bitmap16 = (uint16_t *)bitmap; + for (i = 0; i < font->fontheight; i++) { + pattern = *bitmap16 << 16; + + rex3_write_go(dc, REX3_REG_ZPATTERN, pattern); - bitmap += font->stride; + bitmap16++; + } + } rex3_wait_gfifo(dc); } @@ -805,14 +832,14 @@ newport_erasecols(void *c, int row, int struct rasops_info *ri = c; struct vcons_screen *scr = ri->ri_hw; struct newport_devconfig *dc = scr->scr_cookie; - struct wsdisplay_font *font = dc->dc_fontdata; + struct wsdisplay_font *font = ri->ri_font; newport_fill_rectangle(dc, - startcol * font->fontwidth, /* x1 */ - row * font->fontheight, /* y1 */ - (startcol + ncols) * font->fontwidth - 1, /* x2 */ - (row + 1) * font->fontheight - 1, /* y2 */ - NEWPORT_ATTR_BG(attr)); + startcol * font->fontwidth + ri->ri_xorigin, /* x1 */ + row * font->fontheight + ri->ri_yorigin, /* y1 */ + ncols * font->fontwidth, /* wi */ + font->fontheight, /* he */ + ri->ri_devcmap[(attr >> 16) & 0xf]); } static void @@ -838,39 +865,23 @@ newport_eraserows(void *c, int startrow, struct rasops_info *ri = c; struct vcons_screen *scr = ri->ri_hw; struct newport_devconfig *dc = scr->scr_cookie; - struct wsdisplay_font *font = dc->dc_fontdata; - - newport_fill_rectangle(dc, - 0, /* x1 */ - startrow * font->fontheight, /* y1 */ - dc->dc_xres, /* x2 */ - (startrow + nrows) * font->fontheight - 1, /* y2 */ - NEWPORT_ATTR_BG(attr)); -} - -static int -newport_allocattr(void *c, int fg, int bg, int flags, long *attr) -{ - if (flags & WSATTR_BLINK) - return EINVAL; - - if ((flags & WSATTR_WSCOLORS) == 0) { - fg = WSCOL_WHITE; - bg = WSCOL_BLACK; - } - - if (flags & WSATTR_HILIT) - fg += 8; + struct wsdisplay_font *font = ri->ri_font; - if (flags & WSATTR_REVERSE) { - int tmp = fg; - fg = bg; - bg = tmp; + if (startrow == 0 && nrows == ri->ri_rows) { + newport_fill_rectangle(dc, + 0, /* x1 */ + 0, /* y1 */ + dc->dc_xres, /* wi */ + dc->dc_yres, /* he */ + ri->ri_devcmap[(attr >> 16) & 0xf]); + } else { + newport_fill_rectangle(dc, + 0, /* x1 */ + startrow * font->fontheight + ri->ri_yorigin, /* y1 */ + dc->dc_xres, /* wi */ + nrows * font->fontheight, /* he */ + ri->ri_devcmap[(attr >> 16) & 0xf]); } - - *attr = NEWPORT_ATTR_ENCODE(fg, bg); - - return 0; } /**** wsdisplay accessops ****/ @@ -895,7 +906,7 @@ newport_ioctl(void *v, void *vs, u_long FBINFO.width = dc->dc_xres; FBINFO.height = dc->dc_yres; FBINFO.depth = dc->dc_depth; - FBINFO.cmsize = 1 << FBINFO.depth; + FBINFO.cmsize = 256; return 0; case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_NEWPORT; @@ -906,8 +917,11 @@ newport_ioctl(void *v, void *vs, u_long dc->dc_mode = nmode; if (nmode == WSDISPLAYIO_MODE_EMUL) { rex3_wait_gfifo(dc); - newport_setup_hw(dc); + newport_setup_hw(dc, 8); vcons_redraw_screen(vd->active); + } else { + rex3_wait_gfifo(dc); + newport_setup_hw(dc, dc->dc_depth); } } return 0;