diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-10-16 19:56:02 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-11-08 00:40:18 -0500 |
commit | 9838366c1597dfd8fe5663ad02024adce2fa07fe (patch) | |
tree | 24109d1cd08d7af491facb62033fc62da1dbb0cf | |
parent | 7c856522069755ab9d163a24ac332cd3cb35fe30 (diff) |
drm/nouveau/device: initial control object class, with pstate control methods
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/base.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/ctrl.c | 144 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/priv.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/class.h | 40 |
5 files changed, 196 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index e65ebb2e3820..e61dcbe09f08 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -187,6 +187,7 @@ nouveau-y += core/engine/copy/nve0.o | |||
187 | nouveau-y += core/engine/crypt/nv84.o | 187 | nouveau-y += core/engine/crypt/nv84.o |
188 | nouveau-y += core/engine/crypt/nv98.o | 188 | nouveau-y += core/engine/crypt/nv98.o |
189 | nouveau-y += core/engine/device/base.o | 189 | nouveau-y += core/engine/device/base.o |
190 | nouveau-y += core/engine/device/ctrl.o | ||
190 | nouveau-y += core/engine/device/nv04.o | 191 | nouveau-y += core/engine/device/nv04.o |
191 | nouveau-y += core/engine/device/nv10.o | 192 | nouveau-y += core/engine/device/nv10.o |
192 | nouveau-y += core/engine/device/nv20.o | 193 | nouveau-y += core/engine/device/nv20.o |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index f775f43f3f77..9135b25a29d0 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | #include <core/class.h> | 30 | #include <core/class.h> |
31 | 31 | ||
32 | #include <engine/device.h> | 32 | #include "priv.h" |
33 | 33 | ||
34 | static DEFINE_MUTEX(nv_devices_mutex); | 34 | static DEFINE_MUTEX(nv_devices_mutex); |
35 | static LIST_HEAD(nv_devices); | 35 | static LIST_HEAD(nv_devices); |
@@ -121,7 +121,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent, | |||
121 | return -ENODEV; | 121 | return -ENODEV; |
122 | } | 122 | } |
123 | 123 | ||
124 | ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL, | 124 | ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, |
125 | nouveau_control_oclass, | ||
125 | (1ULL << NVDEV_ENGINE_DMAOBJ) | | 126 | (1ULL << NVDEV_ENGINE_DMAOBJ) | |
126 | (1ULL << NVDEV_ENGINE_FIFO) | | 127 | (1ULL << NVDEV_ENGINE_FIFO) | |
127 | (1ULL << NVDEV_ENGINE_DISP) | | 128 | (1ULL << NVDEV_ENGINE_DISP) | |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c new file mode 100644 index 000000000000..4b69bf56ed01 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs <bskeggs@redhat.com> | ||
23 | */ | ||
24 | |||
25 | #include <core/object.h> | ||
26 | #include <core/class.h> | ||
27 | |||
28 | #include <subdev/clock.h> | ||
29 | |||
30 | #include "priv.h" | ||
31 | |||
32 | static int | ||
33 | nouveau_control_mthd_pstate_info(struct nouveau_object *object, u32 mthd, | ||
34 | void *data, u32 size) | ||
35 | { | ||
36 | struct nouveau_clock *clk = nouveau_clock(object); | ||
37 | struct nv_control_pstate_info *args = data; | ||
38 | |||
39 | if (size < sizeof(*args)) | ||
40 | return -EINVAL; | ||
41 | |||
42 | if (clk) { | ||
43 | args->count = clk->state_nr; | ||
44 | args->ustate = clk->ustate; | ||
45 | args->pstate = clk->pstate; | ||
46 | } else { | ||
47 | args->count = 0; | ||
48 | args->ustate = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE; | ||
49 | args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN; | ||
50 | } | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int | ||
56 | nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, | ||
57 | void *data, u32 size) | ||
58 | { | ||
59 | struct nouveau_clock *clk = nouveau_clock(object); | ||
60 | struct nv_control_pstate_attr *args = data; | ||
61 | struct nouveau_clocks *domain; | ||
62 | struct nouveau_pstate *pstate; | ||
63 | struct nouveau_cstate *cstate; | ||
64 | int i = 0, j = -1; | ||
65 | u32 lo, hi; | ||
66 | |||
67 | if ((size < sizeof(*args)) || !clk || | ||
68 | (args->state >= 0 && args->state >= clk->state_nr)) | ||
69 | return -EINVAL; | ||
70 | domain = clk->domains; | ||
71 | |||
72 | while (domain->name != nv_clk_src_max) { | ||
73 | if (domain->mname && ++j == args->index) | ||
74 | break; | ||
75 | domain++; | ||
76 | } | ||
77 | |||
78 | if (domain->name == nv_clk_src_max) | ||
79 | return -EINVAL; | ||
80 | |||
81 | if (args->state != NV_CONTROL_PSTATE_ATTR_STATE_CURRENT) { | ||
82 | list_for_each_entry(pstate, &clk->states, head) { | ||
83 | if (i++ == args->state) | ||
84 | break; | ||
85 | } | ||
86 | |||
87 | lo = pstate->base.domain[domain->name]; | ||
88 | hi = lo; | ||
89 | list_for_each_entry(cstate, &pstate->list, head) { | ||
90 | lo = min(lo, cstate->domain[domain->name]); | ||
91 | hi = max(hi, cstate->domain[domain->name]); | ||
92 | } | ||
93 | |||
94 | args->state = pstate->pstate; | ||
95 | } else { | ||
96 | lo = max(clk->read(clk, domain->name), 0); | ||
97 | hi = lo; | ||
98 | } | ||
99 | |||
100 | snprintf(args->name, sizeof(args->name), "%s", domain->mname); | ||
101 | snprintf(args->unit, sizeof(args->unit), "MHz"); | ||
102 | args->min = lo / domain->mdiv; | ||
103 | args->max = hi / domain->mdiv; | ||
104 | |||
105 | args->index = 0; | ||
106 | while ((++domain)->name != nv_clk_src_max) { | ||
107 | if (domain->mname) { | ||
108 | args->index = ++j; | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int | ||
117 | nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd, | ||
118 | void *data, u32 size) | ||
119 | { | ||
120 | struct nouveau_clock *clk = nouveau_clock(object); | ||
121 | struct nv_control_pstate_user *args = data; | ||
122 | |||
123 | if (size < sizeof(*args) || !clk) | ||
124 | return -EINVAL; | ||
125 | |||
126 | return nouveau_clock_ustate(clk, args->state); | ||
127 | } | ||
128 | |||
129 | struct nouveau_oclass | ||
130 | nouveau_control_oclass[] = { | ||
131 | { .handle = NV_CONTROL_CLASS, | ||
132 | .ofuncs = &nouveau_object_ofuncs, | ||
133 | .omthds = (struct nouveau_omthds[]) { | ||
134 | { NV_CONTROL_PSTATE_INFO, | ||
135 | NV_CONTROL_PSTATE_INFO, nouveau_control_mthd_pstate_info }, | ||
136 | { NV_CONTROL_PSTATE_ATTR, | ||
137 | NV_CONTROL_PSTATE_ATTR, nouveau_control_mthd_pstate_attr }, | ||
138 | { NV_CONTROL_PSTATE_USER, | ||
139 | NV_CONTROL_PSTATE_USER, nouveau_control_mthd_pstate_user }, | ||
140 | {}, | ||
141 | }, | ||
142 | }, | ||
143 | {} | ||
144 | }; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/priv.h b/drivers/gpu/drm/nouveau/core/engine/device/priv.h new file mode 100644 index 000000000000..035fd5b9cfc3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/device/priv.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef __NVKM_DEVICE_PRIV_H__ | ||
2 | #define __NVKM_DEVICE_PRIV_H__ | ||
3 | |||
4 | #include <engine/device.h> | ||
5 | |||
6 | extern struct nouveau_oclass nouveau_control_oclass[]; | ||
7 | |||
8 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index a30fd990afc8..560c3593dae7 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h | |||
@@ -129,6 +129,46 @@ struct nv_perfctr_read { | |||
129 | u32 clk; | 129 | u32 clk; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | /* Device control class | ||
133 | * | ||
134 | * XXXX: NV_CONTROL | ||
135 | */ | ||
136 | #define NV_CONTROL_CLASS 0x0000fffe | ||
137 | |||
138 | #define NV_CONTROL_PSTATE_INFO 0x00000000 | ||
139 | #define NV_CONTROL_PSTATE_INFO_USTATE_DISABLE (-1) | ||
140 | #define NV_CONTROL_PSTATE_INFO_USTATE_PERFMON (-2) | ||
141 | #define NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN (-1) | ||
142 | #define NV_CONTROL_PSTATE_INFO_PSTATE_PERFMON (-2) | ||
143 | #define NV_CONTROL_PSTATE_ATTR 0x00000001 | ||
144 | #define NV_CONTROL_PSTATE_ATTR_STATE_CURRENT (-1) | ||
145 | #define NV_CONTROL_PSTATE_USER 0x00000002 | ||
146 | #define NV_CONTROL_PSTATE_USER_STATE_UNKNOWN (-1) | ||
147 | #define NV_CONTROL_PSTATE_USER_STATE_PERFMON (-2) | ||
148 | |||
149 | struct nv_control_pstate_info { | ||
150 | u32 count; /* out: number of power states */ | ||
151 | s32 ustate; /* out: current target pstate index */ | ||
152 | u32 pstate; /* out: current pstate index */ | ||
153 | }; | ||
154 | |||
155 | struct nv_control_pstate_attr { | ||
156 | s32 state; /* in: index of pstate to query | ||
157 | * out: pstate identifier | ||
158 | */ | ||
159 | u32 index; /* in: index of attribute to query | ||
160 | * out: index of next attribute, or 0 if no more | ||
161 | */ | ||
162 | char name[32]; | ||
163 | char unit[16]; | ||
164 | u32 min; | ||
165 | u32 max; | ||
166 | }; | ||
167 | |||
168 | struct nv_control_pstate_user { | ||
169 | s32 state; /* in: pstate identifier */ | ||
170 | }; | ||
171 | |||
132 | /* DMA FIFO channel classes | 172 | /* DMA FIFO channel classes |
133 | * | 173 | * |
134 | * 006b: NV03_CHANNEL_DMA | 174 | * 006b: NV03_CHANNEL_DMA |