diff options
author | Mahantesh Kumbar <mkumbar@nvidia.com> | 2016-09-19 01:37:46 -0400 |
---|---|---|
committer | Deepak Nibade <dnibade@nvidia.com> | 2016-12-27 04:56:50 -0500 |
commit | 173bdefc92e2e4ef8f1e7e6ead7f86e746bee935 (patch) | |
tree | 69d9a43a453e988c54927ade2f5ce04457eaf312 /drivers/gpu/nvgpu/volt/volt_rail.c | |
parent | db529935a5f50e9e683d44d2eb01d0d76a915792 (diff) |
gpu: nvgpu: add support for voltage config
- changes to read voltage tables from VBIOS
& create boardobj then send to pmu
- Rail, Device & Policy objects are read from VBIOS & created boardobjs
- RPC support to load, Set & get voltage.
JIRA DNVGPU-122
Change-Id: I61621a514eef9c081a64c4ab066f01dfc28f8402
Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com>
Reviewed-on: http://git-master/r/1222774
(cherry picked from commit 9da86d8c2c547623cf5f38c89afeb3f5bb1667ac)
Reviewed-on: http://git-master/r/1244656
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/volt/volt_rail.c')
-rw-r--r-- | drivers/gpu/nvgpu/volt/volt_rail.c | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/volt/volt_rail.c b/drivers/gpu/nvgpu/volt/volt_rail.c new file mode 100644 index 00000000..87b85160 --- /dev/null +++ b/drivers/gpu/nvgpu/volt/volt_rail.c | |||
@@ -0,0 +1,438 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include "gk20a/gk20a.h" | ||
15 | #include "include/bios.h" | ||
16 | #include "boardobj/boardobjgrp.h" | ||
17 | #include "boardobj/boardobjgrp_e32.h" | ||
18 | #include "pmuif/gpmuifboardobj.h" | ||
19 | #include "gm206/bios_gm206.h" | ||
20 | #include "ctrl/ctrlvolt.h" | ||
21 | #include "gk20a/pmu_gk20a.h" | ||
22 | |||
23 | #include "pmuif/gpmuifperfvfe.h" | ||
24 | #include "include/bios.h" | ||
25 | #include "volt.h" | ||
26 | |||
27 | u8 volt_rail_volt_domain_convert_to_idx(struct gk20a *g, u8 volt_domain) | ||
28 | { | ||
29 | switch (g->perf_pmu.volt.volt_rail_metadata.volt_domain_hal) { | ||
30 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL: | ||
31 | if (volt_domain == CTRL_BOARDOBJ_IDX_INVALID) | ||
32 | return 0; | ||
33 | break; | ||
34 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL: | ||
35 | switch (volt_domain) { | ||
36 | case CTRL_VOLT_DOMAIN_LOGIC: | ||
37 | return 0; | ||
38 | case CTRL_VOLT_DOMAIN_SRAM: | ||
39 | return 1; | ||
40 | } | ||
41 | break; | ||
42 | } | ||
43 | |||
44 | return CTRL_BOARDOBJ_IDX_INVALID; | ||
45 | } | ||
46 | |||
47 | u32 volt_rail_volt_dev_register(struct gk20a *g, struct voltage_rail | ||
48 | *pvolt_rail, u8 volt_dev_idx, u8 operation_type) | ||
49 | { | ||
50 | u32 status = 0; | ||
51 | |||
52 | if (operation_type == CTRL_VOLT_DEVICE_OPERATION_TYPE_DEFAULT) { | ||
53 | if (pvolt_rail->volt_dev_idx_default == | ||
54 | CTRL_BOARDOBJ_IDX_INVALID) { | ||
55 | pvolt_rail->volt_dev_idx_default = volt_dev_idx; | ||
56 | } else { | ||
57 | status = -EINVAL; | ||
58 | goto exit; | ||
59 | } | ||
60 | } else { | ||
61 | goto exit; | ||
62 | } | ||
63 | |||
64 | status = boardobjgrpmask_bitset(&pvolt_rail->volt_dev_mask.super, | ||
65 | volt_dev_idx); | ||
66 | |||
67 | exit: | ||
68 | if (status) | ||
69 | gk20a_err(dev_from_gk20a(g), "Failed to register VOLTAGE_DEVICE"); | ||
70 | |||
71 | return status; | ||
72 | } | ||
73 | |||
74 | static u32 volt_rail_state_init(struct gk20a *g, | ||
75 | struct voltage_rail *pvolt_rail) | ||
76 | { | ||
77 | u32 status = 0; | ||
78 | u32 i; | ||
79 | |||
80 | pvolt_rail->volt_dev_idx_default = CTRL_BOARDOBJ_IDX_INVALID; | ||
81 | |||
82 | for (i = 0; i < CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES; i++) { | ||
83 | pvolt_rail->volt_delta_uv[i] = NV_PMU_VOLT_VALUE_0V_IN_UV; | ||
84 | g->perf_pmu.volt.volt_rail_metadata.ext_rel_delta_uv[i] = | ||
85 | NV_PMU_VOLT_VALUE_0V_IN_UV; | ||
86 | } | ||
87 | |||
88 | pvolt_rail->volt_margin_limit_vfe_equ_mon_handle = | ||
89 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
90 | pvolt_rail->rel_limit_vfe_equ_mon_handle = | ||
91 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
92 | pvolt_rail->alt_rel_limit_vfe_equ_mon_handle = | ||
93 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
94 | pvolt_rail->ov_limit_vfe_equ_mon_handle = | ||
95 | NV_PMU_PERF_RPC_VFE_EQU_MONITOR_COUNT_MAX; | ||
96 | |||
97 | status = boardobjgrpmask_e32_init(&pvolt_rail->volt_dev_mask, NULL); | ||
98 | if (status) { | ||
99 | gk20a_err(dev_from_gk20a(g), | ||
100 | "Failed to initialize BOARDOBJGRPMASK of VOLTAGE_DEVICEs"); | ||
101 | } | ||
102 | |||
103 | return status; | ||
104 | } | ||
105 | |||
106 | static u32 volt_rail_init_pmudata_super(struct gk20a *g, | ||
107 | struct boardobj *board_obj_ptr, struct nv_pmu_boardobj *ppmudata) | ||
108 | { | ||
109 | u32 status = 0; | ||
110 | struct voltage_rail *prail; | ||
111 | struct nv_pmu_volt_volt_rail_boardobj_set *rail_pmu_data; | ||
112 | u32 i; | ||
113 | |||
114 | gk20a_dbg_info(""); | ||
115 | |||
116 | status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata); | ||
117 | if (status) | ||
118 | return status; | ||
119 | |||
120 | prail = (struct voltage_rail *)board_obj_ptr; | ||
121 | rail_pmu_data = (struct nv_pmu_volt_volt_rail_boardobj_set *) | ||
122 | ppmudata; | ||
123 | |||
124 | rail_pmu_data->rel_limit_vfe_equ_idx = prail->rel_limit_vfe_equ_idx; | ||
125 | rail_pmu_data->alt_rel_limit_vfe_equ_idx = | ||
126 | prail->alt_rel_limit_vfe_equ_idx; | ||
127 | rail_pmu_data->ov_limit_vfe_equ_idx = prail->ov_limit_vfe_equ_idx; | ||
128 | rail_pmu_data->vmin_limit_vfe_equ_idx = prail->vmin_limit_vfe_equ_idx; | ||
129 | rail_pmu_data->volt_margin_limit_vfe_equ_idx = | ||
130 | prail->volt_margin_limit_vfe_equ_idx; | ||
131 | rail_pmu_data->pwr_equ_idx = prail->pwr_equ_idx; | ||
132 | rail_pmu_data->volt_dev_idx_default = prail->volt_dev_idx_default; | ||
133 | |||
134 | for (i = 0; i < CTRL_VOLT_RAIL_VOLT_DELTA_MAX_ENTRIES; i++) { | ||
135 | rail_pmu_data->volt_delta_uv[i] = prail->volt_delta_uv[i] + | ||
136 | g->perf_pmu.volt.volt_rail_metadata.ext_rel_delta_uv[i]; | ||
137 | } | ||
138 | |||
139 | status = boardobjgrpmask_export(&prail->volt_dev_mask.super, | ||
140 | prail->volt_dev_mask.super.bitcount, | ||
141 | &rail_pmu_data->volt_dev_mask.super); | ||
142 | if (status) | ||
143 | gk20a_err(dev_from_gk20a(g), | ||
144 | "Failed to export BOARDOBJGRPMASK of VOLTAGE_DEVICEs"); | ||
145 | |||
146 | gk20a_dbg_info("Done"); | ||
147 | |||
148 | return status; | ||
149 | } | ||
150 | |||
151 | static struct voltage_rail *construct_volt_rail(struct gk20a *g, void *pargs) | ||
152 | { | ||
153 | struct boardobj *board_obj_ptr = NULL; | ||
154 | struct voltage_rail *ptemp_rail = (struct voltage_rail *)pargs; | ||
155 | struct voltage_rail *board_obj_volt_rail_ptr = NULL; | ||
156 | u32 status; | ||
157 | |||
158 | gk20a_dbg_info(""); | ||
159 | status = boardobj_construct_super(g, &board_obj_ptr, | ||
160 | sizeof(struct voltage_rail), pargs); | ||
161 | if (status) | ||
162 | return NULL; | ||
163 | |||
164 | board_obj_volt_rail_ptr = (struct voltage_rail *)board_obj_ptr; | ||
165 | /* override super class interface */ | ||
166 | board_obj_ptr->pmudatainit = volt_rail_init_pmudata_super; | ||
167 | |||
168 | board_obj_volt_rail_ptr->boot_voltage_uv = | ||
169 | ptemp_rail->boot_voltage_uv; | ||
170 | board_obj_volt_rail_ptr->rel_limit_vfe_equ_idx = | ||
171 | ptemp_rail->rel_limit_vfe_equ_idx; | ||
172 | board_obj_volt_rail_ptr->alt_rel_limit_vfe_equ_idx = | ||
173 | ptemp_rail->alt_rel_limit_vfe_equ_idx; | ||
174 | board_obj_volt_rail_ptr->ov_limit_vfe_equ_idx = | ||
175 | ptemp_rail->ov_limit_vfe_equ_idx; | ||
176 | board_obj_volt_rail_ptr->pwr_equ_idx = | ||
177 | ptemp_rail->pwr_equ_idx; | ||
178 | board_obj_volt_rail_ptr->boot_volt_vfe_equ_idx = | ||
179 | ptemp_rail->boot_volt_vfe_equ_idx; | ||
180 | board_obj_volt_rail_ptr->vmin_limit_vfe_equ_idx = | ||
181 | ptemp_rail->vmin_limit_vfe_equ_idx; | ||
182 | board_obj_volt_rail_ptr->volt_margin_limit_vfe_equ_idx = | ||
183 | ptemp_rail->volt_margin_limit_vfe_equ_idx; | ||
184 | |||
185 | gk20a_dbg_info("Done"); | ||
186 | |||
187 | return (struct voltage_rail *)board_obj_ptr; | ||
188 | } | ||
189 | |||
190 | u8 volt_rail_vbios_volt_domain_convert_to_internal(struct gk20a *g, | ||
191 | u8 vbios_volt_domain) | ||
192 | { | ||
193 | switch (g->perf_pmu.volt.volt_rail_metadata.volt_domain_hal) { | ||
194 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SINGLE_RAIL: | ||
195 | if (vbios_volt_domain == 0) | ||
196 | return CTRL_VOLT_DOMAIN_LOGIC; | ||
197 | break; | ||
198 | case CTRL_VOLT_DOMAIN_HAL_GP10X_SPLIT_RAIL: | ||
199 | switch (vbios_volt_domain) { | ||
200 | case 0: | ||
201 | return CTRL_VOLT_DOMAIN_LOGIC; | ||
202 | case 1: | ||
203 | return CTRL_VOLT_DOMAIN_SRAM; | ||
204 | } | ||
205 | break; | ||
206 | } | ||
207 | |||
208 | return CTRL_VOLT_DOMAIN_INVALID; | ||
209 | } | ||
210 | |||
211 | u32 volt_rail_pmu_setup(struct gk20a *g) | ||
212 | { | ||
213 | u32 status; | ||
214 | struct boardobjgrp *pboardobjgrp = NULL; | ||
215 | |||
216 | gk20a_dbg_info(""); | ||
217 | |||
218 | pboardobjgrp = &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super; | ||
219 | |||
220 | if (!pboardobjgrp->bconstructed) | ||
221 | return -EINVAL; | ||
222 | |||
223 | status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); | ||
224 | |||
225 | gk20a_dbg_info("Done"); | ||
226 | return status; | ||
227 | } | ||
228 | |||
229 | static u32 volt_get_volt_rail_table(struct gk20a *g, | ||
230 | struct voltage_rail_metadata *pvolt_rail_metadata) | ||
231 | { | ||
232 | u32 status = 0; | ||
233 | u8 *volt_rail_table_ptr = NULL; | ||
234 | struct voltage_rail *prail = NULL; | ||
235 | struct vbios_voltage_rail_table_1x_header header = { 0 }; | ||
236 | struct vbios_voltage_rail_table_1x_entry entry = { 0 }; | ||
237 | u8 i; | ||
238 | u8 volt_domain; | ||
239 | u8 *entry_ptr; | ||
240 | union rail_type { | ||
241 | struct boardobj board_obj; | ||
242 | struct voltage_rail volt_rail; | ||
243 | } rail_type_data; | ||
244 | |||
245 | if (g->ops.bios.get_perf_table_ptrs) { | ||
246 | volt_rail_table_ptr = (u8 *)g->ops.bios.get_perf_table_ptrs(g, | ||
247 | g->bios.perf_token, VOLTAGE_RAIL_TABLE); | ||
248 | if (volt_rail_table_ptr == NULL) { | ||
249 | status = -EINVAL; | ||
250 | goto done; | ||
251 | } | ||
252 | } else { | ||
253 | status = -EINVAL; | ||
254 | goto done; | ||
255 | } | ||
256 | |||
257 | memcpy(&header, volt_rail_table_ptr, | ||
258 | sizeof(struct vbios_voltage_rail_table_1x_header)); | ||
259 | |||
260 | pvolt_rail_metadata->volt_domain_hal = (u8)header.volt_domain_hal; | ||
261 | |||
262 | for (i = 0; i < header.num_table_entries; i++) { | ||
263 | entry_ptr = (volt_rail_table_ptr + header.header_size + | ||
264 | (i * header.table_entry_size)); | ||
265 | |||
266 | memset(&rail_type_data, 0x0, sizeof(rail_type_data)); | ||
267 | |||
268 | memcpy(&entry, entry_ptr, | ||
269 | sizeof(struct vbios_voltage_rail_table_1x_entry)); | ||
270 | |||
271 | volt_domain = volt_rail_vbios_volt_domain_convert_to_internal(g, | ||
272 | i); | ||
273 | if (volt_domain == CTRL_VOLT_DOMAIN_INVALID) | ||
274 | continue; | ||
275 | |||
276 | rail_type_data.board_obj.type = volt_domain; | ||
277 | rail_type_data.volt_rail.boot_voltage_uv = | ||
278 | (u32)entry.boot_voltage_uv; | ||
279 | rail_type_data.volt_rail.rel_limit_vfe_equ_idx = | ||
280 | (u8)entry.rel_limit_vfe_equ_idx; | ||
281 | rail_type_data.volt_rail.alt_rel_limit_vfe_equ_idx = | ||
282 | (u8)entry.alt_rel_limit_vfe_equidx; | ||
283 | rail_type_data.volt_rail.ov_limit_vfe_equ_idx = | ||
284 | (u8)entry.ov_limit_vfe_equ_idx; | ||
285 | |||
286 | if (header.table_entry_size >= | ||
287 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0B) | ||
288 | rail_type_data.volt_rail.volt_margin_limit_vfe_equ_idx = | ||
289 | (u8)entry.volt_margin_limit_vfe_equ_idx; | ||
290 | else | ||
291 | rail_type_data.volt_rail.volt_margin_limit_vfe_equ_idx = | ||
292 | CTRL_BOARDOBJ_IDX_INVALID; | ||
293 | |||
294 | if (header.table_entry_size >= | ||
295 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_0A) | ||
296 | rail_type_data.volt_rail.vmin_limit_vfe_equ_idx = | ||
297 | (u8)entry.vmin_limit_vfe_equ_idx; | ||
298 | else | ||
299 | rail_type_data.volt_rail.vmin_limit_vfe_equ_idx = | ||
300 | CTRL_BOARDOBJ_IDX_INVALID; | ||
301 | |||
302 | if (header.table_entry_size >= | ||
303 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_09) | ||
304 | rail_type_data.volt_rail.boot_volt_vfe_equ_idx = | ||
305 | (u8)entry.boot_volt_vfe_equ_idx; | ||
306 | else | ||
307 | rail_type_data.volt_rail.boot_volt_vfe_equ_idx = | ||
308 | CTRL_BOARDOBJ_IDX_INVALID; | ||
309 | |||
310 | if (header.table_entry_size >= | ||
311 | NV_VBIOS_VOLTAGE_RAIL_1X_ENTRY_SIZE_08) | ||
312 | rail_type_data.volt_rail.pwr_equ_idx = | ||
313 | (u8)entry.pwr_equ_idx; | ||
314 | else | ||
315 | rail_type_data.volt_rail.pwr_equ_idx = | ||
316 | CTRL_PMGR_PWR_EQUATION_INDEX_INVALID; | ||
317 | |||
318 | prail = construct_volt_rail(g, &rail_type_data); | ||
319 | |||
320 | status = boardobjgrp_objinsert( | ||
321 | &pvolt_rail_metadata->volt_rails.super, | ||
322 | (struct boardobj *)prail, i); | ||
323 | } | ||
324 | |||
325 | done: | ||
326 | return status; | ||
327 | } | ||
328 | |||
329 | static u32 _volt_rail_devgrp_pmudata_instget(struct gk20a *g, | ||
330 | struct nv_pmu_boardobjgrp *pmuboardobjgrp, struct nv_pmu_boardobj | ||
331 | **ppboardobjpmudata, u8 idx) | ||
332 | { | ||
333 | struct nv_pmu_volt_volt_rail_boardobj_grp_set *pgrp_set = | ||
334 | (struct nv_pmu_volt_volt_rail_boardobj_grp_set *) | ||
335 | pmuboardobjgrp; | ||
336 | |||
337 | gk20a_dbg_info(""); | ||
338 | |||
339 | /*check whether pmuboardobjgrp has a valid boardobj in index*/ | ||
340 | if (((u32)BIT(idx) & | ||
341 | pgrp_set->hdr.data.super.obj_mask.super.data[0]) == 0) | ||
342 | return -EINVAL; | ||
343 | |||
344 | *ppboardobjpmudata = (struct nv_pmu_boardobj *) | ||
345 | &pgrp_set->objects[idx].data.board_obj; | ||
346 | gk20a_dbg_info(" Done"); | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static u32 _volt_rail_devgrp_pmustatus_instget(struct gk20a *g, | ||
351 | void *pboardobjgrppmu, struct nv_pmu_boardobj_query | ||
352 | **ppboardobjpmustatus, u8 idx) | ||
353 | { | ||
354 | struct nv_pmu_volt_volt_rail_boardobj_grp_get_status *pgrp_get_status = | ||
355 | (struct nv_pmu_volt_volt_rail_boardobj_grp_get_status *) | ||
356 | pboardobjgrppmu; | ||
357 | |||
358 | /*check whether pmuboardobjgrp has a valid boardobj in index*/ | ||
359 | if (((u32)BIT(idx) & | ||
360 | pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0) | ||
361 | return -EINVAL; | ||
362 | |||
363 | *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) | ||
364 | &pgrp_get_status->objects[idx].data.board_obj; | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | u32 volt_rail_sw_setup(struct gk20a *g) | ||
369 | { | ||
370 | u32 status = 0; | ||
371 | struct boardobjgrp *pboardobjgrp = NULL; | ||
372 | struct voltage_rail *pvolt_rail; | ||
373 | u8 i; | ||
374 | |||
375 | gk20a_dbg_info(""); | ||
376 | |||
377 | status = boardobjgrpconstruct_e32(&g->perf_pmu.volt.volt_rail_metadata. | ||
378 | volt_rails); | ||
379 | if (status) { | ||
380 | gk20a_err(dev_from_gk20a(g), | ||
381 | "error creating boardobjgrp for volt rail, status - 0x%x", | ||
382 | status); | ||
383 | goto done; | ||
384 | } | ||
385 | |||
386 | pboardobjgrp = &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super; | ||
387 | |||
388 | pboardobjgrp->pmudatainstget = _volt_rail_devgrp_pmudata_instget; | ||
389 | pboardobjgrp->pmustatusinstget = _volt_rail_devgrp_pmustatus_instget; | ||
390 | |||
391 | g->perf_pmu.volt.volt_rail_metadata.pct_delta = | ||
392 | NV_PMU_VOLT_VALUE_0V_IN_UV; | ||
393 | |||
394 | /* Obtain Voltage Rail Table from VBIOS */ | ||
395 | status = volt_get_volt_rail_table(g, &g->perf_pmu.volt. | ||
396 | volt_rail_metadata); | ||
397 | if (status) | ||
398 | goto done; | ||
399 | |||
400 | /* Populate data for the VOLT_RAIL PMU interface */ | ||
401 | BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, VOLT, VOLT_RAIL); | ||
402 | |||
403 | status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, | ||
404 | volt, VOLT, volt_rail, VOLT_RAIL); | ||
405 | if (status) { | ||
406 | gk20a_err(dev_from_gk20a(g), | ||
407 | "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", | ||
408 | status); | ||
409 | goto done; | ||
410 | } | ||
411 | |||
412 | status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, | ||
413 | &g->perf_pmu.volt.volt_rail_metadata.volt_rails.super, | ||
414 | volt, VOLT, volt_rail, VOLT_RAIL); | ||
415 | if (status) { | ||
416 | gk20a_err(dev_from_gk20a(g), | ||
417 | "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", | ||
418 | status); | ||
419 | goto done; | ||
420 | } | ||
421 | |||
422 | /* update calibration to fuse */ | ||
423 | BOARDOBJGRP_FOR_EACH(&(g->perf_pmu.volt.volt_rail_metadata. | ||
424 | volt_rails.super), | ||
425 | struct voltage_rail *, pvolt_rail, i) { | ||
426 | status = volt_rail_state_init(g, pvolt_rail); | ||
427 | if (status) { | ||
428 | gk20a_err(dev_from_gk20a(g), | ||
429 | "Failure while executing RAIL's state init railIdx = %d", | ||
430 | i); | ||
431 | goto done; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | done: | ||
436 | gk20a_dbg_info(" done status %x", status); | ||
437 | return status; | ||
438 | } | ||