[coreboot-gerrit] Change in coreboot[master]: soc/amd/common: Relocate spi.c

John E. Kabat Jr. (Code Review) gerrit at coreboot.org
Tue Oct 17 03:25:58 CEST 2017


Hello frank vibrans,

I'd like you to do a code review. Please visit

    https://review.coreboot.org/22062

to review the following change.


Change subject: soc/amd/common: Relocate spi.c
......................................................................

soc/amd/common: Relocate spi.c

Relocate spi.c from soc/amd/common to soc/amd/common/block/spi. Also
change the associated make files.

Change-Id: I24085fd6ec1d5fedb7269d935fd95a46f00ae687
Signed-off-by: Frank Vibrans <frank.vibrans at scarletltd.com>
---
M src/soc/amd/common/Makefile.inc
A src/soc/amd/common/block/include/amdblocks/spi.h
A src/soc/amd/common/block/spi/Makefile.inc
A src/soc/amd/common/block/spi/spi.c
D src/soc/amd/common/spi.c
M src/soc/amd/stoneyridge/Kconfig
6 files changed, 250 insertions(+), 40 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/62/22062/1

diff --git a/src/soc/amd/common/Makefile.inc b/src/soc/amd/common/Makefile.inc
index aa27512..0816287 100644
--- a/src/soc/amd/common/Makefile.inc
+++ b/src/soc/amd/common/Makefile.inc
@@ -15,7 +15,6 @@
 ramstage-y += amd_pci_util.c
 ramstage-y += def_callouts.c
 ramstage-y += heapmanager.c
-ramstage-$(CONFIG_SPI_FLASH) += spi.c
 
 subdirs-$(CONFIG_SOC_AMD_COMMON_BLOCK) += block
 
