aboutsummaryrefslogtreecommitdiffstats
path: root/include/pmgr/pwrdev.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2023-06-28 18:24:25 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2023-06-28 18:24:25 -0400
commit01e6fac4d61fdd7fff5433942ec93fc2ea1e4df1 (patch)
tree4ef34501728a087be24f4ba0af90f91486bf780b /include/pmgr/pwrdev.c
parent306a03d18b305e4e573be3b2931978fa10679eb9 (diff)
Include nvgpu headers
These are needed to build on NVIDIA's Jetson boards for the time being. Only a couple structs are required, so it should be fairly easy to remove this dependency at some point in the future.
Diffstat (limited to 'include/pmgr/pwrdev.c')
-rw-r--r--include/pmgr/pwrdev.c319
1 files changed, 319 insertions, 0 deletions
diff --git a/include/pmgr/pwrdev.c b/include/pmgr/pwrdev.c
new file mode 100644
index 0000000..c1bf084
--- /dev/null
+++ b/include/pmgr/pwrdev.c
@@ -0,0 +1,319 @@
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 "pwrdev.h"
27#include "boardobj/boardobjgrp.h"
28#include "boardobj/boardobjgrp_e32.h"
29#include "gp106/bios_gp106.h"
30
31static int _pwr_device_pmudata_instget(struct gk20a *g,
32 struct nv_pmu_boardobjgrp *pmuboardobjgrp,
33 struct nv_pmu_boardobj **ppboardobjpmudata,
34 u8 idx)
35{
36 struct nv_pmu_pmgr_pwr_device_desc_table *ppmgrdevice =
37 (struct nv_pmu_pmgr_pwr_device_desc_table *)pmuboardobjgrp;
38
39 nvgpu_log_info(g, " ");
40
41 /*check whether pmuboardobjgrp has a valid boardobj in index*/
42 if (((u32)BIT(idx) &
43 ppmgrdevice->hdr.data.super.obj_mask.super.data[0]) == 0U) {
44 return -EINVAL;
45 }
46
47 *ppboardobjpmudata = (struct nv_pmu_boardobj *)
48 &ppmgrdevice->devices[idx].data.board_obj;
49
50 nvgpu_log_info(g, " Done");
51
52 return 0;
53}
54
55static int _pwr_domains_pmudatainit_ina3221(struct gk20a *g,
56 struct boardobj *board_obj_ptr,
57 struct nv_pmu_boardobj *ppmudata)
58{
59 struct nv_pmu_pmgr_pwr_device_desc_ina3221 *ina3221_desc;
60 struct pwr_device_ina3221 *ina3221;
61 int status = 0;
62 u32 indx;
63
64 status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata);
65 if (status) {
66 nvgpu_err(g,
67 "error updating pmu boardobjgrp for pwr domain 0x%x",
68 status);
69 goto done;
70 }
71
72 ina3221 = (struct pwr_device_ina3221 *)board_obj_ptr;
73 ina3221_desc = (struct nv_pmu_pmgr_pwr_device_desc_ina3221 *) ppmudata;
74
75 ina3221_desc->super.power_corr_factor = ina3221->super.power_corr_factor;
76 ina3221_desc->i2c_dev_idx = ina3221->super.i2c_dev_idx;
77 ina3221_desc->configuration = ina3221->configuration;
78 ina3221_desc->mask_enable = ina3221->mask_enable;
79 /* configure NV_PMU_THERM_EVENT_EXT_OVERT */
80 ina3221_desc->event_mask = (1 << 0);
81 ina3221_desc->curr_correct_m = ina3221->curr_correct_m;
82 ina3221_desc->curr_correct_b = ina3221->curr_correct_b;
83
84 for (indx = 0; indx < NV_PMU_PMGR_PWR_DEVICE_INA3221_CH_NUM; indx++) {
85 ina3221_desc->r_shuntm_ohm[indx] = ina3221->r_shuntm_ohm[indx];
86 }
87
88done:
89 return status;
90}
91
92static struct boardobj *construct_pwr_device(struct gk20a *g,
93 void *pargs, u16 pargs_size, u8 type)
94{
95 struct boardobj *board_obj_ptr = NULL;
96 int status;
97 u32 indx;
98 struct pwr_device_ina3221 *pwrdev;
99 struct pwr_device_ina3221 *ina3221 = (struct pwr_device_ina3221*)pargs;
100
101 status = boardobj_construct_super(g, &board_obj_ptr,
102 pargs_size, pargs);
103 if (status) {
104 return NULL;
105 }
106
107 pwrdev = (struct pwr_device_ina3221*)board_obj_ptr;
108
109 /* Set Super class interfaces */
110 board_obj_ptr->pmudatainit = _pwr_domains_pmudatainit_ina3221;
111 pwrdev->super.power_rail = ina3221->super.power_rail;
112 pwrdev->super.i2c_dev_idx = ina3221->super.i2c_dev_idx;
113 pwrdev->super.power_corr_factor = (1 << 12);
114 pwrdev->super.bIs_inforom_config = false;
115
116 /* Set INA3221-specific information */
117 pwrdev->configuration = ina3221->configuration;
118 pwrdev->mask_enable = ina3221->mask_enable;
119 pwrdev->gpio_function = ina3221->gpio_function;
120 pwrdev->curr_correct_m = ina3221->curr_correct_m;
121 pwrdev->curr_correct_b = ina3221->curr_correct_b;
122
123 for (indx = 0; indx < NV_PMU_PMGR_PWR_DEVICE_INA3221_CH_NUM; indx++) {
124 pwrdev->r_shuntm_ohm[indx] = ina3221->r_shuntm_ohm[indx];
125 }
126
127 nvgpu_log_info(g, " Done");
128
129 return board_obj_ptr;
130}
131
132static int devinit_get_pwr_device_table(struct gk20a *g,
133 struct pwr_devices *ppwrdeviceobjs)
134{
135 int status = 0;
136 u8 *pwr_device_table_ptr = NULL;
137 u8 *curr_pwr_device_table_ptr = NULL;
138 struct boardobj *boardobj;
139 struct pwr_sensors_2x_header pwr_sensor_table_header = { 0 };
140 struct pwr_sensors_2x_entry pwr_sensor_table_entry = { 0 };
141 u32 index;
142 u32 obj_index = 0;
143 u16 pwr_device_size;
144 union {
145 struct boardobj boardobj;
146 struct pwr_device pwrdev;
147 struct pwr_device_ina3221 ina3221;
148 } pwr_device_data;
149
150 nvgpu_log_info(g, " ");
151
152 pwr_device_table_ptr = (u8 *)nvgpu_bios_get_perf_table_ptrs(g,
153 g->bios.perf_token, POWER_SENSORS_TABLE);
154 if (pwr_device_table_ptr == NULL) {
155 status = -EINVAL;
156 goto done;
157 }
158
159 memcpy(&pwr_sensor_table_header, pwr_device_table_ptr,
160 VBIOS_POWER_SENSORS_2X_HEADER_SIZE_08);
161
162 if (pwr_sensor_table_header.version !=
163 VBIOS_POWER_SENSORS_VERSION_2X) {
164 status = -EINVAL;
165 goto done;
166 }
167
168 if (pwr_sensor_table_header.header_size <
169 VBIOS_POWER_SENSORS_2X_HEADER_SIZE_08) {
170 status = -EINVAL;
171 goto done;
172 }
173
174 if (pwr_sensor_table_header.table_entry_size !=
175 VBIOS_POWER_SENSORS_2X_ENTRY_SIZE_15) {
176 status = -EINVAL;
177 goto done;
178 }
179
180 curr_pwr_device_table_ptr = (pwr_device_table_ptr +
181 VBIOS_POWER_SENSORS_2X_HEADER_SIZE_08);
182
183 for (index = 0; index < pwr_sensor_table_header.num_table_entries; index++) {
184 bool use_fxp8_8 = false;
185 u8 i2c_dev_idx;
186 u8 device_type;
187
188 curr_pwr_device_table_ptr += (pwr_sensor_table_header.table_entry_size * index);
189
190 pwr_sensor_table_entry.flags0 = *curr_pwr_device_table_ptr;
191
192 memcpy(&pwr_sensor_table_entry.class_param0,
193 (curr_pwr_device_table_ptr + 1),
194 (VBIOS_POWER_SENSORS_2X_ENTRY_SIZE_15 - 1U));
195
196 device_type = (u8)BIOS_GET_FIELD(
197 pwr_sensor_table_entry.flags0,
198 NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS);
199
200 if (device_type == NV_VBIOS_POWER_SENSORS_2X_ENTRY_FLAGS0_CLASS_I2C) {
201 i2c_dev_idx = (u8)BIOS_GET_FIELD(
202 pwr_sensor_table_entry.class_param0,
203 NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_INDEX);
204 use_fxp8_8 = (u8)BIOS_GET_FIELD(
205 pwr_sensor_table_entry.class_param0,
206 NV_VBIOS_POWER_SENSORS_2X_ENTRY_CLASS_PARAM0_I2C_USE_FXP8_8);
207
208 pwr_device_data.ina3221.super.i2c_dev_idx = i2c_dev_idx;
209 pwr_device_data.ina3221.r_shuntm_ohm[0].use_fxp8_8 = use_fxp8_8;
210 pwr_device_data.ina3221.r_shuntm_ohm[1].use_fxp8_8 = use_fxp8_8;
211 pwr_device_data.ina3221.r_shuntm_ohm[2].use_fxp8_8 = use_fxp8_8;
212 pwr_device_data.ina3221.r_shuntm_ohm[0].rshunt_value =
213 (u16)BIOS_GET_FIELD(
214 pwr_sensor_table_entry.sensor_param0,
215 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT0_MOHM);
216
217 pwr_device_data.ina3221.r_shuntm_ohm[1].rshunt_value =
218 (u16)BIOS_GET_FIELD(
219 pwr_sensor_table_entry.sensor_param0,
220 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM0_INA3221_RSHUNT1_MOHM);
221
222 pwr_device_data.ina3221.r_shuntm_ohm[2].rshunt_value =
223 (u16)BIOS_GET_FIELD(
224 pwr_sensor_table_entry.sensor_param1,
225 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_RSHUNT2_MOHM);
226 pwr_device_data.ina3221.configuration =
227 (u16)BIOS_GET_FIELD(
228 pwr_sensor_table_entry.sensor_param1,
229 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM1_INA3221_CONFIGURATION);
230
231 pwr_device_data.ina3221.mask_enable =
232 (u16)BIOS_GET_FIELD(
233 pwr_sensor_table_entry.sensor_param2,
234 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_MASKENABLE);
235
236 pwr_device_data.ina3221.gpio_function =
237 (u8)BIOS_GET_FIELD(
238 pwr_sensor_table_entry.sensor_param2,
239 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM2_INA3221_GPIOFUNCTION);
240
241 pwr_device_data.ina3221.curr_correct_m =
242 (u16)BIOS_GET_FIELD(
243 pwr_sensor_table_entry.sensor_param3,
244 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_M);
245
246 pwr_device_data.ina3221.curr_correct_b =
247 (u16)BIOS_GET_FIELD(
248 pwr_sensor_table_entry.sensor_param3,
249 NV_VBIOS_POWER_SENSORS_2X_ENTRY_SENSOR_PARAM3_INA3221_CURR_CORRECT_B);
250
251 if (!pwr_device_data.ina3221.curr_correct_m) {
252 pwr_device_data.ina3221.curr_correct_m = (1 << 12);
253 }
254 pwr_device_size = sizeof(struct pwr_device_ina3221);
255 } else {
256 continue;
257 }
258
259 pwr_device_data.boardobj.type = CTRL_PMGR_PWR_DEVICE_TYPE_INA3221;
260 pwr_device_data.pwrdev.power_rail = (u8)0;
261
262 boardobj = construct_pwr_device(g, &pwr_device_data,
263 pwr_device_size, pwr_device_data.boardobj.type);
264
265 if (!boardobj) {
266 nvgpu_err(g,
267 "unable to create pwr device for %d type %d", index, pwr_device_data.boardobj.type);
268 status = -EINVAL;
269 goto done;
270 }
271
272 status = boardobjgrp_objinsert(&ppwrdeviceobjs->super.super,
273 boardobj, obj_index);
274
275 if (status) {
276 nvgpu_err(g,
277 "unable to insert pwr device boardobj for %d", index);
278 status = -EINVAL;
279 goto done;
280 }
281
282 ++obj_index;
283 }
284
285done:
286 nvgpu_log_info(g, " done status %x", status);
287 return status;
288}
289
290int pmgr_device_sw_setup(struct gk20a *g)
291{
292 int status;
293 struct boardobjgrp *pboardobjgrp = NULL;
294 struct pwr_devices *ppwrdeviceobjs;
295
296 /* Construct the Super Class and override the Interfaces */
297 status = boardobjgrpconstruct_e32(g, &g->pmgr_pmu.pmgr_deviceobjs.super);
298 if (status) {
299 nvgpu_err(g,
300 "error creating boardobjgrp for pmgr devices, status - 0x%x",
301 status);
302 goto done;
303 }
304
305 pboardobjgrp = &g->pmgr_pmu.pmgr_deviceobjs.super.super;
306 ppwrdeviceobjs = &(g->pmgr_pmu.pmgr_deviceobjs);
307
308 /* Override the Interfaces */
309 pboardobjgrp->pmudatainstget = _pwr_device_pmudata_instget;
310
311 status = devinit_get_pwr_device_table(g, ppwrdeviceobjs);
312 if (status) {
313 goto done;
314 }
315
316done:
317 nvgpu_log_info(g, " done status %x", status);
318 return status;
319}