summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-05-22 10:59:14 +1000
committerBen Skeggs <bskeggs@redhat.com>2013-01-09 14:32:47 +1000
commit827ac5471ac6b03d7a74e8fe0805787b0b3c8364 (patch)
treec493524ff33dedb9f6aa54b51832b4947921f75b /bin
downloadnouveau-827ac5471ac6b03d7a74e8fe0805787b0b3c8364.tar.gz
initial import of nouveau kernel module core, some simple tools, and drm
Ignore (or, if you're really keen, fix) any of the horrors that are part of the emulate-linux-on-libpciaccess (lib/) layer. When I started down this path I was only aiming to prototype the reworked driver core, and never actually intended on going quite this far with things, but it turns out that being able to develop and test the nouveau core from userspace is *very* useful. This tree is based on the code available as of Linux 3.8-rc2. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'bin')
-rw-r--r--bin/Makefile.am15
-rw-r--r--bin/nv_disp.c51
-rw-r--r--bin/nv_rd08.c7
-rw-r--r--bin/nv_rd16.c7
-rw-r--r--bin/nv_rd32.c7
-rw-r--r--bin/nv_rdfunc.h88
-rw-r--r--bin/nv_rf08.c6
-rw-r--r--bin/nv_rf16.c6
-rw-r--r--bin/nv_rf32.c6
-rw-r--r--bin/nv_rffunc.h41
-rw-r--r--bin/nv_ri08.c6
-rw-r--r--bin/nv_ri16.c6
-rw-r--r--bin/nv_ri32.c6
-rw-r--r--bin/nv_rifunc.h47
-rw-r--r--bin/nv_rs08.c7
-rw-r--r--bin/nv_rs16.c7
-rw-r--r--bin/nv_rs32.c7
-rw-r--r--bin/nv_rsfunc.h26
-rw-r--r--bin/nv_rv08.c7
-rw-r--r--bin/nv_rv16.c7
-rw-r--r--bin/nv_rv32.c7
-rw-r--r--bin/nv_rvfunc.h26
-rw-r--r--bin/nv_wf08.c6
-rw-r--r--bin/nv_wf16.c6
-rw-r--r--bin/nv_wf32.c6
-rw-r--r--bin/nv_wffunc.h41
-rw-r--r--bin/nv_wi08.c6
-rw-r--r--bin/nv_wi16.c6
-rw-r--r--bin/nv_wi32.c6
-rw-r--r--bin/nv_wifunc.h47
-rw-r--r--bin/nv_wr08.c7
-rw-r--r--bin/nv_wr16.c7
-rw-r--r--bin/nv_wr32.c7
-rw-r--r--bin/nv_wrfunc.h101
-rw-r--r--bin/nv_ws08.c7
-rw-r--r--bin/nv_ws16.c7
-rw-r--r--bin/nv_ws32.c7
-rw-r--r--bin/nv_wsfunc.h24
-rw-r--r--bin/nv_wv08.c7
-rw-r--r--bin/nv_wv16.c7
-rw-r--r--bin/nv_wv32.c7
-rw-r--r--bin/nv_wvfunc.h24
42 files changed, 729 insertions, 0 deletions
diff --git a/bin/Makefile.am b/bin/Makefile.am
new file mode 100644
index 000000000..998e5ebe4
--- /dev/null
+++ b/bin/Makefile.am
@@ -0,0 +1,15 @@
+bin_PROGRAMS = \
+ nv_rd08 nv_rd16 nv_rd32 nv_wr08 nv_wr16 nv_wr32 \
+ nv_rf08 nv_rf16 nv_rf32 nv_wf08 nv_wf16 nv_wf32 \
+ nv_ri08 nv_ri16 nv_ri32 nv_wi08 nv_wi16 nv_wi32 \
+ nv_rv08 nv_rv16 nv_rv32 nv_wv08 nv_wv16 nv_wv32 \
+ nv_rs08 nv_rs16 nv_rs32 nv_ws08 nv_ws16 nv_ws32 \
+ nv_disp
+
+AM_CPPFLAGS = -I$(top_srcdir)/nvkm/include \
+ -I$(top_srcdir)/nvkm \
+ -I$(top_srcdir)/lib/
+
+LDADD = -lpciaccess \
+ $(top_srcdir)/lib/libpciaccessos.la \
+ $(top_srcdir)/nvkm/libnouveau.la
diff --git a/bin/nv_disp.c b/bin/nv_disp.c
new file mode 100644
index 000000000..2b2011380
--- /dev/null
+++ b/bin/nv_disp.c
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static unsigned long chan = 0;
+
+static void
+nv_disp(struct nouveau_object *device, u16 mthd, u32 data)
+{
+ if (nv_device(device)->card_type == NV_50) {
+ u32 ctrl = nv_ro32(device, 0x610300 + (chan * 8));
+ nv_wo32(device, 0x610300 + (chan * 8), ctrl | 0x00000001);
+ nv_wo32(device, 0x610304 + (chan * 8), data);
+ nv_wo32(device, 0x610300 + (chan * 8), mthd | 0x80000001);
+ while (nv_ro32(device, 0x610300 + (chan * 8)) & 0x80000000) {}
+ nv_wo32(device, 0x610300 + (chan * 8), ctrl);
+ } else
+ if (nv_device(device)->card_type >= NV_D0 &&
+ nv_device(device)->card_type <= NV_E0) {
+ u32 ctrl = nv_ro32(device, 0x610700 + (chan * 16));
+ nv_wo32(device, 0x610700 + (chan * 16), ctrl | 0x00000001);
+ nv_wo32(device, 0x610704 + (chan * 16), data);
+ nv_wo32(device, 0x610700 + (chan * 16), mthd | 0x80000001);
+ while (nv_ro32(device, 0x610700 + (chan * 16)) & 0x80000000) {}
+ nv_wo32(device, 0x610700 + (chan * 16), ctrl);
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define FMTADDR "0x%04lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_disp"
+#define CAST u32
+#define WRITE(o,v) nv_disp(device, (o), (v))
+#define MAIN main_
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"
+
+int
+main(int argc, char **argv)
+{
+ if (argc < 2 || ((chan = strtol(argv[1], NULL, 0)) == ULONG_MAX))
+ return 0;
+
+ argv[1] = argv[0];
+ return main_(argc - 1, argv + 1);
+}
diff --git a/bin/nv_rd08.c b/bin/nv_rd08.c
new file mode 100644
index 000000000..f3384416f
--- /dev/null
+++ b/bin/nv_rd08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rd08"
+#define CAST u8
+#define READ(o) nv_ro08(device, (o))
+#define MAIN main
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rd16.c b/bin/nv_rd16.c
new file mode 100644
index 000000000..4c37cb7a5
--- /dev/null
+++ b/bin/nv_rd16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rd16"
+#define CAST u16
+#define READ(o) nv_ro16(device, (o))
+#define MAIN main
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rd32.c b/bin/nv_rd32.c
new file mode 100644
index 000000000..95cbd3b5c
--- /dev/null
+++ b/bin/nv_rd32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rd32"
+#define CAST u32
+#define READ(o) nv_ro32(device, (o))
+#define MAIN main
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rdfunc.h b/bin/nv_rdfunc.h
new file mode 100644
index 000000000..bca7cca3a
--- /dev/null
+++ b/bin/nv_rdfunc.h
@@ -0,0 +1,88 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/class.h>
+
+#ifndef ENABLE
+#define ENABLE NV_DEVICE_DISABLE_MMIO
+#endif
+#ifndef DEBUG0
+#define DEBUG0 0ULL
+#endif
+
+int
+main(int argc, char **argv)
+{
+ struct nouveau_object *client;
+ struct nouveau_object *device;
+ struct nv_device_class args;
+ char *rstr = NULL;
+ int quiet = 0;
+ int ret, c;
+
+ while ((c = getopt(argc, argv, "-q")) != -1) {
+ switch (c) {
+ case 'q':
+ quiet = 1;
+ break;
+ case 1:
+ if (rstr)
+ return 1;
+ rstr = optarg;
+ break;
+ }
+ }
+
+ ret = os_client_new(NULL, "fatal", argc, argv, &client);
+ if (ret)
+ return ret;
+
+ args.device = ~0ULL;
+ args.disable = ~ENABLE;
+ args.debug0 = ~DEBUG0;
+
+ ret = nouveau_object_new(client, ~0, 0, 0x0080, &args, sizeof(args),
+ &device);
+ if (ret)
+ return ret;
+
+ while (rstr && *rstr != '\0') {
+ unsigned long cnt = 1;
+ unsigned long reg;
+
+ if ((reg = strtoul(rstr, &rstr, 0)) == ULONG_MAX)
+ return 1;
+
+ if (*rstr == '/') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ } else
+ if (*rstr == '+') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ cnt /= sizeof(CAST);
+ }
+
+ switch (*rstr) {
+ case ',':
+ rstr++;
+ case '\0':
+ while (cnt--) {
+ CAST val = READ(reg);
+ if (quiet)
+ printk(FMTDATA"\n", val);
+ else
+ printk(NAME" "FMTADDR" "FMTDATA"\n", reg, val);
+ reg += sizeof(CAST);
+ }
+ break;
+ default:
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/bin/nv_rf08.c b/bin/nv_rf08.c
new file mode 100644
index 000000000..864b98ca6
--- /dev/null
+++ b/bin/nv_rf08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rf08"
+#define CAST u8
+#define MAIN main
+#include "nv_rffunc.h"
diff --git a/bin/nv_rf16.c b/bin/nv_rf16.c
new file mode 100644
index 000000000..d40c6e20f
--- /dev/null
+++ b/bin/nv_rf16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rf16"
+#define CAST u16
+#define MAIN main
+#include "nv_rffunc.h"
diff --git a/bin/nv_rf32.c b/bin/nv_rf32.c
new file mode 100644
index 000000000..c84c77b09
--- /dev/null
+++ b/bin/nv_rf32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rf32"
+#define CAST u32
+#define MAIN main
+#include "nv_rffunc.h"
diff --git a/bin/nv_rffunc.h b/bin/nv_rffunc.h
new file mode 100644
index 000000000..f7db0317f
--- /dev/null
+++ b/bin/nv_rffunc.h
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static CAST
+nv_rfb(struct nouveau_object *device, u64 offset)
+{
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_04 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ map = ioremap(pci_resource_start(nv_device(device)->pdev, 1) +
+ page, PAGE_SIZE);
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ return *(CAST *)(map + addr);
+}
+
+#define READ(o) nv_rfb(device, (o))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_rdfunc.h"
diff --git a/bin/nv_ri08.c b/bin/nv_ri08.c
new file mode 100644
index 000000000..5cb4fe74d
--- /dev/null
+++ b/bin/nv_ri08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_ri08"
+#define CAST u8
+#define MAIN main
+#include "nv_rifunc.h"
diff --git a/bin/nv_ri16.c b/bin/nv_ri16.c
new file mode 100644
index 000000000..81aa04894
--- /dev/null
+++ b/bin/nv_ri16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_ri16"
+#define CAST u16
+#define MAIN main
+#include "nv_rifunc.h"
diff --git a/bin/nv_ri32.c b/bin/nv_ri32.c
new file mode 100644
index 000000000..25a98f568
--- /dev/null
+++ b/bin/nv_ri32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_ri32"
+#define CAST u32
+#define MAIN main
+#include "nv_rifunc.h"
diff --git a/bin/nv_rifunc.h b/bin/nv_rifunc.h
new file mode 100644
index 000000000..096e16f2d
--- /dev/null
+++ b/bin/nv_rifunc.h
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static CAST
+nv_rfb(struct nouveau_object *device, u64 offset)
+{
+ struct pci_dev *pdev = nv_device(device)->pdev;
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_40 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ if (pci_resource_len(pdev, 2)) {
+ map = ioremap(pci_resource_start(pdev, 2) +
+ page, PAGE_SIZE);
+ } else {
+ map = ioremap(pci_resource_start(pdev, 3) +
+ page, PAGE_SIZE);
+ }
+
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ return *(CAST *)(map + addr);
+}
+
+#define READ(o) nv_rfb(device, (o))
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rs08.c b/bin/nv_rs08.c
new file mode 100644
index 000000000..b379d7fe8
--- /dev/null
+++ b/bin/nv_rs08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rs08"
+#define CAST u8
+#define MAIN main
+#define RSYS nv_ro08
+#include "nv_rsfunc.h"
diff --git a/bin/nv_rs16.c b/bin/nv_rs16.c
new file mode 100644
index 000000000..6582197e6
--- /dev/null
+++ b/bin/nv_rs16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rs16"
+#define CAST u16
+#define MAIN main
+#define RSYS nv_ro16
+#include "nv_rsfunc.h"
diff --git a/bin/nv_rs32.c b/bin/nv_rs32.c
new file mode 100644
index 000000000..326f49fd9
--- /dev/null
+++ b/bin/nv_rs32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rs32"
+#define CAST u32
+#define MAIN main
+#define RSYS nv_ro32
+#include "nv_rsfunc.h"
diff --git a/bin/nv_rsfunc.h b/bin/nv_rsfunc.h
new file mode 100644
index 000000000..c73f1f737
--- /dev/null
+++ b/bin/nv_rsfunc.h
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static CAST
+nv_rsys(struct nouveau_object *device, u64 addr)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ CAST data;
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x02000000 | (addr >> 16));
+ data = RSYS(device, 0x700000 + (addr & 0xffffULL));
+ nv_wo32(device, 0x001700, pmem);
+ return data;
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define READ(o) nv_rsys(device, (o))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rv08.c b/bin/nv_rv08.c
new file mode 100644
index 000000000..1b51c8f40
--- /dev/null
+++ b/bin/nv_rv08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rv08"
+#define CAST u8
+#define MAIN main
+#define RVRAM nv_ro08
+#include "nv_rvfunc.h"
diff --git a/bin/nv_rv16.c b/bin/nv_rv16.c
new file mode 100644
index 000000000..9f6b6e47e
--- /dev/null
+++ b/bin/nv_rv16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rv16"
+#define CAST u16
+#define MAIN main
+#define RVRAM nv_ro16
+#include "nv_rvfunc.h"
diff --git a/bin/nv_rv32.c b/bin/nv_rv32.c
new file mode 100644
index 000000000..d147bf17a
--- /dev/null
+++ b/bin/nv_rv32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rv32"
+#define CAST u32
+#define MAIN main
+#define RVRAM nv_ro32
+#include "nv_rvfunc.h"
diff --git a/bin/nv_rvfunc.h b/bin/nv_rvfunc.h
new file mode 100644
index 000000000..18f43219c
--- /dev/null
+++ b/bin/nv_rvfunc.h
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static CAST
+nv_rvram(struct nouveau_object *device, u64 addr)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ CAST data;
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x00000000 | (addr >> 16));
+ data = RVRAM(device, 0x700000 + (addr & 0xffffULL));
+ nv_wo32(device, 0x001700, pmem);
+ return data;
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define READ(o) nv_rvram(device, (o))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_rdfunc.h"
diff --git a/bin/nv_wf08.c b/bin/nv_wf08.c
new file mode 100644
index 000000000..f05a7e7cd
--- /dev/null
+++ b/bin/nv_wf08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wf08"
+#define CAST u8
+#define MAIN main
+#include "nv_wffunc.h"
diff --git a/bin/nv_wf16.c b/bin/nv_wf16.c
new file mode 100644
index 000000000..c1b747cc2
--- /dev/null
+++ b/bin/nv_wf16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wf16"
+#define CAST u16
+#define MAIN main
+#include "nv_wffunc.h"
diff --git a/bin/nv_wf32.c b/bin/nv_wf32.c
new file mode 100644
index 000000000..88140064c
--- /dev/null
+++ b/bin/nv_wf32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wf32"
+#define CAST u32
+#define MAIN main
+#include "nv_wffunc.h"
diff --git a/bin/nv_wffunc.h b/bin/nv_wffunc.h
new file mode 100644
index 000000000..4166afd89
--- /dev/null
+++ b/bin/nv_wffunc.h
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static void
+nv_wfb(struct nouveau_object *device, u64 offset, CAST data)
+{
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_04 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ map = ioremap(pci_resource_start(nv_device(device)->pdev, 1) +
+ page, PAGE_SIZE);
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ *(CAST *)(map + addr) = data;
+}
+
+#define WRITE(o,v) nv_wfb(device, (o), (v))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wi08.c b/bin/nv_wi08.c
new file mode 100644
index 000000000..ebd5fb530
--- /dev/null
+++ b/bin/nv_wi08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wi08"
+#define CAST u8
+#define MAIN main
+#include "nv_wifunc.h"
diff --git a/bin/nv_wi16.c b/bin/nv_wi16.c
new file mode 100644
index 000000000..dc815e7e9
--- /dev/null
+++ b/bin/nv_wi16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wi16"
+#define CAST u16
+#define MAIN main
+#include "nv_wifunc.h"
diff --git a/bin/nv_wi32.c b/bin/nv_wi32.c
new file mode 100644
index 000000000..a2420facf
--- /dev/null
+++ b/bin/nv_wi32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wi32"
+#define CAST u32
+#define MAIN main
+#include "nv_wifunc.h"
diff --git a/bin/nv_wifunc.h b/bin/nv_wifunc.h
new file mode 100644
index 000000000..8e4abb1fc
--- /dev/null
+++ b/bin/nv_wifunc.h
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static void
+nv_wfb(struct nouveau_object *device, u64 offset, CAST data)
+{
+ struct pci_dev *pdev = nv_device(device)->pdev;
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_40 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ if (pci_resource_len(pdev, 2)) {
+ map = ioremap(pci_resource_start(pdev, 2) +
+ page, PAGE_SIZE);
+ } else {
+ map = ioremap(pci_resource_start(pdev, 3) +
+ page, PAGE_SIZE);
+ }
+
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ *(CAST *)(map + addr) = data;
+}
+
+#define WRITE(o,v) nv_wfb(device, (o), (v))
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wr08.c b/bin/nv_wr08.c
new file mode 100644
index 000000000..184bfef46
--- /dev/null
+++ b/bin/nv_wr08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wr08"
+#define CAST u8
+#define WRITE(o,v) nv_wo08(device, (o), (v))
+#define MAIN main
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wr16.c b/bin/nv_wr16.c
new file mode 100644
index 000000000..0e2271eb6
--- /dev/null
+++ b/bin/nv_wr16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wr16"
+#define CAST u16
+#define WRITE(o,v) nv_wo16(device, (o), (v))
+#define MAIN main
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wr32.c b/bin/nv_wr32.c
new file mode 100644
index 000000000..6dd188840
--- /dev/null
+++ b/bin/nv_wr32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wr32"
+#define CAST u32
+#define WRITE(o,v) nv_wo32(device, (o), (v))
+#define MAIN main
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wrfunc.h b/bin/nv_wrfunc.h
new file mode 100644
index 000000000..eae75c248
--- /dev/null
+++ b/bin/nv_wrfunc.h
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/class.h>
+
+#ifndef ENABLE
+#define ENABLE NV_DEVICE_DISABLE_MMIO
+#endif
+#ifndef DEBUG0
+#define DEBUG0 0ULL
+#endif
+
+int
+MAIN(int argc, char **argv)
+{
+ struct nouveau_object *client;
+ struct nouveau_object *device;
+ struct nv_device_class args;
+ char *rstr = NULL;
+ char *vstr = NULL;
+ int quiet = 0;
+ int ret, c;
+
+ while ((c = getopt(argc, argv, "-q")) != -1) {
+ switch (c) {
+ case 'q':
+ quiet = 1;
+ break;
+ case 1:
+ if (rstr) {
+ if (vstr)
+ return 1;
+ vstr = optarg;
+ } else {
+ rstr = optarg;
+ }
+ break;
+ }
+ }
+
+ ret = os_client_new(NULL, "fatal", argc, argv, &client);
+ if (ret)
+ return ret;
+
+ args.device = ~0ULL;
+ args.disable = ~ENABLE;
+ args.debug0 = ~DEBUG0;
+
+ ret = nouveau_object_new(client, ~0, 0, 0x0080, &args, sizeof(args),
+ &device);
+ if (ret)
+ return ret;
+
+ while (rstr && *rstr != '\0') {
+ unsigned long cnt = 1;
+ unsigned long reg;
+ unsigned long val;
+
+ if ((reg = strtoul(rstr, &rstr, 0)) == ULONG_MAX)
+ return 1;
+
+ if (*rstr == '/') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ } else
+ if (*rstr == '+') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ cnt /= sizeof(CAST);
+ }
+
+ if (*rstr == '=') {
+ if ((val = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ } else {
+ if (!vstr ||
+ (val = strtoul(vstr, NULL, 0)) == ULONG_MAX)
+ return 1;
+ }
+
+ switch (*rstr) {
+ case ',':
+ rstr++;
+ case '\0':
+ while (cnt--) {
+ if (!quiet)
+ printk(NAME" "FMTADDR" "FMTDATA"\n", reg, (CAST)val);
+ WRITE(reg, val);
+ reg += sizeof(CAST);
+ }
+ break;
+ default:
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/bin/nv_ws08.c b/bin/nv_ws08.c
new file mode 100644
index 000000000..5d49f2edc
--- /dev/null
+++ b/bin/nv_ws08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rs08"
+#define CAST u8
+#define MAIN main
+#define WSYS nv_wo08
+#include "nv_wsfunc.h"
diff --git a/bin/nv_ws16.c b/bin/nv_ws16.c
new file mode 100644
index 000000000..a3f0702be
--- /dev/null
+++ b/bin/nv_ws16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_ws16"
+#define CAST u16
+#define MAIN main
+#define WSYS nv_wo16
+#include "nv_wsfunc.h"
diff --git a/bin/nv_ws32.c b/bin/nv_ws32.c
new file mode 100644
index 000000000..78756fe09
--- /dev/null
+++ b/bin/nv_ws32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_ws32"
+#define CAST u32
+#define MAIN main
+#define WSYS nv_wo32
+#include "nv_wsfunc.h"
diff --git a/bin/nv_wsfunc.h b/bin/nv_wsfunc.h
new file mode 100644
index 000000000..596eede5f
--- /dev/null
+++ b/bin/nv_wsfunc.h
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void
+nv_wsys(struct nouveau_object *device, u64 addr, CAST data)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x02000000 | (addr >> 16));
+ WSYS(device, 0x700000 + (addr & 0xffffULL), data);
+ nv_wo32(device, 0x001700, pmem);
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define WRITE(o,v) nv_wsys(device, (o), (v))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wv08.c b/bin/nv_wv08.c
new file mode 100644
index 000000000..c78d42e83
--- /dev/null
+++ b/bin/nv_wv08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wv08"
+#define CAST u8
+#define MAIN main
+#define WVRAM nv_wo08
+#include "nv_wvfunc.h"
diff --git a/bin/nv_wv16.c b/bin/nv_wv16.c
new file mode 100644
index 000000000..d738cf89f
--- /dev/null
+++ b/bin/nv_wv16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wv16"
+#define CAST u16
+#define MAIN main
+#define WVRAM nv_wo16
+#include "nv_wvfunc.h"
diff --git a/bin/nv_wv32.c b/bin/nv_wv32.c
new file mode 100644
index 000000000..ba381a38e
--- /dev/null
+++ b/bin/nv_wv32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wv32"
+#define CAST u32
+#define MAIN main
+#define WVRAM nv_wo32
+#include "nv_wvfunc.h"
diff --git a/bin/nv_wvfunc.h b/bin/nv_wvfunc.h
new file mode 100644
index 000000000..1f218ffc6
--- /dev/null
+++ b/bin/nv_wvfunc.h
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void
+nv_wvram(struct nouveau_object *device, u64 addr, CAST data)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x00000000 | (addr >> 16));
+ WVRAM(device, 0x700000 + (addr & 0xffffULL), data);
+ nv_wo32(device, 0x001700, pmem);
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define WRITE(o,v) nv_wvram(device, (o), (v))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"