diff options
author | 2012-04-18 17:28:24 +0000 | |
---|---|---|
committer | 2012-04-18 17:28:24 +0000 | |
commit | dafdb93f71b2cfef068c4ec44413b602b3f17f9c (patch) | |
tree | 464f343bad7ad5e3dd94579aa98cf4c2fd23fa47 /sys/arch/sgi/dev | |
parent | Don't attach a wsdisplay if not the console device, for part of the device (diff) | |
download | wireguard-openbsd-dafdb93f71b2cfef068c4ec44413b602b3f17f9c.tar.xz wireguard-openbsd-dafdb93f71b2cfef068c4ec44413b602b3f17f9c.zip |
Split the existing impact@xbow attachment into generic impact routines, and
bus-specific attachment; impactreg.h and impactvar.h move from sgi/xbow/ to
sgi/dev/.
Teach the generic impact code how to code with pre-ImpactSR boards, which have
a slightly different register layout (information obtained from Peter Fuerst's
Linux IP28 patches).
Add an impact@gio attachment (unfortunately untested, no Impact GIO boards
here). All Indigo 2 graphics options should be supported now (assuming the
Extreme/Ultra will actually work with grtwo(4) out of the box).
Tested not to disturb operation on IP30.
** ATTENTION! If you are building IP27 or IP30 kernels, be sure to rm impact.d
** before building a new kernel.
Diffstat (limited to 'sys/arch/sgi/dev')
-rw-r--r-- | sys/arch/sgi/dev/impact.c | 794 | ||||
-rw-r--r-- | sys/arch/sgi/dev/impactreg.h | 112 | ||||
-rw-r--r-- | sys/arch/sgi/dev/impactvar.h | 36 |
3 files changed, 942 insertions, 0 deletions
diff --git a/sys/arch/sgi/dev/impact.c b/sys/arch/sgi/dev/impact.c new file mode 100644 index 00000000000..ca4b9229056 --- /dev/null +++ b/sys/arch/sgi/dev/impact.c @@ -0,0 +1,794 @@ +/* $OpenBSD: impact.c,v 1.1 2012/04/18 17:28:24 miod Exp $ */ + +/* + * Copyright (c) 2010 Miodrag Vallat. + * Copyright (c) 2009, 2010 Joel Sing <jsing@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Driver for the SGI Impact and ImpactSR graphics board. + */ + +/* + * The details regarding the design and operation of this hardware, along with + * the necessary magic numbers, are only available thanks to the reverse + * engineering work undertaken by Stanislaw Skowronek <skylark@linux-mips.org>. + * + * Differences between ImpactSR and Impact researched by Peter Fuerst + * <post@pfrst.de>. + */ + +/* + * This driver currently lacks support for the HQ3 and HQ4 DMA engines, which + * could be used to speed up rasops `copy' operations a lot by doing + * framebuffer to memory, then memory to framebuffer operations. + * + * Of course, in an ideal world, these operations would be done with + * framebuffer to framebuffer operations, but according to Skowronek, these + * operations are not reliable and IRIX' Xsgi X server does not even try to + * use them. + * + * Thus this driver currently implements rasops `copy' operations by repainting + * affected areas with PIO routines. This is unfortunately slower than DMA, + * but this will work until I have more time to spend on this. -- miod + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/types.h> +#include <sys/malloc.h> + +#include <machine/bus.h> + +#include <sgi/dev/gl.h> +#include <sgi/dev/impactreg.h> +#include <sgi/dev/impactvar.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> + +struct cfdriver impact_cd = { + NULL, "impact", DV_DULL, +}; + +#define IMPACT_WIDTH 1280 +#define IMPACT_HEIGHT 1024 +#define IMPACT_DEPTH 32 + +struct impact_screen { + struct rasops_info ri; + long defattr; + struct wsdisplay_charcell *bs; + + struct impact_softc *sc; + int has_hq4; + + bus_addr_t fifo_status; + bus_addr_t cfifo; + + bus_space_tag_t iot; + bus_space_handle_t ioh; + + struct wsscreen_descr wsd; + struct wsscreen_list wsl; + struct wsscreen_descr *scrlist[1]; +}; + +static inline void + impact_cmd_fifo_write(struct impact_screen *, uint64_t, uint32_t, int); +int impact_cmd_fifo_wait(struct impact_screen *); + +void impact_setup(struct impact_screen *, int); +int impact_init_screen(struct impact_screen *); + +/* + * Hardware acceleration (sort of) for rasops. + */ +void impact_rop(struct impact_screen *, int, int, int, int, int, u_int); +void impact_fillrect(struct impact_screen *, int, int, int, int, u_int); +int impact_do_cursor(struct rasops_info *); +int impact_putchar(void *, int, int, u_int, long); +int impact_copycols(void *, int, int, int, int); +int impact_erasecols(void *, int, int, int, long); +int impact_copyrows(void *, int, int, int); +int impact_eraserows(void *, int, int, long); + +/* + * Interfaces for wscons. + */ +int impact_ioctl(void *, u_long, caddr_t, int, struct proc *); +paddr_t impact_mmap(void *, off_t, int); +int impact_alloc_screen(void *, const struct wsscreen_descr *, void **, + int *, int *, long *); +void impact_free_screen(void *, void *); +int impact_show_screen(void *, void *, int, void (*)(void *, int, int), + void *); + +static struct impact_screen impact_cons; + +struct wsdisplay_accessops impact_accessops = { + impact_ioctl, + impact_mmap, + impact_alloc_screen, + impact_free_screen, + impact_show_screen, + NULL, /* load_font */ + NULL, /* scrollback */ + NULL, /* getchar */ + NULL, /* burner */ + NULL /* pollc */ +}; + +int +impact_attach_common(struct impact_softc *sc, bus_space_tag_t iot, + bus_space_handle_t ioh, int console, int has_hq4) +{ + struct wsemuldisplaydev_attach_args waa; + struct impact_screen *scr; + + if (console) { + /* + * Setup has already been done via impact_cnattach(). + */ + scr = &impact_cons; + scr->sc = sc; + sc->curscr = scr; + sc->console = 1; + } else { + /* + * Setup screen data. + */ + scr = malloc(sizeof(struct impact_screen), M_DEVBUF, + M_NOWAIT | M_ZERO); + if (scr == NULL) { + printf("failed to allocate screen memory!\n"); + return ENOMEM; + } + + scr->iot = iot; + scr->ioh = ioh; + scr->sc = sc; + sc->curscr = scr; + + /* Setup hardware and clear screen. */ + impact_setup(scr, has_hq4); + if (impact_init_screen(scr) != 0) { + printf("failed to allocate memory\n"); + free(scr, M_DEVBUF); + return ENOMEM; + } + } + + scr->scrlist[0] = &scr->wsd; + scr->wsl.nscreens = 1; + scr->wsl.screens = (const struct wsscreen_descr **)scr->scrlist; + + waa.console = sc->console; + waa.scrdata = &scr->wsl; + waa.accessops = &impact_accessops; + waa.accesscookie = scr; + waa.defaultscreens = 0; + + config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint); + + return 0; +} + +int +impact_init_screen(struct impact_screen *scr) +{ + struct rasops_info *ri = &scr->ri; + size_t bssize; + + bzero(ri, sizeof(struct rasops_info)); + + ri->ri_flg = RI_CENTER | RI_FULLCLEAR; + ri->ri_depth = IMPACT_DEPTH; + ri->ri_width = IMPACT_WIDTH; + ri->ri_height = IMPACT_HEIGHT; + ri->ri_stride = IMPACT_WIDTH * IMPACT_DEPTH / 8; + + rasops_init(ri, 160, 160); + + /* + * Allocate backing store to remember character cells, to + * be able to fulfill scrolling requests. + */ + if (scr->bs == NULL) { + bssize = ri->ri_rows * ri->ri_cols * + sizeof(struct wsdisplay_charcell); + scr->bs = malloc(bssize, M_DEVBUF, M_NOWAIT | M_ZERO); + if (scr->bs == NULL) + return ENOMEM; + } + + ri->ri_hw = scr; + + ri->ri_ops.putchar = impact_putchar; + ri->ri_do_cursor = impact_do_cursor; + ri->ri_ops.copyrows = impact_copyrows; + ri->ri_ops.copycols = impact_copycols; + ri->ri_ops.eraserows = impact_eraserows; + ri->ri_ops.erasecols = impact_erasecols; + + /* clear display */ + impact_fillrect(scr, 0, 0, ri->ri_width, ri->ri_height, + ri->ri_devcmap[WSCOL_BLACK]); + + strlcpy(scr->wsd.name, "std", sizeof(scr->wsd.name)); + scr->wsd.ncols = ri->ri_cols; + scr->wsd.nrows = ri->ri_rows; + scr->wsd.textops = &ri->ri_ops; + scr->wsd.fontwidth = ri->ri_font->fontwidth; + scr->wsd.fontheight = ri->ri_font->fontheight; + scr->wsd.capabilities = ri->ri_caps; + + return 0; +} + +/* + * Hardware initialization. + */ + +void +impact_setup(struct impact_screen *scr, int has_hq4) +{ + bus_addr_t xmap_base; + bus_addr_t vc3_base; + + scr->has_hq4 = has_hq4; + + if (has_hq4) { + xmap_base = IMPACTSR_XMAP_BASE; + vc3_base = IMPACTSR_VC3_BASE; + scr->fifo_status = IMPACTSR_FIFOSTATUS; + scr->cfifo = IMPACTSR_CFIFO; + } else { + xmap_base = IMPACT_XMAP_BASE; + vc3_base = IMPACT_VC3_BASE; + scr->fifo_status = IMPACT_FIFOSTATUS; + scr->cfifo = IMPACT_CFIFO; + } + + if (has_hq4) { + /* HQ4 initialization */ + bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_CFIFO_HW, + 0x00000047); + bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_CFIFO_LW, + 0x00000014); + bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_CFIFO_DELAY, + 0x00000064); + bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_DFIFO_HW, + 0x00000040); + bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_DFIFO_LW, + 0x00000010); + bus_space_write_4(scr->iot, scr->ioh, IMPACTSR_DFIFO_DELAY, + 0x00000000); + } else { + /* HQ3 initialization */ + bus_space_write_4(scr->iot, scr->ioh, IMPACT_CFIFO_HW, + 0x00000020); + bus_space_write_4(scr->iot, scr->ioh, IMPACT_CFIFO_LW, + 0x00000014); + bus_space_write_4(scr->iot, scr->ioh, IMPACT_CFIFO_DELAY, + 0x00000064); + bus_space_write_4(scr->iot, scr->ioh, IMPACT_DFIFO_HW, + 0x00000028); + bus_space_write_4(scr->iot, scr->ioh, IMPACT_DFIFO_LW, + 0x00000014); + bus_space_write_4(scr->iot, scr->ioh, IMPACT_DFIFO_DELAY, + 0x00000fff); + } + + /* VC3 initialization: disable hardware cursor */ + bus_space_write_4(scr->iot, scr->ioh, + vc3_base + IMPACTSR_VC3_INDEXDATA, 0x1d000100); + + /* RSS initialization */ + impact_cmd_fifo_write(scr, IMPACTSR_CMD_COLORMASKLSBSA, 0xffffff, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_COLORMASKLSBSB, 0xffffff, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_COLORMASKMSBS, 0, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRMASKLO, 0xffffff, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRMASKHI, 0xffffff, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_DRBPOINTERS, 0xc8240, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_CONFIG, 0xcac, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XYWIN, + IMPACTSR_YXCOORDS(0, 0x3ff), 0); + + /* XMAP initialization */ + bus_space_write_1(scr->iot, scr->ioh, + xmap_base + IMPACTSR_XMAP_PP1SELECT, 0x01); + bus_space_write_1(scr->iot, scr->ioh, + xmap_base + IMPACTSR_XMAP_INDEX, 0x00); + bus_space_write_4(scr->iot, scr->ioh, + xmap_base + IMPACTSR_XMAP_MAIN_MODE, 0x000007a4); +} + +/* + * Write to the command FIFO. + */ +static inline void +impact_cmd_fifo_write(struct impact_screen *scr, uint64_t reg, uint32_t val, + int exec) +{ + uint64_t cmd; + + cmd = IMPACTSR_CFIFO_WRITE | (reg << IMPACTSR_CFIFO_REG_SHIFT); + if (exec) + cmd |= IMPACTSR_CFIFO_EXEC; + bus_space_write_8(scr->iot, scr->ioh, scr->cfifo, cmd | val); +} + +/* + * Wait until the command FIFO is empty. + */ +int +impact_cmd_fifo_wait(struct impact_screen *scr) +{ + u_int32_t val, timeout = 1000000; +#ifdef DIAGNOSTIC + struct impact_softc *sc = scr->sc; +#endif + + val = bus_space_read_4(scr->iot, scr->ioh, scr->fifo_status); + while ((val & IMPACTSR_FIFO_MASK) != 0) { + delay(1); + if (--timeout == 0) { +#ifdef DIAGNOSTIC + if (sc != NULL && sc->console == 0) + printf("%s: timeout waiting for command fifo\n", + sc != NULL ? sc->sc_dev.dv_xname : + impact_cd.cd_name); +#endif + return ETIMEDOUT; + } + val = bus_space_read_4(scr->iot, scr->ioh, scr->fifo_status); + } + + return 0; +} + +/* + * Interfaces for wscons. + */ + +int +impact_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) +{ + struct impact_screen *scr = (struct impact_screen *)v; + struct rasops_info *ri; + struct wsdisplay_fbinfo *fb; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_IMPACT; + break; + case WSDISPLAYIO_GINFO: + fb = (struct wsdisplay_fbinfo *)data; + ri = &scr->ri; + fb->height = ri->ri_height; + fb->width = ri->ri_width; + fb->depth = ri->ri_depth; + fb->cmsize = 0; + break; +#if 0 + case WSDISPLAYIO_LINEBYTES: + ri = &scr->ri; + *(u_int *)data = ri->ri_stride; + break; +#endif + default: + return -1; + } + + return 0; +} + +paddr_t +impact_mmap(void *v, off_t offset, int prot) +{ + if (offset < 0 || (offset & PAGE_MASK) != 0) + return -1; + + return -1; +} + +int +impact_alloc_screen(void *v, const struct wsscreen_descr *type, + void **cookiep, int *curxp, int *curyp, long *attrp) +{ + struct impact_screen *scr = (struct impact_screen *)v; + struct rasops_info *ri = &scr->ri; + struct impact_softc *sc = (struct impact_softc *)scr->sc; + + /* We do not allow multiple consoles at the moment. */ + if (sc->nscreens > 0) + return ENOMEM; + + sc->nscreens++; + + *cookiep = ri; + *curxp = 0; + *curyp = 0; + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &scr->defattr); + *attrp = scr->defattr; + + return 0; +} + +void +impact_free_screen(void *v, void *cookie) +{ + /* We do not allow multiple consoles at the moment. */ +} + +int +impact_show_screen(void *v, void *cookie, int waitok, + void (*cb)(void *, int, int), void *cbarg) +{ + /* We do not allow multiple consoles at the moment. */ + return 0; +} + +/* + * Hardware accelerated functions. + */ + +void +impact_rop(struct impact_screen *scr, int x, int y, int w, int h, int op, + u_int c) +{ + impact_cmd_fifo_wait(scr); + if (op == OPENGL_LOGIC_OP_COPY) + impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE, + IMPACTSR_PP1FILLMODE(0x6300, op), 0); + else + impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE, + IMPACTSR_PP1FILLMODE(0x6304, op), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_FILLMODE, 0, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_PACKEDCOLOR, c & 0x00ffffff, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYSTARTI, + IMPACTSR_XYCOORDS(x, y), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYENDI, + IMPACTSR_XYCOORDS(x + w - 1, y + h - 1), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_IR_ALIAS, 0x18, 1); +} + +void +impact_fillrect(struct impact_screen *scr, int x, int y, int w, int h, u_int c) +{ + impact_rop(scr, x, y, w, h, OPENGL_LOGIC_OP_COPY, c); +} + +int +impact_do_cursor(struct rasops_info *ri) +{ + struct impact_screen *scr = ri->ri_hw; + int y, x, w, h, fg, bg; + + w = ri->ri_font->fontwidth; + h = ri->ri_font->fontheight; + x = ri->ri_xorigin + ri->ri_ccol * w; + y = ri->ri_yorigin + ri->ri_crow * h; + + ri->ri_ops.unpack_attr(ri, scr->defattr, &fg, &bg, NULL); + + impact_rop(scr, x, y, w, h, OPENGL_LOGIC_OP_XOR, ri->ri_devcmap[fg]); + impact_cmd_fifo_wait(scr); + + return 0; +} + +int +impact_putchar(void *cookie, int row, int col, u_int uc, long attr) +{ + struct rasops_info *ri = cookie; + struct impact_screen *scr = ri->ri_hw; + struct wsdisplay_font *font = ri->ri_font; + int x, y, w, h, bg, fg, ul; + u_int8_t *fontbitmap; + u_int chunk; + struct wsdisplay_charcell *cell; + + /* Update backing store. */ + cell = scr->bs + row * ri->ri_cols + col; + cell->uc = uc; + cell->attr = attr; + + w = font->fontwidth; + h = font->fontheight; + x = ri->ri_xorigin + col * w; + y = ri->ri_yorigin + row * h; + + ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, &ul); + + /* Handle spaces with a single fillrect. */ + if ((uc == ' ' || uc == 0) && ul == 0) { + impact_fillrect(scr, x, y, w, h, ri->ri_devcmap[bg]); + return 0; + } + + fontbitmap = (u_int8_t *)(font->data + (uc - font->firstchar) * + ri->ri_fontscale); + + impact_cmd_fifo_wait(scr); + if (ri->ri_devcmap[bg] == 0) { + /* + * 1bpp pixel expansion; fast but background color ends up + * being incorrect (white renders as light green, and other + * colors end up slightly more greenish), which is why it is + * only done for black background. + */ + impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE, + IMPACTSR_PP1FILLMODE(0x6300, OPENGL_LOGIC_OP_COPY), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_FILLMODE, + 0x00400018, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_PACKEDCOLOR, + ri->ri_devcmap[fg], 0); +#if 0 + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_RG, + (ri->ri_devcmap[bg] & 0x0000ffff) << 8, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_BA, + (ri->ri_devcmap[bg] & 0x00ff0000) >> 8, 0); +#else + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_RG, 0, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BKGRD_BA, 0, 0); +#endif + + if (w <= 8) { + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYSTARTI, + IMPACTSR_XYCOORDS(x, y), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYENDI, + IMPACTSR_XYCOORDS(x + w - 1, y + h - 1), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_IR_ALIAS, + 0x18, 1); + + for (; h != 0; h--) { + chunk = *fontbitmap; + fontbitmap += font->stride; + + /* Handle underline. */ + if (ul && h == 1) + chunk = 0xff; + + impact_cmd_fifo_wait(scr); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_H, + chunk << 24, 1); + } + } else { + for (; h != 0; h--) { + chunk = *(u_int16_t *)fontbitmap; + fontbitmap += font->stride; + + /* Handle underline. */ + if (ul && h == 1) + chunk = 0xffff; + + impact_cmd_fifo_write(scr, + IMPACTSR_CMD_BLOCKXYSTARTI, + IMPACTSR_XYCOORDS(x, y), 0); + impact_cmd_fifo_write(scr, + IMPACTSR_CMD_BLOCKXYENDI, + IMPACTSR_XYCOORDS(x + w - 1, y + 1 - 1), 0); + impact_cmd_fifo_write(scr, + IMPACTSR_CMD_IR_ALIAS, 0x18, 1); + + impact_cmd_fifo_wait(scr); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_H, + chunk << 16, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_L, + chunk << 24, 1); + + y++; + } + } + } else { + uint mask; + uint32_t data; + int i, flip; + + /* slower 8bpp blt; hopefully gives us the correct colors */ + impact_cmd_fifo_write(scr, IMPACTSR_CMD_PP1FILLMODE, + IMPACTSR_PP1FILLMODE(0x6300, OPENGL_LOGIC_OP_COPY), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYSTARTI, + IMPACTSR_XYCOORDS(x, y), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_BLOCKXYENDI, + IMPACTSR_XYCOORDS(x + w - 1, y + h - 1), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_FILLMODE, + 0x00c00000, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRMODE, 0x0080, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRSIZE, + IMPACTSR_YXCOORDS(w, h), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRCOUNTERS, + IMPACTSR_YXCOORDS(w, h), 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_GLINE_XSTARTF, 1, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_IR_ALIAS, 0x18, 1); + for (i = 0; i < 32 + 1; i++) + impact_cmd_fifo_write(scr, IMPACTSR_CMD_ALPHA, 0, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRCONTROL, 2, 0); + + flip = 0; + for (; h != 0; h--) { + if (w > 8) + chunk = *(u_int16_t *)fontbitmap; + else + chunk = *fontbitmap; + fontbitmap += font->stride; + + /* Handle underline. */ + if (ul && h == 1) + chunk = 0xffff; + + /* font data is packed towards most significant bit */ + mask = w > 8 ? 0x8000 : 0x80; + for (i = w; i != 0; i--, mask >>= 1) { + data = ri->ri_devcmap[(chunk & mask) ? fg : bg]; + impact_cmd_fifo_write(scr, flip ? + IMPACTSR_CMD_CHAR_L : IMPACTSR_CMD_CHAR_H, + data, flip); + flip ^= 1; + } + if (flip) + impact_cmd_fifo_write(scr, IMPACTSR_CMD_CHAR_L, + 0, 1); + } + + impact_cmd_fifo_write(scr, IMPACTSR_CMD_GLINE_XSTARTF, 0, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_RE_TOGGLECNTX, 0, 0); + impact_cmd_fifo_write(scr, IMPACTSR_CMD_XFRCOUNTERS, + IMPACTSR_YXCOORDS(0, 0), 0); + } + + return 0; +} + +int +impact_copycols(void *cookie, int row, int src, int dst, int num) +{ + struct rasops_info *ri = cookie; + struct impact_screen *scr = ri->ri_hw; + struct wsdisplay_charcell *cell; + + /* Copy columns in backing store. */ + cell = scr->bs + row * ri->ri_cols; + ovbcopy(cell + src, cell + dst, + num * sizeof(struct wsdisplay_charcell)); + + /* Repaint affected area */ + cell += dst; + for (; num != 0; num--, dst++, cell++) + impact_putchar(cookie, row, dst, cell->uc, cell->attr); + + return 0; +} + +int +impact_erasecols(void *cookie, int row, int col, int num, long attr) +{ + struct rasops_info *ri = cookie; + struct impact_screen *scr = ri->ri_hw; + int bg, fg, i; + struct wsdisplay_charcell *cell; + + /* Erase columns in backing store. */ + cell = scr->bs + row * ri->ri_cols + col; + for (i = num; i != 0; i--, cell++) { + cell->uc = 0; + cell->attr = attr; + } + + ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); + + row *= ri->ri_font->fontheight; + col *= ri->ri_font->fontwidth; + num *= ri->ri_font->fontwidth; + + impact_fillrect(scr, ri->ri_xorigin + col, ri->ri_yorigin + row, + num, ri->ri_font->fontheight, ri->ri_devcmap[bg]); + + return 0; +} + +int +impact_copyrows(void *cookie, int src, int dst, int num) +{ + struct rasops_info *ri = cookie; + struct impact_screen *scr = ri->ri_hw; + struct wsdisplay_charcell *cell; + int col; + + /* Copy rows in backing store. */ + cell = scr->bs + dst * ri->ri_cols; + ovbcopy(scr->bs + src * ri->ri_cols, cell, + num * ri->ri_cols * sizeof(struct wsdisplay_charcell)); + + /* Repaint affected area */ + for (; num != 0; num--, dst++) { + for (col = 0; col < ri->ri_cols; col++, cell++) + impact_putchar(cookie, dst, col, cell->uc, cell->attr); + } + + return 0; +} + +int +impact_eraserows(void *cookie, int row, int num, long attr) +{ + struct rasops_info *ri = cookie; + struct impact_screen *scr = ri->ri_hw; + int x, y, w, bg, fg; + struct wsdisplay_charcell *cell; + + /* Erase rows in backing store. */ + cell = scr->bs + row * ri->ri_cols; + for (x = ri->ri_cols; x != 0; x--, cell++) { + cell->uc = 0; + cell->attr = attr; + } + for (y = 1; y < num; y++) + ovbcopy(scr->bs + row * ri->ri_cols, + scr->bs + (row + y) * ri->ri_cols, + ri->ri_cols * sizeof(struct wsdisplay_charcell)); + + ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); + + if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) { + num = ri->ri_height; + x = y = 0; + w = ri->ri_width; + } else { + num *= ri->ri_font->fontheight; + x = ri->ri_xorigin; + y = ri->ri_yorigin + row * ri->ri_font->fontheight; + w = ri->ri_emuwidth; + } + + impact_fillrect(scr, x, y, w, num, ri->ri_devcmap[bg]); + impact_cmd_fifo_wait(scr); + + return 0; +} + +/* + * Console support. + */ + +/* console backing store, worst case font selection */ +static struct wsdisplay_charcell + impact_cons_bs[(IMPACT_WIDTH / 8) * (IMPACT_HEIGHT / 16)]; + +int +impact_cnattach_common(bus_space_tag_t iot, bus_space_handle_t ioh, int has_hq4) +{ + struct impact_screen *scr = &impact_cons; + struct rasops_info *ri = &scr->ri; + int rc; + + scr->iot = iot; + scr->ioh = ioh; + impact_setup(scr, has_hq4); + scr->bs = impact_cons_bs; + rc = impact_init_screen(scr); + if (rc != 0) + return rc; + + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &scr->defattr); + wsdisplay_cnattach(&scr->wsd, ri, 0, 0, scr->defattr); + + return 0; +} diff --git a/sys/arch/sgi/dev/impactreg.h b/sys/arch/sgi/dev/impactreg.h new file mode 100644 index 00000000000..15b6f909b2d --- /dev/null +++ b/sys/arch/sgi/dev/impactreg.h @@ -0,0 +1,112 @@ +/* $OpenBSD: impactreg.h,v 1.1 2012/04/18 17:28:24 miod Exp $ */ +/* + * Copyright (c) 2010 Miodrag Vallat. + * Copyright (c) 2009, 2010 Joel Sing <jsing@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Impact and ImpactSR registers + */ + +#define IMPACTSR_STATUS 0x020000 +#define IMPACTSR_FIFOSTATUS 0x020008 +#define IMPACTSR_FIFO_MASK 0x000000ff +#define IMPACTSR_GIOSTATUS 0x020100 +#define IMPACTSR_DMABUSY 0x020200 +#define IMPACTSR_CFIFO 0x020400 + +#define IMPACT_STATUS 0x070000 +#define IMPACT_FIFOSTATUS 0x070004 +#define IMPACT_GIOSTATUS 0x070100 +#define IMPACT_DMABUSY 0x070104 +#define IMPACT_CFIFO 0x070080 + +#define IMPACTSR_CFIFO_HW 0x040000 +#define IMPACTSR_CFIFO_LW 0x040008 +#define IMPACTSR_CFIFO_DELAY 0x040010 +#define IMPACTSR_DFIFO_HW 0x040020 +#define IMPACTSR_DFIFO_LW 0x040028 +#define IMPACTSR_DFIFO_DELAY 0x040030 +#define IMPACT_CFIFO_HW 0x050020 +#define IMPACT_CFIFO_LW 0x050024 +#define IMPACT_CFIFO_DELAY 0x050028 +#define IMPACT_DFIFO_HW 0x05002c +#define IMPACT_DFIFO_LW 0x050030 +#define IMPACT_DFIFO_DELAY 0x050034 + +#define IMPACTSR_XMAP_BASE 0x071c00 +#define IMPACT_XMAP_BASE 0x061c00 + +#define IMPACTSR_XMAP_PP1SELECT 0x000008 +#define IMPACTSR_XMAP_INDEX 0x000088 +#define IMPACTSR_XMAP_CONFIG 0x000100 +#define IMPACTSR_XMAP_CONFIGB 0x000108 +#define IMPACTSR_XMAP_BUF_SELECT 0x000180 +#define IMPACTSR_XMAP_MAIN_MODE 0x000200 +#define IMPACTSR_XMAP_OVERLAY_MODE 0x000280 +#define IMPACTSR_XMAP_DIB 0x000300 +#define IMPACTSR_XMAP_DIB_DW 0x000340 +#define IMPACTSR_XMAP_RE_RAC 0x000380 + +#define IMPACTSR_VC3_BASE 0x072000 +#define IMPACT_VC3_BASE 0x062000 + +#define IMPACTSR_VC3_INDEX 0x000008 +#define IMPACTSR_VC3_INDEXDATA 0x000038 +#define IMPACTSR_VC3_DATA 0x0000b0 +#define IMPACTSR_VC3_RAM 0x000190 + +/* + * Command FIFO instruction encoding + */ + +#define IMPACTSR_CFIFO_WRITE 0x0018000400000000UL +#define IMPACTSR_CFIFO_EXEC 0x0004000000000000UL +#define IMPACTSR_CFIFO_REG_SHIFT 40 + +/* + * Command FIFO registers + */ + +#define IMPACTSR_CMD_GLINE_XSTARTF 0x0c +#define IMPACTSR_CMD_IR_ALIAS 0x45 +#define IMPACTSR_CMD_BLOCKXYSTARTI 0x46 /* XY coords */ +#define IMPACTSR_CMD_BLOCKXYENDI 0x47 /* XY coords */ +#define IMPACTSR_CMD_PACKEDCOLOR 0x5b +#define IMPACTSR_CMD_ALPHA 0x5f +#define IMPACTSR_CMD_CHAR_H 0x70 +#define IMPACTSR_CMD_CHAR_L 0x71 +#define IMPACTSR_CMD_XFRCONTROL 0x102 +#define IMPACTSR_CMD_FILLMODE 0x110 +#define IMPACTSR_CMD_CONFIG 0x112 +#define IMPACTSR_CMD_XYWIN 0x115 /* YX coords */ +#define IMPACTSR_CMD_BKGRD_RG 0x140 +#define IMPACTSR_CMD_BKGRD_BA 0x141 +#define IMPACTSR_CMD_XFRSIZE 0x153 /* YX coords */ +#define IMPACTSR_CMD_XFRMASKLO 0x156 +#define IMPACTSR_CMD_XFRMASKHI 0x157 +#define IMPACTSR_CMD_XFRCOUNTERS 0x158 /* YX coords */ +#define IMPACTSR_CMD_XFRMODE 0x159 +#define IMPACTSR_CMD_RE_TOGGLECNTX 0x15f +#define IMPACTSR_CMD_PP1FILLMODE 0x161 +#define IMPACTSR_CMD_COLORMASKMSBS 0x162 +#define IMPACTSR_CMD_COLORMASKLSBSA 0x163 +#define IMPACTSR_CMD_COLORMASKLSBSB 0x164 +#define IMPACTSR_CMD_DRBPOINTERS 0x16d + +#define IMPACTSR_XYCOORDS(x,y) (((x) << 16) | (y)) +#define IMPACTSR_YXCOORDS(x,y) (((y) << 16) | (x)) + +#define IMPACTSR_PP1FILLMODE(mode,op) ((mode) | ((op) << 26)) diff --git a/sys/arch/sgi/dev/impactvar.h b/sys/arch/sgi/dev/impactvar.h new file mode 100644 index 00000000000..cc88b38a44c --- /dev/null +++ b/sys/arch/sgi/dev/impactvar.h @@ -0,0 +1,36 @@ +/* $OpenBSD: impactvar.h,v 1.1 2012/04/18 17:28:24 miod Exp $ */ + +/* + * Copyright (c) 2010 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct impact_screen; + +struct impact_softc { + struct device sc_dev; + struct impact_screen *curscr; + int console; + int nscreens; +}; + +int impact_attach_common(struct impact_softc *, bus_space_tag_t, + bus_space_handle_t, int, int); +int impact_cnattach_common(bus_space_tag_t, bus_space_handle_t, int); + +struct gio_attach_args; +int impact_gio_cnprobe(struct gio_attach_args *); +int impact_gio_cnattach(struct gio_attach_args *); +int impact_xbow_cnprobe(void); +int impact_xbow_cnattach(void); |