diff --git a/sys/dev/pci/r128fb.c b/sys/dev/pci/r128fb.c index a0d9c8421274..faf16bac2fb2 100644 --- a/sys/dev/pci/r128fb.c +++ b/sys/dev/pci/r128fb.c @@ -1,4 +1,4 @@ -/* $NetBSD: r128fb.c,v 1.12 2010/09/14 02:11:06 macallan Exp $ */ +/* $NetBSD: r128fb.c,v 1.13 2010/09/30 03:16:51 macallan Exp $ */ /* * Copyright (c) 2007 Michael Lorenz @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1.12 2010/09/14 02:11:06 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1.13 2010/09/30 03:16:51 macallan Exp $"); #include #include @@ -76,14 +76,12 @@ struct r128fb_softc { bus_space_tag_t sc_memt; bus_space_tag_t sc_iot; - bus_space_handle_t sc_fbh; bus_space_handle_t sc_regh; bus_addr_t sc_fb, sc_reg; bus_size_t sc_fbsize, sc_regsize; int sc_width, sc_height, sc_depth, sc_stride; int sc_locked, sc_have_backlight, sc_bl_level; - void *sc_fbaddr; struct vcons_screen sc_console_screen; struct wsscreen_descr sc_defaultscreen_descr; const struct wsscreen_descr *sc_screens[1]; @@ -124,9 +122,7 @@ static void r128fb_bitblt(struct r128fb_softc *, int, int, int, int, int, int, int); static void r128fb_cursor(void *, int, int, int); -#if 0 static void r128fb_putchar(void *, int, int, u_int, long); -#endif static void r128fb_copycols(void *, int, int, int, int); static void r128fb_erasecols(void *, int, int, int, long); static void r128fb_copyrows(void *, int, int, int); @@ -203,7 +199,7 @@ r128fb_attach(device_t parent, device_t self, void *aux) unsigned long defattr; bool is_console; int i, j; - uint32_t reg; + uint32_t reg, flags; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; @@ -236,13 +232,11 @@ r128fb_attach(device_t parent, device_t self, void *aux) prop_dictionary_get_bool(dict, "is_console", &is_console); - if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, - BUS_SPACE_MAP_LINEAR, - &sc->sc_memt, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) { + if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, 0x10, PCI_MAPREG_TYPE_MEM, + &sc->sc_fb, &sc->sc_fbsize, &flags)) { aprint_error("%s: failed to map the frame buffer.\n", device_xname(sc->sc_dev)); } - sc->sc_fbaddr = bus_space_vaddr(sc->sc_memt, sc->sc_fbh); if (pci_mapreg_map(pa, 0x18, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_memt, &sc->sc_regh, &sc->sc_reg, &sc->sc_regsize)) { @@ -250,10 +244,6 @@ r128fb_attach(device_t parent, device_t self, void *aux) device_xname(sc->sc_dev)); } - /* - * XXX yeah, casting the fb address to uint32_t is formally wrong - * but as far as I know there are no mach64 with 64bit BARs - */ aprint_normal("%s: %d MB aperture at 0x%08x\n", device_xname(self), (int)(sc->sc_fbsize >> 20), (uint32_t)sc->sc_fb); @@ -385,7 +375,6 @@ r128fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, { int new_mode = *(int*)data; - /* notify the bus backend */ if (new_mode != sc->sc_mode) { sc->sc_mode = new_mode; if(new_mode == WSDISPLAYIO_MODE_EMUL) { @@ -396,25 +385,25 @@ r128fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, } return 0; - case WSDISPLAYIO_GETPARAM: - param = (struct wsdisplay_param *)data; - if ((param->param == WSDISPLAYIO_PARAM_BACKLIGHT) && - (sc->sc_have_backlight != 0)) { - param->min = 0; - param->max = 255; - param->curval = sc->sc_bl_level; - return 0; - } - return EPASSTHROUGH; + case WSDISPLAYIO_GETPARAM: + param = (struct wsdisplay_param *)data; + if ((param->param == WSDISPLAYIO_PARAM_BACKLIGHT) && + (sc->sc_have_backlight != 0)) { + param->min = 0; + param->max = 255; + param->curval = sc->sc_bl_level; + return 0; + } + return EPASSTHROUGH; - case WSDISPLAYIO_SETPARAM: - param = (struct wsdisplay_param *)data; - if ((param->param == WSDISPLAYIO_PARAM_BACKLIGHT) && - (sc->sc_have_backlight != 0)) { - r128fb_set_backlight(sc, param->curval); - return 0; - } - return EPASSTHROUGH; + case WSDISPLAYIO_SETPARAM: + param = (struct wsdisplay_param *)data; + if ((param->param == WSDISPLAYIO_PARAM_BACKLIGHT) && + (sc->sc_have_backlight != 0)) { + r128fb_set_backlight(sc, param->curval); + return 0; + } + return EPASSTHROUGH; } return EPASSTHROUGH; } @@ -488,13 +477,7 @@ r128fb_init_screen(void *cookie, struct vcons_screen *scr, ri->ri_width = sc->sc_width; ri->ri_height = sc->sc_height; ri->ri_stride = sc->sc_stride; - ri->ri_flg = RI_CENTER | RI_FULLCLEAR; - - ri->ri_bits = (char *)sc->sc_fbaddr; - - if (existing) { - ri->ri_flg |= RI_CLEAR; - } + ri->ri_flg = RI_CENTER; rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8); ri->ri_caps = WSSCREEN_WSCOLORS; @@ -508,9 +491,7 @@ r128fb_init_screen(void *cookie, struct vcons_screen *scr, ri->ri_ops.eraserows = r128fb_eraserows; ri->ri_ops.erasecols = r128fb_erasecols; ri->ri_ops.cursor = r128fb_cursor; -#if 0 ri->ri_ops.putchar = r128fb_putchar; -#endif } static int @@ -608,7 +589,7 @@ r128fb_init(struct r128fb_softc *sc) r128fb_flush_engine(sc); - r128fb_wait(sc, 8); + r128fb_wait(sc, 9); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_CRTC_OFFSET, 0); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DEFAULT_OFFSET, 0); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DEFAULT_PITCH, @@ -620,8 +601,17 @@ r128fb_init(struct r128fb_softc *sc) bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_SC_TOP_LEFT, 0); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_SC_BOTTOM_RIGHT, R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX); + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_DEFAULT_SC_BOTTOM_RIGHT, + R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX); + +#if BYTE_ORDER == BIG_ENDIAN bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DP_DATATYPE, R128_HOST_BIG_ENDIAN_EN); +#else + bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DP_DATATYPE, + R128_HOST_LITTLE_ENDIAN_EN); +#endif r128fb_wait(sc, 5); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_SRC_PITCH, @@ -665,7 +655,7 @@ r128fb_rectfill(struct r128fb_softc *sc, int x, int y, int wi, int he, uint32_t colour) { - r128fb_wait(sc, 6); + r128fb_wait(sc, 5); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DP_GUI_MASTER_CNTL, R128_GMC_BRUSH_SOLID_COLOR | R128_GMC_SRC_DATATYPE_COLOR | @@ -681,7 +671,6 @@ r128fb_rectfill(struct r128fb_softc *sc, int x, int y, int wi, int he, (x << 16) | y); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DST_WIDTH_HEIGHT, (wi << 16) | he); - r128fb_flush_engine(sc); } static void @@ -719,7 +708,6 @@ r128fb_bitblt(struct r128fb_softc *sc, int xs, int ys, int xd, int yd, (xd << 16) | yd); bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DST_WIDTH_HEIGHT, (wi << 16) | he); - r128fb_flush_engine(sc); } static void @@ -756,12 +744,107 @@ r128fb_cursor(void *cookie, int on, int row, int col) } -#if 0 static void r128fb_putchar(void *cookie, int row, int col, u_int c, long attr) { + struct rasops_info *ri = cookie; + struct wsdisplay_font *font = PICK_FONT(ri, c); + struct vcons_screen *scr = ri->ri_hw; + struct r128fb_softc *sc = scr->scr_cookie; + + if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { + void *data; + uint32_t fg, bg; + int uc, i; + int x, y, wi, he, offset; + + wi = font->fontwidth; + he = font->fontheight; + + if (!CHAR_IN_FONT(c, font)) + return; + bg = ri->ri_devcmap[(attr >> 16) & 0xf]; + fg = ri->ri_devcmap[(attr >> 24) & 0xf]; + x = ri->ri_xorigin + col * wi; + y = ri->ri_yorigin + row * he; + if (c == 0x20) { + r128fb_rectfill(sc, x, y, wi, he, bg); + } else { + uc = c - font->firstchar; + data = (uint8_t *)font->data + uc * ri->ri_fontscale; + + r128fb_wait(sc, 8); + + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_DP_GUI_MASTER_CNTL, + R128_GMC_BRUSH_SOLID_COLOR | + R128_GMC_SRC_DATATYPE_MONO_FG_BG | + R128_ROP3_S | + R128_DP_SRC_SOURCE_HOST_DATA | + R128_GMC_DST_CLIPPING | + sc->sc_master_cntl); + + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_DP_CNTL, + R128_DST_Y_TOP_TO_BOTTOM | + R128_DST_X_LEFT_TO_RIGHT); + + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_DP_SRC_FRGD_CLR, fg); + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_DP_SRC_BKGD_CLR, bg); + + /* + * The Rage 128 doesn't have anything to skip pixels + * when colour expanding but all coordinates + * are signed so we just clip the leading bytes and + * trailing bits away + */ + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_SC_RIGHT, x + wi - 1); + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_SC_LEFT, x); + + /* needed? */ + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_SRC_X_Y, 0); + + offset = 32 - (ri->ri_font->stride << 3); + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_DST_X_Y, ((x - offset) << 16) | y); + bus_space_write_4(sc->sc_memt, sc->sc_regh, + R128_DST_WIDTH_HEIGHT, (32 << 16) | he); + + r128fb_wait(sc, he); + switch (ri->ri_font->stride) { + case 1: { + uint8_t *data8 = data; + uint32_t reg; + for (i = 0; i < he; i++) { + reg = *data8; + bus_space_write_stream_4(sc->sc_memt, + sc->sc_regh, + R128_HOST_DATA0, reg); + data8++; + } + break; + } + case 2: { + uint16_t *data16 = data; + uint32_t reg; + for (i = 0; i < he; i++) { + reg = *data16; + bus_space_write_stream_4(sc->sc_memt, + sc->sc_regh, + R128_HOST_DATA0, reg); + data16++; + } + break; + } + } + } + } } -#endif static void r128fb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) @@ -813,7 +896,7 @@ r128fb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; width = ri->ri_emuwidth; - height = ri->ri_font->fontheight*nrows; + height = ri->ri_font->fontheight * nrows; r128fb_bitblt(sc, x, ys, x, yd, width, height, R128_ROP3_S); } }