aboutsummaryrefslogtreecommitdiffstats
path: root/include/pstate
diff options
context:
space:
mode:
Diffstat (limited to 'include/pstate')
-rw-r--r--include/pstate/pstate.c488
-rw-r--r--include/pstate/pstate.h74
2 files changed, 0 insertions, 562 deletions
diff --git a/include/pstate/pstate.c b/include/pstate/pstate.c
deleted file mode 100644
index c1f696a..0000000
--- a/include/pstate/pstate.c
+++ /dev/null
@@ -1,488 +0,0 @@
1/*
2 * general p state infrastructure
3 *
4 * Copyright (c) 2016-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/bios.h>
26#include <nvgpu/gk20a.h>
27
28#include "clk/clk.h"
29#include "pmu_perf/pmu_perf.h"
30#include "pmgr/pmgr.h"
31#include "pstate/pstate.h"
32#include "therm/thrm.h"
33
34static int pstate_sw_setup(struct gk20a *g);
35
36void gk20a_deinit_pstate_support(struct gk20a *g)
37{
38 if (g->ops.clk.mclk_deinit) {
39 g->ops.clk.mclk_deinit(g);
40 }
41
42 nvgpu_mutex_destroy(&g->perf_pmu.pstatesobjs.pstate_mutex);
43}
44
45/*sw setup for pstate components*/
46int gk20a_init_pstate_support(struct gk20a *g)
47{
48 int err;
49
50 nvgpu_log_fn(g, " ");
51
52 err = volt_rail_sw_setup(g);
53 if (err) {
54 return err;
55 }
56
57 err = volt_dev_sw_setup(g);
58 if (err) {
59 return err;
60 }
61
62 err = volt_policy_sw_setup(g);
63 if (err) {
64 return err;
65 }
66
67 err = clk_vin_sw_setup(g);
68 if (err) {
69 return err;
70 }
71
72 err = clk_fll_sw_setup(g);
73 if (err) {
74 return err;
75 }
76
77 err = therm_domain_sw_setup(g);
78 if (err) {
79 return err;
80 }
81
82 err = vfe_var_sw_setup(g);
83 if (err) {
84 return err;
85 }
86
87 err = vfe_equ_sw_setup(g);
88 if (err) {
89 return err;
90 }
91
92 err = clk_domain_sw_setup(g);
93 if (err) {
94 return err;
95 }
96
97 err = clk_vf_point_sw_setup(g);
98 if (err) {
99 return err;
100 }
101
102 err = clk_prog_sw_setup(g);
103 if (err) {
104 return err;
105 }
106
107 err = pstate_sw_setup(g);
108 if (err) {
109 return err;
110 }
111
112 if(g->ops.clk.support_pmgr_domain) {
113 err = pmgr_domain_sw_setup(g);
114 if (err) {
115 return err;
116 }
117 }
118
119 if (g->ops.clk.support_clk_freq_controller) {
120 err = clk_freq_controller_sw_setup(g);
121 if (err) {
122 return err;
123 }
124 }
125
126 if(g->ops.clk.support_lpwr_pg) {
127 err = nvgpu_lpwr_pg_setup(g);
128 if (err) {
129 return err;
130 }
131 }
132
133 return err;
134}
135
136/*sw setup for pstate components*/
137int gk20a_init_pstate_pmu_support(struct gk20a *g)
138{
139 u32 err;
140
141 nvgpu_log_fn(g, " ");
142
143 if (g->ops.clk.mclk_init) {
144 err = g->ops.clk.mclk_init(g);
145 if (err) {
146 nvgpu_err(g, "failed to set mclk");
147 /* Indicate error and continue */
148 }
149 }
150
151 err = volt_rail_pmu_setup(g);
152 if (err) {
153 return err;
154 }
155
156 err = volt_dev_pmu_setup(g);
157 if (err) {
158 return err;
159 }
160
161 err = volt_policy_pmu_setup(g);
162 if (err) {
163 return err;
164 }
165
166 err = g->ops.pmu_ver.volt.volt_send_load_cmd_to_pmu(g);
167 if (err) {
168 nvgpu_err(g,
169 "Failed to send VOLT LOAD CMD to PMU: status = 0x%08x.",
170 err);
171 return err;
172 }
173
174 err = therm_domain_pmu_setup(g);
175 if (err) {
176 return err;
177 }
178
179 err = vfe_var_pmu_setup(g);
180 if (err) {
181 return err;
182 }
183
184 err = vfe_equ_pmu_setup(g);
185 if (err) {
186 return err;
187 }
188
189 err = clk_domain_pmu_setup(g);
190 if (err) {
191 return err;
192 }
193
194 err = clk_prog_pmu_setup(g);
195 if (err) {
196 return err;
197 }
198
199 err = clk_vin_pmu_setup(g);
200 if (err) {
201 return err;
202 }
203
204 err = clk_fll_pmu_setup(g);
205 if (err) {
206 return err;
207 }
208
209 err = clk_vf_point_pmu_setup(g);
210 if (err) {
211 return err;
212 }
213
214 if (g->ops.clk.support_clk_freq_controller) {
215 err = clk_freq_controller_pmu_setup(g);
216 if (err) {
217 return err;
218 }
219 }
220 err = clk_pmu_vin_load(g);
221 if (err) {
222 return err;
223 }
224
225 err = g->ops.clk.perf_pmu_vfe_load(g);
226 if (err) {
227 return err;
228 }
229
230 if (g->ops.clk.support_pmgr_domain) {
231 err = pmgr_domain_pmu_setup(g);
232 }
233
234 return err;
235}
236
237static int pstate_construct_super(struct gk20a *g, struct boardobj **ppboardobj,
238 u16 size, void *args)
239{
240 struct pstate *ptmppstate = (struct pstate *)args;
241 struct pstate *pstate;
242 int err;
243
244 err = boardobj_construct_super(g, ppboardobj, size, args);
245 if (err) {
246 return err;
247 }
248
249 pstate = (struct pstate *)*ppboardobj;
250
251 pstate->num = ptmppstate->num;
252 pstate->clklist = ptmppstate->clklist;
253 pstate->lpwr_entry_idx = ptmppstate->lpwr_entry_idx;
254
255 return 0;
256}
257
258static int pstate_construct_3x(struct gk20a *g, struct boardobj **ppboardobj,
259 u16 size, void *args)
260{
261 struct boardobj *ptmpobj = (struct boardobj *)args;
262
263 ptmpobj->type_mask |= BIT(CTRL_PERF_PSTATE_TYPE_3X);
264 return pstate_construct_super(g, ppboardobj, size, args);
265}
266
267static struct pstate *pstate_construct(struct gk20a *g, void *args)
268{
269 struct pstate *pstate = NULL;
270 struct pstate *tmp = (struct pstate *)args;
271
272 if ((tmp->super.type != CTRL_PERF_PSTATE_TYPE_3X) ||
273 (pstate_construct_3x(g, (struct boardobj **)&pstate,
274 sizeof(struct pstate), args))) {
275 nvgpu_err(g,
276 "error constructing pstate num=%u", tmp->num);
277 }
278
279 return pstate;
280}
281
282static int pstate_insert(struct gk20a *g, struct pstate *pstate, int index)
283{
284 struct pstates *pstates = &(g->perf_pmu.pstatesobjs);
285 int err;
286
287 err = boardobjgrp_objinsert(&pstates->super.super,
288 (struct boardobj *)pstate, index);
289 if (err) {
290 nvgpu_err(g,
291 "error adding pstate boardobj %d", index);
292 return err;
293 }
294
295 pstates->num_levels++;
296
297 return err;
298}
299
300static int parse_pstate_entry_5x(struct gk20a *g,
301 struct vbios_pstate_header_5x *hdr,
302 struct vbios_pstate_entry_5x *entry,
303 struct pstate *pstate)
304{
305 u8 *p = (u8 *)entry;
306 u32 clkidx;
307
308 p += hdr->base_entry_size;
309
310 memset(pstate, 0, sizeof(struct pstate));
311 pstate->super.type = CTRL_PERF_PSTATE_TYPE_3X;
312 pstate->num = 0x0F - entry->pstate_level;
313 pstate->clklist.num_info = hdr->clock_entry_count;
314 pstate->lpwr_entry_idx = entry->lpwr_entry_idx;
315
316 nvgpu_log_info(g, "pstate P%u", pstate->num);
317
318 for (clkidx = 0; clkidx < hdr->clock_entry_count; clkidx++) {
319 struct clk_set_info *pclksetinfo;
320 struct vbios_pstate_entry_clock_5x *clk_entry;
321 struct clk_domain *clk_domain;
322
323 clk_domain = (struct clk_domain *)BOARDOBJGRP_OBJ_GET_BY_IDX(
324 &g->clk_pmu.clk_domainobjs.super.super, clkidx);
325
326 pclksetinfo = &pstate->clklist.clksetinfo[clkidx];
327 clk_entry = (struct vbios_pstate_entry_clock_5x *)p;
328
329 pclksetinfo->clkwhich = clk_domain->domain;
330 pclksetinfo->nominal_mhz =
331 BIOS_GET_FIELD(clk_entry->param0,
332 VBIOS_PSTATE_5X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ);
333 pclksetinfo->min_mhz =
334 BIOS_GET_FIELD(clk_entry->param1,
335 VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MIN_FREQ_MHZ);
336 pclksetinfo->max_mhz =
337 BIOS_GET_FIELD(clk_entry->param1,
338 VBIOS_PSTATE_5X_CLOCK_PROG_PARAM1_MAX_FREQ_MHZ);
339
340 nvgpu_log_info(g,
341 "clk_domain=%u nominal_mhz=%u min_mhz=%u max_mhz=%u",
342 pclksetinfo->clkwhich, pclksetinfo->nominal_mhz,
343 pclksetinfo->min_mhz, pclksetinfo->max_mhz);
344
345 p += hdr->clock_entry_size;
346 }
347
348 return 0;
349}
350
351static int parse_pstate_table_5x(struct gk20a *g,
352 struct vbios_pstate_header_5x *hdr)
353{
354 struct pstate _pstate, *pstate;
355 struct vbios_pstate_entry_5x *entry;
356 u32 entry_size;
357 u8 i;
358 u8 *p = (u8 *)hdr;
359 int err = 0;
360
361 if ((hdr->header_size != VBIOS_PSTATE_HEADER_5X_SIZE_10) ||
362 (hdr->base_entry_count == 0) ||
363 ((hdr->base_entry_size != VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_2) &&
364 (hdr->base_entry_size != VBIOS_PSTATE_BASE_ENTRY_5X_SIZE_3)) ||
365 (hdr->clock_entry_size != VBIOS_PSTATE_CLOCK_ENTRY_5X_SIZE_6) ||
366 (hdr->clock_entry_count > CLK_SET_INFO_MAX_SIZE)) {
367 return -EINVAL;
368 }
369
370 p += hdr->header_size;
371
372 entry_size = hdr->base_entry_size +
373 hdr->clock_entry_count * hdr->clock_entry_size;
374
375 for (i = 0; i < hdr->base_entry_count; i++, p += entry_size) {
376 entry = (struct vbios_pstate_entry_5x *)p;
377
378 if (entry->pstate_level == VBIOS_PERFLEVEL_SKIP_ENTRY) {
379 continue;
380 }
381
382 err = parse_pstate_entry_5x(g, hdr, entry, &_pstate);
383 if (err) {
384 goto done;
385 }
386
387 pstate = pstate_construct(g, &_pstate);
388 if (!pstate) {
389 goto done;
390 }
391
392 err = pstate_insert(g, pstate, i);
393 if (err) {
394 goto done;
395 }
396 }
397
398done:
399 return err;
400}
401
402static int pstate_sw_setup(struct gk20a *g)
403{
404 struct vbios_pstate_header_5x *hdr = NULL;
405 int err = 0;
406
407 nvgpu_log_fn(g, " ");
408
409 nvgpu_cond_init(&g->perf_pmu.pstatesobjs.pstate_notifier_wq);
410
411 err = nvgpu_mutex_init(&g->perf_pmu.pstatesobjs.pstate_mutex);
412 if (err) {
413 return err;
414 }
415
416 err = boardobjgrpconstruct_e32(g, &g->perf_pmu.pstatesobjs.super);
417 if (err) {
418 nvgpu_err(g,
419 "error creating boardobjgrp for pstates, err=%d",
420 err);
421 goto done;
422 }
423
424 hdr = (struct vbios_pstate_header_5x *)
425 nvgpu_bios_get_perf_table_ptrs(g,
426 g->bios.perf_token, PERFORMANCE_TABLE);
427
428 if (!hdr) {
429 nvgpu_err(g, "performance table not found");
430 err = -EINVAL;
431 goto done;
432 }
433
434 if (hdr->version != VBIOS_PSTATE_TABLE_VERSION_5X) {
435 nvgpu_err(g, "unknown/unsupported clocks table version=0x%02x",
436 hdr->version);
437 err = -EINVAL;
438 goto done;
439 }
440
441 err = parse_pstate_table_5x(g, hdr);
442done:
443 if (err) {
444 nvgpu_mutex_destroy(&g->perf_pmu.pstatesobjs.pstate_mutex);
445 }
446 return err;
447}
448
449struct pstate *pstate_find(struct gk20a *g, u32 num)
450{
451 struct pstates *pstates = &(g->perf_pmu.pstatesobjs);
452 struct pstate *pstate;
453 u8 i;
454
455 nvgpu_log_info(g, "pstates = %p", pstates);
456
457 BOARDOBJGRP_FOR_EACH(&pstates->super.super,
458 struct pstate *, pstate, i) {
459 nvgpu_log_info(g, "pstate=%p num=%u (looking for num=%u)",
460 pstate, pstate->num, num);
461 if (pstate->num == num) {
462 return pstate;
463 }
464 }
465 return NULL;
466}
467
468struct clk_set_info *pstate_get_clk_set_info(struct gk20a *g,
469 u32 pstate_num, enum nv_pmu_clk_clkwhich clkwhich)
470{
471 struct pstate *pstate = pstate_find(g, pstate_num);
472 struct clk_set_info *info;
473 u32 clkidx;
474
475 nvgpu_log_info(g, "pstate = %p", pstate);
476
477 if (!pstate) {
478 return NULL;
479 }
480
481 for (clkidx = 0; clkidx < pstate->clklist.num_info; clkidx++) {
482 info = &pstate->clklist.clksetinfo[clkidx];
483 if (info->clkwhich == clkwhich) {
484 return info;
485 }
486 }
487 return NULL;
488}
diff --git a/include/pstate/pstate.h b/include/pstate/pstate.h
deleted file mode 100644
index 42b27ea..0000000
--- a/include/pstate/pstate.h
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * general p state infrastructure
3 *
4 * Copyright (c) 2016-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#ifndef NVGPU_PSTATE_H
25#define NVGPU_PSTATE_H
26
27#include "clk/clk.h"
28
29#define CTRL_PERF_PSTATE_TYPE_3X 0x3
30
31#define CTRL_PERF_PSTATE_P0 0
32#define CTRL_PERF_PSTATE_P5 5
33#define CTRL_PERF_PSTATE_P8 8
34
35#define CLK_SET_INFO_MAX_SIZE (32)
36
37struct gk20a;
38
39struct clk_set_info {
40 enum nv_pmu_clk_clkwhich clkwhich;
41 u32 nominal_mhz;
42 u16 min_mhz;
43 u16 max_mhz;
44};
45
46struct clk_set_info_list {
47 u32 num_info;
48 struct clk_set_info clksetinfo[CLK_SET_INFO_MAX_SIZE];
49};
50
51struct pstate {
52 struct boardobj super;
53 u32 num;
54 u8 lpwr_entry_idx;
55 struct clk_set_info_list clklist;
56};
57
58struct pstates {
59 struct boardobjgrp_e32 super;
60 u32 num_levels;
61 struct nvgpu_cond pstate_notifier_wq;
62 u32 is_pstate_switch_on;
63 struct nvgpu_mutex pstate_mutex; /* protect is_pstate_switch_on */
64};
65
66int gk20a_init_pstate_support(struct gk20a *g);
67void gk20a_deinit_pstate_support(struct gk20a *g);
68int gk20a_init_pstate_pmu_support(struct gk20a *g);
69
70struct clk_set_info *pstate_get_clk_set_info(struct gk20a *g, u32 pstate_num,
71 enum nv_pmu_clk_clkwhich clkwhich);
72struct pstate *pstate_find(struct gk20a *g, u32 num);
73
74#endif /* NVGPU_PSTATE_H */