From b05b9e100a9dd1c1c66963e59bffe4b9ea32f8e4 Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Thu, 22 Jul 2010 18:04:19 +0000 Subject: Move SB600 SPI initialization to sb600spi.c Corresponding to flashrom svn r1099. Signed-off-by: Michael Karcher Acked-by: Carl-Daniel Hailfinger --- sb600spi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'sb600spi.c') diff --git a/sb600spi.c b/sb600spi.c index caf1a99..3efdd5d 100644 --- a/sb600spi.c +++ b/sb600spi.c @@ -40,7 +40,7 @@ *}; */ -uint8_t *sb600_spibar = NULL; +static uint8_t *sb600_spibar = NULL; int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { @@ -152,4 +152,86 @@ int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt, return 0; } +int sb600_probe_spi(struct pci_dev *dev) +{ + struct pci_dev *smbus_dev; + uint32_t tmp; + uint8_t reg; + /* Read SPI_BaseAddr */ + tmp = pci_read_long(dev, 0xa0); + tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */ + msg_pdbg("SPI base address is at 0x%x\n", tmp); + + /* If the BAR has address 0, it is unlikely SPI is used. */ + if (!tmp) + return 0; + + /* Physical memory has to be mapped at page (4k) boundaries. */ + sb600_spibar = physmap("SB600 SPI registers", tmp & 0xfffff000, + 0x1000); + /* The low bits of the SPI base address are used as offset into + * the mapped page. + */ + sb600_spibar += tmp & 0xfff; + + tmp = pci_read_long(dev, 0xa0); + msg_pdbg("AltSpiCSEnable=%i, SpiRomEnable=%i, " + "AbortEnable=%i\n", tmp & 0x1, (tmp & 0x2) >> 1, + (tmp & 0x4) >> 2); + tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2; + msg_pdbg("PrefetchEnSPIFromIMC=%i, ", tmp); + + tmp = pci_read_byte(dev, 0xbb); + msg_pdbg("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n", + tmp & 0x1, (tmp & 0x20) >> 5); + tmp = mmio_readl(sb600_spibar); + msg_pdbg("SpiArbEnable=%i, SpiAccessMacRomEn=%i, " + "SpiHostAccessRomEn=%i, ArbWaitCount=%i, " + "SpiBridgeDisable=%i, DropOneClkOnRd=%i\n", + (tmp >> 19) & 0x1, (tmp >> 22) & 0x1, + (tmp >> 23) & 0x1, (tmp >> 24) & 0x7, + (tmp >> 27) & 0x1, (tmp >> 28) & 0x1); + + /* Look for the SMBus device. */ + smbus_dev = pci_dev_find(0x1002, 0x4385); + + if (!smbus_dev) { + msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n"); + return ERROR_NONFATAL; + } + + /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */ + /* GPIO11/SPI_DO and GPIO12/SPI_DI status */ + reg = pci_read_byte(smbus_dev, 0xAB); + reg &= 0xC0; + msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO"); + msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI"); + if (reg != 0x00) { + msg_pdbg("Not enabling SPI"); + return 0; + } + /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */ + reg = pci_read_byte(smbus_dev, 0x83); + reg &= 0xC0; + msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD"); + msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS"); + /* SPI_HOLD is not used on all boards, filter it out. */ + if ((reg & 0x80) != 0x00) { + msg_pdbg("Not enabling SPI"); + return 0; + } + /* GPIO47/SPI_CLK status */ + reg = pci_read_byte(smbus_dev, 0xA7); + reg &= 0x40; + msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK"); + if (reg != 0x00) { + msg_pdbg("Not enabling SPI"); + return 0; + } + + buses_supported |= CHIP_BUSTYPE_SPI; + spi_controller = SPI_CONTROLLER_SB600; + return 0; +} + #endif -- cgit v1.1