aboutsummaryrefslogtreecommitdiffstats
path: root/include/pmgr/pwrpolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/pmgr/pwrpolicy.c')
-rw-r--r--include/pmgr/pwrpolicy.c782
1 files changed, 782 insertions, 0 deletions
diff --git a/include/pmgr/pwrpolicy.c b/include/pmgr/pwrpolicy.c
new file mode 100644
index 0000000..3bf6f32
--- /dev/null
+++ b/include/pmgr/pwrpolicy.c
@@ -0,0 +1,782 @@
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/bug.h>
25#include <nvgpu/gk20a.h>
26
27#include "pwrpolicy.h"
28#include "boardobj/boardobjgrp.h"
29#include "boardobj/boardobjgrp_e32.h"
30#include "gp106/bios_gp106.h"
31
32#define _pwr_policy_limitarboutputget_helper(p_limit_arb) (p_limit_arb)->output
33#define _pwr_policy_limitdeltaapply(limit, delta) ((u32)max(((s32)limit) + (delta), 0))
34
35static u32 _pwr_policy_limitarbinputset_helper(struct gk20a *g,
36 struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb,
37 u8 client_idx,
38 u32 limit_value)
39{
40 u8 indx;
41 bool b_found = false;
42 u32 status = 0;
43 u32 output = limit_value;
44
45 for (indx = 0; indx< p_limit_arb->num_inputs; indx++) {
46 if (p_limit_arb->inputs[indx].pwr_policy_idx == client_idx) {
47 p_limit_arb->inputs[indx].limit_value = limit_value;
48 b_found = true;
49 } else if (p_limit_arb->b_arb_max) {
50 output = max(output, p_limit_arb->inputs[indx].limit_value);
51 } else {
52 output = min(output, p_limit_arb->inputs[indx].limit_value);
53 }
54 }
55
56 if (!b_found) {
57 if (p_limit_arb->num_inputs <
58 CTRL_PMGR_PWR_POLICY_MAX_LIMIT_INPUTS) {
59 p_limit_arb->inputs[
60 p_limit_arb->num_inputs].pwr_policy_idx = client_idx;
61 p_limit_arb->inputs[
62 p_limit_arb->num_inputs].limit_value = limit_value;
63 p_limit_arb->num_inputs++;
64 } else {
65 nvgpu_err(g, "No entries remaining for clientIdx=%d",
66 client_idx);
67 status = -EINVAL;
68 }
69 }
70
71 if (!status) {
72 p_limit_arb->output = output;
73 }
74
75 return status;
76}
77
78static u32 _pwr_policy_limitid_translate(struct gk20a *g,
79 struct pwr_policy *ppolicy,
80 enum pwr_policy_limit_id limit_id,
81 struct ctrl_pmgr_pwr_policy_limit_arbitration **p_limit_arb,
82 struct ctrl_pmgr_pwr_policy_limit_arbitration **p_limit_arb_sec)
83{
84 u32 status = 0;
85
86 switch (limit_id) {
87 case PWR_POLICY_LIMIT_ID_MIN:
88 *p_limit_arb = &ppolicy->limit_arb_min;
89 break;
90
91 case PWR_POLICY_LIMIT_ID_RATED:
92 *p_limit_arb = &ppolicy->limit_arb_rated;
93
94 if (p_limit_arb_sec != NULL) {
95 *p_limit_arb_sec = &ppolicy->limit_arb_curr;
96 }
97 break;
98
99 case PWR_POLICY_LIMIT_ID_MAX:
100 *p_limit_arb = &ppolicy->limit_arb_max;
101 break;
102
103 case PWR_POLICY_LIMIT_ID_CURR:
104 *p_limit_arb = &ppolicy->limit_arb_curr;
105 break;
106
107 case PWR_POLICY_LIMIT_ID_BATT:
108 *p_limit_arb = &ppolicy->limit_arb_batt;
109 break;
110
111 default:
112 nvgpu_err(g, "Unsupported limitId=%d",
113 limit_id);
114 status = -EINVAL;
115 break;
116 }
117
118 return status;
119}
120
121static u32 _pwr_policy_limitarbinputset(struct gk20a *g,
122 struct pwr_policy *ppolicy,
123 enum pwr_policy_limit_id limit_id,
124 u8 client_idx,
125 u32 limit)
126{
127 u32 status = 0;
128 struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb = NULL;
129 struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb_sec = NULL;
130
131 status = _pwr_policy_limitid_translate(g,
132 ppolicy,
133 limit_id,
134 &p_limit_arb,
135 &p_limit_arb_sec);
136 if (status) {
137 goto exit;
138 }
139
140 status = _pwr_policy_limitarbinputset_helper(g, p_limit_arb, client_idx, limit);
141 if (status) {
142 nvgpu_err(g,
143 "Error setting client limit value: status=0x%08x, limitId=0x%x, clientIdx=0x%x, limit=%d",
144 status, limit_id, client_idx, limit);
145 goto exit;
146 }
147
148 if (NULL != p_limit_arb_sec) {
149 status = _pwr_policy_limitarbinputset_helper(g, p_limit_arb_sec,
150 CTRL_PMGR_PWR_POLICY_LIMIT_INPUT_CLIENT_IDX_RM,
151 _pwr_policy_limitarboutputget_helper(p_limit_arb));
152 }
153
154exit:
155 return status;
156}
157
158static inline void _pwr_policy_limitarbconstruct(
159 struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb,
160 bool b_arb_max)
161{
162 p_limit_arb->num_inputs = 0;
163 p_limit_arb->b_arb_max = b_arb_max;
164}
165
166static u32 _pwr_policy_limitarboutputget(struct gk20a *g,
167 struct pwr_policy *ppolicy,
168 enum pwr_policy_limit_id limit_id)
169{
170 u32 status = 0;
171 struct ctrl_pmgr_pwr_policy_limit_arbitration *p_limit_arb = NULL;
172
173 status = _pwr_policy_limitid_translate(g,
174 ppolicy,
175 limit_id,
176 &p_limit_arb,
177 NULL);
178 if (status) {
179 return 0;
180 }
181
182 return _pwr_policy_limitarboutputget_helper(p_limit_arb);
183}
184
185static int _pwr_domains_pmudatainit_hw_threshold(struct gk20a *g,
186 struct boardobj *board_obj_ptr,
187 struct nv_pmu_boardobj *ppmudata)
188{
189 struct nv_pmu_pmgr_pwr_policy_hw_threshold *pmu_hw_threshold_data;
190 struct pwr_policy_hw_threshold *p_hw_threshold;
191 struct pwr_policy *p_pwr_policy;
192 struct nv_pmu_pmgr_pwr_policy *pmu_pwr_policy;
193 int status = 0;
194
195 status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata);
196 if (status) {
197 nvgpu_err(g,
198 "error updating pmu boardobjgrp for pwr sensor 0x%x",
199 status);
200 status = -ENOMEM;
201 goto done;
202 }
203
204 p_hw_threshold = (struct pwr_policy_hw_threshold *)board_obj_ptr;
205 pmu_hw_threshold_data = (struct nv_pmu_pmgr_pwr_policy_hw_threshold *) ppmudata;
206 pmu_pwr_policy = (struct nv_pmu_pmgr_pwr_policy *) ppmudata;
207 p_pwr_policy = (struct pwr_policy *)&(p_hw_threshold->super.super);
208
209 pmu_pwr_policy->ch_idx = 0;
210 pmu_pwr_policy->limit_unit = p_pwr_policy->limit_unit;
211 pmu_pwr_policy->num_limit_inputs = p_pwr_policy->num_limit_inputs;
212
213 pmu_pwr_policy->limit_min = _pwr_policy_limitdeltaapply(
214 _pwr_policy_limitarboutputget(g, p_pwr_policy,
215 PWR_POLICY_LIMIT_ID_MIN),
216 p_pwr_policy->limit_delta);
217
218 pmu_pwr_policy->limit_max = _pwr_policy_limitdeltaapply(
219 _pwr_policy_limitarboutputget(g, p_pwr_policy,
220 PWR_POLICY_LIMIT_ID_MAX),
221 p_pwr_policy->limit_delt