| /* |
| * Copyright (c) 2017-2019, 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 hwinfo_linux.c |
| //! \brief The purpose of the file is to get the sku/wa table according to platform information. |
| //! |
| |
| #include "hwinfo_linux.h" |
| #include "mos_utilities.h" |
| #include "mos_util_debug.h" |
| #include "skuwa_factory.h" |
| #include "linux_system_info.h" |
| #include "linux_shadow_skuwa.h" |
| #include "mos_solo_generic.h" |
| |
| #if defined(USE_MAGMA) |
| #include "magma_fd.h" |
| #endif |
| |
| typedef DeviceInfoFactory<struct GfxDeviceInfo> DeviceInfoFact; |
| typedef DeviceInfoFactory<struct LinuxDeviceInit> DeviceInitFact; |
| |
| static GfxDeviceInfo *getDeviceInfo(uint32_t devId) |
| { |
| GfxDeviceInfo *devInfo = DeviceInfoFact::LookupDevice(devId); |
| |
| return devInfo; |
| } |
| |
| static LinuxDeviceInit *getDeviceInit(uint32_t platKey) |
| { |
| LinuxDeviceInit *devInfo = DeviceInitFact::LookupDevice(platKey); |
| |
| return devInfo; |
| } |
| |
| static bool MediaGetParam(int fd, int32_t param, uint32_t *retValue) |
| { |
| struct drm_i915_getparam gp; |
| |
| gp.param = param; |
| gp.value = (int32_t *)retValue; |
| #if defined(USE_MAGMA) |
| return query_magma_fd(fd, param, retValue); |
| #else |
| return drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0; |
| #endif |
| } |
| |
| /*****************************************************************************\ |
| Description: |
| Get ProductFamily according to input device FD |
| |
| Input: |
| fd - file descriptor to the /dev/dri/cardX |
| Output: |
| eProductFamily - describing current platform product family |
| \*****************************************************************************/ |
| MOS_STATUS HWInfo_GetGfxProductFamily(int32_t fd, PRODUCT_FAMILY &eProductFamily) |
| { |
| if (fd < 0) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid parameter \n"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| LinuxDriverInfo drvInfo = {18, 3, 0, 23172, 3, 1, 0, 1, 0, 0, 1, 0}; |
| if (HWInfoGetLinuxDrvInfo(fd, &drvInfo) != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get the chipset id\n"); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| GfxDeviceInfo *devInfo = getDeviceInfo(drvInfo.devId); |
| if (devInfo == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get the device info for Device id: %x\n", drvInfo.devId); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| eProductFamily = (PRODUCT_FAMILY)devInfo->productFamily; |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| |
| /*****************************************************************************\ |
| Description: |
| Get Sku/Wa tables and platform information according to input device FD |
| |
| Input: |
| fd - file descriptor to the /dev/dri/cardX |
| Output: |
| gfxPlatform - describing current platform. is it mobile, desk, |
| server? Sku/Wa must know. |
| skuTable - describing SKU |
| waTable - the constraints list |
| gtSystemInfo - describing current system information |
| \*****************************************************************************/ |
| MOS_STATUS HWInfo_GetGfxInfo(int32_t fd, |
| MOS_BUFMGR *pDrmBufMgr, |
| PLATFORM *gfxPlatform, |
| MEDIA_FEATURE_TABLE *skuTable, |
| MEDIA_WA_TABLE *waTable, |
| MEDIA_SYSTEM_INFO *gtSystemInfo) |
| { |
| if ((fd < 0) || |
| (pDrmBufMgr == nullptr) || |
| (gfxPlatform == nullptr) || |
| (skuTable == nullptr) || |
| (waTable == nullptr) || |
| (gtSystemInfo == nullptr)) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid parameter \n"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| #endif |
| |
| LinuxDriverInfo drvInfo = {18, 3, 0, 23172, 3, 1, 0, 1, 0, 0, 1, 0}; |
| if (!Mos_Solo_IsEnabled(nullptr) && HWInfoGetLinuxDrvInfo(fd, &drvInfo) != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get the chipset id\n"); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| GfxDeviceInfo *devInfo = getDeviceInfo(drvInfo.devId); |
| if (devInfo == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get the device info for Device id: %x\n", drvInfo.devId); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| /* Initialize Platform Info */ |
| gfxPlatform->ePlatformType = (PLATFORM_TYPE)devInfo->platformType; |
| gfxPlatform->eProductFamily = (PRODUCT_FAMILY)devInfo->productFamily; |
| gfxPlatform->ePCHProductFamily = PCH_UNKNOWN; |
| gfxPlatform->eDisplayCoreFamily = (GFXCORE_FAMILY)devInfo->displayFamily; |
| gfxPlatform->eRenderCoreFamily = (GFXCORE_FAMILY)devInfo->renderFamily; |
| gfxPlatform->eGTType = (GTTYPE)devInfo->eGTType; |
| gfxPlatform->usDeviceID = drvInfo.devId; |
| gfxPlatform->usRevId = drvInfo.devRev; |
| |
| if (mos_query_device_blob(fd, gtSystemInfo) == 0) |
| { |
| gtSystemInfo->EUCount = gtSystemInfo->SubSliceCount * gtSystemInfo->MaxEuPerSubSlice; |
| gtSystemInfo->ThreadCount = gtSystemInfo->EUCount * gtSystemInfo->NumThreadsPerEu; |
| gtSystemInfo->VEBoxInfo.IsValid = true; |
| gtSystemInfo->VDBoxInfo.IsValid = true; |
| } |
| else |
| { |
| MOS_OS_NORMALMESSAGE("Device blob query is not supported yet.\n"); |
| gtSystemInfo->SliceCount = drvInfo.sliceCount; |
| gtSystemInfo->SubSliceCount = drvInfo.subSliceCount; |
| gtSystemInfo->EUCount = drvInfo.euCount; |
| |
| if (devInfo->InitMediaSysInfo && |
| devInfo->InitMediaSysInfo(devInfo, gtSystemInfo)) |
| { |
| MOS_OS_NORMALMESSAGE("Init Media SystemInfo\n"); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to Init Gt System Info\n"); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| } |
| |
| unsigned int maxNengine = 0; |
| if((gtSystemInfo->VDBoxInfo.NumberOfVDBoxEnabled == 0) |
| || (gtSystemInfo->VEBoxInfo.NumberOfVEBoxEnabled == 0)) |
| { |
| if (mos_query_engines_count(pDrmBufMgr, &maxNengine)) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to query engines count.\n"); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| } |
| |
| if (gtSystemInfo->VDBoxInfo.NumberOfVDBoxEnabled == 0) |
| { |
| unsigned int nengine = maxNengine; |
| struct i915_engine_class_instance *uengines = nullptr; |
| uengines = (struct i915_engine_class_instance *)MOS_AllocAndZeroMemory(nengine * sizeof(struct i915_engine_class_instance)); |
| MOS_OS_CHK_NULL_RETURN(uengines); |
| if (mos_query_engines(pDrmBufMgr,I915_ENGINE_CLASS_VIDEO,0,&nengine,uengines) == 0) |
| { |
| gtSystemInfo->VDBoxInfo.NumberOfVDBoxEnabled = nengine; |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to query vdbox engine\n"); |
| MOS_SafeFreeMemory(uengines); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| for (int i=0; i<nengine; i++) |
| { |
| gtSystemInfo->VDBoxInfo.Instances.VDBoxEnableMask |= 1<<uengines[i].engine_instance; |
| } |
| MOS_SafeFreeMemory(uengines); |
| } |
| |
| if (gtSystemInfo->VEBoxInfo.NumberOfVEBoxEnabled == 0) |
| { |
| unsigned int nengine = maxNengine; |
| struct i915_engine_class_instance *uengines = nullptr; |
| uengines = (struct i915_engine_class_instance *)MOS_AllocAndZeroMemory(nengine * sizeof(struct i915_engine_class_instance)); |
| MOS_OS_CHK_NULL_RETURN(uengines); |
| if (mos_query_engines(pDrmBufMgr,I915_ENGINE_CLASS_VIDEO_ENHANCE,0,&nengine,uengines) == 0) |
| { |
| MOS_OS_ASSERT(nengine <= maxNengine); |
| gtSystemInfo->VEBoxInfo.NumberOfVEBoxEnabled = nengine; |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to query vebox engine\n"); |
| MOS_SafeFreeMemory(uengines); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| MOS_SafeFreeMemory(uengines); |
| } |
| |
| uint32_t platformKey = devInfo->productFamily; |
| LinuxDeviceInit *devInit = getDeviceInit(platformKey); |
| |
| if (devInit && devInit->InitMediaFeature && |
| devInit->InitMediaWa && |
| devInit->InitMediaFeature(devInfo, skuTable, &drvInfo) && |
| devInit->InitMediaWa(devInfo, waTable, &drvInfo)) |
| { |
| MOS_OS_NORMALMESSAGE("Init Media SKU/WA info successfully\n"); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to Init SKU/WA Info\n"); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| |
| uint32_t devExtKey = platformKey + MEDIA_EXT_FLAG; |
| LinuxDeviceInit *devExtInit = getDeviceInit(devExtKey); |
| |
| /* The initializationof Ext SKU/WA is optional. So skip the check of return value */ |
| if (devExtInit && devExtInit->InitMediaFeature && |
| devExtInit->InitMediaWa && |
| devExtInit->InitMediaFeature(devInfo, skuTable, &drvInfo) && |
| devExtInit->InitMediaWa(devInfo, waTable, &drvInfo)) |
| { |
| MOS_OS_NORMALMESSAGE("Init Media SystemInfo successfully\n"); |
| } |
| |
| /* disable it on Linux */ |
| MEDIA_WR_SKU(skuTable, FtrPerCtxtPreemptionGranularityControl, 0); |
| MEDIA_WR_SKU(skuTable, FtrMediaThreadGroupLevelPreempt, 0); |
| MEDIA_WR_SKU(skuTable, FtrMediaMidBatchPreempt, 0); |
| MEDIA_WR_SKU(skuTable, FtrMediaMidThreadLevelPreempt, 0); |
| MEDIA_WR_SKU(skuTable, FtrGpGpuThreadGroupLevelPreempt, 0); |
| MEDIA_WR_SKU(skuTable, FtrGpGpuMidBatchPreempt, 0); |
| MEDIA_WR_SKU(skuTable, FtrGpGpuMidThreadLevelPreempt, 0); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| // User feature read to detect if simulation environment (MediaSolo) is enabled |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_MEDIASOLO_ENABLE_ID, |
| &UserFeatureData, |
| nullptr); |
| //Disable plarform checks to support pre-si features (e.g., MMCD) on MediaSolo |
| MEDIA_WR_WA(waTable, WaDisregardPlatformChecks, (UserFeatureData.i32Data) ? true : false); |
| #endif |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| #ifndef I915_PARAM_HAS_BSD2 |
| #define LOCAL_I915_PARAM_HAS_BSD2 I915_PARAM_HAS_BSD2 |
| #else |
| #define LOCAL_I915_PARAM_HAS_BSD2 31 |
| #endif |
| |
| #ifdef I915_PARAM_HUC_STATUS |
| #define LOCAL_I915_PARAM_HAS_HUC I915_PARAM_HUC_STATUS |
| #else |
| #define LOCAL_I915_PARAM_HAS_HUC 42 |
| #endif |
| |
| #ifdef I915_PARAM_EU_TOTAL |
| #define LOCAL_I915_PARAM_EU_TOTAL I915_PARAM_EU_TOTAL |
| #else |
| #define LOCAL_I915_PARAM_EU_TOTAL 34 |
| #endif |
| |
| #ifdef I915_PARAM_SUBSLICE_TOTAL |
| #define LOCAL_I915_PARAM_SUBSLICE I915_PARAM_SUBSLICE_TOTAL |
| #else |
| #define LOCAL_I915_PARAM_SUBSLICE 33 |
| #endif |
| |
| #ifdef I915_PARAM_REVISION |
| #define LOCAL_I915_PARAM_REVISION I915_PARAM_REVISION |
| #else |
| #define LOCAL_I915_PARAM_REVISION 32 |
| #endif |
| |
| MOS_STATUS HWInfoGetLinuxDrvInfo(int fd, struct LinuxDriverInfo *drvInfo) |
| { |
| if ((fd < 0) || (drvInfo == nullptr)) |
| { |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| uint32_t retValue = 0; |
| |
| drvInfo->hasBsd = 0; |
| if (MediaGetParam(fd, I915_PARAM_HAS_BSD, &retValue)) |
| { |
| drvInfo->hasBsd = !!retValue; |
| } |
| |
| drvInfo->hasBsd2 = 0; |
| retValue = 0; |
| if (MediaGetParam(fd, LOCAL_I915_PARAM_HAS_BSD2, &retValue)) |
| { |
| drvInfo->hasBsd2 = !!retValue; |
| } |
| |
| drvInfo->hasVebox = 0; |
| retValue = 0; |
| if (MediaGetParam(fd, I915_PARAM_HAS_VEBOX, &retValue)) |
| { |
| drvInfo->hasVebox = !!retValue; |
| } |
| |
| drvInfo->hasPpgtt = 1; |
| retValue = 0; |
| if (MediaGetParam(fd, I915_PARAM_HAS_ALIASING_PPGTT, &retValue)) |
| { |
| drvInfo->hasPpgtt = !!retValue; |
| } |
| |
| drvInfo->hasHuc = 0; |
| retValue = 0; |
| if (MediaGetParam(fd, LOCAL_I915_PARAM_HAS_HUC, &retValue)) |
| { |
| drvInfo->hasHuc = !!retValue; |
| } |
| |
| drvInfo->devId = 0; |
| retValue = 0; |
| if (MediaGetParam(fd, I915_PARAM_CHIPSET_ID, &retValue)) |
| { |
| drvInfo->devId = retValue; |
| } |
| drvInfo->devRev = 0; |
| retValue = 0; |
| if (MediaGetParam(fd, LOCAL_I915_PARAM_REVISION, &retValue)) |
| { |
| drvInfo->devRev = retValue; |
| } |
| |
| drvInfo->euCount = 0; |
| retValue = 0; |
| if (MediaGetParam(fd, LOCAL_I915_PARAM_EU_TOTAL, &retValue)) |
| { |
| drvInfo->euCount = retValue; |
| } |
| |
| drvInfo->subSliceCount = 0; |
| retValue = 0; |
| if (MediaGetParam(fd, LOCAL_I915_PARAM_SUBSLICE, &retValue)) |
| { |
| drvInfo->subSliceCount = retValue; |
| } |
| |
| // There is no interface to read total slice count from drm/i915, so we |
| // will set the slice count in InitMediaSysInfo accordint to Device ID. |
| drvInfo->sliceCount = 0; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| /*****************************************************************************\ |
| Description: |
| Get the required Sku/Wa tables for GMM and platform information based on device Fd |
| |
| Input: |
| fd - file descriptor to the /dev/dri/cardX |
| Output: |
| SHADOW_MEDIA_FEATURE_TABLE *shadowSkuTable |
| SHADOW_MEDIA_WA_TABLE *shadowWaTable, |
| MEDIA_SYSTEM_INFO *systemInfo |
| \*****************************************************************************/ |
| MOS_STATUS HWInfo_GetGmmInfo(int32_t fd, |
| SHADOW_MEDIA_FEATURE_TABLE *shadowSkuTable, |
| SHADOW_MEDIA_WA_TABLE *shadowWaTable, |
| MEDIA_SYSTEM_INFO *systemInfo) |
| { |
| if ((fd < 0) || |
| (shadowSkuTable == nullptr) || |
| (shadowWaTable == nullptr) || |
| (systemInfo == nullptr)) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid parameter \n"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| LinuxDriverInfo drvInfo = {18, 3, 0, 23172, 3, 1, 0, 1, 0, 0, 1, 0}; |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| #endif |
| |
| if (!Mos_Solo_IsEnabled(nullptr) && HWInfoGetLinuxDrvInfo(fd, &drvInfo) != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get the chipset id\n"); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| GfxDeviceInfo *devInfo = getDeviceInfo(drvInfo.devId); |
| if (devInfo == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get the device info for Device id: %x\n", drvInfo.devId); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| |
| if (devInfo->InitMediaSysInfo && |
| devInfo->InitShadowSku && |
| devInfo->InitShadowWa && |
| devInfo->InitMediaSysInfo(devInfo, systemInfo) && |
| devInfo->InitShadowSku(devInfo, shadowSkuTable, &drvInfo) && |
| devInfo->InitShadowWa(devInfo, shadowWaTable, &drvInfo)) |
| { |
| MOS_OS_NORMALMESSAGE("Init Media SystemInfo successfully\n"); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to Init Media System Info\n"); |
| return MOS_STATUS_PLATFORM_NOT_SUPPORTED; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |