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