aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-06-13 00:17:09 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-08-09 15:11:08 -0400
commit7238eca4cf18a5bba8679afc8c71a274e264f82e (patch)
tree96014d6d02c4c8c6db819e36a70bbf4d8d986f78 /drivers/gpu
parent7e1ee6333c32a4b83aad430a4bcb8a7057f36194 (diff)
drm/nouveau: expose pstate selection per-power source in sysfs
echo ac:id >> pstate # select mode when on mains power echo dc:id >> pstate # select mode when on battery echo id >> pstate # select mode for both Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/ctrl.c25
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/class.h7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sysfs.c38
3 files changed, 52 insertions, 18 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c
index 754fc1da6a0b..fb546f3a1af0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c
@@ -40,15 +40,16 @@ nouveau_control_mthd_pstate_info(struct nouveau_object *object, u32 mthd,
40 return -EINVAL; 40 return -EINVAL;
41 41
42 if (clk) { 42 if (clk) {
43 args->count = clk->state_nr; 43 args->count = clk->state_nr;
44 if (clk->pwrsrc) 44 args->ustate_ac = clk->ustate_ac;
45 args->ustate = clk->ustate_ac; 45 args->ustate_dc = clk->ustate_dc;
46 else 46 args->pwrsrc = clk->pwrsrc;
47 args->ustate = clk->ustate_dc;
48 args->pstate = clk->pstate; 47 args->pstate = clk->pstate;
49 } else { 48 } else {
50 args->count = 0; 49 args->count = 0;
51 args->ustate = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE; 50 args->ustate_ac = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE;
51 args->ustate_dc = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE;
52 args->pwrsrc = -ENOSYS;
52 args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN; 53 args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN;
53 } 54 }
54 55
@@ -122,11 +123,19 @@ nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd,
122{ 123{
123 struct nouveau_clock *clk = nouveau_clock(object); 124 struct nouveau_clock *clk = nouveau_clock(object);
124 struct nv_control_pstate_user *args = data; 125 struct nv_control_pstate_user *args = data;
126 int ret = 0;
125 127
126 if (size < sizeof(*args) || !clk) 128 if (size < sizeof(*args) || !clk)
127 return -EINVAL; 129 return -EINVAL;
128 130
129 return nouveau_clock_ustate(clk, args->state, clk->pwrsrc); 131 if (args->pwrsrc >= 0) {
132 ret |= nouveau_clock_ustate(clk, args->ustate, args->pwrsrc);
133 } else {
134 ret |= nouveau_clock_ustate(clk, args->ustate, 0);
135 ret |= nouveau_clock_ustate(clk, args->ustate, 1);
136 }
137
138 return ret;
130} 139}
131 140
132struct nouveau_oclass 141struct nouveau_oclass
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h
index e0c812bc884f..d6fd2cbe4333 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/class.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/class.h
@@ -148,7 +148,9 @@ struct nv_perfctr_read {
148 148
149struct nv_control_pstate_info { 149struct nv_control_pstate_info {
150 u32 count; /* out: number of power states */ 150 u32 count; /* out: number of power states */
151 s32 ustate; /* out: current target pstate index */ 151 s32 ustate_ac; /* out: target pstate index */
152 s32 ustate_dc; /* out: target pstate index */
153 s32 pwrsrc; /* out: current power source */
152 u32 pstate; /* out: current pstate index */ 154 u32 pstate; /* out: current pstate index */
153}; 155};
154 156
@@ -166,7 +168,8 @@ struct nv_control_pstate_attr {
166}; 168};
167 169
168struct nv_control_pstate_user { 170struct nv_control_pstate_user {
169 s32 state; /* in: pstate identifier */ 171 s32 ustate; /* in: pstate identifier */
172 s32 pwrsrc; /* in: target power source */
170}; 173};
171 174
172/* DMA FIFO channel classes 175/* DMA FIFO channel classes
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
index 75dda2b07176..ab5afc50460a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
@@ -68,7 +68,9 @@ nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b)
68 if (i < info.count) 68 if (i < info.count)
69 snappendf(buf, cnt, "%02x:", attr.state); 69 snappendf(buf, cnt, "%02x:", attr.state);
70 else 70 else
71 snappendf(buf, cnt, "--:"); 71 snappendf(buf, cnt, "%s:", info.pwrsrc == 0 ? "DC" :
72 info.pwrsrc == 1 ? "AC" :
73 "--");
72 74
73 attr.index = 0; 75 attr.index = 0;
74 do { 76 do {
@@ -84,9 +86,20 @@ nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b)
84 snappendf(buf, cnt, " %s", attr.unit); 86 snappendf(buf, cnt, " %s", attr.unit);
85 } while (attr.index); 87 } while (attr.index);
86 88
87 if ((state >= 0 && info.pstate == state) || 89 if (state >= 0) {
88 (state < 0 && info.ustate < 0)) 90 if (info.ustate_ac == state)
89 snappendf(buf, cnt, " *"); 91 snappendf(buf, cnt, " AC");
92 if (info.ustate_dc == state)
93 snappendf(buf, cnt, " DC");
94 if (info.pstate == state)
95 snappendf(buf, cnt, " *");
96 } else {
97 if (info.ustate_ac < -1)
98 snappendf(buf, cnt, " AC");
99 if (info.ustate_dc < -1)
100 snappendf(buf, cnt, " DC");
101 }
102
90 snappendf(buf, cnt, "\n"); 103 snappendf(buf, cnt, "\n");
91 } 104 }
92 105
@@ -98,23 +111,32 @@ nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a,
98 const char *buf, size_t count) 111 const char *buf, size_t count)
99{ 112{
100 struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); 113 struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d));
101 struct nv_control_pstate_user args; 114 struct nv_control_pstate_user args = { .pwrsrc = -EINVAL };
102 long value, ret; 115 long value, ret;
103 char *tmp; 116 char *tmp;
104 117
105 if ((tmp = strchr(buf, '\n'))) 118 if ((tmp = strchr(buf, '\n')))
106 *tmp = '\0'; 119 *tmp = '\0';
107 120
121 if (!strncasecmp(buf, "dc:", 3)) {
122 args.pwrsrc = 0;
123 buf += 3;
124 } else
125 if (!strncasecmp(buf, "ac:", 3)) {
126 args.pwrsrc = 1;
127 buf += 3;
128 }
129
108 if (!strcasecmp(buf, "none")) 130 if (!strcasecmp(buf, "none"))
109 args.state = NV_CONTROL_PSTATE_USER_STATE_UNKNOWN; 131 args.ustate = NV_CONTROL_PSTATE_USER_STATE_UNKNOWN;
110 else 132 else
111 if (!strcasecmp(buf, "auto")) 133 if (!strcasecmp(buf, "auto"))
112 args.state = NV_CONTROL_PSTATE_USER_STATE_PERFMON; 134 args.ustate = NV_CONTROL_PSTATE_USER_STATE_PERFMON;
113 else { 135 else {
114 ret = kstrtol(buf, 16, &value); 136 ret = kstrtol(buf, 16, &value);
115 if (ret) 137 if (ret)
116 return ret; 138 return ret;
117 args.state = value; 139 args.ustate = value;
118 } 140 }
119 141
120 ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_USER, &args, sizeof(args)); 142 ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_USER, &args, sizeof(args));