[coreboot-gerrit] Patch set updated for coreboot: [WIP] bd82x6x: Improve SATA hot plug support (not working yet)

Iru Cai (mytbk920423@gmail.com) gerrit at coreboot.org
Sun Jun 12 09:47:47 CEST 2016


Iru Cai (mytbk920423 at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14635

-gerrit

commit b376bb0c2d754a7651405c60a12f3b6afa492107
Author: Iru Cai <mytbk920423 at gmail.com>
Date:   Sat May 7 00:35:47 2016 +0800

    [WIP] bd82x6x: Improve SATA hot plug support (not working yet)
    
    This change is going to improve hot plug support on SATA ports like
    DVD drive and eSATA port. Before this change, SATA hot plug will fail
    on link power saving state.
    
    TODO: it seems that there's some problem writing PxCMD.ALPE and
    PxCMD.ASP for the kernel when running commands like:
    
    echo 'min_power' > '/sys/class/scsi_host/host1/link_power_management_policy'
    
    Change-Id: Id959145b1ebe87fdcadc7a062a1de9b217e58dd4
    Signed-off-by: Iru Cai <mytbk920423 at gmail.com>
---
 src/mainboard/lenovo/t420/devicetree.cb |  2 ++
 src/mainboard/lenovo/t520/devicetree.cb |  3 ++
 src/southbridge/intel/bd82x6x/chip.h    |  2 ++
 src/southbridge/intel/bd82x6x/sata.c    | 62 ++++++++++++++++++++++++++++++++-
 4 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/src/mainboard/lenovo/t420/devicetree.cb b/src/mainboard/lenovo/t420/devicetree.cb
index 9f42cbb..d9830a8 100644
--- a/src/mainboard/lenovo/t420/devicetree.cb
+++ b/src/mainboard/lenovo/t420/devicetree.cb
@@ -56,6 +56,8 @@ chip northbridge/intel/sandybridge
 
 			# Enable SATA ports 0 (HDD bay) & 1 (ODD bay) & 2 (mSATA) & 3 (eSATA) & 4 (dock)
 			register "sata_port_map" = "0x1f"
+			register "sata_hotplug_port_map" = "0x02"
+			register "esata_port_map" = "0x08"
 			# Set max SATA speed to 6.0 Gb/s
 			register "sata_interface_speed_support" = "0x3"
 
diff --git a/src/mainboard/lenovo/t520/devicetree.cb b/src/mainboard/lenovo/t520/devicetree.cb
index 379a95d..ff65dcf 100644
--- a/src/mainboard/lenovo/t520/devicetree.cb
+++ b/src/mainboard/lenovo/t520/devicetree.cb
@@ -51,7 +51,10 @@ chip northbridge/intel/sandybridge
 			register "gpi13_routing" = "2"
 
 			# Enable SATA ports 0 (HDD bay) & 1 (ODD bay) & 2 (mSATA) & 3 (eSATA) & 4 (dock)
+			# support hot plug on ODD bay and eSATA
 			register "sata_port_map" = "0x1f"
+			register "sata_hotplug_port_map" = "0x02"
+			register "esata_port_map" = "0x08"
 			# Set max SATA speed to 6.0 Gb/s
 			register "sata_interface_speed_support" = "0x3"
 
diff --git a/src/southbridge/intel/bd82x6x/chip.h b/src/southbridge/intel/bd82x6x/chip.h
index e1064a7..2a06391 100644
--- a/src/southbridge/intel/bd82x6x/chip.h
+++ b/src/southbridge/intel/bd82x6x/chip.h
@@ -48,6 +48,8 @@ struct southbridge_intel_bd82x6x_config {
 
 	/* IDE configuration */
 	uint8_t sata_port_map;
+	uint8_t sata_hotplug_port_map;
+	uint8_t esata_port_map;
 	uint32_t sata_port0_gen3_tx;
 	uint32_t sata_port1_gen3_tx;
 
diff --git a/src/southbridge/intel/bd82x6x/sata.c b/src/southbridge/intel/bd82x6x/sata.c
index d217a04..b2b599f 100644
--- a/src/southbridge/intel/bd82x6x/sata.c
+++ b/src/southbridge/intel/bd82x6x/sata.c
@@ -44,6 +44,7 @@ static void sata_init(struct device *dev)
 	/* Get the chip configuration */
 	config_t *config = dev->chip_info;
 	u8 sata_mode;
+	u8 sata_port;
 
 	printk(BIOS_DEBUG, "SATA: Initializing...\n");
 
@@ -102,7 +103,13 @@ static void sata_init(struct device *dev)
 		/* CAP (HBA Capabilities) : enable power management */
 		reg32 = read32(abar + 0x00);
 		reg32 |= 0x0c006000;  // set PSC+SSC+SALP+SSS
-		reg32 &= ~0x00020060; // clear SXS+EMS+PMS
+		reg32 &= ~0x00020040; // clear EMS+PMS
+		/* clear SXS, if no eSATA port is available, otherwise set it */
+		if (config->esata_port_map==0) {
+			reg32 &= ~0x00000020;
+		} else {
+			reg32 |= 0x00000020;
+		}
 		/* Set ISS, if available */
 		if (config->sata_interface_speed_support)
 		{
@@ -111,6 +118,8 @@ static void sata_init(struct device *dev)
 			  << 20;
 		}
 		write32(abar + 0x00, reg32);
+		reg32 = read32(abar + 0x00);
+		printk(BIOS_DEBUG, "CAP register value: 0x%08x.\n", reg32);
 		/* PI (Ports implemented) */
 		write32(abar + 0x0c, config->sata_port_map);
 		(void) read32(abar + 0x0c); /* Read back 1 */
@@ -123,6 +132,57 @@ static void sata_init(struct device *dev)
 		reg32 = read32(abar + 0xa0);
 		reg32 &= ~0x00000005;
 		write32(abar + 0xa0, reg32);
+
+		/* Enable SATA hot plug and eSATA */
+		for (sata_port = 0; sata_port < 6; sata_port++) {
+			u8 *port_control_reg = abar + 0x100 + 0x80 * sata_port;
+			u8 *PxSCTL = port_control_reg + 0x2c;
+			u8 *PxCMD = port_control_reg + 0x18;
+			u8 *PxIE = port_control_reg + 0x14;
+			if (((1<<sata_port)&config->sata_hotplug_port_map)
+				 || ((1<<sata_port)&config->esata_port_map)) {
+				printk(BIOS_DEBUG, "port %d:\n", sata_port);
+				/* set PxSCTL.IPM (bit 8-11) to 3,
+				 * disable transitions to PARTIAL and SLUMBER states
+				 */
+				reg32 = read32(PxSCTL);
+				printk(BIOS_DEBUG, "changing PxSCTL(0x%03x): 0x%08x.\n", (int)(PxSCTL-abar), reg32);
+				reg32 |= 0x00000300;
+				write32(PxSCTL, reg32);
+				reg32 = read32(PxSCTL);
+				printk(BIOS_DEBUG, "new PxSCTL: 0x%08x.\n", reg32);
+
+				/* clear PxCMD.ALPE (bit 26) to disable
+				 * aggressive power management
+				 */
+				reg32 = read32(PxCMD);
+				printk(BIOS_DEBUG, "changing PxCMD(0x%03x): 0x%08x.\n", (int)(PxCMD-abar), reg32);
+				reg32 &= ~0x04000000;
+				/* ESP is mutually exclusive with HPCP, according to
+					Serial ATA AHCI 1.3.1 Specification
+				*/
+				if ((1<<sata_port)&config->sata_hotplug_port_map) {
+					/* set PxCMD.HPCP(bit 18), PxCMD.MPSP(bit 19) */
+					reg32 |= 0x000c0000;
+				} else {
+					/* set PxCMD.ESP(bit 21) */
+					reg32 |= 0x00200000;
+				}
+				write32(PxCMD, reg32);
+				reg32 = read32(PxCMD);
+				printk(BIOS_DEBUG, "new PxCMD: 0x%08x.\n", reg32);
+
+				/* set PxIE.PRCE (bit 22) to enable interrupts on
+				 * hot plug removals
+				 */
+				reg32 = read32(PxIE);
+				printk(BIOS_DEBUG, "changing PxIE(0x%03x): 0x%08x.\n", (int)(PxIE-abar), reg32);
+				reg32 |= 0x00400000;
+				write32(PxIE, reg32);
+				reg32 = read32(PxIE);
+				printk(BIOS_DEBUG, "new PxIE: 0x%08x.\n", reg32);
+			}
+		}
 	} else {
 	        /* IDE */
 		printk(BIOS_DEBUG, "SATA: Controller in plain mode.\n");



More information about the coreboot-gerrit mailing list