[Media Common] Add media reset support for VP and decode

Media reset will be enabled when reg key and env variable are set.
diff --git a/media_driver/agnostic/common/hw/mhw_mi.cpp b/media_driver/agnostic/common/hw/mhw_mi.cpp
index 066118e..4ec20d7 100644
--- a/media_driver/agnostic/common/hw/mhw_mi.cpp
+++ b/media_driver/agnostic/common/hw/mhw_mi.cpp
@@ -64,21 +64,7 @@
 
     MediaResetParam.watchdogCountThreshold = MHW_MI_DEFAULT_WATCHDOG_THRESHOLD_IN_MS;
 
-    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-#if (_DEBUG || _RELEASE_INTERNAL)
-    // User feature config of watchdog timer threshold
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-    MOS_UserFeature_ReadValue_ID(
-        nullptr,
-        __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
-        &userFeatureData,
-        osInterface->pOsContext);
-    if (userFeatureData.u32Data != 0)
-    {
-        MediaResetParam.watchdogCountThreshold = userFeatureData.u32Data;
-    }
-#endif
+    GetWatchdogThreshold(m_osInterface);
 
     if (m_osInterface->bUsesGfxAddress)
     {
@@ -111,3 +97,4 @@
 
     return MOS_STATUS_SUCCESS;
 }
+
diff --git a/media_driver/agnostic/common/hw/mhw_mi.h b/media_driver/agnostic/common/hw/mhw_mi.h
index 84323ea..4ad568d 100644
--- a/media_driver/agnostic/common/hw/mhw_mi.h
+++ b/media_driver/agnostic/common/hw/mhw_mi.h
@@ -748,6 +748,8 @@
     //!
     bool IsGlobalGttInUse();
 
+    void GetWatchdogThreshold(PMOS_INTERFACE osInterface);
+
     MhwCpInterface      *m_cpInterface = nullptr; //!< Responsible for CP functionality
     PMOS_INTERFACE      m_osInterface = nullptr;   //!< Responsible for interaction with OS
 
diff --git a/media_driver/agnostic/common/os/mos_utilities.cpp b/media_driver/agnostic/common/os/mos_utilities.cpp
index 7b0f847..dfd3f9f 100644
--- a/media_driver/agnostic/common/os/mos_utilities.cpp
+++ b/media_driver/agnostic/common/os/mos_utilities.cpp
@@ -266,7 +266,7 @@
         MOS_USER_FEATURE_TYPE_USER,
         MOS_USER_FEATURE_VALUE_TYPE_INT32,
         "1",
-        "If enabled, media reset will be enabled. This key is not valid on Linux."),
+        "If enabled, media reset will be enabled."),
     MOS_DECLARE_UF_KEY_DBGONLY(__MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
         "Media Reset TH",
         __MEDIA_USER_FEATURE_SUBKEY_INTERNAL,
@@ -275,7 +275,7 @@
         MOS_USER_FEATURE_TYPE_USER,
         MOS_USER_FEATURE_VALUE_TYPE_INT32,
         "0",
-        "If enabled, media reset will be enabled. This key is not valid on Linux."),
+        "If enabled, media reset will be enabled."),
     MOS_DECLARE_UF_KEY_DBGONLY(__MEDIA_USER_FEATURE_VALUE_SOFT_RESET_ENABLE_ID,
         "Soft Reset",
         __MEDIA_USER_FEATURE_SUBKEY_INTERNAL,
@@ -4190,7 +4190,7 @@
          MOS_USER_FEATURE_TYPE_USER,
          MOS_USER_FEATURE_VALUE_TYPE_INT32,
          "0",
-         "Eanble EuFusion path. 1: enable, 0: disable."),
+         "Enable EuFusion path. 1: enable, 0: disable."),
 };
 
 PMOS_USER_FEATURE_VALUE const MosUtilities::m_mosUserFeatureDescFields = MOSUserFeatureDescFields;
diff --git a/media_driver/agnostic/gen10/hw/mhw_mi_g10_X.cpp b/media_driver/agnostic/gen10/hw/mhw_mi_g10_X.cpp
index bd7de27..7bebff1 100644
--- a/media_driver/agnostic/gen10/hw/mhw_mi_g10_X.cpp
+++ b/media_driver/agnostic/gen10/hw/mhw_mi_g10_X.cpp
@@ -177,21 +177,7 @@
         }
     }
 
-    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-#if (_DEBUG || _RELEASE_INTERNAL)
-    // User feature config of watchdog timer threshold
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-    MOS_UserFeature_ReadValue_ID(
-        nullptr,
-        __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
-        &userFeatureData,
-        m_osInterface->pOsContext);
-    if (userFeatureData.u32Data != 0)
-    {
-        MediaResetParam.watchdogCountThreshold = userFeatureData.u32Data;
-    }
-#endif
+    GetWatchdogThreshold(m_osInterface);
 
     return MOS_STATUS_SUCCESS;
 }
