diff options
author | Joshua Bakita <bakitajoshua@gmail.com> | 2023-06-28 18:24:25 -0400 |
---|---|---|
committer | Joshua Bakita <bakitajoshua@gmail.com> | 2023-06-28 18:24:25 -0400 |
commit | 01e6fac4d61fdd7fff5433942ec93fc2ea1e4df1 (patch) | |
tree | 4ef34501728a087be24f4ba0af90f91486bf780b /include/therm/thrmpmu.c | |
parent | 306a03d18b305e4e573be3b2931978fa10679eb9 (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/therm/thrmpmu.c')
-rw-r--r-- | include/therm/thrmpmu.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/include/therm/thrmpmu.c b/include/therm/thrmpmu.c new file mode 100644 index 0000000..65587ab --- /dev/null +++ b/include/therm/thrmpmu.c | |||
@@ -0,0 +1,271 @@ | |||
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 | #include <nvgpu/gk20a.h> | ||
23 | |||
24 | #include "boardobj/boardobjgrp.h" | ||
25 | #include "boardobj/boardobjgrp_e32.h" | ||
26 | #include "thrmpmu.h" | ||
27 | #include <nvgpu/pmuif/nvgpu_gpmu_cmdif.h> | ||
28 | |||
29 | struct therm_pmucmdhandler_params { | ||
30 | struct nv_pmu_therm_rpc *prpccall; | ||
31 | u32 success; | ||
32 | }; | ||
33 | |||
34 | static void therm_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, | ||
35 | void *param, u32 handle, u32 status) | ||
36 | { | ||
37 | struct therm_pmucmdhandler_params *phandlerparams = | ||
38 | (struct therm_pmucmdhandler_params *)param; | ||
39 | |||
40 | if (msg->msg.therm.msg_type != NV_PMU_THERM_MSG_ID_RPC) { | ||
41 | nvgpu_err(g, "unknow msg %x", | ||
42 | msg->msg.pmgr.msg_type); | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | if (!phandlerparams->prpccall->b_supported) { | ||
47 | nvgpu_err(g, "RPC msg %x failed", | ||
48 | msg->msg.pmgr.msg_type); | ||
49 | } else { | ||
50 | phandlerparams->success = 1; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | int therm_send_pmgr_tables_to_pmu(struct gk20a *g) | ||
55 | { | ||
56 | int status = 0; | ||
57 | struct boardobjgrp *pboardobjgrp = NULL; | ||
58 | |||
59 | if (!BOARDOBJGRP_IS_EMPTY(&g->therm_pmu.therm_deviceobjs.super.super)) { | ||
60 | pboardobjgrp = &g->therm_pmu.therm_deviceobjs.super.super; | ||
61 | status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); | ||
62 | if (status) { | ||
63 | nvgpu_err(g, | ||
64 | "therm_send_pmgr_tables_to_pmu - therm_device failed %x", | ||
65 | status); | ||
66 | goto exit; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | if (!BOARDOBJGRP_IS_EMPTY( | ||
71 | &g->therm_pmu.therm_channelobjs.super.super)) { | ||
72 | pboardobjgrp = &g->therm_pmu.therm_channelobjs.super.super; | ||
73 | status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); | ||
74 | if (status) { | ||
75 | nvgpu_err(g, | ||
76 | "therm_send_pmgr_tables_to_pmu - therm_channel failed %x", | ||
77 | status); | ||
78 | goto exit; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | exit: | ||
83 | return status; | ||
84 | } | ||
85 | |||
86 | static u32 therm_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, | ||
87 | struct pmu_msg *msg, struct pmu_payload *payload, | ||
88 | u32 queue_id, pmu_callback callback, void* cb_param, | ||
89 | u32 *seq_desc, unsigned long timeout) | ||
90 | { | ||
91 | u32 status; | ||
92 | struct therm_pmucmdhandler_params *handlerparams = NULL; | ||
93 | |||
94 | status = nvgpu_pmu_cmd_post(g, cmd, msg, payload, | ||
95 | queue_id, | ||
96 | callback, | ||
97 | cb_param, | ||
98 | seq_desc, | ||
99 | timeout); | ||
100 | if (status) { | ||
101 | nvgpu_err(g, | ||
102 | "unable to post therm cmd for unit %x cmd id %x size %x", | ||
103 | cmd->hdr.unit_id, cmd->cmd.therm.cmd_type, cmd->hdr.size); | ||
104 | goto exit; | ||
105 | } | ||
106 | |||
107 | if (cb_param) { | ||
108 | handlerparams = (struct therm_pmucmdhandler_params*)cb_param; | ||
109 | |||
110 | pmu_wait_message_cond(&g->pmu, | ||
111 | gk20a_get_gr_idle_timeout(g), | ||
112 | &handlerparams->success, 1); | ||
113 | |||
114 | if (handlerparams->success == 0) { | ||
115 | nvgpu_err(g, "could not process cmd"); | ||
116 | status = -ETIMEDOUT; | ||
117 | goto exit; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | exit: | ||
122 | return status; | ||
123 | } | ||
124 | |||
125 | static u32 therm_set_warn_temp_limit(struct gk20a *g) | ||
126 | { | ||
127 | u32 seqdesc = 0; | ||
128 | struct pmu_cmd cmd; | ||
129 | struct pmu_msg msg; | ||
130 | struct pmu_payload payload; | ||
131 | struct nv_pmu_therm_rpc rpccall; | ||
132 | struct therm_pmucmdhandler_params handlerparams; | ||
133 | |||
134 | memset(&payload, 0, sizeof(struct pmu_payload)); | ||
135 | memset(&cmd, 0, sizeof(struct pmu_cmd)); | ||
136 | memset(&msg, 0, sizeof(struct pmu_msg)); | ||
137 | memset(&rpccall, 0, sizeof(struct nv_pmu_therm_rpc)); | ||
138 | memset(&handlerparams, 0, sizeof(struct therm_pmucmdhandler_params)); | ||
139 | |||
140 | rpccall.function = NV_PMU_THERM_RPC_ID_SLCT_EVENT_TEMP_TH_SET; | ||
141 | rpccall.params.slct_event_temp_th_set.event_id = | ||
142 | NV_PMU_THERM_EVENT_THERMAL_1; | ||
143 | rpccall.params.slct_event_temp_th_set.temp_threshold = g->curr_warn_temp; | ||
144 | rpccall.b_supported = 0; | ||
145 | |||
146 | cmd.hdr.unit_id = PMU_UNIT_THERM; | ||
147 | cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + | ||
148 | (u32)sizeof(struct pmu_hdr)); | ||
149 | cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; | ||
150 | |||
151 | msg.hdr.size = sizeof(struct pmu_msg); | ||
152 | |||
153 | payload.in.buf = (u8 *)&rpccall; | ||
154 | payload.in.size = (u32)sizeof(struct nv_pmu_therm_rpc); | ||
155 | payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
156 | payload.in.offset = NV_PMU_THERM_CMD_RPC_ALLOC_OFFSET; | ||
157 | |||
158 | payload.out.buf = (u8 *)&rpccall; | ||
159 | payload.out.size = (u32)sizeof(struct nv_pmu_therm_rpc); | ||
160 | payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
161 | payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; | ||
162 | |||
163 | /* Setup the handler params to communicate back results.*/ | ||
164 | handlerparams.success = 0; | ||
165 | handlerparams.prpccall = &rpccall; | ||
166 | |||
167 | return therm_pmu_cmd_post(g, &cmd, NULL, &payload, | ||
168 | PMU_COMMAND_QUEUE_LPQ, | ||
169 | therm_pmucmdhandler, | ||
170 | (void *)&handlerparams, | ||
171 | &seqdesc, ~0); | ||
172 | } | ||
173 | |||
174 | static u32 therm_enable_slct_notification_request(struct gk20a *g) | ||
175 | { | ||
176 | u32 seqdesc = 0; | ||
177 | struct pmu_cmd cmd = { {0} }; | ||
178 | |||
179 | cmd.hdr.unit_id = PMU_UNIT_THERM; | ||
180 | cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_hw_slowdown_notification) + | ||
181 | (u32)sizeof(struct pmu_hdr)); | ||
182 | |||
183 | cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_HW_SLOWDOWN_NOTIFICATION; | ||
184 | cmd.cmd.therm.hw_slct_notification.request = | ||
185 | NV_RM_PMU_THERM_HW_SLOWDOWN_NOTIFICATION_REQUEST_ENABLE; | ||
186 | |||
187 | return therm_pmu_cmd_post(g, &cmd, NULL, NULL, | ||
188 | PMU_COMMAND_QUEUE_LPQ, | ||
189 | NULL, | ||
190 | NULL, | ||
191 | &seqdesc, ~0); | ||
192 | } | ||
193 | |||
194 | static u32 therm_send_slct_configuration_to_pmu(struct gk20a *g) | ||
195 | { | ||
196 | u32 seqdesc = 0; | ||
197 | struct pmu_cmd cmd; | ||
198 | struct pmu_msg msg; | ||
199 | struct pmu_payload payload; | ||
200 | struct nv_pmu_therm_rpc rpccall; | ||
201 | struct therm_pmucmdhandler_params handlerparams; | ||
202 | |||
203 | memset(&payload, 0, sizeof(struct pmu_payload)); | ||
204 | memset(&cmd, 0, sizeof(struct pmu_cmd)); | ||
205 | memset(&msg, 0, sizeof(struct pmu_msg)); | ||
206 | memset(&rpccall, 0, sizeof(struct nv_pmu_therm_rpc)); | ||
207 | memset(&handlerparams, 0, sizeof(struct therm_pmucmdhandler_params)); | ||
208 | |||
209 | rpccall.function = NV_PMU_THERM_RPC_ID_SLCT; | ||
210 | rpccall.params.slct.mask_enabled = | ||
211 | (1 << NV_PMU_THERM_EVENT_THERMAL_1); | ||
212 | rpccall.b_supported = 0; | ||
213 | |||
214 | cmd.hdr.unit_id = PMU_UNIT_THERM; | ||
215 | cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + | ||
216 | (u32)sizeof(struct pmu_hdr)); | ||
217 | cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; | ||
218 | |||
219 | msg.hdr.size = sizeof(struct pmu_msg); | ||
220 | |||
221 | payload.in.buf = (u8 *)&rpccall; | ||
222 | payload.in.size = (u32)sizeof(struct nv_pmu_therm_rpc); | ||
223 | payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
224 | payload.in.offset = NV_PMU_THERM_CMD_RPC_ALLOC_OFFSET; | ||
225 | |||
226 | payload.out.buf = (u8 *)&rpccall; | ||
227 | payload.out.size = (u32)sizeof(struct nv_pmu_therm_rpc); | ||
228 | payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; | ||
229 | payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; | ||
230 | |||
231 | /* Setup the handler params to communicate back results.*/ | ||
232 | handlerparams.success = 0; | ||
233 | handlerparams.prpccall = &rpccall; | ||
234 | |||
235 | return therm_pmu_cmd_post(g, &cmd, NULL, &payload, | ||
236 | PMU_COMMAND_QUEUE_LPQ, | ||
237 | therm_pmucmdhandler, | ||
238 | (void *)&handlerparams, | ||
239 | &seqdesc, ~0); | ||
240 | } | ||
241 | |||
242 | u32 therm_configure_therm_alert(struct gk20a *g) | ||
243 | { | ||
244 | u32 status; | ||
245 | |||
246 | status = therm_enable_slct_notification_request(g); | ||
247 | if (status) { | ||
248 | nvgpu_err(g, | ||
249 | "therm_enable_slct_notification_request-failed %d", | ||
250 | status); | ||
251 | goto exit; | ||
252 | } | ||
253 | |||
254 | status = therm_send_slct_configuration_to_pmu(g); | ||
255 | if (status) { | ||
256 | nvgpu_err(g, | ||
257 | "therm_send_slct_configuration_to_pmu-failed %d", | ||
258 | status); | ||
259 | goto exit; | ||
260 | } | ||
261 | |||
262 | status = therm_set_warn_temp_limit(g); | ||
263 | if (status) { | ||
264 | nvgpu_err(g, | ||
265 | "therm_set_warn_temp_limit-failed %d", | ||
266 | status); | ||
267 | goto exit; | ||
268 | } | ||
269 | exit: | ||
270 | return status; | ||
271 | } | ||