summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/nv_perfmon.c193
-rw-r--r--drm/nouveau/include/nvif/class.h30
-rw-r--r--drm/nouveau/include/nvif/ioctl.h2
-rw-r--r--drm/nouveau/nvkm/engine/pm/base.c208
-rw-r--r--drm/nouveau/nvkm/engine/pm/gf100.c10
-rw-r--r--drm/nouveau/nvkm/engine/pm/nv40.c10
-rw-r--r--drm/nouveau/nvkm/engine/pm/priv.h10
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[];
};