summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index c83da8b4..643adca5 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -486,6 +486,95 @@ static int gk20a_channel_cycle_stats(struct channel_gk20a *ch,
486 return -EINVAL; 486 return -EINVAL;
487 } 487 }
488} 488}
489
490
491static int gk20a_flush_cycle_stats_snapshot(struct channel_gk20a *ch)
492{
493 int ret;
494
495 mutex_lock(&ch->cs_client_mutex);
496 if (ch->cs_client)
497 ret = gr_gk20a_css_flush(ch->g, ch->cs_client);
498 else
499 ret = -EBADF;
500 mutex_unlock(&ch->cs_client_mutex);
501
502 return ret;
503}
504
505static int gk20a_attach_cycle_stats_snapshot(struct channel_gk20a *ch,
506 u32 dmabuf_fd,
507 u32 perfmon_id_count,
508 u32 *perfmon_id_start)
509{
510 int ret;
511
512 mutex_lock(&ch->cs_client_mutex);
513 if (ch->cs_client) {
514 ret = -EEXIST;
515 } else {
516 ret = gr_gk20a_css_attach(ch->g,
517 dmabuf_fd,
518 perfmon_id_count,
519 perfmon_id_start,
520 &ch->cs_client);
521 }
522 mutex_unlock(&ch->cs_client_mutex);
523
524 return ret;
525}
526
527static int gk20a_free_cycle_stats_snapshot(struct channel_gk20a *ch)
528{
529 int ret;
530
531 mutex_lock(&ch->cs_client_mutex);
532 if (ch->cs_client) {
533 ret = gr_gk20a_css_detach(ch->g, ch->cs_client);
534 ch->cs_client = NULL;
535 } else {
536 ret = 0;
537 }
538 mutex_unlock(&ch->cs_client_mutex);
539
540 return ret;
541}
542
543static int gk20a_channel_cycle_stats_snapshot(struct channel_gk20a *ch,
544 struct nvgpu_cycle_stats_snapshot_args *args)
545{
546 int ret;
547
548 if (!args->dmabuf_fd)
549 return -EINVAL;
550
551 /* handle the command (most frequent cases first) */
552 switch (args->cmd) {
553 case NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT_CMD_FLUSH:
554 ret = gk20a_flush_cycle_stats_snapshot(ch);
555 args->extra = 0;
556 break;
557
558 case NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT_CMD_ATTACH:
559 ret = gk20a_attach_cycle_stats_snapshot(ch,
560 args->dmabuf_fd,
561 args->extra,
562 &args->extra);
563 break;
564
565 case NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT_CMD_DETACH:
566 ret = gk20a_free_cycle_stats_snapshot(ch);
567 args->extra = 0;
568 break;
569
570 default:
571 pr_err("cyclestats: unknown command %u\n", args->cmd);
572 ret = -EINVAL;
573 break;
574 }
575
576 return ret;
577}
489#endif 578#endif
490 579
491static int gk20a_init_error_notifier(struct channel_gk20a *ch, 580static int gk20a_init_error_notifier(struct channel_gk20a *ch,
@@ -602,6 +691,7 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
602 691
603#if defined(CONFIG_GK20A_CYCLE_STATS) 692#if defined(CONFIG_GK20A_CYCLE_STATS)
604 gk20a_free_cycle_stats_buffer(ch); 693 gk20a_free_cycle_stats_buffer(ch);
694 gk20a_free_cycle_stats_snapshot(ch);
605#endif 695#endif
606 696
607 channel_gk20a_free_priv_cmdbuf(ch); 697 channel_gk20a_free_priv_cmdbuf(ch);
@@ -1639,6 +1729,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
1639 INIT_LIST_HEAD(&c->jobs); 1729 INIT_LIST_HEAD(&c->jobs);
1640#if defined(CONFIG_GK20A_CYCLE_STATS) 1730#if defined(CONFIG_GK20A_CYCLE_STATS)
1641 mutex_init(&c->cyclestate.cyclestate_buffer_mutex); 1731 mutex_init(&c->cyclestate.cyclestate_buffer_mutex);
1732 mutex_init(&c->cs_client_mutex);
1642#endif 1733#endif
1643 INIT_LIST_HEAD(&c->dbg_s_list); 1734 INIT_LIST_HEAD(&c->dbg_s_list);
1644 mutex_init(&c->dbg_s_lock); 1735 mutex_init(&c->dbg_s_lock);
@@ -2335,6 +2426,20 @@ long gk20a_channel_ioctl(struct file *filp,
2335 err = gk20a_channel_events_ctrl(ch, 2426 err = gk20a_channel_events_ctrl(ch,
2336 (struct nvgpu_channel_events_ctrl_args *)buf); 2427 (struct nvgpu_channel_events_ctrl_args *)buf);
2337 break; 2428 break;
2429#ifdef CONFIG_GK20A_CYCLE_STATS
2430 case NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT:
2431 err = gk20a_busy(dev);
2432 if (err) {
2433 dev_err(&dev->dev,
2434 "%s: failed to host gk20a for ioctl cmd: 0x%x",
2435 __func__, cmd);
2436 break;
2437 }
2438 err = gk20a_channel_cycle_stats_snapshot(ch,
2439 (struct nvgpu_cycle_stats_snapshot_args *)buf);
2440 gk20a_idle(dev);
2441 break;
2442#endif
2338 default: 2443 default:
2339 dev_dbg(&dev->dev, "unrecognized ioctl cmd: 0x%x", cmd); 2444 dev_dbg(&dev->dev, "unrecognized ioctl cmd: 0x%x", cmd);
2340 err = -ENOTTY; 2445 err = -ENOTTY;