[coreboot] Patch set updated for coreboot: 3bc3bbe SPI: Add early romstage SPI driver using hardware sequencing

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Mon Nov 12 03:54:58 CET 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1777

-gerrit

commit 3bc3bbe874d4f994b5881ced233de8728f89a1f2
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Thu Oct 11 13:04:14 2012 -0700

    SPI: Add early romstage SPI driver using hardware sequencing
    
    This is a basic romstage driver that can be used for the
    MRC cache code on systems where we do not have the MRC cache
    stored in a flash region that is memory mapped.
    
    It uses the hardware sequencing interface to avoid having
    to know anything about the flash chip itself.
    
    BUG=chrome-os-partner:15031
    BRANCH=stout
    TEST=manual: this was tested with debug code added to romstage
    that attempted to read the MRC cache at offset 0x3e0000.
    
    SPI READ offset=003e0000 size=64 buffer=ff7fba00
    SPI ADDR 0x003e0000
    SPI HSFC 0x3f00
    SPI READ: 0=4443524d
    SPI READ: 1=00000bb0
    SPI READ: 2=00008e24
    SPI READ: 3=00000000
    SPI READ: 4=001c8bbb
    SPI READ: 5=0c206466
    SPI READ: 6=0a043220
    SPI READ: 7=000058b4
    SPI READ: 8=00000000
    SPI READ: 9=00000000
    SPI READ: 10=00100000
    SPI READ: 11=00100005
    SPI READ: 12=20202025
    SPI READ: 13=000e0001
    SPI READ: 14=00000000
    SPI READ: 15=00000000
    
    Change-Id: I5f78f53111f912ff5dda52bbf90fdc1824b82681
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/southbridge/intel/bd82x6x/Makefile.inc |   1 +
 src/southbridge/intel/bd82x6x/early_spi.c  | 115 +++++++++++++++++++++++++++++
 src/southbridge/intel/bd82x6x/pch.h        |  15 ++++
 3 files changed, 131 insertions(+)

diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc
index c588341..9ffed9b 100644
--- a/src/southbridge/intel/bd82x6x/Makefile.inc
+++ b/src/southbridge/intel/bd82x6x/Makefile.inc
@@ -44,4 +44,5 @@ romstage-$(CONFIG_USBDEBUG) += usb_debug.c
 ramstage-$(CONFIG_USBDEBUG) += usb_debug.c
 smm-$(CONFIG_USBDEBUG) += usb_debug.c
 romstage-y += reset.c
+romstage-y += early_spi.c
 
