xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/gen12/hw/mhw_mi_g12_X.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2015-2020, 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 
AddPipeControl(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_PIPE_CONTROL_PARAMS params)52 MOS_STATUS MhwMiInterfaceG12::AddPipeControl(
53     PMOS_COMMAND_BUFFER      cmdBuffer,
54     PMHW_BATCH_BUFFER        batchBuffer,
55     PMHW_PIPE_CONTROL_PARAMS params)
56 {
57     MHW_FUNCTION_ENTER;
58 
59     MHW_MI_CHK_NULL(params);
60 
61     MHW_MI_CHK_NULL(m_osInterface);
62     MEDIA_WA_TABLE *pWaTable = m_osInterface->pfnGetWaTable(m_osInterface);
63     MHW_MI_CHK_NULL(pWaTable);
64 
65     if (cmdBuffer == nullptr && batchBuffer == nullptr)
66     {
67         MHW_ASSERTMESSAGE("There was no valid buffer to add the HW command to.");
68         return MOS_STATUS_NULL_POINTER;
69     }
70 
71     mhw_mi_g12_X::PIPE_CONTROL_CMD     cmd;
72     cmd.DW1.PipeControlFlushEnable     = params->bKernelFenceEnabled ? false : true;
73     cmd.DW1.CommandStreamerStallEnable = !params->bDisableCSStall;
74     cmd.DW4_5.Value[0]                 = params->dwDataDW1;
75     cmd.DW4_5.Value[1]                 = params->dwDataDW2;
76 
77     if (params->presDest)
78     {
79         cmd.DW1.PostSyncOperation      = params->dwPostSyncOp;
80         cmd.DW1.DestinationAddressType = UseGlobalGtt.m_cs;
81 
82         MHW_RESOURCE_PARAMS resourceParams;
83         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
84         resourceParams.presResource    = params->presDest;
85         resourceParams.dwOffset        = params->dwResourceOffset;
86         resourceParams.pdwCmd          = &(cmd.DW2.Value);
87         resourceParams.dwLocationInCmd = 2;
88         resourceParams.dwLsbNum        = MHW_COMMON_MI_PIPE_CONTROL_SHIFT;
89         resourceParams.bIsWritable     = true;
90         resourceParams.HwCommandType   = MOS_PIPE_CONTROL;
91 
92         MHW_MI_CHK_STATUS(AddResourceToCmd(
93             m_osInterface,
94             cmdBuffer,
95             &resourceParams));
96     }
97     else
98     {
99         if (MEDIA_IS_WA(pWaTable, Wa_14010840176))
100         {
101             cmd.DW0.HdcPipelineFlush                = true;
102             cmd.DW1.ConstantCacheInvalidationEnable = false;
103         }
104         else
105         {
106             cmd.DW1.ConstantCacheInvalidationEnable = true;
107         }
108         cmd.DW1.StateCacheInvalidationEnable     = true;
109         cmd.DW1.VfCacheInvalidationEnable        = true;
110         cmd.DW1.InstructionCacheInvalidateEnable = true;
111         cmd.DW1.RenderTargetCacheFlushEnable     = true;
112         cmd.DW1.PostSyncOperation                = cmd.POST_SYNC_OPERATION_NOWRITE;
113     }
114 
115     // Cache flush mode
116     switch (params->dwFlushMode)
117     {
118     // Flush all Write caches
119     case MHW_FLUSH_WRITE_CACHE:
120         cmd.DW1.RenderTargetCacheFlushEnable = true;
121         cmd.DW1.DcFlushEnable                = true;
122         break;
123 
124     // Invalidate all Read-only caches
125     case MHW_FLUSH_READ_CACHE:
126         if (MEDIA_IS_WA(pWaTable, Wa_14010840176))
127         {
128             cmd.DW0.HdcPipelineFlush                = true;
129             cmd.DW1.ConstantCacheInvalidationEnable = false;
130         }
131         else
132         {
133             cmd.DW1.ConstantCacheInvalidationEnable = true;
134         }
135         cmd.DW1.RenderTargetCacheFlushEnable     = false;
136         cmd.DW1.StateCacheInvalidationEnable     = true;
137         cmd.DW1.VfCacheInvalidationEnable        = true;
138         cmd.DW1.InstructionCacheInvalidateEnable = true;
139         break;
140 
141     // Custom flush parameters
142     case MHW_FLUSH_CUSTOM:
143         if (MEDIA_IS_WA(pWaTable, Wa_14010840176) && params->bInvalidateConstantCache)
144         {
145             cmd.DW0.HdcPipelineFlush                = true;
146             cmd.DW1.StateCacheInvalidationEnable    = true;
147             cmd.DW1.ConstantCacheInvalidationEnable = false;
148         }
149         else
150         {
151             cmd.DW1.StateCacheInvalidationEnable    = params->bInvalidateStateCache;
152             cmd.DW1.ConstantCacheInvalidationEnable = params->bInvalidateConstantCache;
153         }
154 
155         cmd.DW1.RenderTargetCacheFlushEnable     = params->bFlushRenderTargetCache;
156         cmd.DW1.DcFlushEnable                    = params->bFlushRenderTargetCache;  // same as above
157         cmd.DW1.VfCacheInvalidationEnable        = params->bInvalidateVFECache;
158         cmd.DW1.InstructionCacheInvalidateEnable = params->bInvalidateInstructionCache;
159         cmd.DW1.TlbInvalidate                    = params->bTlbInvalidate;
160         cmd.DW1.TextureCacheInvalidationEnable   = params->bInvalidateTextureCache;
161         break;
162 
163     // No-flush operation requested
164     case MHW_FLUSH_NONE:
165     default:
166         cmd.DW1.RenderTargetCacheFlushEnable = false;
167         break;
168     }
169 
170     // When PIPE_CONTROL stall bit is set, one of the following must also be set, otherwise set stall bit to 0
171     if (cmd.DW1.CommandStreamerStallEnable &&
172         (cmd.DW1.DcFlushEnable == 0 && cmd.DW1.NotifyEnable == 0 && cmd.DW1.PostSyncOperation == 0 &&
173             cmd.DW1.DepthStallEnable == 0 && cmd.DW1.StallAtPixelScoreboard == 0 && cmd.DW1.DepthCacheFlushEnable == 0 &&
174             cmd.DW1.RenderTargetCacheFlushEnable == 0) &&
175             !params->bKernelFenceEnabled)
176     {
177         cmd.DW1.CommandStreamerStallEnable = 0;
178     }
179 
180     if (params->bGenericMediaStateClear)
181     {
182         cmd.DW1.GenericMediaStateClear = true;
183     }
184 
185     if (params->bIndirectStatePointersDisable)
186     {
187         cmd.DW1.IndirectStatePointersDisable = true;
188     }
189 
190     if (params->bHdcPipelineFlush)
191     {
192         cmd.DW0.HdcPipelineFlush = true;
193     }
194 
195     MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize));
196 
197     return MOS_STATUS_SUCCESS;
198 }
199 
AddMiBatchBufferStartCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)200 MOS_STATUS MhwMiInterfaceG12::AddMiBatchBufferStartCmd(
201     PMOS_COMMAND_BUFFER                 cmdBuffer,
202     PMHW_BATCH_BUFFER                   batchBuffer)
203 {
204     MHW_FUNCTION_ENTER;
205 
206     MHW_MI_CHK_NULL(cmdBuffer);
207     MHW_MI_CHK_NULL(batchBuffer);
208     MHW_MI_CHK_NULL(m_osInterface);
209     bool vcsEngineUsed =
210         MOS_VCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface));
211 
212     mhw_mi_g12_X::MI_BATCH_BUFFER_START_CMD cmd;
213     MHW_RESOURCE_PARAMS                     resourceParams;
214     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
215     resourceParams.presResource     = &batchBuffer->OsResource;
216     resourceParams.dwOffset         = batchBuffer->dwOffset;
217     resourceParams.pdwCmd           = cmd.DW1_2.Value;
218     resourceParams.dwLocationInCmd  = 1;
219     resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
220     resourceParams.HwCommandType    = vcsEngineUsed ?
221         MOS_MI_BATCH_BUFFER_START : MOS_MI_BATCH_BUFFER_START_RCS;
222 
223     MHW_MI_CHK_STATUS(AddResourceToCmd(
224         m_osInterface,
225         cmdBuffer,
226         &resourceParams));
227 
228     // Set BB start
229     cmd.DW0.Obj3.SecondLevelBatchBuffer = true;
230     cmd.DW0.Obj0.AddressSpaceIndicator  = !IsGlobalGttInUse();
231 
232     // Send BB start command
233     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
234 
235     return MOS_STATUS_SUCCESS;
236 }
237 
AddMiBatchBufferStartCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,bool useChainedBB)238 MOS_STATUS MhwMiInterfaceG12::AddMiBatchBufferStartCmd(
239     PMOS_COMMAND_BUFFER cmdBuffer,
240     PMHW_BATCH_BUFFER   batchBuffer,
241     bool useChainedBB)
242 {
243     MHW_FUNCTION_ENTER;
244 
245     MHW_MI_CHK_NULL(cmdBuffer);
246     MHW_MI_CHK_NULL(batchBuffer);
247     MHW_MI_CHK_NULL(m_osInterface);
248     bool vcsEngineUsed =
249         MOS_VCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface));
250 
251     mhw_mi_g12_X::MI_BATCH_BUFFER_START_CMD cmd;
252     MHW_RESOURCE_PARAMS                     resourceParams;
253     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
254     resourceParams.presResource    = &batchBuffer->OsResource;
255     resourceParams.dwOffset        = batchBuffer->dwOffset;
256     resourceParams.pdwCmd          = cmd.DW1_2.Value;
257     resourceParams.dwLocationInCmd = 1;
258     resourceParams.dwLsbNum        = MHW_COMMON_MI_GENERAL_SHIFT;
259     resourceParams.HwCommandType   = vcsEngineUsed ? MOS_MI_BATCH_BUFFER_START : MOS_MI_BATCH_BUFFER_START_RCS;
260 
261     MHW_MI_CHK_STATUS(AddResourceToCmd(
262         m_osInterface,
263         cmdBuffer,
264         &resourceParams));
265 
266     // Set BB start
267     cmd.DW0.Obj3.SecondLevelBatchBuffer = useChainedBB ? false : true;
268     cmd.DW0.Obj0.AddressSpaceIndicator  = !IsGlobalGttInUse();
269 
270     // Send BB start command
271     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
272 
273     return MOS_STATUS_SUCCESS;
274 }
275 
AddMiConditionalBatchBufferEndCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS params)276 MOS_STATUS MhwMiInterfaceG12::AddMiConditionalBatchBufferEndCmd(
277     PMOS_COMMAND_BUFFER                             cmdBuffer,
278     PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS     params)
279 {
280     MHW_FUNCTION_ENTER;
281 
282     MHW_MI_CHK_NULL(m_osInterface);
283     MHW_MI_CHK_NULL(cmdBuffer);
284     MHW_MI_CHK_NULL(params);
285     MHW_MI_CHK_NULL(params->presSemaphoreBuffer);
286 
287     // Case 1 - Batch buffer condition matches - If this is not present then conditional
288     //          batch buffer will  exit to ring with terminating CP.
289     // Case 2 - Batch buffer condition DOES NOT match - Although this will disable CP
290     //          but after end of conditional batch buffer CP will be re-enabled.
291     MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(m_osInterface, cmdBuffer));
292 
293     mhw_mi_g12_X::MI_CONDITIONAL_BATCH_BUFFER_END_CMD cmd;
294     cmd.DW0.UseGlobalGtt        = IsGlobalGttInUse();
295     cmd.DW0.CompareSemaphore    = 1; // CompareDataDword is always assumed to be set
296     cmd.DW0.CompareMaskMode     = !params->bDisableCompareMask;
297     if (params->dwParamsType == MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS::ENHANCED_PARAMS)
298     {
299         cmd.DW0.EndCurrentBatchBufferLevel
300             = static_cast<MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS*>(params)->enableEndCurrentBatchBuffLevel;
301         cmd.DW0.CompareOperation
302             = static_cast<MHW_MI_ENHANCED_CONDITIONAL_BATCH_BUFFER_END_PARAMS*>(params)->compareOperation;
303     }
304     cmd.DW1.CompareDataDword    = params->dwValue;
305 
306     MHW_RESOURCE_PARAMS resourceParams;
307     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
308     resourceParams.presResource     = params->presSemaphoreBuffer;
309     resourceParams.dwOffset         = params->dwOffset;
310     resourceParams.pdwCmd           = cmd.DW2_3.Value;
311     resourceParams.dwLocationInCmd  = 2;
312     resourceParams.dwLsbNum         = MHW_COMMON_MI_CONDITIONAL_BATCH_BUFFER_END_SHIFT;
313     resourceParams.HwCommandType    = MOS_MI_CONDITIONAL_BATCH_BUFFER_END;
314 
315     MHW_MI_CHK_STATUS(AddResourceToCmd(
316         m_osInterface,
317         cmdBuffer,
318         &resourceParams));
319 
320     // Send Conditional Batch Buffer End command
321     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
322 
323     //Re-enable CP for Case 2
324     MHW_MI_CHK_STATUS(m_cpInterface->AddProlog(m_osInterface, cmdBuffer));
325 
326     return MOS_STATUS_SUCCESS;
327 }
328 
AddMiSetPredicateCmd(PMOS_COMMAND_BUFFER cmdBuffer,MHW_MI_SET_PREDICATE_ENABLE enableFlag)329 MOS_STATUS MhwMiInterfaceG12::AddMiSetPredicateCmd(
330     PMOS_COMMAND_BUFFER                 cmdBuffer,
331     MHW_MI_SET_PREDICATE_ENABLE         enableFlag)
332 {
333     MHW_FUNCTION_ENTER;
334 
335     MHW_MI_CHK_NULL(m_osInterface);
336     MHW_MI_CHK_NULL(cmdBuffer);
337 
338     mhw_mi_g12_X::MI_SET_PREDICATE_CMD cmd;
339     cmd.DW0.PredicateEnable = enableFlag;
340     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
341 
342     return MOS_STATUS_SUCCESS;
343 }
344 
AddMiStoreRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_STORE_REGISTER_MEM_PARAMS params)345 MOS_STATUS MhwMiInterfaceG12::AddMiStoreRegisterMemCmd(
346     PMOS_COMMAND_BUFFER                 cmdBuffer,
347     PMHW_MI_STORE_REGISTER_MEM_PARAMS   params)
348 {
349     MHW_FUNCTION_ENTER;
350 
351     MHW_MI_CHK_NULL(cmdBuffer);
352     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
353     MHW_MI_CHK_NULL(params);
354     MHW_MI_CHK_NULL(m_osInterface);
355 
356     mhw_mi_g12_X::MI_STORE_REGISTER_MEM_CMD cmd{};
357     MHW_RESOURCE_PARAMS resourceParams{};
358     resourceParams.presResource     = params->presStoreBuffer;
359     resourceParams.dwOffset         = params->dwOffset;
360     resourceParams.pdwCmd           = cmd.DW2_3.Value;
361     resourceParams.dwLocationInCmd  = 2;
362     resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
363     resourceParams.HwCommandType    = MOS_MI_STORE_REGISTER_MEM;
364     resourceParams.bIsWritable      = true;
365 
366     MHW_MI_CHK_STATUS(AddResourceToCmd(
367         m_osInterface,
368         cmdBuffer,
369         &resourceParams));
370 
371     cmd.DW0.UseGlobalGtt = IsGlobalGttInUse();
372     cmd.DW1.RegisterAddress = params->dwRegister >> 2;
373 
374     if (IsRelativeMMIO(params->dwRegister))
375     {
376         cmd.DW0.AddCsMmioStartOffset = 1;
377         cmd.DW1.RegisterAddress = params->dwRegister >> 2;
378     }
379 
380     if (params->dwOption == CCS_HW_FRONT_END_MMIO_REMAP)
381     {
382         MOS_GPU_CONTEXT gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
383 
384         if (MOS_RCS_ENGINE_USED(gpuContext))
385         {
386             params->dwRegister &= M_CCS_HW_FRONT_END_MMIO_MASK;
387             params->dwRegister += M_MMIO_CCS0_HW_FRONT_END_BASE_BEGIN;
388         }
389     }
390 
391     cmd.DW0.MmioRemapEnable = IsRemappingMMIO(params->dwRegister);
392 
393     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
394 
395     return MOS_STATUS_SUCCESS;
396 }
397 
AddMiLoadRegisterMemCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_MEM_PARAMS params)398 MOS_STATUS MhwMiInterfaceG12::AddMiLoadRegisterMemCmd(
399     PMOS_COMMAND_BUFFER                 cmdBuffer,
400     PMHW_MI_LOAD_REGISTER_MEM_PARAMS    params)
401 {
402     MHW_FUNCTION_ENTER;
403 
404     MHW_MI_CHK_NULL(cmdBuffer);
405     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
406     MHW_MI_CHK_NULL(params);
407 
408     mhw_mi_g12_X::MI_LOAD_REGISTER_MEM_CMD *cmd =
409         (mhw_mi_g12_X::MI_LOAD_REGISTER_MEM_CMD*)cmdBuffer->pCmdPtr;
410 
411     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiLoadRegisterMemCmd(cmdBuffer, params));
412 
413     if (IsRelativeMMIO(params->dwRegister))
414     {
415         cmd->DW0.AddCsMmioStartOffset = 1;
416         cmd->DW1.RegisterAddress = params->dwRegister >> 2;
417     }
418 
419     cmd->DW0.MmioRemapEnable = IsRemappingMMIO(params->dwRegister);
420 
421     return MOS_STATUS_SUCCESS;
422 }
423 
AddMiLoadRegisterImmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_IMM_PARAMS params)424 MOS_STATUS MhwMiInterfaceG12::AddMiLoadRegisterImmCmd(
425     PMOS_COMMAND_BUFFER                 cmdBuffer,
426     PMHW_MI_LOAD_REGISTER_IMM_PARAMS    params)
427 {
428     MHW_FUNCTION_ENTER;
429 
430     MHW_MI_CHK_NULL(cmdBuffer);
431     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
432     MHW_MI_CHK_NULL(params);
433 
434     mhw_mi_g12_X::MI_LOAD_REGISTER_IMM_CMD *cmd =
435         (mhw_mi_g12_X::MI_LOAD_REGISTER_IMM_CMD*)cmdBuffer->pCmdPtr;
436 
437     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiLoadRegisterImmCmd(cmdBuffer, params));
438 
439     if (IsRelativeMMIO(params->dwRegister))
440     {
441         cmd->DW0.AddCsMmioStartOffset = 1;
442         cmd->DW1.RegisterOffset = params->dwRegister >> 2;
443     }
444 
445     cmd->DW0.MmioRemapEnable = IsRemappingMMIO(params->dwRegister);
446 
447     return MOS_STATUS_SUCCESS;
448 }
449 
AddMiLoadRegisterRegCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_LOAD_REGISTER_REG_PARAMS params)450 MOS_STATUS MhwMiInterfaceG12::AddMiLoadRegisterRegCmd(
451     PMOS_COMMAND_BUFFER                 cmdBuffer,
452     PMHW_MI_LOAD_REGISTER_REG_PARAMS    params)
453 {
454     MHW_FUNCTION_ENTER;
455 
456     MHW_MI_CHK_NULL(cmdBuffer);
457     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
458     MHW_MI_CHK_NULL(params);
459 
460     mhw_mi_g12_X::MI_LOAD_REGISTER_REG_CMD *cmd =
461         (mhw_mi_g12_X::MI_LOAD_REGISTER_REG_CMD*)cmdBuffer->pCmdPtr;
462 
463     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiLoadRegisterRegCmd(cmdBuffer, params));
464 
465     if (IsRelativeMMIO(params->dwSrcRegister))
466     {
467         cmd->DW0.AddCsMmioStartOffsetSource = 1;
468         cmd->DW1.SourceRegisterAddress = params->dwSrcRegister >> 2;
469     }
470     if (IsRelativeMMIO(params->dwDstRegister))
471     {
472         cmd->DW0.AddCsMmioStartOffsetDestination = 1;
473         cmd->DW2.DestinationRegisterAddress = params->dwDstRegister >> 2;
474     }
475 
476     cmd->DW0.MmioRemapEnableSource      = IsRemappingMMIO(params->dwSrcRegister);
477     cmd->DW0.MmioRemapEnableDestination = IsRemappingMMIO(params->dwDstRegister);
478 
479     return MOS_STATUS_SUCCESS;
480 }
481 
AddMiForceWakeupCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_FORCE_WAKEUP_PARAMS params)482 MOS_STATUS MhwMiInterfaceG12::AddMiForceWakeupCmd(
483     PMOS_COMMAND_BUFFER                 cmdBuffer,
484     PMHW_MI_FORCE_WAKEUP_PARAMS         params)
485 {
486     MHW_FUNCTION_ENTER;
487 
488     MHW_MI_CHK_NULL(m_osInterface);
489     MHW_MI_CHK_NULL(cmdBuffer);
490     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
491     MHW_MI_CHK_NULL(params);
492 
493     mhw_mi_g12_X::MI_FORCE_WAKEUP_CMD cmd;
494     cmd.DW1.ForceMediaSlice0Awake               = params->bForceMediaSlice0Awake;
495     cmd.DW1.ForceRenderAwake                    = params->bForceRenderAwake;
496     cmd.DW1.ForceMediaSlice1Awake               = params->bForceMediaSlice1Awake;
497     cmd.DW1.ForceMediaSlice2Awake               = params->bForceMediaSlice2Awake;
498     cmd.DW1.ForceMediaSlice3Awake               = params->bForceMediaSlice3Awake;
499     cmd.DW1.HevcPowerWellControl                = params->bHEVCPowerWellControl;
500     cmd.DW1.MfxPowerWellControl                 = params->bMFXPowerWellControl;
501     cmd.DW1.MaskBits                            = params->bForceMediaSlice0AwakeMask;
502     cmd.DW1.MaskBits                            += (params->bForceRenderAwakeMask << 1);
503     cmd.DW1.MaskBits                            += (params->bForceMediaSlice1AwakeMask << 2);
504     cmd.DW1.MaskBits                            += (params->bForceMediaSlice2AwakeMask << 3);
505     cmd.DW1.MaskBits                            += (params->bForceMediaSlice3AwakeMask << 4);
506     cmd.DW1.MaskBits                            += (params->bHEVCPowerWellControlMask  << 8);
507     cmd.DW1.MaskBits                            += (params->bMFXPowerWellControlMask   << 9);
508 
509     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
510 
511     return MOS_STATUS_SUCCESS;
512 }
513 
AddMiVdControlStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_VD_CONTROL_STATE_PARAMS params)514 MOS_STATUS MhwMiInterfaceG12::AddMiVdControlStateCmd(
515     PMOS_COMMAND_BUFFER                  cmdBuffer,
516     PMHW_MI_VD_CONTROL_STATE_PARAMS      params)
517 {
518     MHW_FUNCTION_ENTER;
519 
520     MHW_MI_CHK_NULL(m_osInterface);
521     MHW_MI_CHK_NULL(cmdBuffer);
522     MHW_MI_CHK_NULL(params);
523 
524     mhw_mi_g12_X::VD_CONTROL_STATE_CMD cmd;
525 
526     if (params->vdencEnabled)
527     {
528         cmd.DW0.MediaInstructionCommand =
529             mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORVDENC;
530         cmd.DW0.MediaInstructionOpcode  =
531             mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORVDENC;
532     }
533     else
534     {
535         cmd.DW0.MediaInstructionCommand =
536             mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_COMMAND_VDCONTROLSTATEFORHCP;
537         if (params->avpEnabled)
538         {
539             cmd.DW0.MediaInstructionOpcode =
540                 mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORAVP;
541         }
542         else
543         {
544             cmd.DW0.MediaInstructionOpcode =
545                 mhw_mi_g12_X::VD_CONTROL_STATE_CMD::MEDIA_INSTRUCTION_OPCODE_CODECENGINENAMEFORHCP;
546         }
547 
548         cmd.DW1.PipelineInitialization  = params->initialization;
549         cmd.DW2.MemoryImplicitFlush     = params->memoryImplicitFlush;
550         cmd.DW2.ScalableModePipeLock    = params->scalableModePipeLock;
551         cmd.DW2.ScalableModePipeUnlock  = params->scalableModePipeUnlock;
552     }
553 
554     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd)));
555 
556     return MOS_STATUS_SUCCESS;
557 }
558 
InitMmioRegisters()559 void MhwMiInterfaceG12::InitMmioRegisters()
560 {
561     MHW_MI_MMIOREGISTERS *mmioRegisters = &m_mmioRegisters;
562 
563     mmioRegisters->generalPurposeRegister0LoOffset            = GP_REGISTER0_LO_OFFSET_G12;
564     mmioRegisters->generalPurposeRegister0HiOffset            = GP_REGISTER0_HI_OFFSET_G12;
565     mmioRegisters->generalPurposeRegister4LoOffset            = GP_REGISTER4_LO_OFFSET_G12;
566     mmioRegisters->generalPurposeRegister4HiOffset            = GP_REGISTER4_HI_OFFSET_G12;
567     mmioRegisters->generalPurposeRegister11LoOffset           = GP_REGISTER11_LO_OFFSET_G12;
568     mmioRegisters->generalPurposeRegister11HiOffset           = GP_REGISTER11_HI_OFFSET_G12;
569     mmioRegisters->generalPurposeRegister12LoOffset           = GP_REGISTER12_LO_OFFSET_G12;
570     mmioRegisters->generalPurposeRegister12HiOffset           = GP_REGISTER12_HI_OFFSET_G12;
571 }
572 
SetWatchdogTimerThreshold(uint32_t frameWidth,uint32_t frameHeight,bool isEncoder)573 MOS_STATUS MhwMiInterfaceG12::SetWatchdogTimerThreshold(uint32_t frameWidth, uint32_t frameHeight, bool isEncoder)
574 {
575     MEDIA_WA_TABLE *waTable = nullptr;
576 
577     MHW_FUNCTION_ENTER;
578     MHW_MI_CHK_NULL(m_osInterface);
579     if (m_osInterface->bMediaReset == false ||
580         m_osInterface->umdMediaResetEnable == false)
581     {
582         return MOS_STATUS_SUCCESS;
583     }
584 
585     waTable = m_osInterface->pfnGetWaTable(m_osInterface);
586     MHW_CHK_NULL_RETURN(waTable);
587 
588     if (isEncoder)
589     {
590         if ((frameWidth * frameHeight) >= (7680 * 4320))
591         {
592             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_16K_WATCHDOG_THRESHOLD_IN_MS;
593         }
594         else if ((frameWidth * frameHeight) >= (3840 * 2160))
595         {
596             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_8K_WATCHDOG_THRESHOLD_IN_MS;
597         }
598         else if ((frameWidth * frameHeight) >= (1920 * 1080))
599         {
600             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_4K_WATCHDOG_THRESHOLD_IN_MS;
601         }
602         else
603         {
604             MediaResetParam.watchdogCountThreshold = MHW_MI_ENCODER_FHD_WATCHDOG_THRESHOLD_IN_MS;
605         }
606     }
607     else
608     {
609         if ((frameWidth * frameHeight) >= (7680 * 4320))
610         {
611             MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_8K_WATCHDOG_THRESHOLD_IN_MS;
612         }
613         else if ((frameWidth * frameHeight) >= (3840 * 2160))
614         {
615             MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_4K_WATCHDOG_THRESHOLD_IN_MS;
616         }
617         else
618         {
619             MediaResetParam.watchdogCountThreshold = MHW_MI_DECODER_720P_WATCHDOG_THRESHOLD_IN_MS;
620         }
621     }
622 
623     GetWatchdogThreshold(m_osInterface);
624 
625     return MOS_STATUS_SUCCESS;
626 }
627 
SetWatchdogTimerRegisterOffset(MOS_GPU_CONTEXT gpuContext)628 MOS_STATUS MhwMiInterfaceG12::SetWatchdogTimerRegisterOffset(
629     MOS_GPU_CONTEXT                 gpuContext)
630 {
631     MHW_FUNCTION_ENTER;
632 
633     switch (gpuContext)
634     {
635         // RCS
636     case MOS_GPU_CONTEXT_RENDER:
637     case MOS_GPU_CONTEXT_RENDER2:
638     case MOS_GPU_CONTEXT_RENDER3:
639     case MOS_GPU_CONTEXT_RENDER4:
640     case MOS_GPU_CONTEXT_COMPUTE:
641     case MOS_GPU_CONTEXT_CM_COMPUTE:
642     case MOS_GPU_CONTEXT_RENDER_RA:
643     case MOS_GPU_CONTEXT_COMPUTE_RA:
644         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_RCS_G12;
645         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_RCS_G12;
646         break;
647         // VCS0
648     case MOS_GPU_CONTEXT_VIDEO:
649     case MOS_GPU_CONTEXT_VIDEO2:
650     case MOS_GPU_CONTEXT_VIDEO3:
651     case MOS_GPU_CONTEXT_VIDEO4:
652     case MOS_GPU_CONTEXT_VIDEO5:
653     case MOS_GPU_CONTEXT_VIDEO6:
654     case MOS_GPU_CONTEXT_VIDEO7:
655         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_VCS0_G12;
656         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VCS0_G12;
657         break;
658         // VCS1
659     case MOS_GPU_CONTEXT_VDBOX2_VIDEO:
660     case MOS_GPU_CONTEXT_VDBOX2_VIDEO2:
661     case MOS_GPU_CONTEXT_VDBOX2_VIDEO3:
662         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_VCS1_G12;
663         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VCS1_G12;
664         break;
665         // VECS
666     case MOS_GPU_CONTEXT_VEBOX:
667         MediaResetParam.watchdogCountCtrlOffset = WATCHDOG_COUNT_CTRL_OFFSET_VECS_G12;
668         MediaResetParam.watchdogCountThresholdOffset = WATCHDOG_COUNT_THRESTHOLD_OFFSET_VECS_G12;
669         break;
670         // Default
671     default:
672         break;
673     }
674 
675     return MOS_STATUS_SUCCESS;
676 }
677 
AddWatchdogTimerStartCmd(PMOS_COMMAND_BUFFER cmdBuffer)678 MOS_STATUS MhwMiInterfaceG12::AddWatchdogTimerStartCmd(
679     PMOS_COMMAND_BUFFER                 cmdBuffer)
680 {
681     MOS_GPU_CONTEXT gpuContext;
682 
683     MHW_FUNCTION_ENTER;
684     MHW_MI_CHK_NULL(m_osInterface);
685     if (m_osInterface->bMediaReset == false ||
686         m_osInterface->umdMediaResetEnable == false)
687     {
688         return MOS_STATUS_SUCCESS;
689     }
690 
691     MHW_MI_CHK_NULL(cmdBuffer);
692 
693     // Set Watchdog Timer Register Offset
694     gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
695     MHW_MI_CHK_STATUS(SetWatchdogTimerRegisterOffset(gpuContext));
696 
697     // Send Stop before Start is to help recover from incorrect wdt state if previous submission
698     // cause hang and not have a chance to execute the stop cmd in the end of batch buffer.
699     MHW_MI_CHK_STATUS(AddWatchdogTimerStopCmd(cmdBuffer));
700 
701     //Configure Watchdog timer Threshold
702     MHW_MI_LOAD_REGISTER_IMM_PARAMS registerImmParams;
703     MOS_ZeroMemory(&registerImmParams, sizeof(registerImmParams));
704     registerImmParams.dwData = MHW_MI_WATCHDOG_COUNTS_PER_MILLISECOND * MediaResetParam.watchdogCountThreshold *
705         (m_osInterface->bSimIsActive ? 2 : 1);
706     registerImmParams.dwRegister = MediaResetParam.watchdogCountThresholdOffset;
707     MHW_MI_CHK_STATUS(AddMiLoadRegisterImmCmd(
708         cmdBuffer,
709         &registerImmParams));
710 
711     MHW_VERBOSEMESSAGE("MediaReset Threshold is %d", MediaResetParam.watchdogCountThreshold * (m_osInterface->bSimIsActive ? 2 : 1));
712 
713     //Start Watchdog Timer
714     registerImmParams.dwData = MHW_MI_WATCHDOG_ENABLE_COUNTER;
715     registerImmParams.dwRegister = MediaResetParam.watchdogCountCtrlOffset;
716     MHW_MI_CHK_STATUS(AddMiLoadRegisterImmCmd(
717         cmdBuffer,
718         &registerImmParams));
719 
720     return MOS_STATUS_SUCCESS;
721 }
722 
AddWatchdogTimerStopCmd(PMOS_COMMAND_BUFFER cmdBuffer)723 MOS_STATUS MhwMiInterfaceG12::AddWatchdogTimerStopCmd(
724     PMOS_COMMAND_BUFFER                 cmdBuffer)
725 {
726     MOS_GPU_CONTEXT gpuContext;
727 
728     MHW_FUNCTION_ENTER;
729     MHW_MI_CHK_NULL(m_osInterface);
730     if (m_osInterface->bMediaReset == false ||
731         m_osInterface->umdMediaResetEnable == false)
732     {
733         return MOS_STATUS_SUCCESS;
734     }
735 
736     MHW_MI_CHK_NULL(cmdBuffer);
737 
738     // Set Watchdog Timer Register Offset
739     gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
740     MHW_MI_CHK_STATUS(SetWatchdogTimerRegisterOffset(gpuContext));
741 
742     //Stop Watchdog Timer
743     MHW_MI_LOAD_REGISTER_IMM_PARAMS registerImmParams;
744     MOS_ZeroMemory(&registerImmParams, sizeof(registerImmParams));
745     registerImmParams.dwData = MHW_MI_WATCHDOG_DISABLE_COUNTER;
746     registerImmParams.dwRegister = MediaResetParam.watchdogCountCtrlOffset;
747     MHW_MI_CHK_STATUS(AddMiLoadRegisterImmCmd(
748         cmdBuffer,
749         &registerImmParams));
750 
751     return MOS_STATUS_SUCCESS;
752 }
753 
AddMediaStateFlush(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_MEDIA_STATE_FLUSH_PARAM params)754 MOS_STATUS MhwMiInterfaceG12::AddMediaStateFlush(
755     PMOS_COMMAND_BUFFER          cmdBuffer,
756     PMHW_BATCH_BUFFER            batchBuffer,
757     PMHW_MEDIA_STATE_FLUSH_PARAM params)
758 {
759     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMediaStateFlush(cmdBuffer, batchBuffer, params));
760 
761     mhw_mi_g12_X::MEDIA_STATE_FLUSH_CMD cmd;
762 
763     if (params != nullptr)
764     {
765         cmd.DW1.FlushToGo                 = params->bFlushToGo;
766         cmd.DW1.InterfaceDescriptorOffset = params->ui8InterfaceDescriptorOffset;
767     }
768 
769     MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, cmd.byteSize));
770 
771 #if (_DEBUG || _RELEASE_INTERNAL)
772     if (batchBuffer)
773     {
774         batchBuffer->iLastCurrent = batchBuffer->iCurrent;
775     }
776 #endif
777 
778     return MOS_STATUS_SUCCESS;
779 }
780 
SkipMiBatchBufferEndBb(PMHW_BATCH_BUFFER batchBuffer)781 MOS_STATUS MhwMiInterfaceG12::SkipMiBatchBufferEndBb(
782     PMHW_BATCH_BUFFER batchBuffer)
783 {
784     MHW_FUNCTION_ENTER;
785 
786     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::SkipMiBatchBufferEndBb(batchBuffer));
787     MHW_MI_CHK_NULL(m_osInterface);
788     auto waTable = m_osInterface->pfnGetWaTable(m_osInterface);
789     MHW_MI_CHK_NULL(waTable);
790 
791     // This WA does not apply for video or other engines, render requirement only
792     bool isRender =
793         MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface));
794 
795     if (isRender && (MEDIA_IS_WA(waTable, WaMSFWithNoWatermarkTSGHang) ||
796                         MEDIA_IS_WA(waTable, WaAddMediaStateFlushCmd)))
797     {
798         mhw_mi_g12_X::MEDIA_STATE_FLUSH_CMD FlushCmd;
799         MHW_MI_CHK_STATUS(Mhw_AddCommandBB(
800             batchBuffer,
801             nullptr,
802             FlushCmd.byteSize));
803     }
804 
805     mhw_mi_g12_X::MI_BATCH_BUFFER_END_CMD cmd;
806     MHW_MI_CHK_STATUS(Mhw_AddCommandBB(
807         batchBuffer,
808         nullptr,
809         cmd.byteSize));
810 
811     return MOS_STATUS_SUCCESS;
812 }
813 
AddMiFlushDwCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_FLUSH_DW_PARAMS params)814 MOS_STATUS MhwMiInterfaceG12::AddMiFlushDwCmd(
815     PMOS_COMMAND_BUFFER     cmdBuffer,
816     PMHW_MI_FLUSH_DW_PARAMS params)
817 {
818     MHW_FUNCTION_ENTER;
819 
820     MHW_MI_CHK_NULL(m_osInterface);
821     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g12_X>::AddMiFlushDwCmd(cmdBuffer, params));
822 
823     mhw_mi_g12_X::MI_FLUSH_DW_CMD cmd;
824 
825     // set the protection bit based on CP status
826     MHW_MI_CHK_STATUS(m_cpInterface->SetProtectionSettingsForMiFlushDw(m_osInterface, &cmd));
827 
828     cmd.DW0.VideoPipelineCacheInvalidate = params->bVideoPipelineCacheInvalidate;
829     cmd.DW0.PostSyncOperation = cmd.POST_SYNC_OPERATION_NOWRITE;
830     cmd.DW3_4.Value[0]        = params->dwDataDW1;
831 
832     if (params->pOsResource)
833     {
834         cmd.DW0.PostSyncOperation = cmd.POST_SYNC_OPERATION_WRITEIMMEDIATEDATA;
835         cmd.DW1_2.DestinationAddressType = UseGlobalGtt.m_vcs;
836 
837         MHW_RESOURCE_PARAMS resourceParams;
838         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
839         resourceParams.presResource = params->pOsResource;
840         resourceParams.dwOffset     = params->dwResourceOffset;
841         resourceParams.pdwCmd          = cmd.DW1_2.Value;
842         resourceParams.dwLocationInCmd = 1;
843         resourceParams.dwLsbNum        = MHW_COMMON_MI_FLUSH_DW_SHIFT;
844         resourceParams.HwCommandType   = MOS_MI_FLUSH_DW;
845         resourceParams.bIsWritable     = true;
846 
847         MHW_MI_CHK_STATUS(AddResourceToCmd(
848             m_osInterface,
849             cmdBuffer,
850             &resourceParams));
851     }
852 
853     if (params->postSyncOperation)
854     {
855         cmd.DW0.PostSyncOperation = params->postSyncOperation;
856     }
857 
858     if (params->dwDataDW2 || params->bQWordEnable)
859     {
860         cmd.DW3_4.Value[1] = params->dwDataDW2;
861     }
862     else
863     {
864         cmd.DW0.DwordLength--;
865     }
866 
867     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
868 
869     return MOS_STATUS_SUCCESS;
870 }