efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 1 | |
| 2 | /** |
| 3 | * @file |
| 4 | * |
| 5 | * Config Southbridge SATA controller |
| 6 | * |
| 7 | * Init SATA features. |
| 8 | * |
| 9 | * @xrefitem bom "File Content Label" "Release Content" |
| 10 | * @e project: CIMx-SB |
| 11 | * @e sub-project: |
| 12 | * @e \$Revision:$ @e \$Date:$ |
| 13 | * |
| 14 | */ |
| 15 | /* |
| 16 | ***************************************************************************** |
| 17 | * |
| 18 | * Copyright (c) 2011, Advanced Micro Devices, Inc. |
| 19 | * All rights reserved. |
Edward O'Callaghan | ef5981b | 2014-07-06 19:20:52 +1000 | [diff] [blame] | 20 | * |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 21 | * Redistribution and use in source and binary forms, with or without |
| 22 | * modification, are permitted provided that the following conditions are met: |
| 23 | * * Redistributions of source code must retain the above copyright |
| 24 | * notice, this list of conditions and the following disclaimer. |
| 25 | * * Redistributions in binary form must reproduce the above copyright |
| 26 | * notice, this list of conditions and the following disclaimer in the |
| 27 | * documentation and/or other materials provided with the distribution. |
Edward O'Callaghan | ef5981b | 2014-07-06 19:20:52 +1000 | [diff] [blame] | 28 | * * Neither the name of Advanced Micro Devices, Inc. nor the names of |
| 29 | * its contributors may be used to endorse or promote products derived |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 30 | * from this software without specific prior written permission. |
Edward O'Callaghan | ef5981b | 2014-07-06 19:20:52 +1000 | [diff] [blame] | 31 | * |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 33 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 34 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 35 | * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY |
| 36 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 37 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 38 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 39 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 40 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 41 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Edward O'Callaghan | ef5981b | 2014-07-06 19:20:52 +1000 | [diff] [blame] | 42 | * |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 43 | **************************************************************************** |
| 44 | */ |
| 45 | #include "SbPlatform.h" |
| 46 | #include "cbtypes.h" |
| 47 | #include "AmdSbLib.h" |
| 48 | |
| 49 | // |
| 50 | // Declaration of local functions |
| 51 | // |
| 52 | VOID sataSetIrqIntResource (IN AMDSBCFG* pConfig); |
| 53 | VOID sataBar5setting (IN AMDSBCFG* pConfig, IN UINT32 *pBar5); |
| 54 | #ifdef SATA_BUS_DEV_FUN_FPGA |
| 55 | VOID sataBar5settingFpga (IN AMDSBCFG* pConfig, IN UINT32 *pBar5); |
| 56 | #endif |
| 57 | VOID shutdownUnconnectedSataPortClock (IN AMDSBCFG* pConfig, IN UINT32 ddBar5); |
| 58 | VOID CaculateAhciPortNumber (IN AMDSBCFG* pConfig, IN UINT32 ddBar5); |
| 59 | VOID sataDriveDetection (IN AMDSBCFG* pConfig, IN UINT32 *pBar5); |
| 60 | #ifdef SATA_BUS_DEV_FUN_FPGA |
| 61 | VOID sataDriveDetectionFpga (IN AMDSBCFG* pConfig, IN UINT32 *pBar5); |
| 62 | #endif |
| 63 | VOID sataGpioPorcedure (IN AMDSBCFG* pConfig); |
| 64 | |
| 65 | /** |
| 66 | * sataSetIrqIntResource - Config SATA IRQ/INT# resource |
| 67 | * |
| 68 | * |
| 69 | * - Private function |
| 70 | * |
| 71 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 72 | * |
| 73 | */ |
| 74 | VOID |
| 75 | sataSetIrqIntResource ( |
| 76 | IN AMDSBCFG* pConfig |
| 77 | ) |
| 78 | { |
| 79 | UINT8 dbValue; |
| 80 | // IRQ14/IRQ15 come from IDE or SATA |
| 81 | dbValue = 0x08; |
| 82 | WriteIO (SB_IOMAP_REGC00, AccWidthUint8, &dbValue); |
| 83 | ReadIO (SB_IOMAP_REGC01, AccWidthUint8, &dbValue); |
| 84 | dbValue = dbValue & 0x0F; |
| 85 | if (pConfig->SataClass == 3) { |
| 86 | dbValue = dbValue | 0x50; |
| 87 | } else { |
| 88 | if (pConfig->SataIdeMode == 1) { |
| 89 | // Both IDE & SATA set to Native mode |
| 90 | dbValue = dbValue | 0xF0; |
| 91 | } |
| 92 | } |
| 93 | WriteIO (SB_IOMAP_REGC01, AccWidthUint8, &dbValue); |
| 94 | } |
| 95 | |
| 96 | /** |
| 97 | * sataBar5setting - Config SATA BAR5 |
| 98 | * |
| 99 | * - Private function |
| 100 | * |
| 101 | * @param[in] pConfig - Southbridge configuration structure pointer. |
| 102 | * @param[in] *pBar5 - SATA BAR5 buffer. |
| 103 | * |
| 104 | */ |
| 105 | VOID |
| 106 | sataBar5setting ( |
| 107 | IN AMDSBCFG* pConfig, |
| 108 | IN UINT32 *pBar5 |
| 109 | ) |
| 110 | { |
| 111 | //Get BAR5 value |
| 112 | ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, pBar5); |
| 113 | //Assign temporary BAR if is not already assigned |
| 114 | if ( (*pBar5 == 0) || (*pBar5 == - 1) ) { |
| 115 | //assign temporary BAR5 |
| 116 | if ( (pConfig->TempMMIO == 0) || (pConfig->TempMMIO == - 1) ) { |
| 117 | *pBar5 = 0xFEC01000; |
| 118 | } else { |
| 119 | *pBar5 = pConfig->TempMMIO; |
| 120 | } |
| 121 | WritePCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, pBar5); |
| 122 | } |
| 123 | //Clear Bits 9:0 |
| 124 | *pBar5 = *pBar5 & 0xFFFFFC00; |
| 125 | } |
| 126 | #ifdef SATA_BUS_DEV_FUN_FPGA |
| 127 | VOID |
| 128 | sataBar5settingFpga ( |
| 129 | IN AMDSBCFG* pConfig, |
| 130 | IN UINT32 *pBar5 |
| 131 | ) |
| 132 | { |
| 133 | UINT8 dbValue; |
| 134 | //Get BAR5 value |
| 135 | ReadPCI (((SATA_BUS_DEV_FUN_FPGA << 16) + SB_SATA_REG24), AccWidthUint32, pBar5); |
| 136 | //Assign temporary BAR if is not already assigned |
| 137 | if ( (*pBar5 == 0) || (*pBar5 == - 1) ) { |
| 138 | //assign temporary BAR5 |
| 139 | if ( (pConfig->TempMMIO == 0) || (pConfig->TempMMIO == - 1) ) { |
| 140 | *pBar5 = 0xFEC01000; |
| 141 | } else { |
| 142 | *pBar5 = pConfig->TempMMIO; |
| 143 | } |
| 144 | WritePCI (((SATA_BUS_DEV_FUN_FPGA << 16) + SB_SATA_REG24), AccWidthUint32, pBar5); |
| 145 | } |
| 146 | //Clear Bits 9:0 |
| 147 | *pBar5 = *pBar5 & 0xFFFFFC00; |
| 148 | dbValue = 0x07; |
| 149 | WritePCI (((SATA_BUS_DEV_FUN_FPGA << 16) + 0x04), AccWidthUint8, &dbValue); |
| 150 | WritePCI (((PCIB_BUS_DEV_FUN << 16) + 0x04), AccWidthUint8, &dbValue); |
| 151 | } |
| 152 | #endif |
| 153 | /** |
| 154 | * shutdownUnconnectedSataPortClock - Shutdown unconnected Sata port clock |
| 155 | * |
| 156 | * - Private function |
| 157 | * |
| 158 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 159 | * @param[in] ddBar5 Sata BAR5 base address. |
| 160 | * |
| 161 | */ |
| 162 | VOID |
| 163 | shutdownUnconnectedSataPortClock ( |
| 164 | IN AMDSBCFG* pConfig, |
| 165 | IN UINT32 ddBar5 |
| 166 | ) |
| 167 | { |
| 168 | UINT8 dbPortNum; |
| 169 | UINT32 ddPortSataStatus; |
| 170 | UINT8 cimSataClkAutoOff; |
| 171 | |
| 172 | cimSataClkAutoOff = (UINT8) pConfig->SataClkAutoOff; |
| 173 | #if SB_CIMx_PARAMETER == 0 |
| 174 | cimSataClkAutoOff = cimSataClkAutoOffDefault; |
| 175 | #endif |
| 176 | if ( cimSataClkAutoOff == TRUE ) { |
| 177 | //ENH225976 Enable SATA auto clock control by default ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE) ) { |
| 178 | for ( dbPortNum = 0; dbPortNum < 8; dbPortNum++ ) { |
| 179 | ReadMEM (ddBar5 + SB_SATA_BAR5_REG128 + (dbPortNum * 0x80), AccWidthUint32, &ddPortSataStatus); |
| 180 | // Shutdown the clock for the port and do the necessary port reporting changes. |
| 181 | // ?? Error port status should be 1 not 3 |
| 182 | ddPortSataStatus &= 0x00000F0F; |
| 183 | if ( (!((ddPortSataStatus == 0x601) || (ddPortSataStatus == 0x201) || (ddPortSataStatus == 0x103))) && (! ((pConfig->SATAESPPORT.SataPortReg) & (1 << dbPortNum))) ) { |
| 184 | TRACE ((DMSG_SB_TRACE, "Shutting down clock for SATA port %X \n", dbPortNum)); |
| 185 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8, 0xFF, (1 << dbPortNum)); |
| 186 | } |
| 187 | } //end of for (dbPortNum=0;dbPortNum<6;dbPortNum++) |
| 188 | } //end of SataClkAuto Off option |
| 189 | } |
| 190 | |
| 191 | /** |
| 192 | * CaculateAhciPortNumber - Caculat AHCI Port Number |
| 193 | * |
| 194 | * - Private function |
| 195 | * |
| 196 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 197 | * @param[in] ddBar5 Sata BAR5 base address. |
| 198 | * |
| 199 | */ |
| 200 | VOID |
| 201 | CaculateAhciPortNumber ( |
| 202 | IN AMDSBCFG* pConfig, |
| 203 | IN UINT32 ddBar5 |
| 204 | ) |
| 205 | { |
| 206 | UINT8 dbPortNum; |
| 207 | UINT8 dbPortSataStatus; |
| 208 | UINT8 NumOfPorts; |
| 209 | UINT8 MaxPortNum; |
| 210 | NumOfPorts = 0; |
| 211 | MaxPortNum = 4; |
| 212 | if ( (pConfig->SATAMODE.SataMode.SataIdeCombMdPriSecOpt) == ENABLED ) { |
| 213 | MaxPortNum = 6; |
| 214 | } else if ( (pConfig->SATAMODE.SataMode.SataIdeCombinedMode) == ENABLED ) { |
| 215 | MaxPortNum = 8; |
| 216 | } |
| 217 | ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8, &dbPortSataStatus); |
| 218 | for ( dbPortNum = 0; dbPortNum < MaxPortNum; dbPortNum++ ) { |
| 219 | if ( dbPortSataStatus & (1 << dbPortNum) ) { |
| 220 | RWMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, ~(1 << dbPortNum), 00); |
| 221 | } |
| 222 | } |
| 223 | ReadMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, &dbPortSataStatus); |
| 224 | //if all ports are in disabled state, report atleast one port |
| 225 | if ( (dbPortSataStatus & 0xFF) == 0) { |
| 226 | RWMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, (UINT32) ~(0xFF), 01); |
| 227 | } |
| 228 | ReadMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, &dbPortSataStatus); |
| 229 | for (dbPortNum = 0; dbPortNum < MaxPortNum; dbPortNum ++) { |
| 230 | if (dbPortSataStatus & (1 << dbPortNum)) { |
| 231 | NumOfPorts++; |
| 232 | } |
| 233 | } |
| 234 | if ( NumOfPorts == 0) { |
| 235 | NumOfPorts = 0x01; |
| 236 | } |
| 237 | RWMEM (ddBar5 + SB_SATA_BAR5_REG00, AccWidthUint8, 0xE0, NumOfPorts - 1); |
| 238 | } |
| 239 | |
| 240 | /** |
| 241 | * sataGpioPorcedure - Sata GPIO function Procedure |
| 242 | * |
| 243 | * - Private function |
| 244 | * |
| 245 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 246 | * |
| 247 | */ |
| 248 | VOID |
| 249 | sataGpioPorcedure ( |
| 250 | IN AMDSBCFG* pConfig |
| 251 | ) |
| 252 | { |
| 253 | UINT32 ddBar5; |
| 254 | UINT32 ddData; |
| 255 | UINT32 eMb; |
| 256 | UINT32 ddTempVariable; |
| 257 | UINT8 cimSataSgpio0; |
| 258 | |
| 259 | ddBar5 = 0; |
| 260 | eMb = 0; |
| 261 | cimSataSgpio0 = (UINT8) pConfig->SataSgpio0; |
| 262 | |
| 263 | #if SB_CIMx_PARAMETER == 0 |
| 264 | cimSataSgpio0 = cimSataSgpio0Default; |
| 265 | #endif |
| 266 | |
| 267 | sataBar5setting (pConfig, &ddBar5); |
| 268 | ReadMEM (ddBar5 + SB_SATA_BAR5_REG1C , AccWidthUint32 | S3_SAVE, &ddData); |
| 269 | eMb = (ddBar5 + (( ddData & 0xFFFF0000) >> 14)); |
| 270 | if ( eMb ) { |
| 271 | ddTempVariable = 0x03040C00; |
| 272 | WriteMEM ( ddBar5 + eMb, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 273 | ddTempVariable = 0x00C08240; |
| 274 | WriteMEM ( ddBar5 + eMb + 4, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 275 | ddTempVariable = 0x00000001; |
| 276 | WriteMEM ( ddBar5 + eMb + 8, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 277 | if ( cimSataSgpio0 ) { |
| 278 | ddTempVariable = 0x00000060; |
| 279 | } else { |
| 280 | ddTempVariable = 0x00000061; |
| 281 | } |
| 282 | WriteMEM ( ddBar5 + eMb + 0x0C, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 283 | |
| 284 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG20), AccWidthUint16 | S3_SAVE, ~(BIT8), BIT8); |
| 285 | do { |
| 286 | ReadMEM (ddBar5 + SB_SATA_BAR5_REG20 , AccWidthUint32 | S3_SAVE, &ddData); |
| 287 | ddData = ddData & BIT8; |
| 288 | } while ( ddData != 0 ); |
| 289 | |
| 290 | ddTempVariable = 0x03040F00; |
| 291 | WriteMEM ( ddBar5 + eMb, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 292 | ddTempVariable = 0x00008240; |
| 293 | WriteMEM ( ddBar5 + eMb + 4, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 294 | ddTempVariable = 0x00000002; |
| 295 | WriteMEM ( ddBar5 + eMb + 8, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 296 | ddTempVariable = 0x00800000; |
| 297 | WriteMEM ( ddBar5 + eMb + 0x0C, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 298 | ddTempVariable = 0x0F003700; |
| 299 | WriteMEM ( ddBar5 + eMb + 0x0C, AccWidthUint32 | S3_SAVE, &ddTempVariable); |
| 300 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG20), AccWidthUint16 | S3_SAVE, ~(BIT8), BIT8); |
| 301 | do { |
| 302 | ReadMEM (ddBar5 + SB_SATA_BAR5_REG20 , AccWidthUint32 | S3_SAVE, &ddData); |
| 303 | ddData = ddData & BIT8; |
| 304 | } while ( ddData != 0 ); |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | |
| 309 | /** |
| 310 | * Table for class code of SATA Controller in different modes |
| 311 | * |
| 312 | * |
| 313 | * |
| 314 | * |
| 315 | */ |
| 316 | UINT32 sataIfCodeTable[] = |
| 317 | { |
| 318 | 0x01018F40, //sata class ID of IDE |
| 319 | 0x01040040, //sata class ID of RAID |
| 320 | 0x01060140, //sata class ID of AHCI |
| 321 | 0x01018A40, //sata class ID of Legacy IDE |
| 322 | 0x01018F40, //sata class ID of IDE to AHCI mode |
| 323 | }; |
| 324 | |
| 325 | /** |
| 326 | * Table for device id of SATA Controller in different modes |
| 327 | * |
| 328 | * |
| 329 | * |
| 330 | * |
| 331 | */ |
| 332 | |
| 333 | UINT16 sataDeviceIDTable[] = |
| 334 | { |
| 335 | SB_SATA_DID, //sata device ID of IDE |
| 336 | SB_SATA_RAID_DID, //sata device ID of RAID |
| 337 | SB_SATA_AHCI_DID, //sata class ID of AHCI |
| 338 | SB_SATA_DID, //sata device ID of Legacy IDE |
| 339 | SB_SATA_DID, //sata device ID of IDE->AHCI mode |
| 340 | }; |
| 341 | |
| 342 | /** |
| 343 | * Table for Sata Phy Fine Setting |
| 344 | * |
| 345 | * |
| 346 | * |
| 347 | * |
| 348 | */ |
| 349 | SATAPHYSETTING sataPhyTable[] = |
| 350 | { |
| 351 | //Gen3 |
| 352 | {0x0030, 0x0057A607}, |
| 353 | {0x0031, 0x0057A607}, |
| 354 | {0x0032, 0x0057A407}, |
| 355 | {0x0033, 0x0057A407}, |
| 356 | {0x0034, 0x0057A607}, |
| 357 | {0x0035, 0x0057A607}, |
| 358 | {0x0036, 0x0057A403}, |
| 359 | {0x0037, 0x0057A403}, |
| 360 | |
| 361 | //Gen2 |
| 362 | {0x0120, 0x00071302}, |
| 363 | |
| 364 | //Gen1 |
| 365 | {0x0110, 0x00174101} |
| 366 | }; |
| 367 | |
| 368 | /** |
| 369 | * sataInitBeforePciEnum - Config SATA controller before PCI emulation |
| 370 | * |
| 371 | * |
| 372 | * |
| 373 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 374 | * |
| 375 | */ |
| 376 | VOID |
| 377 | sataInitBeforePciEnum ( |
| 378 | IN AMDSBCFG* pConfig |
| 379 | ) |
| 380 | { |
| 381 | UINT32 ddTempVar; |
| 382 | UINT32 ddValue; |
| 383 | UINT32 *tempptr; |
| 384 | UINT16 *pDeviceIdptr; |
| 385 | UINT32 dwDeviceId; |
| 386 | UINT8 dbValue; |
| 387 | UINT8 pValue; |
| 388 | UINT8 dbChannel; |
| 389 | UINT16 i; |
| 390 | SATAPHYSETTING *pPhyTable; |
| 391 | |
| 392 | pConfig->SATAPORTPOWER.SataPortPowerReg = \ |
| 393 | + pConfig->SATAPORTPOWER.SataPortPower.PORT0 \ |
| 394 | + (pConfig->SATAPORTPOWER.SataPortPower.PORT1 << 1) \ |
| 395 | + (pConfig->SATAPORTPOWER.SataPortPower.PORT2 << 2) \ |
| 396 | + (pConfig->SATAPORTPOWER.SataPortPower.PORT3 << 3) \ |
| 397 | + (pConfig->SATAPORTPOWER.SataPortPower.PORT4 << 4) \ |
| 398 | + (pConfig->SATAPORTPOWER.SataPortPower.PORT5 << 5) \ |
| 399 | + (pConfig->SATAPORTPOWER.SataPortPower.PORT6 << 6) \ |
| 400 | + (pConfig->SATAPORTPOWER.SataPortPower.PORT7 << 7); |
| 401 | // BIT0 Enable write access to PCI header (reg 08h-0Bh) by setting SATA PCI register 40h |
| 402 | // BIT4:disable fast boot //? |
| 403 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0 + BIT4); |
| 404 | // BIT0 Enable write access to PCI header (reg 08h-0Bh) by setting IDE PCI register 40h |
| 405 | RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0); |
| 406 | // RPR Enable IDE DMA read enhancement |
| 407 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48 + 3), AccWidthUint8 | S3_SAVE, 0xff, BIT7); |
| 408 | // RPR Unused SATA Ports Disabled |
| 409 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8 | S3_SAVE, 0, pConfig->SATAPORTPOWER.SataPortPowerReg); |
| 410 | dbValue = (UINT8)pConfig->SataClass; |
| 411 | if (dbValue == AHCI_MODE_7804) { |
| 412 | dbValue = AHCI_MODE; |
| 413 | } |
| 414 | if (dbValue == IDE_TO_AHCI_MODE_7804) { |
| 415 | dbValue = IDE_TO_AHCI_MODE; |
| 416 | } |
| 417 | // Disable PATA MSI |
| 418 | RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG34), AccWidthUint8 | S3_SAVE, 0x00, 0x00); |
| 419 | RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG06), AccWidthUint8 | S3_SAVE, 0xEF, 0x00); |
| 420 | |
| 421 | if ( (pConfig->SataClass == 3) | (pConfig->SataClass == 0)) { |
| 422 | dbChannel = 0x00; |
| 423 | ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48 + 3), AccWidthUint8, &dbChannel); |
| 424 | dbChannel &= 0xCF; |
| 425 | if ( pConfig->SataDisUnusedIdePChannel ) { |
| 426 | dbChannel |= 0x10; |
| 427 | } |
| 428 | if ( pConfig->SataDisUnusedIdeSChannel ) { |
| 429 | dbChannel |= 0x20; |
| 430 | } |
| 431 | WritePCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48 + 3), AccWidthUint8, &dbChannel); |
| 432 | } |
| 433 | |
| 434 | if ((pConfig->SATAMODE.SataMode.SataIdeCombinedMode) == DISABLED ) { |
| 435 | ReadPCI (((IDE_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 11), AccWidthUint8, &dbChannel); |
| 436 | dbChannel &= 0xCF; |
| 437 | if ( pConfig->IdeDisUnusedIdePChannel ) { |
| 438 | dbChannel |= 0x10; |
| 439 | } |
| 440 | if ( pConfig->IdeDisUnusedIdeSChannel ) { |
| 441 | dbChannel |= 0x20; |
| 442 | } |
| 443 | WritePCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG40 + 11), AccWidthUint8, &dbChannel); |
| 444 | } |
| 445 | // Get the appropriate class code from the table and write it to PCI register 08h-0Bh |
| 446 | // Set the appropriate SATA class based on the input parameters |
| 447 | // SATA IDE Controller Class ID & SSID |
| 448 | tempptr = (UINT32 *) FIXUP_PTR (&sataIfCodeTable[0]); |
| 449 | if ( (pConfig->SataIdeMode == 1) && (pConfig->SataClass != 3) ) { |
| 450 | ddValue = tempptr[0]; |
| 451 | // Write the class code to IDE PCI register 08h-0Bh |
| 452 | RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG08), AccWidthUint32 | S3_SAVE, 0, ddValue); |
| 453 | } |
| 454 | ddValue = tempptr[dbValue]; |
| 455 | // Write the class code to SATA PCI register 08h-0Bh |
| 456 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, ddValue); |
| 457 | if ( pConfig->SataClass == LEGACY_IDE_MODE ) { |
| 458 | //Set PATA controller to native mode |
| 459 | RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG09), AccWidthUint8 | S3_SAVE, 0x00, 0x08F); |
| 460 | } |
Aaron Durbin | d907a34 | 2014-01-30 22:20:01 -0600 | [diff] [blame] | 461 | if (pConfig->BuildParameters.IdeSsid != 0 ) { |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 462 | RWPCI ((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.IdeSsid); |
| 463 | } |
| 464 | // SATA Controller Class ID & SSID |
| 465 | pDeviceIdptr = (UINT16 *) FIXUP_PTR (&sataDeviceIDTable[0]); |
| 466 | ddTempVar = pConfig->BuildParameters.SataIDESsid; |
| 467 | dwDeviceId = pDeviceIdptr[dbValue]; |
| 468 | if ( pConfig->SataClass == RAID_MODE) { |
| 469 | ddTempVar = pConfig->BuildParameters.SataRAID5Ssid; |
| 470 | dwDeviceId = SB_SATA_RAID5_DID; |
| 471 | pValue = SATA_EFUSE_LOCATION; |
| 472 | getEfuseStatus (&pValue); |
| 473 | if (( pValue & SATA_EFUSE_BIT ) || ( pConfig->SataForceRaid == 1 )) { |
| 474 | dwDeviceId = SB_SATA_RAID_DID; |
| 475 | ddTempVar = pConfig->BuildParameters.SataRAIDSsid; |
| 476 | } |
| 477 | } |
| 478 | if ( ((pConfig->SataClass) == AHCI_MODE) || ((pConfig->SataClass) == IDE_TO_AHCI_MODE) || |
| 479 | ((pConfig->SataClass) == AHCI_MODE_7804) || ((pConfig->SataClass) == IDE_TO_AHCI_MODE_7804) ) { |
| 480 | ddTempVar = pConfig->BuildParameters.SataAHCISsid; |
| 481 | } |
| 482 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, dwDeviceId); |
| 483 | RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG2C, AccWidthUint32 | S3_SAVE, 0x00, ddTempVar); |
| 484 | |
| 485 | // SATA IRQ Resource |
| 486 | sataSetIrqIntResource (pConfig); |
| 487 | |
| 488 | // RPR 9.5 SATA PHY Programming Sequence |
| 489 | pPhyTable = (SATAPHYSETTING*)FIXUP_PTR (&sataPhyTable[0]); |
Patrick Georgi | 6b688f5 | 2021-02-12 13:49:11 +0100 | [diff] [blame^] | 490 | for (i = 0; i < ARRAY_SIZE(sataPhyTable); i++) { |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 491 | RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG80, AccWidthUint16 | S3_SAVE, 0x00, pPhyTable->wPhyCoreControl); |
| 492 | RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG98, AccWidthUint32 | S3_SAVE, 0x00, pPhyTable->dwPhyFineTune); |
| 493 | ++pPhyTable; |
| 494 | } |
| 495 | RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG80, AccWidthUint16 | S3_SAVE, 0x00, 0x110); |
| 496 | RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG9C, AccWidthUint32 | S3_SAVE, (UINT32) (~(0x7 << 4)), (UINT32) (0x2 << 4)); |
| 497 | RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG80, AccWidthUint16 | S3_SAVE, 0x00, 0x10); |
| 498 | |
| 499 | RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0); |
| 500 | // Disable write access to PCI header |
| 501 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0); |
| 502 | if ( IsSbA12Plus () ) { |
| 503 | //SATA PCI Config 0x4C[31:26] program 111111b (six 1's) |
| 504 | //SATA PCI Config 0x48[11] program 1 |
| 505 | //SATA PCI Config 0x84[31] program 0 |
| 506 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG4C), AccWidthUint32 | S3_SAVE, (UINT32) (~ (0x3f << 26)), (UINT32) (0x3f << 26)); |
| 507 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48), AccWidthUint32 | S3_SAVE, (UINT32) (~ (0x01 << 11)), (UINT32) (0x01 << 11)); |
| 508 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG84), AccWidthUint32 | S3_SAVE, (UINT32) (~ (0x01 << 31)), (UINT32) (0x00 << 31)); |
| 509 | } |
| 510 | |
| 511 | //SATA PCI config register 0x4C [20] =1 |
| 512 | //SATA PCI config register 0x4C [21] =1 |
| 513 | //SATA PCI config register 0x4C [18] =1 |
| 514 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG4C), AccWidthUint32 | S3_SAVE, ~ (BIT18 + BIT20 + BIT21), (BIT18 + BIT20 + BIT21)); |
| 515 | } |
| 516 | |
| 517 | /** |
| 518 | * sataInitAfterPciEnum - Config SATA controller after PCI emulation |
| 519 | * |
| 520 | * |
| 521 | * |
| 522 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 523 | * |
| 524 | */ |
| 525 | VOID |
| 526 | sataInitAfterPciEnum ( |
| 527 | IN AMDSBCFG* pConfig |
| 528 | ) |
| 529 | { |
| 530 | UINT32 ddAndMask; |
| 531 | UINT32 ddOrMask; |
| 532 | UINT32 ddBar5; |
| 533 | UINT8 dbVar; |
| 534 | UINT8 dbPortNum; |
| 535 | UINT8 dbEfuse; |
| 536 | UINT8 dbPortMode; |
| 537 | UINT16 SataPortMode; |
| 538 | UINT8 cimSataAggrLinkPmCap; |
| 539 | UINT8 cimSataPortMultCap; |
| 540 | UINT8 cimSataPscCap; |
| 541 | UINT8 cimSataSscCap; |
| 542 | UINT8 cimSataFisBasedSwitching; |
| 543 | UINT8 cimSataCccSupport; |
| 544 | UINT8 cimSataMsiCapability; |
| 545 | UINT8 cimSataTargetSupport8Device; |
| 546 | UINT8 cimSataDisableGenericMode; |
| 547 | UINT8 cimSataAhciEnclosureManagement; |
| 548 | UINT8 cimSataSgpio0; |
| 549 | UINT8 cimSataSgpio1; |
| 550 | UINT8 cimSataHotRemovelEnh; |
| 551 | UINT8 cimSataPhyPllShutDown; |
| 552 | UINT8 dbCccInt; |
| 553 | |
| 554 | cimSataAggrLinkPmCap = (UINT8) pConfig->SataAggrLinkPmCap; |
| 555 | cimSataPortMultCap = (UINT8) pConfig->SataPortMultCap; |
| 556 | cimSataPscCap = (UINT8) pConfig->SataPscCap; |
| 557 | cimSataSscCap = (UINT8) pConfig->SataSscCap; |
| 558 | cimSataFisBasedSwitching = (UINT8) pConfig->SataFisBasedSwitching; |
| 559 | cimSataCccSupport = (UINT8) pConfig->SataCccSupport; |
| 560 | cimSataMsiCapability = (UINT8) pConfig->SataMsiCapability; |
| 561 | cimSataTargetSupport8Device = (UINT8) pConfig->SataTargetSupport8Device; |
| 562 | cimSataDisableGenericMode = (UINT8) pConfig->SataDisableGenericMode; |
| 563 | cimSataAhciEnclosureManagement = (UINT8) pConfig->SataAhciEnclosureManagement; |
| 564 | cimSataSgpio0 = (UINT8) pConfig->SataSgpio0; |
| 565 | cimSataSgpio1 = (UINT8) pConfig->SataSgpio1; |
| 566 | cimSataHotRemovelEnh = (UINT8) pConfig->SataHotRemoveEnh; |
| 567 | cimSataPhyPllShutDown = (UINT8) pConfig->SataPhyPllShutDown; |
| 568 | |
| 569 | #if SB_CIMx_PARAMETER == 0 |
| 570 | cimSataAggrLinkPmCap = cimSataAggrLinkPmCapDefault; |
| 571 | cimSataPortMultCap = cimSataPortMultCapDefault; |
| 572 | cimSataPscCap = cimSataPscCapDefault; |
| 573 | cimSataSscCap = cimSataSscCapDefault; |
| 574 | cimSataFisBasedSwitching = cimSataFisBasedSwitchingDefault; |
| 575 | cimSataCccSupport = cimSataCccSupportDefault; |
| 576 | cimSataMsiCapability = cimSataMsiCapabilityDefault; |
| 577 | cimSataTargetSupport8Device = cimSataTargetSupport8DeviceDefault; |
| 578 | cimSataDisableGenericMode = cimSataDisableGenericModeDefault; |
| 579 | cimSataAhciEnclosureManagement = cimSataAhciEnclosureManagementDefault; |
| 580 | cimSataSgpio0 = cimSataSgpio0Default; |
| 581 | cimSataSgpio1 = cimSataSgpio1Default; |
| 582 | cimSataHotRemovelEnh = cimSataHotRemoveEnhDefault; |
| 583 | cimSataPhyPllShutDown = cimSataPhyPllShutDownDefault; |
| 584 | #endif |
| 585 | |
| 586 | ddAndMask = 0; |
| 587 | ddOrMask = 0; |
| 588 | ddBar5 = 0; |
| 589 | if ( pConfig->SATAMODE.SataMode.SataController == 0 ) { |
| 590 | return; //return if SATA controller is disabled. |
| 591 | } |
| 592 | |
| 593 | //Enable write access to pci header, pm capabilities |
| 594 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xFF, BIT0); |
| 595 | |
| 596 | sataBar5setting (pConfig, &ddBar5); |
| 597 | |
| 598 | ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar); |
| 599 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, 0xFF, 0x03); //memory and io access enable |
| 600 | dbEfuse = SATA_FIS_BASE_EFUSE_LOC; |
| 601 | getEfuseStatus (&dbEfuse); |
| 602 | |
| 603 | if ( !cimSataPortMultCap ) { |
| 604 | ddAndMask |= BIT12; |
| 605 | } |
| 606 | if ( cimSataAggrLinkPmCap ) { |
| 607 | ddOrMask |= BIT11; |
| 608 | } else { |
| 609 | ddAndMask |= BIT11; |
| 610 | } |
| 611 | if ( cimSataPscCap ) { |
| 612 | ddOrMask |= BIT1; |
| 613 | } else { |
| 614 | ddAndMask |= BIT1; |
| 615 | } |
| 616 | if ( cimSataSscCap ) { |
| 617 | ddOrMask |= BIT26; |
| 618 | } else { |
| 619 | ddAndMask |= BIT26; |
| 620 | } |
| 621 | if ( cimSataFisBasedSwitching ) { |
| 622 | if (dbEfuse & BIT1) { |
| 623 | ddAndMask |= BIT10; |
| 624 | } else { |
| 625 | ddOrMask |= BIT10; |
| 626 | } |
| 627 | } else { |
| 628 | ddAndMask |= BIT10; |
| 629 | } |
| 630 | // RPR 8.10 Disabling CCC (Command Completion Coalescing) support. |
| 631 | if ( cimSataCccSupport ) { |
| 632 | ddOrMask |= BIT19; |
| 633 | } else { |
| 634 | ddAndMask |= BIT19; |
| 635 | } |
| 636 | if ( cimSataAhciEnclosureManagement ) { |
| 637 | ddOrMask |= BIT27; |
| 638 | } else { |
| 639 | ddAndMask |= BIT27; |
| 640 | } |
| 641 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint32 | S3_SAVE, ~ddAndMask, ddOrMask); |
| 642 | |
| 643 | |
| 644 | // SATA ESP port setting |
| 645 | // These config bits are set for SATA driver to identify which ports are external SATA ports and need to |
| 646 | // support hotplug. If a port is set as an external SATA port and need to support hotplug, then driver will |
| 647 | // not enable power management (HIPM & DIPM) for these ports. |
| 648 | pConfig->SATAESPPORT.SataPortReg = \ |
| 649 | + pConfig->SATAESPPORT.SataEspPort.PORT0 \ |
| 650 | + (pConfig->SATAESPPORT.SataEspPort.PORT1 << 1) \ |
| 651 | + (pConfig->SATAESPPORT.SataEspPort.PORT2 << 2) \ |
| 652 | + (pConfig->SATAESPPORT.SataEspPort.PORT3 << 3) \ |
| 653 | + (pConfig->SATAESPPORT.SataEspPort.PORT4 << 4) \ |
| 654 | + (pConfig->SATAESPPORT.SataEspPort.PORT5 << 5) \ |
| 655 | + (pConfig->SATAESPPORT.SataEspPort.PORT6 << 6) \ |
| 656 | + (pConfig->SATAESPPORT.SataEspPort.PORT7 << 7); |
| 657 | if ( pConfig->SATAESPPORT.SataPortReg != 0 ) { |
| 658 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, ~(pConfig->SATAESPPORT.SataPortReg), 0); |
| 659 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, 0xFF00FF00, (pConfig->SATAESPPORT.SataPortReg << 16)); |
| 660 | // RPR 8.7 External SATA Port Indication Registers |
| 661 | // If any of the ports was programmed as an external port, HCAP.SXS should also be set |
| 662 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint32 | S3_SAVE, ~(BIT20), BIT20); |
| 663 | } else { |
| 664 | // RPR 8.7 External SATA Port Indication Registers |
| 665 | // If any of the ports was programmed as an external port, HCAP.SXS should also be set (Clear for no ESP port) |
| 666 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, 0xFF00FF00, 0x00); |
| 667 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint32 | S3_SAVE, ~(BIT20), 0x00); |
| 668 | } |
| 669 | |
| 670 | if ( cimSataFisBasedSwitching ) { |
| 671 | if (dbEfuse & BIT1) { |
| 672 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, 0x00FFFFFF, 0x00); |
| 673 | } else { |
| 674 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, 0x00FFFFFF, 0xFF000000); |
| 675 | } |
| 676 | } else { |
| 677 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, 0x00FFFFFF, 0x00); |
| 678 | } |
| 679 | |
| 680 | //SB02712 Turn off MSI for SATA IDE mode. |
| 681 | if ((pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE)) { |
| 682 | cimSataMsiCapability = 0; |
| 683 | } |
| 684 | //Enabled SATA MSI capability |
| 685 | // RPR 8.11 SATA MSI and D3 Power State Capability |
| 686 | if (IsSbA12Plus ()) { |
| 687 | if ( cimSataMsiCapability ) { |
| 688 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG34), AccWidthUint8 | S3_SAVE, 0, 0x50); |
| 689 | } else { |
| 690 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG34), AccWidthUint8 | S3_SAVE, 0, 0x70); |
| 691 | } |
| 692 | } else { |
| 693 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG34), AccWidthUint8 | S3_SAVE, 0, 0x70); |
| 694 | } |
| 695 | |
| 696 | if (((pConfig->SataClass) != NATIVE_IDE_MODE) && ((pConfig->SataClass) != LEGACY_IDE_MODE)) { |
Paul Menzel | 0b31286 | 2013-04-12 14:03:04 +0200 | [diff] [blame] | 697 | // RAID or AHCI |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 698 | if ((pConfig->SATAMODE.SataMode.SataIdeCombinedMode) == DISABLED) { |
| 699 | // IDE2 Controller is enabled |
| 700 | if ((pConfig->SATAMODE.SataMode.SataIdeCombMdPriSecOpt) == ENABLED) { |
| 701 | // 6 AHCI mode |
| 702 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG0C), AccWidthUint8 | S3_SAVE, 0x00, 0x3F); |
| 703 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG00), AccWidthUint8 | S3_SAVE, ~(BIT2 + BIT1 + BIT0), BIT2 + BIT0); |
| 704 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1); |
| 705 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint8, 0x07, 0x30); |
| 706 | } else { |
| 707 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG0C), AccWidthUint8 | S3_SAVE, 0x00, 0x0F); |
| 708 | if ( pConfig->SataCccSupport ) { |
| 709 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1); |
| 710 | } else { |
| 711 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT2); |
| 712 | } |
| 713 | } |
| 714 | } else { |
| 715 | // IDE2 Controller is disabled |
| 716 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG00), AccWidthUint8 | S3_SAVE, ~(BIT2 + BIT1 + BIT0), BIT2 + BIT1 + BIT0); |
| 717 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG0C), AccWidthUint8 | S3_SAVE, 0x00, 0xFF); |
| 718 | if ( pConfig->SataCccSupport ) { |
| 719 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT3); |
| 720 | } else { |
| 721 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1); |
| 722 | } |
| 723 | } |
| 724 | } |
| 725 | if ( pConfig->BIOSOSHandoff == 1 ) { |
| 726 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG24), AccWidthUint8 | S3_SAVE, ~BIT0, BIT0); |
| 727 | } else { |
| 728 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG24), AccWidthUint8 | S3_SAVE, ~BIT0, 0x00); |
| 729 | } |
| 730 | pConfig->SATAPORTMODE.SataPortMode = \ |
| 731 | pConfig->SATAPORTMODE.SataPortMd.PORT0 \ |
| 732 | + (pConfig->SATAPORTMODE.SataPortMd.PORT1 << 2) \ |
| 733 | + (pConfig->SATAPORTMODE.SataPortMd.PORT2 << 4) \ |
| 734 | + (pConfig->SATAPORTMODE.SataPortMd.PORT3 << 6) \ |
| 735 | + (pConfig->SATAPORTMODE.SataPortMd.PORT4 << 8) \ |
| 736 | + (pConfig->SATAPORTMODE.SataPortMd.PORT5 << 10) \ |
| 737 | + (pConfig->SATAPORTMODE.SataPortMd.PORT6 << 12) \ |
| 738 | + (pConfig->SATAPORTMODE.SataPortMd.PORT7 << 14); |
| 739 | SataPortMode = (UINT16)pConfig->SATAPORTMODE.SataPortMode; |
| 740 | dbPortNum = 0; |
| 741 | |
| 742 | while ( dbPortNum < 8 ) { |
| 743 | dbPortMode = (UINT8) (SataPortMode & 3); |
| 744 | if ( (dbPortMode == BIT0) || (dbPortMode == BIT1) ) { |
| 745 | if ( dbPortMode == BIT0 ) { |
| 746 | // set GEN 1 |
| 747 | RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0x0F, 0x10); |
| 748 | } |
| 749 | if ( dbPortMode == BIT1 ) { |
| 750 | // set GEN2 (default is GEN3) |
| 751 | RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0x0F, 0x20); |
| 752 | } |
| 753 | RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFF, 0x01); |
| 754 | cimSbStall (1000); |
| 755 | RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFE, 0x00); |
| 756 | } |
| 757 | SataPortMode >>= 2; |
| 758 | dbPortNum ++; |
| 759 | } |
| 760 | SbStall (1000); |
| 761 | SataPortMode = (UINT16)pConfig->SATAPORTMODE.SataPortMode; |
| 762 | dbPortNum = 0; |
| 763 | |
| 764 | while ( dbPortNum < 8 ) { |
| 765 | dbPortMode = (UINT8) (SataPortMode & 3); |
| 766 | if ( (dbPortMode == BIT0) || (dbPortMode == BIT1) ) { |
| 767 | RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFE, 0x00); |
| 768 | } |
| 769 | dbPortNum ++; |
| 770 | SataPortMode >>= 2; |
| 771 | } |
| 772 | |
| 773 | if ( cimSataTargetSupport8Device ) { |
| 774 | RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint16, ~BIT12, BIT12); |
| 775 | } else { |
| 776 | RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint16, ~BIT12, 0x00); |
| 777 | } |
| 778 | |
| 779 | if ( cimSataDisableGenericMode ) { |
| 780 | RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint16, ~BIT13, BIT13); |
| 781 | } else { |
| 782 | RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint16, ~BIT13, 0x00); |
| 783 | } |
| 784 | // 9.19 Optionally Disable Hot-removal Detection Enhancement |
| 785 | if ( cimSataHotRemovelEnh ) { |
| 786 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG80), AccWidthUint16 | S3_SAVE, ~BIT8, BIT8 ); |
| 787 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REGA8), AccWidthUint16 | S3_SAVE, ~BIT0, BIT0); |
| 788 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG80), AccWidthUint16 | S3_SAVE, ~BIT8, 0 ); |
| 789 | } |
| 790 | if ( cimSataSgpio0 ) { |
| 791 | sataGpioPorcedure (pConfig); |
| 792 | } |
| 793 | if ( cimSataSgpio1 ) { |
| 794 | sataGpioPorcedure (pConfig); |
| 795 | } |
| 796 | if ( IsSbA11 () ) { |
| 797 | if ( cimSataPhyPllShutDown ) { |
| 798 | RWPCI (((SATA_BUS_DEV_FUN << 16) + 0x87), AccWidthUint8 | S3_SAVE, ~(BIT6 + BIT7), BIT6 + BIT7); |
| 799 | } else { |
| 800 | RWPCI (((SATA_BUS_DEV_FUN << 16) + 0x87), AccWidthUint8 | S3_SAVE, ~(BIT6 + BIT7), 0x00); |
| 801 | } |
| 802 | } else { |
| 803 | if ( cimSataPhyPllShutDown ) { |
| 804 | RWPCI (((SATA_BUS_DEV_FUN << 16) + 0x87), AccWidthUint8 | S3_SAVE, ~(BIT6), BIT6); |
| 805 | } else { |
| 806 | RWPCI (((SATA_BUS_DEV_FUN << 16) + 0x87), AccWidthUint8 | S3_SAVE, ~(BIT6), 0x00); |
| 807 | } |
| 808 | } |
| 809 | if ( IsSbA12Plus () ) { |
| 810 | //SATA PCI Config 0x4C[31:26] program 111111b (six 1's) |
| 811 | //SATA PCI Config 0x48[11] program 1 |
| 812 | //SATA PCI Config 0x84[31] program 0 |
| 813 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG4C), AccWidthUint32 | S3_SAVE, (UINT32) (~ (0x3f << 26)), (UINT32) (0x3f << 26)); |
| 814 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48), AccWidthUint32 | S3_SAVE, (UINT32) (~ (0x01 << 11)), (UINT32) (0x01 << 11)); |
| 815 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG84), AccWidthUint32 | S3_SAVE, (UINT32) (~ (0x01 << 31)), (UINT32) (0x00 << 31)); |
| 816 | } |
| 817 | // RPR 9.18 CCC Interrupt |
| 818 | dbCccInt = 4; |
| 819 | if ((pConfig->SATAMODE.SataMode.SataIdeCombinedMode) == DISABLED) { |
| 820 | if ((pConfig->SATAMODE.SataMode.SataIdeCombMdPriSecOpt) == ENABLED) { |
| 821 | dbCccInt = 6; |
| 822 | } |
| 823 | } else { |
| 824 | dbCccInt = 8; |
| 825 | } |
| 826 | RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint8, 0x07, (dbCccInt << 3)); |
| 827 | |
| 828 | shutdownUnconnectedSataPortClock (pConfig, ddBar5); |
| 829 | |
| 830 | WritePCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar); |
| 831 | |
| 832 | // RPR 9.13 Disable SATA FLR Capability |
| 833 | // SATA_PCI_config 0x70 [15:8] = 0x00 |
| 834 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG70), AccWidthUint32 | S3_SAVE, 0xFFFF00FF, 0x00); |
| 835 | //Disable write access to pci header, pm capabilities |
| 836 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0); |
| 837 | } |
| 838 | |
| 839 | |
| 840 | /** |
| 841 | * sataInitMidPost - Config SATA controller in Middle POST. |
| 842 | * |
| 843 | * |
| 844 | * |
| 845 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 846 | * |
| 847 | */ |
| 848 | VOID |
| 849 | sataInitMidPost ( |
| 850 | IN AMDSBCFG* pConfig |
| 851 | ) |
| 852 | { |
| 853 | UINT32 ddBar5; |
| 854 | sataBar5setting (pConfig, &ddBar5); |
Paul Menzel | 0086162 | 2013-04-28 14:44:08 +0200 | [diff] [blame] | 855 | //If this is not S3 resume and also if SATA set to one of IDE mode, then implement drive detection workaround. |
efdesign98 | ee39ea7 | 2011-06-16 16:39:30 -0700 | [diff] [blame] | 856 | if ( ! (pConfig->S3Resume) && ( ((pConfig->SataClass) != AHCI_MODE) && ((pConfig->SataClass) != RAID_MODE) ) ) { |
| 857 | sataDriveDetection (pConfig, &ddBar5); |
| 858 | } |
| 859 | #ifdef SATA_BUS_DEV_FUN_FPGA |
| 860 | sataBar5settingFpga (pConfig, &ddBar5); |
| 861 | sataDriveDetectionFpga (pConfig, &ddBar5); |
| 862 | #endif |
| 863 | } |
| 864 | |
| 865 | /** |
| 866 | * sataDriveDetection - Sata drive detection |
| 867 | * |
| 868 | * |
| 869 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 870 | * @param[in] *pBar5 Sata BAR5 base address. |
| 871 | * |
| 872 | */ |
| 873 | VOID |
| 874 | sataDriveDetection ( |
| 875 | IN AMDSBCFG* pConfig, |
| 876 | IN UINT32 *pBar5 |
| 877 | ) |
| 878 | { |
| 879 | UINT32 ddVar0; |
| 880 | UINT8 dbPortNum; |
| 881 | UINT8 dbVar0; |
| 882 | UINT16 dwIoBase; |
| 883 | UINT32 ddVar1; |
| 884 | TRACE ((DMSG_SB_TRACE, "CIMx - Entering sata drive detection procedure\n\n")); |
| 885 | TRACE ((DMSG_SB_TRACE, "SATA BAR5 is %X \n", *pBar5)); |
| 886 | if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE) ) { |
| 887 | for ( dbPortNum = 0; dbPortNum < 4; dbPortNum++ ) { |
| 888 | ReadMEM (*pBar5 + SB_SATA_BAR5_REG128 + dbPortNum * 0x80, AccWidthUint32, &ddVar0); |
| 889 | if ( ( ddVar0 & 0x0F ) == 0x03 ) { |
| 890 | if ( dbPortNum & BIT0 ) { |
| 891 | //this port belongs to secondary channel |
| 892 | ReadPCI (((UINT32) (SATA_BUS_DEV_FUN << 16) + SB_SATA_REG18), AccWidthUint16, &dwIoBase); |
| 893 | } else { |
| 894 | //this port belongs to primary channel |
| 895 | ReadPCI (((UINT32) (SATA_BUS_DEV_FUN << 16) + SB_SATA_REG10), AccWidthUint16, &dwIoBase); |
| 896 | } |
| 897 | //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them |
| 898 | if ( pConfig->SataClass == LEGACY_IDE_MODE ) { |
| 899 | dwIoBase = ( (0x170) | ((UINT16) ( (~((UINT8) (dbPortNum & BIT0) << 7)) & 0x80 )) ); |
| 900 | } |
| 901 | if ( dbPortNum & BIT1 ) { |
| 902 | //this port is slave |
| 903 | dbVar0 = 0xB0; |
| 904 | } else { |
| 905 | //this port is master |
| 906 | dbVar0 = 0xA0; |
| 907 | } |
| 908 | dwIoBase &= 0xFFF8; |
| 909 | WriteIO (dwIoBase + 6, AccWidthUint8, &dbVar0); |
| 910 | //Wait in loop for 30s for the drive to become ready |
| 911 | for ( ddVar1 = 0; ddVar1 < 300000; ddVar1++ ) { |
| 912 | ReadIO (dwIoBase + 7, AccWidthUint8, &dbVar0); |
| 913 | if ( (dbVar0 & 0x88) == 0 ) { |
| 914 | break; |
| 915 | } |
| 916 | SbStall (100); |
| 917 | } |
| 918 | } //end of if ( ( ddVar0 & 0x0F ) == 0x03) |
| 919 | } //for (dbPortNum = 0; dbPortNum < 4; dbPortNum++) |
| 920 | } //if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE)) |
| 921 | } |
| 922 | |
| 923 | #ifdef SATA_BUS_DEV_FUN_FPGA |
| 924 | VOID |
| 925 | sataDriveDetectionFpga ( |
| 926 | IN AMDSBCFG* pConfig, |
| 927 | IN UINT32 *pBar5 |
| 928 | ) |
| 929 | { |
| 930 | UINT32 ddVar0; |
| 931 | UINT8 dbPortNum; |
| 932 | UINT8 dbVar0; |
| 933 | UINT16 dwIoBase; |
| 934 | UINT32 ddVar1; |
| 935 | TRACE ((DMSG_SB_TRACE, "CIMx - Entering sata drive detection procedure\n\n")); |
| 936 | TRACE ((DMSG_SB_TRACE, "SATA BAR5 is %X \n", *pBar5)); |
| 937 | for ( dbPortNum = 0; dbPortNum < 4; dbPortNum++ ) { |
| 938 | ReadMEM (*pBar5 + SB_SATA_BAR5_REG128 + dbPortNum * 0x80, AccWidthUint32, &ddVar0); |
| 939 | if ( ( ddVar0 & 0x0F ) == 0x03 ) { |
| 940 | if ( dbPortNum & BIT0 ) { |
| 941 | //this port belongs to secondary channel |
| 942 | ReadPCI (((UINT32) (SATA_BUS_DEV_FUN_FPGA << 16) + SB_SATA_REG18), AccWidthUint16, &dwIoBase); |
| 943 | } else { |
| 944 | //this port belongs to primary channel |
| 945 | ReadPCI (((UINT32) (SATA_BUS_DEV_FUN_FPGA << 16) + SB_SATA_REG10), AccWidthUint16, &dwIoBase); |
| 946 | } |
| 947 | //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them |
| 948 | if ( pConfig->SataClass == LEGACY_IDE_MODE ) { |
| 949 | dwIoBase = ( (0x170) | ((UINT16) ( (~((UINT8) (dbPortNum & BIT0) << 7)) & 0x80 )) ); |
| 950 | } |
| 951 | if ( dbPortNum & BIT1 ) { |
| 952 | //this port is slave |
| 953 | dbVar0 = 0xB0; |
| 954 | } else { |
| 955 | //this port is master |
| 956 | dbVar0 = 0xA0; |
| 957 | } |
| 958 | dwIoBase &= 0xFFF8; |
| 959 | WriteIO (dwIoBase + 6, AccWidthUint8, &dbVar0); |
| 960 | //Wait in loop for 30s for the drive to become ready |
| 961 | for ( ddVar1 = 0; ddVar1 < 300000; ddVar1++ ) { |
| 962 | ReadIO (dwIoBase + 7, AccWidthUint8, &dbVar0); |
| 963 | if ( (dbVar0 & 0x88) == 0 ) { |
| 964 | break; |
| 965 | } |
| 966 | SbStall (100); |
| 967 | } |
| 968 | } //end of if ( ( ddVar0 & 0x0F ) == 0x03) |
| 969 | } //for (dbPortNum = 0; dbPortNum < 4; dbPortNum++) |
| 970 | } |
| 971 | #endif |
| 972 | |
| 973 | /** |
| 974 | * sataInitLatePost - Prepare SATA controller to boot to OS. |
| 975 | * |
| 976 | * - Set class ID to AHCI (if set to AHCI * Mode) |
| 977 | * - Enable AHCI interrupt |
| 978 | * |
| 979 | * @param[in] pConfig Southbridge configuration structure pointer. |
| 980 | * |
| 981 | */ |
| 982 | VOID |
| 983 | sataInitLatePost ( |
| 984 | IN AMDSBCFG* pConfig |
| 985 | ) |
| 986 | { |
| 987 | UINT32 ddBar5; |
| 988 | UINT8 dbVar; |
| 989 | UINT8 dbPortNum; |
| 990 | |
| 991 | //Return immediately is sata controller is not enabled |
| 992 | if ( pConfig->SATAMODE.SataMode.SataController == 0 ) { |
| 993 | return; |
| 994 | } |
| 995 | //Enable write access to pci header, pm capabilities |
| 996 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0); |
| 997 | |
| 998 | sataBar5setting (pConfig, &ddBar5); |
| 999 | |
| 1000 | ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar); |
| 1001 | //Enable memory and io access |
| 1002 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, 0xFF, 0x03); |
| 1003 | |
| 1004 | if (( pConfig->SataClass == IDE_TO_AHCI_MODE) || ( pConfig->SataClass == IDE_TO_AHCI_MODE_7804 )) { |
| 1005 | //program the AHCI class code |
| 1006 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, 0x01060100); |
| 1007 | //Set interrupt enable bit |
| 1008 | RWMEM ((ddBar5 + 0x04), AccWidthUint8, (UINT32)~0, BIT1); |
| 1009 | //program the correct device id for AHCI mode |
| 1010 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, SB_SATA_AHCI_DID); |
| 1011 | } |
| 1012 | |
| 1013 | if (( pConfig->SataClass == AHCI_MODE_7804 ) || ( pConfig->SataClass == IDE_TO_AHCI_MODE_7804 )) { |
| 1014 | //program the correct device id for AHCI 7804 mode |
| 1015 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, SB_SATA_AMDAHCI_DID); |
| 1016 | } |
| 1017 | // OBS236459 IDE controller not shown in device manager when Os installed on IDE mode port |
| 1018 | //if ( pConfig->SataClass == IDE_TO_AHCI_MODE_7804 ) { |
| 1019 | //Disable IDE2 and Enable 8 channel for IDE-AHCI mode |
| 1020 | //RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint8, ~BIT1, BIT3); |
| 1021 | //} |
| 1022 | |
| 1023 | //Clear error status |
| 1024 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG130), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1025 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG1B0), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1026 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG230), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1027 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG2B0), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1028 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG330), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1029 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG3B0), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1030 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG430), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1031 | RWMEM ((ddBar5 + SB_SATA_BAR5_REG4B0), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF); |
| 1032 | CaculateAhciPortNumber (pConfig, ddBar5); |
| 1033 | //Restore memory and io access bits |
| 1034 | WritePCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar ); |
| 1035 | //Disable write access to pci header and pm capabilities |
| 1036 | RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0); |
| 1037 | for ( dbPortNum = 0; dbPortNum < 6; dbPortNum++ ) { |
| 1038 | RWMEM ((ddBar5 + 0x110 + (dbPortNum * 0x80)), AccWidthUint32, 0xFFFFFFFF, 0x00); |
| 1039 | } |
| 1040 | } |
| 1041 | |
| 1042 | |