xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/gen9/hw/mhw_mi_g9_X.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2014-2018, 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 //!
23 //! \file     mhw_mi_g9_X.cpp
24 //! \brief    Constructs MI commands on Gen9-based platforms
25 //! \details  Each client facing function both creates a HW command and adds
26 //!           that command to a command or batch buffer.
27 //!
28 
29 #include "mhw_mi_g9_X.h"
30 #include "mhw_mi_hwcmd_g9_X.h"
31 #include "mhw_mmio_g9.h"
32 
AddMiSemaphoreWaitCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_SEMAPHORE_WAIT_PARAMS params)33 MOS_STATUS MhwMiInterfaceG9::AddMiSemaphoreWaitCmd(
34     PMOS_COMMAND_BUFFER             cmdBuffer,
35     PMHW_MI_SEMAPHORE_WAIT_PARAMS   params)
36 {
37     MHW_FUNCTION_ENTER;
38 
39     MHW_MI_CHK_NULL(cmdBuffer);
40     MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
41     MHW_MI_CHK_NULL(params);
42 
43     mhw_mi_g9_X::MI_SEMAPHORE_WAIT_CMD *cmd =
44         (mhw_mi_g9_X::MI_SEMAPHORE_WAIT_CMD*)cmdBuffer->pCmdPtr;
45 
46     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g9_X>::AddMiSemaphoreWaitCmd(cmdBuffer, params));
47 
48     cmd->DW0.RegisterPollMode = params->bRegisterPollMode;
49 
50     return MOS_STATUS_SUCCESS;
51 }
52 
AddMiBatchBufferStartCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer)53 MOS_STATUS MhwMiInterfaceG9::AddMiBatchBufferStartCmd(
54     PMOS_COMMAND_BUFFER                 cmdBuffer,
55     PMHW_BATCH_BUFFER                   batchBuffer)
56 {
57     MHW_FUNCTION_ENTER;
58 
59     MHW_MI_CHK_NULL(m_osInterface);
60     MHW_MI_CHK_NULL(cmdBuffer);
61     MHW_MI_CHK_NULL(batchBuffer);
62 
63     bool vcsEngineUsed =
64         MOS_VCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface));
65 
66     mhw_mi_g9_X::MI_BATCH_BUFFER_START_CMD  cmd;
67     MHW_RESOURCE_PARAMS                     resourceParams;
68     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
69     resourceParams.presResource     = &batchBuffer->OsResource;
70     resourceParams.dwOffset         = batchBuffer->dwOffset;
71     resourceParams.pdwCmd           = cmd.DW1_2.Value;
72     resourceParams.dwLocationInCmd  = 1;
73     resourceParams.dwLsbNum         = MHW_COMMON_MI_GENERAL_SHIFT;
74     resourceParams.HwCommandType    = vcsEngineUsed ?
75         MOS_MI_BATCH_BUFFER_START : MOS_MI_BATCH_BUFFER_START_RCS;
76 
77     MHW_MI_CHK_STATUS(AddResourceToCmd(
78         m_osInterface,
79         cmdBuffer,
80         &resourceParams));
81 
82     // Set BB start
83     cmd.DW0.SecondLevelBatchBuffer = true;
84     cmd.DW0.AddressSpaceIndicator = !IsGlobalGttInUse();
85 
86     // Send BB start command
87     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
88 
89     return MOS_STATUS_SUCCESS;
90 }
91 
AddMiConditionalBatchBufferEndCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS params)92 MOS_STATUS MhwMiInterfaceG9::AddMiConditionalBatchBufferEndCmd(
93     PMOS_COMMAND_BUFFER                             cmdBuffer,
94     PMHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS     params)
95 {
96     MHW_FUNCTION_ENTER;
97 
98     MHW_MI_CHK_NULL(m_osInterface);
99     MHW_MI_CHK_NULL(cmdBuffer);
100     MHW_MI_CHK_NULL(params);
101     MHW_MI_CHK_NULL(params->presSemaphoreBuffer);
102 
103     // Case 1 - Batch buffer condition matches - If this is not present then conditional
104     //          batch buffer will  exit to ring with terminating CP.
105     // Case 2 - Batch buffer condition DOES NOT match - Although this will disable CP
106     //          but after end of conditional batch buffer CP will be re-enabled.
107     MHW_MI_CHK_STATUS(m_cpInterface->AddEpilog(m_osInterface, cmdBuffer));
108 
109     mhw_mi_g9_X::MI_CONDITIONAL_BATCH_BUFFER_END_CMD cmd;
110     cmd.DW0.UseGlobalGtt        = IsGlobalGttInUse();
111     cmd.DW0.CompareSemaphore    = 1; // CompareDataDword is always assumed to be set
112     cmd.DW0.CompareMaskMode     = !params->bDisableCompareMask;
113     cmd.DW1.CompareDataDword    = params->dwValue;
114 
115     MHW_RESOURCE_PARAMS resourceParams;
116     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
117     resourceParams.presResource      = params->presSemaphoreBuffer;
118     resourceParams.dwOffset         = params->dwOffset;
119     resourceParams.pdwCmd           = cmd.DW2_3.Value;
120     resourceParams.dwLocationInCmd  = 2;
121     resourceParams.dwLsbNum         = MHW_COMMON_MI_CONDITIONAL_BATCH_BUFFER_END_SHIFT;
122     resourceParams.HwCommandType    = MOS_MI_CONDITIONAL_BATCH_BUFFER_END;
123 
124     MHW_MI_CHK_STATUS(AddResourceToCmd(
125         m_osInterface,
126         cmdBuffer,
127         &resourceParams));
128 
129     // Send Conditional Batch Buffer End command
130     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
131 
132     //Re-enable CP for Case 2
133     MHW_MI_CHK_STATUS(m_cpInterface->AddProlog(m_osInterface, cmdBuffer));
134 
135     return MOS_STATUS_SUCCESS;
136 }
137 
AddMediaStateFlush(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_MEDIA_STATE_FLUSH_PARAM params)138 MOS_STATUS MhwMiInterfaceG9::AddMediaStateFlush(
139     PMOS_COMMAND_BUFFER             cmdBuffer,
140     PMHW_BATCH_BUFFER               batchBuffer,
141     PMHW_MEDIA_STATE_FLUSH_PARAM    params)
142 {
143     MHW_FUNCTION_ENTER;
144 
145     mhw_mi_g9_X::MEDIA_STATE_FLUSH_CMD *cmd = nullptr;
146 
147     if (cmdBuffer)
148     {
149         MHW_MI_CHK_NULL(cmdBuffer->pCmdPtr);
150         cmd = (mhw_mi_g9_X::MEDIA_STATE_FLUSH_CMD *)cmdBuffer->pCmdPtr;
151     }
152     else if (batchBuffer)
153     {
154         MHW_MI_CHK_NULL(batchBuffer->pData);
155         cmd = (mhw_mi_g9_X::MEDIA_STATE_FLUSH_CMD *)(batchBuffer->pData + batchBuffer->iCurrent);
156     }
157     else
158     {
159         MHW_ASSERTMESSAGE("No valid buffer to add the command to!");
160         return MOS_STATUS_INVALID_PARAMETER;
161     }
162 
163     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g9_X>::AddMediaStateFlush(cmdBuffer, batchBuffer, params));
164 
165     mhw_mi_g9_X::MEDIA_STATE_FLUSH_CMD AddMediaStateFlushcmd;
166 
167     if (params != nullptr)
168     {
169         AddMediaStateFlushcmd.DW1.FlushToGo                 = params->bFlushToGo;
170         AddMediaStateFlushcmd.DW1.InterfaceDescriptorOffset = params->ui8InterfaceDescriptorOffset;
171     }
172 
173     MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &AddMediaStateFlushcmd, AddMediaStateFlushcmd.byteSize));
174 
175 #if (_DEBUG || _RELEASE_INTERNAL)
176     if (batchBuffer)
177     {
178         batchBuffer->iLastCurrent = batchBuffer->iCurrent;
179     }
180 #endif
181 
182     auto waTable = m_osInterface->pfnGetWaTable(m_osInterface);
183     MHW_MI_CHK_NULL(waTable);
184 
185     if (MEDIA_IS_WA(waTable, WaMSFWithNoWatermarkTSGHang))
186     {
187         cmd->DW1.WatermarkRequired = 0;
188         cmd->DW1.FlushToGo         = 1;
189     }
190 
191     return MOS_STATUS_SUCCESS;
192 }
193 
InitMmioRegisters()194 void MhwMiInterfaceG9::InitMmioRegisters()
195 {
196     MHW_MI_MMIOREGISTERS *mmioRegisters = &m_mmioRegisters;
197 
198     mmioRegisters->generalPurposeRegister0LoOffset            = GP_REGISTER0_LO_OFFSET_G9;
199     mmioRegisters->generalPurposeRegister0HiOffset            = GP_REGISTER0_HI_OFFSET_G9;
200     mmioRegisters->generalPurposeRegister4LoOffset            = GP_REGISTER4_LO_OFFSET_G9;
201     mmioRegisters->generalPurposeRegister4HiOffset            = GP_REGISTER4_HI_OFFSET_G9;
202     mmioRegisters->generalPurposeRegister11LoOffset           = GP_REGISTER11_LO_OFFSET_G9;
203     mmioRegisters->generalPurposeRegister11HiOffset           = GP_REGISTER11_HI_OFFSET_G9;
204     mmioRegisters->generalPurposeRegister12LoOffset           = GP_REGISTER12_LO_OFFSET_G9;
205     mmioRegisters->generalPurposeRegister12HiOffset           = GP_REGISTER12_HI_OFFSET_G9;
206 }
207 
SkipMiBatchBufferEndBb(PMHW_BATCH_BUFFER batchBuffer)208 MOS_STATUS MhwMiInterfaceG9::SkipMiBatchBufferEndBb(
209     PMHW_BATCH_BUFFER batchBuffer)
210 {
211     MHW_FUNCTION_ENTER;
212 
213     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g9_X>::SkipMiBatchBufferEndBb(batchBuffer));
214 
215     auto waTable = m_osInterface->pfnGetWaTable(m_osInterface);
216     MHW_MI_CHK_NULL(waTable);
217 
218     // This WA does not apply for video or other engines, render requirement only
219     bool isRender =
220         MOS_RCS_ENGINE_USED(m_osInterface->pfnGetGpuContext(m_osInterface));
221 
222     if (isRender && (MEDIA_IS_WA(waTable, WaMSFWithNoWatermarkTSGHang) ||
223                         MEDIA_IS_WA(waTable, WaAddMediaStateFlushCmd)))
224     {
225         mhw_mi_g9_X::MEDIA_STATE_FLUSH_CMD FlushCmd;
226         MHW_MI_CHK_STATUS(Mhw_AddCommandBB(
227             batchBuffer,
228             nullptr,
229             FlushCmd.byteSize));
230     }
231 
232     mhw_mi_g9_X::MI_BATCH_BUFFER_END_CMD cmd;
233     MHW_MI_CHK_STATUS(Mhw_AddCommandBB(
234         batchBuffer,
235         nullptr,
236         cmd.byteSize));
237 
238     return MOS_STATUS_SUCCESS;
239 }
240 
AddMiFlushDwCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_MI_FLUSH_DW_PARAMS params)241 MOS_STATUS MhwMiInterfaceG9::AddMiFlushDwCmd(
242     PMOS_COMMAND_BUFFER     cmdBuffer,
243     PMHW_MI_FLUSH_DW_PARAMS params)
244 {
245     MHW_FUNCTION_ENTER;
246 
247     MHW_MI_CHK_NULL(m_osInterface);
248     MHW_MI_CHK_STATUS(MhwMiInterfaceGeneric<mhw_mi_g9_X>::AddMiFlushDwCmd(cmdBuffer, params));
249 
250     mhw_mi_g9_X::MI_FLUSH_DW_CMD cmd;
251 
252     // set the protection bit based on CP status
253     MHW_MI_CHK_STATUS(m_cpInterface->SetProtectionSettingsForMiFlushDw(m_osInterface, &cmd));
254 
255     cmd.DW0.VideoPipelineCacheInvalidate = params->bVideoPipelineCacheInvalidate;
256     cmd.DW0.PostSyncOperation            = cmd.POST_SYNC_OPERATION_NOWRITE;
257     cmd.DW3_4.Value[0]                   = params->dwDataDW1;
258 
259     if (params->pOsResource)
260     {
261         cmd.DW0.PostSyncOperation        = cmd.POST_SYNC_OPERATION_WRITEIMMEDIATEDATA;
262         cmd.DW1_2.DestinationAddressType = UseGlobalGtt.m_vcs;
263 
264         MHW_RESOURCE_PARAMS resourceParams;
265         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
266         resourceParams.presResource    = params->pOsResource;
267         resourceParams.dwOffset        = params->dwResourceOffset;
268         resourceParams.pdwCmd          = cmd.DW1_2.Value;
269         resourceParams.dwLocationInCmd = 1;
270         resourceParams.dwLsbNum        = MHW_COMMON_MI_FLUSH_DW_SHIFT;
271         resourceParams.HwCommandType   = MOS_MI_FLUSH_DW;
272         resourceParams.bIsWritable     = true;
273 
274         MHW_MI_CHK_STATUS(AddResourceToCmd(
275             m_osInterface,
276             cmdBuffer,
277             &resourceParams));
278     }
279 
280     if (params->postSyncOperation)
281     {
282         cmd.DW0.PostSyncOperation = params->postSyncOperation;
283     }
284 
285     if (params->dwDataDW2 || params->bQWordEnable)
286     {
287         cmd.DW3_4.Value[1] = params->dwDataDW2;
288     }
289     else
290     {
291         cmd.DW0.DwordLength--;
292     }
293 
294     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
295 
296     return MOS_STATUS_SUCCESS;
297 }
298