Stefan Reinauer (stefan.reinauer@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@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@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 */