From 7302d1e4cec1149a3da61824497160cea514e2ca Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 10 Jan 2013 13:19:23 -0800 Subject: 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 Reviewed-on: http://review.coreboot.org/2694 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich --- src/southbridge/intel/lynxpoint/pch.c | 80 +++++++++++++++++++++++++---------- src/southbridge/intel/lynxpoint/pch.h | 10 +++-- 2 files changed, 65 insertions(+), 25 deletions(-) (limited to 'src/southbridge/intel/lynxpoint') diff --git a/src/southbridge/intel/lynxpoint/pch.c b/src/southbridge/intel/lynxpoint/pch.c index c4a3acf8b6..c2765e91eb 100644 --- a/src/southbridge/intel/lynxpoint/pch.c +++ b/src/southbridge/intel/lynxpoint/pch.c @@ -113,56 +113,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 d00ee621f6..3738a13dbd 100644 --- a/src/southbridge/intel/lynxpoint/pch.h +++ b/src/southbridge/intel/lynxpoint/pch.h @@ -355,9 +355,13 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer); #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 */ -- cgit v1.2.3