1 /*
2  * Copyright (C) 2020-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "level_zero/tools/source/sysman/frequency/windows/os_frequency_imp.h"
9 
10 #include "level_zero/tools/source/sysman/sysman_const.h"
11 
12 namespace L0 {
13 
osFrequencyGetProperties(zes_freq_properties_t & properties)14 ze_result_t WddmFrequencyImp::osFrequencyGetProperties(zes_freq_properties_t &properties) {
15     readOverclockingInfo();
16     uint32_t value = 0;
17 
18     std::vector<KmdSysman::RequestProperty> vRequests = {};
19     std::vector<KmdSysman::ResponseProperty> vResponses = {};
20     KmdSysman::RequestProperty request = {};
21 
22     request.commandId = KmdSysman::Command::Get;
23     request.componentId = KmdSysman::Component::FrequencyComponent;
24     request.requestId = KmdSysman::Requests::Frequency::FrequencyThrottledEventSupported;
25     request.paramInfo = static_cast<uint32_t>(frequencyDomainNumber);
26     vRequests.push_back(request);
27 
28     request.requestId = KmdSysman::Requests::Frequency::FrequencyRangeMinDefault;
29     request.paramInfo = static_cast<uint32_t>(frequencyDomainNumber);
30     vRequests.push_back(request);
31 
32     request.requestId = KmdSysman::Requests::Frequency::FrequencyRangeMaxDefault;
33     request.paramInfo = static_cast<uint32_t>(frequencyDomainNumber);
34     vRequests.push_back(request);
35 
36     request.requestId = KmdSysman::Requests::Frequency::CanControlFrequency;
37     request.paramInfo = static_cast<uint32_t>(frequencyDomainNumber);
38     vRequests.push_back(request);
39 
40     ze_result_t status = pKmdSysManager->requestMultiple(vRequests, vResponses);
41 
42     if ((status != ZE_RESULT_SUCCESS) || (vResponses.size() != vRequests.size())) {
43         return status;
44     }
45 
46     properties.isThrottleEventSupported = false;
47     if (vResponses[0].returnCode == ZE_RESULT_SUCCESS) {
48         memcpy_s(&value, sizeof(uint32_t), vResponses[0].dataBuffer, sizeof(uint32_t));
49         properties.isThrottleEventSupported = static_cast<ze_bool_t>(value);
50     }
51 
52     properties.min = unsupportedProperty;
53     if (vResponses[1].returnCode == ZE_RESULT_SUCCESS) {
54         value = 0;
55         memcpy_s(&value, sizeof(uint32_t), vResponses[1].dataBuffer, sizeof(uint32_t));
56         properties.min = static_cast<double>(value);
57     }
58 
59     properties.max = unsupportedProperty;
60     if (vResponses[2].returnCode == ZE_RESULT_SUCCESS) {
61         value = 0;
62         memcpy_s(&value, sizeof(uint32_t), vResponses[2].dataBuffer, sizeof(uint32_t));
63         properties.max = static_cast<double>(value);
64     }
65 
66     properties.canControl = false;
67     if (vResponses[3].returnCode == ZE_RESULT_SUCCESS) {
68         value = 0;
69         memcpy_s(&value, sizeof(uint32_t), vResponses[3].dataBuffer, sizeof(uint32_t));
70         properties.canControl = (value == 1);
71     }
72 
73     properties.onSubdevice = false;
74     properties.subdeviceId = 0;
75     properties.type = frequencyDomainNumber;
76 
77     return ZE_RESULT_SUCCESS;
78 }
79 
osFrequencyGetStepSize()80 double WddmFrequencyImp::osFrequencyGetStepSize() {
81     return 50.0 / 3; // Step of 16.6666667 Mhz (GEN9 Hardcode);
82 }
83 
osFrequencyGetRange(zes_freq_range_t * pLimits)84 ze_result_t WddmFrequencyImp::osFrequencyGetRange(zes_freq_range_t *pLimits) {
85     return getRange(&pLimits->min, &pLimits->max);
86 }
87 
osFrequencySetRange(const zes_freq_range_t * pLimits)88 ze_result_t WddmFrequencyImp::osFrequencySetRange(const zes_freq_range_t *pLimits) {
89     return setRange(pLimits->min, pLimits->max);
90 }
91 
osFrequencyGetState(zes_freq_state_t * pState)92 ze_result_t WddmFrequencyImp::osFrequencyGetState(zes_freq_state_t *pState) {
93     uint32_t value = 0;
94     std::vector<KmdSysman::RequestProperty> vRequests = {};
95     std::vector<KmdSysman::ResponseProperty> vResponses = {};
96     KmdSysman::RequestProperty request = {};
97 
98     request.commandId = KmdSysman::Command::Get;
99     request.componentId = KmdSysman::Component::FrequencyComponent;
100     request.requestId = KmdSysman::Requests::Frequency::CurrentRequestedFrequency;
101     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
102     vRequests.push_back(request);
103 
104     request.requestId = KmdSysman::Requests::Frequency::CurrentTdpFrequency;
105     vRequests.push_back(request);
106 
107     request.requestId = KmdSysman::Requests::Frequency::CurrentResolvedFrequency;
108     vRequests.push_back(request);
109 
110     request.requestId = KmdSysman::Requests::Frequency::CurrentEfficientFrequency;
111     vRequests.push_back(request);
112 
113     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltage;
114     vRequests.push_back(request);
115 
116     request.requestId = KmdSysman::Requests::Frequency::CurrentThrottleReasons;
117     vRequests.push_back(request);
118 
119     ze_result_t status = pKmdSysManager->requestMultiple(vRequests, vResponses);
120 
121     if ((status != ZE_RESULT_SUCCESS) || (vResponses.size() != vRequests.size())) {
122         return status;
123     }
124 
125     pState->request = unsupportedProperty;
126     if (vResponses[0].returnCode == KmdSysman::Success) {
127         memcpy_s(&value, sizeof(uint32_t), vResponses[0].dataBuffer, sizeof(uint32_t));
128         pState->request = static_cast<double>(value);
129     }
130 
131     pState->tdp = unsupportedProperty;
132     if (vResponses[1].returnCode == KmdSysman::Success) {
133         memcpy_s(&value, sizeof(uint32_t), vResponses[1].dataBuffer, sizeof(uint32_t));
134         pState->tdp = static_cast<double>(value);
135     }
136 
137     pState->actual = unsupportedProperty;
138     if (vResponses[2].returnCode == KmdSysman::Success) {
139         memcpy_s(&value, sizeof(uint32_t), vResponses[2].dataBuffer, sizeof(uint32_t));
140         pState->actual = static_cast<double>(value);
141     }
142 
143     pState->efficient = unsupportedProperty;
144     if (vResponses[3].returnCode == KmdSysman::Success) {
145         memcpy_s(&value, sizeof(uint32_t), vResponses[3].dataBuffer, sizeof(uint32_t));
146         pState->efficient = static_cast<double>(value);
147     }
148 
149     pState->currentVoltage = unsupportedProperty;
150     if (vResponses[4].returnCode == KmdSysman::Success) {
151         memcpy_s(&value, sizeof(uint32_t), vResponses[4].dataBuffer, sizeof(uint32_t));
152         pState->currentVoltage = static_cast<double>(value);
153         pState->currentVoltage /= milliVoltsFactor;
154     }
155 
156     if (vResponses[5].returnCode == KmdSysman::Success) {
157         KmdThrottleReasons value = {0};
158         pState->throttleReasons = {0};
159         memcpy_s(&value, sizeof(uint32_t), vResponses[5].dataBuffer, sizeof(uint32_t));
160 
161         if (value.power3) {
162             pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_AVE_PWR_CAP;
163         }
164         if (value.power4) {
165             pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_BURST_PWR_CAP;
166         }
167         if (value.current1) {
168             pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_CURRENT_LIMIT;
169         }
170         if (value.thermal1 || value.thermal2 || value.thermal3 || value.thermal4) {
171             pState->throttleReasons |= ZES_FREQ_THROTTLE_REASON_FLAG_THERMAL_LIMIT;
172         }
173     }
174 
175     return ZE_RESULT_SUCCESS;
176 }
177 
osFrequencyGetThrottleTime(zes_freq_throttle_time_t * pThrottleTime)178 ze_result_t WddmFrequencyImp::osFrequencyGetThrottleTime(zes_freq_throttle_time_t *pThrottleTime) {
179     return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
180 }
181 
getOcCapabilities(zes_oc_capabilities_t * pOcCapabilities)182 ze_result_t WddmFrequencyImp::getOcCapabilities(zes_oc_capabilities_t *pOcCapabilities) {
183     *pOcCapabilities = ocCapabilities;
184     return ZE_RESULT_SUCCESS;
185 }
186 
getOcFrequencyTarget(double * pCurrentOcFrequency)187 ze_result_t WddmFrequencyImp::getOcFrequencyTarget(double *pCurrentOcFrequency) {
188     ze_result_t status = ZE_RESULT_SUCCESS;
189     uint32_t value = 0;
190     KmdSysman::RequestProperty request;
191     KmdSysman::ResponseProperty response;
192 
193     request.commandId = KmdSysman::Command::Get;
194     request.componentId = KmdSysman::Component::FrequencyComponent;
195     request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyTarget;
196     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
197 
198     status = pKmdSysManager->requestSingle(request, response);
199 
200     if (status != ZE_RESULT_SUCCESS) {
201         return status;
202     }
203 
204     memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
205     *pCurrentOcFrequency = currentFrequencyTarget = static_cast<double>(value);
206 
207     return status;
208 }
209 
setOcFrequencyTarget(double currentOcFrequency)210 ze_result_t WddmFrequencyImp::setOcFrequencyTarget(double currentOcFrequency) {
211     this->currentFrequencyTarget = currentOcFrequency;
212     return applyOcSettings();
213 }
214 
getOcVoltageTarget(double * pCurrentVoltageTarget,double * pCurrentVoltageOffset)215 ze_result_t WddmFrequencyImp::getOcVoltageTarget(double *pCurrentVoltageTarget, double *pCurrentVoltageOffset) {
216     uint32_t unsignedValue = 0;
217     int32_t signedValue = 0;
218     std::vector<KmdSysman::RequestProperty> vRequests = {};
219     std::vector<KmdSysman::ResponseProperty> vResponses = {};
220     KmdSysman::RequestProperty request = {};
221 
222     request.commandId = KmdSysman::Command::Get;
223     request.componentId = KmdSysman::Component::FrequencyComponent;
224     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageTarget;
225     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
226     vRequests.push_back(request);
227 
228     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageOffset;
229     vRequests.push_back(request);
230 
231     ze_result_t status = pKmdSysManager->requestMultiple(vRequests, vResponses);
232 
233     if ((status != ZE_RESULT_SUCCESS) || (vResponses.size() != vRequests.size())) {
234         return status;
235     }
236 
237     if (vResponses[0].returnCode == KmdSysman::Success) {
238         memcpy_s(&unsignedValue, sizeof(uint32_t), vResponses[0].dataBuffer, sizeof(uint32_t));
239         *pCurrentVoltageTarget = currentVoltageTarget = static_cast<double>(unsignedValue);
240     }
241 
242     if (vResponses[1].returnCode == KmdSysman::Success) {
243         memcpy_s(&signedValue, sizeof(int32_t), vResponses[1].dataBuffer, sizeof(int32_t));
244         *pCurrentVoltageOffset = currentVoltageOffset = static_cast<double>(signedValue);
245     }
246 
247     return ZE_RESULT_SUCCESS;
248 }
249 
setOcVoltageTarget(double currentVoltageTarget,double currentVoltageOffset)250 ze_result_t WddmFrequencyImp::setOcVoltageTarget(double currentVoltageTarget, double currentVoltageOffset) {
251     this->currentVoltageTarget = currentVoltageTarget;
252     this->currentVoltageOffset = currentVoltageOffset;
253     return applyOcSettings();
254 }
255 
getOcMode(zes_oc_mode_t * pCurrentOcMode)256 ze_result_t WddmFrequencyImp::getOcMode(zes_oc_mode_t *pCurrentOcMode) {
257     ze_result_t status = ZE_RESULT_SUCCESS;
258 
259     uint32_t value = 0;
260     KmdSysman::RequestProperty request;
261     KmdSysman::ResponseProperty response;
262 
263     request.commandId = KmdSysman::Command::Get;
264     request.componentId = KmdSysman::Component::FrequencyComponent;
265     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageMode;
266     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
267 
268     status = pKmdSysManager->requestSingle(request, response);
269 
270     if (status != ZE_RESULT_SUCCESS) {
271         return status;
272     }
273 
274     memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
275     currentVoltageMode = value ? ZES_OC_MODE_OVERRIDE : ZES_OC_MODE_INTERPOLATIVE;
276 
277     *pCurrentOcMode = currentVoltageMode;
278 
279     return status;
280 }
281 
setOcMode(zes_oc_mode_t currentOcMode)282 ze_result_t WddmFrequencyImp::setOcMode(zes_oc_mode_t currentOcMode) {
283     if (currentOcMode == ZES_OC_MODE_FIXED) {
284         this->currentVoltageMode = ZES_OC_MODE_INTERPOLATIVE;
285         return ze_result_t::ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
286     }
287 
288     if (currentOcMode == ZES_OC_MODE_OFF) {
289         this->currentVoltageMode = ZES_OC_MODE_INTERPOLATIVE;
290         return applyOcSettings();
291     }
292 
293     if (currentOcMode == ZES_OC_MODE_INTERPOLATIVE || currentOcMode == ZES_OC_MODE_OVERRIDE) {
294         this->currentVoltageMode = currentOcMode;
295         return applyOcSettings();
296     }
297 
298     return ZE_RESULT_SUCCESS;
299 }
300 
getOcIccMax(double * pOcIccMax)301 ze_result_t WddmFrequencyImp::getOcIccMax(double *pOcIccMax) {
302     ze_result_t status = ZE_RESULT_SUCCESS;
303     uint32_t value = 0;
304     KmdSysman::RequestProperty request;
305     KmdSysman::ResponseProperty response;
306 
307     request.commandId = KmdSysman::Command::Get;
308     request.componentId = KmdSysman::Component::FrequencyComponent;
309     request.requestId = KmdSysman::Requests::Frequency::CurrentIccMax;
310     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
311 
312     status = pKmdSysManager->requestSingle(request, response);
313 
314     if (status != ZE_RESULT_SUCCESS) {
315         return status;
316     }
317 
318     memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
319     *pOcIccMax = static_cast<double>(value);
320 
321     return status;
322 }
323 
setOcIccMax(double ocIccMax)324 ze_result_t WddmFrequencyImp::setOcIccMax(double ocIccMax) {
325     uint32_t value = 0;
326     KmdSysman::RequestProperty request;
327     KmdSysman::ResponseProperty response;
328 
329     request.commandId = KmdSysman::Command::Set;
330     request.componentId = KmdSysman::Component::FrequencyComponent;
331     request.requestId = KmdSysman::Requests::Frequency::CurrentIccMax;
332     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
333     request.dataSize = sizeof(uint32_t);
334 
335     value = static_cast<uint32_t>(ocIccMax);
336     memcpy_s(request.dataBuffer, sizeof(uint32_t), &value, sizeof(uint32_t));
337 
338     return pKmdSysManager->requestSingle(request, response);
339 }
340 
getOcTjMax(double * pOcTjMax)341 ze_result_t WddmFrequencyImp::getOcTjMax(double *pOcTjMax) {
342     ze_result_t status = ZE_RESULT_SUCCESS;
343     uint32_t value = 0;
344     KmdSysman::RequestProperty request;
345     KmdSysman::ResponseProperty response;
346 
347     request.commandId = KmdSysman::Command::Get;
348     request.componentId = KmdSysman::Component::FrequencyComponent;
349     request.requestId = KmdSysman::Requests::Frequency::CurrentTjMax;
350     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
351 
352     status = pKmdSysManager->requestSingle(request, response);
353 
354     if (status != ZE_RESULT_SUCCESS) {
355         return status;
356     }
357 
358     memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
359     *pOcTjMax = static_cast<double>(value);
360 
361     return status;
362 }
363 
setOcTjMax(double ocTjMax)364 ze_result_t WddmFrequencyImp::setOcTjMax(double ocTjMax) {
365     uint32_t value = 0;
366     KmdSysman::RequestProperty request;
367     KmdSysman::ResponseProperty response;
368 
369     request.commandId = KmdSysman::Command::Set;
370     request.componentId = KmdSysman::Component::FrequencyComponent;
371     request.requestId = KmdSysman::Requests::Frequency::CurrentTjMax;
372     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
373     request.dataSize = sizeof(uint32_t);
374 
375     value = static_cast<uint32_t>(ocTjMax);
376     memcpy_s(request.dataBuffer, sizeof(uint32_t), &value, sizeof(uint32_t));
377 
378     return pKmdSysManager->requestSingle(request, response);
379 }
380 
setRange(double min,double max)381 ze_result_t WddmFrequencyImp::setRange(double min, double max) {
382     uint32_t value = 0;
383     KmdSysman::RequestProperty request;
384     KmdSysman::ResponseProperty response;
385 
386     request.commandId = KmdSysman::Command::Set;
387     request.componentId = KmdSysman::Component::FrequencyComponent;
388     request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyRange;
389     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
390     request.dataSize = 2 * sizeof(uint32_t);
391 
392     value = static_cast<uint32_t>(min);
393     memcpy_s(request.dataBuffer, sizeof(uint32_t), &value, sizeof(uint32_t));
394     value = static_cast<uint32_t>(max);
395     memcpy_s((request.dataBuffer + sizeof(uint32_t)), sizeof(uint32_t), &value, sizeof(uint32_t));
396 
397     return pKmdSysManager->requestSingle(request, response);
398 }
399 
getRange(double * min,double * max)400 ze_result_t WddmFrequencyImp::getRange(double *min, double *max) {
401     ze_result_t status = ZE_RESULT_SUCCESS;
402     KmdSysman::RequestProperty request;
403     KmdSysman::ResponseProperty response;
404 
405     request.commandId = KmdSysman::Command::Get;
406     request.componentId = KmdSysman::Component::FrequencyComponent;
407     request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyRange;
408     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
409 
410     status = pKmdSysManager->requestSingle(request, response);
411 
412     if (status != ZE_RESULT_SUCCESS) {
413         return status;
414     }
415 
416     uint32_t value = 0;
417     memcpy_s(&value, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
418     *min = static_cast<double>(value);
419     memcpy_s(&value, sizeof(uint32_t), (response.dataBuffer + sizeof(uint32_t)), sizeof(uint32_t));
420     *max = static_cast<double>(value);
421 
422     return status;
423 }
424 
applyOcSettings()425 ze_result_t WddmFrequencyImp::applyOcSettings() {
426     int32_t value = 0;
427     std::vector<KmdSysman::RequestProperty> vRequests = {};
428     std::vector<KmdSysman::ResponseProperty> vResponses = {};
429     KmdSysman::RequestProperty request = {};
430 
431     request.commandId = KmdSysman::Command::Set;
432     request.componentId = KmdSysman::Component::FrequencyComponent;
433     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
434     request.dataSize = sizeof(int32_t);
435 
436     // Fixed mode not supported.
437     request.requestId = KmdSysman::Requests::Frequency::CurrentFixedMode;
438     value = 0;
439     memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t));
440     vRequests.push_back(request);
441 
442     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageMode;
443     value = (currentVoltageMode == ZES_OC_MODE_OVERRIDE) ? 1 : 0;
444     memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t));
445     vRequests.push_back(request);
446 
447     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageOffset;
448     value = static_cast<int32_t>(currentVoltageOffset);
449     memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t));
450     vRequests.push_back(request);
451 
452     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageTarget;
453     value = static_cast<int32_t>(currentVoltageTarget);
454     memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t));
455     vRequests.push_back(request);
456 
457     request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyTarget;
458     value = static_cast<int32_t>(currentFrequencyTarget);
459     memcpy_s(request.dataBuffer, sizeof(int32_t), &value, sizeof(int32_t));
460     vRequests.push_back(request);
461 
462     ze_result_t status = pKmdSysManager->requestMultiple(vRequests, vResponses);
463 
464     if ((status != ZE_RESULT_SUCCESS) || (vResponses.size() != vRequests.size())) {
465         return status;
466     }
467 
468     for (uint32_t i = 0; i < vResponses.size(); i++) {
469         if (vResponses[i].returnCode != KmdSysman::ReturnCodes::Success) {
470             return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
471         }
472     }
473 
474     return status;
475 }
476 
readOverclockingInfo()477 void WddmFrequencyImp::readOverclockingInfo() {
478     uint32_t value = 0;
479     std::vector<KmdSysman::RequestProperty> vRequests = {};
480     std::vector<KmdSysman::ResponseProperty> vResponses = {};
481     KmdSysman::RequestProperty request = {};
482 
483     request.commandId = KmdSysman::Command::Get;
484     request.componentId = KmdSysman::Component::FrequencyComponent;
485     request.paramInfo = static_cast<uint32_t>(this->frequencyDomainNumber);
486 
487     request.requestId = KmdSysman::Requests::Frequency::ExtendedOcSupported;
488     vRequests.push_back(request);
489 
490     request.requestId = KmdSysman::Requests::Frequency::FixedModeSupported;
491     vRequests.push_back(request);
492 
493     request.requestId = KmdSysman::Requests::Frequency::HighVoltageModeSupported;
494     vRequests.push_back(request);
495 
496     request.requestId = KmdSysman::Requests::Frequency::HighVoltageEnabled;
497     vRequests.push_back(request);
498 
499     request.requestId = KmdSysman::Requests::Frequency::CurrentIccMax;
500     vRequests.push_back(request);
501 
502     request.requestId = KmdSysman::Requests::Frequency::FrequencyOcSupported;
503     vRequests.push_back(request);
504 
505     request.requestId = KmdSysman::Requests::Frequency::CurrentTjMax;
506     vRequests.push_back(request);
507 
508     request.requestId = KmdSysman::Requests::Frequency::MaxNonOcFrequencyDefault;
509     vRequests.push_back(request);
510 
511     request.requestId = KmdSysman::Requests::Frequency::MaxNonOcVoltageDefault;
512     vRequests.push_back(request);
513 
514     request.requestId = KmdSysman::Requests::Frequency::MaxOcFrequencyDefault;
515     vRequests.push_back(request);
516 
517     request.requestId = KmdSysman::Requests::Frequency::MaxOcVoltageDefault;
518     vRequests.push_back(request);
519 
520     request.requestId = KmdSysman::Requests::Frequency::CurrentFrequencyTarget;
521     vRequests.push_back(request);
522 
523     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageTarget;
524     vRequests.push_back(request);
525 
526     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageOffset;
527     vRequests.push_back(request);
528 
529     request.requestId = KmdSysman::Requests::Frequency::CurrentVoltageMode;
530     vRequests.push_back(request);
531 
532     ze_result_t status = pKmdSysManager->requestMultiple(vRequests, vResponses);
533 
534     if ((status != ZE_RESULT_SUCCESS) || (vResponses.size() != vRequests.size())) {
535         return;
536     }
537 
538     if (vResponses[0].returnCode == KmdSysman::Success) {
539         memcpy_s(&value, sizeof(uint32_t), vResponses[0].dataBuffer, sizeof(uint32_t));
540         ocCapabilities.isExtendedModeSupported = static_cast<ze_bool_t>(value);
541     }
542 
543     if (vResponses[1].returnCode == KmdSysman::Success) {
544         memcpy_s(&value, sizeof(uint32_t), vResponses[1].dataBuffer, sizeof(uint32_t));
545         ocCapabilities.isFixedModeSupported = static_cast<ze_bool_t>(value);
546     }
547 
548     if (vResponses[2].returnCode == KmdSysman::Success) {
549         memcpy_s(&value, sizeof(uint32_t), vResponses[2].dataBuffer, sizeof(uint32_t));
550         ocCapabilities.isHighVoltModeCapable = static_cast<ze_bool_t>(value);
551     }
552 
553     if (vResponses[3].returnCode == KmdSysman::Success) {
554         memcpy_s(&value, sizeof(uint32_t), vResponses[3].dataBuffer, sizeof(uint32_t));
555         ocCapabilities.isHighVoltModeEnabled = static_cast<ze_bool_t>(value);
556     }
557 
558     if (vResponses[4].returnCode == KmdSysman::Success) {
559         memcpy_s(&value, sizeof(uint32_t), vResponses[4].dataBuffer, sizeof(uint32_t));
560         ocCapabilities.isIccMaxSupported = static_cast<ze_bool_t>(value > 0);
561     }
562 
563     if (vResponses[5].returnCode == KmdSysman::Success) {
564         memcpy_s(&value, sizeof(uint32_t), vResponses[5].dataBuffer, sizeof(uint32_t));
565         ocCapabilities.isOcSupported = static_cast<ze_bool_t>(value);
566     }
567 
568     if (vResponses[6].returnCode == KmdSysman::Success) {
569         memcpy_s(&value, sizeof(uint32_t), vResponses[6].dataBuffer, sizeof(uint32_t));
570         ocCapabilities.isTjMaxSupported = static_cast<ze_bool_t>(value > 0);
571     }
572 
573     if (vResponses[7].returnCode == KmdSysman::Success) {
574         memcpy_s(&value, sizeof(uint32_t), vResponses[7].dataBuffer, sizeof(uint32_t));
575         ocCapabilities.maxFactoryDefaultFrequency = static_cast<double>(value);
576     }
577 
578     if (vResponses[8].returnCode == KmdSysman::Success) {
579         memcpy_s(&value, sizeof(uint32_t), vResponses[8].dataBuffer, sizeof(uint32_t));
580         ocCapabilities.maxFactoryDefaultVoltage = static_cast<double>(value);
581     }
582 
583     if (vResponses[9].returnCode == KmdSysman::Success) {
584         memcpy_s(&value, sizeof(uint32_t), vResponses[9].dataBuffer, sizeof(uint32_t));
585         ocCapabilities.maxOcFrequency = static_cast<double>(value);
586     }
587 
588     if (vResponses[10].returnCode == KmdSysman::Success) {
589         memcpy_s(&value, sizeof(uint32_t), vResponses[10].dataBuffer, sizeof(uint32_t));
590         ocCapabilities.maxOcVoltage = static_cast<double>(value);
591     }
592 
593     if (vResponses[11].returnCode == KmdSysman::Success) {
594         memcpy_s(&value, sizeof(uint32_t), vResponses[11].dataBuffer, sizeof(uint32_t));
595         currentFrequencyTarget = static_cast<double>(value);
596     }
597 
598     if (vResponses[12].returnCode == KmdSysman::Success) {
599         memcpy_s(&value, sizeof(uint32_t), vResponses[12].dataBuffer, sizeof(uint32_t));
600         currentVoltageTarget = static_cast<double>(value);
601     }
602 
603     if (vResponses[13].returnCode == KmdSysman::Success) {
604         memcpy_s(&value, sizeof(uint32_t), vResponses[13].dataBuffer, sizeof(uint32_t));
605         currentVoltageOffset = static_cast<double>(value);
606     }
607 
608     if (vResponses[14].returnCode == KmdSysman::Success) {
609         memcpy_s(&value, sizeof(uint32_t), vResponses[14].dataBuffer, sizeof(uint32_t));
610         currentVoltageMode = value ? ZES_OC_MODE_OVERRIDE : ZES_OC_MODE_INTERPOLATIVE;
611     }
612 }
613 
WddmFrequencyImp(OsSysman * pOsSysman,ze_bool_t onSubdevice,uint32_t subdeviceId,zes_freq_domain_t frequencyDomainNumber)614 WddmFrequencyImp::WddmFrequencyImp(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber) {
615     WddmSysmanImp *pWddmSysmanImp = static_cast<WddmSysmanImp *>(pOsSysman);
616     this->frequencyDomainNumber = frequencyDomainNumber;
617     pKmdSysManager = &pWddmSysmanImp->getKmdSysManager();
618 }
619 
create(OsSysman * pOsSysman,ze_bool_t onSubdevice,uint32_t subdeviceId,zes_freq_domain_t frequencyDomainNumber)620 OsFrequency *OsFrequency::create(OsSysman *pOsSysman, ze_bool_t onSubdevice, uint32_t subdeviceId, zes_freq_domain_t frequencyDomainNumber) {
621     WddmFrequencyImp *pWddmFrequencyImp = new WddmFrequencyImp(pOsSysman, onSubdevice, subdeviceId, frequencyDomainNumber);
622     return static_cast<OsFrequency *>(pWddmFrequencyImp);
623 }
624 
getNumberOfFreqDoainsSupported(OsSysman * pOsSysman)625 uint16_t OsFrequency::getNumberOfFreqDoainsSupported(OsSysman *pOsSysman) {
626     WddmSysmanImp *pWddmSysmanImp = static_cast<WddmSysmanImp *>(pOsSysman);
627     KmdSysManager *pKmdSysManager = &pWddmSysmanImp->getKmdSysManager();
628 
629     KmdSysman::RequestProperty request;
630     KmdSysman::ResponseProperty response;
631 
632     request.commandId = KmdSysman::Command::Get;
633     request.componentId = KmdSysman::Component::FrequencyComponent;
634     request.requestId = KmdSysman::Requests::Frequency::NumFrequencyDomains;
635 
636     ze_result_t status = pKmdSysManager->requestSingle(request, response);
637 
638     if (status != ZE_RESULT_SUCCESS) {
639         return 0;
640     }
641 
642     uint32_t maxNumEnginesSupported = 0;
643     memcpy_s(&maxNumEnginesSupported, sizeof(uint32_t), response.dataBuffer, sizeof(uint32_t));
644 
645     return static_cast<uint16_t>(maxNumEnginesSupported);
646 }
647 
648 } // namespace L0
649