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(®isterImmParams, 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 ®isterImmParams));
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 ®isterImmParams));
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(®isterImmParams, sizeof(registerImmParams));
745 registerImmParams.dwData = MHW_MI_WATCHDOG_DISABLE_COUNTER;
746 registerImmParams.dwRegister = MediaResetParam.watchdogCountCtrlOffset;
747 MHW_MI_CHK_STATUS(AddMiLoadRegisterImmCmd(
748 cmdBuffer,
749 ®isterImmParams));
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 }