aboutsummaryrefslogtreecommitdiffstats
path: root/include/clk/clk_domain.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2024-09-25 16:09:09 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2024-09-25 16:09:09 -0400
commitf347fde22f1297e4f022600d201780d5ead78114 (patch)
tree76be305d6187003a1e0486ff6e91efb1062ae118 /include/clk/clk_domain.c
parent8340d234d78a7d0f46c11a584de538148b78b7cb (diff)
Delete no-longer-needed nvgpu headersHEADmasterjbakita-wip
The dependency on these was removed in commit 8340d234.
Diffstat (limited to 'include/clk/clk_domain.c')
-rw-r--r--include/clk/clk_domain.c1666
1 files changed, 0 insertions, 1666 deletions
diff --git a/include/clk/clk_domain.c b/include/clk/clk_domain.c
deleted file mode 100644
index 3b64f51..0000000
--- a/include/clk/clk_domain.c
+++ /dev/null
@@ -1,1666 +0,0 @@
1/*
2 * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <nvgpu/bios.h>
24#include <nvgpu/gk20a.h>
25
26#include "clk.h"
27#include "clk_fll.h"
28#include "clk_domain.h"
29#include "boardobj/boardobjgrp.h"
30#include "boardobj/boardobjgrp_e32.h"
31#include "ctrl/ctrlclk.h"
32#include "ctrl/ctrlvolt.h"
33
34static struct clk_domain *construct_clk_domain(struct gk20a *g, void *pargs);
35
36static int devinit_get_clocks_table(struct gk20a *g,
37 struct clk_domains *pdomainobjs);
38
39static int clk_domain_pmudatainit_super(struct gk20a *g, struct boardobj
40 *board_obj_ptr, struct nv_pmu_boardobj *ppmudata);
41
42static struct vbios_clocks_table_1x_hal_clock_entry
43 vbiosclktbl1xhalentry_gp[] = {
44 { clkwhich_gpc2clk, true, 1, },
45 { clkwhich_xbar2clk, true, 1, },
46 { clkwhich_mclk, false, 1, },
47 { clkwhich_sys2clk, true, 1, },
48 { clkwhich_hub2clk, false, 1, },
49 { clkwhich_nvdclk, false, 1, },
50 { clkwhich_pwrclk, false, 1, },
51 { clkwhich_dispclk, false, 1, },
52 { clkwhich_pciegenclk, false, 1, }
53};
54/*
55 * Updated from RM devinit_clock.c
56 * GV100 is 0x03 and
57 * GP10x is 0x02 in clocks_hal.
58 */
59static struct vbios_clocks_table_1x_hal_clock_entry
60 vbiosclktbl1xhalentry_gv[] = {
61 { clkwhich_gpcclk, true, 2, },
62 { clkwhich_xbarclk, true, 1, },
63 { clkwhich_mclk, false, 1, },
64 { clkwhich_sysclk, true, 1, },
65 { clkwhich_hubclk, false, 1, },
66 { clkwhich_nvdclk, true, 1, },
67 { clkwhich_pwrclk, false, 1, },
68 { clkwhich_dispclk, false, 1, },
69 { clkwhich_pciegenclk, false, 1, },
70 { clkwhich_hostclk, true, 1, }
71};
72
73static u32 clktranslatehalmumsettoapinumset(u32 clkhaldomains)
74{
75 u32 clkapidomains = 0;
76
77 if (clkhaldomains & BIT(clkwhich_gpcclk)) {
78 clkapidomains |= CTRL_CLK_DOMAIN_GPCCLK;
79 }
80 if (clkhaldomains & BIT(clkwhich_xbarclk)) {
81 clkapidomains |= CTRL_CLK_DOMAIN_XBARCLK;
82 }
83 if (clkhaldomains & BIT(clkwhich_sysclk)) {
84 clkapidomains |= CTRL_CLK_DOMAIN_SYSCLK;
85 }
86 if (clkhaldomains & BIT(clkwhich_hubclk)) {
87 clkapidomains |= CTRL_CLK_DOMAIN_HUBCLK;
88 }
89 if (clkhaldomains & BIT(clkwhich_hostclk)) {
90 clkapidomains |= CTRL_CLK_DOMAIN_HOSTCLK;
91 }
92 if (clkhaldomains & BIT(clkwhich_gpc2clk)) {
93 clkapidomains |= CTRL_CLK_DOMAIN_GPC2CLK;
94 }
95 if (clkhaldomains & BIT(clkwhich_xbar2clk)) {
96 clkapidomains |= CTRL_CLK_DOMAIN_XBAR2CLK;
97 }
98 if (clkhaldomains & BIT(clkwhich_sys2clk)) {
99 clkapidomains |= CTRL_CLK_DOMAIN_SYS2CLK;
100 }
101 if (clkhaldomains & BIT(clkwhich_hub2clk)) {
102 clkapidomains |= CTRL_CLK_DOMAIN_HUB2CLK;
103 }
104 if (clkhaldomains & BIT(clkwhich_pwrclk)) {
105 clkapidomains |= CTRL_CLK_DOMAIN_PWRCLK;
106 }
107 if (clkhaldomains & BIT(clkwhich_pciegenclk)) {
108 clkapidomains |= CTRL_CLK_DOMAIN_PCIEGENCLK;
109 }
110 if (clkhaldomains & BIT(clkwhich_mclk)) {
111 clkapidomains |= CTRL_CLK_DOMAIN_MCLK;
112 }
113 if (clkhaldomains & BIT(clkwhich_nvdclk)) {
114 clkapidomains |= CTRL_CLK_DOMAIN_NVDCLK;
115 }
116 if (clkhaldomains & BIT(clkwhich_dispclk)) {
117 clkapidomains |= CTRL_CLK_DOMAIN_DISPCLK;
118 }
119
120 return clkapidomains;
121}
122
123static int _clk_domains_pmudatainit_3x(struct gk20a *g,
124 struct boardobjgrp *pboardobjgrp,
125 struct nv_pmu_boardobjgrp_super *pboardobjgrppmu)
126{
127 struct nv_pmu_clk_clk_domain_boardobjgrp_set_header *pset =
128 (struct nv_pmu_clk_clk_domain_boardobjgrp_set_header *)
129 pboardobjgrppmu;
130 struct clk_domains *pdomains = (struct clk_domains *)pboardobjgrp;
131 int status = 0;
132
133 status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu);
134 if (status) {
135 nvgpu_err(g,
136 "error updating pmu boardobjgrp for clk domain 0x%x",
137 status);
138 goto done;
139 }
140
141 pset->vbios_domains = pdomains->vbios_domains;
142 pset->cntr_sampling_periodms = pdomains->cntr_sampling_periodms;
143 pset->version = CLK_DOMAIN_BOARDOBJGRP_VERSION;
144 pset->b_override_o_v_o_c = false;
145 pset->b_debug_mode = false;
146 pset->b_enforce_vf_monotonicity = pdomains->b_enforce_vf_monotonicity;
147 pset->b_enforce_vf_smoothening = pdomains->b_enforce_vf_smoothening;
148 if (g->ops.clk.split_rail_support) {
149 pset->volt_rails_max = 2;
150 } else {
151 pset->volt_rails_max = 1;
152 }
153 status = boardobjgrpmask_export(
154 &pdomains->master_domains_mask.super,
155 pdomains->master_domains_mask.super.bitcount,
156 &pset->master_domains_mask.super);
157
158 memcpy(&pset->deltas, &pdomains->deltas,
159 (sizeof(struct ctrl_clk_clk_delta)));
160
161done:
162 return status;
163}
164
165static int _clk_domains_pmudata_instget(struct gk20a *g,
166 struct nv_pmu_boardobjgrp *pmuboardobjgrp,
167 struct nv_pmu_boardobj **ppboardobjpmudata,
168 u8 idx)
169{
170 struct nv_pmu_clk_clk_domain_boardobj_grp_set *pgrp_set =
171 (struct nv_pmu_clk_clk_domain_boardobj_grp_set *)
172 pmuboardobjgrp;
173
174 nvgpu_log_info(g, " ");
175
176 /*check whether pmuboardobjgrp has a valid boardobj in index*/
177 if (((u32)BIT(idx) &
178 pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) {
179 return -EINVAL;
180 }
181
182 *ppboardobjpmudata = (struct nv_pmu_boardobj *)
183 &pgrp_set->objects[idx].data.board_obj;
184 nvgpu_log_info(g, " Done");
185 return 0;
186}
187
188int clk_domain_sw_setup(struct gk20a *g)
189{
190 int status;
191 struct boardobjgrp *pboardobjgrp = NULL;
192 struct clk_domains *pclkdomainobjs;
193 struct clk_domain *pdomain;
194 struct clk_domain_3x_master *pdomain_master;
195 struct clk_domain_3x_slave *pdomain_slave;
196 u8 i;
197
198 nvgpu_log_info(g, " ");
199
200 status = boardobjgrpconstruct_e32(g, &g->clk_pmu.clk_domainobjs.super);
201 if (status) {
202 nvgpu_err(g,
203 "error creating boardobjgrp for clk domain, status - 0x%x",
204 status);
205 goto done;
206 }
207
208 pboardobjgrp = &g->clk_pmu.clk_domainobjs.super.super;
209 pclkdomainobjs = &(g->clk_pmu.clk_domainobjs);
210
211 BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, CLK_DOMAIN);
212
213 status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp,
214 clk, CLK, clk_domain, CLK_DOMAIN);
215 if (status) {
216 nvgpu_err(g,
217 "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x",
218 status);
219 goto done;
220 }
221
222 pboardobjgrp->pmudatainit = _clk_domains_pmudatainit_3x;
223 pboardobjgrp->pmudatainstget = _clk_domains_pmudata_instget;
224
225 /* Initialize mask to zero.*/
226 boardobjgrpmask_e32_init(&pclkdomainobjs->prog_domains_mask, NULL);
227 boardobjgrpmask_e32_init(&pclkdomainobjs->master_domains_mask, NULL);
228 pclkdomainobjs->b_enforce_vf_monotonicity = true;
229 pclkdomainobjs->b_enforce_vf_smoothening = true;
230
231 memset(&pclkdomainobjs->ordered_noise_aware_list, 0,
232 sizeof(pclkdomainobjs->ordered_noise_aware_list));
233
234 memset(&pclkdomainobjs->ordered_noise_unaware_list, 0,
235 sizeof(pclkdomainobjs->ordered_noise_unaware_list));
236
237 memset(&pclkdomainobjs->deltas, 0,
238 sizeof(struct ctrl_clk_clk_delta));
239
240 status = devinit_get_clocks_table(g, pclkdomainobjs);
241 if (status) {
242 goto done;
243 }
244
245 BOARDOBJGRP_FOR_EACH(&(pclkdomainobjs->super.super),
246 struct clk_domain *, pdomain, i) {
247 pdomain_master = NULL;
248 if (pdomain->super.implements(g, &pdomain->super,
249 CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG)) {
250 status = boardobjgrpmask_bitset(
251 &pclkdomainobjs->prog_domains_mask.super, i);
252 if (status) {
253 goto done;
254 }
255 }
256
257 if (pdomain->super.implements(g, &pdomain->super,
258 CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) {
259 status = boardobjgrpmask_bitset(
260 &pclkdomainobjs->master_domains_mask.super, i);
261 if (status) {
262 goto done;
263 }
264 }
265
266 if (pdomain->super.implements(g, &pdomain->super,
267 CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) {
268 pdomain_slave =
269 (struct clk_domain_3x_slave *)pdomain;
270 pdomain_master =
271 (struct clk_domain_3x_master *)
272 (CLK_CLK_DOMAIN_GET((&g->clk_pmu),
273 pdomain_slave->master_idx));
274 pdomain_master->slave_idxs_mask |= BIT(i);
275 }
276
277 }
278
279done:
280 nvgpu_log_info(g, " done status %x", status);
281 return status;
282}
283
284int clk_domain_pmu_setup(struct gk20a *g)
285{
286 int status;
287 struct boardobjgrp *pboardobjgrp = NULL;
288
289 nvgpu_log_info(g, " ");
290
291 pboardobjgrp = &g->clk_pmu.clk_domainobjs.super.super;
292
293 if (!pboardobjgrp->bconstructed) {
294 return -EINVAL;
295 }
296
297 status = pboardobjgrp->pmuinithandle(g, pboardobjgrp);
298
299 nvgpu_log_info(g, "Done");
300 return status;
301}
302
303static int devinit_get_clocks_table_35(struct gk20a *g,
304 struct clk_domains *pclkdomainobjs, u8 *clocks_table_ptr)
305{
306 int status = 0;
307 struct vbios_clocks_table_35_header clocks_table_header = { 0 };
308 struct vbios_clocks_table_35_entry clocks_table_entry = { 0 };
309 struct vbios_clocks_table_1x_hal_clock_entry *vbiosclktbl1xhalentry;
310 u8 *clocks_tbl_entry_ptr = NULL;
311 u32 index = 0;
312 struct clk_domain *pclkdomain_dev;
313 union {
314 struct boardobj boardobj;
315 struct clk_domain clk_domain;
316 struct clk_domain_3x v3x;
317 struct clk_domain_3x_fixed v3x_fixed;
318 struct clk_domain_35_prog v35_prog;
319 struct clk_domain_35_master v35_master;
320 struct clk_domain_35_slave v35_slave;
321 } clk_domain_data;
322
323 nvgpu_log_info(g, " ");
324
325 memcpy(&clocks_table_header, clocks_table_ptr,
326 VBIOS_CLOCKS_TABLE_35_HEADER_SIZE_09);
327 if (clocks_table_header.header_size <
328 (u8) VBIOS_CLOCKS_TABLE_35_HEADER_SIZE_09) {
329 status = -EINVAL;
330 goto done;
331 }
332
333 if (clocks_table_header.entry_size <
334 (u8) VBIOS_CLOCKS_TABLE_35_ENTRY_SIZE_11) {
335 status = -EINVAL;
336 goto done;
337 }
338
339 switch (clocks_table_header.clocks_hal) {
340 case CLK_TABLE_HAL_ENTRY_GP:
341 {
342 vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gp;
343 break;
344 }
345 case CLK_TABLE_HAL_ENTRY_GV:
346 {
347 vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gv;
348 break;
349 }
350 default:
351 {
352 status = -EINVAL;
353 goto done;
354 }
355 }
356
357 pclkdomainobjs->cntr_sampling_periodms =
358 (u16)clocks_table_header.cntr_sampling_periodms;
359
360 /* Read table entries*/
361 clocks_tbl_entry_ptr = clocks_table_ptr +
362 clocks_table_header.header_size;
363 for (index = 0; index < clocks_table_header.entry_count; index++) {
364 memcpy((void*) &clocks_table_entry, (void*) clocks_tbl_entry_ptr,
365 clocks_table_header.entry_size);
366 clk_domain_data.clk_domain.domain =
367 (u8) vbiosclktbl1xhalentry[index].domain;
368 clk_domain_data.clk_domain.api_domain =
369 clktranslatehalmumsettoapinumset(
370 (u32) BIT(clk_domain_data.clk_domain.domain));
371 clk_domain_data.v3x.b_noise_aware_capable =
372 vbiosclktbl1xhalentry[index].b_noise_aware_capable;
373
374 switch (BIOS_GET_FIELD(clocks_table_entry.flags0,
375 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE)) {
376 case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_FIXED:
377 {
378 clk_domain_data.boardobj.type =
379 CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED;
380 clk_domain_data.v3x_fixed.freq_mhz = (u16)BIOS_GET_FIELD(
381 clocks_table_entry.param1,
382 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_FIXED_FREQUENCY_MHZ);
383 break;
384 }
385
386 case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_MASTER:
387 {
388 clk_domain_data.boardobj.type =
389 CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER;
390 clk_domain_data.v35_prog.super.clk_prog_idx_first =
391 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
392 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST));
393 clk_domain_data.v35_prog.super.clk_prog_idx_last =
394 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
395 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST));
396 clk_domain_data.v35_prog.super.noise_unaware_ordering_index =
397 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
398 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX));
399 if (clk_domain_data.v3x.b_noise_aware_capable) {
400 clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering =
401 (bool)(BIOS_GET_FIELD(clocks_table_entry.param2,
402 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING));
403
404 } else {
405 clk_domain_data.v35_prog.super.noise_aware_ordering_index =
406 CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID;
407 clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering = false;
408 }
409 clk_domain_data.v35_prog.pre_volt_ordering_index =
410 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
411 NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_PRE_VOLT_ORDERING_IDX));
412
413 clk_domain_data.v35_prog.post_volt_ordering_index =
414 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
415 NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_POST_VOLT_ORDERING_IDX));
416
417 clk_domain_data.v35_prog.super.factory_delta.data.delta_khz = 0;
418 clk_domain_data.v35_prog.super.factory_delta.type = 0;
419
420 clk_domain_data.v35_prog.super.freq_delta_min_mhz =
421 (u16)(BIOS_GET_FIELD(clocks_table_entry.param1,
422 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MIN_MHZ));
423
424 clk_domain_data.v35_prog.super.freq_delta_max_mhz =
425 (u16)(BIOS_GET_FIELD(clocks_table_entry.param1,
426 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MAX_MHZ));
427 clk_domain_data.v35_prog.clk_vf_curve_count =
428 vbiosclktbl1xhalentry[index].clk_vf_curve_count;
429 break;
430 }
431
432 case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_SLAVE:
433 {
434 clk_domain_data.boardobj.type =
435 CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE;
436 clk_domain_data.v35_prog.super.clk_prog_idx_first =
437 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
438 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST));
439 clk_domain_data.v35_prog.super.clk_prog_idx_last =
440 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
441 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST));
442 clk_domain_data.v35_prog.super.noise_unaware_ordering_index =
443 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
444 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX));
445
446 if (clk_domain_data.v3x.b_noise_aware_capable) {
447 clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering =
448 (bool)(BIOS_GET_FIELD(clocks_table_entry.param2,
449 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING));
450
451 } else {
452 clk_domain_data.v35_prog.super.noise_aware_ordering_index =
453 CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID;
454 clk_domain_data.v35_prog.super.b_force_noise_unaware_ordering = false;
455 }
456 clk_domain_data.v35_prog.pre_volt_ordering_index =
457 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
458 NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_PRE_VOLT_ORDERING_IDX));
459
460 clk_domain_data.v35_prog.post_volt_ordering_index =
461 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
462 NV_VBIOS_CLOCKS_TABLE_35_ENTRY_PARAM2_PROG_POST_VOLT_ORDERING_IDX));
463
464 clk_domain_data.v35_prog.super.factory_delta.data.delta_khz = 0;
465 clk_domain_data.v35_prog.super.factory_delta.type = 0;
466 clk_domain_data.v35_prog.super.freq_delta_min_mhz = 0;
467 clk_domain_data.v35_prog.super.freq_delta_max_mhz = 0;
468 clk_domain_data.v35_slave.slave.master_idx =
469 (u8)(BIOS_GET_FIELD(clocks_table_entry.param1,
470 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_SLAVE_MASTER_DOMAIN));
471 break;
472 }
473
474 default:
475 {
476 nvgpu_err(g,
477 "error reading clock domain entry %d", index);
478 status = -EINVAL;
479 goto done;
480 }
481
482 }
483 pclkdomain_dev = construct_clk_domain(g,
484 (void *)&clk_domain_data);
485 if (pclkdomain_dev == NULL) {
486 nvgpu_err(g,
487 "unable to construct clock domain boardobj for %d",
488 index);
489 status = -EINVAL;
490 goto done;
491 }
492 status = boardobjgrp_objinsert(
493 &pclkdomainobjs->super.super,
494 (struct boardobj *)(void*) pclkdomain_dev, index);
495 if (status != 0UL) {
496 nvgpu_err(g,
497 "unable to insert clock domain boardobj for %d", index);
498 status = (u32) -EINVAL;
499 goto done;
500 }
501 clocks_tbl_entry_ptr += clocks_table_header.entry_size;
502 }
503
504done:
505 nvgpu_log_info(g, " done status %x", status);
506 return status;
507}
508
509static int devinit_get_clocks_table_1x(struct gk20a *g,
510 struct clk_domains *pclkdomainobjs, u8 *clocks_table_ptr)
511{
512 int status = 0;
513 struct vbios_clocks_table_1x_header clocks_table_header = { 0 };
514 struct vbios_clocks_table_1x_entry clocks_table_entry = { 0 };
515 struct vbios_clocks_table_1x_hal_clock_entry *vbiosclktbl1xhalentry;
516 u8 *clocks_tbl_entry_ptr = NULL;
517 u32 index = 0;
518 struct clk_domain *pclkdomain_dev;
519 union {
520 struct boardobj boardobj;
521 struct clk_domain clk_domain;
522 struct clk_domain_3x v3x;
523 struct clk_domain_3x_fixed v3x_fixed;
524 struct clk_domain_3x_prog v3x_prog;
525 struct clk_domain_3x_master v3x_master;
526 struct clk_domain_3x_slave v3x_slave;
527 } clk_domain_data;
528
529 nvgpu_log_info(g, " ");
530
531 memcpy(&clocks_table_header, clocks_table_ptr,
532 VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07);
533 if (clocks_table_header.header_size <
534 (u8) VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07) {
535 status = -EINVAL;
536 goto done;
537 }
538
539 if (clocks_table_header.entry_size <
540 (u8) VBIOS_CLOCKS_TABLE_1X_ENTRY_SIZE_09) {
541 status = -EINVAL;
542 goto done;
543 }
544
545 switch (clocks_table_header.clocks_hal) {
546 case CLK_TABLE_HAL_ENTRY_GP:
547 {
548 vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gp;
549 break;
550 }
551 case CLK_TABLE_HAL_ENTRY_GV:
552 {
553 vbiosclktbl1xhalentry = vbiosclktbl1xhalentry_gv;
554 break;
555 }
556 default:
557 {
558 status = -EINVAL;
559 goto done;
560 }
561 }
562
563 pclkdomainobjs->cntr_sampling_periodms =
564 (u16)clocks_table_header.cntr_sampling_periodms;
565
566 /* Read table entries*/
567 clocks_tbl_entry_ptr = clocks_table_ptr +
568 VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07;
569 for (index = 0; index < clocks_table_header.entry_count; index++) {
570 memcpy((void*) &clocks_table_entry, (void*) clocks_tbl_entry_ptr,
571 clocks_table_header.entry_size);
572 clk_domain_data.clk_domain.domain =
573 (u8) vbiosclktbl1xhalentry[index].domain;
574 clk_domain_data.clk_domain.api_domain =
575 clktranslatehalmumsettoapinumset(
576 BIT(clk_domain_data.clk_domain.domain));
577 clk_domain_data.v3x.b_noise_aware_capable =
578 vbiosclktbl1xhalentry[index].b_noise_aware_capable;
579
580 switch (BIOS_GET_FIELD(clocks_table_entry.flags0,
581 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE)) {
582 case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_FIXED:
583 {
584 clk_domain_data.boardobj.type =
585 CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED;
586 clk_domain_data.v3x_fixed.freq_mhz = (u16)BIOS_GET_FIELD(
587 clocks_table_entry.param1,
588 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_FIXED_FREQUENCY_MHZ);
589 break;
590 }
591
592 case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_MASTER:
593 {
594 clk_domain_data.boardobj.type =
595 CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER;
596 clk_domain_data.v3x_prog.clk_prog_idx_first =
597 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
598 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST));
599 clk_domain_data.v3x_prog.clk_prog_idx_last =
600 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
601 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST));
602 clk_domain_data.v3x_prog.noise_unaware_ordering_index =
603 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
604 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX));
605 if (clk_domain_data.v3x.b_noise_aware_capable) {
606 clk_domain_data.v3x_prog.noise_aware_ordering_index =
607 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
608 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_AWARE_ORDERING_IDX));
609 clk_domain_data.v3x_prog.b_force_noise_unaware_ordering =
610 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
611 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING));
612 } else {
613 clk_domain_data.v3x_prog.noise_aware_ordering_index =
614 CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID;
615 clk_domain_data.v3x_prog.b_force_noise_unaware_ordering = false;
616 }
617
618 clk_domain_data.v3x_prog.factory_delta.data.delta_khz = 0;
619 clk_domain_data.v3x_prog.factory_delta.type = 0;
620
621 clk_domain_data.v3x_prog.freq_delta_min_mhz =
622 (u16)(BIOS_GET_FIELD(clocks_table_entry.param1,
623 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MIN_MHZ));
624
625 clk_domain_data.v3x_prog.freq_delta_max_mhz =
626 (u16)(BIOS_GET_FIELD(clocks_table_entry.param1,
627 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_MASTER_FREQ_OC_DELTA_MAX_MHZ));
628 break;
629 }
630
631 case NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_FLAGS0_USAGE_SLAVE:
632 {
633 clk_domain_data.boardobj.type =
634 CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE;
635 clk_domain_data.v3x_prog.clk_prog_idx_first =
636 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
637 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_FIRST));
638 clk_domain_data.v3x_prog.clk_prog_idx_last =
639 (u8)(BIOS_GET_FIELD(clocks_table_entry.param0,
640 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM0_PROG_CLK_PROG_IDX_LAST));
641 clk_domain_data.v3x_prog.noise_unaware_ordering_index =
642 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
643 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_UNAWARE_ORDERING_IDX));
644
645 if (clk_domain_data.v3x.b_noise_aware_capable) {
646 clk_domain_data.v3x_prog.noise_aware_ordering_index =
647 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
648 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_NOISE_AWARE_ORDERING_IDX));
649 clk_domain_data.v3x_prog.b_force_noise_unaware_ordering =
650 (u8)(BIOS_GET_FIELD(clocks_table_entry.param2,
651 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM2_PROG_FORCE_NOISE_UNAWARE_ORDERING));
652 } else {
653 clk_domain_data.v3x_prog.noise_aware_ordering_index =
654 CTRL_CLK_CLK_DOMAIN_3X_PROG_ORDERING_INDEX_INVALID;
655 clk_domain_data.v3x_prog.b_force_noise_unaware_ordering = false;
656 }
657 clk_domain_data.v3x_prog.factory_delta.data.delta_khz = 0;
658 clk_domain_data.v3x_prog.factory_delta.type = 0;
659 clk_domain_data.v3x_prog.freq_delta_min_mhz = 0;
660 clk_domain_data.v3x_prog.freq_delta_max_mhz = 0;
661 clk_domain_data.v3x_slave.master_idx =
662 (u8)(BIOS_GET_FIELD(clocks_table_entry.param1,
663 NV_VBIOS_CLOCKS_TABLE_1X_ENTRY_PARAM1_SLAVE_MASTER_DOMAIN));
664 break;
665 }
666
667 default:
668 {
669 nvgpu_err(g,
670 "error reading clock domain entry %d", index);
671 status = (u32) -EINVAL;
672 goto done;
673 }
674
675 }
676 pclkdomain_dev = construct_clk_domain(g,
677 (void *)&clk_domain_data);
678 if (pclkdomain_dev == NULL) {
679 nvgpu_err(g,
680 "unable to construct clock domain boardobj for %d",
681 index);
682 status = (u32) -EINVAL;
683 goto done;
684 }
685 status = boardobjgrp_objinsert(&pclkdomainobjs->super.super,
686 (struct boardobj *)(void *)pclkdomain_dev, index);
687 if (status != 0UL) {
688 nvgpu_err(g,
689 "unable to insert clock domain boardobj for %d", index);
690 status = (u32) -EINVAL;
691 goto done;
692 }
693 clocks_tbl_entry_ptr += clocks_table_header.entry_size;
694 }
695
696done:
697 nvgpu_log_info(g, " done status %x", status);
698 return status;
699}
700
701static int devinit_get_clocks_table(struct gk20a *g,
702 struct clk_domains *pclkdomainobjs)
703{
704 int status = 0;
705 u8 *clocks_table_ptr = NULL;
706 struct vbios_clocks_table_1x_header clocks_table_header = { 0 };
707 nvgpu_log_info(g, " ");
708
709 clocks_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g,
710 g->bios.clock_token, CLOCKS_TABLE);
711 if (clocks_table_ptr == NULL) {
712 status = -EINVAL;
713 goto done;
714 }
715 memcpy(&clocks_table_header, clocks_table_ptr,
716 VBIOS_CLOCKS_TABLE_1X_HEADER_SIZE_07);
717 if (clocks_table_header.version == 0x35U) {
718 devinit_get_clocks_table_35(g, pclkdomainobjs, clocks_table_ptr);
719 }
720 else {
721 devinit_get_clocks_table_1x(g, pclkdomainobjs, clocks_table_ptr);
722 }
723 done:
724 return status;
725
726}
727
728static int clkdomainclkproglink_not_supported(struct gk20a *g,
729 struct clk_pmupstate *pclk,
730 struct clk_domain *pdomain)
731{
732 nvgpu_log_info(g, " ");
733 return -EINVAL;
734}
735
736static int clkdomainvfsearch_stub(
737 struct gk20a *g,
738 struct clk_pmupstate *pclk,
739 struct clk_domain *pdomain,
740 u16 *clkmhz,
741 u32 *voltuv,
742 u8 rail)
743
744{
745 nvgpu_log_info(g, " ");
746 return -EINVAL;
747}
748
749static u32 clkdomaingetfpoints_stub(
750 struct gk20a *g,
751 struct clk_pmupstate *pclk,
752 struct clk_domain *pdomain,
753 u32 *pfpointscount,
754 u16 *pfreqpointsinmhz,
755 u8 rail)
756{
757 nvgpu_log_info(g, " ");
758 return -EINVAL;
759}
760
761
762static int clk_domain_construct_super(struct gk20a *g,
763 struct boardobj **ppboardobj,
764 u16 size, void *pargs)
765{
766 struct clk_domain *pdomain;
767 struct clk_domain *ptmpdomain = (struct clk_domain *)pargs;
768 int status = 0;
769
770 status = boardobj_construct_super(g, ppboardobj,
771 size, pargs);
772
773 if (status) {
774 return -EINVAL;
775 }
776
777 pdomain = (struct clk_domain *)*ppboardobj;
778
779 pdomain->super.pmudatainit =
780 clk_domain_pmudatainit_super;
781
782 pdomain->clkdomainclkproglink =
783 clkdomainclkproglink_not_supported;
784
785 pdomain->clkdomainclkvfsearch =
786 clkdomainvfsearch_stub;
787
788 pdomain->clkdomainclkgetfpoints =
789 clkdomaingetfpoints_stub;
790
791 pdomain->api_domain = ptmpdomain->api_domain;
792 pdomain->domain = ptmpdomain->domain;
793 pdomain->perf_domain_grp_idx =
794 ptmpdomain->perf_domain_grp_idx;
795
796 return status;
797}
798
799static int _clk_domain_pmudatainit_3x(struct gk20a *g,
800 struct boardobj *board_obj_ptr,
801 struct nv_pmu_boardobj *ppmudata)
802{
803 int status = 0;
804 struct clk_domain_3x *pclk_domain_3x;
805 struct nv_pmu_clk_clk_domain_3x_boardobj_set *pset;
806
807 nvgpu_log_info(g, " ");
808
809 status = clk_domain_pmudatainit_super(g, board_obj_ptr, ppmudata);
810 if (status != 0) {
811 return status;
812 }
813
814 pclk_domain_3x = (struct clk_domain_3x *)board_obj_ptr;
815
816 pset = (struct nv_pmu_clk_clk_domain_3x_boardobj_set *)ppmudata;
817
818 pset->b_noise_aware_capable = pclk_domain_3x->b_noise_aware_capable;
819
820 return status;
821}
822
823static int clk_domain_construct_3x(struct gk20a *g,
824 struct boardobj **ppboardobj,
825 u16 size, void *pargs)
826{
827 struct boardobj *ptmpobj = (struct boardobj *)pargs;
828 struct clk_domain_3x *pdomain;
829 struct clk_domain_3x *ptmpdomain =
830 (struct clk_domain_3x *)pargs;
831 int status = 0;
832
833 ptmpobj->type_mask = BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X);
834 status = clk_domain_construct_super(g, ppboardobj,
835 size, pargs);
836 if (status) {
837 return -EINVAL;
838 }
839
840 pdomain = (struct clk_domain_3x *)*ppboardobj;
841
842 pdomain->super.super.pmudatainit =
843 _clk_domain_pmudatainit_3x;
844
845 pdomain->b_noise_aware_capable = ptmpdomain->b_noise_aware_capable;
846
847 return status;
848}
849
850static int clkdomainclkproglink_3x_prog(struct gk20a *g,
851 struct clk_pmupstate *pclk,
852 struct clk_domain *pdomain)
853{
854 int status = 0;
855 struct clk_domain_3x_prog *p3xprog =
856 (struct clk_domain_3x_prog *)pdomain;
857 struct clk_prog *pprog = NULL;
858 u8 i;
859
860 nvgpu_log_info(g, " ");
861
862 for (i = p3xprog->clk_prog_idx_first;
863 i <= p3xprog->clk_prog_idx_last;
864 i++) {
865 pprog = CLK_CLK_PROG_GET(pclk, i);
866 if (pprog == NULL) {
867 status = -EINVAL;
868 }
869 }
870 return status;
871}
872
873static int clkdomaingetslaveclk(struct gk20a *g,
874 struct clk_pmupstate *pclk,
875 struct clk_domain *pdomain,
876 u16 *pclkmhz,
877 u16 masterclkmhz)
878{
879 int status = 0;
880 struct clk_prog *pprog = NULL;
881 struct clk_prog_1x_master *pprog1xmaster = NULL;
882 u8 slaveidx;
883 struct clk_domain_3x_master *p3xmaster;
884
885 nvgpu_log_info(g, " ");
886
887 if (pclkmhz == NULL) {
888 return -EINVAL;
889 }
890
891 if (masterclkmhz == 0) {
892 return -EINVAL;
893 }
894
895 slaveidx = BOARDOBJ_GET_IDX(pdomain);
896 p3xmaster = (struct clk_domain_3x_master *)
897 CLK_CLK_DOMAIN_GET(pclk,
898 ((struct clk_domain_3x_slave *)
899 pdomain)->master_idx);
900 pprog = CLK_CLK_PROG_GET(pclk, p3xmaster->super.clk_prog_idx_first);
901 pprog1xmaster = (struct clk_prog_1x_master *)pprog;
902
903 status = pprog1xmaster->getslaveclk(g, pclk, pprog1xmaster,
904 slaveidx, pclkmhz, masterclkmhz);
905 return status;
906}
907
908static int clkdomainvfsearch(struct gk20a *g,
909 struct clk_pmupstate *pclk,
910 struct clk_domain *pdomain,
911 u16 *pclkmhz,
912 u32 *pvoltuv,
913 u8 rail)
914{
915 int status = 0;
916 struct clk_domain_3x_master *p3xmaster =
917 (struct clk_domain_3x_master *)pdomain;
918 struct clk_prog *pprog = NULL;
919 struct clk_prog_1x_master *pprog1xmaster = NULL;
920 u8 i;
921 u8 *pslaveidx = NULL;
922 u8 slaveidx;
923 u16 clkmhz;
924 u32 voltuv;
925 u16 bestclkmhz;
926 u32 bestvoltuv;
927
928 nvgpu_log_info(g, " ");
929
930 if ((pclkmhz == NULL) || (pvoltuv == NULL)) {
931 return -EINVAL;
932 }
933
934 if ((*pclkmhz != 0) && (*pvoltuv != 0)) {
935 return -EINVAL;
936 }
937
938 bestclkmhz = *pclkmhz;
939 bestvoltuv = *pvoltuv;
940
941 if (pdomain->super.implements(g, &pdomain->super,
942 CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) {
943 slaveidx = BOARDOBJ_GET_IDX(pdomain);
944 pslaveidx = &slaveidx;
945 p3xmaster = (struct clk_domain_3x_master *)
946 CLK_CLK_DOMAIN_GET(pclk,
947 ((struct clk_domain_3x_slave *)
948 pdomain)->master_idx);
949 }
950 /* Iterate over the set of CLK_PROGs pointed at by this domain.*/
951 for (i = p3xmaster->super.clk_prog_idx_first;
952 i <= p3xmaster->super.clk_prog_idx_last;
953 i++) {
954 clkmhz = *pclkmhz;
955 voltuv = *pvoltuv;
956 pprog = CLK_CLK_PROG_GET(pclk, i);
957
958 /* MASTER CLK_DOMAINs must point to MASTER CLK_PROGs.*/
959 if (!pprog->super.implements(g, &pprog->super,
960 CTRL_CLK_CLK_PROG_TYPE_1X_MASTER)) {
961 status = -EINVAL;
962 goto done;
963 }
964
965 pprog1xmaster = (struct clk_prog_1x_master *)pprog;
966 status = pprog1xmaster->vflookup(g, pclk, pprog1xmaster,
967 pslaveidx, &clkmhz, &voltuv, rail);
968 /* if look up has found the V or F value matching to other
969 exit */
970 if (status == 0) {
971 if (*pclkmhz == 0) {
972 bestclkmhz = clkmhz;
973 } else {
974 bestvoltuv = voltuv;
975 break;
976 }
977 }
978 }
979 /* clk and volt sent as zero to print vf table */
980 if ((*pclkmhz == 0) && (*pvoltuv == 0)) {
981 status = 0;
982 goto done;
983 }
984 /* atleast one search found a matching value? */
985 if ((bestvoltuv != 0) && (bestclkmhz != 0)) {
986 *pclkmhz = bestclkmhz;
987 *pvoltuv = bestvoltuv;
988 status = 0;
989 goto done;
990 }
991done:
992 nvgpu_log_info(g, "done status %x", status);
993 return status;
994}
995
996static u32 clkdomaingetfpoints
997(
998 struct gk20a *g,
999 struct clk_pmupstate *pclk,
1000 struct clk_domain *pdomain,
1001 u32 *pfpointscount,
1002 u16 *pfreqpointsinmhz,
1003 u8 rail
1004)
1005{
1006 u32 status = 0;
1007 struct clk_domain_3x_master *p3xmaster =
1008 (struct clk_domain_3x_master *)pdomain;
1009 struct clk_prog *pprog = NULL;
1010 struct clk_prog_1x_master *pprog1xmaster = NULL;
1011 u32 fpointscount = 0;
1012 u32 remainingcount;
1013 u32 totalcount;
1014 u16 *freqpointsdata;
1015 u8 i;
1016
1017 nvgpu_log_info(g, " ");
1018
1019 if (pfpointscount == NULL) {
1020 return -EINVAL;
1021 }
1022
1023 if ((pfreqpointsinmhz == NULL) && (*pfpointscount != 0)) {
1024 return -EINVAL;
1025 }
1026
1027 if (pdomain->super.implements(g, &pdomain->super,
1028 CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE)) {
1029 return -EINVAL;
1030 }
1031
1032 freqpointsdata = pfreqpointsinmhz;
1033 totalcount = 0;
1034 fpointscount = *pfpointscount;
1035 remainingcount = fpointscount;
1036 /* Iterate over the set of CLK_PROGs pointed at by this domain.*/
1037 for (i = p3xmaster->super.clk_prog_idx_first;
1038 i <= p3xmaster->super.clk_prog_idx_last;
1039 i++) {
1040 pprog = CLK_CLK_PROG_GET(pclk, i);
1041 pprog1xmaster = (struct clk_prog_1x_master *)pprog;
1042 status = pprog1xmaster->getfpoints(g, pclk, pprog1xmaster,
1043 &fpointscount, &freqpointsdata, rail);
1044 if (status) {
1045 *pfpointscount = 0;
1046 goto done;
1047 }
1048 totalcount += fpointscount;
1049 if (*pfpointscount) {
1050 remainingcount -= fpointscount;
1051 fpointscount = remainingcount;
1052 } else {
1053 fpointscount = 0;
1054 }
1055
1056 }
1057
1058 *pfpointscount = totalcount;
1059done:
1060 nvgpu_log_info(g, "done status %x", status);
1061 return status;
1062}
1063
1064static int clk_domain_pmudatainit_35_prog(struct gk20a *g,
1065 struct boardobj *board_obj_ptr,
1066 struct nv_pmu_boardobj *ppmudata)
1067{
1068 int status = 0;
1069 struct clk_domain_35_prog *pclk_domain_35_prog;
1070 struct clk_domain_3x_prog *pclk_domain_3x_prog;
1071 struct nv_pmu_clk_clk_domain_35_prog_boardobj_set *pset;
1072 struct clk_domains *pdomains = &(g->clk_pmu.clk_domainobjs);
1073
1074 nvgpu_log_info(g, " ");
1075
1076 status = _clk_domain_pmudatainit_3x(g, board_obj_ptr, ppmudata);
1077 if (status != 0UL) {
1078 return status;
1079 }
1080
1081 pclk_domain_35_prog = (struct clk_domain_35_prog *)(void*)board_obj_ptr;
1082 pclk_domain_3x_prog = &pclk_domain_35_prog->super;
1083
1084 pset = (struct nv_pmu_clk_clk_domain_35_prog_boardobj_set *)
1085 (void*) ppmudata;
1086
1087 pset->super.clk_prog_idx_first = pclk_domain_3x_prog->clk_prog_idx_first;
1088 pset->super.clk_prog_idx_last = pclk_domain_3x_prog->clk_prog_idx_last;
1089 pset->super.b_force_noise_unaware_ordering =
1090 pclk_domain_3x_prog->b_force_noise_unaware_ordering;
1091 pset->super.factory_delta = pclk_domain_3x_prog->factory_delta;
1092 pset->super.freq_delta_min_mhz = pclk_domain_3x_prog->freq_delta_min_mhz;
1093 pset->super.freq_delta_max_mhz = pclk_domain_3x_prog->freq_delta_max_mhz;
1094 memcpy(&pset->super.deltas, &pdomains->deltas,
1095 (sizeof(struct ctrl_clk_clk_delta)));
1096 pset->pre_volt_ordering_index = pclk_domain_35_prog->pre_volt_ordering_index;
1097 pset->post_volt_ordering_index = pclk_domain_35_prog->post_volt_ordering_index;
1098 pset->clk_pos = pclk_domain_35_prog->clk_pos;
1099 pset->clk_vf_curve_count = pclk_domain_35_prog->clk_vf_curve_count;
1100
1101 return status;
1102}
1103
1104static int _clk_domain_pmudatainit_3x_prog(struct gk20a *g,
1105 struct boardobj *board_obj_ptr,
1106 struct nv_pmu_boardobj *ppmudata)
1107{
1108 int status = 0;
1109 struct clk_domain_3x_prog *pclk_domain_3x_prog;
1110 struct nv_pmu_clk_clk_domain_30_prog_boardobj_set *pset;
1111 struct clk_domains *pdomains = &(g->clk_pmu.clk_domainobjs);
1112
1113 nvgpu_log_info(g, " ");
1114
1115 status = _clk_domain_pmudatainit_3x(g, board_obj_ptr, ppmudata);
1116 if (status != 0) {
1117 return status;
1118 }
1119
1120 pclk_domain_3x_prog = (struct clk_domain_3x_prog *)board_obj_ptr;
1121
1122 pset = (struct nv_pmu_clk_clk_domain_30_prog_boardobj_set *)
1123 ppmudata;
1124
1125 pset->super.clk_prog_idx_first = pclk_domain_3x_prog->clk_prog_idx_first;
1126 pset->super.clk_prog_idx_last = pclk_domain_3x_prog->clk_prog_idx_last;
1127 pset->noise_unaware_ordering_index =
1128 pclk_domain_3x_prog->noise_unaware_ordering_index;
1129 pset->noise_aware_ordering_index =
1130 pclk_domain_3x_prog->noise_aware_ordering_index;
1131 pset->super.b_force_noise_unaware_ordering =
1132 pclk_domain_3x_prog->b_force_noise_unaware_ordering;
1133 pset->super.factory_delta = pclk_domain_3x_prog->factory_delta;
1134 pset->super.freq_delta_min_mhz = pclk_domain_3x_prog->freq_delta_min_mhz;
1135 pset->super.freq_delta_max_mhz = pclk_domain_3x_prog->freq_delta_max_mhz;
1136 memcpy(&pset->super.deltas, &pdomains->deltas,
1137 (sizeof(struct ctrl_clk_clk_delta)));
1138
1139 return status;
1140}
1141
1142static int clk_domain_construct_35_prog(struct gk20a *g,
1143 struct boardobj **ppboardobj,
1144 u16 size, void *pargs)
1145{
1146 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1147 struct clk_domain_35_prog *pdomain;
1148 struct clk_domain_35_prog *ptmpdomain =
1149 (struct clk_domain_35_prog *)pargs;
1150 int status = 0;
1151
1152 ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG);
1153 status = clk_domain_construct_3x(g, ppboardobj, size, pargs);
1154 if (status != 0UL)
1155 {
1156 return (u32) -EINVAL;
1157 }
1158
1159 pdomain = (struct clk_domain_35_prog *)(void*) *ppboardobj;
1160
1161 pdomain->super.super.super.super.pmudatainit =
1162 clk_domain_pmudatainit_35_prog;
1163
1164 pdomain->super.super.super.clkdomainclkproglink =
1165 clkdomainclkproglink_3x_prog;
1166
1167 pdomain->super.super.super.clkdomainclkvfsearch =
1168 clkdomainvfsearch;
1169
1170 pdomain->super.super.super.clkdomainclkgetfpoints =
1171 clkdomaingetfpoints;
1172
1173 pdomain->super.clk_prog_idx_first = ptmpdomain->super.clk_prog_idx_first;
1174 pdomain->super.clk_prog_idx_last = ptmpdomain->super.clk_prog_idx_last;
1175 pdomain->super.noise_unaware_ordering_index =
1176 ptmpdomain->super.noise_unaware_ordering_index;
1177 pdomain->super.noise_aware_ordering_index =
1178 ptmpdomain->super.noise_aware_ordering_index;
1179 pdomain->super.b_force_noise_unaware_ordering =
1180 ptmpdomain->super.b_force_noise_unaware_ordering;
1181 pdomain->super.factory_delta = ptmpdomain->super.factory_delta;
1182 pdomain->super.freq_delta_min_mhz = ptmpdomain->super.freq_delta_min_mhz;
1183 pdomain->super.freq_delta_max_mhz = ptmpdomain->super.freq_delta_max_mhz;
1184 pdomain->pre_volt_ordering_index = ptmpdomain->pre_volt_ordering_index;
1185 pdomain->post_volt_ordering_index = ptmpdomain->post_volt_ordering_index;
1186 pdomain->clk_pos = ptmpdomain->clk_pos;
1187 pdomain->clk_vf_curve_count = ptmpdomain->clk_vf_curve_count;
1188
1189 return status;
1190}
1191
1192static int clk_domain_construct_3x_prog(struct gk20a *g,
1193 struct boardobj **ppboardobj,
1194 u16 size, void *pargs)
1195{
1196 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1197 struct clk_domain_3x_prog *pdomain;
1198 struct clk_domain_3x_prog *ptmpdomain =
1199 (struct clk_domain_3x_prog *)pargs;
1200 int status = 0;
1201
1202 ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_PROG);
1203 status = clk_domain_construct_3x(g, ppboardobj, size, pargs);
1204 if (status) {
1205 return -EINVAL;
1206 }
1207
1208 pdomain = (struct clk_domain_3x_prog *)*ppboardobj;
1209
1210 pdomain->super.super.super.pmudatainit =
1211 _clk_domain_pmudatainit_3x_prog;
1212
1213 pdomain->super.super.clkdomainclkproglink =
1214 clkdomainclkproglink_3x_prog;
1215
1216 pdomain->super.super.clkdomainclkvfsearch =
1217 clkdomainvfsearch;
1218
1219 pdomain->super.super.clkdomainclkgetfpoints =
1220 clkdomaingetfpoints;
1221
1222 pdomain->clk_prog_idx_first = ptmpdomain->clk_prog_idx_first;
1223 pdomain->clk_prog_idx_last = ptmpdomain->clk_prog_idx_last;
1224 pdomain->noise_unaware_ordering_index =
1225 ptmpdomain->noise_unaware_ordering_index;
1226 pdomain->noise_aware_ordering_index =
1227 ptmpdomain->noise_aware_ordering_index;
1228 pdomain->b_force_noise_unaware_ordering =
1229 ptmpdomain->b_force_noise_unaware_ordering;
1230 pdomain->factory_delta = ptmpdomain->factory_delta;
1231 pdomain->freq_delta_min_mhz = ptmpdomain->freq_delta_min_mhz;
1232 pdomain->freq_delta_max_mhz = ptmpdomain->freq_delta_max_mhz;
1233
1234 return status;
1235}
1236
1237static int _clk_domain_pmudatainit_35_slave(struct gk20a *g,
1238 struct boardobj *board_obj_ptr,
1239 struct nv_pmu_boardobj *ppmudata)
1240{
1241 int status = 0;
1242 struct clk_domain_35_slave *pclk_domain_35_slave;
1243 struct nv_pmu_clk_clk_domain_35_slave_boardobj_set *pset;
1244
1245 nvgpu_log_info(g, " ");
1246
1247 status = clk_domain_pmudatainit_35_prog(g, board_obj_ptr, ppmudata);
1248 if (status != 0UL) {
1249 return status;
1250 }
1251
1252 pclk_domain_35_slave = (struct clk_domain_35_slave *)(void*)board_obj_ptr;
1253
1254 pset = (struct nv_pmu_clk_clk_domain_35_slave_boardobj_set *)
1255 (void*) ppmudata;
1256
1257 pset->slave.master_idx = pclk_domain_35_slave->slave.master_idx;
1258
1259 return status;
1260}
1261
1262static int clk_domain_pmudatainit_3x_slave(struct gk20a *g,
1263 struct boardobj *board_obj_ptr,
1264 struct nv_pmu_boardobj *ppmudata)
1265{
1266 int status = 0;
1267 struct clk_domain_3x_slave *pclk_domain_3x_slave;
1268 struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set *pset;
1269
1270 nvgpu_log_info(g, " ");
1271
1272 status = _clk_domain_pmudatainit_3x_prog(g, board_obj_ptr, ppmudata);
1273 if (status != 0) {
1274 return status;
1275 }
1276
1277 pclk_domain_3x_slave = (struct clk_domain_3x_slave *)board_obj_ptr;
1278
1279 pset = (struct nv_pmu_clk_clk_domain_3x_slave_boardobj_set *)
1280 ppmudata;
1281
1282 pset->master_idx = pclk_domain_3x_slave->master_idx;
1283
1284 return status;
1285}
1286
1287static int clk_domain_construct_35_slave(struct gk20a *g,
1288 struct boardobj **ppboardobj,
1289 u16 size, void *pargs)
1290{
1291 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1292 struct clk_domain_35_slave *pdomain;
1293 struct clk_domain_35_slave *ptmpdomain =
1294 (struct clk_domain_35_slave *)pargs;
1295 int status = 0;
1296
1297 if (BOARDOBJ_GET_TYPE(pargs) != (u8) CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE) {
1298 return (u32) -EINVAL;
1299 }
1300
1301 ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE);
1302 status = clk_domain_construct_35_prog(g, ppboardobj, size, pargs);
1303 if (status != 0UL) {
1304 return (u32) -EINVAL;
1305 }
1306
1307 pdomain = (struct clk_domain_35_slave *)(void*)*ppboardobj;
1308
1309 pdomain->super.super.super.super.super.pmudatainit =
1310 _clk_domain_pmudatainit_35_slave;
1311
1312 pdomain->slave.master_idx = ptmpdomain->slave.master_idx;
1313
1314 pdomain->slave.clkdomainclkgetslaveclk =
1315 clkdomaingetslaveclk;
1316
1317 return status;
1318}
1319
1320static int clk_domain_construct_3x_slave(struct gk20a *g,
1321 struct boardobj **ppboardobj,
1322 u16 size, void *pargs)
1323{
1324 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1325 struct clk_domain_3x_slave *pdomain;
1326 struct clk_domain_3x_slave *ptmpdomain =
1327 (struct clk_domain_3x_slave *)pargs;
1328 int status = 0;
1329
1330 if (BOARDOBJ_GET_TYPE(pargs) != (u8) CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE) {
1331 return -EINVAL;
1332 }
1333
1334 ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE);
1335 status = clk_domain_construct_3x_prog(g, ppboardobj, size, pargs);
1336 if (status != 0UL) {
1337 return -EINVAL;
1338 }
1339
1340 pdomain = (struct clk_domain_3x_slave *)*ppboardobj;
1341
1342 pdomain->super.super.super.super.pmudatainit =
1343 clk_domain_pmudatainit_3x_slave;
1344
1345 pdomain->master_idx = ptmpdomain->master_idx;
1346
1347 pdomain->clkdomainclkgetslaveclk =
1348 clkdomaingetslaveclk;
1349
1350 return status;
1351}
1352
1353static int clkdomainclkproglink_3x_master(struct gk20a *g,
1354 struct clk_pmupstate *pclk,
1355 struct clk_domain *pdomain)
1356{
1357 int status = 0;
1358 struct clk_domain_3x_master *p3xmaster =
1359 (struct clk_domain_3x_master *)pdomain;
1360 struct clk_prog *pprog = NULL;
1361 struct clk_prog_1x_master *pprog1xmaster = NULL;
1362 u16 freq_max_last_mhz = 0;
1363 u8 i;
1364
1365 nvgpu_log_info(g, " ");
1366
1367 status = clkdomainclkproglink_3x_prog(g, pclk, pdomain);
1368 if (status) {
1369 goto done;
1370 }
1371
1372 /* Iterate over the set of CLK_PROGs pointed at by this domain.*/
1373 for (i = p3xmaster->super.clk_prog_idx_first;
1374 i <= p3xmaster->super.clk_prog_idx_last;
1375 i++) {
1376 pprog = CLK_CLK_PROG_GET(pclk, i);
1377
1378 /* MASTER CLK_DOMAINs must point to MASTER CLK_PROGs.*/
1379 if (!pprog->super.implements(g, &pprog->super,
1380 CTRL_CLK_CLK_PROG_TYPE_1X_MASTER)) {
1381 status = -EINVAL;
1382 goto done;
1383 }
1384
1385 pprog1xmaster = (struct clk_prog_1x_master *)pprog;
1386 status = pprog1xmaster->vfflatten(g, pclk, pprog1xmaster,
1387 BOARDOBJ_GET_IDX(p3xmaster), &freq_max_last_mhz);
1388 if (status) {
1389 goto done;
1390 }
1391 }
1392done:
1393 nvgpu_log_info(g, "done status %x", status);
1394 return status;
1395}
1396
1397static int clk_domain_pmudatainit_35_master(struct gk20a *g,
1398 struct boardobj *board_obj_ptr,
1399 struct nv_pmu_boardobj *ppmudata)
1400{
1401 int status = 0;
1402 struct clk_domain_35_master *pclk_domain_35_master;
1403 struct nv_pmu_clk_clk_domain_35_master_boardobj_set *pset;
1404
1405 nvgpu_log_info(g, " ");
1406
1407 status = clk_domain_pmudatainit_35_prog(g, board_obj_ptr, ppmudata);
1408 if (status != 0UL) {
1409 return status;
1410 }
1411
1412 pclk_domain_35_master = (struct clk_domain_35_master *)
1413 (void*) board_obj_ptr;
1414
1415 pset = (struct nv_pmu_clk_clk_domain_35_master_boardobj_set *)
1416 (void*) ppmudata;
1417
1418 pset->master.slave_idxs_mask = pclk_domain_35_master->master.slave_idxs_mask;
1419
1420 return status;
1421}
1422
1423static int _clk_domain_pmudatainit_3x_master(struct gk20a *g,
1424 struct boardobj *board_obj_ptr,
1425 struct nv_pmu_boardobj *ppmudata)
1426{
1427 int status = 0;
1428 struct clk_domain_3x_master *pclk_domain_3x_master;
1429 struct nv_pmu_clk_clk_domain_3x_master_boardobj_set *pset;
1430
1431 nvgpu_log_info(g, " ");
1432
1433 status = _clk_domain_pmudatainit_3x_prog(g, board_obj_ptr, ppmudata);
1434 if (status != 0) {
1435 return status;
1436 }
1437
1438 pclk_domain_3x_master = (struct clk_domain_3x_master *)board_obj_ptr;
1439
1440 pset = (struct nv_pmu_clk_clk_domain_3x_master_boardobj_set *)
1441 ppmudata;
1442
1443 pset->slave_idxs_mask = pclk_domain_3x_master->slave_idxs_mask;
1444
1445 return status;
1446}
1447
1448static int clk_domain_construct_35_master(struct gk20a *g,
1449 struct boardobj **ppboardobj,
1450 u16 size, void *pargs)
1451{
1452 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1453 struct clk_domain_35_master *pdomain;
1454 int status = 0;
1455
1456 if (BOARDOBJ_GET_TYPE(pargs) != (u8) CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER) {
1457 return -EINVAL;
1458 }
1459
1460 ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER);
1461 status = clk_domain_construct_35_prog(g, ppboardobj, size, pargs);
1462 if (status != 0UL) {
1463 return (u32) -EINVAL;
1464 }
1465
1466 pdomain = (struct clk_domain_35_master *)(void*) *ppboardobj;
1467
1468 pdomain->super.super.super.super.super.pmudatainit =
1469 clk_domain_pmudatainit_35_master;
1470 pdomain->super.super.super.super.clkdomainclkproglink =
1471 clkdomainclkproglink_3x_master;
1472
1473 pdomain->master.slave_idxs_mask = 0;
1474
1475 return status;
1476}
1477
1478static int clk_domain_construct_3x_master(struct gk20a *g,
1479 struct boardobj **ppboardobj,
1480 u16 size, void *pargs)
1481{
1482 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1483 struct clk_domain_3x_master *pdomain;
1484 int status = 0;
1485
1486 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER) {
1487 return -EINVAL;
1488 }
1489
1490 ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER);
1491 status = clk_domain_construct_3x_prog(g, ppboardobj, size, pargs);
1492 if (status) {
1493 return -EINVAL;
1494 }
1495
1496 pdomain = (struct clk_domain_3x_master *)*ppboardobj;
1497
1498 pdomain->super.super.super.super.pmudatainit =
1499 _clk_domain_pmudatainit_3x_master;
1500 pdomain->super.super.super.clkdomainclkproglink =
1501 clkdomainclkproglink_3x_master;
1502
1503 pdomain->slave_idxs_mask = 0;
1504
1505 return status;
1506}
1507
1508static int clkdomainclkproglink_fixed(struct gk20a *g,
1509 struct clk_pmupstate *pclk,
1510 struct clk_domain *pdomain)
1511{
1512 nvgpu_log_info(g, " ");
1513 return 0;
1514}
1515
1516static int _clk_domain_pmudatainit_3x_fixed(struct gk20a *g,
1517 struct boardobj *board_obj_ptr,
1518 struct nv_pmu_boardobj *ppmudata)
1519{
1520 int status = 0;
1521 struct clk_domain_3x_fixed *pclk_domain_3x_fixed;
1522 struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set *pset;
1523
1524 nvgpu_log_info(g, " ");
1525
1526 status = _clk_domain_pmudatainit_3x(g, board_obj_ptr, ppmudata);
1527 if (status != 0) {
1528 return status;
1529 }
1530
1531 pclk_domain_3x_fixed = (struct clk_domain_3x_fixed *)board_obj_ptr;
1532
1533 pset = (struct nv_pmu_clk_clk_domain_3x_fixed_boardobj_set *)
1534 ppmudata;
1535
1536 pset->freq_mhz = pclk_domain_3x_fixed->freq_mhz;
1537
1538 return status;
1539}
1540
1541static int clk_domain_construct_3x_fixed(struct gk20a *g,
1542 struct boardobj **ppboardobj,
1543 u16 size, void *pargs)
1544{
1545 struct boardobj *ptmpobj = (struct boardobj *)pargs;
1546 struct clk_domain_3x_fixed *pdomain;
1547 struct clk_domain_3x_fixed *ptmpdomain =
1548 (struct clk_domain_3x_fixed *)pargs;
1549 int status = 0;
1550
1551 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED) {
1552 return -EINVAL;
1553 }
1554
1555 ptmpobj->type_mask |= BIT(CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED);
1556 status = clk_domain_construct_3x(g, ppboardobj, size, pargs);
1557 if (status) {
1558 return -EINVAL;
1559 }
1560
1561 pdomain = (struct clk_domain_3x_fixed *)*ppboardobj;
1562
1563 pdomain->super.super.super.pmudatainit =
1564 _clk_domain_pmudatainit_3x_fixed;
1565
1566 pdomain->super.super.clkdomainclkproglink =
1567 clkdomainclkproglink_fixed;
1568
1569 pdomain->freq_mhz = ptmpdomain->freq_mhz;
1570
1571 return status;
1572}
1573
1574static struct clk_domain *construct_clk_domain(struct gk20a *g, void *pargs)
1575{
1576 struct boardobj *board_obj_ptr = NULL;
1577 u32 status;
1578
1579 nvgpu_log_info(g, " %d", BOARDOBJ_GET_TYPE(pargs));
1580 switch (BOARDOBJ_GET_TYPE(pargs)) {
1581 case CTRL_CLK_CLK_DOMAIN_TYPE_3X_FIXED:
1582 status = clk_domain_construct_3x_fixed(g, &board_obj_ptr,
1583 sizeof(struct clk_domain_3x_fixed), pargs);
1584 break;
1585
1586 case CTRL_CLK_CLK_DOMAIN_TYPE_35_MASTER:
1587 status = clk_domain_construct_35_master(g, &board_obj_ptr,
1588 sizeof(struct clk_domain_35_master), pargs);
1589 break;
1590
1591
1592 case CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER:
1593 status = clk_domain_construct_3x_master(g, &board_obj_ptr,
1594 sizeof(struct clk_domain_3x_master), pargs);
1595 break;
1596
1597 case CTRL_CLK_CLK_DOMAIN_TYPE_35_SLAVE:
1598 status = clk_domain_construct_35_slave(g, &board_obj_ptr,
1599 sizeof(struct clk_domain_35_slave), pargs);
1600 break;
1601
1602 case CTRL_CLK_CLK_DOMAIN_TYPE_3X_SLAVE:
1603 status = clk_domain_construct_3x_slave(g, &board_obj_ptr,
1604 sizeof(struct clk_domain_3x_slave), pargs);
1605 break;
1606
1607 default:
1608 return NULL;
1609 }
1610
1611 if (status) {
1612 return NULL;
1613 }
1614
1615 nvgpu_log_info(g, " Done");
1616
1617 return (struct clk_domain *)board_obj_ptr;
1618}
1619
1620static int clk_domain_pmudatainit_super(struct gk20a *g,
1621 struct boardobj *board_obj_ptr,
1622 struct nv_pmu_boardobj *ppmudata)
1623{
1624 int status = 0;
1625 struct clk_domain *pclk_domain;
1626 struct nv_pmu_clk_clk_domain_boardobj_set *pset;
1627
1628 nvgpu_log_info(g, " ");
1629
1630 status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata);
1631 if (status != 0) {
1632 return status;
1633 }
1634
1635 pclk_domain = (struct clk_domain *)board_obj_ptr;
1636
1637 pset = (struct nv_pmu_clk_clk_domain_boardobj_set *)ppmudata;
1638
1639 pset->domain = pclk_domain->domain;
1640 pset->api_domain = pclk_domain->api_domain;
1641 pset->perf_domain_grp_idx = pclk_domain->perf_domain_grp_idx;
1642
1643 return status;
1644}
1645
1646int clk_domain_clk_prog_link(struct gk20a *g, struct clk_pmupstate *pclk)
1647{
1648 int status = 0;
1649 struct clk_domain *pdomain;
1650 u8 i;
1651
1652 /* Iterate over all CLK_DOMAINs and flatten their VF curves.*/
1653 BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super),
1654 struct clk_domain *, pdomain, i) {
1655 status = pdomain->clkdomainclkproglink(g, pclk, pdomain);
1656 if (status) {
1657 nvgpu_err(g,
1658 "error flattening VF for CLK DOMAIN - 0x%x",
1659 pdomain->domain);
1660 goto done;
1661 }
1662 }
1663
1664done:
1665 return status;
1666}