summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2016-09-30 19:40:29 -0400
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:51 -0500
commit7a8b12ab634c05cd39c08e704c28ee3f4e111c7f (patch)
treedd9ad4e4d27e0eb779329a0e86c8b8dff5b3312e
parent3d9c33c5953e383527c7e4af594adfe0c82b5788 (diff)
gpu: nvgpu: clk requests completion and event fds
Install one completion fd per SET request. Notifications on dedicated event fd. Changed frequencies unit to Hz from MHz. Remove sequence numbers from dummy arbiter. Added effective clock type (query frequency from counters). Jira DNVGPU-125 Change-Id: Id5445c6ae1d6bf06f7f59c82ff6c5d3b34e26483 Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: http://git-master/r/1230239 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> (cherry picked from commit d17083f4ceb69725c661678607a3e43148d38560) Reviewed-on: http://git-master/r/1243106
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c326
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.h29
-rw-r--r--drivers/gpu/nvgpu/gp106/clk_arb_gp106.c10
3 files changed, 211 insertions, 154 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 1d02c7d7..98b7cb5f 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -21,50 +21,63 @@
21 21
22#include "clk/clk_arb.h" 22#include "clk/clk_arb.h"
23 23
24static int nvgpu_clk_arb_release_session_dev(struct inode *inode, struct file *filp); 24static int nvgpu_clk_arb_release_event_dev(struct inode *inode,
25static unsigned int nvgpu_clk_arb_poll_session_dev(struct file *filp, poll_table *wait); 25 struct file *filp);
26static int nvgpu_clk_arb_release_completion_dev(struct inode *inode,
27 struct file *filp);
28static unsigned int nvgpu_clk_arb_poll_dev(struct file *filp, poll_table *wait);
26 29
27static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work); 30static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work);
28 31
29struct nvgpu_clk_arb { 32struct nvgpu_clk_arb {
30 struct mutex wlock; 33 struct mutex req_lock;
31 struct mutex users_lock; 34 struct mutex users_lock;
32 struct list_head users; 35 struct list_head users;
33 u32 gpc2clk_current_mhz; 36 struct list_head requests;
34 u32 gpc2clk_target_mhz; 37
35 u32 gpc2clk_default_mhz; 38 u64 gpc2clk_current_hz;
36 u32 mclk_current_mhz; 39 u64 gpc2clk_target_hz;
37 u32 mclk_target_mhz; 40 u64 gpc2clk_default_hz;
38 u32 mclk_default_mhz; 41 u64 mclk_current_hz;
42 u64 mclk_target_hz;
43 u64 mclk_default_hz;
39 atomic_t usercount; 44 atomic_t usercount;
40 struct work_struct update_fn_work; 45 struct work_struct update_fn_work;
46};
47
41 48
42 atomic_t req_nr; /* for allocations */ 49struct nvgpu_clk_dev {
43 atomic_t last_req_nr; /* last completed by arbiter */ 50 struct nvgpu_clk_session *session;
51 struct list_head link;
52 wait_queue_head_t readout_wq;
53 atomic_t poll_mask;
44}; 54};
45 55
46struct nvgpu_clk_session { 56struct nvgpu_clk_session {
57 bool zombie;
47 struct gk20a *g; 58 struct gk20a *g;
48 int fd;
49 atomic_t req_nr;
50 struct kref refcount; 59 struct kref refcount;
51 wait_queue_head_t readout_wq; 60
52 atomic_t poll_mask; 61 u64 gpc2clk_target_hz;
53 struct list_head user; 62 u64 mclk_target_hz;
54 u32 gpc2clk_target_mhz;
55 u32 mclk_target_mhz;
56}; 63};
57 64
58const struct file_operations clk_dev_ops = { 65static const struct file_operations completion_dev_ops = {
59 .owner = THIS_MODULE, 66 .owner = THIS_MODULE,
60 .release = nvgpu_clk_arb_release_session_dev, 67 .release = nvgpu_clk_arb_release_completion_dev,
61 .poll = nvgpu_clk_arb_poll_session_dev, 68 .poll = nvgpu_clk_arb_poll_dev,
69};
70
71static const struct file_operations event_dev_ops = {
72 .owner = THIS_MODULE,
73 .release = nvgpu_clk_arb_release_event_dev,
74 .poll = nvgpu_clk_arb_poll_dev,
62}; 75};
63 76
64int nvgpu_clk_arb_init_arbiter(struct gk20a *g) 77int nvgpu_clk_arb_init_arbiter(struct gk20a *g)
65{ 78{
66 struct nvgpu_clk_arb *arb; 79 struct nvgpu_clk_arb *arb;
67 u16 default_mhz; 80 u64 default_hz;
68 int err; 81 int err;
69 82
70 gk20a_dbg_fn(""); 83 gk20a_dbg_fn("");
@@ -78,32 +91,31 @@ int nvgpu_clk_arb_init_arbiter(struct gk20a *g)
78 91
79 g->clk_arb = arb; 92 g->clk_arb = arb;
80 93
81 mutex_init(&arb->wlock); 94 mutex_init(&arb->req_lock);
82 mutex_init(&arb->users_lock); 95 mutex_init(&arb->users_lock);
83 96
84 err = g->ops.clk_arb.get_arbiter_clk_default(g, 97 err = g->ops.clk_arb.get_arbiter_clk_default(g,
85 NVGPU_GPU_CLK_DOMAIN_MCLK, &default_mhz); 98 NVGPU_GPU_CLK_DOMAIN_MCLK, &default_hz);
86 if (err) 99 if (err)
87 return -EINVAL; 100 return -EINVAL;
88 101
89 arb->mclk_target_mhz = default_mhz; 102 arb->mclk_target_hz = default_hz;
90 arb->mclk_current_mhz = default_mhz; 103 arb->mclk_current_hz = default_hz;
91 arb->mclk_default_mhz = default_mhz; 104 arb->mclk_default_hz = default_hz;
92 105
93 err = g->ops.clk_arb.get_arbiter_clk_default(g, 106 err = g->ops.clk_arb.get_arbiter_clk_default(g,
94 NVGPU_GPU_CLK_DOMAIN_GPC2CLK, &default_mhz); 107 NVGPU_GPU_CLK_DOMAIN_GPC2CLK, &default_hz);
95 if (err) 108 if (err)
96 return -EINVAL; 109 return -EINVAL;
97 110
98 arb->gpc2clk_target_mhz = default_mhz; 111 arb->gpc2clk_target_hz = default_hz;
99 arb->gpc2clk_current_mhz = default_mhz; 112 arb->gpc2clk_current_hz = default_hz;
100 arb->gpc2clk_default_mhz = default_mhz; 113 arb->gpc2clk_default_hz = default_hz;
101 114
102 atomic_set(&arb->usercount, 0); 115 atomic_set(&arb->usercount, 0);
103 atomic_set(&arb->req_nr, 0);
104 atomic_set(&arb->last_req_nr, 0);
105 116
106 INIT_LIST_HEAD(&arb->users); 117 INIT_LIST_HEAD(&arb->users);
118 INIT_LIST_HEAD(&arb->requests);
107 INIT_WORK(&arb->update_fn_work, nvgpu_clk_arb_run_arbiter_cb); 119 INIT_WORK(&arb->update_fn_work, nvgpu_clk_arb_run_arbiter_cb);
108 120
109 return 0; 121 return 0;
@@ -114,44 +126,50 @@ void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g)
114 kfree(g->clk_arb); 126 kfree(g->clk_arb);
115} 127}
116 128
117 129static int nvgpu_clk_arb_install_fd(struct gk20a *g,
118int nvgpu_clk_arb_install_session_fd(struct gk20a *g, 130 struct nvgpu_clk_session *session,
119 struct nvgpu_clk_session *session) 131 const struct file_operations *fops,
132 struct nvgpu_clk_dev **_dev)
120{ 133{
121 struct file *file; 134 struct file *file;
122 char *name; 135 char *name;
123 int fd; 136 int fd;
124 int err; 137 int err;
138 struct nvgpu_clk_dev *dev;
125 139
126 gk20a_dbg_fn(""); 140 gk20a_dbg_fn("");
127 141
128 if (session->fd >= 0) 142 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
129 goto done; 143 if (!dev)
144 return -ENOMEM;
130 145
131 fd = get_unused_fd_flags(O_RDWR); 146 fd = get_unused_fd_flags(O_RDWR);
132 if (fd < 0) 147 if (fd < 0)
133 return fd; 148 return fd;
134 149
135 name = kasprintf(GFP_KERNEL, "%s-clk-fd%d", dev_name(g->dev), fd); 150 name = kasprintf(GFP_KERNEL, "%s-clk-fd%d", dev_name(g->dev), fd);
136 file = anon_inode_getfile(name, &clk_dev_ops, session, O_RDWR); 151 file = anon_inode_getfile(name, fops, dev, O_RDWR);
137 kfree(name); 152 kfree(name);
138 if (IS_ERR(file)) { 153 if (IS_ERR(file)) {
139 err = PTR_ERR(file); 154 err = PTR_ERR(file);
140 goto clean_up_fd; 155 goto fail;
141 } 156 }
142 157
143 BUG_ON(file->private_data != session);
144
145 fd_install(fd, file); 158 fd_install(fd, file);
159
160 init_waitqueue_head(&dev->readout_wq);
161 atomic_set(&dev->poll_mask, 0);
162
163 dev->session = session;
146 kref_get(&session->refcount); 164 kref_get(&session->refcount);
147 165
148 session->fd = fd; 166 *_dev = dev;
149done:
150 return session->fd;
151 167
152clean_up_fd: 168 return fd;
153 put_unused_fd(fd);
154 169
170fail:
171 kfree(dev);
172 put_unused_fd(fd);
155 return err; 173 return err;
156} 174}
157 175
@@ -163,8 +181,6 @@ int nvgpu_clk_arb_init_session(struct gk20a *g,
163 181
164 gk20a_dbg_fn(""); 182 gk20a_dbg_fn("");
165 183
166 *_session = NULL;
167
168 if (!g->ops.clk_arb.get_arbiter_clk_domains) 184 if (!g->ops.clk_arb.get_arbiter_clk_domains)
169 return 0; 185 return 0;
170 186
@@ -172,23 +188,14 @@ int nvgpu_clk_arb_init_session(struct gk20a *g,
172 if (!session) 188 if (!session)
173 return -ENOMEM; 189 return -ENOMEM;
174 session->g = g; 190 session->g = g;
175 session->fd = -1;
176 191
177 kref_init(&session->refcount); 192 kref_init(&session->refcount);
178 init_waitqueue_head(&session->readout_wq);
179
180 atomic_set(&session->poll_mask, 0);
181 atomic_set(&session->req_nr, 0);
182 193
183 mutex_lock(&arb->users_lock);
184 list_add_tail(&session->user, &arb->users);
185 mutex_unlock(&arb->users_lock);
186 atomic_inc(&arb->usercount); 194 atomic_inc(&arb->usercount);
187 195
188 mutex_lock(&arb->wlock); 196 session->zombie = false;
189 session->mclk_target_mhz = arb->mclk_default_mhz; 197 session->mclk_target_hz = arb->mclk_default_hz;
190 session->gpc2clk_target_mhz = arb->gpc2clk_default_mhz; 198 session->gpc2clk_target_hz = arb->gpc2clk_default_hz;
191 mutex_unlock(&arb->wlock);
192 199
193 *_session = session; 200 *_session = session;
194 201
@@ -199,23 +206,41 @@ void nvgpu_clk_arb_free_session(struct kref *refcount)
199{ 206{
200 struct nvgpu_clk_session *session = container_of(refcount, 207 struct nvgpu_clk_session *session = container_of(refcount,
201 struct nvgpu_clk_session, refcount); 208 struct nvgpu_clk_session, refcount);
202 struct gk20a *g = session->g;
203 struct nvgpu_clk_arb *arb = g->clk_arb;
204
205 mutex_lock(&arb->users_lock);
206 list_del_init(&session->user);
207 mutex_unlock(&arb->users_lock);
208
209 if (atomic_dec_and_test(&arb->usercount))
210 nvgpu_clk_arb_apply_session_constraints(g, NULL);
211 209
212 kfree(session); 210 kfree(session);
213} 211}
214 212
215void nvgpu_clk_arb_cleanup_session(struct gk20a *g, 213void nvgpu_clk_arb_release_session(struct gk20a *g,
216 struct nvgpu_clk_session *session) 214 struct nvgpu_clk_session *session)
217{ 215{
216 struct nvgpu_clk_arb *arb = g->clk_arb;
217
218 session->zombie = true;
218 kref_put(&session->refcount, nvgpu_clk_arb_free_session); 219 kref_put(&session->refcount, nvgpu_clk_arb_free_session);
220
221 /* schedule arbiter if no more user */
222 if (!atomic_dec_and_test(&arb->usercount))
223 schedule_work(&arb->update_fn_work);
224}
225
226int nvgpu_clk_arb_install_event_fd(struct gk20a *g,
227 struct nvgpu_clk_session *session, int *event_fd)
228{
229 struct nvgpu_clk_arb *arb = g->clk_arb;
230 struct nvgpu_clk_dev *dev;
231 int fd;
232
233 fd = nvgpu_clk_arb_install_fd(g, session, &event_dev_ops, &dev);
234 if (fd < 0)
235 return fd;
236
237 mutex_lock(&arb->users_lock);
238 list_add_tail(&dev->link, &arb->users);
239 mutex_unlock(&arb->users_lock);
240
241 *event_fd = fd;
242
243 return 0;
219} 244}
220 245
221static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work) 246static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
@@ -223,88 +248,125 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
223 struct nvgpu_clk_arb *arb = 248 struct nvgpu_clk_arb *arb =
224 container_of(work, struct nvgpu_clk_arb, update_fn_work); 249 container_of(work, struct nvgpu_clk_arb, update_fn_work);
225 struct nvgpu_clk_session *session; 250 struct nvgpu_clk_session *session;
251 struct nvgpu_clk_dev *dev;
252 struct nvgpu_clk_dev *tmp;
253
254 mutex_lock(&arb->req_lock);
226 255
227 mutex_lock(&arb->wlock); 256 arb->mclk_target_hz = arb->mclk_default_hz;
257 arb->gpc2clk_target_hz = arb->gpc2clk_default_hz;
258
259 list_for_each_entry(dev, &arb->requests, link) {
260 session = dev->session;
261 if (!session->zombie) {
262 /* TODO: arbiter policy. For now last request wins */
263
264 arb->mclk_target_hz = session->mclk_target_hz;
265 arb->gpc2clk_target_hz = session->gpc2clk_target_hz;
266 }
267 }
228 268
229 /* TODO: loop up higher or equal VF points */ 269 /* TODO: loop up higher or equal VF points */
230 270
231 arb->mclk_current_mhz = arb->mclk_target_mhz; 271 arb->mclk_current_hz = arb->mclk_target_hz;
232 arb->gpc2clk_current_mhz = arb->gpc2clk_target_mhz; 272 arb->gpc2clk_current_hz = arb->gpc2clk_target_hz;
233 273
234 /* TODO: actually program the clocks */ 274 /* TODO: actually program the clocks */
235 275
236 atomic_set(&arb->last_req_nr, atomic_read(&arb->req_nr)); 276 /* notify completion for all requests */
237 mutex_unlock(&arb->wlock); 277 list_for_each_entry_safe(dev, tmp, &arb->requests, link) {
278 atomic_set(&dev->poll_mask, POLLIN | POLLRDNORM);
279 wake_up_interruptible(&dev->readout_wq);
280 list_del_init(&dev->link);
281 }
282 mutex_unlock(&arb->req_lock);
238 283
284 /* notify event for all users */
239 mutex_lock(&arb->users_lock); 285 mutex_lock(&arb->users_lock);
240 list_for_each_entry(session, &arb->users, user) { 286 list_for_each_entry(dev, &arb->users, link) {
241 atomic_set(&session->poll_mask, POLLIN | POLLRDNORM); 287 atomic_set(&dev->poll_mask, POLLIN | POLLRDNORM);
242 wake_up_interruptible(&session->readout_wq); 288 wake_up_interruptible(&dev->readout_wq);
243 } 289 }
244 mutex_unlock(&arb->users_lock); 290 mutex_unlock(&arb->users_lock);
245 291
246} 292}
247 293
248void nvgpu_clk_arb_apply_session_constraints(struct gk20a *g, 294int nvgpu_clk_arb_apply_session_constraints(struct gk20a *g,
249 struct nvgpu_clk_session *session) 295 struct nvgpu_clk_session *session, int *completion_fd)
250{ 296{
251 struct nvgpu_clk_arb *arb = g->clk_arb; 297 struct nvgpu_clk_arb *arb = g->clk_arb;
298 struct nvgpu_clk_dev *dev;
299 int fd;
252 300
253 mutex_lock(&arb->wlock); 301 fd = nvgpu_clk_arb_install_fd(g, session, &completion_dev_ops, &dev);
254 atomic_inc(&arb->req_nr); 302 if (fd < 0)
255 303 return fd;
256 /* TODO: arbitration between users.
257 For now, last session to run arbiter wins.
258 */
259 304
260 if (session) { 305 *completion_fd = fd;
261 arb->mclk_target_mhz = session->mclk_target_mhz;
262 arb->gpc2clk_target_mhz = session->gpc2clk_target_mhz;
263 306
264 atomic_set(&session->req_nr, atomic_read(&arb->req_nr)); 307 mutex_lock(&arb->req_lock);
265 } else { 308 list_add_tail(&dev->link, &arb->requests);
266 arb->mclk_target_mhz = arb->mclk_default_mhz; 309 mutex_unlock(&arb->req_lock);
267 arb->gpc2clk_target_mhz = arb->gpc2clk_default_mhz;
268 }
269 mutex_unlock(&arb->wlock);
270 310
271 schedule_work(&arb->update_fn_work); 311 schedule_work(&arb->update_fn_work);
312
313 return 0;
272} 314}
273 315
274static unsigned int nvgpu_clk_arb_poll_session_dev(struct file *filp, poll_table *wait) 316static unsigned int nvgpu_clk_arb_poll_dev(struct file *filp, poll_table *wait)
275{ 317{
276 struct nvgpu_clk_session *session = filp->private_data; 318 struct nvgpu_clk_dev *dev = filp->private_data;
277 319
278 gk20a_dbg_fn(""); 320 gk20a_dbg_fn("");
279 321
280 poll_wait(filp, &session->readout_wq, wait); 322 poll_wait(filp, &dev->readout_wq, wait);
281 return atomic_xchg(&session->poll_mask, 0); 323 return atomic_xchg(&dev->poll_mask, 0);
282} 324}
283 325
284static int nvgpu_clk_arb_release_session_dev(struct inode *inode, struct file *filp) 326static int nvgpu_clk_arb_release_completion_dev(struct inode *inode,
327 struct file *filp)
285{ 328{
286 struct nvgpu_clk_session *session = filp->private_data; 329 struct nvgpu_clk_dev *dev = filp->private_data;
287 struct gk20a *g = session->g; 330 struct nvgpu_clk_session *session = dev->session;
288 331
289 session->fd = -1; 332 gk20a_dbg_fn("");
290 nvgpu_clk_arb_cleanup_session(g, session); 333
334 kref_put(&session->refcount, nvgpu_clk_arb_free_session);
335 kfree(dev);
336 return 0;
337}
338
339static int nvgpu_clk_arb_release_event_dev(struct inode *inode,
340 struct file *filp)
341{
342 struct nvgpu_clk_dev *dev = filp->private_data;
343 struct nvgpu_clk_session *session = dev->session;
344 struct nvgpu_clk_arb *arb = session->g->clk_arb;
345
346 gk20a_dbg_fn("");
291 347
348 mutex_lock(&arb->users_lock);
349 list_del_init(&dev->link);
350 mutex_unlock(&arb->users_lock);
351
352 kref_put(&session->refcount, nvgpu_clk_arb_free_session);
353 kfree(dev);
292 return 0; 354 return 0;
293} 355}
294 356
295int nvgpu_clk_arb_set_session_target_mhz(struct nvgpu_clk_session *session, 357int nvgpu_clk_arb_set_session_target_hz(struct nvgpu_clk_session *session,
296 u32 api_domain, u16 target_mhz) 358 u32 api_domain, u64 target_hz)
297{ 359{
298 360
299 gk20a_dbg_fn("domain=0x%08x target_mhz=%u", api_domain, target_mhz); 361 gk20a_dbg_fn("domain=0x%08x target_hz=%llu", api_domain, target_hz);
300 362
301 switch (api_domain) { 363 switch (api_domain) {
302 case NVGPU_GPU_CLK_DOMAIN_MCLK: 364 case NVGPU_GPU_CLK_DOMAIN_MCLK:
303 session->mclk_target_mhz = target_mhz; 365 session->mclk_target_hz = target_hz;
304 return 0; 366 return 0;
305 367
306 case NVGPU_GPU_CLK_DOMAIN_GPC2CLK: 368 case NVGPU_GPU_CLK_DOMAIN_GPC2CLK:
307 session->gpc2clk_target_mhz = target_mhz; 369 session->gpc2clk_target_hz = target_hz;
308 return 0; 370 return 0;
309 371
310 default: 372 default:
@@ -312,61 +374,61 @@ int nvgpu_clk_arb_set_session_target_mhz(struct nvgpu_clk_session *session,
312 } 374 }
313} 375}
314 376
315int nvgpu_clk_arb_get_session_target_mhz(struct nvgpu_clk_session *session, 377int nvgpu_clk_arb_get_session_target_hz(struct nvgpu_clk_session *session,
316 u32 api_domain, u16 *target_mhz) 378 u32 api_domain, u64 *freq_hz)
317{ 379{
318 switch (api_domain) { 380 switch (api_domain) {
319 case NVGPU_GPU_CLK_DOMAIN_MCLK: 381 case NVGPU_GPU_CLK_DOMAIN_MCLK:
320 *target_mhz = session->mclk_target_mhz; 382 *freq_hz = session->mclk_target_hz;
321 return 0; 383 return 0;
322 384
323 case NVGPU_GPU_CLK_DOMAIN_GPC2CLK: 385 case NVGPU_GPU_CLK_DOMAIN_GPC2CLK:
324 *target_mhz = session->gpc2clk_target_mhz; 386 *freq_hz = session->gpc2clk_target_hz;
325 return 0; 387 return 0;
326 388
327 default: 389 default:
328 *target_mhz = 0; 390 *freq_hz = 0;
329 return -EINVAL; 391 return -EINVAL;
330 } 392 }
331} 393}
332 394
333int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, 395int nvgpu_clk_arb_get_arbiter_actual_hz(struct gk20a *g,
334 u32 api_domain, u16 *actual_mhz) 396 u32 api_domain, u64 *freq_hz)
335{ 397{
336 struct nvgpu_clk_arb *arb = g->clk_arb; 398 struct nvgpu_clk_arb *arb = g->clk_arb;
337 int err = 0; 399 int err = 0;
338 400
339 mutex_lock(&arb->wlock); 401 mutex_lock(&arb->req_lock);
340 switch (api_domain) { 402 switch (api_domain) {
341 case NVGPU_GPU_CLK_DOMAIN_MCLK: 403 case NVGPU_GPU_CLK_DOMAIN_MCLK:
342 *actual_mhz = arb->mclk_current_mhz; 404 *freq_hz = arb->mclk_current_hz;
343 break; 405 break;
344 406
345 case NVGPU_GPU_CLK_DOMAIN_GPC2CLK: 407 case NVGPU_GPU_CLK_DOMAIN_GPC2CLK:
346 *actual_mhz = arb->gpc2clk_current_mhz; 408 *freq_hz = arb->gpc2clk_current_hz;
347 break; 409 break;
348 410
349 default: 411 default:
350 *actual_mhz = 0; 412 *freq_hz = 0;
351 err = -EINVAL; 413 err = -EINVAL;
352 } 414 }
353 mutex_unlock(&arb->wlock); 415 mutex_unlock(&arb->req_lock);
354 416
355 return err; 417 return err;
356} 418}
357 419
358u32 nvgpu_clk_arb_get_arbiter_req_nr(struct gk20a *g) 420int nvgpu_clk_arb_get_arbiter_effective_hz(struct gk20a *g,
421 u32 api_domain, u64 *freq_hz)
359{ 422{
360 struct nvgpu_clk_arb *arb = g->clk_arb; 423 /* TODO: measure clocks from counters */
361 424 return nvgpu_clk_arb_get_arbiter_actual_hz(g, api_domain, freq_hz);
362 return atomic_read(&arb->last_req_nr);
363} 425}
364 426
365int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, 427int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain,
366 u16 *min_mhz, u16 *max_mhz) 428 u64 *min_hz, u64 *max_hz)
367{ 429{
368 return g->ops.clk_arb.get_arbiter_clk_range(g, api_domain, 430 return g->ops.clk_arb.get_arbiter_clk_range(g, api_domain,
369 min_mhz, max_mhz); 431 min_hz, max_hz);
370} 432}
371 433
372u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g) 434u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g)
@@ -374,12 +436,6 @@ u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g)
374 return g->ops.clk_arb.get_arbiter_clk_domains(g); 436 return g->ops.clk_arb.get_arbiter_clk_domains(g);
375} 437}
376 438
377u32 nvgpu_clk_arb_get_session_req_nr(struct gk20a *g,
378 struct nvgpu_clk_session *session)
379{
380 return atomic_read(&session->req_nr);
381}
382
383int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g, 439int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g,
384 u32 api_domain, u32 *max_points, u16 *fpoints) 440 u32 api_domain, u32 *max_points, u16 *fpoints)
385{ 441{
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.h b/drivers/gpu/nvgpu/clk/clk_arb.h
index 9981041b..95749369 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.h
+++ b/drivers/gpu/nvgpu/clk/clk_arb.h
@@ -22,16 +22,17 @@ struct nvgpu_clk_session;
22int nvgpu_clk_arb_init_arbiter(struct gk20a *g); 22int nvgpu_clk_arb_init_arbiter(struct gk20a *g);
23 23
24int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, 24int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain,
25 u16 *min_mhz, u16 *max_mhz); 25 u64 *min_hz, u64 *max_hz);
26 26
27int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, 27int nvgpu_clk_arb_get_arbiter_actual_hz(struct gk20a *g,
28 u32 api_domain, u16 *actual_mhz); 28 u32 api_domain, u64 *actual_hz);
29
30int nvgpu_clk_arb_get_arbiter_effective_hz(struct gk20a *g,
31 u32 api_domain, u64 *actual_hz);
29 32
30int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g, 33int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g,
31 u32 api_domain, u32 *max_points, u16 *fpoints); 34 u32 api_domain, u32 *max_points, u16 *fpoints);
32 35
33u32 nvgpu_clk_arb_get_arbiter_req_nr(struct gk20a *g);
34
35u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g); 36u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g);
36 37
37void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g); 38void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g);
@@ -42,20 +43,20 @@ int nvgpu_clk_arb_install_session_fd(struct gk20a *g,
42int nvgpu_clk_arb_init_session(struct gk20a *g, 43int nvgpu_clk_arb_init_session(struct gk20a *g,
43 struct nvgpu_clk_session **_session); 44 struct nvgpu_clk_session **_session);
44 45
45void nvgpu_clk_arb_cleanup_session(struct gk20a *g, 46void nvgpu_clk_arb_release_session(struct gk20a *g,
46 struct nvgpu_clk_session *session); 47 struct nvgpu_clk_session *session);
47 48
48void nvgpu_clk_arb_apply_session_constraints(struct gk20a *g, 49int nvgpu_clk_arb_apply_session_constraints(struct gk20a *g,
49 struct nvgpu_clk_session *session); 50 struct nvgpu_clk_session *session, int *completion_fd);
50 51
51int nvgpu_clk_arb_set_session_target_mhz(struct nvgpu_clk_session *session, 52int nvgpu_clk_arb_set_session_target_hz(struct nvgpu_clk_session *session,
52 u32 api_domain, u16 target_mhz); 53 u32 api_domain, u64 target_hz);
53 54
54int nvgpu_clk_arb_get_session_target_mhz(struct nvgpu_clk_session *session, 55int nvgpu_clk_arb_get_session_target_hz(struct nvgpu_clk_session *session,
55 u32 api_domain, u16 *target_mhz); 56 u32 api_domain, u64 *target_hz);
56 57
57u32 nvgpu_clk_arb_get_session_req_nr(struct gk20a *g, 58int nvgpu_clk_arb_install_event_fd(struct gk20a *g,
58 struct nvgpu_clk_session *session); 59 struct nvgpu_clk_session *session, int *event_fd);
59 60
60 61
61 62
diff --git a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c
index d1cbb32b..112cb588 100644
--- a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c
@@ -23,7 +23,7 @@ static u32 gp106_get_arbiter_clk_domains(struct gk20a *g)
23} 23}
24 24
25static int gp106_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, 25static int gp106_get_arbiter_clk_range(struct gk20a *g, u32 api_domain,
26 u16 *min_mhz, u16 *max_mhz) 26 u64 *min_hz, u64 *max_hz)
27{ 27{
28 enum nv_pmu_clk_clkwhich clkwhich; 28 enum nv_pmu_clk_clkwhich clkwhich;
29 struct clk_set_info *p0_info; 29 struct clk_set_info *p0_info;
@@ -52,14 +52,14 @@ static int gp106_get_arbiter_clk_range(struct gk20a *g, u32 api_domain,
52 if (!p0_info) 52 if (!p0_info)
53 return -EINVAL; 53 return -EINVAL;
54 54
55 *min_mhz = p5_info->min_mhz; 55 *min_hz = (u64)(p5_info->min_mhz) * (u64)MHZ;
56 *max_mhz = p0_info->max_mhz; 56 *max_hz = (u64)(p0_info->max_mhz) * (u64)MHZ;
57 57
58 return 0; 58 return 0;
59} 59}
60 60
61static int gp106_get_arbiter_clk_default(struct gk20a *g, u32 api_domain, 61static int gp106_get_arbiter_clk_default(struct gk20a *g, u32 api_domain,
62 u16 *default_mhz) 62 u64 *default_hz)
63{ 63{
64 enum nv_pmu_clk_clkwhich clkwhich; 64 enum nv_pmu_clk_clkwhich clkwhich;
65 struct clk_set_info *p0_info; 65 struct clk_set_info *p0_info;
@@ -82,7 +82,7 @@ static int gp106_get_arbiter_clk_default(struct gk20a *g, u32 api_domain,
82 if (!p0_info) 82 if (!p0_info)
83 return -EINVAL; 83 return -EINVAL;
84 84
85 *default_mhz = p0_info->max_mhz; 85 *default_hz = (u64)p0_info->max_mhz * (u64)MHZ;
86 86
87 return 0; 87 return 0;
88} 88}