1 /*****************************************************************************
3 * Copyright (C) 2012 Advanced Micro Devices, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 ***************************************************************************/
34 //Table for class code of SATA Controller in different modes
35 UINT32 sataIfCodeTable[] = {
36 0x01018f00, //sata class ID of IDE
37 0x01040000, //sata class ID of RAID
38 0x01060100, //sata class ID of AHCI
39 0x01018a00, //sata class ID of Legacy IDE
40 0x01018f00, //sata class ID of IDE to AHCI mode
41 0x01060100, //sata class ID of AMD-AHCI mode
42 0x01018f00 //sata class ID of IDE to AMD-AHCI mode
45 //Table for device id of SATA Controller in different modes
46 UINT16 sataDeviceIDTable[] = {
47 0x4390, //sata device ID of IDE
48 0x4392, //sata device ID of RAID
49 0x4391, //sata class ID of AHCI
50 0x4390, //sata device ID of Legacy IDE
51 0x4390, //sata device ID of IDE->AHCI mode
52 0x4394, //sata device ID for AMD-AHCI mode
53 0x4390 //sata device ID of IDE->AMDAHCI mode
57 void sataInitBeforePciEnum(AMDSBCFG* pConfig){
58 UINT32 ddValue, *tempptr;
59 UINT16 *pDeviceIdptr, dwDeviceId;
60 UINT8 dbValue, dbOrMask, dbAndMask;
65 // Enable/Disable Combined mode & do primary/secondary selections, enable/disable
66 if (pConfig->SataIdeCombinedMode == CIMX_OPTION_DISABLED) dbAndMask= BIT3; //Clear BIT3
67 if (pConfig->SataIdeCombMdPriSecOpt == 1) dbOrMask = BIT4; //Set BIT4
68 if (pConfig->SataSmbus == 0) dbOrMask = BIT1;
70 RWPCI(((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REGAD), AccWidthUint8 | S3_SAVE, ~(dbAndMask), dbOrMask);
72 if (pConfig->SataController == 0){
73 // SATA Controller Disabled & set Power Saving mode to disabled
74 RWPCI(((SMBUS_BUS_DEV_FUN << 16) + SB_SMBUS_REGAD), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, BIT1);
78 restrictSataCapabilities(pConfig);
80 // Get the appropriate class code from the table and write it to PCI register 08h-0Bh
81 // Set the appropriate SATA class based on the input parameters
82 dbValue=pConfig->SataClass;
83 tempptr= (UINT32 *) FIXUP_PTR (&sataIfCodeTable[0]);
84 ddValue=tempptr[dbValue];
86 // BIT0: Enable write access to PCI header (reg 08h-0Bh) by setting SATA PCI register 40h, bit 0
87 // BIT4:disable fast boot
88 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT4+BIT0);
90 // Write the class code to SATA PCI register 08h-0Bh
91 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, ddValue);
93 if (pConfig->SataClass == LEGACY_IDE_MODE) //SATA = Legacy IDE
94 //Set PATA controller to native mode
95 RWPCI(((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG09), AccWidthUint8 | S3_SAVE, 0x00, 0x08F);
97 //Change the appropriate device id
98 if (pConfig->SataClass == AMD_AHCI_MODE) {
99 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 3), AccWidthUint8 | S3_SAVE, 0xff, BIT0);
101 pDeviceIdptr= (UINT16 *) FIXUP_PTR (&sataDeviceIDTable[0]);
103 ReadPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, &dwDeviceId);
104 if ( !((dwDeviceId==SB750_SATA_DEFAULT_DEVICE_ID) && (pConfig->SataClass == RAID_MODE)) ){
105 //if not (SB750 & RAID mode), then program the device id
106 dwDeviceId=pDeviceIdptr[dbValue];
107 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, dwDeviceId);
110 if (pConfig->AcpiS1Supported)
111 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG34), AccWidthUint8 | S3_SAVE, 00, 0x70);//Disable SATA PM & MSI capability
113 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG60+1), AccWidthUint8 | S3_SAVE, 00, 0x70);//Disable SATA MSI capability
115 if (getRevisionID() >= SB700_A13){
116 //Enable test/enhancement mode for A13
117 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40+3), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT5, 00);
118 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48), AccWidthUint32 | S3_SAVE, ~(UINT32)(BIT24+BIT21), 0xBF80);
121 if (getRevisionID() >= SB700_A14){
122 //Fix for TT SB01352 - LED Stays On When ODD Attached To Slave Port In IDE Mode
123 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG48), AccWidthUint8 | S3_SAVE, 0xFF, BIT6);
126 // Disable write access to PCI header
127 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, 0);
129 // RPR 6.5 SATA PHY Programming Sequence
130 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG86, AccWidthUint16 | S3_SAVE, 0x00, 0x2C00);
131 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG88, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016);
132 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG8C, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016);
133 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG90, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016);
134 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG94, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016);
135 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG98, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016);
136 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG9C, AccWidthUint32 | S3_SAVE, 0x00, 0x01B48016);
137 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REGA0, AccWidthUint32 | S3_SAVE, 0x00, 0xA07AA07A);
138 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REGA4, AccWidthUint32 | S3_SAVE, 0x00, 0xA07AA07A);
139 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REGA8, AccWidthUint32 | S3_SAVE, 0x00, 0xA07AA07A);
141 CallBackToOEM(SATA_PHY_PROGRAMMING, NULL, pConfig);
144 void sataInitAfterPciEnum(AMDSBCFG* pConfig){
145 UINT32 ddAndMask=0, ddOrMask=0, ddBar5=0;
146 UINT8 dbVar, dbPortNum;
148 if (pConfig->SataController == 0) return; //return if SATA controller is disabled.
150 //Enable write access to pci header, pm capabilities
151 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xFF, BIT0);
153 //Disable AHCI enhancement function (RPR 7.2)
154 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8 | S3_SAVE, 0xFF, BIT7);
156 restrictSataCapabilities(pConfig);
158 ReadPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5);
160 if ( (ddBar5 == 0) || (ddBar5 == -1) ) {
161 //assign temporary BAR5
162 if ( (pConfig->TempMMIO == 0) || (pConfig->TempMMIO == -1))
165 ddBar5=pConfig->TempMMIO;
167 WritePCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5);
170 ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar);
171 RWPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8,0xFF, 0x03); //memory and io access enable
173 ddBar5 &= 0xFFFFFC00; //Clear Bits 9:0
174 if (!pConfig->SataPortMultCap)
176 if (!pConfig->SataAggrLinkPmCap)
178 if (pConfig->SataSscPscCap)
181 RWMEM((ddBar5 + SB_SATA_BAR5_REGFC),AccWidthUint32 | S3_SAVE, ~ddAndMask, ddOrMask);
184 //Clear HPCP and ESP by default
185 RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, 0xFFFC0FC0, 0);
187 if (pConfig->SataHpcpButNonESP !=0) {
188 RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, 0xFFFFFFC0, pConfig->SataHpcpButNonESP);
191 // SATA ESP port setting
192 // These config bits are set for SATA driver to identify which ports are external SATA ports and need to
193 // support hotplug. If a port is set as an external SATA port and need to support hotplug, then driver will
194 // not enable power management(HIPM & DIPM) for these ports.
195 if (pConfig->SataEspPort !=0) {
196 RWMEM((ddBar5 + SB_SATA_BAR5_REGFC),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, BIT20);
197 RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, ~(pConfig->SataEspPort), 0);
198 RWMEM((ddBar5 + SB_SATA_BAR5_REGF8),AccWidthUint32 | S3_SAVE, ~(UINT32)(BIT17+BIT16+BIT15+BIT14+BIT13+BIT12),(pConfig->SataEspPort << 12));
201 if ( ((pConfig->SataClass) != NATIVE_IDE_MODE) && ((pConfig->SataClass) != LEGACY_IDE_MODE) )
202 RWPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50+2), AccWidthUint8, ~(UINT32)(BIT3+BIT2+BIT1), BIT2+BIT1); //set MSI to 8 messages
204 if ( ((pConfig->SataClass) != NATIVE_IDE_MODE) && ((pConfig->SataClass) != LEGACY_IDE_MODE) && ((pConfig->SataIdeCombinedMode) == CIMX_OPTION_DISABLED) ){
205 RWMEM((ddBar5 + SB_SATA_BAR5_REG00),AccWidthUint8 | S3_SAVE, ~(UINT32)(BIT2+BIT1+BIT0), BIT2+BIT0);
206 RWMEM((ddBar5 + SB_SATA_BAR5_REG0C),AccWidthUint8 | S3_SAVE, 0xC0, 0x3F);
209 for (dbPortNum=0;dbPortNum<=5;dbPortNum++){
210 if (pConfig->SataPortMode & (1 << dbPortNum)){
212 RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0x0F, 0x10);
213 RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFF, 0x01);
215 RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFE, 0x00);
219 //If this is not S3 resume and also if SATA set to one of IDE mode, then implement drive detection workaround.
220 if ( !(pConfig->S3Resume) && ( ((pConfig->SataClass) != AHCI_MODE) && ((pConfig->SataClass) != RAID_MODE) && ((pConfig->SataClass) != AMD_AHCI_MODE) ) )
221 sataDriveDetection(pConfig, ddBar5);
223 if ( (pConfig->SataPhyWorkaround==1) || ( (pConfig->SataPhyWorkaround==0) && (getRevisionID() < SB700_A13)) )
224 sataPhyWorkaround(pConfig, ddBar5);
226 // Set the handshake bit for IDE driver to detect the disabled IDE channel correctly.
227 // Set IDE PCI Config 0x63 [3] if primary channel disabled, [4] if secondary channel disabled.
228 if (pConfig->SataIdeCombinedMode == CIMX_OPTION_DISABLED)
229 RWPCI( ((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG63), AccWidthUint8 , 0xF9, (0x02 << (pConfig->SataIdeCombMdPriSecOpt)) );
231 WritePCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar);
233 //Disable write access to pci header, pm capabilities
234 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, 0);
238 void sataDriveDetection(AMDSBCFG* pConfig, UINT32 ddBar5){
240 UINT8 dbPortNum, dbVar0;
241 UINT16 dwIoBase, dwVar0;
243 TRACE((DMSG_SB_TRACE, "CIMx - Entering sata drive detection procedure\n\n"));
244 TRACE((DMSG_SB_TRACE, "SATA BAR5 is %X \n", ddBar5));
246 if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE) || (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE) ){
247 for (dbPortNum=0;dbPortNum<4;dbPortNum++){
248 ReadMEM(ddBar5+ SB_SATA_BAR5_REG128 + dbPortNum * 0x80, AccWidthUint32, &ddVar0);
249 if ( ( ddVar0 & 0x0F ) == 0x03){
250 if ( dbPortNum & BIT0)
251 //this port belongs to secondary channel
252 ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG18), AccWidthUint16, &dwIoBase);
254 //this port belongs to primary channel
255 ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG10), AccWidthUint16, &dwIoBase);
257 //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them
258 if (pConfig->SataClass == LEGACY_IDE_MODE)
259 dwIoBase = ( (0x170) | ( (~((dbPortNum & BIT0) << 7)) & 0x80 ) );
261 if ( dbPortNum & BIT1)
265 //this port is master
268 WriteIO(dwIoBase+6, AccWidthUint8, &dbVar0);
270 //Wait in loop for 30s for the drive to become ready
271 for (dwVar0=0;dwVar0<3000;dwVar0++){
272 ReadIO(dwIoBase+7, AccWidthUint8, &dbVar0);
273 if ( (dbVar0 & 0x88) == 0)
277 } //end of if ( ( ddVar0 & 0x0F ) == 0x03)
278 } //for (dbPortNum=0;dbPortNum<4;dbPortNum++)
279 } //if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE) || (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE) )
283 //This patch is to workaround the SATA PHY logic hardware issue in the SB700.
284 //Internally this workaround is called as 7NewA
285 void sataPhyWorkaround(AMDSBCFG* pConfig, UINT32 ddBar5){
287 UINT8 dbPortNum, dbVar0;
289 if (pConfig->Gen1DeviceShutdownDuringPhyWrknd == 0x01){
290 for (dbPortNum=0;dbPortNum<=5;dbPortNum++){
291 ReadMEM(ddBar5+ SB_SATA_BAR5_REG128 + dbPortNum * 0x80, AccWidthUint8, &dbVar0);
292 if ( (dbVar0 & 0xF0) == 0x10){
293 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40+2, AccWidthUint8 | S3_SAVE, 0xFF, (01 << dbPortNum));
299 RWPMIO(SB_PMIO_REGD0, AccWidthUint8, ~(UINT32)(BIT4+BIT3), BIT4+BIT3);//set PMIO_D0[4:3] = 11b // this is to tell SATA PHY to use the internal 100MHz clock
300 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG86, AccWidthUint8 | S3_SAVE, 0x00, 0x40);// set SATA PCI_CFG 0x86[7:0] = 0x40 //after the reset is done, perform this to turn on the diff clock path into SATA PHY
301 Stall(2000);// Wait for 2ms
302 RWPMIO(SB_PMIO_REGD0, AccWidthUint8, ~(UINT32)(BIT4+BIT3), 00);//13. set PMIO_D0[4:3] = 00b
303 Stall(20000);// Wait 20ms
304 forceOOB(ddBar5);// Force OOB
306 RWPCI((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40+2, AccWidthUint8 | S3_SAVE, ~(0x03F), 00);
310 void forceOOB(UINT32 ddBar5){
312 for (dbPortNum=0;dbPortNum<=5;dbPortNum++)
313 RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFF, 0x01);
315 for (dbPortNum=0;dbPortNum<=5;dbPortNum++)
316 RWMEM(ddBar5+ SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFE, 0x00);
317 Stall(2000);// Wait for 2ms
324 SATA Late Configuration
326 if the mode is selected as IDE->AHCI
327 { 1. Set class ID to AHCI
328 2. Enable AHCI interrupt
333 pConfig - SBconfiguration
340 void sataInitLatePost(AMDSBCFG* pConfig){
344 //Return immediately is sata controller is not enabled
345 if (pConfig->SataController == 0) return;
347 restrictSataCapabilities(pConfig);
350 ReadPCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5);
352 //Assign temporary BAR if is not already assigned
353 if ( (ddBar5 == 0) || (ddBar5 == -1) ){
354 //assign temporary BAR5
355 if ( (pConfig->TempMMIO == 0) || (pConfig->TempMMIO == -1))
358 ddBar5=pConfig->TempMMIO;
359 WritePCI( ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, &ddBar5);
362 ReadPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar);
363 //Enable memory and io access
364 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, 0xFF, 0x03);
365 //Enable write access to pci header, pm capabilities
366 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0);
368 shutdownUnconnectedSataPortClock(pConfig, ddBar5);
370 if ( (pConfig->SataClass == IDE_TO_AHCI_MODE) || (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE)){
371 //program the AHCI class code
372 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, 0x01060100);
373 //Set interrupt enable bit
374 RWMEM((ddBar5 + 0x04),AccWidthUint8,~(UINT32)0,BIT1);
375 //program the correct device id for AHCI mode
376 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, 0x4391);
378 if (pConfig->SataClass == IDE_TO_AMD_AHCI_MODE)
379 //program the correct device id for AMD-AHCI mode
380 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 3), AccWidthUint8 | S3_SAVE, 0xFF, BIT0);
383 //Disable write access to pci header and pm capabilities
384 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~(UINT32)BIT0, 0);
386 RWMEM((ddBar5 + SB_SATA_BAR5_REG130),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
387 RWMEM((ddBar5 + SB_SATA_BAR5_REG1B0),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
388 RWMEM((ddBar5 + SB_SATA_BAR5_REG230),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
389 RWMEM((ddBar5 + SB_SATA_BAR5_REG2B0),AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
390 //Restore memory and io access bits
391 WritePCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar );
395 void shutdownUnconnectedSataPortClock(AMDSBCFG* pConfig, UINT32 ddBar5){
396 UINT8 dbPortNum, dbPortSataStatus, NumOfPorts=0;
397 UINT8 UnusedPortBitMap;
399 UINT8 ClockOffEnabled ;
401 UnusedPortBitMap = 0;
403 // First scan for all unused SATA ports
404 for (dbPortNum = 5; dbPortNum <= 5; dbPortNum--) {
405 ReadMEM (ddBar5 + SB_SATA_BAR5_REG128 + (dbPortNum * 0x80), AccWidthUint8, &dbPortSataStatus);
406 if ((!(dbPortSataStatus & 0x01)) && (!((pConfig->SataEspPort) & (1 << dbPortNum)))) {
407 UnusedPortBitMap |= (1 << dbPortNum);
411 // Decide if we need to shutdown the clock for all unused ports
412 SataType = pConfig->SataClass;
413 ClockOffEnabled = (pConfig->SataClkAutoOff && ((SataType == NATIVE_IDE_MODE) || (SataType == LEGACY_IDE_MODE) || \
414 (SataType == IDE_TO_AHCI_MODE) || (SataType == IDE_TO_AMD_AHCI_MODE))) || \
415 (pConfig->SataClkAutoOffAhciMode && ((SataType == AHCI_MODE) || (SataType == AMD_AHCI_MODE)));
417 if (ClockOffEnabled) {
418 //Shutdown the clock for the port and do the necessary port reporting changes.
419 TRACE((DMSG_SB_TRACE, "Shutting down clock for SATA ports %X \n", UnusedPortBitMap));
420 RWPCI(((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8, 0xFF, UnusedPortBitMap);
421 RWMEM(ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, ~UnusedPortBitMap, 00);
424 // If all ports are in disabled state, report at least one
425 ReadMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, &dbPortSataStatus);
426 if ( (dbPortSataStatus & 0x3F) == 0) {
427 dbPortSataStatus = 1;
428 RWMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, ~(0x3F), dbPortSataStatus);
431 // Decide if we need to hide unused ports from being seen by OS (this saves OS startup time)
432 if (pConfig->SataHideUnusedPort && ClockOffEnabled) {
433 dbPortSataStatus &= ~UnusedPortBitMap; // Mask off unused ports
434 for (dbPortNum = 0; dbPortNum <= 6; dbPortNum++) {
435 if (dbPortSataStatus & (1 << dbPortNum))
438 if (NumOfPorts == 0 ) {
441 RWMEM (ddBar5 + SB_SATA_BAR5_REG00, AccWidthUint8, 0xE0, NumOfPorts - 1);
446 void restrictSataCapabilities(AMDSBCFG* pConfig){
447 //Restrict capabilities
448 if ( ((getSbCapability(Sb_Raid0_1_Capability)== 0x02) && (pConfig->SataClass == RAID_MODE)) || \
449 ((getSbCapability(Sb_Raid5_Capability)== 0x02) && (pConfig->SataClass == RAID_MODE)) || \
450 ((getSbCapability(Sb_Ahci_Capability)== 0x02) && ((pConfig->SataClass == AHCI_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE)))){
451 pConfig->SataClass = NATIVE_IDE_MODE;