aboutsummaryrefslogtreecommitdiffstats
path: root/include/volt/volt_rail.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/volt/volt_rail.c')
-rw-r--r--include/volt/volt_rail.c485
1 files changed, 485 insertions, 0 deletions
diff --git a/include/volt/volt_rail.c b/include/volt/volt_rail.c
new file mode 100644
index 0000000..caf297f
--- /dev/null
+++ b/include/volt/volt_rail.c
@@ -0,0 +1,485 @@
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
33u8 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
55u32 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
91exit:
92 if (status) {
93 nvgpu_err(g, "Failed to register VOLTAGE_DEVICE");
94 }
95
96 return status;
97}
98
99static 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
131static 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
181static 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;