summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}