summaryrefslogtreecommitdiff
path: root/src/southbridge/amd/sb600
diff options
context:
space:
mode:
authorDan Lykowski <lykowdk@gmail.com>2009-01-15 02:35:30 +0000
committerPeter Stuge <peter@stuge.se>2009-01-15 02:35:30 +0000
commit6912846dda39e5c81993a64832301e78492ec254 (patch)
tree4dfd6a7d89c2b3a2f02a9ade7d995a6881a58f97 /src/southbridge/amd/sb600
parent0f502c7537707c82e4cea124df53eb76a3ddd807 (diff)
downloadcoreboot-6912846dda39e5c81993a64832301e78492ec254.tar.xz
Adds a retry/faildown to SB600 SATA detection logic.
SATA port status kept returning 0x1: BAR5+po+28h 1h = Device presence detected but Phy communication not established This patch adds logic to force 1.5g if the drive fails to communicate at 3.0g. Signed-off-by: Dan Lykowski <lykowdk@gmail.com> Acked-by: Peter Stuge <peter@stuge.se> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3864 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/southbridge/amd/sb600')
-rw-r--r--src/southbridge/amd/sb600/sb600_sata.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/southbridge/amd/sb600/sb600_sata.c b/src/southbridge/amd/sb600/sb600_sata.c
index 970af07512..933f59936e 100644
--- a/src/southbridge/amd/sb600/sb600_sata.c
+++ b/src/southbridge/amd/sb600/sb600_sata.c
@@ -175,6 +175,35 @@ static void sata_init(struct device *dev)
byte = readb(sata_bar5 + 0x128 + 0x80 * i);
printk_spew("SATA port %i status = %x\n", i, byte);
byte &= 0xF;
+
+ if( byte == 0x1 ) {
+ /* If the drive status is 0x1 then we see it but we aren't talking to it. */
+ /* Try to do something about it. */
+ printk_spew("SATA device detected but not talking. Trying lower speed.\n");
+
+ /* Read in Port-N Serial ATA Control Register */
+ byte = readb(sata_bar5 + 0x12C + 0x80 * i);
+
+ /* Set Reset Bit and 1.5g bit */
+ byte |= 0x11;
+ writeb(byte, (sata_bar5 + 0x12C + 0x80 * i));
+
+ /* Wait 1ms */
+ mdelay(1);
+
+ /* Clear Reset Bit */
+ byte &= ~0x01;
+ writeb(byte, (sata_bar5 + 0x12C + 0x80 * i));
+
+ /* Wait 1ms */
+ mdelay(1);
+
+ /* Reread status */
+ byte = readb(sata_bar5 + 0x128 + 0x80 * i);
+ printk_spew("SATA port %i status = %x\n", i, byte);
+ byte &= 0xF;
+ }
+
if (byte == 0x3) {
for (j = 0; j < 10; j++) {
if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2))