<p>John E. Kabat Jr. would like frank vibrans to <strong>review</strong> this change.</p><p><a href="https://review.coreboot.org/22062">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/amd/common: Relocate spi.c<br><br>Relocate spi.c from soc/amd/common to soc/amd/common/block/spi. Also<br>change the associated make files.<br><br>Change-Id: I24085fd6ec1d5fedb7269d935fd95a46f00ae687<br>Signed-off-by: Frank Vibrans <frank.vibrans@scarletltd.com><br>---<br>M src/soc/amd/common/Makefile.inc<br>A src/soc/amd/common/block/include/amdblocks/spi.h<br>A src/soc/amd/common/block/spi/Makefile.inc<br>A src/soc/amd/common/block/spi/spi.c<br>D src/soc/amd/common/spi.c<br>M src/soc/amd/stoneyridge/Kconfig<br>6 files changed, 250 insertions(+), 40 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/62/22062/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/amd/common/Makefile.inc b/src/soc/amd/common/Makefile.inc<br>index aa27512..0816287 100644<br>--- a/src/soc/amd/common/Makefile.inc<br>+++ b/src/soc/amd/common/Makefile.inc<br>@@ -15,7 +15,6 @@<br> ramstage-y += amd_pci_util.c<br> ramstage-y += def_callouts.c<br> ramstage-y += heapmanager.c<br>-ramstage-$(CONFIG_SPI_FLASH) += spi.c<br> <br> subdirs-$(CONFIG_SOC_AMD_COMMON_BLOCK) += block<br> <br>diff --git a/src/soc/amd/common/block/include/amdblocks/spi.h b/src/soc/amd/common/block/include/amdblocks/spi.h<br>new file mode 100644<br>index 0000000..4b1bb06<br>--- /dev/null<br>+++ b/src/soc/amd/common/block/include/amdblocks/spi.h<br>@@ -0,0 +1,63 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2017 Advanced Micro Devices, Inc.<br>+ *<br>+ * This program is free software; you can redistribute it and/or modify<br>+ * it under the terms of the GNU General Public License as published by<br>+ * the Free Software Foundation; version 2 of the License.<br>+ *<br>+ * This program is distributed in the hope that it will be useful,<br>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>+ * GNU General Public License for more details.<br>+ */<br>+<br>+#ifndef __AMD_SPI_H__<br>+#define __AMD_SPI_H__<br>+<br>+#include <stdint.h><br>+#include <compiler.h><br>+<br>+#define SPI_PCI_DEV           0x14<br>+#define SPI_PCI_FN               0x03<br>+<br>+/* SPI registers in PCI space */<br>+#define SPI_PCI_BASE_ADDR  0xa0<br>+<br>+/* SPI registers in MMIO space */<br>+#define SPI_REG_OPCODE            0x0<br>+#define SPI_REG_CNTRL01           0x1<br>+#define SPI_REG_CNTRL02           0x2<br>+# define CNTRL02_FIFO_RESET       (1 << 4)<br>+# define CNTRL02_EXEC_OPCODE   (1 << 0)<br>+#define SPI_REG_CNTRL03                0x3<br>+# define CNTRL03_SPIBUSY  (1 << 7)<br>+#define SPI_REG_FIFO           0xc<br>+#define SPI_REG_CNTRL11           0xd<br>+# define CNTRL11_FIFOPTR_MASK     0x07<br>+<br>+#define SPI_REG_EXT_IDX               0x1e<br>+#define SPI_REG_EXT_DATA 0x1f<br>+# define SPI_REG1F_DDR_CMD       0x00<br>+# define SPI_REG1F_QDR_CMD       0x01<br>+# define SPI_REG1F_DPR_CMD       0x02<br>+# define SPI_REG1F_QPR_CMD       0x03<br>+# define SPI_REG1F_MODE_BYTE     0x04<br>+# define SPI_REG1F_TX_BYTE_CNT   0x05<br>+# define SPI_REG1F_RX_BYTE_CNT   0x06<br>+# define SPI_REG1F_FIFO_PTR      0x07<br>+<br>+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE)<br>+#define AMD_SB_SPI_TX_LEN      64<br>+#else<br>+#define AMD_SB_SPI_TX_LEN  8<br>+#endif<br>+<br>+/* TODO: Replace this with APM_CNT_GNVS_UPDATE */<br>+#define APM_CNT_SPI_SMM_INIT                0xd9<br>+<br>+/* SPI related functions called from AMD vendorcode */<br>+void spi_SaveS3info(uint32_t pos, size_t size, uint8_t *buf, u32 len);<br>+<br>+#endif /* __AMD_SPI_H__ */<br>diff --git a/src/soc/amd/common/block/spi/Makefile.inc b/src/soc/amd/common/block/spi/Makefile.inc<br>new file mode 100644<br>index 0000000..bcb8c9c<br>--- /dev/null<br>+++ b/src/soc/amd/common/block/spi/Makefile.inc<br>@@ -0,0 +1,2 @@<br>+romstage-$(CONFIG_SPI_FLASH) += spi.c<br>+ramstage-$(CONFIG_SPI_FLASH) += spi.c<br>diff --git a/src/soc/amd/common/block/spi/spi.c b/src/soc/amd/common/block/spi/spi.c<br>new file mode 100644<br>index 0000000..d0fa766<br>--- /dev/null<br>+++ b/src/soc/amd/common/block/spi/spi.c<br>@@ -0,0 +1,184 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2012 Advanced Micro Devices, Inc.<br>+ *<br>+ * This program is free software; you can redistribute it and/or modify<br>+ * it under the terms of the GNU General Public License as published by<br>+ * the Free Software Foundation; version 2 of the License.<br>+ *<br>+ * This program is distributed in the hope that it will be useful,<br>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>+ * GNU General Public License for more details.<br>+ */<br>+<br>+#include <stdint.h><br>+#include <stdlib.h><br>+#include <string.h><br>+#include <arch/io.h><br>+#include <console/console.h><br>+#include <device/device.h><br>+#include <device/pci.h><br>+#include <device/pci_ops.h><br>+#include <spi_flash.h><br>+#include <spi-generic.h><br>+#include <amdblocks/spi.h><br>+<br>+void spi_SaveS3info(uint32_t pos, size_t size, uint8_t *buf, u32 len)<br>+{<br>+ struct spi_flash *flash = NULL;<br>+<br>+   spi_init();<br>+  int retval = spi_flash_probe(0, 0, flash);<br>+   if (retval) {<br>+                printk(BIOS_DEBUG, "Could not find SPI device\n");<br>+         /* Dont make flow stop. */<br>+           return;<br>+      }<br>+<br>+ spi_flash_volatile_group_begin(flash);<br>+<br>+    spi_flash_erase(flash, pos, size);<br>+   spi_flash_write(flash, pos, sizeof(len), &len);<br>+  spi_flash_write(flash, pos + sizeof(len), len, buf);<br>+<br>+      spi_flash_volatile_group_end(flash);<br>+}<br>+<br>+static uintptr_t spibar;<br>+<br>+static inline uint8_t spi_read(uint8_t reg)<br>+{<br>+  return read8((void *)(spibar + reg));<br>+}<br>+<br>+static inline void spi_write(uint8_t reg, uint8_t val)<br>+{<br>+    write8((void *)(spibar + reg), val);<br>+}<br>+<br>+static void reset_internal_fifo_pointer(void)<br>+{<br>+      uint8_t reg8;<br>+<br>+     do {<br>+         reg8 = spi_read(SPI_REG_CNTRL02);<br>+            reg8 |= CNTRL02_FIFO_RESET;<br>+          spi_write(SPI_REG_CNTRL02, reg8);<br>+    } while (spi_read(SPI_REG_CNTRL11) & CNTRL11_FIFOPTR_MASK);<br>+}<br>+<br>+static void execute_command(void)<br>+{<br>+       uint8_t reg8;<br>+<br>+     reg8 = spi_read(SPI_REG_CNTRL02);<br>+    reg8 |= CNTRL02_EXEC_OPCODE;<br>+ spi_write(SPI_REG_CNTRL02, reg8);<br>+<br>+ while ((spi_read(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) &&<br>+             (spi_read(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY));<br>+}<br>+<br>+static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,<br>+               size_t bytesout, void *din, size_t bytesin)<br>+{<br>+      /* First byte is cmd which can not being sent through FIFO. */<br>+       uint8_t cmd = read8(dout);<br>+   uint8_t readoffby1;<br>+  size_t count;<br>+<br>+     dout += 1;      /* Advance past cmd */<br>+       bytesout--;<br>+<br>+       /*<br>+    * Check if this is a write command attempting to transfer more bytes<br>+         * than the controller can handle. Iterations for writes are not<br>+      * supported here because each SPI write command needs to be preceded<br>+         * and followed by other SPI commands, and this sequence is controlled<br>+        * by the SPI chip driver.<br>+    */<br>+  if (bytesout > AMD_SB_SPI_TX_LEN) {<br>+               printk(BIOS_DEBUG, "FCH SPI: Too much to write. Does your SPI chip driver use"<br>+                  " spi_crop_chunk()?\n");<br>+              return -1;<br>+   }<br>+<br>+ readoffby1 = bytesout ? 0 : 1;<br>+<br>+#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE)<br>+     spi_write(SPI_REG_EXT_IDX, SPI_REG1F_TX_BYTE_CNT);<br>+   spi_write(SPI_REG_EXT_DATA, bytesout); /* TxByteCount */<br>+     spi_write(SPI_REG_EXT_IDX, SPI_REG1F_RX_BYTE_CNT);<br>+   spi_write(SPI_REG_EXT_DATA, bytesin);  /* RxByteCount */<br>+#else<br>+     uint8_t readwrite = (bytesin + readoffby1) << 4 | bytesout;<br>+    spi_write(SPI_REG_CNTRL01, readwrite);<br>+#endif<br>+      spi_write(SPI_REG_OPCODE, cmd);<br>+<br>+   reset_internal_fifo_pointer();<br>+       for (count = 0; count < bytesout; count++, dout++) {<br>+              spi_write(SPI_REG_FIFO, *(uint8_t *)dout);<br>+   }<br>+<br>+ reset_internal_fifo_pointer();<br>+       execute_command();<br>+<br>+        reset_internal_fifo_pointer();<br>+       /* Skip the bytes we sent. */<br>+        for (count = 0; count < bytesout; count++) {<br>+              cmd = spi_read(SPI_REG_FIFO);<br>+        }<br>+<br>+ for (count = 0; count < bytesin; count++, din++) {<br>+                *(uint8_t *)din = spi_read(SPI_REG_FIFO);<br>+            write8(din, spi_read(SPI_REG_FIFO));<br>+ }<br>+<br>+ return 0;<br>+}<br>+<br>+int chipset_volatile_group_begin(const struct spi_flash *flash)<br>+{<br>+       if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM))<br>+             return 0;<br>+<br>+ /* ImcSleep(NULL); */<br>+        return 0;<br>+}<br>+<br>+int chipset_volatile_group_end(const struct spi_flash *flash)<br>+{<br>+ if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM))<br>+             return 0;<br>+<br>+ /* ImcWakeup(NULL); */<br>+       return 0;<br>+}<br>+<br>+void spi_init(void)<br>+{<br>+   device_t dev;<br>+<br>+     dev = (device_t)dev_find_slot(0, PCI_DEVFN(SPI_PCI_DEV, SPI_PCI_FN));<br>+        spibar = pci_read_config32(dev, SPI_PCI_BASE_ADDR) & ~0x1F;<br>+}<br>+<br>+static const struct spi_ctrlr spi_ctrlr = {<br>+ .xfer = spi_ctrlr_xfer,<br>+      .xfer_vector = spi_xfer_two_vectors,<br>+ .max_xfer_size = AMD_SB_SPI_TX_LEN,<br>+  .deduct_cmd_len = true,<br>+};<br>+<br>+const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {<br>+       {<br>+            .ctrlr = &spi_ctrlr,<br>+             .bus_start = 0,<br>+              .bus_end = 0,<br>+        },<br>+};<br>+<br>+const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);<br>diff --git a/src/soc/amd/common/spi.c b/src/soc/amd/common/spi.c<br>deleted file mode 100644<br>index 31b686d..0000000<br>--- a/src/soc/amd/common/spi.c<br>+++ /dev/null<br>@@ -1,39 +0,0 @@<br>-/*<br>- * This file is part of the coreboot project.<br>- *<br>- * Copyright (C) 2012 Advanced Micro Devices, Inc.<br>- *<br>- * This program is free software; you can redistribute it and/or modify<br>- * it under the terms of the GNU General Public License as published by<br>- * the Free Software Foundation; version 2 of the License.<br>- *<br>- * This program is distributed in the hope that it will be useful,<br>- * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>- * GNU General Public License for more details.<br>- */<br>-<br>-#include <console/console.h><br>-#include <spi-generic.h><br>-#include <spi_flash.h><br>-<br>-void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len)<br>-{<br>-      struct spi_flash *flash;<br>-<br>-  spi_init();<br>-  flash = spi_flash_probe(0, 0);<br>-       if (!flash) {<br>-                printk(BIOS_DEBUG, "Could not find SPI device\n");<br>-         /* Dont make flow stop. */<br>-           return;<br>-      }<br>-<br>- spi_flash_volatile_group_begin(flash);<br>-<br>-    spi_flash_erase(flash, pos, size);<br>-   spi_flash_write(flash, pos, sizeof(len), &len);<br>-  spi_flash_write(flash, pos + sizeof(len), len, buf);<br>-<br>-      spi_flash_volatile_group_end(flash);<br>-}<br>diff --git a/src/soc/amd/stoneyridge/Kconfig b/src/soc/amd/stoneyridge/Kconfig<br>index 4bf1e57..31bcebd 100644<br>--- a/src/soc/amd/stoneyridge/Kconfig<br>+++ b/src/soc/amd/stoneyridge/Kconfig<br>@@ -56,6 +56,7 @@<br>      select RELOCATABLE_RAMSTAGE<br>   select POSTCAR_STAGE<br>  select POSTCAR_CONSOLE<br>+       select SPI_FLASH<br>      select SSE<br>    select SSE2<br> <br></pre><p>To view, visit <a href="https://review.coreboot.org/22062">change 22062</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/22062"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I24085fd6ec1d5fedb7269d935fd95a46f00ae687 </div>
<div style="display:none"> Gerrit-Change-Number: 22062 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: John E. Kabat Jr. <john.kabat@scarletltd.com> </div>
<div style="display:none"> Gerrit-Reviewer: frank vibrans <frank.vibrans@scarletltd.com> </div>