===================================================================
@@ -692,7 +692,9 @@
/* Read SPI_BaseAddr */
tmp = pci_read_long(dev, 0xa0);
- tmp &= 0xfffffff0; /* remove low 4 bits (reserved) */
+ printf_debug("AltSpiCSEnable=%i, SpiRomEnable=%i, AbortEnable=%i\n",
+ tmp & 0x1, (tmp & 0x2) >> 1, (tmp & 0x4) >> 2);
+ tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
printf_debug("SPI base address is at 0x%x\n", tmp);
/* If the BAR has address 0, it is unlikely SPI is used. */
@@ -704,6 +706,13 @@
/* The low bits of the SPI base address are used as offset into the mapped page */
sb600_spibar += tmp & 0xfff;
+ tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2;
+ printf_debug("PrefetchEnSPIFromIMC=%i, ", tmp);
+
+ tmp = pci_read_byte(dev, 0xbb);
+ printf_debug("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n",
+ tmp & 0x1, (tmp & 0x20) >> 5);
+
/* Look for the SMBus device. */
smbus_dev = pci_dev_find(0x1002, 0x4385);
===================================================================
@@ -104,6 +104,7 @@
const unsigned char *writearr, unsigned char *readarr)
{
int count;
+ int tmp;
/* First byte is cmd which can not being sent through FIFO. */
unsigned char cmd = *writearr++;
@@ -124,15 +125,24 @@
return SPI_INVALID_LENGTH;
}
+ tmp = mmio_readb(sb600_spibar + 1);
+ printf_debug("%s, old readcnt=%i, old writecnt=%i\n",
+ __func__, tmp >> 4, tmp & 0xf);
+ mmio_writeb(readcnt << 4 | (writecnt), sb600_spibar + 1);
mmio_writeb(cmd, sb600_spibar + 0);
- mmio_writeb(readcnt << 4 | (writecnt), sb600_spibar + 1);
/* Before we use the FIFO, reset it first. */
reset_internal_fifo_pointer();
+ /* Scrub the FIFO by writing a stream of 0xab. */
+ for (count = 0; count < 8; count++)
+ mmio_writeb(0xab, sb600_spibar + 0xC);
+ reset_internal_fifo_pointer();
+
/* Send the write byte to FIFO. */
for (count = 0; count < writecnt; count++, writearr++) {
printf_debug(" [%x]", *writearr);
+ /* FIXME: Can we rely on auto-posting these writes or do we have to issue a read afterwards? */
mmio_writeb(*writearr, sb600_spibar + 0xC);
}
printf_debug("\n");
@@ -150,19 +160,28 @@
* received byte. Here we just reset the FIFO pointer, skip the
* writecnt, is there anyone who have anther method to replace it?
*/
+ printf_debug("The FIFO pointer before reset is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07);
reset_internal_fifo_pointer();
for (count = 0; count < writecnt; count++) {
- cmd = mmio_readb(sb600_spibar + 0xC); /* Skip the byte we send. */
+ cmd = mmio_readb(sb600_spibar + 0xC); /* Skip the bytes we send. */
printf_debug("[ %2x]", cmd);
}
- printf_debug("The FIFO pointer 6 is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07);
+ printf_debug("The FIFO pointer after skipping is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07);
for (count = 0; count < readcnt; count++, readarr++) {
*readarr = mmio_readb(sb600_spibar + 0xC);
printf_debug("[%02x]", *readarr);
}
printf_debug("\n");
+ printf_debug("The FIFO pointer after reading is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07);
+ printf_debug("Dumping everything that's left in the FIFO\n");
+ for (count = 0; count < 8; count++) {
+ cmd = mmio_readb(sb600_spibar + 0xC);
+ printf_debug("[ %2x]", cmd);
+ }
+ printf_debug("The FIFO pointer after dumping is %d.\n", mmio_readb(sb600_spibar + 0xd) & 0x07);
+
return 0;
}