summaryrefslogtreecommitdiffstats
path: root/resources/libreboot/patch/kgpe-d16/0067-src-southbridge-amd-sb700-Reset-SATA-controller-in-A.patch
blob: 350e3d7e71766ae9455c353baec3650579cd013a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
From 6e707886c395da568608ac70760ce03b00c737c4 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <kb9vqf@pearsoncomputing.net>
Date: Sun, 21 Jun 2015 16:27:03 -0500
Subject: [PATCH 067/146] src/southbridge/amd/sb700: Reset SATA controller in
 AHCI mode during startup

In AHCI mode SeaBIOS randomly fails to detect disks (AHCI timeouts),
with the probability of a failure increasing with the number of disks
connected to the controller.  Resetting the SATA controller appears to
show the true state of the underlying hardware, allowing the drive
detection code to attempt link renegotiation as needed.
---
 src/southbridge/amd/sb700/sata.c |   47 ++++++++++++++++++++++++++++----------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/southbridge/amd/sb700/sata.c b/src/southbridge/amd/sb700/sata.c
index 6afdfdf..9f610a4 100644
--- a/src/southbridge/amd/sb700/sata.c
+++ b/src/southbridge/amd/sb700/sata.c
@@ -135,6 +135,8 @@ static void sata_init(struct device *dev)
 	/* get rev_id */
 	rev_id = pci_read_config8(sm_dev, 0x08) - 0x28;
 
+	printk(BIOS_SPEW, "rev_id=%x\n", rev_id);
+
 	if (sata_ahci_mode) {
 		/* Enable link latency enhancement on A14 and above */
 		if (rev_id >= 0x14) {
@@ -245,6 +247,27 @@ static void sata_init(struct device *dev)
 		write32(sata_bar5 + 0xfc, dword);
 	}
 
+	if (sata_ahci_mode) {
+		/* FIXME
+		* SeaBIOS does not know how to spin
+		* up the drives and therefore hangs
+		* in AHCI init if this is enabled...
+		*/
+		/* Enable staggered spin-up */
+		dword = read32(sata_bar5 + 0x00);
+#if 0
+		dword |= 0x1 << 27;
+#else
+		dword &= ~(0x1 << 27);
+#endif
+		write32(sata_bar5 + 0x00, dword);
+	
+		/* Reset the HBA to avoid stuck drives in SeaBIOS */
+		dword = read32(sata_bar5 + 0x04);
+		dword |= 0x1;
+		write32(sata_bar5 + 0x04, dword);
+	}
+
 	/* Write protect Sub-Class Code */
 	byte = pci_read_config8(dev, 0x40);
 	byte &= ~(1 << 0);
@@ -371,21 +394,21 @@ static void sata_init(struct device *dev)
 	}
 
 	/* Below is CIM InitSataLateFar */
-	/* Enable interrupts from the HBA  */
-	byte = read8(sata_bar5 + 0x4);
-	byte |= 1 << 1;
-	write8((sata_bar5 + 0x4), byte);
-
 	if (!sata_ahci_mode) {
-		/* Clear error status */
-		write32((sata_bar5 + 0x130), 0xFFFFFFFF);
-		write32((sata_bar5 + 0x1b0), 0xFFFFFFFF);
-		write32((sata_bar5 + 0x230), 0xFFFFFFFF);
-		write32((sata_bar5 + 0x2b0), 0xFFFFFFFF);
-		write32((sata_bar5 + 0x330), 0xFFFFFFFF);
-		write32((sata_bar5 + 0x3b0), 0xFFFFFFFF);
+		/* Enable interrupts from the HBA  */
+		byte = read8(sata_bar5 + 0x4);
+		byte |= 1 << 1;
+		write8((sata_bar5 + 0x4), byte);
 	}
 
+	/* Clear error status */
+	write32((sata_bar5 + 0x130), 0xFFFFFFFF);
+	write32((sata_bar5 + 0x1b0), 0xFFFFFFFF);
+	write32((sata_bar5 + 0x230), 0xFFFFFFFF);
+	write32((sata_bar5 + 0x2b0), 0xFFFFFFFF);
+	write32((sata_bar5 + 0x330), 0xFFFFFFFF);
+	write32((sata_bar5 + 0x3b0), 0xFFFFFFFF);
+
 	/* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */
 	/* ????? why CIM does not set the AcpiGpe0BlkAddr , but use it??? */
 
-- 
1.7.9.5