diff options
author | Kevin Huang <kevinh@nvidia.com> | 2014-05-09 14:41:26 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:11:06 -0400 |
commit | 1d9eba07c58b0a30f479b233371c939180a0e419 (patch) | |
tree | 1b4081a723834d8b295a147e85f6d7b7b205a88c /drivers/gpu/nvgpu | |
parent | 5cd313e20221c93008f1d56ac223d6e08966505e (diff) |
gpu: nvgpu: add HAL for regops
Bug 1500195
Change-Id: I5545d1a95a58e7daa5a74cc20f3fc6828774fc42
Signed-off-by: Kevin Huang <kevinh@nvidia.com>
Reviewed-on: http://git-master/r/488507
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 18 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hal_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/regops_gk20a.c | 146 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/regops_gk20a.h | 11 |
5 files changed, 147 insertions, 32 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index de234972..fc97fcb9 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -298,6 +298,24 @@ struct gpu_ops { | |||
298 | int (*suspend_clk_support)(struct gk20a *g); | 298 | int (*suspend_clk_support)(struct gk20a *g); |
299 | } clk; | 299 | } clk; |
300 | bool privsecurity; | 300 | bool privsecurity; |
301 | struct { | ||
302 | const struct regop_offset_range* ( | ||
303 | *get_global_whitelist_ranges)(void); | ||
304 | int (*get_global_whitelist_ranges_count)(void); | ||
305 | const struct regop_offset_range* ( | ||
306 | *get_context_whitelist_ranges)(void); | ||
307 | int (*get_context_whitelist_ranges_count)(void); | ||
308 | const u32* (*get_runcontrol_whitelist)(void); | ||
309 | int (*get_runcontrol_whitelist_count)(void); | ||
310 | const struct regop_offset_range* ( | ||
311 | *get_runcontrol_whitelist_ranges)(void); | ||
312 | int (*get_runcontrol_whitelist_ranges_count)(void); | ||
313 | const u32* (*get_qctl_whitelist)(void); | ||
314 | int (*get_qctl_whitelist_count)(void); | ||
315 | const struct regop_offset_range* ( | ||
316 | *get_qctl_whitelist_ranges)(void); | ||
317 | int (*get_qctl_whitelist_ranges_count)(void); | ||
318 | } regops; | ||
301 | }; | 319 | }; |
302 | 320 | ||
303 | struct gk20a { | 321 | struct gk20a { |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index c1789427..cbad1292 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -5080,7 +5080,7 @@ static inline bool is_valid_cyclestats_bar0_offset_gk20a(struct gk20a *g, | |||
5080 | 5080 | ||
5081 | /* whitelist check */ | 5081 | /* whitelist check */ |
5082 | valid = valid && | 5082 | valid = valid && |
5083 | is_bar0_global_offset_whitelisted_gk20a(offset); | 5083 | is_bar0_global_offset_whitelisted_gk20a(g, offset); |
5084 | /* resource size check in case there was a problem | 5084 | /* resource size check in case there was a problem |
5085 | * with allocating the assumed size of bar0 */ | 5085 | * with allocating the assumed size of bar0 */ |
5086 | valid = valid && | 5086 | valid = valid && |
diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c index 1b8157f1..218491ea 100644 --- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "mm_gk20a.h" | 25 | #include "mm_gk20a.h" |
26 | #include "pmu_gk20a.h" | 26 | #include "pmu_gk20a.h" |
27 | #include "clk_gk20a.h" | 27 | #include "clk_gk20a.h" |
28 | #include "regops_gk20a.h" | ||
28 | 29 | ||
29 | struct gpu_ops gk20a_ops = { | 30 | struct gpu_ops gk20a_ops = { |
30 | .clock_gating = { | 31 | .clock_gating = { |
@@ -53,6 +54,7 @@ int gk20a_init_hal(struct gpu_ops *gops) | |||
53 | gk20a_init_mm(gops); | 54 | gk20a_init_mm(gops); |
54 | gk20a_init_pmu_ops(gops); | 55 | gk20a_init_pmu_ops(gops); |
55 | gk20a_init_clk_ops(gops); | 56 | gk20a_init_clk_ops(gops); |
57 | gk20a_init_regops(gops); | ||
56 | gops->name = "gk20a"; | 58 | gops->name = "gk20a"; |
57 | 59 | ||
58 | return 0; | 60 | return 0; |
diff --git a/drivers/gpu/nvgpu/gk20a/regops_gk20a.c b/drivers/gpu/nvgpu/gk20a/regops_gk20a.c index 4a115fb1..87a95afe 100644 --- a/drivers/gpu/nvgpu/gk20a/regops_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/regops_gk20a.c | |||
@@ -29,11 +29,6 @@ | |||
29 | 29 | ||
30 | 30 | ||
31 | 31 | ||
32 | struct regop_offset_range { | ||
33 | u32 base:24; | ||
34 | u32 count:8; | ||
35 | }; | ||
36 | |||
37 | static int regop_bsearch_range_cmp(const void *pkey, const void *pelem) | 32 | static int regop_bsearch_range_cmp(const void *pkey, const void *pelem) |
38 | { | 33 | { |
39 | u32 key = *(u32 *)pkey; | 34 | u32 key = *(u32 *)pkey; |
@@ -551,31 +546,32 @@ static int validate_reg_op_info(struct dbg_session_gk20a *dbg_s, | |||
551 | static bool check_whitelists(struct dbg_session_gk20a *dbg_s, | 546 | static bool check_whitelists(struct dbg_session_gk20a *dbg_s, |
552 | struct nvhost_dbg_gpu_reg_op *op, u32 offset) | 547 | struct nvhost_dbg_gpu_reg_op *op, u32 offset) |
553 | { | 548 | { |
549 | struct gk20a *g = dbg_s->g; | ||
554 | bool valid = false; | 550 | bool valid = false; |
555 | 551 | ||
556 | if (op->type == REGOP(TYPE_GLOBAL)) { | 552 | if (op->type == REGOP(TYPE_GLOBAL)) { |
557 | /* search global list */ | 553 | /* search global list */ |
558 | valid = !!bsearch(&offset, | 554 | valid = !!bsearch(&offset, |
559 | gk20a_global_whitelist_ranges, | 555 | g->ops.regops.get_global_whitelist_ranges(), |
560 | gk20a_global_whitelist_ranges_count, | 556 | g->ops.regops.get_global_whitelist_ranges_count(), |
561 | sizeof(*gk20a_global_whitelist_ranges), | 557 | sizeof(*g->ops.regops.get_global_whitelist_ranges()), |
562 | regop_bsearch_range_cmp); | 558 | regop_bsearch_range_cmp); |
563 | 559 | ||
564 | /* if debug session and channel is bound search context list */ | 560 | /* if debug session and channel is bound search context list */ |
565 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { | 561 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { |
566 | /* binary search context list */ | 562 | /* binary search context list */ |
567 | valid = !!bsearch(&offset, | 563 | valid = !!bsearch(&offset, |
568 | gk20a_context_whitelist_ranges, | 564 | g->ops.regops.get_context_whitelist_ranges(), |
569 | gk20a_context_whitelist_ranges_count, | 565 | g->ops.regops.get_context_whitelist_ranges_count(), |
570 | sizeof(*gk20a_context_whitelist_ranges), | 566 | sizeof(*g->ops.regops.get_context_whitelist_ranges()), |
571 | regop_bsearch_range_cmp); | 567 | regop_bsearch_range_cmp); |
572 | } | 568 | } |
573 | 569 | ||
574 | /* if debug session and channel is bound search runcontrol list */ | 570 | /* if debug session and channel is bound search runcontrol list */ |
575 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { | 571 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { |
576 | valid = linear_search(offset, | 572 | valid = linear_search(offset, |
577 | gk20a_runcontrol_whitelist, | 573 | g->ops.regops.get_runcontrol_whitelist(), |
578 | gk20a_runcontrol_whitelist_count); | 574 | g->ops.regops.get_runcontrol_whitelist_count()); |
579 | } | 575 | } |
580 | } else if (op->type == REGOP(TYPE_GR_CTX)) { | 576 | } else if (op->type == REGOP(TYPE_GR_CTX)) { |
581 | /* it's a context-relative op */ | 577 | /* it's a context-relative op */ |
@@ -587,22 +583,22 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s, | |||
587 | 583 | ||
588 | /* binary search context list */ | 584 | /* binary search context list */ |
589 | valid = !!bsearch(&offset, | 585 | valid = !!bsearch(&offset, |
590 | gk20a_context_whitelist_ranges, | 586 | g->ops.regops.get_context_whitelist_ranges(), |
591 | gk20a_context_whitelist_ranges_count, | 587 | g->ops.regops.get_context_whitelist_ranges_count(), |
592 | sizeof(*gk20a_context_whitelist_ranges), | 588 | sizeof(*g->ops.regops.get_context_whitelist_ranges()), |
593 | regop_bsearch_range_cmp); | 589 | regop_bsearch_range_cmp); |
594 | 590 | ||
595 | /* if debug session and channel is bound search runcontrol list */ | 591 | /* if debug session and channel is bound search runcontrol list */ |
596 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { | 592 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { |
597 | valid = linear_search(offset, | 593 | valid = linear_search(offset, |
598 | gk20a_runcontrol_whitelist, | 594 | g->ops.regops.get_runcontrol_whitelist(), |
599 | gk20a_runcontrol_whitelist_count); | 595 | g->ops.regops.get_runcontrol_whitelist_count()); |
600 | } | 596 | } |
601 | 597 | ||
602 | } else if (op->type == REGOP(TYPE_GR_CTX_QUAD)) { | 598 | } else if (op->type == REGOP(TYPE_GR_CTX_QUAD)) { |
603 | valid = linear_search(offset, | 599 | valid = linear_search(offset, |
604 | gk20a_qctl_whitelist, | 600 | g->ops.regops.get_qctl_whitelist(), |
605 | gk20a_qctl_whitelist_count); | 601 | g->ops.regops.get_qctl_whitelist_count()); |
606 | } | 602 | } |
607 | 603 | ||
608 | return valid; | 604 | return valid; |
@@ -692,13 +688,105 @@ static bool validate_reg_ops(struct dbg_session_gk20a *dbg_s, | |||
692 | } | 688 | } |
693 | 689 | ||
694 | /* exported for tools like cyclestats, etc */ | 690 | /* exported for tools like cyclestats, etc */ |
695 | bool is_bar0_global_offset_whitelisted_gk20a(u32 offset) | 691 | bool is_bar0_global_offset_whitelisted_gk20a(struct gk20a *g, u32 offset) |
696 | { | 692 | { |
697 | |||
698 | bool valid = !!bsearch(&offset, | 693 | bool valid = !!bsearch(&offset, |
699 | gk20a_global_whitelist_ranges, | 694 | g->ops.regops.get_global_whitelist_ranges(), |
700 | gk20a_global_whitelist_ranges_count, | 695 | g->ops.regops.get_global_whitelist_ranges_count(), |
701 | sizeof(*gk20a_global_whitelist_ranges), | 696 | sizeof(*g->ops.regops.get_global_whitelist_ranges()), |
702 | regop_bsearch_range_cmp); | 697 | regop_bsearch_range_cmp); |
703 | return valid; | 698 | return valid; |
704 | } | 699 | } |
700 | |||
701 | const struct regop_offset_range *gk20a_get_global_whitelist_ranges(void) | ||
702 | { | ||
703 | return gk20a_global_whitelist_ranges; | ||
704 | } | ||
705 | |||
706 | int gk20a_get_global_whitelist_ranges_count(void) | ||
707 | { | ||
708 | return gk20a_global_whitelist_ranges_count; | ||
709 | } | ||
710 | |||
711 | const struct regop_offset_range *gk20a_get_context_whitelist_ranges(void) | ||
712 | { | ||
713 | return gk20a_context_whitelist_ranges; | ||
714 | } | ||
715 | |||
716 | int gk20a_get_context_whitelist_ranges_count(void) | ||
717 | { | ||
718 | return gk20a_context_whitelist_ranges_count; | ||
719 | } | ||
720 | |||
721 | const u32 *gk20a_get_runcontrol_whitelist(void) | ||
722 | { | ||
723 | return gk20a_runcontrol_whitelist; | ||
724 | } | ||
725 | |||
726 | int gk20a_get_runcontrol_whitelist_count(void) | ||
727 | { | ||
728 | return gk20a_runcontrol_whitelist_count; | ||
729 | } | ||
730 | |||
731 | const struct regop_offset_range *gk20a_get_runcontrol_whitelist_ranges(void) | ||
732 | { | ||
733 | return gk20a_runcontrol_whitelist_ranges; | ||
734 | } | ||
735 | |||
736 | int gk20a_get_runcontrol_whitelist_ranges_count(void) | ||
737 | { | ||
738 | return gk20a_runcontrol_whitelist_ranges_count; | ||
739 | } | ||
740 | |||
741 | const u32 *gk20a_get_qctl_whitelist(void) | ||
742 | { | ||
743 | return gk20a_qctl_whitelist; | ||
744 | } | ||
745 | |||
746 | int gk20a_get_qctl_whitelist_count(void) | ||
747 | { | ||
748 | return gk20a_qctl_whitelist_count; | ||
749 | } | ||
750 | |||
751 | const struct regop_offset_range *gk20a_get_qctl_whitelist_ranges(void) | ||
752 | { | ||
753 | return gk20a_qctl_whitelist_ranges; | ||
754 | } | ||
755 | |||
756 | int gk20a_get_qctl_whitelist_ranges_count(void) | ||
757 | { | ||
758 | return gk20a_qctl_whitelist_ranges_count; | ||
759 | } | ||
760 | |||
761 | void gk20a_init_regops(struct gpu_ops *gops) | ||
762 | { | ||
763 | gops->regops.get_global_whitelist_ranges = | ||
764 | gk20a_get_global_whitelist_ranges; | ||
765 | gops->regops.get_global_whitelist_ranges_count = | ||
766 | gk20a_get_global_whitelist_ranges_count; | ||
767 | |||
768 | gops->regops.get_context_whitelist_ranges = | ||
769 | gk20a_get_context_whitelist_ranges; | ||
770 | gops->regops.get_context_whitelist_ranges_count = | ||
771 | gk20a_get_context_whitelist_ranges_count; | ||
772 | |||
773 | gops->regops.get_runcontrol_whitelist = | ||
774 | gk20a_get_runcontrol_whitelist; | ||
775 | gops->regops.get_runcontrol_whitelist_count = | ||
776 | gk20a_get_runcontrol_whitelist_count; | ||
777 | |||
778 | gops->regops.get_runcontrol_whitelist_ranges = | ||
779 | gk20a_get_runcontrol_whitelist_ranges; | ||
780 | gops->regops.get_runcontrol_whitelist_ranges_count = | ||
781 | gk20a_get_runcontrol_whitelist_ranges_count; | ||
782 | |||
783 | gops->regops.get_qctl_whitelist = | ||
784 | gk20a_get_qctl_whitelist; | ||
785 | gops->regops.get_qctl_whitelist_count = | ||
786 | gk20a_get_qctl_whitelist_count; | ||
787 | |||
788 | gops->regops.get_qctl_whitelist_ranges = | ||
789 | gk20a_get_qctl_whitelist_ranges; | ||
790 | gops->regops.get_qctl_whitelist_ranges_count = | ||
791 | gk20a_get_qctl_whitelist_ranges_count; | ||
792 | } | ||
diff --git a/drivers/gpu/nvgpu/gk20a/regops_gk20a.h b/drivers/gpu/nvgpu/gk20a/regops_gk20a.h index 23b4865b..808e8bbe 100644 --- a/drivers/gpu/nvgpu/gk20a/regops_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/regops_gk20a.h | |||
@@ -19,6 +19,13 @@ | |||
19 | #ifndef __REGOPS_GK20A_H_ | 19 | #ifndef __REGOPS_GK20A_H_ |
20 | #define __REGOPS_GK20A_H_ | 20 | #define __REGOPS_GK20A_H_ |
21 | 21 | ||
22 | #include <linux/nvhost_dbg_gpu_ioctl.h> | ||
23 | |||
24 | struct regop_offset_range { | ||
25 | u32 base:24; | ||
26 | u32 count:8; | ||
27 | }; | ||
28 | |||
22 | int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, | 29 | int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, |
23 | struct nvhost_dbg_gpu_reg_op *ops, | 30 | struct nvhost_dbg_gpu_reg_op *ops, |
24 | u64 num_ops); | 31 | u64 num_ops); |
@@ -26,7 +33,6 @@ int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, | |||
26 | /* turn seriously unwieldy names -> something shorter */ | 33 | /* turn seriously unwieldy names -> something shorter */ |
27 | #define REGOP(x) NVHOST_DBG_GPU_REG_OP_##x | 34 | #define REGOP(x) NVHOST_DBG_GPU_REG_OP_##x |
28 | 35 | ||
29 | |||
30 | static inline bool reg_op_is_gr_ctx(u8 type) | 36 | static inline bool reg_op_is_gr_ctx(u8 type) |
31 | { | 37 | { |
32 | return type == REGOP(TYPE_GR_CTX) || | 38 | return type == REGOP(TYPE_GR_CTX) || |
@@ -42,6 +48,7 @@ static inline bool reg_op_is_read(u8 op) | |||
42 | op == REGOP(READ_64) ; | 48 | op == REGOP(READ_64) ; |
43 | } | 49 | } |
44 | 50 | ||
45 | bool is_bar0_global_offset_whitelisted_gk20a(u32 offset); | 51 | bool is_bar0_global_offset_whitelisted_gk20a(struct gk20a *g, u32 offset); |
46 | 52 | ||
53 | void gk20a_init_regops(struct gpu_ops *gops); | ||
47 | #endif /* __REGOPS_GK20A_H_ */ | 54 | #endif /* __REGOPS_GK20A_H_ */ |