| /* |
| * Copyright (c) 2017, 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" |
| |
| |
| 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; |
| return drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0; |
| } |
| |
| // Currently all Gen HW has 7 threads per EU. Redefine when this changes. |
| #define GEN_HW_THREADS_PER_EU 7 |
| |
| /*****************************************************************************\ |
| 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, |
| PLATFORM *gfxPlatform, |
| MEDIA_FEATURE_TABLE *skuTable, |
| MEDIA_WA_TABLE *waTable, |
| MEDIA_SYSTEM_INFO *gtSystemInfo) |
| { |
| if ((fd < 0) || |
| (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() && 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; |
| |
| 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; |
| } |
| |
| 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); |
| //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() && 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; |
| } |
| |