diff --git a/src/southbridge/intel/bd82x6x/early_spi.c b/src/southbridge/intel/bd82x6x/early_spi.c
new file mode 100644
index 0000000..8fe5161
--- /dev/null
+++ b/src/southbridge/intel/bd82x6x/early_spi.c
@@ -0,0 +1,115 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include <delay.h>
+#include "pch.h"
+
+#define SPI_DELAY 10     /* 10us */
+#define SPI_RETRY 200000 /* 2s */
+
+static int early_spi_read_block(u32 offset, u8 size, u8 *buffer)
+{
+	u32 *ptr32 = (u32*)buffer;
+	u32 i;
+
+	/* Clear status bits */
+	RCBA16(SPIBAR_HSFS) |= SPIBAR_HSFS_AEL | SPIBAR_HSFS_FCERR |
+		SPIBAR_HSFS_FDONE;
+
+	if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) {
+		printk(BIOS_ERR, "SPI ERROR: transaction in progress\n");
+		return -1;
+	}
+
+	/* Set flash address */
+	RCBA32(SPIBAR_FADDR) = offset;
+
+	/* Setup read transaction */
+	RCBA16(SPIBAR_HSFC) = SPIBAR_HSFC_BYTE_COUNT(size) |
+		SPIBAR_HSFC_CYCLE_READ;
+
+	/* Start transactinon */
+	RCBA16(SPIBAR_HSFC) |= SPIBAR_HSFC_GO;
+
+	/* Wait for completion */
+	for (i = 0; i < SPI_RETRY; i++) {
+		if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) {
+			/* Cycle in progress, wait 1ms */
+			udelay(SPI_DELAY);
+			continue;
+		}
+
+		if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_AEL) {
+			printk(BIOS_ERR, "SPI ERROR: Access Error\n");
+			return -1;
+
+		}
+
+		if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) {
+			printk(BIOS_ERR, "SPI ERROR: Flash Cycle Error\n");
+			return -1;
+		}
+		break;
+	}
+
+	if (i >= SPI_RETRY) {
+		printk(BIOS_ERR, "SPI ERROR: Timeout\n");
+		return -1;
+	}
+
+	/* Read the data */
+	for (i = 0; i < size; i+=sizeof(u32)) {
+		if (size-i >= 4) {
+			/* reading >= dword */
+			*ptr32++ = RCBA32(SPIBAR_FDATA(i/sizeof(u32)));
+		} else {
+			/* reading < dword */
+			u8 j, *ptr8 = (u8*)ptr32;
+			u32 temp = RCBA32(SPIBAR_FDATA(i/sizeof(u32)));
+			for (j = 0; j < (size-i); j++) {
+				*ptr8++ = temp & 0xff;
+				temp >>= 8;
+			}
+		}
+	}
+
+	return size;
+}
+
+int early_spi_read(u32 offset, u32 size, u8 *buffer)
+{
+	u32 current = 0;
+
+	while (size > 0) {
+		u8 count = (size < 64) ? size : 64;
+		if (early_spi_read_block(offset + current, count,
+					 buffer + current) < 0)
+			return -1;
+		size -= count;
+		current += count;
+	}
+
+	return 0;
+}
diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h
index 8481554..9f9f876 100644
--- a/src/southbridge/intel/bd82x6x/pch.h
+++ b/src/southbridge/intel/bd82x6x/pch.h
@@ -71,6 +71,7 @@ void pch_log_state(void);
 void enable_smbus(void);
 void enable_usb_bar(void);
 int smbus_read_byte(unsigned device, unsigned address);
+int early_spi_read(u32 offset, u32 size, u8 *buffer);
 #endif
 #endif
 
@@ -539,5 +540,19 @@ int smbus_read_byte(unsigned device, unsigned address);
 
 #define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */
 
+#define SPIBAR_HSFS                 0x3804   /* SPI hardware sequence status */
+#define  SPIBAR_HSFS_SCIP           (1 << 5) /* SPI Cycle In Progress */
+#define  SPIBAR_HSFS_AEL            (1 << 2) /* SPI Access Error Log */
+#define  SPIBAR_HSFS_FCERR          (1 << 1) /* SPI Flash Cycle Error */
+#define  SPIBAR_HSFS_FDONE          (1 << 0) /* SPI Flash Cycle Done */
+#define SPIBAR_HSFC                 0x3806   /* SPI hardware sequence control */
+#define  SPIBAR_HSFC_BYTE_COUNT(c)  (((c - 1) & 0x3f) << 8)
+#define  SPIBAR_HSFC_CYCLE_READ     (0 << 1) /* Read cycle */
+#define  SPIBAR_HSFC_CYCLE_WRITE    (2 << 1) /* Write cycle */
+#define  SPIBAR_HSFC_CYCLE_ERASE    (3 << 1) /* Erase cycle */
+#define  SPIBAR_HSFC_GO             (1 << 0) /* GO: start SPI transaction */
+#define SPIBAR_FADDR                0x3808   /* SPI flash address */
+#define SPIBAR_FDATA(n)             (0x3810 + (4 * n)) /* SPI flash data */
+
 #endif /* __ACPI__ */
 #endif				/* SOUTHBRIDGE_INTEL_BD82X6X_PCH_H */




More information about the coreboot mailing list