[coreboot] New patch to review for coreboot: d8c86a5 lynxpoint: Update IOBP programming method

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Wed Mar 13 02:42:21 CET 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2694

-gerrit

commit d8c86a5ed40a2a87283b5032657565af43031683
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Thu Jan 10 13:19:23 2013 -0800

    lynxpoint: Update IOBP programming method
    
    This follows the new method outlined in the LPT BWG.
    
    It is also very pedantic about its operation so it
    is easier to read and compare against the docs and
    the reference code implementation.
    
    Change-Id: I235d634cded0c75ec0e9f53488f5b366107a18fa
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/southbridge/intel/lynxpoint/pch.c | 80 +++++++++++++++++++++++++----------
 src/southbridge/intel/lynxpoint/pch.h | 10 +++--
 2 files changed, 65 insertions(+), 25 deletions(-)

diff --git a/src/southbridge/intel/lynxpoint/pch.c b/src/southbridge/intel/lynxpoint/pch.c
index e992fb2..1fb4915 100644
--- a/src/southbridge/intel/lynxpoint/pch.c
+++ b/src/southbridge/intel/lynxpoint/pch.c
@@ -116,56 +116,92 @@ static void pch_hide_devfn(unsigned devfn)
 #define IOBP_RETRY 1000
 static inline int iobp_poll(void)
 {
-	unsigned try = IOBP_RETRY;
-	u32 data;
+	unsigned try;
 
-	while (try--) {
-		data = RCBA32(IOBPS);
-		if ((data & 1) == 0)
+	for (try = IOBP_RETRY; try > 0; try--) {
+		u16 status = RCBA16(IOBPS);
+		if ((status & IOBPS_READY) == 0)
 			return 1;
 		udelay(10);
 	}
 
-	printk(BIOS_ERR, "IOBP timeout\n");
+	printk(BIOS_ERR, "IOBP: timeout waiting for transaction to complete\n");
 	return 0;
 }
 
-void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
+static u32 pch_iobp_read(u32 address)
 {
-	u32 data;
+	u16 status;
+
+	if (!iobp_poll())
+		return 0;
 
 	/* Set the address */
 	RCBA32(IOBPIRI) = address;
 
 	/* READ OPCODE */
-	RCBA32(IOBPS) = IOBPS_RW_BX;
-	if (!iobp_poll())
-		return;
+	status = RCBA16(IOBPS);
+	status &= ~IOBPS_MASK;
+	status |= IOBPS_READ;
+	RCBA16(IOBPS) = status;
+
+	/* Undocumented magic */
+	RCBA16(IOBPU) = IOBPU_MAGIC;
+
+	/* Set ready bit */
+	status = RCBA16(IOBPS);
+	status |= IOBPS_READY;
+	RCBA16(IOBPS) = status;
 
-	/* Read IOBP data */
-	data = RCBA32(IOBPD);
 	if (!iobp_poll())
-		return;
+		return 0;
 
 	/* Check for successful transaction */
-	if ((RCBA32(IOBPS) & 0x6) != 0) {
-		printk(BIOS_ERR, "IOBP read 0x%08x failed\n", address);
-		return;
+	status = RCBA16(IOBPS);
+	if (status & IOBPS_TX_MASK) {
+		printk(BIOS_ERR, "IOBP: read 0x%08x failed\n", address);
+		return 0;
 	}
 
+	/* Read IOBP data */
+	return RCBA32(IOBPD);
+}
+
+void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
+{
+	u16 status;
+	u32 data = pch_iobp_read(address);
+
+	/* WRITE OPCODE */
+	status = RCBA16(IOBPS);
+	status &= ~IOBPS_MASK;
+	status |= IOBPS_WRITE;
+	RCBA16(IOBPS) = status;
+
 	/* Update the data */
 	data &= andvalue;
 	data |= orvalue;
+	RCBA32(IOBPD) = data;
+
+	/* Undocumented magic */
+	RCBA16(IOBPU) = IOBPU_MAGIC;
+
+	/* Set ready bit */
+	status = RCBA16(IOBPS);
+	status |= IOBPS_READY;
+	RCBA16(IOBPS) = status;
 
-	/* WRITE OPCODE */
-	RCBA32(IOBPS) = IOBPS_RW_BX;
 	if (!iobp_poll())
 		return;
 
-	/* Write IOBP data */
-	RCBA32(IOBPD) = data;
-	if (!iobp_poll())
+	/* Check for successful transaction */
+	status = RCBA16(IOBPS);
+	if (status & IOBPS_TX_MASK) {
+		printk(BIOS_ERR, "IOBP: write 0x%08x failed\n", address);
 		return;
+	}
+
+	printk(BIOS_INFO, "IOBP: set 0x%08x to 0x%08x\n", address, data);
 }
 
 /* Check if any port in set X to X+3 is enabled */
diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
index eea3465..229b795 100644
--- a/src/southbridge/intel/lynxpoint/pch.h
+++ b/src/southbridge/intel/lynxpoint/pch.h
@@ -413,9 +413,13 @@ unsigned get_gpios(const int *gpio_num_array);
 #define IOBPIRI		0x2330
 #define IOBPD		0x2334
 #define IOBPS		0x2338
-#define  IOBPS_RW_BX    ((1 << 9)|(1 << 10))
-#define  IOBPS_WRITE_AX	((1 << 9)|(1 << 10))
-#define  IOBPS_READ_AX	((1 << 8)|(1 << 9)|(1 << 10))
+#define  IOBPS_READY	0x0001
+#define  IOBPS_TX_MASK	0x0006
+#define  IOBPS_MASK     0xff00
+#define  IOBPS_READ     0x0600
+#define  IOBPS_WRITE	0x0700
+#define IOBPU		0x233a
+#define  IOBPU_MAGIC	0xf000
 
 #define D31IP		0x3100	/* 32bit */
 #define D31IP_TTIP	24	/* Thermal Throttle Pin */



More information about the coreboot mailing list