summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/conf/GENERIC4
-rw-r--r--sys/arch/sparc64/conf/RAMDISK4
-rw-r--r--sys/arch/sparc64/conf/files.sparc648
-rw-r--r--sys/arch/sparc64/dev/radeonfb.c662
4 files changed, 674 insertions, 4 deletions
diff --git a/sys/arch/sparc64/conf/GENERIC b/sys/arch/sparc64/conf/GENERIC
index 3c9b6cecc21..cb9c6e7c784 100644
--- a/sys/arch/sparc64/conf/GENERIC
+++ b/sys/arch/sparc64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.240 2009/06/24 11:38:40 deraadt Exp $
+# $OpenBSD: GENERIC,v 1.241 2009/07/05 17:13:25 kettenis Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -485,6 +485,8 @@ machfb* at pci? # PGX/PGX64 framebuffers
wsdisplay* at machfb?
mgx* at sbus? # SMS MGX/MGXPlus framebuffer
wsdisplay* at mgx?
+radeonfb* at pci? # XVR-100 framebuffer
+wsdisplay* at radeonfb?
raptor* at pci? # Raptor framebuffer
wsdisplay* at raptor?
rfx* at sbus? # RasterFlex framebuffer series
diff --git a/sys/arch/sparc64/conf/RAMDISK b/sys/arch/sparc64/conf/RAMDISK
index 9b1d246b212..b6c9eb05e89 100644
--- a/sys/arch/sparc64/conf/RAMDISK
+++ b/sys/arch/sparc64/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.92 2009/06/24 15:02:18 todd Exp $
+# $OpenBSD: RAMDISK,v 1.93 2009/07/05 17:13:25 kettenis Exp $
# Machine architecture; required by config(8)
machine sparc64
@@ -293,6 +293,8 @@ machfb* at pci? # PGX/PGX64 framebuffers
wsdisplay* at machfb?
mgx* at sbus? # SMS MGX/MGXPlus framebuffer
wsdisplay* at mgx?
+radeonfb* at pci? # XVR-100 framebuffer
+wsdisplay* at radeonfb?
raptor* at pci? # Raptor framebuffer
wsdisplay* at raptor?
rfx* at sbus? # RasterFlex framebuffer series
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64
index f70f55631e1..ac70dfdf778 100644
--- a/sys/arch/sparc64/conf/files.sparc64
+++ b/sys/arch/sparc64/conf/files.sparc64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc64,v 1.125 2009/06/03 23:45:15 kettenis Exp $
+# $OpenBSD: files.sparc64,v 1.126 2009/07/05 17:13:25 kettenis Exp $
# $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $
# maxpartitions must be first item in files.${ARCH}
@@ -140,6 +140,10 @@ device machfb: wsemuldisplaydev, rasops_bswap, rasops8
attach machfb at pci
file arch/sparc64/dev/machfb.c machfb
+device radeonfb: wsemuldisplaydev, rasops_bswap, rasops8, rasops32
+attach radeonfb at pci
+file arch/sparc64/dev/radeonfb.c radeonfb
+
device ifb: ifb_ident, wsemuldisplaydev, rasops_bswap, rasops8
attach ifb at pci
file arch/sparc64/dev/ifb.c ifb
@@ -148,7 +152,7 @@ device raptor: wsemuldisplaydev, rasops_bswap, rasops8
attach raptor at pci
file arch/sparc64/dev/raptor.c raptor
-device gfxp: wsemuldisplaydev, rasops_bswap, rasops8
+device gfxp: wsemuldisplaydev, rasops_bswap, rasops8, rasops32
attach gfxp at pci
file arch/sparc64/dev/gfxp.c gfxp
diff --git a/sys/arch/sparc64/dev/radeonfb.c b/sys/arch/sparc64/dev/radeonfb.c
new file mode 100644
index 00000000000..94056d17117
--- /dev/null
+++ b/sys/arch/sparc64/dev/radeonfb.c
@@ -0,0 +1,662 @@
+/* $OpenBSD: radeonfb.c,v 1.1 2009/07/05 17:13:25 kettenis Exp $ */
+
+/*
+ * Copyright (c) 2009 Mark Kettenis.
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/pciio.h>
+#include <sys/systm.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+#include <machine/openfirm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+
+#include <dev/rasops/rasops.h>
+
+#include <machine/fbvar.h>
+
+#define RADEON_PCI_MEM 0x10
+#define RADEON_PCI_MMIO 0x18
+
+#define RADEON_PALETTE_INDEX 0x00b0
+#define RADEON_PALETTE_DATA 0x00b4
+
+#define RADEON_CRTC_OFFSET 0x0224
+
+#define RADEON_SURFACE_CNTL 0x0b00
+#define RADEON_NONSURF_AP0_SWP_16BPP 0x00100000
+#define RADEON_NONSURF_AP0_SWP_32BPP 0x00200000
+#define RADEON_NONSURF_AP1_SWP_16BPP 0x00400000
+#define RADEON_NONSURF_AP1_SWP_32BPP 0x00800000
+
+#define RADEON_RBBM_STATUS 0x0e40
+#define RADEON_RBBM_FIFOCNT_MASK 0x0000007f
+#define RADEON_RBBM_ACTIVE 0x80000000
+
+#define RADEON_SRC_Y_X 0x1434
+#define RADEON_DST_Y_X 0x1438
+#define RADEON_DST_HEIGHT_WIDTH 0x143c
+
+#define RADEON_DP_GUI_MASTER_CNTL 0x146c
+#define RADEON_GMC_DST_8BPP 0x00000200
+#define RADEON_GMC_DST_32BPP 0x00000600
+#define RADEON_GMC_BRUSH_NONE 0x000000e0
+#define RADEON_GMC_BRUSH_SOLID_COLOR 0x000000d0
+#define RADEON_GMC_SRC_DATATYPE_COLOR 0x00003000
+#define RADEON_GMC_SRC_SOURCE_MEMORY 0x02000000
+#define RADEON_ROP3_S 0x00cc0000
+#define RADEON_ROP3_P 0x00f00000
+#define RADEON_GMC_CLR_CMP_CNTL_DIS 0x10000000
+
+#define RADEON_DP_BRUSH_BKGD_CLR 0x1478
+#define RADEON_DP_BRUSH_FRGD_CLR 0x147c
+
+#define RADEON_DP_CNTL 0x16c0
+#define RADEON_DST_X_LEFT_TO_RIGHT 0x00000001
+#define RADEON_DST_Y_TOP_TO_BOTTOM 0x00000002
+#define RADEON_DP_WRITE_MASK 0x16cc
+
+#define RADEON_DEFAULT_PITCH_OFFSET 0x16e0
+#define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8
+
+#define RADEON_WAIT_UNTIL 0x1720
+#define RADEON_WAIT_2D_IDLECLEAN 0x00010000
+#define RADEON_WAIT_3D_IDLECLEAN 0x00020000
+#define RADEON_WAIT_HOST_IDLECLEAN 0x00040000
+
+#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
+#define RADEON_RB3D_DC_FLUSH_ALL 0x0000000f
+#define RADEON_RB3D_DC_BUSY 0x80000000
+
+#define RADEON_COORDS(x, y) ((y << 16) | (x))
+
+#ifdef APERTURE
+extern int allowaperture;
+#endif
+
+struct radeonfb_softc {
+ struct sunfb sc_sunfb;
+
+ bus_space_tag_t sc_memt;
+ bus_space_handle_t sc_memh;
+ bus_addr_t sc_membase;
+ bus_size_t sc_memsize;
+ bus_size_t sc_memoff;
+
+ bus_space_tag_t sc_mmiot;
+ bus_space_handle_t sc_mmioh;
+ bus_addr_t sc_mmiobase;
+ bus_size_t sc_mmiosize;
+
+ pcitag_t sc_pcitag;
+
+ int sc_mode;
+ u_int8_t sc_cmap_red[256];
+ u_int8_t sc_cmap_green[256];
+ u_int8_t sc_cmap_blue[256];
+};
+
+int radeonfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t radeonfb_mmap(void *, off_t, int);
+
+struct wsdisplay_accessops radeonfb_accessops = {
+ radeonfb_ioctl,
+ radeonfb_mmap,
+ NULL, /* alloc_screen */
+ NULL, /* free_screen */
+ NULL, /* show_screen */
+ NULL, /* load_font */
+ NULL, /* scrollback */
+ NULL, /* getchar */
+ NULL, /* burner */
+ NULL /* pollc */
+};
+
+int radeonfb_match(struct device *, void *, void *);
+void radeonfb_attach(struct device *, struct device *, void *);
+
+struct cfattach radeonfb_ca = {
+ sizeof(struct radeonfb_softc), radeonfb_match, radeonfb_attach
+};
+
+struct cfdriver radeonfb_cd = {
+ NULL, "radeonfb", DV_DULL
+};
+
+int radeonfb_is_console(int);
+int radeonfb_getcmap(struct radeonfb_softc *, struct wsdisplay_cmap *);
+int radeonfb_putcmap(struct radeonfb_softc *, struct wsdisplay_cmap *);
+void radeonfb_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
+
+void radeonfb_copycols(void *, int, int, int, int);
+void radeonfb_erasecols(void *, int, int, int, long);
+void radeonfb_copyrows(void *, int, int, int);
+void radeonfb_eraserows(void *, int, int, long);
+
+void radeonfb_wait_fifo(struct radeonfb_softc *, int);
+void radeonfb_wait(struct radeonfb_softc *);
+void radeonfb_copyrect(struct radeonfb_softc *, int, int, int, int, int, int);
+void radeonfb_fillrect(struct radeonfb_softc *, int, int, int, int, int);
+
+int
+radeonfb_match(struct device *parent, void *cf, void *aux)
+{
+ struct pci_attach_args *pa = aux;
+ char buf[32];
+ int node;
+
+ node = PCITAG_NODE(pa->pa_tag);
+ OF_getprop(node, "name", buf, sizeof(buf));
+ if (strcmp(buf, "SUNW,XVR-100") == 0)
+ return (10);
+
+ return (0);
+}
+
+void
+radeonfb_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct radeonfb_softc *sc = (struct radeonfb_softc *)self;
+ struct pci_attach_args *pa = aux;
+ struct rasops_info *ri;
+ int node, console, flags;
+ char *model;
+
+ sc->sc_pcitag = pa->pa_tag;
+
+ node = PCITAG_NODE(pa->pa_tag);
+ console = radeonfb_is_console(node);
+
+ printf("\n");
+
+ model = getpropstring(node, "model");
+ printf("%s: %s", self->dv_xname, model);
+
+ if (pci_mapreg_map(pa, RADEON_PCI_MEM, PCI_MAPREG_TYPE_MEM,
+ BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh,
+ &sc->sc_membase, &sc->sc_memsize, 0)) {
+ printf("\n%s: can't map video memory\n", self->dv_xname);
+ return;
+ }
+
+ if (pci_mapreg_map(pa, RADEON_PCI_MMIO, PCI_MAPREG_TYPE_MEM, 0,
+ &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase,
+ &sc->sc_mmiosize, 0)) {
+ printf("\n%s: can't map registers\n", self->dv_xname);
+ return;
+ }
+
+ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
+
+ printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
+
+ /*
+ * The firmware sets up the framebuffer such that at starts at
+ * an offset from the start of video memory.
+ */
+ sc->sc_memoff =
+ bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_CRTC_OFFSET);
+
+ ri = &sc->sc_sunfb.sf_ro;
+ ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
+ ri->ri_bits += sc->sc_memoff;
+ ri->ri_hw = sc;
+
+ if (sc->sc_sunfb.sf_depth == 32)
+ flags = 0;
+ else
+ flags = RI_BSWAP;
+
+ fbwscons_init(&sc->sc_sunfb, flags, console);
+ fbwscons_setcolormap(&sc->sc_sunfb, radeonfb_setcolor);
+ sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
+
+ /*
+ * Setup acceleration engine.
+ */
+ radeonfb_wait_fifo(sc, 2);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DEFAULT_PITCH_OFFSET,
+ ((sc->sc_sunfb.sf_linebytes >> 6) << 22) | (sc->sc_memoff >> 10));
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DEFAULT_SC_BOTTOM_RIGHT, 0x1fff1fff);
+
+ ri->ri_ops.copyrows = radeonfb_copyrows;
+ ri->ri_ops.copycols = radeonfb_copycols;
+ ri->ri_ops.eraserows = radeonfb_eraserows;
+ ri->ri_ops.erasecols = radeonfb_erasecols;
+
+ if (console)
+ fbwscons_console_init(&sc->sc_sunfb, -1);
+ fbwscons_attach(&sc->sc_sunfb, &radeonfb_accessops, console);
+}
+
+int
+radeonfb_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ struct radeonfb_softc *sc = v;
+ struct wsdisplay_fbinfo *wdf;
+ struct pcisel *sel;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_RADEONFB;
+ break;
+ case WSDISPLAYIO_SMODE:
+ sc->sc_mode = *(u_int *)data;
+ if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
+ struct rasops_info *ri = &sc->sc_sunfb.sf_ro;
+
+ /* Restore colormap. */
+ fbwscons_setcolormap(&sc->sc_sunfb, radeonfb_setcolor);
+
+ /* Clear screen. */
+ ri = &sc->sc_sunfb.sf_ro;
+ radeonfb_fillrect(sc, 0, 0, ri->ri_width,
+ ri->ri_height, ri->ri_devcmap[WSCOL_WHITE]);
+ }
+ break;
+
+ case WSDISPLAYIO_GINFO:
+ wdf = (void *)data;
+ wdf->height = sc->sc_sunfb.sf_height;
+ wdf->width = sc->sc_sunfb.sf_width;
+ wdf->depth = sc->sc_sunfb.sf_depth;
+ if (sc->sc_sunfb.sf_depth == 32)
+ wdf->cmsize = 0;
+ else
+ wdf->cmsize = 256;
+ break;
+ case WSDISPLAYIO_GETSUPPORTEDDEPTH:
+ if (sc->sc_sunfb.sf_depth == 32)
+ *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
+ else
+ return (-1);
+ break;
+ case WSDISPLAYIO_LINEBYTES:
+ *(u_int *)data = sc->sc_sunfb.sf_linebytes;
+ break;
+
+ case WSDISPLAYIO_GETCMAP:
+ return radeonfb_getcmap(sc, (struct wsdisplay_cmap *)data);
+ case WSDISPLAYIO_PUTCMAP:
+ return radeonfb_putcmap(sc, (struct wsdisplay_cmap *)data);
+
+ case WSDISPLAYIO_GPCIID:
+ sel = (struct pcisel *)data;
+ sel->pc_bus = PCITAG_BUS(sc->sc_pcitag);
+ sel->pc_dev = PCITAG_DEV(sc->sc_pcitag);
+ sel->pc_func = PCITAG_FUN(sc->sc_pcitag);
+ break;
+
+ case WSDISPLAYIO_SVIDEO:
+ case WSDISPLAYIO_GVIDEO:
+ break;
+
+ case WSDISPLAYIO_GCURPOS:
+ case WSDISPLAYIO_SCURPOS:
+ case WSDISPLAYIO_GCURMAX:
+ case WSDISPLAYIO_GCURSOR:
+ case WSDISPLAYIO_SCURSOR:
+ default:
+ return -1; /* not supported yet */
+ }
+
+ return (0);
+}
+
+paddr_t
+radeonfb_mmap(void *v, off_t off, int prot)
+{
+ struct radeonfb_softc *sc = v;
+
+ if (off & PGOFSET)
+ return (-1);
+
+ switch (sc->sc_mode) {
+ case WSDISPLAYIO_MODE_MAPPED:
+#ifdef APERTURE
+ if (allowaperture == 0)
+ return (-1);
+#endif
+
+ if (sc->sc_mmiosize == 0)
+ return (-1);
+
+ if (off >= sc->sc_membase &&
+ off < (sc->sc_membase + sc->sc_memsize))
+ return (bus_space_mmap(sc->sc_memt,
+ sc->sc_membase, off - sc->sc_membase,
+ prot, BUS_SPACE_MAP_LINEAR));
+
+ if (off >= sc->sc_mmiobase &&
+ off < (sc->sc_mmiobase + sc->sc_mmiosize))
+ return (bus_space_mmap(sc->sc_mmiot,
+ sc->sc_mmiobase, off - sc->sc_mmiobase,
+ prot, BUS_SPACE_MAP_LINEAR));
+ break;
+
+ case WSDISPLAYIO_MODE_DUMBFB:
+ if ((sc->sc_memoff % PAGE_SIZE) != 0)
+ return (-1);
+
+ if (off >= 0 && off < sc->sc_memsize / 2) {
+ bus_addr_t base = sc->sc_membase + sc->sc_memoff;
+
+ /*
+ * In 32bpp mode, use the second aperture,
+ * which has been set up by the firmware to do
+ * proper byte swapping.
+ */
+ if (sc->sc_sunfb.sf_depth == 32)
+ base += sc->sc_memsize / 2;
+
+ return (bus_space_mmap(sc->sc_memt, base, off,
+ prot, BUS_SPACE_MAP_LINEAR));
+ }
+ break;
+ }
+
+ return (-1);
+}
+
+int
+radeonfb_is_console(int node)
+{
+ extern int fbnode;
+
+ return (fbnode == node);
+}
+
+int
+radeonfb_getcmap(struct radeonfb_softc *sc, struct wsdisplay_cmap *cm)
+{
+ u_int index = cm->index;
+ u_int count = cm->count;
+ int error;
+
+ if (index >= 256 || count > 256 - index)
+ return (EINVAL);
+
+ error = copyout(&sc->sc_cmap_red[index], cm->red, count);
+ if (error)
+ return (error);
+ error = copyout(&sc->sc_cmap_green[index], cm->green, count);
+ if (error)
+ return (error);
+ error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
+ if (error)
+ return (error);
+ return (0);
+}
+
+int
+radeonfb_putcmap(struct radeonfb_softc *sc, struct wsdisplay_cmap *cm)
+{
+ u_int index = cm->index;
+ u_int count = cm->count;
+ u_int i;
+ int error;
+ u_char *r, *g, *b;
+
+ if (index >= 256 || count > 256 - index)
+ return (EINVAL);
+
+ if ((error = copyin(cm->red, &sc->sc_cmap_red[index], count)) != 0)
+ return (error);
+ if ((error = copyin(cm->green, &sc->sc_cmap_green[index], count)) != 0)
+ return (error);
+ if ((error = copyin(cm->blue, &sc->sc_cmap_blue[index], count)) != 0)
+ return (error);
+
+ r = &sc->sc_cmap_red[index];
+ g = &sc->sc_cmap_green[index];
+ b = &sc->sc_cmap_blue[index];
+
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_PALETTE_INDEX, index);
+ for (i = 0; i < count; i++) {
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_PALETTE_DATA, (*r << 16) | (*g << 8) | *b);
+ r++, g++, b++;
+ }
+ return (0);
+}
+
+void
+radeonfb_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
+{
+ struct radeonfb_softc *sc = v;
+
+ sc->sc_cmap_red[index] = r;
+ sc->sc_cmap_green[index] = g;
+ sc->sc_cmap_blue[index] = b;
+
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_PALETTE_INDEX, index);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_PALETTE_DATA, (r << 16) | (g << 8) | b);
+}
+
+/*
+ * Accelerated routines.
+ */
+
+void
+radeonfb_copycols(void *cookie, int row, int src, int dst, int num)
+{
+ struct rasops_info *ri = cookie;
+ struct radeonfb_softc *sc = ri->ri_hw;
+
+ num *= ri->ri_font->fontwidth;
+ src *= ri->ri_font->fontwidth;
+ dst *= ri->ri_font->fontwidth;
+ row *= ri->ri_font->fontheight;
+
+ radeonfb_copyrect(sc, ri->ri_xorigin + src, ri->ri_yorigin + row,
+ ri->ri_xorigin + dst, ri->ri_yorigin + row,
+ num, ri->ri_font->fontheight);
+}
+
+void
+radeonfb_erasecols(void *cookie, int row, int col, int num, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct radeonfb_softc *sc = ri->ri_hw;
+ int bg, fg;
+
+ 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;
+
+ radeonfb_fillrect(sc, ri->ri_xorigin + col, ri->ri_yorigin + row,
+ num, ri->ri_font->fontheight, ri->ri_devcmap[bg]);
+}
+
+void
+radeonfb_copyrows(void *cookie, int src, int dst, int num)
+{
+ struct rasops_info *ri = cookie;
+ struct radeonfb_softc *sc = ri->ri_hw;
+
+ num *= ri->ri_font->fontheight;
+ src *= ri->ri_font->fontheight;
+ dst *= ri->ri_font->fontheight;
+
+ radeonfb_copyrect(sc, ri->ri_xorigin, ri->ri_yorigin + src,
+ ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num);
+}
+
+void
+radeonfb_eraserows(void *cookie, int row, int num, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct radeonfb_softc *sc = ri->ri_hw;
+ int bg, fg;
+ int x, y, w;
+
+ 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;
+ }
+ radeonfb_fillrect(sc, x, y, w, num, ri->ri_devcmap[bg]);
+}
+
+void
+radeonfb_wait_fifo(struct radeonfb_softc *sc, int n)
+{
+ int i;
+
+ for (i = 1000000; i != 0; i--) {
+ if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK) >= n)
+ break;
+ DELAY(1);
+ }
+}
+
+void
+radeonfb_wait(struct radeonfb_softc *sc)
+{
+ int i;
+
+ radeonfb_wait_fifo(sc, 64);
+
+ for (i = 1000000; i != 0; i--) {
+ if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) == 0)
+ break;
+ DELAY(1);
+ }
+
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH_ALL);
+
+ for (i = 1000000; i != 0; i--) {
+ if ((bus_space_read_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY) == 0)
+ break;
+ DELAY(1);
+ }
+}
+
+void
+radeonfb_copyrect(struct radeonfb_softc *sc, int sx, int sy, int dx, int dy,
+ int w, int h)
+{
+ uint32_t gmc;
+ uint32_t dir;
+
+ radeonfb_wait_fifo(sc, 1);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_WAIT_UNTIL,
+ RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN);
+
+ if (dy < sy) {
+ dir = RADEON_DST_Y_TOP_TO_BOTTOM;
+ } else {
+ sy += h - 1;
+ dy += h - 1;
+ dir = 0;
+ }
+ if (dx < sx) {
+ dir |= RADEON_DST_X_LEFT_TO_RIGHT;
+ } else {
+ sx += w - 1;
+ dx += w - 1;
+ }
+
+ radeonfb_wait_fifo(sc, 6);
+
+ if (sc->sc_sunfb.sf_depth == 32)
+ gmc = RADEON_GMC_DST_32BPP;
+ else
+ gmc = RADEON_GMC_DST_8BPP;
+ gmc |= RADEON_GMC_BRUSH_NONE;
+ gmc |= RADEON_GMC_SRC_DATATYPE_COLOR;
+ gmc |= RADEON_GMC_SRC_SOURCE_MEMORY;
+ gmc |= RADEON_ROP3_S;
+ gmc |= RADEON_GMC_CLR_CMP_CNTL_DIS;
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DP_GUI_MASTER_CNTL, gmc);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DP_WRITE_MASK, 0xffffffff);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DP_CNTL, dir);
+
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_SRC_Y_X, RADEON_COORDS(sx, sy));
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DST_Y_X, RADEON_COORDS(dx, dy));
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DST_HEIGHT_WIDTH, RADEON_COORDS(w, h));
+
+ radeonfb_wait(sc);
+}
+
+void
+radeonfb_fillrect(struct radeonfb_softc *sc, int x, int y, int w, int h,
+ int color)
+{
+ uint32_t gmc;
+
+ radeonfb_wait_fifo(sc, 1);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_WAIT_UNTIL,
+ RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN);
+
+ radeonfb_wait_fifo(sc, 6);
+
+ if (sc->sc_sunfb.sf_depth == 32)
+ gmc = RADEON_GMC_DST_32BPP;
+ else
+ gmc = RADEON_GMC_DST_8BPP;
+ gmc |= RADEON_GMC_BRUSH_SOLID_COLOR;
+ gmc |= RADEON_GMC_SRC_DATATYPE_COLOR;
+ gmc |= RADEON_ROP3_P;
+ gmc |= RADEON_GMC_CLR_CMP_CNTL_DIS;
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DP_GUI_MASTER_CNTL, gmc);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DP_BRUSH_FRGD_CLR, color);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DP_WRITE_MASK, 0xffffffff);
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh, RADEON_DP_CNTL,
+ RADEON_DST_Y_TOP_TO_BOTTOM | RADEON_DST_X_LEFT_TO_RIGHT);
+
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DST_Y_X, RADEON_COORDS(x, y));
+ bus_space_write_4(sc->sc_mmiot, sc->sc_mmioh,
+ RADEON_DST_HEIGHT_WIDTH, RADEON_COORDS(w, h));
+
+ radeonfb_wait(sc);
+}