/*
* 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;
}

