[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