Home | History | Annotate | Download | only in r800
      1 /*
      2  * Copyright  2014 Advanced Micro Devices, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     15  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     16  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
     17  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  * The above copyright notice and this permission notice (including the
     23  * next paragraph) shall be included in all copies or substantial portions
     24  * of the Software.
     25  */
     26 
     27 /**
     28 ***************************************************************************************************
     29 * @file  ciaddrlib.cpp
     30 * @brief Contains the implementation for the CIAddrLib class.
     31 ***************************************************************************************************
     32 */
     33 
     34 #include "ciaddrlib.h"
     35 
     36 #include "si_gb_reg.h"
     37 
     38 #include "si_ci_vi_merged_enum.h"
     39 
     40 #if BRAHMA_BUILD
     41 #include "amdgpu_id.h"
     42 #else
     43 #include "ci_id.h"
     44 #include "kv_id.h"
     45 #include "vi_id.h"
     46 #endif
     47 
     48 ///////////////////////////////////////////////////////////////////////////////////////////////////
     49 ///////////////////////////////////////////////////////////////////////////////////////////////////
     50 
     51 /**
     52 ***************************************************************************************************
     53 *   AddrMask
     54 *
     55 *   @brief
     56 *       Gets a mask of "width"
     57 *   @return
     58 *       Bit mask
     59 ***************************************************************************************************
     60 */
     61 static UINT_64 AddrMask(
     62     UINT_32 width)  ///< Width of bits
     63 {
     64     UINT_64 ret;
     65 
     66     if (width >= sizeof(UINT_64)*8)
     67     {
     68         ret = ~((UINT_64) 0);
     69     }
     70     else
     71     {
     72         return (((UINT_64) 1) << width) - 1;
     73     }
     74     return ret;
     75 }
     76 
     77 /**
     78 ***************************************************************************************************
     79 *   AddrGetBits
     80 *
     81 *   @brief
     82 *       Gets bits within a range of [msb, lsb]
     83 *   @return
     84 *       Bits of this range
     85 ***************************************************************************************************
     86 */
     87 static UINT_64 AddrGetBits(
     88     UINT_64 bits,   ///< Source bits
     89     UINT_32 msb,    ///< Most signicant bit
     90     UINT_32 lsb)    ///< Least signicant bit
     91 {
     92     UINT_64 ret = 0;
     93 
     94     if (msb >= lsb)
     95     {
     96         ret = (bits >> lsb) & (AddrMask(1 + msb - lsb));
     97     }
     98     return ret;
     99 }
    100 
    101 /**
    102 ***************************************************************************************************
    103 *   AddrRemoveBits
    104 *
    105 *   @brief
    106 *       Removes bits within the range of [msb, lsb]
    107 *   @return
    108 *       Modified bits
    109 ***************************************************************************************************
    110 */
    111 static UINT_64 AddrRemoveBits(
    112     UINT_64 bits,   ///< Source bits
    113     UINT_32 msb,    ///< Most signicant bit
    114     UINT_32 lsb)    ///< Least signicant bit
    115 {
    116     UINT_64 ret = bits;
    117 
    118     if (msb >= lsb)
    119     {
    120         ret = AddrGetBits(bits, lsb - 1, 0) // low bits
    121             | (AddrGetBits(bits, 8 * sizeof(bits) - 1, msb + 1) << lsb); //high bits
    122     }
    123     return ret;
    124 }
    125 
    126 /**
    127 ***************************************************************************************************
    128 *   AddrInsertBits
    129 *
    130 *   @brief
    131 *       Inserts new bits into the range of [msb, lsb]
    132 *   @return
    133 *       Modified bits
    134 ***************************************************************************************************
    135 */
    136 static UINT_64 AddrInsertBits(
    137     UINT_64 bits,       ///< Source bits
    138     UINT_64 newBits,    ///< New bits to be inserted
    139     UINT_32 msb,        ///< Most signicant bit
    140     UINT_32 lsb)        ///< Least signicant bit
    141 {
    142     UINT_64 ret = bits;
    143 
    144     if (msb >= lsb)
    145     {
    146         ret = AddrGetBits(bits, lsb - 1, 0) // old low bitss
    147              | (AddrGetBits(newBits, msb - lsb, 0) << lsb) //new bits
    148              | (AddrGetBits(bits, 8 * sizeof(bits) - 1, lsb) << (msb + 1)); //old high bits
    149     }
    150     return ret;
    151 }
    152 
    153 
    154 /**
    155 ***************************************************************************************************
    156 *   AddrCIHwlInit
    157 *
    158 *   @brief
    159 *       Creates an CIAddrLib object.
    160 *
    161 *   @return
    162 *       Returns an CIAddrLib object pointer.
    163 ***************************************************************************************************
    164 */
    165 AddrLib* AddrCIHwlInit(const AddrClient* pClient)
    166 {
    167     return CIAddrLib::CreateObj(pClient);
    168 }
    169 
    170 /**
    171 ***************************************************************************************************
    172 *   CIAddrLib::CIAddrLib
    173 *
    174 *   @brief
    175 *       Constructor
    176 *
    177 ***************************************************************************************************
    178 */
    179 CIAddrLib::CIAddrLib(const AddrClient* pClient) :
    180     SIAddrLib(pClient),
    181     m_noOfMacroEntries(0),
    182     m_allowNonDispThickModes(FALSE)
    183 {
    184     m_class = CI_ADDRLIB;
    185     memset(&m_settings, 0, sizeof(m_settings));
    186 }
    187 
    188 /**
    189 ***************************************************************************************************
    190 *   CIAddrLib::~CIAddrLib
    191 *
    192 *   @brief
    193 *       Destructor
    194 ***************************************************************************************************
    195 */
    196 CIAddrLib::~CIAddrLib()
    197 {
    198 }
    199 
    200 /**
    201 ***************************************************************************************************
    202 *   CIAddrLib::HwlComputeDccInfo
    203 *
    204 *   @brief
    205 *       Compute DCC key size, base alignment
    206 *   @return
    207 *       ADDR_E_RETURNCODE
    208 ***************************************************************************************************
    209 */
    210 ADDR_E_RETURNCODE CIAddrLib::HwlComputeDccInfo(
    211     const ADDR_COMPUTE_DCCINFO_INPUT*  pIn,
    212     ADDR_COMPUTE_DCCINFO_OUTPUT*       pOut) const
    213 {
    214     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    215 
    216     if (m_settings.isVolcanicIslands && IsMacroTiled(pIn->tileMode))
    217     {
    218         UINT_64 dccFastClearSize = pIn->colorSurfSize >> 8;
    219 
    220         ADDR_ASSERT(0 == (pIn->colorSurfSize & 0xff));
    221 
    222         if (pIn->numSamples > 1)
    223         {
    224             UINT_32 tileSizePerSample = BITS_TO_BYTES(pIn->bpp * MicroTileWidth * MicroTileHeight);
    225             UINT_32 samplesPerSplit  = pIn->tileInfo.tileSplitBytes / tileSizePerSample;
    226 
    227             if (samplesPerSplit < pIn->numSamples)
    228             {
    229                 UINT_32 numSplits = pIn->numSamples / samplesPerSplit;
    230                 UINT_32 fastClearBaseAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
    231 
    232                 ADDR_ASSERT(IsPow2(fastClearBaseAlign));
    233 
    234                 dccFastClearSize /= numSplits;
    235 
    236                 if (0 != (dccFastClearSize & (fastClearBaseAlign - 1)))
    237                 {
    238                     // Disable dcc fast clear
    239                     // if key size of fisrt sample split is not pipe*interleave aligned
    240                     dccFastClearSize = 0;
    241                 }
    242             }
    243         }
    244 
    245         pOut->dccRamSize          = pIn->colorSurfSize >> 8;
    246         pOut->dccRamBaseAlign     = pIn->tileInfo.banks *
    247                                     HwlGetPipes(&pIn->tileInfo) *
    248                                     m_pipeInterleaveBytes;
    249         pOut->dccFastClearSize    = dccFastClearSize;
    250 
    251         ADDR_ASSERT(IsPow2(pOut->dccRamBaseAlign));
    252 
    253         if (0 == (pOut->dccRamSize & (pOut->dccRamBaseAlign - 1)))
    254         {
    255             pOut->subLvlCompressible = TRUE;
    256         }
    257         else
    258         {
    259             UINT_64 dccRamSizeAlign = HwlGetPipes(&pIn->tileInfo) * m_pipeInterleaveBytes;
    260 
    261             if (pOut->dccRamSize == pOut->dccFastClearSize)
    262             {
    263                 pOut->dccFastClearSize = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
    264             }
    265             pOut->dccRamSize          = PowTwoAlign(pOut->dccRamSize, dccRamSizeAlign);
    266             pOut->subLvlCompressible  = FALSE;
    267         }
    268     }
    269     else
    270     {
    271         returnCode = ADDR_NOTSUPPORTED;
    272     }
    273 
    274     return returnCode;
    275 }
    276 
    277 /**
    278 ***************************************************************************************************
    279 *   CIAddrLib::HwlComputeCmaskAddrFromCoord
    280 *
    281 *   @brief
    282 *       Compute tc compatible Cmask address from fmask ram address
    283 *
    284 *   @return
    285 *       ADDR_E_RETURNCODE
    286 ***************************************************************************************************
    287 */
    288 ADDR_E_RETURNCODE CIAddrLib::HwlComputeCmaskAddrFromCoord(
    289     const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*  pIn,  ///< [in] fmask addr/bpp/tile input
    290     ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*       pOut  ///< [out] cmask address
    291     ) const
    292 {
    293     ADDR_E_RETURNCODE returnCode = ADDR_NOTSUPPORTED;
    294 
    295     if ((m_settings.isVolcanicIslands == TRUE) &&
    296         (pIn->flags.tcCompatible == TRUE))
    297     {
    298         UINT_32 numOfPipes   = HwlGetPipes(pIn->pTileInfo);
    299         UINT_32 numOfBanks   = pIn->pTileInfo->banks;
    300         UINT_64 fmaskAddress = pIn->fmaskAddr;
    301         UINT_32 elemBits     = pIn->bpp;
    302         UINT_32 blockByte    = 64 * elemBits / 8;
    303         UINT_64 metaNibbleAddress = HwlComputeMetadataNibbleAddress(fmaskAddress,
    304                                                                     0,
    305                                                                     0,
    306                                                                     4,
    307                                                                     elemBits,
    308                                                                     blockByte,
    309                                                                     m_pipeInterleaveBytes,
    310                                                                     numOfPipes,
    311                                                                     numOfBanks,
    312                                                                     1);
    313         pOut->addr = (metaNibbleAddress >> 1);
    314         pOut->bitPosition = (metaNibbleAddress % 2) ? 4 : 0;
    315         returnCode = ADDR_OK;
    316     }
    317 
    318     return returnCode;
    319 }
    320 /**
    321 ***************************************************************************************************
    322 *   CIAddrLib::HwlConvertChipFamily
    323 *
    324 *   @brief
    325 *       Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision
    326 *   @return
    327 *       AddrChipFamily
    328 ***************************************************************************************************
    329 */
    330 AddrChipFamily CIAddrLib::HwlConvertChipFamily(
    331     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
    332     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
    333 {
    334     AddrChipFamily family = ADDR_CHIP_FAMILY_CI;
    335 
    336     switch (uChipFamily)
    337     {
    338         case FAMILY_CI:
    339             m_settings.isSeaIsland  = 1;
    340             m_settings.isBonaire    = ASICREV_IS_BONAIRE_M(uChipRevision);
    341             m_settings.isHawaii     = ASICREV_IS_HAWAII_P(uChipRevision);
    342             break;
    343         case FAMILY_KV:
    344             m_settings.isKaveri     = 1;
    345             m_settings.isSpectre    = ASICREV_IS_SPECTRE(uChipRevision);
    346             m_settings.isSpooky     = ASICREV_IS_SPOOKY(uChipRevision);
    347             m_settings.isKalindi    = ASICREV_IS_KALINDI(uChipRevision);
    348             break;
    349         case FAMILY_VI:
    350             m_settings.isVolcanicIslands = 1;
    351             m_settings.isIceland         = ASICREV_IS_ICELAND_M(uChipRevision);
    352             m_settings.isTonga           = ASICREV_IS_TONGA_P(uChipRevision);
    353             m_settings.isFiji            = ASICREV_IS_FIJI_P(uChipRevision);
    354             m_settings.isPolaris10       = ASICREV_IS_POLARIS10_P(uChipRevision);
    355             m_settings.isPolaris11       = ASICREV_IS_POLARIS11_M(uChipRevision);
    356             m_settings.isPolaris12       = ASICREV_IS_POLARIS12_V(uChipRevision);
    357             break;
    358         case FAMILY_CZ:
    359             m_settings.isCarrizo         = 1;
    360             m_settings.isVolcanicIslands = 1;
    361             break;
    362         default:
    363             ADDR_ASSERT(!"This should be a unexpected Fusion");
    364             break;
    365     }
    366 
    367     return family;
    368 }
    369 
    370 /**
    371 ***************************************************************************************************
    372 *   CIAddrLib::HwlInitGlobalParams
    373 *
    374 *   @brief
    375 *       Initializes global parameters
    376 *
    377 *   @return
    378 *       TRUE if all settings are valid
    379 *
    380 ***************************************************************************************************
    381 */
    382 BOOL_32 CIAddrLib::HwlInitGlobalParams(
    383     const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
    384 {
    385     BOOL_32  valid = TRUE;
    386 
    387     const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue;
    388 
    389     valid = DecodeGbRegs(pRegValue);
    390 
    391     // The following assignments for m_pipes is only for fail-safe, InitTileSettingTable should
    392     // read the correct pipes from tile mode table
    393     if (m_settings.isHawaii)
    394     {
    395         // Hawaii has 16-pipe, see GFXIP_Config_Summary.xls
    396         m_pipes = 16;
    397     }
    398     else if (m_settings.isBonaire || m_settings.isSpectre)
    399     {
    400         m_pipes = 4;
    401     }
    402     else // Treat other KV asics to be 2-pipe
    403     {
    404         m_pipes = 2;
    405     }
    406 
    407     // @todo: VI
    408     // Move this to VI code path once created
    409     if (m_settings.isTonga || m_settings.isPolaris10)
    410     {
    411         m_pipes = 8;
    412     }
    413     else if (m_settings.isIceland)
    414     {
    415         m_pipes = 2;
    416     }
    417     else if (m_settings.isFiji)
    418     {
    419         m_pipes = 16;
    420     }
    421     else if (m_settings.isPolaris11 || m_settings.isPolaris12)
    422     {
    423         m_pipes = 4;
    424     }
    425 
    426     if (valid)
    427     {
    428         valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries);
    429     }
    430     if (valid)
    431     {
    432         valid = InitMacroTileCfgTable(pRegValue->pMacroTileConfig, pRegValue->noOfMacroEntries);
    433     }
    434 
    435     return valid;
    436 }
    437 
    438 /**
    439 ***************************************************************************************************
    440 *   CIAddrLib::HwlPostCheckTileIndex
    441 *
    442 *   @brief
    443 *       Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches
    444 *       tile mode/type/info and change the index if needed
    445 *   @return
    446 *       Tile index.
    447 ***************************************************************************************************
    448 */
    449 INT_32 CIAddrLib::HwlPostCheckTileIndex(
    450     const ADDR_TILEINFO* pInfo,     ///< [in] Tile Info
    451     AddrTileMode         mode,      ///< [in] Tile mode
    452     AddrTileType         type,      ///< [in] Tile type
    453     INT                  curIndex   ///< [in] Current index assigned in HwlSetupTileInfo
    454     ) const
    455 {
    456     INT_32 index = curIndex;
    457 
    458     if (mode == ADDR_TM_LINEAR_GENERAL)
    459     {
    460         index = TileIndexLinearGeneral;
    461     }
    462     else
    463     {
    464         BOOL_32 macroTiled = IsMacroTiled(mode);
    465 
    466         // We need to find a new index if either of them is true
    467         // 1. curIndex is invalid
    468         // 2. tile mode is changed
    469         // 3. tile info does not match for macro tiled
    470         if ((index == TileIndexInvalid)         ||
    471             (mode != m_tileTable[index].mode)   ||
    472             (macroTiled && pInfo->pipeConfig != m_tileTable[index].info.pipeConfig))
    473         {
    474             for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++)
    475             {
    476                 if (macroTiled)
    477                 {
    478                     // macro tile modes need all to match
    479                     if ((pInfo->pipeConfig == m_tileTable[index].info.pipeConfig) &&
    480                         (mode == m_tileTable[index].mode) &&
    481                         (type == m_tileTable[index].type))
    482                     {
    483                         // tileSplitBytes stored in m_tileTable is only valid for depth entries
    484                         if (type == ADDR_DEPTH_SAMPLE_ORDER)
    485                         {
    486                             if (pInfo->tileSplitBytes == m_tileTable[index].info.tileSplitBytes)
    487                             {
    488                                 break;
    489                             }
    490                         }
    491                         else // other entries are determined by other 3 fields
    492                         {
    493                             break;
    494                         }
    495                     }
    496                 }
    497                 else if (mode == ADDR_TM_LINEAR_ALIGNED)
    498                 {
    499                     // linear mode only needs tile mode to match
    500                     if (mode == m_tileTable[index].mode)
    501                     {
    502                         break;
    503                     }
    504                 }
    505                 else
    506                 {
    507                     // micro tile modes only need tile mode and tile type to match
    508                     if (mode == m_tileTable[index].mode &&
    509                         type == m_tileTable[index].type)
    510                     {
    511                         break;
    512                     }
    513                 }
    514             }
    515         }
    516     }
    517 
    518     ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries));
    519 
    520     if (index >= static_cast<INT_32>(m_noOfEntries))
    521     {
    522         index = TileIndexInvalid;
    523     }
    524 
    525     return index;
    526 }
    527 
    528 /**
    529 ***************************************************************************************************
    530 *   CIAddrLib::HwlSetupTileCfg
    531 *
    532 *   @brief
    533 *       Map tile index to tile setting.
    534 *   @return
    535 *       ADDR_E_RETURNCODE
    536 ***************************************************************************************************
    537 */
    538 ADDR_E_RETURNCODE CIAddrLib::HwlSetupTileCfg(
    539     INT_32          index,          ///< [in] Tile index
    540     INT_32          macroModeIndex, ///< [in] Index in macro tile mode table(CI)
    541     ADDR_TILEINFO*  pInfo,          ///< [out] Tile Info
    542     AddrTileMode*   pMode,          ///< [out] Tile mode
    543     AddrTileType*   pType           ///< [out] Tile type
    544     ) const
    545 {
    546     ADDR_E_RETURNCODE returnCode = ADDR_OK;
    547 
    548     // Global flag to control usage of tileIndex
    549     if (UseTileIndex(index))
    550     {
    551         if (static_cast<UINT_32>(index) >= m_noOfEntries)
    552         {
    553             returnCode = ADDR_INVALIDPARAMS;
    554         }
    555         else
    556         {
    557             const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index);
    558 
    559             if (pInfo != NULL)
    560             {
    561                 if (IsMacroTiled(pCfgTable->mode))
    562                 {
    563                     ADDR_ASSERT(((macroModeIndex != TileIndexInvalid)
    564                         && (macroModeIndex != TileIndexNoMacroIndex)));
    565                     // Here we used tile_bytes to replace of tile_split
    566                     // According info as below:
    567                     // "tile_split_c = MIN(ROW_SIZE, tile_split)
    568                     // "tile_bytes = MIN(tile_split_c, num_samples * tile_bytes_1x)
    569                     // when using tile_bytes replacing of tile_split, the result of
    570                     // alignment and others(such as slicesPerTile) are unaffected -
    571                     // since if tile_split_c is larger, split won't happen, otherwise
    572                     // (num_samples * tile_bytes_1x is larger), a correct tile_split is
    573                     // returned.
    574                     *pInfo = m_macroTileTable[macroModeIndex];
    575 
    576                     if (pCfgTable->type == ADDR_DEPTH_SAMPLE_ORDER)
    577                     {
    578                         pInfo->tileSplitBytes = pCfgTable->info.tileSplitBytes;
    579                     }
    580                     pInfo->pipeConfig = pCfgTable->info.pipeConfig;
    581                 }
    582                 else // 1D and linear modes, we return default value stored in table
    583                 {
    584                     *pInfo = pCfgTable->info;
    585                 }
    586             }
    587 
    588             if (pMode != NULL)
    589             {
    590                 *pMode = pCfgTable->mode;
    591             }
    592 
    593             if (pType != NULL)
    594             {
    595                 *pType = pCfgTable->type;
    596             }
    597         }
    598     }
    599 
    600     return returnCode;
    601 }
    602 
    603 /**
    604 ***************************************************************************************************
    605 *   CIAddrLib::HwlComputeSurfaceInfo
    606 *
    607 *   @brief
    608 *       Entry of ci's ComputeSurfaceInfo
    609 *   @return
    610 *       ADDR_E_RETURNCODE
    611 ***************************************************************************************************
    612 */
    613 ADDR_E_RETURNCODE CIAddrLib::HwlComputeSurfaceInfo(
    614     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,    ///< [in] input structure
    615     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [out] output structure
    616     ) const
    617 {
    618     // If tileIndex is invalid, force macroModeIndex to be invalid, too
    619     if (pIn->tileIndex == TileIndexInvalid)
    620     {
    621         pOut->macroModeIndex = TileIndexInvalid;
    622     }
    623 
    624     ADDR_E_RETURNCODE retCode = SIAddrLib::HwlComputeSurfaceInfo(pIn,pOut);
    625 
    626     if (pOut->macroModeIndex == TileIndexNoMacroIndex)
    627     {
    628         pOut->macroModeIndex = TileIndexInvalid;
    629     }
    630 
    631     return retCode;
    632 }
    633 
    634 /**
    635 ***************************************************************************************************
    636 *   CIAddrLib::HwlFmaskSurfaceInfo
    637 *   @brief
    638 *       Entry of r800's ComputeFmaskInfo
    639 *   @return
    640 *       ADDR_E_RETURNCODE
    641 ***************************************************************************************************
    642 */
    643 ADDR_E_RETURNCODE CIAddrLib::HwlComputeFmaskInfo(
    644     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,   ///< [in] input structure
    645     ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut   ///< [out] output structure
    646     )
    647 {
    648     ADDR_E_RETURNCODE retCode = ADDR_OK;
    649 
    650     ADDR_TILEINFO tileInfo = {0};
    651     ADDR_COMPUTE_FMASK_INFO_INPUT fmaskIn;
    652     fmaskIn = *pIn;
    653 
    654     AddrTileMode tileMode = pIn->tileMode;
    655 
    656     // Use internal tile info if pOut does not have a valid pTileInfo
    657     if (pOut->pTileInfo == NULL)
    658     {
    659         pOut->pTileInfo = &tileInfo;
    660     }
    661 
    662     ADDR_ASSERT(tileMode == ADDR_TM_2D_TILED_THIN1     ||
    663                 tileMode == ADDR_TM_3D_TILED_THIN1     ||
    664                 tileMode == ADDR_TM_PRT_TILED_THIN1    ||
    665                 tileMode == ADDR_TM_PRT_2D_TILED_THIN1 ||
    666                 tileMode == ADDR_TM_PRT_3D_TILED_THIN1);
    667 
    668     ADDR_ASSERT(m_tileTable[14].mode == ADDR_TM_2D_TILED_THIN1);
    669     ADDR_ASSERT(m_tileTable[15].mode == ADDR_TM_3D_TILED_THIN1);
    670 
    671     // The only valid tile modes for fmask are 2D_THIN1 and 3D_THIN1 plus non-displayable
    672     INT_32 tileIndex = tileMode == ADDR_TM_2D_TILED_THIN1 ? 14 : 15;
    673     ADDR_SURFACE_FLAGS flags = {{0}};
    674     flags.fmask = 1;
    675 
    676     INT_32 macroModeIndex = TileIndexInvalid;
    677 
    678     UINT_32 numSamples = pIn->numSamples;
    679     UINT_32 numFrags = pIn->numFrags == 0 ? numSamples : pIn->numFrags;
    680 
    681     UINT_32 bpp = QLog2(numFrags);
    682 
    683     // EQAA needs one more bit
    684     if (numSamples > numFrags)
    685     {
    686         bpp++;
    687     }
    688 
    689     if (bpp == 3)
    690     {
    691         bpp = 4;
    692     }
    693 
    694     bpp = Max(8u, bpp * numSamples);
    695 
    696     macroModeIndex = HwlComputeMacroModeIndex(tileIndex, flags, bpp, numSamples, pOut->pTileInfo);
    697 
    698     fmaskIn.tileIndex = tileIndex;
    699     fmaskIn.pTileInfo = pOut->pTileInfo;
    700     pOut->macroModeIndex = macroModeIndex;
    701     pOut->tileIndex = tileIndex;
    702 
    703     retCode = DispatchComputeFmaskInfo(&fmaskIn, pOut);
    704 
    705     if (retCode == ADDR_OK)
    706     {
    707         pOut->tileIndex =
    708             HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
    709                                   pOut->tileIndex);
    710     }
    711 
    712     // Resets pTileInfo to NULL if the internal tile info is used
    713     if (pOut->pTileInfo == &tileInfo)
    714     {
    715         pOut->pTileInfo = NULL;
    716     }
    717 
    718     return retCode;
    719 }
    720 
    721 /**
    722 ***************************************************************************************************
    723 *   CIAddrLib::HwlFmaskPreThunkSurfInfo
    724 *
    725 *   @brief
    726 *       Some preparation before thunking a ComputeSurfaceInfo call for Fmask
    727 *   @return
    728 *       ADDR_E_RETURNCODE
    729 ***************************************************************************************************
    730 */
    731 VOID CIAddrLib::HwlFmaskPreThunkSurfInfo(
    732     const ADDR_COMPUTE_FMASK_INFO_INPUT*    pFmaskIn,   ///< [in] Input of fmask info
    733     const ADDR_COMPUTE_FMASK_INFO_OUTPUT*   pFmaskOut,  ///< [in] Output of fmask info
    734     ADDR_COMPUTE_SURFACE_INFO_INPUT*        pSurfIn,    ///< [out] Input of thunked surface info
    735     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pSurfOut    ///< [out] Output of thunked surface info
    736     ) const
    737 {
    738     pSurfIn->tileIndex = pFmaskIn->tileIndex;
    739     pSurfOut->macroModeIndex  = pFmaskOut->macroModeIndex;
    740 }
    741 
    742 /**
    743 ***************************************************************************************************
    744 *   CIAddrLib::HwlFmaskPostThunkSurfInfo
    745 *
    746 *   @brief
    747 *       Copy hwl extra field after calling thunked ComputeSurfaceInfo
    748 *   @return
    749 *       ADDR_E_RETURNCODE
    750 ***************************************************************************************************
    751 */
    752 VOID CIAddrLib::HwlFmaskPostThunkSurfInfo(
    753     const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut,   ///< [in] Output of surface info
    754     ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut           ///< [out] Output of fmask info
    755     ) const
    756 {
    757     pFmaskOut->tileIndex = pSurfOut->tileIndex;
    758     pFmaskOut->macroModeIndex = pSurfOut->macroModeIndex;
    759 }
    760 
    761 /**
    762 ***************************************************************************************************
    763 *   CIAddrLib::HwlDegradeThickTileMode
    764 *
    765 *   @brief
    766 *       Degrades valid tile mode for thick modes if needed
    767 *
    768 *   @return
    769 *       Suitable tile mode
    770 ***************************************************************************************************
    771 */
    772 AddrTileMode CIAddrLib::HwlDegradeThickTileMode(
    773     AddrTileMode        baseTileMode,   ///< [in] base tile mode
    774     UINT_32             numSlices,      ///< [in] current number of slices
    775     UINT_32*            pBytesPerTile   ///< [in/out] pointer to bytes per slice
    776     ) const
    777 {
    778     return baseTileMode;
    779 }
    780 
    781 /**
    782 ***************************************************************************************************
    783 *   CIAddrLib::HwlOverrideTileMode
    784 *
    785 *   @brief
    786 *       Override THICK to THIN, for specific formats on CI
    787 *
    788 *   @return
    789 *       Suitable tile mode
    790 *
    791 ***************************************************************************************************
    792 */
    793 BOOL_32 CIAddrLib::HwlOverrideTileMode(
    794     const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,       ///< [in] input structure
    795     AddrTileMode*                           pTileMode, ///< [in/out] pointer to the tile mode
    796     AddrTileType*                           pTileType  ///< [in/out] pointer to the tile type
    797     ) const
    798 {
    799     BOOL_32 bOverrided = FALSE;
    800     AddrTileMode tileMode = *pTileMode;
    801 
    802     // currently, all CI/VI family do not
    803     // support ADDR_TM_PRT_2D_TILED_THICK,ADDR_TM_PRT_3D_TILED_THICK and
    804     // ADDR_TM_PRT_2D_TILED_THIN1, ADDR_TM_PRT_3D_TILED_THIN1
    805     switch (tileMode)
    806     {
    807         case ADDR_TM_PRT_2D_TILED_THICK:
    808         case ADDR_TM_PRT_3D_TILED_THICK:
    809             tileMode = ADDR_TM_PRT_TILED_THICK;
    810             break;
    811         case ADDR_TM_PRT_2D_TILED_THIN1:
    812         case ADDR_TM_PRT_3D_TILED_THIN1:
    813             tileMode = ADDR_TM_PRT_TILED_THIN1;
    814             break;
    815         default:
    816             break;
    817     }
    818 
    819     // UBTS#404321, we do not need such overriding, as THICK+THICK entries removed from the tile-mode table
    820     if (!m_settings.isBonaire)
    821     {
    822         UINT_32 thickness = ComputeSurfaceThickness(tileMode);
    823 
    824         // tile_thickness = (array_mode == XTHICK) ? 8 : ((array_mode == THICK) ? 4 : 1)
    825         if (thickness > 1)
    826         {
    827             switch (pIn->format)
    828             {
    829                 // see //gfxip/gcB/devel/cds/src/verif/tc/models/csim/tcp.cpp
    830                 // tcpError("Thick micro tiling is not supported for format...
    831                 case ADDR_FMT_X24_8_32_FLOAT:
    832                 case ADDR_FMT_32_AS_8:
    833                 case ADDR_FMT_32_AS_8_8:
    834                 case ADDR_FMT_32_AS_32_32_32_32:
    835 
    836                 // packed formats
    837                 case ADDR_FMT_GB_GR:
    838                 case ADDR_FMT_BG_RG:
    839                 case ADDR_FMT_1_REVERSED:
    840                 case ADDR_FMT_1:
    841                 case ADDR_FMT_BC1:
    842                 case ADDR_FMT_BC2:
    843                 case ADDR_FMT_BC3:
    844                 case ADDR_FMT_BC4:
    845                 case ADDR_FMT_BC5:
    846                 case ADDR_FMT_BC6:
    847                 case ADDR_FMT_BC7:
    848                     switch (tileMode)
    849                     {
    850                         case ADDR_TM_1D_TILED_THICK:
    851                             tileMode    = ADDR_TM_1D_TILED_THIN1;
    852                             break;
    853 
    854                         case ADDR_TM_2D_TILED_XTHICK:
    855                         case ADDR_TM_2D_TILED_THICK:
    856                             tileMode    = ADDR_TM_2D_TILED_THIN1;
    857                             break;
    858 
    859                         case ADDR_TM_3D_TILED_XTHICK:
    860                         case ADDR_TM_3D_TILED_THICK:
    861                             tileMode    = ADDR_TM_3D_TILED_THIN1;
    862                             break;
    863 
    864                         case ADDR_TM_PRT_TILED_THICK:
    865                             tileMode    = ADDR_TM_PRT_TILED_THIN1;
    866                             break;
    867 
    868                         case ADDR_TM_PRT_2D_TILED_THICK:
    869                             tileMode    = ADDR_TM_PRT_2D_TILED_THIN1;
    870                             break;
    871 
    872                         case ADDR_TM_PRT_3D_TILED_THICK:
    873                             tileMode    = ADDR_TM_PRT_3D_TILED_THIN1;
    874                             break;
    875 
    876                         default:
    877                             break;
    878 
    879                     }
    880 
    881                     // Switch tile type from thick to thin
    882                     if (tileMode != *pTileMode)
    883                     {
    884                         // see tileIndex: 13-18
    885                         *pTileType = ADDR_NON_DISPLAYABLE;
    886                     }
    887 
    888                     break;
    889                 default:
    890                     break;
    891             }
    892         }
    893     }
    894 
    895     if (tileMode != *pTileMode)
    896     {
    897         *pTileMode = tileMode;
    898         bOverrided = TRUE;
    899     }
    900 
    901     return bOverrided;
    902 }
    903 
    904 /**
    905 ***************************************************************************************************
    906 *   CiAddrLib::GetPrtSwitchP4Threshold
    907 *
    908 *   @brief
    909 *       Return the threshold of switching to P4_* instead of P16_* for PRT resources
    910 ***************************************************************************************************
    911 */
    912 UINT_32 CIAddrLib::GetPrtSwitchP4Threshold() const
    913 {
    914     UINT_32 threshold;
    915 
    916     switch (m_pipes)
    917     {
    918         case 8:
    919             threshold = 32;
    920             break;
    921         case 16:
    922             if (m_settings.isFiji)
    923             {
    924                 threshold = 16;
    925             }
    926             else if (m_settings.isHawaii)
    927             {
    928                 threshold = 8;
    929             }
    930             else
    931             {
    932                 ///@todo add for possible new ASICs.
    933                 ADDR_ASSERT_ALWAYS();
    934                 threshold = 16;
    935             }
    936             break;
    937         default:
    938             ///@todo add for possible new ASICs.
    939             ADDR_ASSERT_ALWAYS();
    940             threshold = 32;
    941             break;
    942     }
    943 
    944     return threshold;
    945 }
    946 
    947 /**
    948 ***************************************************************************************************
    949 *   CIAddrLib::HwlSetupTileInfo
    950 *
    951 *   @brief
    952 *       Setup default value of tile info for SI
    953 ***************************************************************************************************
    954 */
    955 VOID CIAddrLib::HwlSetupTileInfo(
    956     AddrTileMode                        tileMode,       ///< [in] Tile mode
    957     ADDR_SURFACE_FLAGS                  flags,          ///< [in] Surface type flags
    958     UINT_32                             bpp,            ///< [in] Bits per pixel
    959     UINT_32                             pitch,          ///< [in] Pitch in pixels
    960     UINT_32                             height,         ///< [in] Height in pixels
    961     UINT_32                             numSamples,     ///< [in] Number of samples
    962     ADDR_TILEINFO*                      pTileInfoIn,    ///< [in] Tile info input: NULL for default
    963     ADDR_TILEINFO*                      pTileInfoOut,   ///< [out] Tile info output
    964     AddrTileType                        inTileType,     ///< [in] Tile type
    965     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut            ///< [out] Output
    966     ) const
    967 {
    968     UINT_32 thickness = ComputeSurfaceThickness(tileMode);
    969     ADDR_TILEINFO* pTileInfo = pTileInfoOut;
    970     INT index = TileIndexInvalid;
    971     INT macroModeIndex = TileIndexInvalid;
    972 
    973     // Fail-safe code
    974     if (!IsLinear(tileMode))
    975     {
    976         // Thick tile modes must use thick micro tile mode but Bonaire does not support due to
    977         // old derived netlists (UBTS 404321)
    978         if (thickness > 1)
    979         {
    980             if (m_settings.isBonaire)
    981             {
    982                 inTileType = ADDR_NON_DISPLAYABLE;
    983             }
    984             else if ((m_allowNonDispThickModes == FALSE) || (inTileType != ADDR_NON_DISPLAYABLE))
    985             {
    986                 inTileType = ADDR_THICK;
    987             }
    988         }
    989         // 128 bpp tiling must be non-displayable.
    990         // Fmask reuse color buffer's entry but bank-height field can be from another entry
    991         // To simplify the logic, fmask entry should be picked from non-displayable ones
    992         else if (bpp == 128 || flags.fmask)
    993         {
    994             inTileType = ADDR_NON_DISPLAYABLE;
    995         }
    996         // These two modes only have non-disp entries though they can be other micro tile modes
    997         else if (tileMode == ADDR_TM_3D_TILED_THIN1 || tileMode == ADDR_TM_PRT_3D_TILED_THIN1)
    998         {
    999             inTileType = ADDR_NON_DISPLAYABLE;
   1000         }
   1001 
   1002         if (flags.depth || flags.stencil)
   1003         {
   1004             inTileType = ADDR_DEPTH_SAMPLE_ORDER;
   1005         }
   1006     }
   1007 
   1008     if (IsTileInfoAllZero(pTileInfo))
   1009     {
   1010         // See table entries 0-4
   1011         if (flags.depth || flags.stencil)
   1012         {
   1013             if (flags.depth && flags.tcCompatible)
   1014             {
   1015                 // tileSize = bpp * numSamples * 8 * 8 / 8
   1016                 UINT_32 tileSize = bpp * numSamples * 8;
   1017 
   1018                 // Texure readable depth surface should not be split
   1019                 switch (tileSize)
   1020                 {
   1021                     case 128:
   1022                         index = 1;
   1023                         break;
   1024                     case 256:
   1025                         index = 2;
   1026                         break;
   1027                     case 512:
   1028                         index = 3;
   1029                         break;
   1030                     default:
   1031                         index = 4;
   1032                         break;
   1033                 }
   1034             }
   1035             else
   1036             {
   1037                 // Depth and stencil need to use the same index, thus the pre-defined tile_split
   1038                 // can meet the requirement to choose the same macro mode index
   1039                 // uncompressed depth/stencil are not supported for now
   1040                 switch (numSamples)
   1041                 {
   1042                     case 1:
   1043                         index = 0;
   1044                         break;
   1045                     case 2:
   1046                     case 4:
   1047                         index = 1;
   1048                         break;
   1049                     case 8:
   1050                         index = 2;
   1051                         break;
   1052                     default:
   1053                         break;
   1054                 }
   1055             }
   1056         }
   1057 
   1058         // See table entries 5-6
   1059         if (inTileType == ADDR_DEPTH_SAMPLE_ORDER)
   1060         {
   1061             switch (tileMode)
   1062             {
   1063                 case ADDR_TM_1D_TILED_THIN1:
   1064                     index = 5;
   1065                     break;
   1066                 case ADDR_TM_PRT_TILED_THIN1:
   1067                     index = 6;
   1068                     break;
   1069                 default:
   1070                     break;
   1071             }
   1072         }
   1073 
   1074         // See table entries 8-12
   1075         if (inTileType == ADDR_DISPLAYABLE)
   1076         {
   1077             switch (tileMode)
   1078             {
   1079                 case ADDR_TM_1D_TILED_THIN1:
   1080                     index = 9;
   1081                     break;
   1082                 case ADDR_TM_2D_TILED_THIN1:
   1083                     index = 10;
   1084                     break;
   1085                 case ADDR_TM_PRT_TILED_THIN1:
   1086                     index = 11;
   1087                     break;
   1088                 default:
   1089                     break;
   1090             }
   1091         }
   1092 
   1093         // See table entries 13-18
   1094         if (inTileType == ADDR_NON_DISPLAYABLE)
   1095         {
   1096             switch (tileMode)
   1097             {
   1098                 case ADDR_TM_1D_TILED_THIN1:
   1099                     index = 13;
   1100                     break;
   1101                 case ADDR_TM_2D_TILED_THIN1:
   1102                     index = 14;
   1103                     break;
   1104                 case ADDR_TM_3D_TILED_THIN1:
   1105                     index = 15;
   1106                     break;
   1107                 case ADDR_TM_PRT_TILED_THIN1:
   1108                     index = 16;
   1109                     break;
   1110                 default:
   1111                     break;
   1112             }
   1113         }
   1114 
   1115         // See table entries 19-26
   1116         if (thickness > 1)
   1117         {
   1118             switch (tileMode)
   1119             {
   1120             case ADDR_TM_1D_TILED_THICK:
   1121                     //special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
   1122                     index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 19 : 18;
   1123                     break;
   1124             case ADDR_TM_2D_TILED_THICK:
   1125                     // special check for bonaire, for the compatablity between old KMD and new UMD for bonaire
   1126                     index = ((inTileType == ADDR_THICK) || m_settings.isBonaire) ? 20 : 24;
   1127                     break;
   1128                 case ADDR_TM_3D_TILED_THICK:
   1129                     index = 21;
   1130                     break;
   1131                 case ADDR_TM_PRT_TILED_THICK:
   1132                     index = 22;
   1133                     break;
   1134                 case ADDR_TM_2D_TILED_XTHICK:
   1135                     index = 25;
   1136                     break;
   1137                 case ADDR_TM_3D_TILED_XTHICK:
   1138                     index = 26;
   1139                     break;
   1140                 default:
   1141                     break;
   1142             }
   1143         }
   1144 
   1145         // See table entries 27-30
   1146         if (inTileType == ADDR_ROTATED)
   1147         {
   1148             switch (tileMode)
   1149             {
   1150                 case ADDR_TM_1D_TILED_THIN1:
   1151                     index = 27;
   1152                     break;
   1153                 case ADDR_TM_2D_TILED_THIN1:
   1154                     index = 28;
   1155                     break;
   1156                 case ADDR_TM_PRT_TILED_THIN1:
   1157                     index = 29;
   1158                     break;
   1159                 case ADDR_TM_PRT_2D_TILED_THIN1:
   1160                     index = 30;
   1161                     break;
   1162                 default:
   1163                     break;
   1164             }
   1165         }
   1166 
   1167         if (m_pipes >= 8)
   1168         {
   1169             ADDR_ASSERT((index + 1) < static_cast<INT_32>(m_noOfEntries));
   1170             // Only do this when tile mode table is updated.
   1171             if (((tileMode == ADDR_TM_PRT_TILED_THIN1) || (tileMode == ADDR_TM_PRT_TILED_THICK)) &&
   1172                 (m_tileTable[index+1].mode == tileMode))
   1173             {
   1174                 UINT_32 bytesXSamples = bpp * numSamples / 8;
   1175                 UINT_32 bytesXThickness = bpp * thickness / 8;
   1176                 UINT_32 switchP4Threshold = GetPrtSwitchP4Threshold();
   1177 
   1178                 if ((bytesXSamples > switchP4Threshold) || (bytesXThickness > switchP4Threshold))
   1179                 {
   1180                     // Pick next 4 pipe entry
   1181                     index += 1;
   1182                 }
   1183             }
   1184         }
   1185     }
   1186     else
   1187     {
   1188         // A pre-filled tile info is ready
   1189         index = pOut->tileIndex;
   1190         macroModeIndex = pOut->macroModeIndex;
   1191 
   1192         // pass tile type back for post tile index compute
   1193         pOut->tileType = inTileType;
   1194     }
   1195 
   1196     // We only need to set up tile info if there is a valid index but macroModeIndex is invalid
   1197     if (index != TileIndexInvalid && macroModeIndex == TileIndexInvalid)
   1198     {
   1199         macroModeIndex = HwlComputeMacroModeIndex(index, flags, bpp, numSamples, pTileInfo);
   1200 
   1201         /// Copy to pOut->tileType/tileIndex/macroModeIndex
   1202         pOut->tileIndex = index;
   1203         pOut->tileType = m_tileTable[index].type; // Or inTileType, the samea
   1204         pOut->macroModeIndex = macroModeIndex;
   1205     }
   1206     else if (tileMode == ADDR_TM_LINEAR_GENERAL)
   1207     {
   1208         pOut->tileIndex = TileIndexLinearGeneral;
   1209 
   1210         // Copy linear-aligned entry??
   1211         *pTileInfo = m_tileTable[8].info;
   1212     }
   1213     else if (tileMode == ADDR_TM_LINEAR_ALIGNED)
   1214     {
   1215         pOut->tileIndex = 8;
   1216         *pTileInfo = m_tileTable[8].info;
   1217     }
   1218 }
   1219 
   1220 /**
   1221 ***************************************************************************************************
   1222 *   CIAddrLib::ReadGbTileMode
   1223 *
   1224 *   @brief
   1225 *       Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG.
   1226 *   @return
   1227 *       NA.
   1228 ***************************************************************************************************
   1229 */
   1230 VOID CIAddrLib::ReadGbTileMode(
   1231     UINT_32             regValue,   ///< [in] GB_TILE_MODE register
   1232     ADDR_TILECONFIG*    pCfg        ///< [out] output structure
   1233     ) const
   1234 {
   1235     GB_TILE_MODE gbTileMode;
   1236     gbTileMode.val = regValue;
   1237 
   1238     pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode_new);
   1239     pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1);
   1240 
   1241     if (pCfg->type == ADDR_DEPTH_SAMPLE_ORDER)
   1242     {
   1243         pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split;
   1244     }
   1245     else
   1246     {
   1247         pCfg->info.tileSplitBytes = 1 << gbTileMode.f.sample_split;
   1248     }
   1249 
   1250     UINT_32 regArrayMode = gbTileMode.f.array_mode;
   1251 
   1252     pCfg->mode = static_cast<AddrTileMode>(regArrayMode);
   1253 
   1254     switch (regArrayMode)
   1255     {
   1256         case 5:
   1257             pCfg->mode = ADDR_TM_PRT_TILED_THIN1;
   1258             break;
   1259         case 6:
   1260             pCfg->mode = ADDR_TM_PRT_2D_TILED_THIN1;
   1261             break;
   1262         case 8:
   1263             pCfg->mode = ADDR_TM_2D_TILED_XTHICK;
   1264             break;
   1265         case 9:
   1266             pCfg->mode = ADDR_TM_PRT_TILED_THICK;
   1267             break;
   1268         case 0xa:
   1269             pCfg->mode = ADDR_TM_PRT_2D_TILED_THICK;
   1270             break;
   1271         case 0xb:
   1272             pCfg->mode = ADDR_TM_PRT_3D_TILED_THIN1;
   1273             break;
   1274         case 0xe:
   1275             pCfg->mode = ADDR_TM_3D_TILED_XTHICK;
   1276             break;
   1277         case 0xf:
   1278             pCfg->mode = ADDR_TM_PRT_3D_TILED_THICK;
   1279             break;
   1280         default:
   1281             break;
   1282     }
   1283 
   1284     // Fail-safe code for these always convert tile info, as the non-macro modes
   1285     // return the entry of tile mode table directly without looking up macro mode table
   1286     if (!IsMacroTiled(pCfg->mode))
   1287     {
   1288         pCfg->info.banks = 2;
   1289         pCfg->info.bankWidth = 1;
   1290         pCfg->info.bankHeight = 1;
   1291         pCfg->info.macroAspectRatio = 1;
   1292         pCfg->info.tileSplitBytes = 64;
   1293     }
   1294 }
   1295 
   1296 /**
   1297 ***************************************************************************************************
   1298 *   CIAddrLib::InitTileSettingTable
   1299 *
   1300 *   @brief
   1301 *       Initialize the ADDR_TILE_CONFIG table.
   1302 *   @return
   1303 *       TRUE if tile table is correctly initialized
   1304 ***************************************************************************************************
   1305 */
   1306 BOOL_32 CIAddrLib::InitTileSettingTable(
   1307     const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
   1308     UINT_32         noOfEntries     ///< [in] Numbe of entries in the table above
   1309     )
   1310 {
   1311     BOOL_32 initOk = TRUE;
   1312 
   1313     ADDR_ASSERT(noOfEntries <= TileTableSize);
   1314 
   1315     memset(m_tileTable, 0, sizeof(m_tileTable));
   1316 
   1317     if (noOfEntries != 0)
   1318     {
   1319         m_noOfEntries = noOfEntries;
   1320     }
   1321     else
   1322     {
   1323         m_noOfEntries = TileTableSize;
   1324     }
   1325 
   1326     if (pCfg) // From Client
   1327     {
   1328         for (UINT_32 i = 0; i < m_noOfEntries; i++)
   1329         {
   1330             ReadGbTileMode(*(pCfg + i), &m_tileTable[i]);
   1331         }
   1332     }
   1333     else
   1334     {
   1335         ADDR_ASSERT_ALWAYS();
   1336         initOk = FALSE;
   1337     }
   1338 
   1339     if (initOk)
   1340     {
   1341         ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED);
   1342 
   1343         if (m_settings.isBonaire == FALSE)
   1344         {
   1345             // Check if entry 18 is "thick+thin" combination
   1346             if ((m_tileTable[18].mode == ADDR_TM_1D_TILED_THICK) &&
   1347                 (m_tileTable[18].type == ADDR_NON_DISPLAYABLE))
   1348             {
   1349                 m_allowNonDispThickModes = TRUE;
   1350                 ADDR_ASSERT(m_tileTable[24].mode == ADDR_TM_2D_TILED_THICK);
   1351             }
   1352         }
   1353         else
   1354         {
   1355             m_allowNonDispThickModes = TRUE;
   1356         }
   1357 
   1358         // Assume the first entry is always programmed with full pipes
   1359         m_pipes = HwlGetPipes(&m_tileTable[0].info);
   1360     }
   1361 
   1362     return initOk;
   1363 }
   1364 
   1365 /**
   1366 ***************************************************************************************************
   1367 *   CIAddrLib::ReadGbMacroTileCfg
   1368 *
   1369 *   @brief
   1370 *       Convert GB_MACRO_TILE_CFG HW value to ADDR_TILE_CONFIG.
   1371 *   @return
   1372 *       NA.
   1373 ***************************************************************************************************
   1374 */
   1375 VOID CIAddrLib::ReadGbMacroTileCfg(
   1376     UINT_32             regValue,   ///< [in] GB_MACRO_TILE_MODE register
   1377     ADDR_TILEINFO*      pCfg        ///< [out] output structure
   1378     ) const
   1379 {
   1380     GB_MACROTILE_MODE gbTileMode;
   1381     gbTileMode.val = regValue;
   1382 
   1383     pCfg->bankHeight = 1 << gbTileMode.f.bank_height;
   1384     pCfg->bankWidth = 1 << gbTileMode.f.bank_width;
   1385     pCfg->banks = 1 << (gbTileMode.f.num_banks + 1);
   1386     pCfg->macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect;
   1387 }
   1388 
   1389 /**
   1390 ***************************************************************************************************
   1391 *   CIAddrLib::InitMacroTileCfgTable
   1392 *
   1393 *   @brief
   1394 *       Initialize the ADDR_MACRO_TILE_CONFIG table.
   1395 *   @return
   1396 *       TRUE if macro tile table is correctly initialized
   1397 ***************************************************************************************************
   1398 */
   1399 BOOL_32 CIAddrLib::InitMacroTileCfgTable(
   1400     const UINT_32*  pCfg,           ///< [in] Pointer to table of tile configs
   1401     UINT_32         noOfMacroEntries     ///< [in] Numbe of entries in the table above
   1402     )
   1403 {
   1404     BOOL_32 initOk = TRUE;
   1405 
   1406     ADDR_ASSERT(noOfMacroEntries <= MacroTileTableSize);
   1407 
   1408     memset(m_macroTileTable, 0, sizeof(m_macroTileTable));
   1409 
   1410     if (noOfMacroEntries != 0)
   1411     {
   1412         m_noOfMacroEntries = noOfMacroEntries;
   1413     }
   1414     else
   1415     {
   1416         m_noOfMacroEntries = MacroTileTableSize;
   1417     }
   1418 
   1419     if (pCfg) // From Client
   1420     {
   1421         for (UINT_32 i = 0; i < m_noOfMacroEntries; i++)
   1422         {
   1423             ReadGbMacroTileCfg(*(pCfg + i), &m_macroTileTable[i]);
   1424 
   1425             m_macroTileTable[i].tileSplitBytes = 64 << (i % 8);
   1426         }
   1427     }
   1428     else
   1429     {
   1430         ADDR_ASSERT_ALWAYS();
   1431         initOk = FALSE;
   1432     }
   1433     return initOk;
   1434 }
   1435 
   1436 /**
   1437 ***************************************************************************************************
   1438 *   CIAddrLib::HwlComputeMacroModeIndex
   1439 *
   1440 *   @brief
   1441 *       Computes macro tile mode index
   1442 *   @return
   1443 *       TRUE if macro tile table is correctly initialized
   1444 ***************************************************************************************************
   1445 */
   1446 INT_32 CIAddrLib::HwlComputeMacroModeIndex(
   1447     INT_32              tileIndex,      ///< [in] Tile mode index
   1448     ADDR_SURFACE_FLAGS  flags,          ///< [in] Surface flags
   1449     UINT_32             bpp,            ///< [in] Bit per pixel
   1450     UINT_32             numSamples,     ///< [in] Number of samples
   1451     ADDR_TILEINFO*      pTileInfo,      ///< [out] Pointer to ADDR_TILEINFO
   1452     AddrTileMode*       pTileMode,      ///< [out] Pointer to AddrTileMode
   1453     AddrTileType*       pTileType       ///< [out] Pointer to AddrTileType
   1454     ) const
   1455 {
   1456     INT_32 macroModeIndex = TileIndexInvalid;
   1457 
   1458     if (flags.tcCompatible && flags.stencil)
   1459     {
   1460         // Don't compute macroModeIndex for tc compatible stencil surface
   1461         macroModeIndex = TileIndexNoMacroIndex;
   1462     }
   1463     else
   1464     {
   1465         AddrTileMode tileMode = m_tileTable[tileIndex].mode;
   1466         AddrTileType tileType = m_tileTable[tileIndex].type;
   1467         UINT_32 thickness = ComputeSurfaceThickness(tileMode);
   1468 
   1469         if (!IsMacroTiled(tileMode))
   1470         {
   1471             *pTileInfo = m_tileTable[tileIndex].info;
   1472             macroModeIndex = TileIndexNoMacroIndex;
   1473         }
   1474         else
   1475         {
   1476             UINT_32 tileBytes1x = BITS_TO_BYTES(bpp * MicroTilePixels * thickness);
   1477             UINT_32 tileSplit;
   1478 
   1479             if (m_tileTable[tileIndex].type == ADDR_DEPTH_SAMPLE_ORDER)
   1480             {
   1481                 // Depth entries store real tileSplitBytes
   1482                 tileSplit = m_tileTable[tileIndex].info.tileSplitBytes;
   1483             }
   1484             else
   1485             {
   1486                 // Non-depth entries store a split factor
   1487                 UINT_32 sampleSplit = m_tileTable[tileIndex].info.tileSplitBytes;
   1488                 UINT_32 colorTileSplit = Max(256u, sampleSplit * tileBytes1x);
   1489 
   1490                 tileSplit = colorTileSplit;
   1491             }
   1492 
   1493             UINT_32 tileSplitC = Min(m_rowSize, tileSplit);
   1494             UINT_32 tileBytes;
   1495 
   1496             if (flags.fmask)
   1497             {
   1498                 tileBytes = Min(tileSplitC, tileBytes1x);
   1499             }
   1500             else
   1501             {
   1502                 tileBytes = Min(tileSplitC, numSamples * tileBytes1x);
   1503             }
   1504 
   1505             if (tileBytes < 64)
   1506             {
   1507                 tileBytes = 64;
   1508             }
   1509 
   1510             macroModeIndex = Log2(tileBytes / 64);
   1511 
   1512             if (flags.prt || IsPrtTileMode(tileMode))
   1513             {
   1514                 // Unknown - assume it is 1/2 of table size
   1515                 const UINT_32 PrtMacroModeOffset = MacroTileTableSize / 2;
   1516 
   1517                 macroModeIndex += PrtMacroModeOffset;
   1518                 *pTileInfo = m_macroTileTable[macroModeIndex];
   1519             }
   1520             else
   1521             {
   1522                 *pTileInfo = m_macroTileTable[macroModeIndex];
   1523             }
   1524 
   1525             pTileInfo->pipeConfig = m_tileTable[tileIndex].info.pipeConfig;
   1526 
   1527             if (m_tileTable[tileIndex].type != ADDR_DEPTH_SAMPLE_ORDER)
   1528             {
   1529                 pTileInfo->tileSplitBytes = tileSplitC;
   1530             }
   1531             else
   1532             {
   1533                 pTileInfo->tileSplitBytes = m_tileTable[tileIndex].info.tileSplitBytes;
   1534             }
   1535         }
   1536 
   1537         if (NULL != pTileMode)
   1538         {
   1539             *pTileMode = tileMode;
   1540         }
   1541 
   1542         if (NULL != pTileType)
   1543         {
   1544             *pTileType = tileType;
   1545         }
   1546     }
   1547 
   1548     return macroModeIndex;
   1549 }
   1550 
   1551 /**
   1552 ***************************************************************************************************
   1553 *   CIAddrLib::HwlComputeTileDataWidthAndHeightLinear
   1554 *
   1555 *   @brief
   1556 *       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
   1557 *
   1558 *   @return
   1559 *       N/A
   1560 *
   1561 *   @note
   1562 *       MacroWidth and macroHeight are measured in pixels
   1563 ***************************************************************************************************
   1564 */
   1565 VOID CIAddrLib::HwlComputeTileDataWidthAndHeightLinear(
   1566     UINT_32*        pMacroWidth,     ///< [out] macro tile width
   1567     UINT_32*        pMacroHeight,    ///< [out] macro tile height
   1568     UINT_32         bpp,             ///< [in] bits per pixel
   1569     ADDR_TILEINFO*  pTileInfo        ///< [in] tile info
   1570     ) const
   1571 {
   1572     ADDR_ASSERT(pTileInfo != NULL);
   1573 
   1574     UINT_32 numTiles;
   1575 
   1576     switch (pTileInfo->pipeConfig)
   1577     {
   1578         case ADDR_PIPECFG_P16_32x32_8x16:
   1579         case ADDR_PIPECFG_P16_32x32_16x16:
   1580         case ADDR_PIPECFG_P8_32x64_32x32:
   1581         case ADDR_PIPECFG_P8_32x32_16x32:
   1582         case ADDR_PIPECFG_P8_32x32_16x16:
   1583         case ADDR_PIPECFG_P8_32x32_8x16:
   1584         case ADDR_PIPECFG_P4_32x32:
   1585             numTiles = 8;
   1586             break;
   1587         default:
   1588             numTiles = 4;
   1589             break;
   1590     }
   1591 
   1592     *pMacroWidth    = numTiles * MicroTileWidth;
   1593     *pMacroHeight   = numTiles * MicroTileHeight;
   1594 }
   1595 
   1596 /**
   1597 ***************************************************************************************************
   1598 *   CIAddrLib::HwlStereoCheckRightOffsetPadding
   1599 *
   1600 *   @brief
   1601 *       check if the height needs extra padding for stereo right eye offset, to avoid swizzling
   1602 *
   1603 *   @return
   1604 *       TRUE is the extra padding is needed
   1605 *
   1606 *   @note
   1607 *       Kalindi (Kabini) is the only one that needs this padding as there is a uncertain
   1608 *       possible HW issue where the right eye displays incorrectly with some type of swizzles, if
   1609 *       the right eye offset is not 64KB aligned - EPR#366461
   1610 *       Other Kaveri APUs also need the padding according to DXX team's report otherwise
   1611 *       corruption observed. - EPR#374788
   1612 ***************************************************************************************************
   1613 */
   1614 BOOL_32 CIAddrLib::HwlStereoCheckRightOffsetPadding() const
   1615 {
   1616     BOOL_32 bNeedPadding = FALSE;
   1617 
   1618     if (m_settings.isKaveri)
   1619     {
   1620         bNeedPadding = TRUE;
   1621     }
   1622 
   1623     return bNeedPadding;
   1624 }
   1625 
   1626 /**
   1627 ***************************************************************************************************
   1628 *   CIAddrLib::HwlComputeMetadataNibbleAddress
   1629 *
   1630 *   @brief
   1631 *        calculate meta data address based on input information
   1632 *
   1633 *   &parameter
   1634 *        uncompressedDataByteAddress - address of a pixel in color surface
   1635 *        dataBaseByteAddress         - base address of color surface
   1636 *        metadataBaseByteAddress     - base address of meta ram
   1637 *        metadataBitSize             - meta key size, 8 for DCC, 4 for cmask
   1638 *        elementBitSize              - element size of color surface
   1639 *        blockByteSize               - compression block size, 256 for DCC
   1640 *        pipeInterleaveBytes         - pipe interleave size
   1641 *        numOfPipes                  - number of pipes
   1642 *        numOfBanks                  - number of banks
   1643 *        numOfSamplesPerSplit        - number of samples per tile split
   1644 *   @return
   1645 *        meta data nibble address (nibble address is used to support DCC compatible cmask)
   1646 *
   1647 ***************************************************************************************************
   1648 */
   1649 UINT_64 CIAddrLib::HwlComputeMetadataNibbleAddress(
   1650     UINT_64 uncompressedDataByteAddress,
   1651     UINT_64 dataBaseByteAddress,
   1652     UINT_64 metadataBaseByteAddress,
   1653     UINT_32 metadataBitSize,
   1654     UINT_32 elementBitSize,
   1655     UINT_32 blockByteSize,
   1656     UINT_32 pipeInterleaveBytes,
   1657     UINT_32 numOfPipes,
   1658     UINT_32 numOfBanks,
   1659     UINT_32 numOfSamplesPerSplit) const
   1660 {
   1661     ///--------------------------------------------------------------------------------------------
   1662     /// Get pipe interleave, bank and pipe bits
   1663     ///--------------------------------------------------------------------------------------------
   1664     UINT_32 pipeInterleaveBits  = Log2(pipeInterleaveBytes);
   1665     UINT_32 pipeBits            = Log2(numOfPipes);
   1666     UINT_32 bankBits            = Log2(numOfBanks);
   1667 
   1668     ///--------------------------------------------------------------------------------------------
   1669     /// Clear pipe and bank swizzles
   1670     ///--------------------------------------------------------------------------------------------
   1671     UINT_32 dataMacrotileBits        = pipeInterleaveBits + pipeBits + bankBits;
   1672     UINT_32 metadataMacrotileBits    = pipeInterleaveBits + pipeBits + bankBits;
   1673 
   1674     UINT_64 dataMacrotileClearMask     = ~((1L << dataMacrotileBits) - 1);
   1675     UINT_64 metadataMacrotileClearMask = ~((1L << metadataMacrotileBits) - 1);
   1676 
   1677     UINT_64 dataBaseByteAddressNoSwizzle = dataBaseByteAddress & dataMacrotileClearMask;
   1678     UINT_64 metadataBaseByteAddressNoSwizzle = metadataBaseByteAddress & metadataMacrotileClearMask;
   1679 
   1680     ///--------------------------------------------------------------------------------------------
   1681     /// Modify metadata base before adding in so that when final address is divided by data ratio,
   1682     /// the base address returns to where it should be
   1683     ///--------------------------------------------------------------------------------------------
   1684     ADDR_ASSERT((0 != metadataBitSize));
   1685     UINT_64 metadataBaseShifted = metadataBaseByteAddressNoSwizzle * blockByteSize * 8 /
   1686                                   metadataBitSize;
   1687     UINT_64 offset = uncompressedDataByteAddress -
   1688                      dataBaseByteAddressNoSwizzle +
   1689                      metadataBaseShifted;
   1690 
   1691     ///--------------------------------------------------------------------------------------------
   1692     /// Save bank data bits
   1693     ///--------------------------------------------------------------------------------------------
   1694     UINT_32 lsb = pipeBits + pipeInterleaveBits;
   1695     UINT_32 msb = bankBits - 1 + lsb;
   1696 
   1697     UINT_64 bankDataBits = AddrGetBits(offset, msb, lsb);
   1698 
   1699     ///--------------------------------------------------------------------------------------------
   1700     /// Save pipe data bits
   1701     ///--------------------------------------------------------------------------------------------
   1702     lsb = pipeInterleaveBits;
   1703     msb = pipeBits - 1 + lsb;
   1704 
   1705     UINT_64 pipeDataBits = AddrGetBits(offset, msb, lsb);
   1706 
   1707     ///--------------------------------------------------------------------------------------------
   1708     /// Remove pipe and bank bits
   1709     ///--------------------------------------------------------------------------------------------
   1710     lsb = pipeInterleaveBits;
   1711     msb = dataMacrotileBits - 1;
   1712 
   1713     UINT_64 offsetWithoutPipeBankBits = AddrRemoveBits(offset, msb, lsb);
   1714 
   1715     ADDR_ASSERT((0 != blockByteSize));
   1716     UINT_64 blockInBankpipe = offsetWithoutPipeBankBits / blockByteSize;
   1717 
   1718     UINT_32 tileSize = 8 * 8 * elementBitSize/8 * numOfSamplesPerSplit;
   1719     UINT_32 blocksInTile = tileSize / blockByteSize;
   1720 
   1721     if (0 == blocksInTile)
   1722     {
   1723         lsb = 0;
   1724     }
   1725     else
   1726     {
   1727         lsb = Log2(blocksInTile);
   1728     }
   1729     msb = bankBits - 1 + lsb;
   1730 
   1731     UINT_64 blockInBankpipeWithBankBits = AddrInsertBits(blockInBankpipe, bankDataBits, msb, lsb);
   1732 
   1733     /// NOTE *2 because we are converting to Nibble address in this step
   1734     UINT_64 metaAddressInPipe = blockInBankpipeWithBankBits * 2 * metadataBitSize / 8;
   1735 
   1736 
   1737     ///--------------------------------------------------------------------------------------------
   1738     /// Reinsert pipe bits back into the final address
   1739     ///--------------------------------------------------------------------------------------------
   1740     lsb = pipeInterleaveBits + 1; ///<+1 due to Nibble address now gives interleave bits extra lsb.
   1741     msb = pipeBits - 1 + lsb;
   1742     UINT_64 metadataAddress = AddrInsertBits(metaAddressInPipe, pipeDataBits, msb, lsb);
   1743 
   1744     return metadataAddress;
   1745 }
   1746 
   1747 /**
   1748 ***************************************************************************************************
   1749 *   CIAddrLib::HwlPadDimensions
   1750 *
   1751 *   @brief
   1752 *       Helper function to pad dimensions
   1753 *
   1754 *   @return
   1755 *       N/A
   1756 *
   1757 ***************************************************************************************************
   1758 */
   1759 VOID CIAddrLib::HwlPadDimensions(
   1760     AddrTileMode        tileMode,    ///< [in] tile mode
   1761     UINT_32             bpp,         ///< [in] bits per pixel
   1762     ADDR_SURFACE_FLAGS  flags,       ///< [in] surface flags
   1763     UINT_32             numSamples,  ///< [in] number of samples
   1764     ADDR_TILEINFO*      pTileInfo,   ///< [in/out] bank structure.
   1765     UINT_32             padDims,     ///< [in] Dimensions to pad valid value 1,2,3
   1766     UINT_32             mipLevel,    ///< [in] MipLevel
   1767     UINT_32*            pPitch,      ///< [in/out] pitch in pixels
   1768     UINT_32             pitchAlign,  ///< [in] pitch alignment
   1769     UINT_32*            pHeight,     ///< [in/out] height in pixels
   1770     UINT_32             heightAlign, ///< [in] height alignment
   1771     UINT_32*            pSlices,     ///< [in/out] number of slices
   1772     UINT_32             sliceAlign   ///< [in] number of slice alignment
   1773     ) const
   1774 {
   1775     if (m_settings.isVolcanicIslands &&
   1776         flags.dccCompatible &&
   1777         (numSamples > 1) &&
   1778         (mipLevel == 0) &&
   1779         IsMacroTiled(tileMode))
   1780     {
   1781         UINT_32 tileSizePerSample = BITS_TO_BYTES(bpp * MicroTileWidth * MicroTileHeight);
   1782         UINT_32 samplesPerSplit  = pTileInfo->tileSplitBytes / tileSizePerSample;
   1783 
   1784         if (samplesPerSplit < numSamples)
   1785         {
   1786             UINT_32 dccFastClearByteAlign = HwlGetPipes(pTileInfo) * m_pipeInterleaveBytes * 256;
   1787             UINT_32 bytesPerSplit = BITS_TO_BYTES((*pPitch) * (*pHeight) * bpp * samplesPerSplit);
   1788 
   1789             ADDR_ASSERT(IsPow2(dccFastClearByteAlign));
   1790 
   1791             if (0 != (bytesPerSplit & (dccFastClearByteAlign - 1)))
   1792             {
   1793                 UINT_32 dccFastClearPixelAlign = dccFastClearByteAlign /
   1794                                                 BITS_TO_BYTES(bpp) /
   1795                                                 samplesPerSplit;
   1796                 UINT_32 macroTilePixelAlign = pitchAlign * heightAlign;
   1797 
   1798                 if ((dccFastClearPixelAlign >= macroTilePixelAlign) &&
   1799                     ((dccFastClearPixelAlign % macroTilePixelAlign) == 0))
   1800                 {
   1801                     UINT_32 dccFastClearPitchAlignInMacroTile =
   1802                         dccFastClearPixelAlign / macroTilePixelAlign;
   1803                     UINT_32 heightInMacroTile = *pHeight / heightAlign;
   1804                     UINT_32 dccFastClearPitchAlignInPixels;
   1805 
   1806                     while ((heightInMacroTile > 1) &&
   1807                            ((heightInMacroTile % 2) == 0) &&
   1808                            (dccFastClearPitchAlignInMacroTile > 1) &&
   1809                            ((dccFastClearPitchAlignInMacroTile % 2) == 0))
   1810                     {
   1811                         heightInMacroTile >>= 1;
   1812                         dccFastClearPitchAlignInMacroTile >>= 1;
   1813                     }
   1814 
   1815                     dccFastClearPitchAlignInPixels = pitchAlign * dccFastClearPitchAlignInMacroTile;
   1816 
   1817                     if (IsPow2(dccFastClearPitchAlignInPixels))
   1818                     {
   1819                         *pPitch = PowTwoAlign((*pPitch), dccFastClearPitchAlignInPixels);
   1820                     }
   1821                     else
   1822                     {
   1823                         *pPitch += (dccFastClearPitchAlignInPixels - 1);
   1824                         *pPitch /= dccFastClearPitchAlignInPixels;
   1825                         *pPitch *= dccFastClearPitchAlignInPixels;
   1826                     }
   1827                 }
   1828             }
   1829         }
   1830     }
   1831 }
   1832 
   1833