1 /*
2 * Copyright (c) 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 
23 //!
24 //! \file     decode_huc.cpp
25 //! \brief    Defines the common interface for decode huc implementation
26 //! \details  The decode huc interface is further sub-divided by different huc usage,
27 //!           this file is for the base interface which is shared by all.
28 //!
29 
30 #include "decode_huc_g12_base.h"
31 #include "codechal_debug.h"
32 #include "decode_pipeline.h"
33 #include "decode_predication_packet_g12.h"
34 #include "decode_marker_packet_g12.h"
35 
36 namespace decode
37 {
38 
DecodeHucBasic_G12_Base(MediaPipeline * pipeline,MediaTask * task,CodechalHwInterface * hwInterface)39 DecodeHucBasic_G12_Base::DecodeHucBasic_G12_Base(MediaPipeline *pipeline, MediaTask *task, CodechalHwInterface *hwInterface)
40     : CmdPacket(task)
41 {
42     m_pipeline = dynamic_cast<DecodePipeline *>(pipeline);
43     if (m_pipeline != nullptr)
44     {
45         m_featureManager = m_pipeline->GetFeatureManager();
46         m_allocator      = m_pipeline->GetDecodeAllocator();
47         m_decodecp       = m_pipeline->GetDecodeCp();
48     }
49 
50     if (hwInterface != nullptr)
51     {
52         m_hwInterface    = hwInterface;
53         m_osInterface    = hwInterface->GetOsInterface();
54         m_hucInterface   = hwInterface->GetHucInterface();
55         m_miInterface    = hwInterface->GetMiInterface();
56         m_vdencInterface = hwInterface->GetVdencInterface();
57     }
58 }
59 
~DecodeHucBasic_G12_Base()60 DecodeHucBasic_G12_Base::~DecodeHucBasic_G12_Base()
61 {
62 }
63 
Init()64 MOS_STATUS DecodeHucBasic_G12_Base::Init()
65 {
66     DECODE_CHK_NULL(m_pipeline);
67     DECODE_CHK_NULL(m_featureManager);
68     DECODE_CHK_NULL(m_osInterface);
69     DECODE_CHK_NULL(m_hucInterface);
70     DECODE_CHK_NULL(m_miInterface);
71     DECODE_CHK_NULL(m_vdencInterface);
72 
73     m_basicFeature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
74     DECODE_CHK_NULL(m_basicFeature);
75 
76     DECODE_CHK_STATUS(CmdPacket::Init());
77     DECODE_CHK_STATUS(AllocateResources());
78 
79     return MOS_STATUS_SUCCESS;
80 }
81 
AllocateResources()82 MOS_STATUS DecodeHucBasic_G12_Base::AllocateResources()
83 {
84     DECODE_CHK_NULL(m_allocator);
85 
86     return MOS_STATUS_SUCCESS;
87 }
88 
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)89 MOS_STATUS DecodeHucBasic_G12_Base::Completed(void* mfxStatus, void* rcsStatus, void* statusReport)
90 {
91     DECODE_FUNC_CALL();
92 
93     DECODE_CHK_NULL(mfxStatus);
94     DECODE_CHK_NULL(statusReport);
95 
96     DecodeStatusMfx* decodeStatusMfx = (DecodeStatusMfx*)mfxStatus;
97     DecodeStatusReportData* statusReportData = (DecodeStatusReportData*)statusReport;
98 
99     // Print HuC_Status and HuC_Status2 registers
100     DECODE_VERBOSEMESSAGE("Index = %d", statusReportData->currDecodedPic.FrameIdx);
101     DECODE_VERBOSEMESSAGE("HUC_STATUS register = 0x%x",
102         decodeStatusMfx->m_hucErrorStatus >> 32);
103     DECODE_VERBOSEMESSAGE("HUC_STATUS2 register = 0x%x",
104         decodeStatusMfx->m_hucErrorStatus2 >> 32);
105 
106     return MOS_STATUS_SUCCESS;
107 }
108 
Destroy()109 MOS_STATUS DecodeHucBasic_G12_Base::Destroy()
110 {
111     return MOS_STATUS_SUCCESS;
112 }
113 
SetHucStatusMask(uint32_t hucStatusMask,uint32_t hucStatus2Mask)114 void DecodeHucBasic_G12_Base::SetHucStatusMask(uint32_t hucStatusMask, uint32_t hucStatus2Mask)
115 {
116     m_hucStatusMask  = hucStatusMask;
117     m_hucStatus2Mask = hucStatus2Mask;
118 }
119 
StoreHucStatusRegister(MOS_COMMAND_BUFFER & cmdBuffer)120 MOS_STATUS DecodeHucBasic_G12_Base::StoreHucStatusRegister(MOS_COMMAND_BUFFER& cmdBuffer)
121 {
122     if(m_hucStatusMask == m_hucStatusInvalidMask)
123     {
124         return MOS_STATUS_SUCCESS;
125     }
126 
127     MOS_RESOURCE* osResource = nullptr;
128     uint32_t     offset = 0;
129 
130     DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatusMask, osResource, offset));
131 
132     // Write HUC_STATUS mask
133     MHW_MI_STORE_DATA_PARAMS storeDataParams;
134     MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
135     storeDataParams.pOsResource = osResource;
136     storeDataParams.dwResourceOffset = offset;
137     storeDataParams.dwValue = m_hucStatusMask;
138     DECODE_CHK_STATUS(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams));
139 
140     DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatusReg, osResource, offset));
141 
142     // Store HUC_STATUS register
143     MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
144     MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
145     storeRegParams.presStoreBuffer = osResource;
146     storeRegParams.dwOffset = offset;
147     storeRegParams.dwRegister = m_hucInterface->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatusRegOffset;
148     DECODE_CHK_STATUS(m_miInterface->AddMiStoreRegisterMemCmd(&cmdBuffer, &storeRegParams));
149 
150     return MOS_STATUS_SUCCESS;
151 }
152 
StoreHucStatus2Register(MOS_COMMAND_BUFFER & cmdBuffer)153 MOS_STATUS DecodeHucBasic_G12_Base::StoreHucStatus2Register(MOS_COMMAND_BUFFER& cmdBuffer)
154 {
155     if(m_hucStatus2Mask == m_hucStatusInvalidMask)
156     {
157         return MOS_STATUS_SUCCESS;
158     }
159 
160     MOS_RESOURCE* osResource = nullptr;
161     uint32_t     offset = 0;
162 
163     DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatus2Mask, osResource, offset));
164 
165     // Write HUC_STATUS2 mask
166     MHW_MI_STORE_DATA_PARAMS storeDataParams;
167     MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
168     storeDataParams.pOsResource = osResource;
169     storeDataParams.dwResourceOffset = offset;
170     storeDataParams.dwValue = m_hucStatus2Mask;
171     DECODE_CHK_STATUS(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams));
172 
173     DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatus2Reg, osResource, offset));
174 
175     // Store HUC_STATUS2 register
176     MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
177     MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
178     storeRegParams.presStoreBuffer = osResource;
179     storeRegParams.dwOffset = offset;
180     storeRegParams.dwRegister = m_hucInterface->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatus2RegOffset;
181     DECODE_CHK_STATUS(m_miInterface->AddMiStoreRegisterMemCmd(&cmdBuffer, &storeRegParams));
182 
183     return MOS_STATUS_SUCCESS;
184 }
185 
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)186 MOS_STATUS DecodeHucBasic_G12_Base::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
187 {
188 
189     MediaPacket::StartStatusReport(srType, cmdBuffer);
190 
191     return MOS_STATUS_SUCCESS;
192 }
193 
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)194 MOS_STATUS DecodeHucBasic_G12_Base::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
195 {
196 
197     DECODE_FUNC_CALL();
198     DECODE_CHK_NULL(cmdBuffer);
199 
200     DECODE_CHK_STATUS(MediaPacket::EndStatusReport(srType, cmdBuffer));
201 
202     return MOS_STATUS_SUCCESS;
203 
204 }
205 
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer,bool mfxWakeup,bool hcpWakeup)206 MOS_STATUS DecodeHucBasic_G12_Base::AddForceWakeup(MOS_COMMAND_BUFFER& cmdBuffer, bool mfxWakeup, bool hcpWakeup)
207 {
208     DECODE_FUNC_CALL();
209 
210     MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
211     MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
212     forceWakeupParams.bMFXPowerWellControl      = mfxWakeup;
213     forceWakeupParams.bMFXPowerWellControlMask  = true;
214     forceWakeupParams.bHEVCPowerWellControl     = hcpWakeup;
215     forceWakeupParams.bHEVCPowerWellControlMask = true;
216 
217     DECODE_CHK_STATUS(m_miInterface->AddMiForceWakeupCmd(&cmdBuffer, &forceWakeupParams));
218 
219     return MOS_STATUS_SUCCESS;
220 }
221 
SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)222 MOS_STATUS DecodeHucBasic_G12_Base::SendPrologCmds(MOS_COMMAND_BUFFER& cmdBuffer)
223 {
224     DecodeSubPacket* subPacket = m_pipeline->GetSubPacket(DecodePacketId(m_pipeline, markerSubPacketId));
225     DecodeMarkerPktG12 *makerPacket = dynamic_cast<DecodeMarkerPktG12*>(subPacket);
226     DECODE_CHK_NULL(makerPacket);
227     DECODE_CHK_STATUS(makerPacket->Execute(cmdBuffer));
228 
229 #ifdef _MMC_SUPPORTED
230     DecodeMemComp *mmcState = m_pipeline->GetMmcState();
231     bool isMmcEnabled = (mmcState != nullptr && mmcState->IsMmcEnabled());
232     if (isMmcEnabled)
233     {
234         DECODE_CHK_STATUS(mmcState->SendPrologCmd(&cmdBuffer, false));
235     }
236 #endif
237 
238     MHW_GENERIC_PROLOG_PARAMS  genericPrologParams;
239     MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
240     genericPrologParams.pOsInterface = m_osInterface;
241     genericPrologParams.pvMiInterface = m_miInterface;
242 #ifdef _MMC_SUPPORTED
243     genericPrologParams.bMmcEnabled = isMmcEnabled;
244 #endif
245     DECODE_CHK_STATUS(Mhw_SendGenericPrologCmd(&cmdBuffer, &genericPrologParams));
246 
247     subPacket = m_pipeline->GetSubPacket(DecodePacketId(m_pipeline, predicationSubPacketId));
248     DecodePredicationPktG12 *predicationPacket = dynamic_cast<DecodePredicationPktG12*>(subPacket);
249     DECODE_CHK_NULL(predicationPacket);
250     DECODE_CHK_STATUS(predicationPacket->Execute(cmdBuffer));
251 
252     return MOS_STATUS_SUCCESS;
253 }
254 
MemoryFlush(MOS_COMMAND_BUFFER & cmdBuffer)255 MOS_STATUS DecodeHucBasic_G12_Base::MemoryFlush(MOS_COMMAND_BUFFER &cmdBuffer)
256 {
257     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
258     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
259     DECODE_CHK_STATUS(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
260     return MOS_STATUS_SUCCESS;
261 }
262 
263 }
264