diff options
Diffstat (limited to 'include/volt/volt_rail.c')
-rw-r--r-- | include/volt/volt_rail.c | 485 |
1 files changed, 0 insertions, 485 deletions
diff --git a/include/volt/volt_rail.c b/include/volt/volt_rail.c deleted file mode 100644 index caf297f..0000000 --- a/include/volt/volt_rail.c +++ /dev/null | |||
@@ -1,485 +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 "boardobj/boardobjgrp.h" | ||
27 | #include "boardobj/boardobjgrp_e32.h" | ||
28 | #include "gp106/bios_gp106.h" | ||
29 | #include "ctrl/ctrlvolt.h" | ||
30 | |||
31 | #include "volt.h" | ||
32 | |||
33 | u8 volt_rail_volt_domain_convert_to_idx(struct gk20a *g, u8 volt_domain) | ||
34 | { | ||
35 | switch (g->perf_pmu.volt.volt_rail_metadata.volt_domain_hal) { | ||
36 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL: | ||
37 | switch (volt_domain) { | ||
38 | case CTRL_VOLT_DOMAIN_LOGIC: | ||
39 | return 0; | ||
40 | } | ||
41 | break; | ||
42 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL: | ||
43 | switch (volt_domain) { | ||
44 | case CTRL_VOLT_DOMAIN_LOGIC: | ||
45 | return 0; | ||
46 | case CTRL_VOLT_DOMAIN_SRAM: | ||
47 | return 1; | ||
48 | } | ||
49 | break; | ||
50 | } | ||
51 | |||
52 | return CTRL_BOARDOBJ_IDX_INVALID; | ||
53 | } | ||
54 | |||
55 | u32 volt_rail_volt_dev_register(struct gk20a *g, struct voltage_rail | ||
56 | *pvolt_rail, u8 volt_dev_idx, u8 operation_type) | ||
57 | { | ||
58 | u32 status = 0; | ||
59 | |||
60 | if (operation_type == CTRL_VOLT_DEVICE_OPERATION_TYPE_DEFAULT) { | ||
61 | if (pvolt_rail->volt_dev_idx_default == | ||
62 | CTRL_BOARDOBJ_IDX_INVALID) { | ||
63 | pvolt_rail->volt_dev_idx_default = volt_dev_idx; | ||
64 | } else { | ||
65 | status = -EINVAL; | ||
66 | goto exit; | ||
67 | } | ||
68 | } else if (operation_type == | ||
69 | CTRL_VOLT_VOLT_DEVICE_OPERATION_TYPE_IPC_VMIN) { | ||
70 | if (pvolt_rail->volt_dev_idx_ipc_vmin == | ||
71 | CTRL_BOARDOBJ_IDX_INVALID) { | ||
72 | pvolt_rail->volt_dev_idx_ipc_vmin = volt_dev_idx; | ||
73 | /* | ||
74 | * Exit on purpose as we do not want to register | ||
75 | * IPC_VMIN device against the rail to avoid | ||
76 | * setting current voltage instead of | ||
77 | * IPC Vmin voltage. | ||
78 | */ | ||
79 | goto exit; | ||
80 | } else { | ||
81 | status = -EINVAL; | ||
82 | goto exit; | ||
83 | } | ||
84 | } else { | ||
85 | goto exit; | ||
86 | } | ||
87 | |||
88 | status = boardobjgrpmask_bitset(&pvolt_rail->volt_dev_mask.super, | ||
89 | volt_dev_idx); | ||
90 | |||
91 | exit: | ||
92 | if (status) { | ||
93 | nvgpu_err(g, "Failed to register VOLTAGE_DEVICE"); | ||
94 | } | ||
95 | |||
96 | return status; | ||
97 | } | ||
98 | |||
99 | static u32 volt_rail_state_init(struct gk20a *g, | ||
100 | struct voltage_rail *pvolt_rail) | ||
101 | { | ||
102 | u32 status = 0; | ||
103 | u32 i; | ||
104 | |||
105 | pvolt_rail->volt_dev_idx_default = CTRL_BOARDOBJ_IDX_INVALID; | ||
106 | |||
107 | for (i = 0; i < CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES; i++) { | ||
108 | pvolt_rail->volt_delta_uv[i] = (int)NV_PMU_VOLT_VALUE_0V_IN_UV; | ||
109 | g->perf_pmu.volt.volt_rail_metadata.ext_rel_delta_uv[i] = | ||
110 | NV_PMU_VOLT_VALUE_0V_IN_UV; | ||
111 | } | ||
112 | |||
113 | pvolt_rail->volt_margin_limit_vfe_equ_mon_handle = | ||
114 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
115 | pvolt_rail->rel_limit_vfe_equ_mon_handle = | ||
116 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
117 | pvolt_rail->alt_rel_limit_vfe_equ_mon_handle = | ||
118 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
119 | pvolt_rail->ov_limit_vfe_equ_mon_handle = | ||
120 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
121 | |||
122 | status = boardobjgrpmask_e32_init(&pvolt_rail->volt_dev_mask, NULL); | ||
123 | if (status) { | ||
124 | nvgpu_err(g, | ||
125 | "Failed to initialize BOARDOBJGRPMASK of VOLTAGE_DEVICEs"); | ||
126 | } | ||
127 | |||
128 | return status; | ||
129 | } | ||
130 | |||
131 | static int volt_rail_init_pmudata_super(struct gk20a *g, | ||
132 | struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) | ||
133 | { | ||
134 | int status = 0; | ||
135 | struct voltage_rail *prail; | ||
136 | struct nv_pmu_volt_volt_rail_boardobj_set *rail_pmu_data; | ||
137 | u32 i; | ||
138 | |||
139 | nvgpu_log_info(g, " "); | ||
140 | |||
141 | status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); | ||
142 | if (status) { | ||
143 | return status; | ||
144 | } | ||
145 | |||
146 | prail = (struct voltage_rail *)board_obj_ptr; | ||
147 | rail_pmu_data = (struct nv_pmu_volt_volt_rail_boardobj_set *) | ||
148 | ppmudata; | ||
149 | |||
150 | rail_pmu_data->rel_limit_vfe_equ_idx = prail->rel_limit_vfe_equ_idx; | ||
151 | rail_pmu_data->alt_rel_limit_vfe_equ_idx = | ||
152 | prail->alt_rel_limit_vfe_equ_idx; | ||
153 | rail_pmu_data->ov_limit_vfe_equ_idx = prail->ov_limit_vfe_equ_idx; | ||
154 | rail_pmu_data->vmin_limit_vfe_equ_idx = prail->vmin_limit_vfe_equ_idx; | ||
155 | rail_pmu_data->volt_margin_limit_vfe_equ_idx = | ||
156 | prail->volt_margin_limit_vfe_equ_idx; | ||
157 | rail_pmu_data->pwr_equ_idx = prail->pwr_equ_idx; | ||
158 | rail_pmu_data->volt_dev_idx_default = prail->volt_dev_idx_default; | ||
159 | rail_pmu_data->volt_scale_exp_pwr_equ_idx = | ||
160 | prail->volt_scale_exp_pwr_equ_idx; | ||
161 | rail_pmu_data->volt_dev_idx_ipc_vmin = prail->volt_dev_idx_ipc_vmin; | ||
162 | |||
163 | for (i = 0; i < CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES; i++) { | ||
164 | rail_pmu_data->volt_delta_uv[i] = prail->volt_delta_uv[i] + | ||
165 | (int)g->perf_pmu.volt.volt_rail_metadata.ext_rel_delta_uv[i]; | ||
166 | } | ||
167 | |||
168 | status = boardobjgrpmask_export(&prail->volt_dev_mask.super, | ||
169 | prail->volt_dev_mask.super.bitcount, | ||
170 | &rail_pmu_data->volt_dev_mask.super); | ||
171 | if (status) { | ||
172 | nvgpu_err(g, | ||
173 | "Failed to export BOARDOBJGRPMASK of VOLTAGE_DEVICEs"); | ||
174 | } | ||
175 | |||
176 | nvgpu_log_info(g, "Done"); | ||
177 | |||
178 | return status; | ||
179 | } | ||
180 | |||
181 | static struct voltage_rail *construct_volt_rail(struct gk20a *g, void *pargs) | ||
182 | { | ||
183 | struct boardobj *board_obj_ptr = NULL; | ||
184 | struct voltage_rail *ptemp_rail = (struct voltage_rail *)pargs; | ||
185 | struct voltage_rail *board_obj_volt_rail_ptr = NULL; | ||
186 | int status; | ||
187 | |||
188 | nvgpu_log_info(g, " "); | ||
189 | status = boardobj_construct_super(g, &board_obj_ptr, | ||
190 | sizeof(struct voltage_rail), pargs); | ||
191 | if (status) { | ||
192 | return NULL; | ||
193 | } | ||
194 | |||
195 | board_obj_volt_rail_ptr = (struct voltage_rail *)board_obj_ptr; | ||
196 | /* override super class interface */ | ||
197 | board_obj_ptr->pmudatainit = volt_rail_init_pmudata_super; | ||
198 | |||
199 | board_obj_volt_rail_ptr->boot_voltage_uv = | ||
200 | ptemp_rail->boot_voltage_uv; | ||
201 | board_obj_volt_rail_ptr->rel_limit_vfe_equ_idx = | ||
202 | ptemp_rail->rel_limit_vfe_equ_idx; | ||
203 | board_obj_volt_rail_ptr->alt_rel_limit_vfe_equ_idx = | ||
204 | ptemp_rail->alt_rel_limit_vfe_equ_idx; | ||
205 | board_obj_volt_rail_ptr->ov_limit_vfe_equ_idx = | ||
206 | ptemp_rail->ov_limit_vfe_equ_idx; | ||
207 | board_obj_volt_rail_ptr->pwr_equ_idx = | ||
208 | ptemp_rail->pwr_equ_idx; | ||
209 | board_obj_volt_rail_ptr->boot_volt_vfe_equ_idx = | ||
210 | ptemp_rail->boot_volt_vfe_equ_idx; | ||
211 | board_obj_volt_rail_ptr->vmin_limit_vfe_equ_idx = | ||
212 | ptemp_rail->vmin_limit_vfe_equ_idx; | ||
213 | board_obj_volt_rail_ptr->volt_margin_limit_vfe_equ_idx = | ||
214 | ptemp_rail->volt_margin_limit_vfe_equ_idx; | ||
215 | board_obj_volt_rail_ptr->volt_scale_exp_pwr_equ_idx = | ||
216 | ptemp_rail->volt_scale_exp_pwr_equ_idx; | ||
217 | |||
218 | nvgpu_log_info(g, "Done"); | ||
219 | |||
220 | return (struct voltage_rail *)board_obj_ptr; | ||
221 | } | ||
222 | |||
223 | u8 volt_rail_vbios_volt_domain_convert_to_internal(struct gk20a *g, | ||
224 | u8 vbios_volt_domain) | ||
225 | { | ||
226 | switch (g->perf_pmu.volt.volt_rail_metadata.volt_domain_hal) { | ||
227 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL: | ||
228 | if (vbios_volt_domain == 0U) { | ||
229 | return CTRL_VOLT_DOMAIN_LOGIC; | ||
230 | } | ||
231 | break; | ||
232 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL: | ||
233 | switch (vbios_volt_domain) { | ||
234 | case 0: | ||
235 | return CTRL_VOLT_DOMAIN_LOGIC; | ||
236 | case 1: | ||
237 | return CTRL_VOLT_DOMAIN_SRAM; | ||
238 | } | ||
239 | break; | ||
240 | } | ||
241 | |||
242 | return CTRL_VOLT_DOMAIN_INVALID; | ||
243 | } | ||
244 | |||
245 | int volt_rail_pmu_setup(struct gk20a *g) | ||
246 | { | ||
247 | int status; | ||
248 | struct boardobjgrp *pboardobjgrp = NULL; | ||
249 | |||
250 | nvgpu_log_info(g, " "); | ||
251 | |||
252 | pboardobjgrp = &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super; | ||
253 | |||
254 | if (!pboardobjgrp->bconstructed) { | ||
255 | return -EINVAL; | ||
256 | } | ||
257 | |||
258 | status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); | ||
259 | |||
260 | nvgpu_log_info(g, "Done"); | ||
261 | return status; | ||
262 | } | ||
263 | |||
264 | static int volt_get_volt_rail_table(struct gk20a *g, | ||
265 | struct voltage_rail_metadata *pvolt_rail_metadata) | ||
266 | { | ||
267 | int status = 0; | ||
268 | u8 *volt_rail_table_ptr = NULL; | ||
269 | struct voltage_rail *prail = NULL; | ||
270 | struct vbios_voltage_rail_table_1x_header header = { 0 }; | ||
271 | struct vbios_voltage_rail_table_1x_entry entry = { 0 }; | ||
272 | u8 i; | ||
273 | u8 volt_domain; | ||
274 | u8 *entry_ptr; | ||
275 | union rail_type { | ||
276 | struct boardobj board_obj; | ||
277 | struct voltage_rail volt_rail; | ||
278 | } rail_type_data; | ||
279 | |||
280 | volt_rail_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g, | ||
281 | g->bios.perf_token, VOLTAGE_RAIL_TABLE); | ||
282 | if (volt_rail_table_ptr == NULL) { | ||
283 | status = -EINVAL; | ||
284 | goto done; | ||
285 | } | ||
286 | |||
287 | memcpy(&header, volt_rail_table_ptr, | ||
288 | sizeof(struct vbios_voltage_rail_table_1x_header)); | ||
289 | |||
290 | pvolt_rail_metadata->volt_domain_hal = (u8)header.volt_domain_hal; | ||
291 | |||
292 | for (i = 0; i < header.num_table_entries; i++) { | ||
293 | entry_ptr = (volt_rail_table_ptr + header.header_size + | ||
294 | (i * header.table_entry_size)); | ||
295 | |||
296 | memset(&rail_type_data, 0x0, sizeof(rail_type_data)); | ||
297 | |||
298 | memcpy(&entry, entry_ptr, | ||
299 | sizeof(struct vbios_voltage_rail_table_1x_entry)); | ||
300 | |||
301 | volt_domain = volt_rail_vbios_volt_domain_convert_to_internal(g, | ||
302 | i); | ||
303 | if (volt_domain == CTRL_VOLT_DOMAIN_INVALID) { | ||
304 | continue; | ||
305 | } | ||
306 | |||
307 | rail_type_data.board_obj.type = volt_domain; | ||
308 | rail_type_data.volt_rail.boot_voltage_uv = | ||
309 | (u32)entry.boot_voltage_uv; | ||
310 | rail_type_data.volt_rail.rel_limit_vfe_equ_idx = | ||
311 | (u8)entry.rel_limit_vfe_equ_idx; | ||
312 | rail_type_data.volt_rail.alt_rel_limit_vfe_equ_idx = | ||
313 | (u8)entry.alt_rel_limit_vfe_equidx; | ||
314 | rail_type_data.volt_rail.ov_limit_vfe_equ_idx = | ||
315 | (u8)entry.ov_limit_vfe_equ_idx; | ||
316 | |||
317 | if (header.table_entry_size >= | ||
318 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0C) { | ||
319 | rail_type_data.volt_rail.volt_scale_exp_pwr_equ_idx = | ||
320 | (u8)entry.volt_scale_exp_pwr_equ_idx; | ||
321 | } else { | ||
322 | rail_type_data.volt_rail.volt_scale_exp_pwr_equ_idx = | ||
323 | CTRL_BOARDOBJ_IDX_INVALID; | ||
324 | } | ||
325 | |||
326 | if (header.table_entry_size >= | ||
327 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0B) { | ||
328 | rail_type_data.volt_rail.volt_margin_limit_vfe_equ_idx = | ||
329 | (u8)entry.volt_margin_limit_vfe_equ_idx; | ||
330 | } else { | ||
331 | rail_type_data.volt_rail.volt_margin_limit_vfe_equ_idx = | ||
332 | CTRL_BOARDOBJ_IDX_INVALID; | ||
333 | } | ||
334 | |||
335 | if (header.table_entry_size >= | ||
336 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0A) { | ||
337 | rail_type_data.volt_rail.vmin_limit_vfe_equ_idx = | ||
338 | (u8)entry.vmin_limit_vfe_equ_idx; | ||
339 | } else { | ||
340 | rail_type_data.volt_rail.vmin_limit_vfe_equ_idx = | ||
341 | CTRL_BOARDOBJ_IDX_INVALID; | ||
342 | } | ||
343 | |||
344 | if (header.table_entry_size >= | ||
345 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_09) { | ||
346 | rail_type_data.volt_rail.boot_volt_vfe_equ_idx = | ||
347 | (u8)entry.boot_volt_vfe_equ_idx; | ||
348 | } else { | ||
349 | rail_type_data.volt_rail.boot_volt_vfe_equ_idx = | ||
350 | CTRL_BOARDOBJ_IDX_INVALID; | ||
351 | } | ||
352 | |||
353 | if (header.table_entry_size >= | ||
354 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_08) { | ||
355 | rail_type_data.volt_rail.pwr_equ_idx = | ||
356 | (u8)entry.pwr_equ_idx; | ||
357 | } else { | ||
358 | rail_type_data.volt_rail.pwr_equ_idx = | ||
359 | CTRL_PMGR_PWR_EQUATION_INDEX_INVALID; | ||
360 | } | ||
361 | |||
362 | prail = construct_volt_rail(g, &rail_type_data); | ||
363 | |||
364 | status = boardobjgrp_objinsert( | ||
365 | &pvolt_rail_metadata->volt_rails.super, | ||
366 | (struct boardobj *)prail, i); | ||
367 | } | ||
368 | |||
369 | done: | ||
370 | return status; | ||
371 | } | ||
372 | |||
373 | static int _volt_rail_devgrp_pmudata_instget(struct gk20a *g, | ||
374 | struct nv_pmu_boardobjgrp *pmuboardobjgrp, struct nv_pmu_boardobj | ||
375 | **ppboardobjpmudata, u8 idx) | ||
376 | { | ||
377 | struct nv_pmu_volt_volt_rail_boardobj_grp_set *pgrp_set = | ||
378 | (struct nv_pmu_volt_volt_rail_boardobj_grp_set *) | ||
379 | pmuboardobjgrp; | ||
380 | |||
381 | nvgpu_log_info(g, " "); | ||
382 | |||
383 | /*check whether pmuboardobjgrp has a valid boardobj in index*/ | ||
384 | if (((u32)BIT(idx) & | ||
385 | pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0U) { | ||
386 | return -EINVAL; | ||
387 | } | ||
388 | |||
389 | *ppboardobjpmudata = (struct nv_pmu_boardobj *) | ||
390 | &pgrp_set->objects[idx].data.board_obj; | ||
391 | nvgpu_log_info(g, " Done"); | ||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static int _volt_rail_devgrp_pmustatus_instget(struct gk20a *g, | ||
396 | void *pboardobjgrppmu, struct nv_pmu_boardobj_query | ||
397 | **ppboardobjpmustatus, u8 idx) | ||
398 | { | ||
399 | struct nv_pmu_volt_volt_rail_boardobj_grp_get_status *pgrp_get_status = | ||
400 | (struct nv_pmu_volt_volt_rail_boardobj_grp_get_status *) | ||
401 | pboardobjgrppmu; | ||
402 | |||
403 | /*check whether pmuboardobjgrp has a valid boardobj in index*/ | ||
404 | if (((u32)BIT(idx) & | ||
405 | pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0U) { | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | |||
409 | *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) | ||
410 | &pgrp_get_status->objects[idx].data.board_obj; | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | int volt_rail_sw_setup(struct gk20a *g) | ||
415 | { | ||
416 | int status = 0; | ||
417 | struct boardobjgrp *pboardobjgrp = NULL; | ||
418 | struct voltage_rail *pvolt_rail; | ||
419 | u8 i; | ||
420 | |||
421 | nvgpu_log_info(g, " "); | ||
422 | |||
423 | status = boardobjgrpconstruct_e32(g, | ||
424 | &g->perf_pmu.volt.volt_rail_metadata.volt_rails); | ||
425 | if (status) { | ||
426 | nvgpu_err(g, | ||
427 | "error creating boardobjgrp for volt rail, status - 0x%x", | ||
428 | status); | ||
429 | goto done; | ||
430 | } | ||
431 | |||
432 | pboardobjgrp = &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super; | ||
433 | |||
434 | pboardobjgrp->pmudatainstget = _volt_rail_devgrp_pmudata_instget; | ||
435 | pboardobjgrp->pmustatusinstget = _volt_rail_devgrp_pmustatus_instget; | ||
436 | |||
437 | g->perf_pmu.volt.volt_rail_metadata.pct_delta = | ||
438 | NV_PMU_VOLT_VALUE_0V_IN_UV; | ||
439 | |||
440 | /* Obtain Voltage Rail Table from VBIOS */ | ||
441 | status = volt_get_volt_rail_table(g, &g->perf_pmu.volt. | ||
442 | volt_rail_metadata); | ||
443 | if (status) { | ||
444 | goto done; | ||
445 | } | ||
446 | |||
447 | /* Populate data for the VOLT_RAIL PMU interface */ | ||
448 | BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, VOLT, VOLT_RAIL); | ||
449 | |||
450 | status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, | ||
451 | volt, VOLT, volt_rail, VOLT_RAIL); | ||
452 | if (status) { | ||
453 | nvgpu_err(g, | ||
454 | "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", | ||
455 | status); | ||
456 | goto done; | ||
457 | } | ||
458 | |||
459 | status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, | ||
460 | &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super, | ||
461 | volt, VOLT, volt_rail, VOLT_RAIL); | ||
462 | if (status) { | ||
463 | nvgpu_err(g, | ||
464 | "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", | ||
465 | status); | ||
466 | goto done; | ||
467 | } | ||
468 | |||
469 | /* update calibration to fuse */ | ||
470 | BOARDOBJGRP_FOR_EACH(&(g->perf_pmu.volt.volt_rail_metadata. | ||
471 | volt_rails.super), | ||
472 | struct voltage_rail *, pvolt_rail, i) { | ||
473 | status = volt_rail_state_init(g, pvolt_rail); | ||
474 | if (status) { | ||
475 | nvgpu_err(g, | ||
476 | "Failure while executing RAIL's state init railIdx = %d", | ||
477 | i); | ||
478 | goto done; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | done: | ||
483 | nvgpu_log_info(g, " done status %x", status); | ||
484 | return status; | ||
485 | } | ||