diff options
-rw-r--r-- | bin/nv_perfmon.c | 193 | ||||
-rw-r--r-- | drm/nouveau/include/nvif/class.h | 30 | ||||
-rw-r--r-- | drm/nouveau/include/nvif/ioctl.h | 2 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/pm/base.c | 208 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/pm/gf100.c | 10 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/pm/nv40.c | 10 | ||||
-rw-r--r-- | drm/nouveau/nvkm/engine/pm/priv.h | 10 |
7 files changed, 293 insertions, 170 deletions
diff --git a/bin/nv_perfmon.c b/bin/nv_perfmon.c index 50c777779..47b2fef34 100644 --- a/bin/nv_perfmon.c +++ b/bin/nv_perfmon.c @@ -248,7 +248,8 @@ ui_menu_win = { struct ui_perfmon_dom { struct list_head head; - struct list_head list; + struct list_head signals; + struct list_head perfdoms; u8 id; }; @@ -260,22 +261,27 @@ struct ui_perfmon_sig { struct ui_main { struct list_head head; - u32 handle; - struct nvif_object object; - const char *name; + struct ui_perfmon_sig *sig; u32 clk; u32 ctr; u64 incr; }; +struct ui_perfdom { + struct nvif_object object; + struct list_head head; + struct ui_main *ctr[4]; + u32 handle; +}; + static struct list_head ui_main_list = LIST_HEAD_INIT(ui_main_list); static struct list_head ui_doms_list = LIST_HEAD_INIT(ui_doms_list); +static struct list_head ui_perfdom_list = LIST_HEAD_INIT(ui_perfdom_list); static u32 ui_main_handle = 0xc0000000; static void ui_main_remove(struct ui_main *item) { - nvif_object_fini(&item->object); list_del(&item->head); free(item); } @@ -303,7 +309,7 @@ ui_perfmon_query_signals(struct nvif_object *perfmon, sig->signal = args.signal; sig->name = malloc(sizeof(args.name)); strncpy(sig->name, args.name, sizeof(args.name)); - list_add_tail(&sig->head, &dom->list); + list_add_tail(&sig->head, &dom->signals); args.iter = prev_iter; ret = nvif_mthd(perfmon, NVIF_PERFMON_V0_QUERY_SIGNAL, @@ -331,7 +337,8 @@ ui_perfmon_query_domains(struct nvif_object *perfmon) if (prev_iter) { dom = calloc(1, sizeof(*dom)); dom->id = args.id; - INIT_LIST_HEAD(&dom->list); + INIT_LIST_HEAD(&dom->signals); + INIT_LIST_HEAD(&dom->perfdoms); list_add_tail(&dom->head, &ui_doms_list); args.iter = prev_iter; @@ -346,6 +353,49 @@ ui_perfmon_query_domains(struct nvif_object *perfmon) } static void +ui_perfdom_init(struct ui_perfdom *dom) +{ + struct nvif_perfdom_init args = {}; + int ret; + + ret = nvif_mthd(&dom->object, NVIF_PERFDOM_V0_INIT, + &args, sizeof(args)); + assert(ret == 0); +} + +static void +ui_perfdom_sample(struct ui_perfdom *dom) +{ + struct nvif_perfdom_sample args = {}; + int ret; + + ret = nvif_mthd(&dom->object, NVIF_PERFDOM_V0_SAMPLE, + &args, sizeof(args)); + assert(ret == 0); +} + +static void +ui_perfdom_read(struct ui_perfdom *dom) +{ + struct nvif_perfdom_read_v0 args = {}; + int ret, i; + + ret = nvif_mthd(&dom->object, NVIF_PERFDOM_V0_READ, + &args, sizeof(args)); + assert(ret == 0 || ret == -EAGAIN); + + if (ret == 0) { + for (i = 0; i < 4; i++) { + if (!dom->ctr[i]) + continue; + dom->ctr[i]->ctr = args.ctr[i]; + dom->ctr[i]->incr += args.ctr[i]; + dom->ctr[i]->clk = args.clk; + } + } +} + +static void ui_perfmon_init(void) { struct nvif_object perfmon; @@ -362,17 +412,37 @@ ui_perfmon_init(void) } static void +ui_perfmon_free_signals(struct ui_perfmon_dom *dom) +{ + struct ui_perfmon_sig *sig, *next; + + list_for_each_entry_safe(sig, next, &dom->signals, head) { + list_del(&sig->head); + free(sig->name); + free(sig); + } +} + +static void +ui_perfmon_free_perfdoms(struct ui_perfmon_dom *dom) +{ + struct ui_perfdom *perfdom, *next; + + list_for_each_entry_safe(perfdom, next, &dom->perfdoms, head) { + nvif_object_fini(&perfdom->object); + list_del(&perfdom->head); + free(perfdom); + } +} + +static void ui_perfmon_fini(void) { - struct ui_perfmon_dom *dom, *next_dom; - struct ui_perfmon_sig *sig, *next_sig; - - list_for_each_entry_safe(dom, next_dom, &ui_doms_list, head) { - list_for_each_entry_safe(sig, next_sig, &dom->list, head) { - list_del(&sig->head); - free(sig->name); - free(sig); - } + struct ui_perfmon_dom *dom, *next; + + list_for_each_entry_safe(dom, next, &ui_doms_list, head) { + ui_perfmon_free_perfdoms(dom); + ui_perfmon_free_signals(dom); list_del(&dom->head); free(dom); } @@ -384,31 +454,62 @@ ui_main_select(void) struct ui_main *item, *temp; struct ui_perfmon_dom *dom; struct ui_perfmon_sig *sig; + struct ui_perfdom *perfdom; int ret; + int i; list_for_each_entry_safe(item, temp, &ui_main_list, head) { ui_main_remove(item); } list_for_each_entry(dom, &ui_doms_list, head) { - list_for_each_entry(sig, &dom->list, head) { - struct nvif_perfctr_v0 args = { - .logic_op = 0xaaaa, - .domain = dom->id, - }; + list_for_each_entry(sig, &dom->signals, head) { + bool found = false; item = calloc(1, sizeof(*item)); - item->handle = ui_main_handle++; - item->name = sig->name; + item->sig = sig; + list_add_tail(&item->head, &ui_main_list); + + /* find a slot */ + list_for_each_entry(perfdom, &dom->perfdoms, head) { + for (i = 0; i < 4; i++) { + if (!perfdom->ctr[i]) { + perfdom->ctr[i] = item; + found = true; + break; + } + } + } + + if (!found) { + /* no free slots, create a new perfdom */ + perfdom = calloc(1, sizeof(*perfdom)); + perfdom->handle = ui_main_handle++; + perfdom->ctr[0] = item; + list_add_tail(&perfdom->head, &dom->perfdoms); + } + } + + /* init perfdom objects */ + list_for_each_entry(perfdom, &dom->perfdoms, head) { + struct nvif_perfdom_v0 args = {}; + int i; + + args.domain = dom->id; + for (i = 0; i < 4; i++) { + struct ui_main *ctr = perfdom->ctr[i]; + if (!ctr) + continue; + args.ctr[i].signal[0] = ctr->sig->signal; + args.ctr[i].logic_op = 0xaaaa; + } - args.signal[0] = sig->signal; ret = nvif_object_init(nvif_object(device), NULL, - item->handle, - NVIF_IOCTL_NEW_V0_PERFCTR, + perfdom->handle, + NVIF_IOCTL_NEW_V0_PERFDOM, &args, sizeof(args), - &item->object); + &perfdom->object); assert(ret == 0); - list_add_tail(&item->head, &ui_main_list); } } } @@ -416,34 +517,34 @@ ui_main_select(void) static void ui_main_alarm_handler(int signal) { - struct ui_main *item; + struct ui_perfmon_dom *dom; + struct ui_perfdom *perfdom; bool sampled = false; if (list_empty(&ui_main_list)) ui_main_select(); - list_for_each_entry(item, &ui_main_list, head) { - struct nvif_perfctr_read_v0 args = {}; - int ret; + list_for_each_entry(dom, &ui_doms_list, head) { + if (list_empty(&dom->perfdoms)) + continue; - if (!sampled) { - struct nvif_perfctr_sample args = {}; + perfdom = list_first_entry(&dom->perfdoms, + typeof(*perfdom), head); - ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_SAMPLE, - &args, sizeof(args)); - assert(ret == 0); + /* sample previous batch of counters */ + if (!sampled) { + ui_perfdom_sample(perfdom); sampled = true; } - ret = nvif_mthd(&item->object, NVIF_PERFCTR_V0_READ, - &args, sizeof(args)); - assert(ret == 0 || ret == -EAGAIN); + /* read previous batch of counters */ + ui_perfdom_read(perfdom); - if (ret == 0) { - item->clk = args.clk; - item->ctr = args.ctr; - } - item->incr += item->ctr; + /* setup next batch of counters for sampling */ + list_move_tail(&perfdom->head, &dom->perfdoms); + perfdom = list_first_entry(&dom->perfdoms, + typeof(*perfdom), head); + ui_perfdom_init(perfdom); } } @@ -485,7 +586,7 @@ ui_main_redraw(struct ui_table *t) y = 2; list_for_each_entry_from(item, &ui_main_list, head) { - set_field_buffer(f[0], 0, item->name); + set_field_buffer(f[0], 0, item->sig->name); set_field_userptr(f[0], item); field_opts_on(f[0], O_VISIBLE | O_ACTIVE); diff --git a/drm/nouveau/include/nvif/class.h b/drm/nouveau/include/nvif/class.h index 528eac8c8..1a76a7fe3 100644 --- a/drm/nouveau/include/nvif/class.h +++ b/drm/nouveau/include/nvif/class.h @@ -287,34 +287,36 @@ struct nvif_perfmon_query_source_v0 { /******************************************************************************* - * perfctr + * perfdom ******************************************************************************/ -struct nvif_perfctr_v0 { +struct nvif_perfdom_v0 { __u8 version; __u8 domain; - __u8 pad02[2]; - __u16 logic_op; - __u8 pad04[2]; - __u8 signal[4]; - __u8 pad06[4]; + __u8 mode; + __u8 pad03[1]; + struct { + __u8 signal[4]; + __u16 logic_op; + } ctr[4]; }; -#define NVIF_PERFCTR_V0_INIT 0x00 -#define NVIF_PERFCTR_V0_SAMPLE 0x01 -#define NVIF_PERFCTR_V0_READ 0x02 +#define NVIF_PERFDOM_V0_INIT 0x00 +#define NVIF_PERFDOM_V0_SAMPLE 0x01 +#define NVIF_PERFDOM_V0_READ 0x02 -struct nvif_perfctr_init { +struct nvif_perfdom_init { }; -struct nvif_perfctr_sample { +struct nvif_perfdom_sample { }; -struct nvif_perfctr_read_v0 { +struct nvif_perfdom_read_v0 { __u8 version; __u8 pad01[7]; - __u32 ctr; + __u32 ctr[4]; __u32 clk; + __u8 pad04[4]; }; diff --git a/drm/nouveau/include/nvif/ioctl.h b/drm/nouveau/include/nvif/ioctl.h index 517cd27cd..2eb9b899a 100644 --- a/drm/nouveau/include/nvif/ioctl.h +++ b/drm/nouveau/include/nvif/ioctl.h @@ -50,7 +50,7 @@ struct nvif_ioctl_new_v0 { __u32 handle; /* these class numbers are made up by us, and not nvidia-assigned */ #define NVIF_IOCTL_NEW_V0_PERFMON 0x0000ffff -#define NVIF_IOCTL_NEW_V0_PERFCTR 0x0000fffe +#define NVIF_IOCTL_NEW_V0_PERFDOM 0x0000fffe #define NVIF_IOCTL_NEW_V0_CONTROL 0x0000fffd __u32 oclass; __u8 data[]; /* class data (class.h) */ diff --git a/drm/nouveau/nvkm/engine/pm/base.c b/drm/nouveau/nvkm/engine/pm/base.c index 5dbb3b4e2..8960bf4ff 100644 --- a/drm/nouveau/nvkm/engine/pm/base.c +++ b/drm/nouveau/nvkm/engine/pm/base.c @@ -31,9 +31,6 @@ #include <nvif/ioctl.h> #include <nvif/unpack.h> -#define QUAD_MASK 0x0f -#define QUAD_FREE 0x01 - static u8 nvkm_pm_count_perfdom(struct nvkm_pm *ppm) { @@ -304,32 +301,27 @@ nvkm_perfmon_ofuncs = { }; /******************************************************************************* - * Perfctr object classes + * Perfdom object classes ******************************************************************************/ static int -nvkm_perfctr_init(struct nvkm_object *object, void *data, u32 size) +nvkm_perfdom_init(struct nvkm_object *object, void *data, u32 size) { union { - struct nvif_perfctr_init none; + struct nvif_perfdom_init none; } *args = data; struct nvkm_pm *ppm = (void *)object->engine; - struct nvkm_perfctr *ctr = (void *)object; - struct nvkm_perfdom *dom = ctr->dom; - int ret; + struct nvkm_perfdom *dom = (void *)object; + int ret, i; - nv_ioctl(object, "perfctr init size %d\n", size); + nv_ioctl(object, "perfdom init size %d\n", size); if (nvif_unvers(args->none)) { - nv_ioctl(object, "perfctr init\n"); + nv_ioctl(object, "perfdom init\n"); } else return ret; - ctr->slot = ffs(dom->quad) - 1; - if (ctr->slot < 0) { - /* no free slots are available */ - return -EINVAL; - } - dom->quad &= ~(QUAD_FREE << ctr->slot); - dom->func->init(ppm, dom, ctr); + for (i = 0; i < 4; i++) + if (dom->ctr[i]) + dom->func->init(ppm, dom, dom->ctr[i]); /* start next batch of counters for sampling */ dom->func->next(ppm, dom); @@ -337,74 +329,70 @@ nvkm_perfctr_init(struct nvkm_object *object, void *data, u32 size) } static int -nvkm_perfctr_sample(struct nvkm_object *object, void *data, u32 size) +nvkm_perfdom_sample(struct nvkm_object *object, void *data, u32 size) { union { - struct nvif_perfctr_sample none; + struct nvif_perfdom_sample none; } *args = data; struct nvkm_pm *ppm = (void *)object->engine; - struct nvkm_perfctr *ctr; struct nvkm_perfdom *dom; int ret; - nv_ioctl(object, "perfctr sample size %d\n", size); + nv_ioctl(object, "perfdom sample size %d\n", size); if (nvif_unvers(args->none)) { - nv_ioctl(object, "perfctr sample\n"); + nv_ioctl(object, "perfdom sample\n"); } else return ret; ppm->sequence++; - list_for_each_entry(dom, &ppm->domains, head) { - /* sample previous batch of counters */ - if (dom->quad != QUAD_MASK) { - dom->func->next(ppm, dom); - - /* read counter values */ - list_for_each_entry(ctr, &dom->list, head) { - dom->func->read(ppm, dom, ctr); - ctr->slot = -1; - } - - dom->quad = QUAD_MASK; - } - } + /* sample previous batch of counters */ + list_for_each_entry(dom, &ppm->domains, head) + dom->func->next(ppm, dom); return 0; } static int -nvkm_perfctr_read(struct nvkm_object *object, void *data, u32 size) +nvkm_perfdom_read(struct nvkm_object *object, void *data, u32 size) { union { - struct nvif_perfctr_read_v0 v0; + struct nvif_perfdom_read_v0 v0; } *args = data; - struct nvkm_perfctr *ctr = (void *)object; - int ret; + struct nvkm_pm *ppm = (void *)object->engine; + struct nvkm_perfdom *dom = (void *)object; + int ret, i; - nv_ioctl(object, "perfctr read size %d\n", size); + nv_ioctl(object, "perfdom read size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { - nv_ioctl(object, "perfctr read vers %d\n", args->v0.version); + nv_ioctl(object, "perfdom read vers %d\n", args->v0.version); } else return ret; - if (!ctr->clk) + for (i = 0; i < 4; i++) { + if (dom->ctr[i]) + dom->func->read(ppm, dom, dom->ctr[i]); + } + + if (!dom->clk) return -EAGAIN; - args->v0.clk = ctr->clk; - args->v0.ctr = ctr->ctr; + for (i = 0; i < 4; i++) + if (dom->ctr[i]) + args->v0.ctr[i] = dom->ctr[i]->ctr; + args->v0.clk = dom->clk; return 0; } static int -nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) +nvkm_perfdom_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) { switch (mthd) { - case NVIF_PERFCTR_V0_INIT: - return nvkm_perfctr_init(object, data, size); - case NVIF_PERFCTR_V0_SAMPLE: - return nvkm_perfctr_sample(object, data, size); - case NVIF_PERFCTR_V0_READ: - return nvkm_perfctr_read(object, data, size); + case NVIF_PERFDOM_V0_INIT: + return nvkm_perfdom_init(object, data, size); + case NVIF_PERFDOM_V0_SAMPLE: + return nvkm_perfdom_sample(object, data, size); + case NVIF_PERFDOM_V0_READ: + return nvkm_perfdom_read(object, data, size); default: break; } @@ -412,70 +400,107 @@ nvkm_perfctr_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) } static void -nvkm_perfctr_dtor(struct nvkm_object *object) +nvkm_perfdom_dtor(struct nvkm_object *object) { - struct nvkm_perfctr *ctr = (void *)object; - if (ctr->dom) - ctr->dom->quad |= (QUAD_FREE << ctr->slot); - if (ctr->head.next) - list_del(&ctr->head); - nvkm_object_destroy(&ctr->base); + struct nvkm_perfdom *dom = (void *)object; + int i; + + for (i = 0; i < 4; i++) { + struct nvkm_perfctr *ctr = dom->ctr[i]; + if (ctr && ctr->head.next) + list_del(&ctr->head); + kfree(ctr); + } + nvkm_object_destroy(&dom->base); } static int -nvkm_perfctr_ctor(struct nvkm_object *parent, struct nvkm_object *engine, +nvkm_perfctr_new(struct nvkm_perfdom *dom, int slot, + struct nvkm_perfsig *signal[4], uint16_t logic_op, + struct nvkm_perfctr **pctr) +{ + struct nvkm_perfctr *ctr; + int i; + + if (!dom) + return -EINVAL; + + ctr = *pctr = kzalloc(sizeof(*ctr), GFP_KERNEL); + if (!ctr) + return -ENOMEM; + + ctr->logic_op = logic_op; + ctr->slot = slot; + for (i = 0; i < 4; i++) { + if (signal[i]) + ctr->signal[i] = signal[i] - dom->signal; + } + list_add_tail(&ctr->head, &dom->list); + + return 0; +} + +static int +nvkm_perfdom_ctor(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { - struct nvif_perfctr_v0 v0; + struct nvif_perfdom_v0 v0; } *args = data; struct nvkm_pm *ppm = (void *)engine; - struct nvkm_perfdom *dom = NULL; - struct nvkm_perfsig *sig[4] = {}; - struct nvkm_perfctr *ctr; - int ret, i; + struct nvkm_perfdom *sdom = NULL; + struct nvkm_perfctr *ctr[4] = {}; + struct nvkm_perfdom *dom; + int c, s; + int ret; - nv_ioctl(parent, "create perfctr size %d\n", size); + nv_ioctl(parent, "create perfdom size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { - nv_ioctl(parent, "create perfctr vers %d logic_op %04x\n", - args->v0.version, args->v0.logic_op); + nv_ioctl(parent, "create perfdom vers %d dom %d mode %02x\n", + args->v0.version, args->v0.domain, args->v0.mode); } else return ret; - for (i = 0; i < ARRAY_SIZE(args->v0.signal); i++) { - sig[i] = nvkm_perfsig_find(ppm, args->v0.domain, - args->v0.signal[i], &dom); - if (args->v0.signal[i] && !sig[i]) - return -EINVAL; + for (c = 0; c < ARRAY_SIZE(args->v0.ctr); c++) { + struct nvkm_perfsig *sig[4] = {}; + for (s = 0; s < ARRAY_SIZE(args->v0.ctr[c].signal); s++) { + sig[s] = nvkm_perfsig_find(ppm, args->v0.domain, + args->v0.ctr[c].signal[s], + &sdom); + if (args->v0.ctr[c].signal[s] && !sig[s]) + return -EINVAL; + } + + ret = nvkm_perfctr_new(sdom, c, sig, + args->v0.ctr[c].logic_op, &ctr[c]); + if (ret) + return ret; } - if (!dom) + if (!sdom) return -EINVAL; - ret = nvkm_object_create(parent, engine, oclass, 0, &ctr); - *pobject = nv_object(ctr); + ret = nvkm_object_create(parent, engine, oclass, 0, &dom); + *pobject = nv_object(dom); if (ret) return ret; - ctr->dom = dom; - ctr->slot = -1; - ctr->logic_op = args->v0.logic_op; - ctr->signal[0] = sig[0]; - ctr->signal[1] = sig[1]; - ctr->signal[2] = sig[2]; - ctr->signal[3] = sig[3]; - list_add_tail(&ctr->head, &dom->list); + dom->func = sdom->func; + dom->addr = sdom->addr; + dom->mode = args->v0.mode; + for (c = 0; c < ARRAY_SIZE(ctr); c++) + dom->ctr[c] = ctr[c]; return 0; } static struct nvkm_ofuncs -nvkm_perfctr_ofuncs = { - .ctor = nvkm_perfctr_ctor, - .dtor = nvkm_perfctr_dtor, +nvkm_perfdom_ofuncs = { + .ctor = nvkm_perfdom_ctor, + .dtor = nvkm_perfdom_dtor, .init = nvkm_object_init, .fini = nvkm_object_fini, - .mthd = nvkm_perfctr_mthd, + .mthd = nvkm_perfdom_mthd, }; struct nvkm_oclass @@ -484,8 +509,8 @@ nvkm_pm_sclass[] = { .handle = NVIF_IOCTL_NEW_V0_PERFMON, .ofuncs = &nvkm_perfmon_ofuncs, }, - { .handle = NVIF_IOCTL_NEW_V0_PERFCTR, - .ofuncs = &nvkm_perfctr_ofuncs, + { .handle = NVIF_IOCTL_NEW_V0_PERFDOM, + .ofuncs = &nvkm_perfdom_ofuncs, }, {}, }; @@ -640,7 +665,6 @@ nvkm_perfdom_new(struct nvkm_pm *ppm, const char *name, u32 mask, INIT_LIST_HEAD(&dom->list); dom->func = sdom->func; dom->addr = addr; - dom->quad = QUAD_MASK; dom->signal_nr = sdom->signal_nr; ssig = (sdom++)->signal; diff --git a/drm/nouveau/nvkm/engine/pm/gf100.c b/drm/nouveau/nvkm/engine/pm/gf100.c index 41350d619..edab97aa9 100644 --- a/drm/nouveau/nvkm/engine/pm/gf100.c +++ b/drm/nouveau/nvkm/engine/pm/gf100.c @@ -48,12 +48,10 @@ gf100_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom, u32 src = 0x00000000; int i; - for (i = 0; i < 4; i++) { - if (ctr->signal[i]) - src |= (ctr->signal[i] - dom->signal) << (i * 8); - } + for (i = 0; i < 4; i++) + src |= ctr->signal[i] << (i * 8); - nv_wr32(priv, dom->addr + 0x09c, 0x00040002); + nv_wr32(priv, dom->addr + 0x09c, 0x00040002 | (dom->mode << 3)); nv_wr32(priv, dom->addr + 0x100, 0x00000000); nv_wr32(priv, dom->addr + 0x040 + (cntr->base.slot * 0x08), src); nv_wr32(priv, dom->addr + 0x044 + (cntr->base.slot * 0x08), log); @@ -72,7 +70,7 @@ gf100_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom, case 2: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x080); break; case 3: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x090); break; } - cntr->base.clk = nv_rd32(priv, dom->addr + 0x070); + dom->clk = nv_rd32(priv, dom->addr + 0x070); } static void diff --git a/drm/nouveau/nvkm/engine/pm/nv40.c b/drm/nouveau/nvkm/engine/pm/nv40.c index 603874ec0..1c6d1ca47 100644 --- a/drm/nouveau/nvkm/engine/pm/nv40.c +++ b/drm/nouveau/nvkm/engine/pm/nv40.c @@ -33,12 +33,10 @@ nv40_perfctr_init(struct nvkm_pm *ppm, struct nvkm_perfdom *dom, u32 src = 0x00000000; int i; - for (i = 0; i < 4; i++) { - if (ctr->signal[i]) - src |= (ctr->signal[i] - dom->signal) << (i * 8); - } + for (i = 0; i < 4; i++) + src |= ctr->signal[i] << (i * 8); - nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001); + nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001 | (dom->mode << 4)); nv_wr32(priv, 0x00a400 + dom->addr + (cntr->base.slot * 0x40), src); nv_wr32(priv, 0x00a420 + dom->addr + (cntr->base.slot * 0x40), log); } @@ -56,7 +54,7 @@ nv40_perfctr_read(struct nvkm_pm *ppm, struct nvkm_perfdom *dom, case 2: cntr->base.ctr = nv_rd32(priv, 0x00a680 + dom->addr); break; case 3: cntr->base.ctr = nv_rd32(priv, 0x00a740 + dom->addr); break; } - cntr->base.clk = nv_rd32(priv, 0x00a600 + dom->addr); + dom->clk = nv_rd32(priv, 0x00a600 + dom->addr); } static void diff --git a/drm/nouveau/nvkm/engine/pm/priv.h b/drm/nouveau/nvkm/engine/pm/priv.h index 4ed77ff49..38adeb731 100644 --- a/drm/nouveau/nvkm/engine/pm/priv.h +++ b/drm/nouveau/nvkm/engine/pm/priv.h @@ -3,13 +3,10 @@ #include <engine/pm.h> struct nvkm_perfctr { - struct nvkm_object base; struct list_head head; - struct nvkm_perfsig *signal[4]; - struct nvkm_perfdom *dom; + u8 signal[4]; int slot; u32 logic_op; - u32 clk; u32 ctr; }; @@ -63,12 +60,15 @@ struct nvkm_specdom { }; struct nvkm_perfdom { + struct nvkm_object base; struct list_head head; struct list_head list; const struct nvkm_funcdom *func; + struct nvkm_perfctr *ctr[4]; char name[32]; u32 addr; - u8 quad; + u8 mode; + u32 clk; u16 signal_nr; struct nvkm_perfsig signal[]; }; |