Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci one step closer to graphics acceleration:
details: https://anonhg.NetBSD.org/src/rev/76ae1a297b13
branches: trunk
changeset: 790293:76ae1a297b13
user: macallan <macallan%NetBSD.org@localhost>
date: Wed Oct 02 16:35:38 2013 +0000
description:
one step closer to graphics acceleration:
- probe and report actual amount of video memory
- add DMA machinery to feed commands to the graphics processor
- adapt a whole bunch of magic number initialization from xf86-video-nv, now
the chip actually reads commands from a buffer in video memory
diffstat:
sys/dev/pci/gffb.c | 290 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 270 insertions(+), 20 deletions(-)
diffs (truncated from 378 to 300 lines):
diff -r dc44bb9c6753 -r 76ae1a297b13 sys/dev/pci/gffb.c
--- a/sys/dev/pci/gffb.c Wed Oct 02 16:32:40 2013 +0000
+++ b/sys/dev/pci/gffb.c Wed Oct 02 16:35:38 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gffb.c,v 1.1 2013/09/18 14:30:45 macallan Exp $ */
+/* $NetBSD: gffb.c,v 1.2 2013/10/02 16:35:38 macallan Exp $ */
/*
* Copyright (c) 2007, 2012 Michael Lorenz
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gffb.c,v 1.1 2013/09/18 14:30:45 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gffb.c,v 1.2 2013/10/02 16:35:38 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -40,6 +40,7 @@
#include <sys/malloc.h>
#include <sys/lwp.h>
#include <sys/kauth.h>
+#include <sys/atomic.h>
#include <dev/videomode/videomode.h>
@@ -81,6 +82,7 @@
bus_addr_t sc_fb, sc_reg;
bus_size_t sc_fbsize, sc_regsize;
uint8_t *sc_fbaddr;
+ size_t sc_vramsize;
int sc_width, sc_height, sc_depth, sc_stride;
int sc_locked;
@@ -93,6 +95,7 @@
u_char sc_cmap_red[256];
u_char sc_cmap_green[256];
u_char sc_cmap_blue[256];
+ int sc_put, sc_current, sc_free;
glyphcache sc_gc;
};
@@ -115,6 +118,8 @@
static void gffb_init(struct gffb_softc *);
+static void gffb_make_room(struct gffb_softc *, int);
+
#if notyet
static void gffb_flush_engine(struct gffb_softc *);
static void gffb_rectfill(struct gffb_softc *, int, int, int, int,
@@ -242,8 +247,16 @@
&gffb_accessops);
sc->vd.init_screen = gffb_init_screen;
+ sc->sc_vramsize = bus_space_read_4(sc->sc_memt, sc->sc_regh,
+ GFFB_VRAM) & 0xfff00000;
+
+ printf("vram: %d MB\n", sc->sc_vramsize >> 20);
+ printf("put: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_PUT));
+ printf("get: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_GET));
/* init engine here */
gffb_init(sc);
+ printf("put: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_PUT));
+ printf("get: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_GET));
ri = &sc->sc_console_screen.scr_ri;
@@ -262,7 +275,7 @@
gffb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height,
ri->ri_devcmap[(defattr >> 16) & 0xff]);
#else
- memset(sc->sc_fbaddr,
+ memset(sc->sc_fbaddr + 0x2000,
ri->ri_devcmap[(defattr >> 16) & 0xff],
sc->sc_height * sc->sc_stride);
#endif
@@ -406,8 +419,8 @@
/* 'regular' framebuffer mmap()ing */
if (offset < sc->sc_fbsize) {
- pa = bus_space_mmap(sc->sc_memt, sc->sc_fb + offset, 0, prot,
- BUS_SPACE_MAP_LINEAR);
+ pa = bus_space_mmap(sc->sc_memt, sc->sc_fb + offset + 0x2000,
+ 0, prot, BUS_SPACE_MAP_LINEAR);
return pa;
}
@@ -466,7 +479,7 @@
ri->ri_width = sc->sc_width;
ri->ri_height = sc->sc_height;
ri->ri_stride = sc->sc_stride;
- ri->ri_bits = sc->sc_fbaddr;
+ ri->ri_bits = sc->sc_fbaddr + 0x2000;
ri->ri_flg = RI_CENTER;
if (sc->sc_depth == 8)
ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA;
@@ -594,29 +607,266 @@
return 0;
}
+
+static void
+gffb_dma_kickoff(struct gffb_softc *sc)
+{
+ volatile uint8_t scratch;
+
+ if(sc->sc_current != sc->sc_put) {
+ sc->sc_put = sc->sc_current;
+ membar_sync();
+ scratch = *sc->sc_fbaddr;
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_PUT,
+ sc->sc_put);
+ }
+}
+
+static void
+gffb_dmanext(struct gffb_softc *sc, uint32_t data)
+{
+ bus_space_write_stream_4(sc->sc_memt, sc->sc_fbh, sc->sc_current, data);
+ sc->sc_current += 4;
+}
+
+static void
+gffb_dmastart(struct gffb_softc *sc, uint32_t tag, int size)
+{
+ if(sc->sc_free <= (size << 2))
+ gffb_make_room(sc, size);
+ gffb_dmanext(sc, ((size) << 18) | (tag));
+ sc->sc_free -= ((size + 1) << 2);
+}
+
+/*
+ * from xf86_video_nv/nv_xaa.c:
+ * There is a HW race condition with videoram command buffers.
+ * You can't jump to the location of your put offset. We write put
+ * at the jump offset + SKIPS dwords with noop padding in between
+ * to solve this problem
+ */
+
+#define SKIPS 8
+
+static void
+gffb_make_room(struct gffb_softc *sc, int size)
+{
+ uint32_t get;
+
+ size = (size + 1) << 2; /* slots -> offset */
+
+ while (sc->sc_free < size) {
+ get = bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_GET);
+
+ if (sc->sc_put >= get) {
+ sc->sc_free = 0x2000 - sc->sc_current;
+ if (sc->sc_free < size) {
+ gffb_dmanext(sc, 0x20000000);
+ if(get <= SKIPS) {
+ if (sc->sc_put <= SKIPS) {
+ /* corner case - will be idle */
+ bus_space_write_4(sc->sc_memt,
+ sc->sc_regh, GFFB_FIFO_PUT,
+ SKIPS + 1);
+ }
+ do {
+ get = bus_space_read_4(
+ sc->sc_memt, sc->sc_regh,
+ GFFB_FIFO_GET);
+ } while (get <= SKIPS);
+ }
+ bus_space_write_4(sc->sc_memt, sc->sc_regh,
+ GFFB_FIFO_PUT, SKIPS);
+ sc->sc_current = sc->sc_put = SKIPS;
+ sc->sc_free = get - (SKIPS + 1);
+ }
+ } else
+ sc->sc_free = get - sc->sc_current - 1;
+ }
+}
+
+static void
+gffb_sync(struct gffb_softc *sc)
+{
+ int bail;
+
+ bail = 100000;
+ while ((bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_GET) !=
+ sc->sc_put) && (bail > 0)) {
+ bail--;
+ delay(1);
+ }
+ if (bail == 0) printf("DMA timed out\n");
+
+ bail = 100000;
+ while((bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_BUSY) != 0) &&
+ (bail > 0)) {
+ bail--;
+ delay(1);
+ }
+ if (bail == 0) printf("engine timed out\n");
+}
+
static void
gffb_init(struct gffb_softc *sc)
{
-#ifdef GFFB_DEBUG
- int i, j;
-
- /* dump the RAMDAC1 register space */
- for (i = 0; i < 0x2000; i+= 32) {
- printf("%04x:", i);
- for (j = 0; j < 32; j += 4) {
- printf(" %08x", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_RAMDAC1 + i + j));
- }
- printf("\n");
- }
-#endif
+ int i;
/* init display start */
bus_space_write_4(sc->sc_memt, sc->sc_regh,
- GFFB_CRTC0 + GFFB_DISPLAYSTART, 0);
+ GFFB_CRTC0 + GFFB_DISPLAYSTART, 0x2000);
bus_space_write_4(sc->sc_memt, sc->sc_regh,
- GFFB_CRTC1 + GFFB_DISPLAYSTART, 0);
+ GFFB_CRTC1 + GFFB_DISPLAYSTART, 0x2000);
bus_space_write_1(sc->sc_memt, sc->sc_regh,
GFFB_PDIO0 + GFFB_PEL_MASK, 0xff);
bus_space_write_1(sc->sc_memt, sc->sc_regh,
GFFB_PDIO1 + GFFB_PEL_MASK, 0xff);
+
+ /* DMA stuff. A whole lot of magic number voodoo from xf86-video-nv */
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PMC + 0x140, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PMC + 0x200, 0xffff00ff);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PMC + 0x200, 0xffffffff);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PTIMER + 0x800, 8);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PTIMER + 0x840, 3);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PTIMER + 0x500, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PTIMER + 0x400, 0xffffffff);
+ for (i = 0; i < 8; i++) {
+ bus_space_write_4(sc->sc_memt, sc->sc_regh,
+ GFFB_PMC + 0x240 + (i * 0x10), 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh,
+ GFFB_PMC + 0x244 + (i * 0x10), sc->sc_vramsize - 1);
+ }
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN, 0x80000010);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x04, 0x80011201);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x08, 0x80000011);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x0c, 0x80011202);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x10, 0x80000012);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x14, 0x80011203);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x18, 0x80000013);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x1c, 0x80011204);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x20, 0x80000014);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x24, 0x80011205);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x28, 0x80000015);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2c, 0x80011206);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x30, 0x80000016);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x34, 0x80011207);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x38, 0x80000017);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x3c, 0x80011208);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2000, 0x00003000);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2004, sc->sc_vramsize - 1);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2008, 0x00000002);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x200c, 0x00000002);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2010, 0x01008042); /* different for nv40 */
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2014, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2018, 0x12001200);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x201c, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2020, 0x01008043);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2024, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2028, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x202c, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2030, 0x01008044);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2034, 0x00000002);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2038, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x203c, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2040, 0x01008019);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2044, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2048, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x204c, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2050, 0x0100a05c);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2054, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2058, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x205c, 0);
+ /* XXX 0x0100805f if !WaitVSynvPossible */
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2060, 0x0100809f);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2064, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2068, 0x12001200);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x206c, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2070, 0x0100804a);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2074, 0x00000002);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2078, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x207c, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2080, 0x01018077);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2084, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2088, 0x12001200);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x208c, 0);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2090, 0x00003002);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2094, 0x00007fff);
+ bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_PRAMIN + 0x2098, 0x00000002); /* start of command buffer? */
Home |
Main Index |
Thread Index |
Old Index