From 33b1104b25f0e58ca56d6dd13ce917371a9115fe Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 20 Aug 2015 14:54:15 +1000 Subject: nvif: simplify and tidy library interfaces A variety of tweaks to the NVIF library interfaces, mostly ripping out things that turned out to be not so useful. - Removed refcounting from nvif_object, callers are expected to not be stupid instead. - nvif_client is directly reachable from anything derived from nvif_object, removing the need for heuristics to locate it - _new() versions of interfaces, that allocate memory for the object they construct, have been removed. The vast majority of callers used the embedded _init() interfaces. - No longer storing constructor arguments (and the data returned from nvkm) inside nvif_object, it's more or less unused and just wastes memory. Signed-off-by: Ben Skeggs --- bin/nv_aux.c | 10 ++++--- bin/nv_disp.c | 36 +++++++++++++++++--------- bin/nv_i2c.c | 12 +++++---- bin/nv_init.c | 13 +++++----- bin/nv_perfmon.c | 12 +++++---- bin/nv_rd08.c | 2 +- bin/nv_rd16.c | 2 +- bin/nv_rd32.c | 2 +- bin/nv_rdfunc.h | 8 +++--- bin/nv_rsfunc.h | 8 +++--- bin/nv_rvfunc.h | 8 +++--- bin/nv_wr08.c | 2 +- bin/nv_wr16.c | 2 +- bin/nv_wr32.c | 2 +- bin/nv_wrfunc.h | 8 +++--- bin/nv_wsfunc.h | 8 +++--- bin/nv_wvfunc.h | 8 +++--- bin/util.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++---------- 18 files changed, 148 insertions(+), 74 deletions(-) (limited to 'bin') diff --git a/bin/nv_aux.c b/bin/nv_aux.c index 68b72cb2e..e3956f1bf 100644 --- a/bin/nv_aux.c +++ b/bin/nv_aux.c @@ -17,7 +17,8 @@ print_aux(struct nvkm_i2c_aux *aux) int main(int argc, char **argv) { - struct nvif_device *device; + struct nvif_client client; + struct nvif_device device; struct nvkm_i2c_aux *aux; struct nvkm_i2c *i2c; int action = -1, index = -1; @@ -63,11 +64,11 @@ main(int argc, char **argv) ret = u_device("lib", argv[0], "error", true, true, (1ULL << NVDEV_SUBDEV_VBIOS) | (1ULL << NVDEV_SUBDEV_I2C), - 0x00000000, &device); + 0x00000000, &client, &device); if (ret) return ret; - i2c = nvxx_i2c(device); + i2c = nvxx_i2c(&device); if (action < 0) { list_for_each_entry(aux, &i2c->aux, head) { @@ -102,6 +103,7 @@ main(int argc, char **argv) } done: - nvif_device_ref(NULL, &device); + nvif_device_fini(&device); + nvif_client_fini(&client); return ret; } diff --git a/bin/nv_disp.c b/bin/nv_disp.c index a092e14d7..3fbcbe541 100644 --- a/bin/nv_disp.c +++ b/bin/nv_disp.c @@ -4,24 +4,36 @@ static unsigned long chan = 0; +static void +nv50_disp_mthd(struct nvif_device *device, u16 mthd, u32 data) +{ + u32 ctrl = nvif_rd32(&device->object, 0x610300 + (chan * 8)); + nvif_wr32(&device->object, 0x610300 + (chan * 8), ctrl | 0x00000001); + nvif_wr32(&device->object, 0x610304 + (chan * 8), data); + nvif_wr32(&device->object, 0x610300 + (chan * 8), mthd | 0x80000001); + while (nvif_rd32(&device->object, 0x610300 + (chan * 8)) & 0x80000000) {} + nvif_wr32(&device->object, 0x610300 + (chan * 8), ctrl); +} + +static void +gf119_disp_mthd(struct nvif_device *device, u16 mthd, u32 data) +{ + u32 ctrl = nvif_rd32(&device->object, 0x610700 + (chan * 16)); + nvif_wr32(&device->object, 0x610700 + (chan * 16), ctrl | 0x00000001); + nvif_wr32(&device->object, 0x610704 + (chan * 16), data); + nvif_wr32(&device->object, 0x610700 + (chan * 16), mthd | 0x80000001); + while (nvif_rd32(&device->object, 0x610700 + (chan * 16)) & 0x80000000) {} + nvif_wr32(&device->object, 0x610700 + (chan * 16), ctrl); +} + static void nv_disp(struct nvif_device *device, u16 mthd, u32 data) { if (device->info.chipset >= 0xd0) { - u32 ctrl = nvif_rd32(device, 0x610700 + (chan * 16)); - nvif_wr32(device, 0x610700 + (chan * 16), ctrl | 0x00000001); - nvif_wr32(device, 0x610704 + (chan * 16), data); - nvif_wr32(device, 0x610700 + (chan * 16), mthd | 0x80000001); - while (nvif_rd32(device, 0x610700 + (chan * 16)) & 0x80000000) {} - nvif_wr32(device, 0x610700 + (chan * 16), ctrl); + nv50_disp_mthd(device, mthd, data); } else if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - u32 ctrl = nvif_rd32(device, 0x610300 + (chan * 8)); - nvif_wr32(device, 0x610300 + (chan * 8), ctrl | 0x00000001); - nvif_wr32(device, 0x610304 + (chan * 8), data); - nvif_wr32(device, 0x610300 + (chan * 8), mthd | 0x80000001); - while (nvif_rd32(device, 0x610300 + (chan * 8)) & 0x80000000) {} - nvif_wr32(device, 0x610300 + (chan * 8), ctrl); + gf119_disp_mthd(device, mthd, data); } else { printk("unsupported chipset\n"); exit(1); diff --git a/bin/nv_i2c.c b/bin/nv_i2c.c index fd9497b7e..6fcd2f2bd 100644 --- a/bin/nv_i2c.c +++ b/bin/nv_i2c.c @@ -40,7 +40,8 @@ find_adapter(struct nvif_device *device, int adapter) int main(int argc, char **argv) { - struct nvif_device *device; + struct nvif_client client; + struct nvif_device device; struct i2c_adapter *adap; int addr = -1, reg = -1, val = -1; int action = -1, index = -1; @@ -91,14 +92,14 @@ main(int argc, char **argv) ret = u_device("lib", argv[0], "error", true, true, (1ULL << NVDEV_SUBDEV_VBIOS) | (1ULL << NVDEV_SUBDEV_I2C), - 0x00000000, &device); + 0x00000000, &client, &device); if (action < 0) { - for (index = 0; (adap = find_adapter(device, index)); index++) { + for (index = 0; (adap = find_adapter(&device, index)); index++) { show_adapter(adap, index); } } else { - adap = find_adapter(device, index); + adap = find_adapter(&device, index); if (!adap) { ret = -ENOENT; goto done; @@ -154,6 +155,7 @@ main(int argc, char **argv) } done: - nvif_device_ref(NULL, &device); + nvif_device_fini(&device); + nvif_client_fini(&client); return ret; } diff --git a/bin/nv_init.c b/bin/nv_init.c index a249da871..90c14d5ea 100644 --- a/bin/nv_init.c +++ b/bin/nv_init.c @@ -12,7 +12,8 @@ int main(int argc, char **argv) { - struct nvif_device *device; + struct nvif_client client; + struct nvif_device device; bool suspend = false, wait = false; int ret, c; @@ -32,14 +33,13 @@ main(int argc, char **argv) } ret = u_device(NULL, argv[0], "info", true, true, ~0ULL, - 0x00000000, &device); + 0x00000000, &client, &device); if (ret) return ret; if (suspend) { - struct nvif_client *client = nvif_client(&device->base); - nvif_client_suspend(client); - nvif_client_resume(client); + nvif_client_suspend(&client); + nvif_client_resume(&client); } while (wait && (c = getchar()) == EOF) { @@ -47,7 +47,8 @@ main(int argc, char **argv) } printf("shutting down...\n"); - nvif_device_ref(NULL, &device); + nvif_device_fini(&device); + nvif_client_fini(&client); printf("done!\n"); return ret; } diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c index 20aa1b8ac..9fcbd602e 100644 --- a/bin/nv_perfmon.c +++ b/bin/nv_perfmon.c @@ -37,7 +37,8 @@ #include "util.h" -static struct nvif_device *device; +static struct nvif_client client; +static struct nvif_device _device, *device = &_device; static struct nvif_object perfmon; static int nr_signals; /* number of signals for all domains */ @@ -402,7 +403,7 @@ ui_perfmon_init(void) { int ret; - ret = nvif_object_init(nvif_object(device), NULL, 0xdeadbeef, + ret = nvif_object_init(&device->object, 0xdeadbeef, NVIF_IOCTL_NEW_V0_PERFMON, NULL, 0, &perfmon); assert(ret == 0); @@ -505,7 +506,7 @@ ui_main_select(void) args.ctr[i].logic_op = 0xaaaa; } - ret = nvif_object_init(&perfmon, NULL, perfdom->handle, + ret = nvif_object_init(&perfmon, perfdom->handle, NVIF_IOCTL_NEW_V0_PERFDOM, &args, sizeof(args), &perfdom->object); @@ -832,7 +833,7 @@ main(int argc, char **argv) ret = u_device(NULL, argv[0], "error", true, true, (1ULL << NVDEV_SUBDEV_TIMER) | (1ULL << NVDEV_ENGINE_PM), - 0x00000000, &device); + 0x00000000, &client, device); if (ret) return ret; @@ -872,6 +873,7 @@ main(int argc, char **argv) endwin(); ui_perfmon_fini(); - nvif_device_ref(NULL, &device); + nvif_device_fini(device); + nvif_client_fini(&client); return 0; } diff --git a/bin/nv_rd08.c b/bin/nv_rd08.c index 30196d41b..f10129b46 100644 --- a/bin/nv_rd08.c +++ b/bin/nv_rd08.c @@ -2,6 +2,6 @@ #define FMTDATA "0x%02x" #define NAME "nv_rd08" #define CAST u8 -#define READ(o) nvif_rd08(device, (o)) +#define READ(o) nvif_rd08(&device->object, (o)) #define MAIN main #include "nv_rdfunc.h" diff --git a/bin/nv_rd16.c b/bin/nv_rd16.c index 61079bcda..db599976b 100644 --- a/bin/nv_rd16.c +++ b/bin/nv_rd16.c @@ -2,6 +2,6 @@ #define FMTDATA "0x%04x" #define NAME "nv_rd16" #define CAST u16 -#define READ(o) nvif_rd16(device, (o)) +#define READ(o) nvif_rd16(&device->object, (o)) #define MAIN main #include "nv_rdfunc.h" diff --git a/bin/nv_rd32.c b/bin/nv_rd32.c index f03739523..04b615e3a 100644 --- a/bin/nv_rd32.c +++ b/bin/nv_rd32.c @@ -2,6 +2,6 @@ #define FMTDATA "0x%08x" #define NAME "nv_rd32" #define CAST u32 -#define READ(o) nvif_rd32(device, (o)) +#define READ(o) nvif_rd32(&device->object, (o)) #define MAIN main #include "nv_rdfunc.h" diff --git a/bin/nv_rdfunc.h b/bin/nv_rdfunc.h index c9c2aea22..6def1b229 100644 --- a/bin/nv_rdfunc.h +++ b/bin/nv_rdfunc.h @@ -15,7 +15,8 @@ int main(int argc, char **argv) { - struct nvif_device *device; + struct nvif_client client; + struct nvif_device _device, *device = &_device; char *rstr = NULL; enum { NORMAL, @@ -49,7 +50,7 @@ main(int argc, char **argv) } ret = u_device("lib", argv[0], "fatal", DETECT, true, 0, - 0x00000000, &device); + 0x00000000, &client, device); if (ret) return ret; @@ -133,6 +134,7 @@ main(int argc, char **argv) } free(data); - nvif_device_ref(NULL, &device); + nvif_device_fini(device); + nvif_client_fini(&client); return 0; } diff --git a/bin/nv_rsfunc.h b/bin/nv_rsfunc.h index 2a36cd128..f234ccac7 100644 --- a/bin/nv_rsfunc.h +++ b/bin/nv_rsfunc.h @@ -8,10 +8,10 @@ nv_rsys(struct nvif_device *device, u64 addr) if (device->info.family >= NV_DEVICE_INFO_V0_TESLA && device->info.family <= NV_DEVICE_INFO_V0_MAXWELL) { CAST data; - u32 pmem = nvif_rd32(device, 0x001700); - nvif_wr32(device, 0x001700, 0x02000000 | (addr >> 16)); - data = RSYS(device, 0x700000 + (addr & 0xffffULL)); - nvif_wr32(device, 0x001700, pmem); + u32 pmem = nvif_rd32(&device->object, 0x001700); + nvif_wr32(&device->object, 0x001700, 0x02000000 | (addr >> 16)); + data = RSYS(&device->object, 0x700000 + (addr & 0xffffULL)); + nvif_wr32(&device->object, 0x001700, pmem); return data; } else { printk("unsupported chipset\n"); diff --git a/bin/nv_rvfunc.h b/bin/nv_rvfunc.h index ffb97dff8..ea8aaf60f 100644 --- a/bin/nv_rvfunc.h +++ b/bin/nv_rvfunc.h @@ -8,10 +8,10 @@ nv_rvram(struct nvif_device *device, u64 addr) if (device->info.family >= NV_DEVICE_INFO_V0_TESLA && device->info.family <= NV_DEVICE_INFO_V0_MAXWELL) { CAST data; - u32 pmem = nvif_rd32(device, 0x001700); - nvif_wr32(device, 0x001700, 0x00000000 | (addr >> 16)); - data = RVRAM(device, 0x700000 + (addr & 0xffffULL)); - nvif_wr32(device, 0x001700, pmem); + u32 pmem = nvif_rd32(&device->object, 0x001700); + nvif_wr32(&device->object, 0x001700, 0x00000000 | (addr >> 16)); + data = RVRAM(&device->object, 0x700000 + (addr & 0xffffULL)); + nvif_wr32(&device->object, 0x001700, pmem); return data; } else { printk("unsupported chipset\n"); diff --git a/bin/nv_wr08.c b/bin/nv_wr08.c index a0be3ee60..0ad03537d 100644 --- a/bin/nv_wr08.c +++ b/bin/nv_wr08.c @@ -2,6 +2,6 @@ #define FMTDATA "0x%02x" #define NAME "nv_wr08" #define CAST u8 -#define WRITE(o,v) nvif_wr08(device, (o), (v)) +#define WRITE(o,v) nvif_wr08(&device->object, (o), (v)) #define MAIN main #include "nv_wrfunc.h" diff --git a/bin/nv_wr16.c b/bin/nv_wr16.c index 122bc82cb..da5f645a0 100644 --- a/bin/nv_wr16.c +++ b/bin/nv_wr16.c @@ -2,6 +2,6 @@ #define FMTDATA "0x%04x" #define NAME "nv_wr16" #define CAST u16 -#define WRITE(o,v) nvif_wr16(device, (o), (v)) +#define WRITE(o,v) nvif_wr16(&device->object, (o), (v)) #define MAIN main #include "nv_wrfunc.h" diff --git a/bin/nv_wr32.c b/bin/nv_wr32.c index 910c92823..eeeda4387 100644 --- a/bin/nv_wr32.c +++ b/bin/nv_wr32.c @@ -2,6 +2,6 @@ #define FMTDATA "0x%08x" #define NAME "nv_wr32" #define CAST u32 -#define WRITE(o,v) nvif_wr32(device, (o), (v)) +#define WRITE(o,v) nvif_wr32(&device->object, (o), (v)) #define MAIN main #include "nv_wrfunc.h" diff --git a/bin/nv_wrfunc.h b/bin/nv_wrfunc.h index cea140443..6a5551073 100644 --- a/bin/nv_wrfunc.h +++ b/bin/nv_wrfunc.h @@ -15,7 +15,8 @@ int MAIN(int argc, char **argv) { - struct nvif_device *device; + struct nvif_client client; + struct nvif_device _device, *device = &_device; char *rstr = NULL; char *vstr = NULL; int quiet = 0; @@ -43,7 +44,7 @@ MAIN(int argc, char **argv) } ret = u_device("lib", argv[0], "fatal", DETECT, true, 0ULL, - 0x00000000, &device); + 0x00000000, &client, device); if (ret) return ret; @@ -89,6 +90,7 @@ MAIN(int argc, char **argv) } } - nvif_device_ref(NULL, &device); + nvif_device_fini(device); + nvif_client_fini(&client); return 0; } diff --git a/bin/nv_wsfunc.h b/bin/nv_wsfunc.h index 909fd70cf..a77dda676 100644 --- a/bin/nv_wsfunc.h +++ b/bin/nv_wsfunc.h @@ -7,10 +7,10 @@ nv_wsys(struct nvif_device *device, u64 addr, CAST data) { if (device->info.family >= NV_DEVICE_INFO_V0_TESLA && device->info.family <= NV_DEVICE_INFO_V0_MAXWELL) { - u32 pmem = nvif_rd32(device, 0x001700); - nvif_wr32(device, 0x001700, 0x02000000 | (addr >> 16)); - WSYS(device, 0x700000 + (addr & 0xffffULL), data); - nvif_wr32(device, 0x001700, pmem); + u32 pmem = nvif_rd32(&device->object, 0x001700); + nvif_wr32(&device->object, 0x001700, 0x02000000 | (addr >> 16)); + WSYS(&device->object, 0x700000 + (addr & 0xffffULL), data); + nvif_wr32(&device->object, 0x001700, pmem); } else { printk("unsupported chipset\n"); exit(1); diff --git a/bin/nv_wvfunc.h b/bin/nv_wvfunc.h index 5a169227e..ea631fa50 100644 --- a/bin/nv_wvfunc.h +++ b/bin/nv_wvfunc.h @@ -7,10 +7,10 @@ nv_wvram(struct nvif_device *device, u64 addr, CAST data) { if (device->info.family >= NV_DEVICE_INFO_V0_TESLA && device->info.family <= NV_DEVICE_INFO_V0_MAXWELL) { - u32 pmem = nvif_rd32(device, 0x001700); - nvif_wr32(device, 0x001700, 0x00000000 | (addr >> 16)); - WVRAM(device, 0x700000 + (addr & 0xffffULL), data); - nvif_wr32(device, 0x001700, pmem); + u32 pmem = nvif_rd32(&device->object, 0x001700); + nvif_wr32(&device->object, 0x001700, 0x00000000 | (addr >> 16)); + WVRAM(&device->object, 0x700000 + (addr & 0xffffULL), data); + nvif_wr32(&device->object, 0x001700, pmem); } else { printk("unsupported chipset\n"); exit(1); diff --git a/bin/util.h b/bin/util.h index af6feac44..c3f6edfef 100644 --- a/bin/util.h +++ b/bin/util.h @@ -12,7 +12,7 @@ static const char *u_drv; static const char *u_cfg; static const char *u_dbg; -static u64 u_dev = ~0ULL; +static int u_dev = 0; static inline bool u_option(int c) @@ -30,30 +30,81 @@ u_option(int c) static inline int u_client(const char *drv, const char *name, const char *dbg, - bool detect, bool mmio, u64 subdev, - struct nvif_client **pclient) + bool detect, bool mmio, u64 subdev, struct nvif_client *client) { os_device_detect = detect; os_device_mmio = mmio; os_device_subdev = subdev; - return nvif_client_new(u_drv ? u_drv : drv, name, u_dev, u_cfg, - u_dbg ? u_dbg : dbg, pclient); + return nvif_client_init(u_drv ? u_drv : drv, name, ~0ULL, u_cfg, + u_dbg ? u_dbg : dbg, client); +} + +static inline struct nv_client_devlist_v0 * +u_device_list(struct nvif_client *client) +{ + struct nvif_object *object = &client->object; + struct nv_client_devlist_v0 *args; + int count = 0; + + for (;;) { + u32 size = sizeof(*args) + count * sizeof(args->device[0]); + if (!(args = malloc(size))) + return NULL; + args->version = 0; + args->count = count; + + if (nvif_object_mthd(object, NV_CLIENT_DEVLIST, args, size)) { + free(args); + return NULL; + } + + if (args->count == count) + return args; + count = args->count; + free(args); + } +} + +static inline void +u_device_show(struct nvif_client *client) +{ + struct nv_client_devlist_v0 *args = u_device_list(client); + int i; + printf("device(s):\n"); + for (i = 0; args && i < args->count; i++) + printf("%2d: %016llx\n", i, args->device[i]); + free(args); +} + +static inline u64 +u_device_name(struct nvif_client *client, int idx) +{ + struct nv_client_devlist_v0 *args = u_device_list(client); + u64 device = ~0ULL; + if (args) { + if (idx >= 0 && idx < args->count) + device = args->device[idx]; + else + u_device_show(client); + free(args); + } + return device; } static inline int u_device(const char *drv, const char *name, const char *dbg, bool detect, bool mmio, u64 subdev, u32 handle, - struct nvif_device **pdevice) + struct nvif_client *client, struct nvif_device *pdevice) { - struct nvif_client *client; - int ret = u_client(drv, name, dbg, detect, mmio, subdev, &client); + int ret = u_client(drv, name, dbg, detect, mmio, subdev, client); if (ret == 0) { - ret = nvif_device_new(client->object, handle, NV_DEVICE, - &(struct nv_device_v0) { - .device = ~0ULL, - }, sizeof(struct nv_device_v0), - pdevice); - nvif_client_ref(NULL, &client); + ret = nvif_device_init(&client->object, handle, NV_DEVICE, + &(struct nv_device_v0) { + .device = u_device_name(client, u_dev), + }, sizeof(struct nv_device_v0), + pdevice); + if (ret) + nvif_client_fini(client); } return ret; } -- cgit v1.2.1