Patchwork A quick hack to support AMD Family 16h SOC

login
register
about
Submitter Wei Hu
Date 2013-06-27 00:34:33
Message ID <CANwcMEbR+j+_UjF2Op9rdTLMwGq-Q=izE8T-nrP_FsO_Md_U6g@mail.gmail.com>
Download mbox | patch
Permalink /patch/3968/
State Superseded
Headers show

Comments

Wei Hu - 2013-06-27 00:34:33
Hello,

In the past I posted a question at
http://www.flashrom.org/pipermail/flashrom/2013-April/010924.html
about failure to run flashrom on the new AMD SOC. It turns out the SPI
flash interface has introduced incompatible changes from SB600. I have
created a quick hack and made it available at
http://blogs.coreboot.org/blog/2013/06/26/gsoc-2013-flashrom-week-1-while1/.
Based on the discussion there I'm posting the patch here as well. Hope
it will be helpful.
A quick hack to support AMD Family 16h SOC (Kabini).
This patch is just a proof of concept and incompatible with previous generations of AMD chipset.
Tested reading and writing on ASRock IMB-A180.

Signed-off-by: Wei Hu <wei@aristanetworks.com>

Patch

Index: sb600spi.c
===================================================================
--- sb600spi.c	(revision 1680)
+++ sb600spi.c	(working copy)
@@ -56,8 +56,13 @@ 
 {
 	uint8_t tmp;
 
+#ifdef USE_THE_EXTENDED_SPIDataFifoPtr_REGISTER
+	mmio_writeb(7, sb600_spibar + 0x1e);
+	tmp = mmio_readb(sb600_spibar + 0x1f);
+#else  /* either way works */
 	tmp = mmio_readb(sb600_spibar + 0xd) & 0x07;
 	want &= 0x7;
+#endif
 	if (want != tmp) {
 		msg_perr("SB600 FIFO pointer corruption! Pointer is %d, wanted "
 			 "%d\n", tmp, want);
@@ -97,8 +102,6 @@ 
 	int count;
 	/* First byte is cmd which can not being sent through FIFO. */
 	unsigned char cmd = *writearr++;
-	unsigned int readoffby1;
-	unsigned char readwrite;
 
 	writecnt--;
 
@@ -117,15 +120,9 @@ 
 		return SPI_INVALID_LENGTH;
 	}
 
-	/* This is a workaround for a bug in SB600 and SB700. If we only send
-	 * an opcode and no additional data/address, the SPI controller will
-	 * read one byte too few from the chip. Basically, the last byte of
-	 * the chip response is discarded and will not end up in the FIFO.
-	 * It is unclear if the CS# line is set high too early as well.
-	 */
-	readoffby1 = (writecnt) ? 0 : 1;
-	readwrite = (readcnt + readoffby1) << 4 | (writecnt);
-	mmio_writeb(readwrite, sb600_spibar + 1);
+	/* Use the extended TxByteCount and RxByteCount register. */
+	mmio_writeb(writecnt, sb600_spibar + 0x48);
+	mmio_writeb(readcnt, sb600_spibar + 0x4b);
 	mmio_writeb(cmd, sb600_spibar + 0);
 
 	/* Before we use the FIFO, reset it first. */
@@ -170,8 +167,12 @@ 
 		msg_pspew("[%02x]", cmd);
 	}
 	msg_pspew("\n");
+	/*
+	Reading doesn't advance the FIFO pointer.
+
 	if (compare_internal_fifo_pointer(writecnt))
 		return SPI_PROGRAMMER_ERROR;
+	*/
 
 	msg_pspew("Reading: ");
 	for (count = 0; count < readcnt; count++, readarr++) {
@@ -179,18 +180,7 @@ 
 		msg_pspew("[%02x]", *readarr);
 	}
 	msg_pspew("\n");
-	if (reset_compare_internal_fifo_pointer(readcnt + writecnt))
-		return SPI_PROGRAMMER_ERROR;
 
-	if (mmio_readb(sb600_spibar + 1) != readwrite) {
-		msg_perr("Unexpected change in SB600 read/write count!\n");
-		msg_perr("Something else is accessing the flash chip and "
-			 "causes random corruption.\nPlease stop all "
-			 "applications and drivers and IPMI which access the "
-			 "flash chip.\n");
-		return SPI_PROGRAMMER_ERROR;
-	}
-
 	return 0;
 }