diff --git a/media_driver/agnostic/gen11/hw/mhw_mi_g11_X.cpp b/media_driver/agnostic/gen11/hw/mhw_mi_g11_X.cpp
index 175defb..98c9e01 100644
--- a/media_driver/agnostic/gen11/hw/mhw_mi_g11_X.cpp
+++ b/media_driver/agnostic/gen11/hw/mhw_mi_g11_X.cpp
@@ -276,21 +276,7 @@
         }
     }
 
-    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-#if (_DEBUG || _RELEASE_INTERNAL)
-    // User feature config of watchdog timer threshold
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-    MOS_UserFeature_ReadValue_ID(
-        nullptr,
-        __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
-        &userFeatureData,
-        m_osInterface->pOsContext);
-    if (userFeatureData.u32Data != 0)
-    {
-        MediaResetParam.watchdogCountThreshold = userFeatureData.u32Data;
-    }
-#endif
+    GetWatchdogThreshold(m_osInterface);
 
     return MOS_STATUS_SUCCESS;
 }
diff --git a/media_driver/agnostic/gen12/hw/mhw_mi_g12_X.cpp b/media_driver/agnostic/gen12/hw/mhw_mi_g12_X.cpp
index be61246..ebfca0b 100644
--- a/media_driver/agnostic/gen12/hw/mhw_mi_g12_X.cpp
+++ b/media_driver/agnostic/gen12/hw/mhw_mi_g12_X.cpp
@@ -566,22 +566,8 @@
         }
     }
 
-    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-#if (_DEBUG || _RELEASE_INTERNAL)
-    // User feature config of watchdog timer threshold
-    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
-    MOS_UserFeature_ReadValue_ID(
-        nullptr,
-        __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
-        &userFeatureData,
-        m_osInterface->pOsContext);
-    if (userFeatureData.u32Data != 0)
-    {
-        MediaResetParam.watchdogCountThreshold = userFeatureData.u32Data;
-    }
-#endif
-
+    GetWatchdogThreshold(m_osInterface);
+    
     return MOS_STATUS_SUCCESS;
 }
 
diff --git a/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp b/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
index ae061d0..2b299e1 100644
--- a/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
+++ b/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
@@ -341,7 +341,7 @@
             }
             else if (surface->curStatusReport.decode.status == CODECHAL_STATUS_INCOMPLETE || surface->curStatusReport.decode.status == CODECHAL_STATUS_UNAVAILABLE)
             {
-                return VA_STATUS_ERROR_HW_BUSY;
+                return mediaCtx->bMediaResetEnable ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_HW_BUSY;
             }
         }
         else
@@ -414,7 +414,7 @@
         }
         else if (surface->curStatusReport.decode.status == CODECHAL_STATUS_INCOMPLETE || surface->curStatusReport.decode.status == CODECHAL_STATUS_UNAVAILABLE)
         {
-            return VA_STATUS_ERROR_HW_BUSY;
+            return mediaCtx->bMediaResetEnable ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_HW_BUSY;
         }
     }
     else
diff --git a/media_driver/linux/common/ddi/media_libva.cpp b/media_driver/linux/common/ddi/media_libva.cpp
index c3f9705..54d1eb5 100755
--- a/media_driver/linux/common/ddi/media_libva.cpp
+++ b/media_driver/linux/common/ddi/media_libva.cpp
@@ -1961,6 +1961,11 @@
     output_dri_init(ctx);
 #endif
 
+    if (VA_STATUS_SUCCESS != DdiMediaUtil_SetMediaResetEnableFlag(mediaCtx))
+    {
+        mediaCtx->bMediaResetEnable = false;
+    }
+
     DdiMediaUtil_UnLockMutex(&GlobalMutex);
 
     return VA_STATUS_SUCCESS;
