summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h8
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c231
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.h30
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c39
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.h4
5 files changed, 289 insertions, 23 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index aeed5838..05ed9270 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -217,6 +217,14 @@ struct gpu_ops {
217 struct pmu_sequence *seq); 217 struct pmu_sequence *seq);
218 void (*set_pmu_cmdline_args_secure_mode)(struct pmu_gk20a *pmu, 218 void (*set_pmu_cmdline_args_secure_mode)(struct pmu_gk20a *pmu,
219 u32 val); 219 u32 val);
220 u32 (*get_perfmon_cntr_sz)(struct pmu_gk20a *pmu);
221 void * (*get_perfmon_cntr_ptr)(struct pmu_gk20a *pmu);
222 void (*set_perfmon_cntr_ut)(struct pmu_gk20a *pmu, u16 ut);
223 void (*set_perfmon_cntr_lt)(struct pmu_gk20a *pmu, u16 lt);
224 void (*set_perfmon_cntr_valid)(struct pmu_gk20a *pmu, u8 val);
225 void (*set_perfmon_cntr_index)(struct pmu_gk20a *pmu, u8 val);
226 void (*set_perfmon_cntr_group_id)(struct pmu_gk20a *pmu,
227 u8 gid);
220 } pmu_ver; 228 } pmu_ver;
221 struct { 229 struct {
222 int (*get_netlist_name)(int index, char *name); 230 int (*get_netlist_name)(int index, char *name);
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index c23d83cf..b147c66f 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -44,6 +44,76 @@ static void ap_callback_init_and_enable_ctrl(
44 struct gk20a *g, struct pmu_msg *msg, 44 struct gk20a *g, struct pmu_msg *msg,
45 void *param, u32 seq_desc, u32 status); 45 void *param, u32 seq_desc, u32 status);
46 46
47static u32 pmu_perfmon_cntr_sz_v0(struct pmu_gk20a *pmu)
48{
49 return sizeof(struct pmu_perfmon_counter_v0);
50}
51
52static u32 pmu_perfmon_cntr_sz_v2(struct pmu_gk20a *pmu)
53{
54 return sizeof(struct pmu_perfmon_counter_v2);
55}
56
57static void *get_perfmon_cntr_ptr_v2(struct pmu_gk20a *pmu)
58{
59 return (void *)(&pmu->perfmon_counter_v2);
60}
61
62static void *get_perfmon_cntr_ptr_v0(struct pmu_gk20a *pmu)
63{
64 return (void *)(&pmu->perfmon_counter_v0);
65}
66
67static void set_perfmon_cntr_ut_v2(struct pmu_gk20a *pmu, u16 ut)
68{
69 pmu->perfmon_counter_v2.upper_threshold = ut;
70}
71
72static void set_perfmon_cntr_ut_v0(struct pmu_gk20a *pmu, u16 ut)
73{
74 pmu->perfmon_counter_v0.upper_threshold = ut;
75}
76
77static void set_perfmon_cntr_lt_v2(struct pmu_gk20a *pmu, u16 lt)
78{
79 pmu->perfmon_counter_v2.lower_threshold = lt;
80}
81
82static void set_perfmon_cntr_lt_v0(struct pmu_gk20a *pmu, u16 lt)
83{
84 pmu->perfmon_counter_v0.lower_threshold = lt;
85}
86
87static void set_perfmon_cntr_valid_v2(struct pmu_gk20a *pmu, u8 valid)
88{
89 pmu->perfmon_counter_v2.valid = valid;
90}
91
92static void set_perfmon_cntr_valid_v0(struct pmu_gk20a *pmu, u8 valid)
93{
94 pmu->perfmon_counter_v0.valid = valid;
95}
96
97static void set_perfmon_cntr_index_v2(struct pmu_gk20a *pmu, u8 index)
98{
99 pmu->perfmon_counter_v2.index = index;
100}
101
102static void set_perfmon_cntr_index_v0(struct pmu_gk20a *pmu, u8 index)
103{
104 pmu->perfmon_counter_v0.index = index;
105}
106
107static void set_perfmon_cntr_group_id_v2(struct pmu_gk20a *pmu, u8 gid)
108{
109 pmu->perfmon_counter_v2.group_id = gid;
110}
111
112static void set_perfmon_cntr_group_id_v0(struct pmu_gk20a *pmu, u8 gid)
113{
114 pmu->perfmon_counter_v0.group_id = gid;
115}
116
47static u32 pmu_cmdline_size_v0(struct pmu_gk20a *pmu) 117static u32 pmu_cmdline_size_v0(struct pmu_gk20a *pmu)
48{ 118{
49 return sizeof(struct pmu_cmdline_args_v0); 119 return sizeof(struct pmu_cmdline_args_v0);
@@ -54,6 +124,37 @@ static u32 pmu_cmdline_size_v1(struct pmu_gk20a *pmu)
54 return sizeof(struct pmu_cmdline_args_v1); 124 return sizeof(struct pmu_cmdline_args_v1);
55} 125}
56 126
127static u32 pmu_cmdline_size_v2(struct pmu_gk20a *pmu)
128{
129 return sizeof(struct pmu_cmdline_args_v2);
130}
131
132static void set_pmu_cmdline_args_cpufreq_v2(struct pmu_gk20a *pmu, u32 freq)
133{
134 pmu->args_v2.cpu_freq_hz = freq;
135}
136static void set_pmu_cmdline_args_secure_mode_v2(struct pmu_gk20a *pmu, u32 val)
137{
138 pmu->args_v2.secure_mode = val;
139}
140
141static void set_pmu_cmdline_args_falctracesize_v2(
142 struct pmu_gk20a *pmu, u32 size)
143{
144 pmu->args_v2.falc_trace_size = size;
145}
146
147static void set_pmu_cmdline_args_falctracedmabase_v2(struct pmu_gk20a *pmu)
148{
149 pmu->args_v2.falc_trace_dma_base = ((u32)pmu->trace_buf.pmu_va)/0x100;
150}
151
152static void set_pmu_cmdline_args_falctracedmaidx_v2(
153 struct pmu_gk20a *pmu, u32 idx)
154{
155 pmu->args_v2.falc_trace_dma_idx = idx;
156}
157
57static void set_pmu_cmdline_args_cpufreq_v1(struct pmu_gk20a *pmu, u32 freq) 158static void set_pmu_cmdline_args_cpufreq_v1(struct pmu_gk20a *pmu, u32 freq)
58{ 159{
59 pmu->args_v1.cpu_freq_hz = freq; 160 pmu->args_v1.cpu_freq_hz = freq;
@@ -69,6 +170,7 @@ static void set_pmu_cmdline_args_falctracesize_v1(
69 pmu->args_v1.falc_trace_size = size; 170 pmu->args_v1.falc_trace_size = size;
70} 171}
71 172
173
72void printtrace(struct pmu_gk20a *pmu) 174void printtrace(struct pmu_gk20a *pmu)
73{ 175{
74 u32 i = 0, j = 0; 176 u32 i = 0, j = 0;
@@ -108,6 +210,11 @@ static void set_pmu_cmdline_args_cpufreq_v0(struct pmu_gk20a *pmu, u32 freq)
108 pmu->args_v0.cpu_freq_hz = freq; 210 pmu->args_v0.cpu_freq_hz = freq;
109} 211}
110 212
213static void *get_pmu_cmdline_args_ptr_v2(struct pmu_gk20a *pmu)
214{
215 return (void *)(&pmu->args_v2);
216}
217
111static void *get_pmu_cmdline_args_ptr_v1(struct pmu_gk20a *pmu) 218static void *get_pmu_cmdline_args_ptr_v1(struct pmu_gk20a *pmu)
112{ 219{
113 return (void *)(&pmu->args_v1); 220 return (void *)(&pmu->args_v1);
@@ -525,6 +632,7 @@ static void *get_pmu_sequence_out_alloc_ptr_v0(struct pmu_sequence *seq)
525int gk20a_init_pmu(struct pmu_gk20a *pmu) 632int gk20a_init_pmu(struct pmu_gk20a *pmu)
526{ 633{
527 struct gk20a *g = gk20a_from_pmu(pmu); 634 struct gk20a *g = gk20a_from_pmu(pmu);
635 struct pmu_v *pv = &g->ops.pmu_ver;
528 636
529 mutex_init(&pmu->elpg_mutex); 637 mutex_init(&pmu->elpg_mutex);
530 mutex_init(&pmu->isr_mutex); 638 mutex_init(&pmu->isr_mutex);
@@ -532,17 +640,107 @@ int gk20a_init_pmu(struct pmu_gk20a *pmu)
532 mutex_init(&pmu->pmu_copy_lock); 640 mutex_init(&pmu->pmu_copy_lock);
533 mutex_init(&pmu->pmu_seq_lock); 641 mutex_init(&pmu->pmu_seq_lock);
534 642
535 pmu->perfmon_counter.index = 3; /* GR & CE2 */
536 pmu->perfmon_counter.group_id = PMU_DOMAIN_GROUP_PSTATE;
537
538 pmu->remove_support = gk20a_remove_pmu_support; 643 pmu->remove_support = gk20a_remove_pmu_support;
539 644
540 switch (pmu->desc->app_version) { 645 switch (pmu->desc->app_version) {
646 case APP_VERSION_GM20B_2:
647 g->ops.pmu_ver.get_perfmon_cntr_ptr = get_perfmon_cntr_ptr_v2;
648 g->ops.pmu_ver.set_perfmon_cntr_ut = set_perfmon_cntr_ut_v2;
649 g->ops.pmu_ver.set_perfmon_cntr_lt = set_perfmon_cntr_lt_v2;
650 g->ops.pmu_ver.set_perfmon_cntr_valid =
651 set_perfmon_cntr_valid_v2;
652 g->ops.pmu_ver.set_perfmon_cntr_index =
653 set_perfmon_cntr_index_v2;
654 g->ops.pmu_ver.set_perfmon_cntr_group_id =
655 set_perfmon_cntr_group_id_v2;
656 g->ops.pmu_ver.get_perfmon_cntr_sz = pmu_perfmon_cntr_sz_v2;
657 g->ops.pmu_ver.cmd_id_zbc_table_update = 16;
658 g->ops.pmu_ver.get_pmu_cmdline_args_size =
659 pmu_cmdline_size_v2;
660 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq =
661 set_pmu_cmdline_args_cpufreq_v2;
662 g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode =
663 set_pmu_cmdline_args_secure_mode_v2;
664 g->ops.pmu_ver.set_pmu_cmdline_args_trace_size =
665 set_pmu_cmdline_args_falctracesize_v2;
666 g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base =
667 set_pmu_cmdline_args_falctracedmabase_v2;
668 g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx =
669 set_pmu_cmdline_args_falctracedmaidx_v2;
670 g->ops.pmu_ver.get_pmu_cmdline_args_ptr =
671 get_pmu_cmdline_args_ptr_v2;
672 g->ops.pmu_ver.get_pmu_allocation_struct_size =
673 get_pmu_allocation_size_v1;
674 g->ops.pmu_ver.set_pmu_allocation_ptr =
675 set_pmu_allocation_ptr_v1;
676 g->ops.pmu_ver.pmu_allocation_set_dmem_size =
677 pmu_allocation_set_dmem_size_v1;
678 g->ops.pmu_ver.pmu_allocation_get_dmem_size =
679 pmu_allocation_get_dmem_size_v1;
680 g->ops.pmu_ver.pmu_allocation_get_dmem_offset =
681 pmu_allocation_get_dmem_offset_v1;
682 g->ops.pmu_ver.pmu_allocation_get_dmem_offset_addr =
683 pmu_allocation_get_dmem_offset_addr_v1;
684 g->ops.pmu_ver.pmu_allocation_set_dmem_offset =
685 pmu_allocation_set_dmem_offset_v1;
686 g->ops.pmu_ver.get_pmu_init_msg_pmu_queue_params =
687 get_pmu_init_msg_pmu_queue_params_v1;
688 g->ops.pmu_ver.get_pmu_msg_pmu_init_msg_ptr =
689 get_pmu_msg_pmu_init_msg_ptr_v1;
690 g->ops.pmu_ver.get_pmu_init_msg_pmu_sw_mg_off =
691 get_pmu_init_msg_pmu_sw_mg_off_v1;
692 g->ops.pmu_ver.get_pmu_init_msg_pmu_sw_mg_size =
693 get_pmu_init_msg_pmu_sw_mg_size_v1;
694 g->ops.pmu_ver.get_pmu_perfmon_cmd_start_size =
695 get_pmu_perfmon_cmd_start_size_v1;
696 g->ops.pmu_ver.get_perfmon_cmd_start_offsetofvar =
697 get_perfmon_cmd_start_offsetofvar_v1;
698 g->ops.pmu_ver.perfmon_start_set_cmd_type =
699 perfmon_start_set_cmd_type_v1;
700 g->ops.pmu_ver.perfmon_start_set_group_id =
701 perfmon_start_set_group_id_v1;
702 g->ops.pmu_ver.perfmon_start_set_state_id =
703 perfmon_start_set_state_id_v1;
704 g->ops.pmu_ver.perfmon_start_set_flags =
705 perfmon_start_set_flags_v1;
706 g->ops.pmu_ver.perfmon_start_get_flags =
707 perfmon_start_get_flags_v1;
708 g->ops.pmu_ver.get_pmu_perfmon_cmd_init_size =
709 get_pmu_perfmon_cmd_init_size_v1;
710 g->ops.pmu_ver.get_perfmon_cmd_init_offsetofvar =
711 get_perfmon_cmd_init_offsetofvar_v1;
712 g->ops.pmu_ver.perfmon_cmd_init_set_sample_buffer =
713 perfmon_cmd_init_set_sample_buffer_v1;
714 g->ops.pmu_ver.perfmon_cmd_init_set_dec_cnt =
715 perfmon_cmd_init_set_dec_cnt_v1;
716 g->ops.pmu_ver.perfmon_cmd_init_set_base_cnt_id =
717 perfmon_cmd_init_set_base_cnt_id_v1;
718 g->ops.pmu_ver.perfmon_cmd_init_set_samp_period_us =
719 perfmon_cmd_init_set_samp_period_us_v1;
720 g->ops.pmu_ver.perfmon_cmd_init_set_num_cnt =
721 perfmon_cmd_init_set_num_cnt_v1;
722 g->ops.pmu_ver.perfmon_cmd_init_set_mov_avg =
723 perfmon_cmd_init_set_mov_avg_v1;
724 g->ops.pmu_ver.get_pmu_seq_in_a_ptr =
725 get_pmu_sequence_in_alloc_ptr_v1;
726 g->ops.pmu_ver.get_pmu_seq_out_a_ptr =
727 get_pmu_sequence_out_alloc_ptr_v1;
728 break;
541 case APP_VERSION_GM20B_1: 729 case APP_VERSION_GM20B_1:
542 case APP_VERSION_GM20B: 730 case APP_VERSION_GM20B:
543 case APP_VERSION_1: 731 case APP_VERSION_1:
544 case APP_VERSION_2: 732 case APP_VERSION_2:
545 g->ops.pmu_ver.cmd_id_zbc_table_update = 16; 733 g->ops.pmu_ver.cmd_id_zbc_table_update = 16;
734 g->ops.pmu_ver.get_perfmon_cntr_ptr = get_perfmon_cntr_ptr_v0;
735 g->ops.pmu_ver.set_perfmon_cntr_ut = set_perfmon_cntr_ut_v0;
736 g->ops.pmu_ver.set_perfmon_cntr_lt = set_perfmon_cntr_lt_v0;
737 g->ops.pmu_ver.set_perfmon_cntr_valid =
738 set_perfmon_cntr_valid_v0;
739 g->ops.pmu_ver.set_perfmon_cntr_index =
740 set_perfmon_cntr_index_v0;
741 g->ops.pmu_ver.set_perfmon_cntr_group_id =
742 set_perfmon_cntr_group_id_v0;
743 g->ops.pmu_ver.get_perfmon_cntr_sz = pmu_perfmon_cntr_sz_v0;
546 g->ops.pmu_ver.get_pmu_cmdline_args_size = 744 g->ops.pmu_ver.get_pmu_cmdline_args_size =
547 pmu_cmdline_size_v1; 745 pmu_cmdline_size_v1;
548 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq = 746 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq =
@@ -616,6 +814,16 @@ int gk20a_init_pmu(struct pmu_gk20a *pmu)
616 break; 814 break;
617 case APP_VERSION_0: 815 case APP_VERSION_0:
618 g->ops.pmu_ver.cmd_id_zbc_table_update = 14; 816 g->ops.pmu_ver.cmd_id_zbc_table_update = 14;
817 g->ops.pmu_ver.get_perfmon_cntr_ptr = get_perfmon_cntr_ptr_v0;
818 g->ops.pmu_ver.set_perfmon_cntr_ut = set_perfmon_cntr_ut_v0;
819 g->ops.pmu_ver.set_perfmon_cntr_lt = set_perfmon_cntr_lt_v0;
820 g->ops.pmu_ver.set_perfmon_cntr_valid =
821 set_perfmon_cntr_valid_v0;
822 g->ops.pmu_ver.set_perfmon_cntr_index =
823 set_perfmon_cntr_index_v0;
824 g->ops.pmu_ver.set_perfmon_cntr_group_id =
825 set_perfmon_cntr_group_id_v0;
826 g->ops.pmu_ver.get_perfmon_cntr_sz = pmu_perfmon_cntr_sz_v0;
619 g->ops.pmu_ver.get_pmu_cmdline_args_size = 827 g->ops.pmu_ver.get_pmu_cmdline_args_size =
620 pmu_cmdline_size_v0; 828 pmu_cmdline_size_v0;
621 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq = 829 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq =
@@ -688,6 +896,9 @@ int gk20a_init_pmu(struct pmu_gk20a *pmu)
688 return -EINVAL; 896 return -EINVAL;
689 break; 897 break;
690 } 898 }
899 pv->set_perfmon_cntr_index(pmu, 3); /* GR & CE2 */
900 pv->set_perfmon_cntr_group_id(pmu, PMU_DOMAIN_GROUP_PSTATE);
901
691 return 0; 902 return 0;
692} 903}
693 904
@@ -2336,8 +2547,8 @@ static int pmu_init_perfmon(struct pmu_gk20a *pmu)
2336 pv->perfmon_cmd_init_set_mov_avg(&cmd.cmd.perfmon, 17); 2547 pv->perfmon_cmd_init_set_mov_avg(&cmd.cmd.perfmon, 17);
2337 2548
2338 memset(&payload, 0, sizeof(struct pmu_payload)); 2549 memset(&payload, 0, sizeof(struct pmu_payload));
2339 payload.in.buf = &pmu->perfmon_counter; 2550 payload.in.buf = pv->get_perfmon_cntr_ptr(pmu);
2340 payload.in.size = sizeof(struct pmu_perfmon_counter); 2551 payload.in.size = pv->get_perfmon_cntr_sz(pmu);
2341 payload.in.offset = pv->get_perfmon_cmd_init_offsetofvar(COUNTER_ALLOC); 2552 payload.in.offset = pv->get_perfmon_cmd_init_offsetofvar(COUNTER_ALLOC);
2342 2553
2343 gk20a_dbg_pmu("cmd post PMU_PERFMON_CMD_ID_INIT"); 2554 gk20a_dbg_pmu("cmd post PMU_PERFMON_CMD_ID_INIT");
@@ -2631,13 +2842,13 @@ static int pmu_perfmon_start_sampling(struct pmu_gk20a *pmu)
2631 memset(&payload, 0, sizeof(struct pmu_payload)); 2842 memset(&payload, 0, sizeof(struct pmu_payload));
2632 2843
2633 /* TBD: PMU_PERFMON_PCT_TO_INC * 100 */ 2844 /* TBD: PMU_PERFMON_PCT_TO_INC * 100 */
2634 pmu->perfmon_counter.upper_threshold = 3000; /* 30% */ 2845 pv->set_perfmon_cntr_ut(pmu, 3000); /* 30% */
2635 /* TBD: PMU_PERFMON_PCT_TO_DEC * 100 */ 2846 /* TBD: PMU_PERFMON_PCT_TO_DEC * 100 */
2636 pmu->perfmon_counter.lower_threshold = 1000; /* 10% */ 2847 pv->set_perfmon_cntr_lt(pmu, 1000); /* 10% */
2637 pmu->perfmon_counter.valid = true; 2848 pv->set_perfmon_cntr_valid(pmu, true);
2638 2849
2639 payload.in.buf = &pmu->perfmon_counter; 2850 payload.in.buf = pv->get_perfmon_cntr_ptr(pmu);
2640 payload.in.size = sizeof(pmu->perfmon_counter); 2851 payload.in.size = pv->get_perfmon_cntr_sz(pmu);
2641 payload.in.offset = 2852 payload.in.offset =
2642 pv->get_perfmon_cmd_start_offsetofvar(COUNTER_ALLOC); 2853 pv->get_perfmon_cmd_start_offsetofvar(COUNTER_ALLOC);
2643 2854
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
index 828058b7..292aabb0 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
@@ -51,6 +51,7 @@
51/* Mapping between AP_CTRLs and Idle counters */ 51/* Mapping between AP_CTRLs and Idle counters */
52#define PMU_AP_IDLE_MASK_GRAPHICS (PMU_AP_IDLE_MASK_HIST_IDX_1) 52#define PMU_AP_IDLE_MASK_GRAPHICS (PMU_AP_IDLE_MASK_HIST_IDX_1)
53 53
54#define APP_VERSION_GM20B_2 18694072
54#define APP_VERSION_GM20B_1 18547257 55#define APP_VERSION_GM20B_1 18547257
55#define APP_VERSION_GM20B 17615280 56#define APP_VERSION_GM20B 17615280
56#define APP_VERSION_2 18542378 57#define APP_VERSION_2 18542378
@@ -339,6 +340,17 @@ struct pmu_cmdline_args_v1 {
339 struct pmu_mem_v1 gc6_ctx; /* dmem offset of gc6 context */ 340 struct pmu_mem_v1 gc6_ctx; /* dmem offset of gc6 context */
340}; 341};
341 342
343struct pmu_cmdline_args_v2 {
344 u32 cpu_freq_hz; /* Frequency of the clock driving PMU */
345 u32 falc_trace_size; /* falctrace buffer size (bytes) */
346 u32 falc_trace_dma_base; /* 256-byte block address */
347 u32 falc_trace_dma_idx; /* dmaIdx for DMA operations */
348 u8 secure_mode;
349 u8 raise_priv_sec; /*Raise priv level required for desired
350 registers*/
351 struct pmu_mem_v1 gc6_ctx; /* dmem offset of gc6 context */
352};
353
342#define GK20A_PMU_TRACE_BUFSIZE 0x4000 /* 4K */ 354#define GK20A_PMU_TRACE_BUFSIZE 0x4000 /* 4K */
343#define GK20A_PMU_DMEM_BLKSIZE2 8 355#define GK20A_PMU_DMEM_BLKSIZE2 8
344 356
@@ -641,13 +653,23 @@ struct pmu_pg_cmd {
641#define PMU_PERFMON_PCT_TO_INC 58 653#define PMU_PERFMON_PCT_TO_INC 58
642#define PMU_PERFMON_PCT_TO_DEC 23 654#define PMU_PERFMON_PCT_TO_DEC 23
643 655
644struct pmu_perfmon_counter { 656struct pmu_perfmon_counter_v0 {
657 u8 index;
658 u8 flags;
659 u8 group_id;
660 u8 valid;
661 u16 upper_threshold; /* units of 0.01% */
662 u16 lower_threshold; /* units of 0.01% */
663};
664
665struct pmu_perfmon_counter_v2 {
645 u8 index; 666 u8 index;
646 u8 flags; 667 u8 flags;
647 u8 group_id; 668 u8 group_id;
648 u8 valid; 669 u8 valid;
649 u16 upper_threshold; /* units of 0.01% */ 670 u16 upper_threshold; /* units of 0.01% */
650 u16 lower_threshold; /* units of 0.01% */ 671 u16 lower_threshold; /* units of 0.01% */
672 u32 scale;
651}; 673};
652 674
653#define PMU_PERFMON_FLAG_ENABLE_INCREASE (0x00000001) 675#define PMU_PERFMON_FLAG_ENABLE_INCREASE (0x00000001)
@@ -1044,7 +1066,10 @@ struct pmu_gk20a {
1044 struct mutex elpg_mutex; /* protect elpg enable/disable */ 1066 struct mutex elpg_mutex; /* protect elpg enable/disable */
1045 int elpg_refcnt; /* disable -1, enable +1, <=0 elpg disabled, > 0 elpg enabled */ 1067 int elpg_refcnt; /* disable -1, enable +1, <=0 elpg disabled, > 0 elpg enabled */
1046 1068
1047 struct pmu_perfmon_counter perfmon_counter; 1069 union {
1070 struct pmu_perfmon_counter_v2 perfmon_counter_v2;
1071 struct pmu_perfmon_counter_v0 perfmon_counter_v0;
1072 };
1048 u32 perfmon_state_id[PMU_DOMAIN_GROUP_NUM]; 1073 u32 perfmon_state_id[PMU_DOMAIN_GROUP_NUM];
1049 1074
1050 bool initialized; 1075 bool initialized;
@@ -1063,6 +1088,7 @@ struct pmu_gk20a {
1063 union { 1088 union {
1064 struct pmu_cmdline_args_v0 args_v0; 1089 struct pmu_cmdline_args_v0 args_v0;
1065 struct pmu_cmdline_args_v1 args_v1; 1090 struct pmu_cmdline_args_v1 args_v1;
1091 struct pmu_cmdline_args_v2 args_v2;
1066 }; 1092 };
1067 unsigned long perfmon_events_cnt; 1093 unsigned long perfmon_events_cnt;
1068 bool perfmon_sampling_enabled; 1094 bool perfmon_sampling_enabled;
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index 77f0653e..e5a3e2cd 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -80,7 +80,7 @@ static void free_blob_res(struct gk20a *g)
80 80
81int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 81int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
82{ 82{
83 const struct firmware *pmu_fw; 83 const struct firmware *pmu_fw, *pmu_desc;
84 struct pmu_gk20a *pmu = &g->pmu; 84 struct pmu_gk20a *pmu = &g->pmu;
85 struct lsf_ucode_desc *lsf_desc; 85 struct lsf_ucode_desc *lsf_desc;
86 int err; 86 int err;
@@ -93,18 +93,28 @@ int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
93 } 93 }
94 gm20b_dbg_pmu("Loaded PMU ucode in for blob preparation"); 94 gm20b_dbg_pmu("Loaded PMU ucode in for blob preparation");
95 95
96 pmu->desc = (struct pmu_ucode_desc *)pmu_fw->data; 96 gm20b_dbg_pmu("requesting PMU ucode desc in GM20B\n");
97 pmu->ucode_image = (u32 *)((u8 *)pmu->desc + 97 pmu_desc = gk20a_request_firmware(g, GM20B_PMU_UCODE_DESC);
98 pmu->desc->descriptor_size); 98 if (!pmu_desc) {
99 gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode desc!!");
100 gm20b_dbg_pmu("requesting PMU ucode in GM20B failed\n");
101 err = -ENOENT;
102 goto release_img_fw;
103 }
104 pmu->desc = (struct pmu_ucode_desc *)pmu_desc->data;
105 pmu->ucode_image = (u32 *)pmu_fw->data;
106
99 err = gk20a_init_pmu(pmu); 107 err = gk20a_init_pmu(pmu);
100 if (err) { 108 if (err) {
101 gm20b_dbg_pmu("failed to set function pointers\n"); 109 gm20b_dbg_pmu("failed to set function pointers\n");
102 return err; 110 goto release_desc;
103 } 111 }
104 112
105 lsf_desc = kzalloc(sizeof(struct lsf_ucode_desc), GFP_KERNEL); 113 lsf_desc = kzalloc(sizeof(struct lsf_ucode_desc), GFP_KERNEL);
106 if (!lsf_desc) 114 if (!lsf_desc) {
107 return -ENOMEM; 115 err = -ENOMEM;
116 goto release_desc;
117 }
108 lsf_desc->falcon_id = LSF_FALCON_ID_PMU; 118 lsf_desc->falcon_id = LSF_FALCON_ID_PMU;
109 119
110 p_img->desc = pmu->desc; 120 p_img->desc = pmu->desc;
@@ -115,6 +125,11 @@ int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
115 p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc; 125 p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
116 gm20b_dbg_pmu("requesting PMU ucode in GM20B exit\n"); 126 gm20b_dbg_pmu("requesting PMU ucode in GM20B exit\n");
117 return 0; 127 return 0;
128release_desc:
129 release_firmware(pmu_desc);
130release_img_fw:
131 release_firmware(pmu_fw);
132 return err;
118} 133}
119 134
120int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) 135int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
@@ -378,10 +393,8 @@ int pmu_populate_loader_cfg(struct gk20a *g,
378 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, 393 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu,
379 clk_get_rate(platform->clk[1])); 394 clk_get_rate(platform->clk[1]));
380 g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode(pmu, 1); 395 g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode(pmu, 1);
381 pmu_copy_to_dmem(pmu, addr_args,
382 (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)),
383 g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0);
384 *p_bl_gen_desc_size = sizeof(p_bl_gen_desc->loader_cfg); 396 *p_bl_gen_desc_size = sizeof(p_bl_gen_desc->loader_cfg);
397 g->acr.pmu_args = addr_args;
385 return 0; 398 return 0;
386} 399}
387 400
@@ -1026,7 +1039,10 @@ int gm20b_init_pmu_setup_hw1(struct gk20a *g, struct flcn_bl_dmem_desc *desc,
1026 int err; 1039 int err;
1027 1040
1028 gk20a_dbg_fn(""); 1041 gk20a_dbg_fn("");
1042 mutex_lock(&pmu->isr_enable_lock);
1029 pmu_reset(pmu); 1043 pmu_reset(pmu);
1044 pmu->isr_enabled = true;
1045 mutex_unlock(&pmu->isr_enable_lock);
1030 1046
1031 /* setup apertures - virtual */ 1047 /* setup apertures - virtual */
1032 gk20a_writel(g, pwr_fbif_transcfg_r(GK20A_PMU_DMAIDX_UCODE), 1048 gk20a_writel(g, pwr_fbif_transcfg_r(GK20A_PMU_DMAIDX_UCODE),
@@ -1045,6 +1061,9 @@ int gm20b_init_pmu_setup_hw1(struct gk20a *g, struct flcn_bl_dmem_desc *desc,
1045 pwr_fbif_transcfg_mem_type_physical_f() | 1061 pwr_fbif_transcfg_mem_type_physical_f() |
1046 pwr_fbif_transcfg_target_noncoherent_sysmem_f()); 1062 pwr_fbif_transcfg_target_noncoherent_sysmem_f());
1047 1063
1064 pmu_copy_to_dmem(pmu, g->acr.pmu_args,
1065 (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)),
1066 g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0);
1048 err = bl_bootstrap(pmu, desc, bl_sz); 1067 err = bl_bootstrap(pmu, desc, bl_sz);
1049 if (err) 1068 if (err)
1050 return err; 1069 return err;
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h
index 073dc135..b186e489 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h
@@ -24,7 +24,8 @@
24#define MAX_SUPPORTED_LSFM 2 /*PMU, FECS, GPCCS*/ 24#define MAX_SUPPORTED_LSFM 2 /*PMU, FECS, GPCCS*/
25#define LSF_UCODE_DATA_ALIGNMENT 4096 25#define LSF_UCODE_DATA_ALIGNMENT 4096
26 26
27#define GM20B_PMU_UCODE_IMAGE "gpmu_ucode.bin" 27#define GM20B_PMU_UCODE_IMAGE "gpmu_ucode_image.bin"
28#define GM20B_PMU_UCODE_DESC "gpmu_ucode_desc.bin"
28#define GM20B_HSBIN_PMU_UCODE_IMAGE "acr_ucode.bin" 29#define GM20B_HSBIN_PMU_UCODE_IMAGE "acr_ucode.bin"
29#define GM20B_HSBIN_PMU_BL_UCODE_IMAGE "pmu_bl.bin" 30#define GM20B_HSBIN_PMU_BL_UCODE_IMAGE "pmu_bl.bin"
30 31
@@ -363,6 +364,7 @@ struct acr_gm20b {
363 struct hsflcn_bl_desc *pmu_hsbl_desc; 364 struct hsflcn_bl_desc *pmu_hsbl_desc;
364 struct bin_hdr *hsbin_hdr; 365 struct bin_hdr *hsbin_hdr;
365 struct acr_fw_header *fw_hdr; 366 struct acr_fw_header *fw_hdr;
367 u32 pmu_args;
366}; 368};
367 369
368void gm20b_init_secure_pmu(struct gpu_ops *gops); 370void gm20b_init_secure_pmu(struct gpu_ops *gops);