aboutsummaryrefslogtreecommitdiffstats
path: root/include/gk20a/pmu_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/gk20a/pmu_gk20a.c')
-rw-r--r--include/gk20a/pmu_gk20a.c879
1 files changed, 0 insertions, 879 deletions
diff --git a/include/gk20a/pmu_gk20a.c b/include/gk20a/pmu_gk20a.c
deleted file mode 100644
index 63a32f0..0000000
--- a/include/gk20a/pmu_gk20a.c
+++ /dev/null
@@ -1,879 +0,0 @@
1/*
2 * GK20A PMU (aka. gPMU outside gk20a context)
3 *
4 * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <nvgpu/nvgpu_common.h>
26#include <nvgpu/timers.h>
27#include <nvgpu/kmem.h>
28#include <nvgpu/dma.h>
29#include <nvgpu/log.h>
30#include <nvgpu/bug.h>
31#include <nvgpu/firmware.h>
32#include <nvgpu/falcon.h>
33#include <nvgpu/mm.h>
34#include <nvgpu/io.h>
35#include <nvgpu/clk_arb.h>
36#include <nvgpu/utils.h>
37#include <nvgpu/unit.h>
38
39#include "gk20a.h"
40#include "gr_gk20a.h"
41#include "pmu_gk20a.h"
42
43#include <nvgpu/hw/gk20a/hw_mc_gk20a.h>
44#include <nvgpu/hw/gk20a/hw_pwr_gk20a.h>
45#include <nvgpu/hw/gk20a/hw_top_gk20a.h>
46
47#define gk20a_dbg_pmu(g, fmt, arg...) \
48 nvgpu_log(g, gpu_dbg_pmu, fmt, ##arg)
49
50bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos)
51{
52 u32 i = 0, j = strlen(strings);
53
54 for (; i < j; i++) {
55 if (strings[i] == '%') {
56 if (strings[i + 1] == 'x' || strings[i + 1] == 'X') {
57 *hex_pos = i;
58 return true;
59 }
60 }
61 }
62 *hex_pos = -1;
63 return false;
64}
65
66static void print_pmu_trace(struct nvgpu_pmu *pmu)
67{
68 struct gk20a *g = pmu->g;
69 u32 i = 0, j = 0, k, l, m, count;
70 char part_str[40], buf[0x40];
71 void *tracebuffer;
72 char *trace;
73 u32 *trace1;
74
75 /* allocate system memory to copy pmu trace buffer */
76 tracebuffer = nvgpu_kzalloc(g, GK20A_PMU_TRACE_BUFSIZE);
77 if (tracebuffer == NULL) {
78 return;
79 }
80
81 /* read pmu traces into system memory buffer */
82 nvgpu_mem_rd_n(g, &pmu->trace_buf, 0, tracebuffer,
83 GK20A_PMU_TRACE_BUFSIZE);
84
85 trace = (char *)tracebuffer;
86 trace1 = (u32 *)tracebuffer;
87
88 nvgpu_err(g, "dump PMU trace buffer");
89 for (i = 0; i < GK20A_PMU_TRACE_BUFSIZE; i += 0x40) {
90 for (j = 0; j < 0x40; j++) {
91 if (trace1[(i / 4) + j]) {
92 break;
93 }
94 }
95 if (j == 0x40) {
96 break;
97 }
98 count = scnprintf(buf, 0x40, "Index %x: ", trace1[(i / 4)]);
99 l = 0;
100 m = 0;
101 while (nvgpu_find_hex_in_string((trace+i+20+m), g, &k)) {
102 if (k >= 40) {
103 break;
104 }
105 strncpy(part_str, (trace+i+20+m), k);
106 part_str[k] = '\0';
107 count += scnprintf((buf + count), 0x40, "%s0x%x",
108 part_str, trace1[(i / 4) + 1 + l]);
109 l++;
110 m += k + 2;
111 }
112
113 scnprintf((buf + count), 0x40, "%s", (trace+i+20+m));
114 nvgpu_err(g, "%s", buf);
115 }
116
117 nvgpu_kfree(g, tracebuffer);
118}
119
120u32 gk20a_pmu_get_irqdest(struct gk20a *g)
121{
122 u32 intr_dest;
123
124 /* dest 0=falcon, 1=host; level 0=irq0, 1=irq1 */
125 intr_dest = pwr_falcon_irqdest_host_gptmr_f(0) |
126 pwr_falcon_irqdest_host_wdtmr_f(1) |
127 pwr_falcon_irqdest_host_mthd_f(0) |
128 pwr_falcon_irqdest_host_ctxsw_f(0) |
129 pwr_falcon_irqdest_host_halt_f(1) |
130 pwr_falcon_irqdest_host_exterr_f(0) |
131 pwr_falcon_irqdest_host_swgen0_f(1) |
132 pwr_falcon_irqdest_host_swgen1_f(0) |
133 pwr_falcon_irqdest_host_ext_f(0xff) |
134 pwr_falcon_irqdest_target_gptmr_f(1) |
135 pwr_falcon_irqdest_target_wdtmr_f(0) |
136 pwr_falcon_irqdest_target_mthd_f(0) |
137 pwr_falcon_irqdest_target_ctxsw_f(0) |
138 pwr_falcon_irqdest_target_halt_f(0) |
139 pwr_falcon_irqdest_target_exterr_f(0) |
140 pwr_falcon_irqdest_target_swgen0_f(0) |
141 pwr_falcon_irqdest_target_swgen1_f(0) |
142 pwr_falcon_irqdest_target_ext_f(0xff);
143
144 return intr_dest;
145}
146
147void gk20a_pmu_enable_irq(struct nvgpu_pmu *pmu, bool enable)
148{
149 struct gk20a *g = gk20a_from_pmu(pmu);
150 u32 intr_mask;
151 u32 intr_dest;
152
153 nvgpu_log_fn(g, " ");
154
155 g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, true,
156 mc_intr_mask_0_pmu_enabled_f());
157 g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, false,
158 mc_intr_mask_1_pmu_enabled_f());
159
160 nvgpu_flcn_set_irq(pmu->flcn, false, 0x0, 0x0);
161
162 if (enable) {
163 intr_dest = g->ops.pmu.get_irqdest(g);
164 /* 0=disable, 1=enable */
165 intr_mask = pwr_falcon_irqmset_gptmr_f(1) |
166 pwr_falcon_irqmset_wdtmr_f(1) |
167 pwr_falcon_irqmset_mthd_f(0) |
168 pwr_falcon_irqmset_ctxsw_f(0) |
169 pwr_falcon_irqmset_halt_f(1) |
170 pwr_falcon_irqmset_exterr_f(1) |
171 pwr_falcon_irqmset_swgen0_f(1) |
172 pwr_falcon_irqmset_swgen1_f(1);
173
174 nvgpu_flcn_set_irq(pmu->flcn, true, intr_mask, intr_dest);
175
176 g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_ENABLE, true,
177 mc_intr_mask_0_pmu_enabled_f());
178 }
179
180 nvgpu_log_fn(g, "done");
181}
182
183
184
185int pmu_bootstrap(struct nvgpu_pmu *pmu)
186{
187 struct gk20a *g = gk20a_from_pmu(pmu);
188 struct mm_gk20a *mm = &g->mm;
189 struct pmu_ucode_desc *desc = pmu->desc;
190 u64 addr_code, addr_data, addr_load;
191 u32 i, blocks, addr_args;
192
193 nvgpu_log_fn(g, " ");
194
195 gk20a_writel(g, pwr_falcon_itfen_r(),
196 gk20a_readl(g, pwr_falcon_itfen_r()) |
197 pwr_falcon_itfen_ctxen_enable_f());
198 gk20a_writel(g, pwr_pmu_new_instblk_r(),
199 pwr_pmu_new_instblk_ptr_f(
200 nvgpu_inst_block_addr(g, &mm->pmu.inst_block) >> 12) |
201 pwr_pmu_new_instblk_valid_f(1) |
202 pwr_pmu_new_instblk_target_sys_coh_f());
203
204 /* TBD: load all other surfaces */
205 g->ops.pmu_ver.set_pmu_cmdline_args_trace_size(
206 pmu, GK20A_PMU_TRACE_BUFSIZE);
207 g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base(pmu);
208 g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx(
209 pmu, GK20A_PMU_DMAIDX_VIRT);
210
211 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu,
212 g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_PWRCLK));
213
214 addr_args = (pwr_falcon_hwcfg_dmem_size_v(
215 gk20a_readl(g, pwr_falcon_hwcfg_r()))
216 << GK20A_PMU_DMEM_BLKSIZE2) -
217 g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu);
218
219 nvgpu_flcn_copy_to_dmem(pmu->flcn, addr_args,
220 (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)),
221 g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0);
222