@@ -3928,7 +3933,7 @@
             }
             else if(surface->curStatusReport.vpp.status == VPREP_NOTREADY)
             {
-                return VA_STATUS_ERROR_HW_BUSY;
+                return mediaCtx->bMediaResetEnable ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_HW_BUSY;
             }
             else
             {
diff --git a/media_driver/linux/common/ddi/media_libva_common.h b/media_driver/linux/common/ddi/media_libva_common.h
index 09dd061..acdd9c6 100644
--- a/media_driver/linux/common/ddi/media_libva_common.h
+++ b/media_driver/linux/common/ddi/media_libva_common.h
@@ -478,6 +478,9 @@
     // Media copy data structure
     void               *pMediaCopyState;
 
+    // Media reset enable flag
+    bool                bMediaResetEnable;
+
     // Media memory decompression function
     void (* pfnMemoryDecompress)(
         PMOS_CONTEXT  pMosCtx,
diff --git a/media_driver/linux/common/ddi/media_libva_util.cpp b/media_driver/linux/common/ddi/media_libva_util.cpp
index 8d96393..be7749d 100755
--- a/media_driver/linux/common/ddi/media_libva_util.cpp
+++ b/media_driver/linux/common/ddi/media_libva_util.cpp
@@ -1816,3 +1816,37 @@
 
     return VA_STATUS_SUCCESS;
 }
+
+VAStatus DdiMediaUtil_SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx)
+{
+    DDI_CHK_NULL(mediaCtx,"nullptr mediaCtx!", VA_STATUS_ERROR_INVALID_CONTEXT);
+    
+    if(!MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrSWMediaReset))
+    {
+        mediaCtx->bMediaResetEnable = false;
+        return VA_STATUS_SUCCESS;
+    }
+
+    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
+    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
+    MOS_USER_FEATURE_INVALID_KEY_ASSERT(
+        MOS_UserFeature_ReadValue_ID(nullptr,
+                                     __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_ENABLE_ID,
+                                     &userFeatureData,
+                                     nullptr));
+    mediaCtx->bMediaResetEnable = userFeatureData.i32Data ? true : false;
+    if(mediaCtx->bMediaResetEnable)
+    {
+        return VA_STATUS_SUCCESS;
+    }
+
+    char* mediaResetEnv = getenv("INTEL_MEDIA_RESET_WATCHDOG");
+    if(!mediaResetEnv)
+    {
+        mediaCtx->bMediaResetEnable = false;
+        return VA_STATUS_SUCCESS;
+    }
+
+    mediaCtx->bMediaResetEnable = strcmp(mediaResetEnv, "1") ? false : true;
+    return VA_STATUS_SUCCESS;
+}
diff --git a/media_driver/linux/common/ddi/media_libva_util.h b/media_driver/linux/common/ddi/media_libva_util.h
index c4d1772..e325cb5 100644
--- a/media_driver/linux/common/ddi/media_libva_util.h
+++ b/media_driver/linux/common/ddi/media_libva_util.h
@@ -357,6 +357,17 @@
 //!
 VAStatus DdiMediaUtil_UnRegisterRTSurfaces(VADriverContextP    ctx,PDDI_MEDIA_SURFACE surface);
 
+//!
+//! \brief  Determine whethere media reset is anabled
+//!
+//! \param  [in] mediaCtx
+//!     Pointer to VA driver context
+//!
+//! \return     VAStatus
+//!     VA_STATUS_SUCCESS if success, else fail reason
+//!
+VAStatus DdiMediaUtil_SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx);
+
 //------------------------------------------------------------------------------
 // Macros for debug messages, Assert, Null check and condition check within ddi files
 //------------------------------------------------------------------------------
diff --git a/media_driver/linux/common/hw/media_srcs.cmake b/media_driver/linux/common/hw/media_srcs.cmake
new file mode 100644
index 0000000..44c26dd
--- /dev/null
+++ b/media_driver/linux/common/hw/media_srcs.cmake
@@ -0,0 +1,30 @@
+# Copyright (c) 2021, Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+set(TMP_SOURCES_
+    ${CMAKE_CURRENT_LIST_DIR}/mhw_mi_linux.cpp
+)
+
+set(SOURCES_
+    ${SOURCES_}
+    ${TMP_SOURCES_}
+ )
+
+media_add_curr_to_include_path()
diff --git a/media_driver/linux/common/hw/mhw_mi_linux.cpp b/media_driver/linux/common/hw/mhw_mi_linux.cpp
new file mode 100644
index 0000000..950d61b
--- /dev/null
+++ b/media_driver/linux/common/hw/mhw_mi_linux.cpp
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2014-2021, Intel Corporation
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+//!
+//! \file     mhw_mi_linux.cpp
+//! \brief    MHW interface for MI and generic flush commands across all engines
+//! \details  Impelements the functionalities common across all platforms for MHW_MI
+//!
+
+#include "mhw_mi.h"
+
+void MhwMiInterface::GetWatchdogThreshold(PMOS_INTERFACE osInterface)
+{
+    char* mediaResetThreshold = getenv("INTEL_MEDIA_RESET_TH");
+    if(mediaResetThreshold)
+    {
+        long int threshold = strtol(mediaResetThreshold, nullptr, 0);
+        if(threshold > 0 )
+        {
+            MediaResetParam.watchdogCountThreshold = threshold;
+            return;
+        }
+    }
+
+    MOS_USER_FEATURE_VALUE_DATA userFeatureData;
+    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
+#if (_DEBUG || _RELEASE_INTERNAL)
+    // User feature config of watchdog timer threshold
+    MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
+    MOS_UserFeature_ReadValue_ID(
+        nullptr,
+        __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_TH_ID,
+        &userFeatureData,
+        osInterface->pOsContext);
+    if (userFeatureData.u32Data != 0)
+    {
+        MediaResetParam.watchdogCountThreshold = userFeatureData.u32Data;
+    }
+#endif
+}
diff --git a/media_driver/linux/common/media_srcs.cmake b/media_driver/linux/common/media_srcs.cmake
index 8be1bc3..081d35b 100644
--- a/media_driver/linux/common/media_srcs.cmake
+++ b/media_driver/linux/common/media_srcs.cmake
@@ -26,3 +26,5 @@
 media_include_subdirectory(os)
 media_include_subdirectory(renderhal)
 media_include_subdirectory(vp)
+media_include_subdirectory(hw)
+