1 /*
2 * Copyright (c) 2021, 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.h"
31 #include "codechal_debug.h"
32 #include "decode_pipeline.h"
33 #include "decode_predication_packet.h"
34 #include "decode_marker_packet.h"
35 
36 namespace decode
37 {
38 
DecodeHucBasic(MediaPipeline * pipeline,MediaTask * task,CodechalHwInterfaceNext * hwInterface)39 DecodeHucBasic::DecodeHucBasic(MediaPipeline *pipeline, MediaTask *task, CodechalHwInterfaceNext*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_miItf          = std::static_pointer_cast<mhw::mi::Itf>(hwInterface->GetMiInterfaceNext());
55         m_vdencItf       = std::static_pointer_cast<mhw::vdbox::vdenc::Itf>(m_hwInterface->GetVdencInterfaceNext());
56         m_hucItf         = std::static_pointer_cast<mhw::vdbox::huc::Itf>(m_hwInterface->GetHucInterfaceNext());
57 
58     }
59 }
60 
~DecodeHucBasic()61 DecodeHucBasic::~DecodeHucBasic()
62 {
63 }
64 
Init()65 MOS_STATUS DecodeHucBasic::Init()
66 {
67     DECODE_CHK_NULL(m_pipeline);
68     DECODE_CHK_NULL(m_featureManager);
69     DECODE_CHK_NULL(m_osInterface);
70     DECODE_CHK_NULL(m_hucItf);
71     DECODE_CHK_NULL(m_miItf);
72     DECODE_CHK_NULL(m_vdencItf);
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::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::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::Destroy()
110 {
111     return MOS_STATUS_SUCCESS;
112 }
113 
SetHucStatusMask(uint32_t hucStatusMask,uint32_t hucStatus2Mask)114 void DecodeHucBasic::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::StoreHucStatusRegister(MOS_COMMAND_BUFFER& cmdBuffer)
121 {
122     if(m_hucStatusMask == m_hucStatusInvalidMask)
123     {
124         return MOS_STATUS_SUCCESS;
125     }
126 
127     MOS_RESOURCE* osResource;
128     uint32_t     offset;
129     {
130         DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatusMask, osResource, offset));
131 
132         // Write HUC_STATUS mask
133         auto &par            = m_miItf->GETPAR_MI_STORE_DATA_IMM();
134         par                  = {};
135         par.pOsResource      = osResource;
136         par.dwResourceOffset = offset;
137         par.dwValue          = m_hucStatusMask;
138         DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_DATA_IMM(&cmdBuffer));
139     }
140     {
141         DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatusReg, osResource, offset));
142 
143         // Store HUC_STATUS register
144         auto &par           = m_miItf->GETPAR_MI_STORE_REGISTER_MEM();
145         par                 = {};
146         par.presStoreBuffer = osResource;
147         par.dwOffset        = offset;
148         par.dwRegister      = m_hucItf->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatusRegOffset;
149         DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
150     }
151 
152     return MOS_STATUS_SUCCESS;
153 }
154 
StoreHucStatus2Register(MOS_COMMAND_BUFFER & cmdBuffer)155 MOS_STATUS DecodeHucBasic::StoreHucStatus2Register(MOS_COMMAND_BUFFER& cmdBuffer)
156 {
157     if(m_hucStatus2Mask == m_hucStatusInvalidMask)
158     {
159         return MOS_STATUS_SUCCESS;
160     }
161 
162     MOS_RESOURCE* osResource;
163     uint32_t     offset;
164     {
165         DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatus2Mask, osResource, offset));
166 
167         // Write HUC_STATUS2 mask
168         auto &par = m_miItf->GETPAR_MI_STORE_DATA_IMM();
169         par                              = {};
170         par.pOsResource                  = osResource;
171         par.dwResourceOffset             = offset;
172         par.dwValue                      = m_hucStatus2Mask;
173         DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_DATA_IMM(&cmdBuffer));
174     }
175     {
176         DECODE_CHK_STATUS(m_statusReport->GetAddress(decode::DecodeStatusReportType::HucErrorStatus2Reg, osResource, offset));
177         // Store HUC_STATUS2 register
178         auto &par = m_miItf->GETPAR_MI_STORE_REGISTER_MEM();
179         par                            = {};
180         par.presStoreBuffer            = osResource;
181         par.dwOffset                   = offset;
182         par.dwRegister                 = m_hucItf->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatus2RegOffset;
183         DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
184     }
185     return MOS_STATUS_SUCCESS;
186 }
187 
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)188 MOS_STATUS DecodeHucBasic::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
189 {
190 
191     MediaPacket::StartStatusReport(srType, cmdBuffer);
192 
193     return MOS_STATUS_SUCCESS;
194 }
195 
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)196 MOS_STATUS DecodeHucBasic::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
197 {
198 
199     DECODE_FUNC_CALL();
200     DECODE_CHK_NULL(cmdBuffer);
201 
202     DECODE_CHK_STATUS(MediaPacket::EndStatusReport(srType, cmdBuffer));
203 
204     return MOS_STATUS_SUCCESS;
205 
206 }
207 
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer,bool mfxWakeup,bool hcpWakeup)208 MOS_STATUS DecodeHucBasic::AddForceWakeup(MOS_COMMAND_BUFFER& cmdBuffer, bool mfxWakeup, bool hcpWakeup)
209 {
210     DECODE_FUNC_CALL();
211 
212     auto &par = m_miItf->GETPAR_MI_FORCE_WAKEUP();
213     par       = {};
214     par.bMFXPowerWellControl                    = mfxWakeup;
215     par.bMFXPowerWellControlMask                = true;
216     par.bHEVCPowerWellControl                   = hcpWakeup;
217     par.bHEVCPowerWellControlMask               = true;
218 
219     DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FORCE_WAKEUP(&cmdBuffer));
220 
221     return MOS_STATUS_SUCCESS;
222 }
223 
SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)224 MOS_STATUS DecodeHucBasic::SendPrologCmds(MOS_COMMAND_BUFFER& cmdBuffer)
225 {
226     DecodeSubPacket* subPacket = m_pipeline->GetSubPacket(DecodePacketId(m_pipeline, markerSubPacketId));
227     DecodeMarkerPkt *makerPacket = dynamic_cast<DecodeMarkerPkt*>(subPacket);
228     DECODE_CHK_NULL(makerPacket);
229     DECODE_CHK_STATUS(makerPacket->Execute(cmdBuffer));
230 
231 #ifdef _MMC_SUPPORTED
232     DecodeMemComp *mmcState = m_pipeline->GetMmcState();
233     bool isMmcEnabled = (mmcState != nullptr && mmcState->IsMmcEnabled());
234     if (isMmcEnabled)
235     {
236         DECODE_CHK_STATUS(mmcState->SendPrologCmd(&cmdBuffer, false));
237     }
238 #endif
239 
240     MHW_GENERIC_PROLOG_PARAMS  genericPrologParams;
241     MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
242     genericPrologParams.pOsInterface = m_osInterface;
243     genericPrologParams.pvMiInterface = nullptr;
244 #ifdef _MMC_SUPPORTED
245     genericPrologParams.bMmcEnabled = isMmcEnabled;
246 #endif
247     DECODE_CHK_STATUS(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
248 
249     subPacket = m_pipeline->GetSubPacket(DecodePacketId(m_pipeline, predicationSubPacketId));
250     DecodePredicationPkt *predicationPacket = dynamic_cast<DecodePredicationPkt*>(subPacket);
251     DECODE_CHK_NULL(predicationPacket);
252     DECODE_CHK_STATUS(predicationPacket->Execute(cmdBuffer));
253 
254     return MOS_STATUS_SUCCESS;
255 }
256 
MemoryFlush(MOS_COMMAND_BUFFER & cmdBuffer)257 MOS_STATUS DecodeHucBasic::MemoryFlush(MOS_COMMAND_BUFFER &cmdBuffer)
258 {
259     auto &par = m_miItf->GETPAR_MI_FLUSH_DW();
260     par       = {};
261     DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
262     return MOS_STATUS_SUCCESS;
263 }
264 
265 }
266