1 /*
2 * Copyright (c) 2015-2019, Intel Corporation
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
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR 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
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //! \file     mhw_mi_g12_X.cpp
23 //! \brief    Constructs MI commands on Gen12-based platforms
24 //! \details  Each client facing function both creates a HW command and adds
25 //!           that command to a command or batch buffer.
26 //!
27 
28 #include "mhw_mi_g12_X.h"
29 #include "mhw_mi_hwcmd_g12_X.h"
30 #include "media_skuwa_specific.h"
31 
AddMiSemaphoreWaitCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_SEMAPHORE_WAIT_PARAMS params)32 MOS_STATUS MhwMiInterfaceG12::AddMiSemaphoreWaitCmd(
33     PMOS_COMMAND_BUFFER             cmdBuffer,
34     PMHW_MI_SEMAPHORE_WAIT_PARAMS   params)
35 {
36     MHW_FUNCTION_ENTER;
37 
38     MHW_MI_CHK_NULL(cmdBuffer);
39     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
40     MHW_MI_CHK_NULL(params);
41 
42     mhw_mi_g12_X::MI_SEMAPHORE_WAIT_CMD *cmd =
43         (mhw_mi_g12_X::MI_SEMAPHORE_WAIT_CMD*)cmdBuffer->pCmdPtr;
44 
45     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiSemaphoreWaitCmd(cmdBuffer, params));
46 
47     cmd->DW0.RegisterPollMode = params->bRegisterPollMode;
48 
49     return MOS_STATUS_SUCCESS;
50 }
51 
AddMiBatchBufferStartCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)52 MOS_STATUS MhwMiInterfaceG12::AddMiBatchBufferStartCmd(
53     PMOS_COMMAND_BUFFER                 cmdBuffer,
54     PMHW_BATCH_BUFFER                   batchBuffer)
55 {
56     MHW_FUNCTION_ENTER;
57 
58     MHW_MI_CHK_NULL(cmdBuffer);
59     MHW_MI_CHK_NULL(batchBuffer);
60 
61     bool vcsEngineUsed =
62         MOS_VCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface));
63 
64     mhw_mi_g12_X::MI_BATCH_BUFFER_START_CMD cmd;
65     MHW_RESOURCE_PARAMS                     resourceParams;
66     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
67     resourceParams.presResource     = &batchBuffer->OsResource;
68     resourceParams.dwOffset         = batchBuffer->dwOffset;
69     resourceParams.pdwCmd           = cmd.DW1_2.Value;
70     resourceParams.dwLocationInCmd  = 1;
71     resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
72     resourceParams.HwCommandType    = vcsEngineUsed ?
73         MOS_MI_BATCH_BUFFER_START : MOS_MI_BATCH_BUFFER_START_RCS;
74 
75     MHW_MI_CHK_STATUS(AddResourceToCmd(
76         m_osInterface,
77         cmdBuffer,
78         &resourceParams));
79 
80     // Set BB start
81     cmd.DW0.Obj3.SecondLevelBatchBuffer = true;
82     cmd.DW0.Obj0.AddressSpaceIndicator  = !IsGlobalGttInUse();
83 
84     // Send BB start command
85     MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
86 
87     return MOS_STATUS_SUCCESS;
88 }
89 
AddMiConditionalBatchBufferEndCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS params)90 MOS_STATUS MhwMiInterfaceG12::AddMiConditionalBatchBufferEndCmd(
91     PMOS_COMMAND_BUFFER                             cmdBuffer,
92     PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS     params)
93 {
94     MHW_FUNCTION_ENTER;
95 
96     MHW_MI_CHK_NULL(cmdBuffer);
97     MHW_MI_CHK_NULL(params);
98     MHW_MI_CHK_NULL(params->presSemaphoreBuffer);
99 
100     // Case 1 - Batch buffer condition matches - If this is not present then conditional
101     //          batch buffer will  exit to ring with terminating CP.
102     // Case 2 - Batch buffer condition DOES NOT match - Although this will disable CP
103     //          but after end of conditional batch buffer CP will be re-enabled.
104     MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(m_osInterface, cmdBuffer));
105 
106     mhw_mi_g12_X::MI_CONDITIONAL_BATCH_BUFFER_END_CMD cmd;
107     cmd.DW0.UseGlobalGtt        = IsGlobalGttInUse();
108     cmd.DW0.CompareSemaphore    = 1; // CompareDataDword is always assumed to be set
109     cmd.DW0.CompareMaskMode     = !params->bDisableCompareMask;
110     if (params->dwParamsType == MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS::ENHANCED_PARAMS)
111     {
112         if (static_cast<MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS*>(params)->enableEndCurrentBatchBuffLevel)
113         {
114             cmd.DW0.EndCurrentBatchBufferLevel
115                 = mhw_mi_g12_X::MI_CONDITIONAL_BATCH_BUFFER_END_CMD::END_CURRENT_BATCH_BUFFER_LEVEL_UNNAMED1;
116             cmd.DW0.CompareOperation
117                 = static_cast<MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS*>(params)->compareOperation;
118         }
119     }
120     cmd.DW1.CompareDataDword    = params->dwValue;
121 
122     MHW_RESOURCE_PARAMS resourceParams;
123     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
124     resourceParams.presResource     = params->presSemaphoreBuffer;
125     resourceParams.dwOffset         = params->dwOffset;
126     resourceParams.pdwCmd           = cmd.DW2_3.Value;
127     resourceParams.dwLocationInCmd  = 2;
128     resourceParams.dwLsbNum         = MHW_COMMON_MI_CONDITIONAL_BATCH_BUFFER_END_SHIFT;
129     resourceParams.HwCommandType    = MOS_MI_CONDITIONAL_BATCH_BUFFER_END;
130 
131     MHW_MI_CHK_STATUS(AddResourceToCmd(
132         m_osInterface,
133         cmdBuffer,
134         &resourceParams));
135 
136     // Send Conditional Batch Buffer End command
137     MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
138 
139     //Re-enable CP for Case 2
140     MHW_MI_CHK_STATUS(m_cpInterface->AddProlog(m_osInterface, cmdBuffer));
141 
142     return MOS_STATUS_SUCCESS;
143 }
144 
AddMiSetPredicateCmd(PMOS_COMMAND_BUFFER cmdBuffer,MHW_MI_SET_PREDICATE_ENABLE enableFlag)145 MOS_STATUS MhwMiInterfaceG12::AddMiSetPredicateCmd(
146     PMOS_COMMAND_BUFFER                 cmdBuffer,
147     MHW_MI_SET_PREDICATE_ENABLE         enableFlag)
148 {
149     MHW_FUNCTION_ENTER;
150 
151     MHW_MI_CHK_NULL(cmdBuffer);
152 
153     mhw_mi_g12_X::MI_SET_PREDICATE_CMD cmd;
154     cmd.DW0.PredicateEnable = enableFlag;
155     MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
156 
157     return MOS_STATUS_SUCCESS;
158 }
159 
AddMiStoreRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_STORE_REGISTER_MEM_PARAMS params)160 MOS_STATUS MhwMiInterfaceG12::AddMiStoreRegisterMemCmd(
161     PMOS_COMMAND_BUFFER                 cmdBuffer,
162     PMHW_MI_STORE_REGISTER_MEM_PARAMS   params)
163 {
164     MHW_FUNCTION_ENTER;
165 
166     MHW_MI_CHK_NULL(cmdBuffer);
167     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
168     MHW_MI_CHK_NULL(params);
169 
170     mhw_mi_g12_X::MI_STORE_REGISTER_MEM_CMD *cmd =
171         (mhw_mi_g12_X::MI_STORE_REGISTER_MEM_CMD*)cmdBuffer->pCmdPtr;
172 
173     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiStoreRegisterMemCmd(cmdBuffer, params));
174 
175     if (IsRelativeMMIO(params->dwRegister))
176     {
177         cmd->DW0.AddCsMmioStartOffset = 1;
178         cmd->DW1.RegisterAddress = params->dwRegister >> 2;
179     }
180 
181     cmd->DW0.MmioRemapEnable = IsRemappingMMIO(params->dwRegister);
182 
183     return MOS_STATUS_SUCCESS;
184 }
185 
AddMiLoadRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_MEM_PARAMS params)186 MOS_STATUS MhwMiInterfaceG12::AddMiLoadRegisterMemCmd(
187     PMOS_COMMAND_BUFFER                 cmdBuffer,
188     PMHW_MI_LOAD_REGISTER_MEM_PARAMS    params)
189 {
190     MHW_FUNCTION_ENTER;
191 
192     MHW_MI_CHK_NULL(cmdBuffer);
193     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
194     MHW_MI_CHK_NULL(params);
195 
196     mhw_mi_g12_X::MI_LOAD_REGISTER_MEM_CMD *cmd =
197         (mhw_mi_g12_X::MI_LOAD_REGISTER_MEM_CMD*)cmdBuffer->pCmdPtr;
198 
199     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiLoadRegisterMemCmd(cmdBuffer, params));
200 
201     if (IsRelativeMMIO(params->dwRegister))
202     {
203         cmd->DW0.AddCsMmioStartOffset = 1;
204         cmd->DW1.RegisterAddress = params->dwRegister >> 2;
205     }
206 
207     cmd->DW0.MmioRemapEnable = IsRemappingMMIO(params->dwRegister);
208 
209     return MOS_STATUS_SUCCESS;
210 }
211 
AddMiLoadRegisterImmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_IMM_PARAMS params)212 MOS_STATUS MhwMiInterfaceG12::AddMiLoadRegisterImmCmd(
213     PMOS_COMMAND_BUFFER                 cmdBuffer,
214     PMHW_MI_LOAD_REGISTER_IMM_PARAMS    params)
215 {
216     MHW_FUNCTION_ENTER;
217 
218     MHW_MI_CHK_NULL(cmdBuffer);
219     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
220     MHW_MI_CHK_NULL(params);
221 
222     mhw_mi_g12_X::MI_LOAD_REGISTER_IMM_CMD *cmd =
223         (mhw_mi_g12_X::MI_LOAD_REGISTER_IMM_CMD*)cmdBuffer->pCmdPtr;
224 
225     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiLoadRegisterImmCmd(cmdBuffer, params));
226 
227     if (IsRelativeMMIO(params->dwRegister))
228     {
229         cmd->DW0.AddCsMmioStartOffset = 1;
230         cmd->DW1.RegisterOffset = params->dwRegister >> 2;
231     }
232 
233     cmd->DW0.MmioRemapEnable = IsRemappingMMIO(params->dwRegister);
234 
235     return MOS_STATUS_SUCCESS;
236 }
237 
AddMiLoadRegisterRegCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_REG_PARAMS params)238 MOS_STATUS MhwMiInterfaceG12::AddMiLoadRegisterRegCmd(
239     PMOS_COMMAND_BUFFER                 cmdBuffer,
240     PMHW_MI_LOAD_REGISTER_REG_PARAMS    params)
241 {
242     MHW_FUNCTION_ENTER;
243 
244     MHW_MI_CHK_NULL(cmdBuffer);
245     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
246     MHW_MI_CHK_NULL(params);
247 
248     mhw_mi_g12_X::MI_LOAD_REGISTER_REG_CMD *cmd =
249         (mhw_mi_g12_X::MI_LOAD_REGISTER_REG_CMD*)cmdBuffer->pCmdPtr;
250 
251     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiLoadRegisterRegCmd(cmdBuffer, params));
252 
253     if (IsRelativeMMIO(params->dwSrcRegister))
254     {
255         cmd->DW0.AddCsMmioStartOffsetSource = 1;
256         cmd->DW1.SourceRegisterAddress = params->dwSrcRegister >> 2;
257     }
258     if (IsRelativeMMIO(params->dwDstRegister))
259     {
260         cmd->DW0.AddCsMmioStartOffsetDestination = 1;
261         cmd->DW2.DestinationRegisterAddress = params->dwDstRegister >> 2;
262     }
263 
264     cmd->DW0.MmioRemapEnableSource      = IsRemappingMMIO(params->dwSrcRegister);
265     cmd->DW0.MmioRemapEnableDestination = IsRemappingMMIO(params->dwDstRegister);
266 
267     return MOS_STATUS_SUCCESS;
268 }
269 
AddMiForceWakeupCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_FORCE_WAKEUP_PARAMS params)270 MOS_STATUS MhwMiInterfaceG12::AddMiForceWakeupCmd(
271     PMOS_COMMAND_BUFFER                 cmdBuffer,
272     PMHW_MI_FORCE_WAKEUP_PARAMS         params)
273 {
274     MHW_FUNCTION_ENTER;
275 
276     MHW_MI_CHK_NULL(cmdBuffer);
277     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
278     MHW_MI_CHK_NULL(params);
279 
280     mhw_mi_g12_X::MI_FORCE_WAKEUP_CMD cmd;
281     cmd.DW1.ForceMediaSlice0Awake               = params->bForceMediaSlice0Awake;
282     cmd.DW1.ForceRenderAwake                    = params->bForceRenderAwake;
283     cmd.DW1.ForceMediaSlice1Awake               = params->bForceMediaSlice1Awake;
284     cmd.DW1.ForceMediaSlice2Awake               = params->bForceMediaSlice2Awake;
285     cmd.DW1.ForceMediaSlice3Awake               = params->bForceMediaSlice3Awake;
286     cmd.DW1.HevcPowerWellControl                = params->bHEVCPowerWellControl;
287     cmd.DW1.MfxPowerWellControl                 = params->bMFXPowerWellControl;
288     cmd.DW1.MaskBits                            = params->bForceMediaSlice0AwakeMask;
289     cmd.DW1.MaskBits                            += (params->bForceRenderAwakeMask << 1);
290     cmd.DW1.MaskBits                            += (params->bForceMediaSlice1AwakeMask << 2);
291     cmd.DW1.MaskBits                            += (params->bForceMediaSlice2AwakeMask << 3);
292     cmd.DW1.MaskBits                            += (params->bForceMediaSlice3AwakeMask << 4);
293     cmd.DW1.MaskBits                            += (params->bHEVCPowerWellControlMask  << 8);
294     cmd.DW1.MaskBits                            += (params->bMFXPowerWellControlMask   << 9);
295 
296     MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, cmd.byteSize));
297 
298     return MOS_STATUS_SUCCESS;
299 }
300 
AddMiVdControlStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_VD_CONTROL_STATE_PARAMS params)301 MOS_STATUS MhwMiInterfaceG12::AddMiVdControlStateCmd(
302     PMOS_COMMAND_BUFFER                  cmdBuffer,
303     PMHW_MI_VD_CONTROL_STATE_PARAMS      params)
304 {
305     MHW_FUNCTION_ENTER;
306 
307     MHW_MI_CHK_NULL(cmdBuffer);
308     MHW_MI_CHK_NULL(params);
309 
310     mhw_mi_g12_X::VD_CONTROL_STATE_CMD cmd;
311 
312     if (params->vdencEnabled)
313     {
314         cmd.DW0.MediaInstructionCommand =
315             mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORVDENC;
316         cmd.DW0.MediaInstructionOpcode  =
317             mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORVDENC;
318     }
319     else
320     {
321         cmd.DW0.MediaInstructionCommand =
322             mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORHCP;
323 
324         cmd.DW0.MediaInstructionOpcode =
325             mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORHCP;
326 
327         cmd.DW1.PipelineInitialization  = params->initialization;
328         cmd.DW2.MemoryImplicitFlush     = params->memoryImplicitFlush;
329         cmd.DW2.ScalableModePipeLock    = params->scalableModePipeLock;
330         cmd.DW2.ScalableModePipeUnlock  = params->scalableModePipeUnlock;
331     }
332 
333     MHW_MI_CHK_STATUS(Mos_AddCommand(cmdBuffer, &cmd, sizeof(cmd)));
334 
335     return MOS_STATUS_SUCCESS;
336 }
337 
InitMmioRegisters()338 void MhwMiInterfaceG12::InitMmioRegisters()
339 {
340     MHW_MI_MMIOREGISTERS *mmioRegisters = &m_mmioRegisters;
341 
342     mmioRegisters->generalPurposeRegister0LoOffset            = GP_REGISTER0_LO_OFFSET_G12;
343     mmioRegisters->generalPurposeRegister0HiOffset            = GP_REGISTER0_HI_OFFSET_G12;
344     mmioRegisters->generalPurposeRegister4LoOffset            = GP_REGISTER4_LO_OFFSET_G12;
345     mmioRegisters->generalPurposeRegister4HiOffset            = GP_REGISTER4_HI_OFFSET_G12;
346     mmioRegisters->generalPurposeRegister11LoOffset           = GP_REGISTER11_LO_OFFSET_G12;
347     mmioRegisters->generalPurposeRegister11HiOffset           = GP_REGISTER11_HI_OFFSET_G12;
348     mmioRegisters->generalPurposeRegister12LoOffset           = GP_REGISTER12_LO_OFFSET_G12;
349     mmioRegisters->generalPurposeRegister12HiOffset           = GP_REGISTER12_HI_OFFSET_G12;
350 }
351 
SetWatchdogTimerThreshold(uint32_t frameWidth,uint32_t frameHeight,bool isEncoder)352 MOS_STATUS MhwMiInterfaceG12::SetWatchdogTimerThreshold(uint32_t frameWidth, uint32_t frameHeight, bool isEncoder)
353 {
354     MEDIA_WA_TABLE *waTable = nullptr;
355 
356     MHW_FUNCTION_ENTER;
357 
358     if (m_osInterface->bMediaReset == false ||
359         m_osInterface->umdMediaResetEnable == false)
360     {
361         return MOS_STATUS_SUCCESS;
362     }
363 
364     waTable = m_osInterface->pfnGetWaTable(m_osInterface);
365     MHW_CHK_NULL_RETURN(waTable);
366 
367     if (isEncoder)
368     {
369         if ((frameWidth * frameHeight) >= (7680 * 4320))
370         {
371             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_16K_WATCHDOG_THRESHOLD_IN_MS;
372         }
373         else if ((frameWidth * frameHeight) >= (3840 * 2160))
374         {
375             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_8K_WATCHDOG_THRESHOLD_IN_MS;
376         }
377         else if ((frameWidth * frameHeight) >= (1920 * 1080))
378         {
379             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_4K_WATCHDOG_THRESHOLD_IN_MS;
380         }
381         else
382         {
383             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_FHD_WATCHDOG_THRESHOLD_IN_MS;
384         }
385     }
386     else
387     {
388         if ((frameWidth * frameHeight) >= (16000 * 16000))
389         {
390             MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_16Kx16K_WATCHDOG_THRESHOLD_IN_MS;
391         }
392         else if ((frameWidth * frameHeight) >= (7680 * 4320))
393         {
394             MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_16K_WATCHDOG_THRESHOLD_IN_MS;
395         }
396         else if (((frameWidth * frameHeight) < (1280 * 720)) && MEDIA_IS_WA(waTable, WaSliceMissingMB))
397         {
398             MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_720P_WATCHDOG_THRESHOLD_IN_MS;
399         }
400         else
401         {
402             // 60ms should be enough for decoder with resolution smaller than 8k
403             MediaResetParam.watchdogCountThreshold = MHW_MI_DEFAULT_WATCHDOG_THRESHOLD_IN_MS;
404         }
405     }
406 
407     MOS_USER_FEATURE_VALUE_DATA userFeatureData;
408     MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
409 #if (_DEBUG || _RELEASE_INTERNAL)
410     // User feature config of watchdog timer threshold
411     MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
412     MOS_UserFeature_ReadValue_ID(
413         nullptr,
414         __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
415         &userFeatureData);
416     if (userFeatureData.u32Data != 0)
417     {
418         MediaResetParam.watchdogCountThreshold = userFeatureData.u32Data;
419     }
420 #endif
421 
422     return MOS_STATUS_SUCCESS;
423 }
424 
SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext)425 MOS_STATUS MhwMiInterfaceG12::SetWatchdogTimerRegisterOffset(
426     MOS_GPU_CONTEXT                 gpuContext)
427 {
428     MHW_FUNCTION_ENTER;
429 
430     switch (gpuContext)
431     {
432         // RCS
433     case MOS_GPU_CONTEXT_RENDER:
434     case MOS_GPU_CONTEXT_RENDER2:
435     case MOS_GPU_CONTEXT_RENDER3:
436     case MOS_GPU_CONTEXT_RENDER4:
437     case MOS_GPU_CONTEXT_COMPUTE:
438     case MOS_GPU_CONTEXT_CM_COMPUTE:
439     case MOS_GPU_CONTEXT_RENDER_RA:
440     case MOS_GPU_CONTEXT_COMPUTE_RA:
441         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_RCS_G12;
442         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_RCS_G12;
443         break;
444         // VCS0
445     case MOS_GPU_CONTEXT_VIDEO:
446     case MOS_GPU_CONTEXT_VIDEO2:
447     case MOS_GPU_CONTEXT_VIDEO3:
448     case MOS_GPU_CONTEXT_VIDEO4:
449     case MOS_GPU_CONTEXT_VIDEO5:
450     case MOS_GPU_CONTEXT_VIDEO6:
451     case MOS_GPU_CONTEXT_VIDEO7:
452         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_VCS0_G12;
453         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VCS0_G12;
454         break;
455         // VCS1
456     case MOS_GPU_CONTEXT_VDBOX2_VIDEO:
457     case MOS_GPU_CONTEXT_VDBOX2_VIDEO2:
458     case MOS_GPU_CONTEXT_VDBOX2_VIDEO3:
459         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_VCS1_G12;
460         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VCS1_G12;
461         break;
462         // VECS
463     case MOS_GPU_CONTEXT_VEBOX:
464         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_VECS_G12;
465         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VECS_G12;
466         break;
467         // Default
468     default:
469         break;
470     }
471 
472     return MOS_STATUS_SUCCESS;
473 }
474 
AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer)475 MOS_STATUS MhwMiInterfaceG12::AddWatchdogTimerStartCmd(
476     PMOS_COMMAND_BUFFER                 cmdBuffer)
477 {
478     MOS_GPU_CONTEXT gpuContext;
479 
480     MHW_FUNCTION_ENTER;
481 
482     if (m_osInterface->bMediaReset == false ||
483         m_osInterface->umdMediaResetEnable == false)
484     {
485         return MOS_STATUS_SUCCESS;
486     }
487 
488     MHW_MI_CHK_NULL(cmdBuffer);
489 
490     // Set Watchdog Timer Register Offset
491     gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
492     MHW_MI_CHK_STATUS(SetWatchdogTimerRegisterOffset(gpuContext));
493 
494     // Send Stop before Start is to help recover from incorrect wdt state if previous submission
495     // cause hang and not have a chance to execute the stop cmd in the end of batch buffer.
496     MHW_MI_CHK_STATUS(AddWatchdogTimerStopCmd(cmdBuffer));
497 
498     //Configure Watchdog timer Threshold
499     MHW_MI_LOAD_REGISTER_IMM_PARAMS registerImmParams;
500     MOS_ZeroMemory(&registerImmParams, sizeof(registerImmParams));
501     registerImmParams.dwData = MHW_MI_WATCHDOG_COUNTS_PER_MILLISECOND * MediaResetParam.watchdogCountThreshold *
502         (m_osInterface->bSimIsActive ? 2 : 1);
503     registerImmParams.dwRegister = MediaResetParam.watchdogCountThresholdOffset;
504     MHW_MI_CHK_STATUS(AddMiLoadRegisterImmCmd(
505         cmdBuffer,
506         &registerImmParams));
507 
508     MHW_VERBOSEMESSAGE("MediaReset Threshold is %d", MediaResetParam.watchdogCountThreshold * (m_osInterface->bSimIsActive ? 2 : 1));
509 
510     //Start Watchdog Timer
511     registerImmParams.dwData = MHW_MI_WATCHDOG_ENABLE_COUNTER;
512     registerImmParams.dwRegister = MediaResetParam.watchdogCountCtrlOffset;
513     MHW_MI_CHK_STATUS(AddMiLoadRegisterImmCmd(
514         cmdBuffer,
515         &registerImmParams));
516 
517     return MOS_STATUS_SUCCESS;
518 }
519 
AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer)520 MOS_STATUS MhwMiInterfaceG12::AddWatchdogTimerStopCmd(
521     PMOS_COMMAND_BUFFER                 cmdBuffer)
522 {
523     MOS_GPU_CONTEXT gpuContext;
524 
525     MHW_FUNCTION_ENTER;
526 
527     if (m_osInterface->bMediaReset == false ||
528         m_osInterface->umdMediaResetEnable == false)
529     {
530         return MOS_STATUS_SUCCESS;
531     }
532 
533     MHW_MI_CHK_NULL(cmdBuffer);
534 
535     // Set Watchdog Timer Register Offset
536     gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
537     MHW_MI_CHK_STATUS(SetWatchdogTimerRegisterOffset(gpuContext));
538 
539     //Stop Watchdog Timer
540     MHW_MI_LOAD_REGISTER_IMM_PARAMS registerImmParams;
541     MOS_ZeroMemory(&registerImmParams, sizeof(registerImmParams));
542     registerImmParams.dwData = MHW_MI_WATCHDOG_DISABLE_COUNTER;
543     registerImmParams.dwRegister = MediaResetParam.watchdogCountCtrlOffset;
544     MHW_MI_CHK_STATUS(AddMiLoadRegisterImmCmd(
545         cmdBuffer,
546         &registerImmParams));
547 
548     return MOS_STATUS_SUCCESS;
549 }
550