use the drawing engine to draw characters so we don't have to sync after each

command and don't need to map the framebuffer anymore
This commit is contained in:
macallan 2010-09-30 03:16:51 +00:00
parent 9d850516d4
commit 672cabf514
1 changed files with 133 additions and 50 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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);
}
}