diff --git a/src/soc/amd/common/block/include/amdblocks/spi.h b/src/soc/amd/common/block/include/amdblocks/spi.h
new file mode 100644
index 0000000..4b1bb06
--- /dev/null
+++ b/src/soc/amd/common/block/include/amdblocks/spi.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __AMD_SPI_H__
+#define __AMD_SPI_H__
+
+#include <stdint.h>
+#include <compiler.h>
+
+#define SPI_PCI_DEV		0x14
+#define SPI_PCI_FN		0x03
+
+/* SPI registers in PCI space */
+#define SPI_PCI_BASE_ADDR	0xa0
+
+/* SPI registers in MMIO space */
+#define SPI_REG_OPCODE		0x0
+#define SPI_REG_CNTRL01		0x1
+#define SPI_REG_CNTRL02		0x2
+# define CNTRL02_FIFO_RESET	(1 << 4)
+# define CNTRL02_EXEC_OPCODE	(1 << 0)
+#define SPI_REG_CNTRL03		0x3
+# define CNTRL03_SPIBUSY	(1 << 7)
+#define SPI_REG_FIFO		0xc
+#define SPI_REG_CNTRL11		0xd
+# define CNTRL11_FIFOPTR_MASK	0x07
+
+#define SPI_REG_EXT_IDX		0x1e
+#define SPI_REG_EXT_DATA	0x1f
+# define SPI_REG1F_DDR_CMD	0x00
+# define SPI_REG1F_QDR_CMD	0x01
+# define SPI_REG1F_DPR_CMD	0x02
+# define SPI_REG1F_QPR_CMD	0x03
+# define SPI_REG1F_MODE_BYTE	0x04
+# define SPI_REG1F_TX_BYTE_CNT	0x05
+# define SPI_REG1F_RX_BYTE_CNT	0x06
+# define SPI_REG1F_FIFO_PTR	0x07
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE)
+#define AMD_SB_SPI_TX_LEN	64
+#else
+#define AMD_SB_SPI_TX_LEN	8
+#endif
+
+/* TODO: Replace this with APM_CNT_GNVS_UPDATE */
+#define APM_CNT_SPI_SMM_INIT		0xd9
+
+/* SPI related functions called from AMD vendorcode */
+void spi_SaveS3info(uint32_t pos, size_t size, uint8_t *buf, u32 len);
+
+#endif /* __AMD_SPI_H__ */
diff --git a/src/soc/amd/common/block/spi/Makefile.inc b/src/soc/amd/common/block/spi/Makefile.inc
new file mode 100644
index 0000000..bcb8c9c
--- /dev/null
+++ b/src/soc/amd/common/block/spi/Makefile.inc
@@ -0,0 +1,2 @@
+romstage-$(CONFIG_SPI_FLASH) += spi.c
+ramstage-$(CONFIG_SPI_FLASH) += spi.c
diff --git a/src/soc/amd/common/block/spi/spi.c b/src/soc/amd/common/block/spi/spi.c
new file mode 100644
index 0000000..d0fa766
--- /dev/null
+++ b/src/soc/amd/common/block/spi/spi.c
@@ -0,0 +1,184 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <spi_flash.h>
+#include <spi-generic.h>
+#include <amdblocks/spi.h>
+
+void spi_SaveS3info(uint32_t pos, size_t size, uint8_t *buf, u32 len)
+{
+	struct spi_flash *flash = NULL;
+
+	spi_init();
+	int retval = spi_flash_probe(0, 0, flash);
+	if (retval) {
+		printk(BIOS_DEBUG, "Could not find SPI device\n");
+		/* Dont make flow stop. */
+		return;
+	}
+
+	spi_flash_volatile_group_begin(flash);
+
+	spi_flash_erase(flash, pos, size);
+	spi_flash_write(flash, pos, sizeof(len), &len);
+	spi_flash_write(flash, pos + sizeof(len), len, buf);
+
+	spi_flash_volatile_group_end(flash);
+}
+
+static uintptr_t spibar;
+
+static inline uint8_t spi_read(uint8_t reg)
+{
+	return read8((void *)(spibar + reg));
+}
+
+static inline void spi_write(uint8_t reg, uint8_t val)
+{
+	write8((void *)(spibar + reg), val);
+}
+
+static void reset_internal_fifo_pointer(void)
+{
+	uint8_t reg8;
+
+	do {
+		reg8 = spi_read(SPI_REG_CNTRL02);
+		reg8 |= CNTRL02_FIFO_RESET;
+		spi_write(SPI_REG_CNTRL02, reg8);
+	} while (spi_read(SPI_REG_CNTRL11) & CNTRL11_FIFOPTR_MASK);
+}
+
+static void execute_command(void)
+{
+	uint8_t reg8;
+
+	reg8 = spi_read(SPI_REG_CNTRL02);
+	reg8 |= CNTRL02_EXEC_OPCODE;
+	spi_write(SPI_REG_CNTRL02, reg8);
+
+	while ((spi_read(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) &&
+	       (spi_read(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY));
+}
+
+static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,
+		size_t bytesout, void *din, size_t bytesin)
+{
+	/* First byte is cmd which can not being sent through FIFO. */
+	uint8_t cmd = read8(dout);
+	uint8_t readoffby1;
+	size_t count;
+
+	dout += 1;	/* Advance past cmd */
+	bytesout--;
+
+	/*
+	 * Check if this is a write command attempting to transfer more bytes
+	 * than the controller can handle. Iterations for writes are not
+	 * supported here because each SPI write command needs to be preceded
+	 * and followed by other SPI commands, and this sequence is controlled
+	 * by the SPI chip driver.
+	 */
+	if (bytesout > AMD_SB_SPI_TX_LEN) {
+		printk(BIOS_DEBUG, "FCH SPI: Too much to write. Does your SPI chip driver use"
+		     " spi_crop_chunk()?\n");
+		return -1;
+	}
+
+	readoffby1 = bytesout ? 0 : 1;
+
+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE)
+	spi_write(SPI_REG_EXT_IDX, SPI_REG1F_TX_BYTE_CNT);
+	spi_write(SPI_REG_EXT_DATA, bytesout); /* TxByteCount */
+	spi_write(SPI_REG_EXT_IDX, SPI_REG1F_RX_BYTE_CNT);
+	spi_write(SPI_REG_EXT_DATA, bytesin);  /* RxByteCount */
+#else
+	uint8_t readwrite = (bytesin + readoffby1) << 4 | bytesout;
+	spi_write(SPI_REG_CNTRL01, readwrite);
+#endif
+	spi_write(SPI_REG_OPCODE, cmd);
+
+	reset_internal_fifo_pointer();
+	for (count = 0; count < bytesout; count++, dout++) {
+		spi_write(SPI_REG_FIFO, *(uint8_t *)dout);
+	}
+
+	reset_internal_fifo_pointer();
+	execute_command();
+
+	reset_internal_fifo_pointer();
+	/* Skip the bytes we sent. */
+	for (count = 0; count < bytesout; count++) {
+		cmd = spi_read(SPI_REG_FIFO);
+	}
+
+	for (count = 0; count < bytesin; count++, din++) {
+		*(uint8_t *)din = spi_read(SPI_REG_FIFO);
+		write8(din, spi_read(SPI_REG_FIFO));
+	}
+
+	return 0;
+}
+
+int chipset_volatile_group_begin(const struct spi_flash *flash)
+{
+	if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM))
+		return 0;
+
+	/* ImcSleep(NULL); */
+	return 0;
+}
+
+int chipset_volatile_group_end(const struct spi_flash *flash)
+{
+	if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM))
+		return 0;
+
+	/* ImcWakeup(NULL); */
+	return 0;
+}
+
+void spi_init(void)
+{
+	device_t dev;
+
+	dev = (device_t)dev_find_slot(0, PCI_DEVFN(SPI_PCI_DEV, SPI_PCI_FN));
+	spibar = pci_read_config32(dev, SPI_PCI_BASE_ADDR) & ~0x1F;
+}
+
+static const struct spi_ctrlr spi_ctrlr = {
+	.xfer = spi_ctrlr_xfer,
+	.xfer_vector = spi_xfer_two_vectors,
+	.max_xfer_size = AMD_SB_SPI_TX_LEN,
+	.deduct_cmd_len = true,
+};
+
+const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
+	{
+		.ctrlr = &spi_ctrlr,
+		.bus_start = 0,
+		.bus_end = 0,
+	},
+};
+
+const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);
diff --git a/src/soc/amd/common/spi.c b/src/soc/amd/common/spi.c
deleted file mode 100644
index 31b686d..0000000
--- a/src/soc/amd/common/spi.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Advanced Micro Devices, Inc.
- *
- * 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.
- */
-
-#include <console/console.h>
-#include <spi-generic.h>
-#include <spi_flash.h>
-
-void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len)
-{
-	struct spi_flash *flash;
-
-	spi_init();
-	flash = spi_flash_probe(0, 0);
-	if (!flash) {
-		printk(BIOS_DEBUG, "Could not find SPI device\n");
-		/* Dont make flow stop. */
-		return;
-	}
-
-	spi_flash_volatile_group_begin(flash);
-
-	spi_flash_erase(flash, pos, size);
-	spi_flash_write(flash, pos, sizeof(len), &len);
-	spi_flash_write(flash, pos + sizeof(len), len, buf);
-
-	spi_flash_volatile_group_end(flash);
-}
diff --git a/src/soc/amd/stoneyridge/Kconfig b/src/soc/amd/stoneyridge/Kconfig
index 4bf1e57..31bcebd 100644
--- a/src/soc/amd/stoneyridge/Kconfig
+++ b/src/soc/amd/stoneyridge/Kconfig
@@ -56,6 +56,7 @@
 	select RELOCATABLE_RAMSTAGE
 	select POSTCAR_STAGE
 	select POSTCAR_CONSOLE
+	select SPI_FLASH
 	select SSE
 	select SSE2
 

-- 
To view, visit https://review.coreboot.org/22062
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I24085fd6ec1d5fedb7269d935fd95a46f00ae687
Gerrit-Change-Number: 22062
Gerrit-PatchSet: 1
Gerrit-Owner: John E. Kabat Jr. <john.kabat at scarletltd.com>
Gerrit-Reviewer: frank vibrans <frank.vibrans at scarletltd.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171017/021f9235/attachment-0001.html>


More information about the coreboot-gerrit mailing list