summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c
diff options
context:
space:
mode:
authorDeepak Goyal <dgoyal@nvidia.com>2018-01-18 01:14:47 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-01-19 02:40:02 -0500
commite0dbf3a784f6cb1a6e1c41a23123b19ec73b8708 (patch)
treed089cf84f16980034b82c53f2913bcdda452151d /drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c
parenta57258e9b18f2f336457165391572bc477371e94 (diff)
gpu: nvgpu: gv11b: Enable perfmon.
t19x PMU ucode uses RPC mechanism for PERFMON commands. - Declared "pmu_init_perfmon", "pmu_perfmon_start_sampling", "pmu_perfmon_stop_sampling" and "pmu_perfmon_get_samples" in pmu ops to differenciate for chips using RPC & legacy cmd/msg mechanism. - Defined and used PERFMON RPC commands for t19x - INIT - START - STOP - QUERY - Adds RPC handler for PERFMON RPC commands. - For guerying GPU utilization/load, we need to send PERFMON_QUERY RPC command for gv11b. - Enables perfmon for gv11b. Bug 2039013 Change-Id: Ic32326f81d48f11bc772afb8fee2dee6e427a699 Signed-off-by: Deepak Goyal <dgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1614114 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Tested-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c')
-rw-r--r--drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c136
1 files changed, 133 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c b/drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c
index 2b952868..25d81b60 100644
--- a/drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c
+++ b/drivers/gpu/nvgpu/common/pmu/pmu_perfmon.c
@@ -221,11 +221,18 @@ int nvgpu_pmu_load_update(struct gk20a *g)
221 221
222 if (!pmu->perfmon_ready) { 222 if (!pmu->perfmon_ready) {
223 pmu->load_shadow = 0; 223 pmu->load_shadow = 0;
224 pmu->load = 0;
224 return 0; 225 return 0;
225 } 226 }
226 227
227 nvgpu_flcn_copy_from_dmem(pmu->flcn, pmu->sample_buffer, 228 if (g->ops.pmu.pmu_perfmon_get_samples_rpc) {
228 (u8 *)&load, 2, 0); 229 nvgpu_pmu_perfmon_get_samples_rpc(pmu);
230 load = pmu->load;
231 } else {
232 nvgpu_flcn_copy_from_dmem(pmu->flcn, pmu->sample_buffer,
233 (u8 *)&load, 2 * 1, 0);
234 }
235
229 pmu->load_shadow = load / 10; 236 pmu->load_shadow = load / 10;
230 pmu->load_avg = (((9*pmu->load_avg) + pmu->load_shadow) / 10); 237 pmu->load_avg = (((9*pmu->load_avg) + pmu->load_shadow) / 10);
231 238
@@ -288,6 +295,129 @@ int nvgpu_pmu_handle_perfmon_event(struct nvgpu_pmu *pmu,
288 295
289 /* restart sampling */ 296 /* restart sampling */
290 if (pmu->perfmon_sampling_enabled) 297 if (pmu->perfmon_sampling_enabled)
291 return nvgpu_pmu_perfmon_start_sampling(pmu); 298 return g->ops.pmu.pmu_perfmon_start_sampling(&(g->pmu));
299
292 return 0; 300 return 0;
293} 301}
302
303/* Perfmon RPC */
304int nvgpu_pmu_init_perfmon_rpc(struct nvgpu_pmu *pmu)
305{
306 struct gk20a *g = gk20a_from_pmu(pmu);
307 struct nv_pmu_rpc_struct_perfmon_init rpc;
308 int status = 0;
309
310 if (!nvgpu_is_enabled(g, NVGPU_PMU_PERFMON))
311 return 0;
312
313 nvgpu_log_fn(g, " ");
314
315 memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_perfmon_init));
316 pmu->perfmon_ready = 0;
317
318 gk20a_pmu_init_perfmon_counter(g);
319
320 /* microseconds interval between pmu polls perf counters */
321 rpc.sample_periodus = 16700;
322 /* number of sample periods below lower threshold
323 * before pmu triggers perfmon decrease event
324 */
325 rpc.to_decrease_count = 15;
326 /* index of base counter, aka. always ticking counter */
327 rpc.base_counter_id = 6;
328 /* moving average window for sample periods */
329 rpc.samples_in_moving_avg = 17;
330 /* number of perfmon counters
331 * counter #3 (GR and CE2) for gk20a
332 */
333 rpc.num_counters = 1;
334
335 memset(rpc.counter, 0, sizeof(struct pmu_perfmon_counter_v3) *
336 NV_PMU_PERFMON_MAX_COUNTERS);
337 /* Counter used to count GR busy cycles */
338 rpc.counter[0].index = 3;
339
340 nvgpu_pmu_dbg(g, "RPC post NV_PMU_RPC_ID_PERFMON_INIT");
341 PMU_RPC_EXECUTE(status, pmu, PERFMON_T18X, INIT, &rpc, 0);
342 if (status) {
343 nvgpu_err(g, "Failed to execute RPC, status=0x%x", status);
344 goto exit;
345 }
346
347exit:
348 return 0;
349}
350
351int nvgpu_pmu_perfmon_start_sampling_rpc(struct nvgpu_pmu *pmu)
352{
353 struct gk20a *g = gk20a_from_pmu(pmu);
354 struct nv_pmu_rpc_struct_perfmon_start rpc;
355 int status = 0;
356
357 if (!nvgpu_is_enabled(g, NVGPU_PMU_PERFMON))
358 return 0;
359
360 nvgpu_log_fn(g, " ");
361
362 memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_perfmon_start));
363 rpc.group_id = PMU_DOMAIN_GROUP_PSTATE;
364 rpc.state_id = pmu->perfmon_state_id[PMU_DOMAIN_GROUP_PSTATE];
365 rpc.flags = PMU_PERFMON_FLAG_ENABLE_INCREASE |
366 PMU_PERFMON_FLAG_ENABLE_DECREASE |
367 PMU_PERFMON_FLAG_CLEAR_PREV;
368
369 rpc.counter[0].upper_threshold = 3000;
370 rpc.counter[0].lower_threshold = 1000;
371
372 nvgpu_pmu_dbg(g, "RPC post NV_PMU_RPC_ID_PERFMON_START\n");
373 PMU_RPC_EXECUTE(status, pmu, PERFMON_T18X, START, &rpc, 0);
374 if (status)
375 nvgpu_err(g, "Failed to execute RPC, status=0x%x", status);
376
377 return status;
378}
379
380int nvgpu_pmu_perfmon_stop_sampling_rpc(struct nvgpu_pmu *pmu)
381{
382 struct gk20a *g = gk20a_from_pmu(pmu);
383 struct nv_pmu_rpc_struct_perfmon_stop rpc;
384 int status = 0;
385
386 if (!nvgpu_is_enabled(g, NVGPU_PMU_PERFMON))
387 return 0;
388
389 nvgpu_log_fn(g, " ");
390
391 memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_perfmon_stop));
392 /* PERFMON Stop */
393 nvgpu_pmu_dbg(g, "RPC post NV_PMU_RPC_ID_PERFMON_STOP\n");
394 PMU_RPC_EXECUTE(status, pmu, PERFMON_T18X, STOP, &rpc, 0);
395 if (status)
396 nvgpu_err(g, "Failed to execute RPC, status=0x%x", status);
397
398 return status;
399}
400
401int nvgpu_pmu_perfmon_get_samples_rpc(struct nvgpu_pmu *pmu)
402{
403 struct gk20a *g = gk20a_from_pmu(pmu);
404 struct nv_pmu_rpc_struct_perfmon_query rpc;
405 int status = 0;
406
407 if (!nvgpu_is_enabled(g, NVGPU_PMU_PERFMON))
408 return 0;
409
410 nvgpu_log_fn(g, " ");
411 pmu->perfmon_query = 0;
412 memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_perfmon_query));
413 /* PERFMON QUERY */
414 nvgpu_pmu_dbg(g, "RPC post NV_PMU_RPC_ID_PERFMON_QUERY\n");
415 PMU_RPC_EXECUTE(status, pmu, PERFMON_T18X, QUERY, &rpc, 0);
416 if (status)
417 nvgpu_err(g, "Failed to execute RPC, status=0x%x", status);
418
419 pmu_wait_message_cond(pmu, gk20a_get_gr_idle_timeout(g),
420 &pmu->perfmon_query, 1);
421
422 return status;
423}