<p>Tristan Hsieh has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/27497">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mediatek: Refactor SPI code among similar SOCs<br><br>Refactor SPI code which will be reused amon similar SOCs.<br><br>BUG=b:80501386<br>BRANCH=none<br>TEST=Boots correctly on Elm<br><br>Change-Id: If5a6c554dc8361e729cf5c464325b97b2bfb7098<br>Signed-off-by: Tristan Shieh <tristan.shieh@mediatek.com><br>---<br>A src/soc/mediatek/common/include/soc/spi_common.h<br>A src/soc/mediatek/common/spi.c<br>M src/soc/mediatek/mt8173/Makefile.inc<br>M src/soc/mediatek/mt8173/include/soc/spi.h<br>M src/soc/mediatek/mt8173/spi.c<br>5 files changed, 381 insertions(+), 333 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/97/27497/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/mediatek/common/include/soc/spi_common.h b/src/soc/mediatek/common/include/soc/spi_common.h</span><br><span>new file mode 100644</span><br><span>index 0000000..0b0ea1f</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/mediatek/common/include/soc/spi_common.h</span><br><span>@@ -0,0 +1,92 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 MediaTek Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef MTK_COMMON_SPI_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define MTK_COMMON_SPI_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <spi-generic.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*SPI_CFG1_REG*/</span><br><span style="color: hsl(120, 100%, 40%);">+enum {</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_CFG1_CS_IDLE_SHIFT = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+   SPI_CFG1_PACKET_LOOP_SHIFT = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+       SPI_CFG1_PACKET_LENGTH_SHIFT = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_CFG1_CS_IDLE_MASK = 0xff << SPI_CFG1_CS_IDLE_SHIFT,</span><br><span style="color: hsl(120, 100%, 40%);">+ SPI_CFG1_PACKET_LOOP_MASK = 0xff << SPI_CFG1_PACKET_LOOP_SHIFT,</span><br><span style="color: hsl(120, 100%, 40%);">+ SPI_CFG1_PACKET_LENGTH_MASK = 0x3ff << SPI_CFG1_PACKET_LENGTH_SHIFT,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum {</span><br><span style="color: hsl(120, 100%, 40%);">+      SPI_CMD_ACT_SHIFT = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_RESUME_SHIFT = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+     SPI_CMD_RST_SHIFT = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_PAUSE_EN_SHIFT = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+   SPI_CMD_DEASSERT_SHIFT = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+   SPI_CMD_CPHA_SHIFT = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+       SPI_CMD_CPOL_SHIFT = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+       SPI_CMD_RX_DMA_SHIFT = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+    SPI_CMD_TX_DMA_SHIFT = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+    SPI_CMD_TXMSBF_SHIFT = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+    SPI_CMD_RXMSBF_SHIFT = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+    SPI_CMD_RX_ENDIAN_SHIFT = 14,</span><br><span style="color: hsl(120, 100%, 40%);">+ SPI_CMD_TX_ENDIAN_SHIFT = 15,</span><br><span style="color: hsl(120, 100%, 40%);">+ SPI_CMD_FINISH_IE_SHIFT = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+ SPI_CMD_PAUSE_IE_SHIFT = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_ACT_EN = BIT(SPI_CMD_ACT_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+      SPI_CMD_RESUME_EN = BIT(SPI_CMD_RESUME_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_RST_EN = BIT(SPI_CMD_RST_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+      SPI_CMD_PAUSE_EN = BIT(SPI_CMD_PAUSE_EN_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+       SPI_CMD_DEASSERT_EN = BIT(SPI_CMD_DEASSERT_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+    SPI_CMD_CPHA_EN = BIT(SPI_CMD_CPHA_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+    SPI_CMD_CPOL_EN = BIT(SPI_CMD_CPOL_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+    SPI_CMD_RX_DMA_EN = BIT(SPI_CMD_RX_DMA_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_TX_DMA_EN = BIT(SPI_CMD_TX_DMA_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_TXMSBF_EN = BIT(SPI_CMD_TXMSBF_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_RXMSBF_EN = BIT(SPI_CMD_RXMSBF_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+        SPI_CMD_RX_ENDIAN_EN = BIT(SPI_CMD_RX_ENDIAN_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_CMD_TX_ENDIAN_EN = BIT(SPI_CMD_TX_ENDIAN_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_CMD_FINISH_IE_EN = BIT(SPI_CMD_FINISH_IE_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_CMD_PAUSE_IE_EN = BIT(SPI_CMD_PAUSE_IE_SHIFT),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum spi_pad_mask {</span><br><span style="color: hsl(120, 100%, 40%);">+ SPI_PAD0_MASK = 0x0,</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_PAD1_MASK = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_PAD2_MASK = 0x2,</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_PAD3_MASK = 0x3,</span><br><span style="color: hsl(120, 100%, 40%);">+  SPI_PAD_SEL_MASK = 0x3</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct mtk_spi_regs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct mtk_spi_bus {</span><br><span style="color: hsl(120, 100%, 40%);">+    struct spi_slave slave;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct mtk_spi_regs *regs;</span><br><span style="color: hsl(120, 100%, 40%);">+    int initialized;</span><br><span style="color: hsl(120, 100%, 40%);">+      int state;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern const struct spi_ctrlr spi_ctrlr;</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct mtk_spi_bus spi_bus[];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void mtk_spi_set_gpio_pinmux(unsigned int bus,</span><br><span style="color: hsl(120, 100%, 40%);">+                         enum spi_pad_mask pad_select);</span><br><span style="color: hsl(120, 100%, 40%);">+void mtk_spi_set_timing(struct mtk_spi_regs *regs, u32 sck_ticks, u32 cs_ticks);</span><br><span style="color: hsl(120, 100%, 40%);">+void mtk_spi_init(unsigned int bus, enum spi_pad_mask pad_select,</span><br><span style="color: hsl(120, 100%, 40%);">+                unsigned int speed_hz);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/soc/mediatek/common/spi.c b/src/soc/mediatek/common/spi.c</span><br><span>new file mode 100644</span><br><span>index 0000000..9eaa376</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/mediatek/common/spi.c</span><br><span>@@ -0,0 +1,277 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 MediaTek Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <endian.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/pll.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/spi.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum {</span><br><span style="color: hsl(120, 100%, 40%);">+    MTK_FIFO_DEPTH = 32,</span><br><span style="color: hsl(120, 100%, 40%);">+  MTK_TXRX_TIMEOUT_US = 1000 * 1000,</span><br><span style="color: hsl(120, 100%, 40%);">+    MTK_ARBITRARY_VALUE = 0xdeaddead</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum {</span><br><span style="color: hsl(120, 100%, 40%);">+        MTK_SPI_IDLE = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+     MTK_SPI_PAUSE_IDLE = 1</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum {</span><br><span style="color: hsl(120, 100%, 40%);">+  MTK_SPI_BUSY_STATUS = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+      MTK_SPI_PAUSE_FINISH_INT_STATUS = 3</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline struct mtk_spi_bus *to_mtk_spi(const struct spi_slave *slave)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     assert(slave->bus < SPI_BUS_NUMBER);</span><br><span style="color: hsl(120, 100%, 40%);">+    return &spi_bus[slave->bus];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void spi_sw_reset(struct mtk_spi_regs *regs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      setbits_le32(&regs->spi_cmd_reg, SPI_CMD_RST_EN);</span><br><span style="color: hsl(120, 100%, 40%);">+      clrbits_le32(&regs->spi_cmd_reg, SPI_CMD_RST_EN);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void mtk_spi_init(unsigned int bus, enum spi_pad_mask pad_select,</span><br><span style="color: hsl(120, 100%, 40%);">+                unsigned int speed_hz)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   u32 div, sck_ticks, cs_ticks, reg_val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (bus >= SPI_BUS_NUMBER)</span><br><span style="color: hsl(120, 100%, 40%);">+         die("Error: Invalid SPI bus.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mtk_spi_bus *slave = &spi_bus[bus];</span><br><span style="color: hsl(120, 100%, 40%);">+        struct mtk_spi_regs *regs = slave->regs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (speed_hz < SPI_HZ / 2)</span><br><span style="color: hsl(120, 100%, 40%);">+         div = div_round_up(SPI_HZ, speed_hz);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+          div = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    sck_ticks = div_round_up(div, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+     cs_ticks = sck_ticks * 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printk(BIOS_DEBUG, "SPI%u(PAD%u) initialized at %u Hz\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          bus, pad_select, SPI_HZ / (sck_ticks * 2));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* set the timing */</span><br><span style="color: hsl(120, 100%, 40%);">+  mtk_spi_set_timing(regs, sck_ticks, cs_ticks);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      reg_val = read32(&regs->spi_cmd_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        reg_val &= ~SPI_CMD_CPHA_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+      reg_val &= ~SPI_CMD_CPOL_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* set the mlsbx and mlsbtx */</span><br><span style="color: hsl(120, 100%, 40%);">+        reg_val |= SPI_CMD_TXMSBF_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+ reg_val |= SPI_CMD_RXMSBF_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* set the tx/rx endian */</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef __LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+    reg_val &= ~SPI_CMD_TX_ENDIAN_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+ reg_val &= ~SPI_CMD_RX_ENDIAN_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+  reg_val |= SPI_CMD_TX_ENDIAN_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+      reg_val |= SPI_CMD_RX_ENDIAN_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* clear pause mode */</span><br><span style="color: hsl(120, 100%, 40%);">+        reg_val &= ~SPI_CMD_PAUSE_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* set finish interrupt always enable */</span><br><span style="color: hsl(120, 100%, 40%);">+      reg_val |= SPI_CMD_FINISH_IE_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* set pause interrupt always enable */</span><br><span style="color: hsl(120, 100%, 40%);">+       reg_val |= SPI_CMD_PAUSE_IE_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* disable dma mode */</span><br><span style="color: hsl(120, 100%, 40%);">+        reg_val &= ~(SPI_CMD_TX_DMA_EN | SPI_CMD_RX_DMA_EN);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* set deassert mode */</span><br><span style="color: hsl(120, 100%, 40%);">+       reg_val &= ~SPI_CMD_DEASSERT_EN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        write32(&regs->spi_cmd_reg, reg_val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        mtk_spi_set_gpio_pinmux(bus, pad_select);</span><br><span style="color: hsl(120, 100%, 40%);">+     /* pad select */</span><br><span style="color: hsl(120, 100%, 40%);">+      clrsetbits_le32(&regs->spi_pad_macro_sel_reg, SPI_PAD_SEL_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+                        pad_select);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void mtk_spi_dump_data(const char *name, const uint8_t *data, int size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef MTK_SPI_DEBUG</span><br><span style="color: hsl(120, 100%, 40%);">+    int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "%s: 0x ", name);</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < size; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+         printk(BIOS_INFO, "%#x ", data[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "\n");</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int spi_ctrlr_claim_bus(const struct spi_slave *slave)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct mtk_spi_regs *regs = mtk_slave->regs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     setbits_le32(&regs->spi_cmd_reg, 1 << SPI_CMD_PAUSE_EN_SHIFT);</span><br><span style="color: hsl(120, 100%, 40%);">+   mtk_slave->state = MTK_SPI_IDLE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int mtk_spi_fifo_transfer(const struct spi_slave *slave, void *in,</span><br><span style="color: hsl(120, 100%, 40%);">+                              const void *out, size_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct mtk_spi_regs *regs = mtk_slave->regs;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t *inb = (uint8_t *)in;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint32_t *outb = (const uint32_t *)out;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t reg_val = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t i, word_count;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct stopwatch sw;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!size || size > MTK_FIFO_DEPTH)</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  clrsetbits_le32(&regs->spi_cfg1_reg,</span><br><span style="color: hsl(120, 100%, 40%);">+                   SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+                      ((size - 1) << SPI_CFG1_PACKET_LENGTH_SHIFT) |</span><br><span style="color: hsl(120, 100%, 40%);">+                  (0 << SPI_CFG1_PACKET_LOOP_SHIFT));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   word_count = div_round_up(size, sizeof(u32));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (outb) {</span><br><span style="color: hsl(120, 100%, 40%);">+           for (i = 0; i < word_count; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                   write32(&regs->spi_tx_data_reg, outb[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+              mtk_spi_dump_data("the outb data is",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 (const uint8_t *)outb, size);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* The SPI controller will transmit in full-duplex for RX,</span><br><span style="color: hsl(120, 100%, 40%);">+             * therefore we need arbitrary data on MOSI which the slave</span><br><span style="color: hsl(120, 100%, 40%);">+            * must ignore.</span><br><span style="color: hsl(120, 100%, 40%);">+                */</span><br><span style="color: hsl(120, 100%, 40%);">+           for (i = 0; i < word_count; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+                   write32(&regs->spi_tx_data_reg, MTK_ARBITRARY_VALUE);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (mtk_slave->state == MTK_SPI_IDLE) {</span><br><span style="color: hsl(120, 100%, 40%);">+            setbits_le32(&regs->spi_cmd_reg, SPI_CMD_ACT_EN);</span><br><span style="color: hsl(120, 100%, 40%);">+              mtk_slave->state = MTK_SPI_PAUSE_IDLE;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else if (mtk_slave->state == MTK_SPI_PAUSE_IDLE) {</span><br><span style="color: hsl(120, 100%, 40%);">+               setbits_le32(&regs->spi_cmd_reg, SPI_CMD_RESUME_EN);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   stopwatch_init_usecs_expire(&sw, MTK_TXRX_TIMEOUT_US);</span><br><span style="color: hsl(120, 100%, 40%);">+    while ((read32(&regs->spi_status1_reg) & MTK_SPI_BUSY_STATUS) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (stopwatch_expired(&sw)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     printk(BIOS_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+                             "Timeout waiting for status1 status.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     stopwatch_init_usecs_expire(&sw, MTK_TXRX_TIMEOUT_US);</span><br><span style="color: hsl(120, 100%, 40%);">+    while ((read32(&regs->spi_status0_reg) &</span><br><span style="color: hsl(120, 100%, 40%);">+          MTK_SPI_PAUSE_FINISH_INT_STATUS) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (stopwatch_expired(&sw)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     printk(BIOS_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+                             "Timeout waiting for status0 status.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (inb) {</span><br><span style="color: hsl(120, 100%, 40%);">+            for (i = 0; i < size; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (i % 4 == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                               reg_val = read32(&regs->spi_rx_data_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+                      *(inb + i) = (reg_val >> ((i % 4) * 8)) & 0xff;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+             mtk_spi_dump_data("the inb data is", inb, size);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+error:</span><br><span style="color: hsl(120, 100%, 40%);">+     spi_sw_reset(regs);</span><br><span style="color: hsl(120, 100%, 40%);">+   mtk_slave->state = MTK_SPI_IDLE;</span><br><span style="color: hsl(120, 100%, 40%);">+   return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,</span><br><span style="color: hsl(120, 100%, 40%);">+                   size_t bytes_out, void *din, size_t bytes_in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t min_size = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Driver implementation does not support full duplex. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((bytes_in && bytes_out) && (bytes_in != bytes_out))</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  while (bytes_out || bytes_in) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (bytes_in && bytes_out)</span><br><span style="color: hsl(120, 100%, 40%);">+                    min_size = MIN(bytes_out, MTK_FIFO_DEPTH);</span><br><span style="color: hsl(120, 100%, 40%);">+            else if (bytes_out)</span><br><span style="color: hsl(120, 100%, 40%);">+                   min_size = MIN(bytes_out, MTK_FIFO_DEPTH);</span><br><span style="color: hsl(120, 100%, 40%);">+            else if (bytes_in)</span><br><span style="color: hsl(120, 100%, 40%);">+                    min_size = MIN(bytes_in, MTK_FIFO_DEPTH);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           ret = mtk_spi_fifo_transfer(slave, din, dout, min_size);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (ret != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                 return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if (bytes_out) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      bytes_out -= min_size;</span><br><span style="color: hsl(120, 100%, 40%);">+                        dout = (const uint8_t *)dout + min_size;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (bytes_in) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       bytes_in -= min_size;</span><br><span style="color: hsl(120, 100%, 40%);">+                 din = (uint8_t *)din + min_size;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void spi_ctrlr_release_bus(const struct spi_slave *slave)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct mtk_spi_regs *regs = mtk_slave->regs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     clrbits_le32(&regs->spi_cmd_reg, SPI_CMD_PAUSE_EN);</span><br><span style="color: hsl(120, 100%, 40%);">+    spi_sw_reset(regs);</span><br><span style="color: hsl(120, 100%, 40%);">+   mtk_slave->state = MTK_SPI_IDLE;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int spi_ctrlr_setup(const struct spi_slave *slave)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct mtk_spi_bus *eslave = to_mtk_spi(slave);</span><br><span style="color: hsl(120, 100%, 40%);">+       assert(read32(&eslave->regs->spi_cfg0_reg) != 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   spi_sw_reset(eslave->regs);</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct spi_ctrlr spi_ctrlr = {</span><br><span style="color: hsl(120, 100%, 40%);">+  .setup = spi_ctrlr_setup,</span><br><span style="color: hsl(120, 100%, 40%);">+     .claim_bus = spi_ctrlr_claim_bus,</span><br><span style="color: hsl(120, 100%, 40%);">+     .release_bus = spi_ctrlr_release_bus,</span><br><span style="color: hsl(120, 100%, 40%);">+ .xfer = spi_ctrlr_xfer,</span><br><span style="color: hsl(120, 100%, 40%);">+       .max_xfer_size = 65535,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span>diff --git a/src/soc/mediatek/mt8173/Makefile.inc b/src/soc/mediatek/mt8173/Makefile.inc</span><br><span>index 1a5ee80..2aa7b8d 100644</span><br><span>--- a/src/soc/mediatek/mt8173/Makefile.inc</span><br><span>+++ b/src/soc/mediatek/mt8173/Makefile.inc</span><br><span>@@ -19,7 +19,7 @@</span><br><span> bootblock-$(CONFIG_SPI_FLASH) += flash_controller.c</span><br><span> bootblock-y += i2c.c</span><br><span> bootblock-y += ../common/pll.c pll.c</span><br><span style="color: hsl(0, 100%, 40%);">-bootblock-y += spi.c</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-y += ../common/spi.c spi.c</span><br><span> bootblock-y += ../common/timer.c</span><br><span> bootblock-y += timer.c</span><br><span> </span><br><span>@@ -34,7 +34,7 @@</span><br><span> ################################################################################</span><br><span> </span><br><span> verstage-y += i2c.c</span><br><span style="color: hsl(0, 100%, 40%);">-verstage-y += spi.c</span><br><span style="color: hsl(120, 100%, 40%);">+verstage-y += ../common/spi.c spi.c</span><br><span> </span><br><span> verstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c</span><br><span> </span><br><span>@@ -53,8 +53,8 @@</span><br><span> </span><br><span> romstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c</span><br><span> romstage-y += ../common/cbmem.c</span><br><span style="color: hsl(0, 100%, 40%);">-romstage-y += spi.c</span><br><span> romstage-y += ../common/gpio.c gpio.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-y += ../common/spi.c spi.c</span><br><span> romstage-y += pmic_wrap.c mt6391.c</span><br><span> romstage-y += memory.c</span><br><span> romstage-y += emi.c dramc_pi_basic_api.c dramc_pi_calibration_api.c</span><br><span>@@ -64,7 +64,7 @@</span><br><span> ################################################################################</span><br><span> </span><br><span> ramstage-y += ../common/cbmem.c emi.c</span><br><span style="color: hsl(0, 100%, 40%);">-ramstage-y += spi.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += ../common/spi.c spi.c</span><br><span> ramstage-$(CONFIG_SPI_FLASH) += flash_controller.c</span><br><span> ramstage-y += soc.c ../common/mtcmos.c</span><br><span> ramstage-y += ../common/timer.c</span><br><span>diff --git a/src/soc/mediatek/mt8173/include/soc/spi.h b/src/soc/mediatek/mt8173/include/soc/spi.h</span><br><span>index 52f4f4c..eebadb4 100644</span><br><span>--- a/src/soc/mediatek/mt8173/include/soc/spi.h</span><br><span>+++ b/src/soc/mediatek/mt8173/include/soc/spi.h</span><br><span>@@ -16,8 +16,9 @@</span><br><span> #ifndef MTK_MT8173_SPI_H</span><br><span> #define MTK_MT8173_SPI_H</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <spi-generic.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/spi_common.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define SPI_BUS_NUMBER 1</span><br><span> </span><br><span> /* SPI peripheral register map. */</span><br><span> typedef struct mtk_spi_regs {</span><br><span>@@ -43,67 +44,4 @@</span><br><span>    SPI_CFG0_CS_SETUP_SHIFT = 24,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*SPI_CFG1_REG*/</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-   SPI_CFG1_CS_IDLE_SHIFT = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-     SPI_CFG1_PACKET_LOOP_SHIFT = 8,</span><br><span style="color: hsl(0, 100%, 40%);">- SPI_CFG1_PACKET_LENGTH_SHIFT = 16,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CFG1_CS_IDLE_MASK = 0xff << SPI_CFG1_CS_IDLE_SHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">-   SPI_CFG1_PACKET_LOOP_MASK = 0xff << SPI_CFG1_PACKET_LOOP_SHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">-   SPI_CFG1_PACKET_LENGTH_MASK = 0x3ff << SPI_CFG1_PACKET_LENGTH_SHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_ACT_SHIFT = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-  SPI_CMD_RESUME_SHIFT = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-       SPI_CMD_RST_SHIFT = 2,</span><br><span style="color: hsl(0, 100%, 40%);">-  SPI_CMD_PAUSE_EN_SHIFT = 4,</span><br><span style="color: hsl(0, 100%, 40%);">-     SPI_CMD_DEASSERT_SHIFT = 5,</span><br><span style="color: hsl(0, 100%, 40%);">-     SPI_CMD_CPHA_SHIFT = 8,</span><br><span style="color: hsl(0, 100%, 40%);">- SPI_CMD_CPOL_SHIFT = 9,</span><br><span style="color: hsl(0, 100%, 40%);">- SPI_CMD_RX_DMA_SHIFT = 10,</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_TX_DMA_SHIFT = 11,</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_TXMSBF_SHIFT = 12,</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_RXMSBF_SHIFT = 13,</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_RX_ENDIAN_SHIFT = 14,</span><br><span style="color: hsl(0, 100%, 40%);">-   SPI_CMD_TX_ENDIAN_SHIFT = 15,</span><br><span style="color: hsl(0, 100%, 40%);">-   SPI_CMD_FINISH_IE_SHIFT = 16,</span><br><span style="color: hsl(0, 100%, 40%);">-   SPI_CMD_PAUSE_IE_SHIFT = 17,</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_CMD_ACT_EN = BIT(SPI_CMD_ACT_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-        SPI_CMD_RESUME_EN = BIT(SPI_CMD_RESUME_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-  SPI_CMD_RST_EN = BIT(SPI_CMD_RST_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-        SPI_CMD_PAUSE_EN = BIT(SPI_CMD_PAUSE_EN_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">- SPI_CMD_DEASSERT_EN = BIT(SPI_CMD_DEASSERT_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_CPHA_EN = BIT(SPI_CMD_CPHA_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_CPOL_EN = BIT(SPI_CMD_CPOL_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-      SPI_CMD_RX_DMA_EN = BIT(SPI_CMD_RX_DMA_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-  SPI_CMD_TX_DMA_EN = BIT(SPI_CMD_TX_DMA_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-  SPI_CMD_TXMSBF_EN = BIT(SPI_CMD_TXMSBF_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-  SPI_CMD_RXMSBF_EN = BIT(SPI_CMD_RXMSBF_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-  SPI_CMD_RX_ENDIAN_EN = BIT(SPI_CMD_RX_ENDIAN_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_CMD_TX_ENDIAN_EN = BIT(SPI_CMD_TX_ENDIAN_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_CMD_FINISH_IE_EN = BIT(SPI_CMD_FINISH_IE_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_CMD_PAUSE_IE_EN = BIT(SPI_CMD_PAUSE_IE_SHIFT),</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum spi_pad_mask {</span><br><span style="color: hsl(0, 100%, 40%);">- SPI_PAD0_MASK = 0x0,</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_PAD1_MASK = 0x1,</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_PAD2_MASK = 0x2,</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_PAD3_MASK = 0x3,</span><br><span style="color: hsl(0, 100%, 40%);">-    SPI_PAD_SEL_MASK = 0x3</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct mtk_spi_bus {</span><br><span style="color: hsl(0, 100%, 40%);">-    struct spi_slave slave;</span><br><span style="color: hsl(0, 100%, 40%);">- struct mtk_spi_regs *regs;</span><br><span style="color: hsl(0, 100%, 40%);">-      int initialized;</span><br><span style="color: hsl(0, 100%, 40%);">-        int state;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void mtk_spi_init(unsigned int bus, unsigned int pad_select,</span><br><span style="color: hsl(0, 100%, 40%);">-                  unsigned int speed_hz);</span><br><span> #endif</span><br><span>diff --git a/src/soc/mediatek/mt8173/spi.c b/src/soc/mediatek/mt8173/spi.c</span><br><span>index 634c46e..669ecf0 100644</span><br><span>--- a/src/soc/mediatek/mt8173/spi.c</span><br><span>+++ b/src/soc/mediatek/mt8173/spi.c</span><br><span>@@ -15,55 +15,20 @@</span><br><span> </span><br><span> #include <arch/io.h></span><br><span> #include <assert.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <console/console.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <delay.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <endian.h></span><br><span> #include <spi_flash.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <timer.h></span><br><span> #include <soc/addressmap.h></span><br><span> #include <soc/flash_controller.h></span><br><span> #include <soc/gpio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <soc/pll.h></span><br><span> #include <soc/spi.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">- MTK_FIFO_DEPTH = 32,</span><br><span style="color: hsl(0, 100%, 40%);">-    MTK_TXRX_TIMEOUT_US = 1000 * 1000,</span><br><span style="color: hsl(0, 100%, 40%);">-      MTK_ARBITRARY_VALUE = 0xdeaddead</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-        MTK_SPI_IDLE = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-       MTK_SPI_PAUSE_IDLE = 1</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-  MTK_SPI_BUSY_STATUS = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-        MTK_SPI_PAUSE_FINISH_INT_STATUS = 3</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct mtk_spi_bus spi_bus[1] = {</span><br><span style="color: hsl(120, 100%, 40%);">+struct mtk_spi_bus spi_bus[SPI_BUS_NUMBER] = {</span><br><span>        {</span><br><span>            .regs = (void *)SPI_BASE,</span><br><span style="color: hsl(0, 100%, 40%);">-               .state = MTK_SPI_IDLE,</span><br><span>       }</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static inline struct mtk_spi_bus *to_mtk_spi(const struct spi_slave *slave)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- assert(slave->bus < ARRAY_SIZE(spi_bus));</span><br><span style="color: hsl(0, 100%, 40%);">- return &spi_bus[slave->bus];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void spi_sw_reset(struct mtk_spi_regs *regs)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        setbits_le32(&regs->spi_cmd_reg, SPI_CMD_RST_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-        clrbits_le32(&regs->spi_cmd_reg, SPI_CMD_RST_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void mtk_spi_set_gpio_pinmux(enum spi_pad_mask pad_select)</span><br><span style="color: hsl(120, 100%, 40%);">+void mtk_spi_set_gpio_pinmux(unsigned int bus,</span><br><span style="color: hsl(120, 100%, 40%);">+                         enum spi_pad_mask pad_select)</span><br><span> {</span><br><span>      /* TODO: implement support for other pads when needed */</span><br><span>     assert(pad_select == SPI_PAD1_MASK);</span><br><span>@@ -73,30 +38,8 @@</span><br><span>    gpio_set_mode(PAD_MSDC2_CMD, PAD_MSDC2_CMD_FUNC_SPI_CS_1);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void mtk_spi_init(unsigned int bus, unsigned int pad_select,</span><br><span style="color: hsl(0, 100%, 40%);">-           unsigned int speed_hz)</span><br><span style="color: hsl(120, 100%, 40%);">+void mtk_spi_set_timing(struct mtk_spi_regs *regs, u32 sck_ticks, u32 cs_ticks)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  u32 div, sck_ticks, cs_ticks, reg_val;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* mtk spi HW just supports bus 0 */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (bus != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-           die("Error: Only SPI bus 0 is supported.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- struct mtk_spi_bus *slave = &spi_bus[bus];</span><br><span style="color: hsl(0, 100%, 40%);">-  struct mtk_spi_regs *regs = slave->regs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (speed_hz < SPI_HZ / 2)</span><br><span style="color: hsl(0, 100%, 40%);">-           div = div_round_up(SPI_HZ, speed_hz);</span><br><span style="color: hsl(0, 100%, 40%);">-   else</span><br><span style="color: hsl(0, 100%, 40%);">-            div = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        sck_ticks = div_round_up(div, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-       cs_ticks = sck_ticks * 2;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       printk(BIOS_DEBUG, "SPI%u initialized at %u Hz",</span><br><span style="color: hsl(0, 100%, 40%);">-             pad_select, SPI_HZ / (sck_ticks * 2));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* set the timing */</span><br><span>         write32(&regs->spi_cfg0_reg,</span><br><span>          ((sck_ticks - 1) << SPI_CFG0_SCK_HIGH_SHIFT) |</span><br><span>                 ((sck_ticks - 1) << SPI_CFG0_SCK_LOW_SHIFT) |</span><br><span>@@ -104,200 +47,6 @@</span><br><span>           ((cs_ticks - 1) << SPI_CFG0_CS_SETUP_SHIFT));</span><br><span>  clrsetbits_le32(&regs->spi_cfg1_reg, SPI_CFG1_CS_IDLE_MASK,</span><br><span>                   ((cs_ticks - 1) << SPI_CFG1_CS_IDLE_SHIFT));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      reg_val = read32(&regs->spi_cmd_reg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    reg_val &= ~SPI_CMD_CPHA_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-        reg_val &= ~SPI_CMD_CPOL_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* set the mlsbx and mlsbtx */</span><br><span style="color: hsl(0, 100%, 40%);">-  reg_val |= SPI_CMD_TXMSBF_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-   reg_val |= SPI_CMD_RXMSBF_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* set the tx/rx endian */</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef __LITTLE_ENDIAN</span><br><span style="color: hsl(0, 100%, 40%);">-        reg_val &= ~SPI_CMD_TX_ENDIAN_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-   reg_val &= ~SPI_CMD_RX_ENDIAN_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">-      reg_val |= SPI_CMD_TX_ENDIAN_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-        reg_val |= SPI_CMD_RX_ENDIAN_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* clear pause mode */</span><br><span style="color: hsl(0, 100%, 40%);">-  reg_val &= ~SPI_CMD_PAUSE_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* set finish interrupt always enable */</span><br><span style="color: hsl(0, 100%, 40%);">-        reg_val |= SPI_CMD_FINISH_IE_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* set pause interrupt always enable */</span><br><span style="color: hsl(0, 100%, 40%);">- reg_val |= SPI_CMD_PAUSE_IE_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* disable dma mode */</span><br><span style="color: hsl(0, 100%, 40%);">-  reg_val &= ~(SPI_CMD_TX_DMA_EN | SPI_CMD_RX_DMA_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* set deassert mode */</span><br><span style="color: hsl(0, 100%, 40%);">- reg_val &= ~SPI_CMD_DEASSERT_EN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    write32(&regs->spi_cmd_reg, reg_val);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    mtk_spi_set_gpio_pinmux(pad_select);</span><br><span style="color: hsl(0, 100%, 40%);">-    /* pad select */</span><br><span style="color: hsl(0, 100%, 40%);">-        clrsetbits_le32(&regs->spi_pad_macro_sel_reg, SPI_PAD_SEL_MASK,</span><br><span style="color: hsl(0, 100%, 40%);">-                  pad_select);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void mtk_spi_dump_data(const char *name, const uint8_t *data,</span><br><span style="color: hsl(0, 100%, 40%);">-                             int size)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef MTK_SPI_DEBUG</span><br><span style="color: hsl(0, 100%, 40%);">-    int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  printk(BIOS_DEBUG, "%s: 0x ", name);</span><br><span style="color: hsl(0, 100%, 40%);">-  for (i = 0; i < size; i++)</span><br><span style="color: hsl(0, 100%, 40%);">-           printk(BIOS_INFO, "%#x ", data[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-   printk(BIOS_DEBUG, "\n");</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int spi_ctrlr_claim_bus(const struct spi_slave *slave)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave);</span><br><span style="color: hsl(0, 100%, 40%);">-      struct mtk_spi_regs *regs = mtk_slave->regs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- setbits_le32(&regs->spi_cmd_reg, 1 << SPI_CMD_PAUSE_EN_SHIFT);</span><br><span style="color: hsl(0, 100%, 40%);">-     mtk_slave->state = MTK_SPI_IDLE;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int mtk_spi_fifo_transfer(const struct spi_slave *slave, void *in,</span><br><span style="color: hsl(0, 100%, 40%);">-                              const void *out, size_t size)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave);</span><br><span style="color: hsl(0, 100%, 40%);">-      struct mtk_spi_regs *regs = mtk_slave->regs;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t *inb = (uint8_t *)in;</span><br><span style="color: hsl(0, 100%, 40%);">-   const uint32_t *outb = (const uint32_t *)out;</span><br><span style="color: hsl(0, 100%, 40%);">-   uint32_t reg_val = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-   uint32_t i, word_count;</span><br><span style="color: hsl(0, 100%, 40%);">- struct stopwatch sw;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!size || size > MTK_FIFO_DEPTH)</span><br><span style="color: hsl(0, 100%, 40%);">-          return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      clrsetbits_le32(&regs->spi_cfg1_reg,</span><br><span style="color: hsl(0, 100%, 40%);">-                     SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK,</span><br><span style="color: hsl(0, 100%, 40%);">-                        ((size - 1) << SPI_CFG1_PACKET_LENGTH_SHIFT) |</span><br><span style="color: hsl(0, 100%, 40%);">-                    (0 << SPI_CFG1_PACKET_LOOP_SHIFT));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       word_count = div_round_up(size, sizeof(u32));</span><br><span style="color: hsl(0, 100%, 40%);">-   if (inb) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* The SPI controller will transmit in full-duplex for RX,</span><br><span style="color: hsl(0, 100%, 40%);">-               * therefore we need arbitrary data on MOSI which the slave</span><br><span style="color: hsl(0, 100%, 40%);">-              * must ignore.</span><br><span style="color: hsl(0, 100%, 40%);">-          */</span><br><span style="color: hsl(0, 100%, 40%);">-             for (i = 0; i < word_count; i++)</span><br><span style="color: hsl(0, 100%, 40%);">-                     write32(&regs->spi_tx_data_reg, MTK_ARBITRARY_VALUE);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (outb) {</span><br><span style="color: hsl(0, 100%, 40%);">-             for (i = 0; i < word_count; i++)</span><br><span style="color: hsl(0, 100%, 40%);">-                     write32(&regs->spi_tx_data_reg, outb[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-                mtk_spi_dump_data("the outb data is",</span><br><span style="color: hsl(0, 100%, 40%);">-                           (const uint8_t *)outb, size);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (mtk_slave->state == MTK_SPI_IDLE) {</span><br><span style="color: hsl(0, 100%, 40%);">-              setbits_le32(&regs->spi_cmd_reg, SPI_CMD_ACT_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-                mtk_slave->state = MTK_SPI_PAUSE_IDLE;</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (mtk_slave->state == MTK_SPI_PAUSE_IDLE) {</span><br><span style="color: hsl(0, 100%, 40%);">-         setbits_le32(&regs->spi_cmd_reg, SPI_CMD_RESUME_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       stopwatch_init_usecs_expire(&sw, MTK_TXRX_TIMEOUT_US);</span><br><span style="color: hsl(0, 100%, 40%);">-      while ((read32(&regs->spi_status1_reg) & MTK_SPI_BUSY_STATUS) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                if (stopwatch_expired(&sw)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       printk(BIOS_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-                               "Timeout waiting for status1 status.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                      goto error;</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       stopwatch_init_usecs_expire(&sw, MTK_TXRX_TIMEOUT_US);</span><br><span style="color: hsl(0, 100%, 40%);">-      while ((read32(&regs->spi_status0_reg) &</span><br><span style="color: hsl(0, 100%, 40%);">-            MTK_SPI_PAUSE_FINISH_INT_STATUS) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (stopwatch_expired(&sw)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       printk(BIOS_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-                               "Timeout waiting for status0 status.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                      goto error;</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (inb) {</span><br><span style="color: hsl(0, 100%, 40%);">-              for (i = 0; i < size; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (i % 4 == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                         reg_val = read32(&regs->spi_rx_data_reg);</span><br><span style="color: hsl(0, 100%, 40%);">-                        *(inb + i) = (reg_val >> ((i % 4) * 8)) & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               mtk_spi_dump_data("the inb data is", inb, size);</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-error:</span><br><span style="color: hsl(0, 100%, 40%);">- spi_sw_reset(regs);</span><br><span style="color: hsl(0, 100%, 40%);">-     mtk_slave->state = MTK_SPI_IDLE;</span><br><span style="color: hsl(0, 100%, 40%);">-     return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,</span><br><span style="color: hsl(0, 100%, 40%);">-                   size_t bytes_out, void *din, size_t bytes_in)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  size_t min_size = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Driver implementation does not support full duplex. */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bytes_in && bytes_out)</span><br><span style="color: hsl(0, 100%, 40%);">-              return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      while (bytes_out || bytes_in) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (bytes_in && bytes_out)</span><br><span style="color: hsl(0, 100%, 40%);">-                      min_size = MIN(MIN(bytes_out, bytes_in), MTK_FIFO_DEPTH);</span><br><span style="color: hsl(0, 100%, 40%);">-               else if (bytes_out)</span><br><span style="color: hsl(0, 100%, 40%);">-                     min_size = MIN(bytes_out, MTK_FIFO_DEPTH);</span><br><span style="color: hsl(0, 100%, 40%);">-              else if (bytes_in)</span><br><span style="color: hsl(0, 100%, 40%);">-                      min_size = MIN(bytes_in, MTK_FIFO_DEPTH);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               ret = mtk_spi_fifo_transfer(slave, din, dout, min_size);</span><br><span style="color: hsl(0, 100%, 40%);">-                if (ret != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                   return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             if (bytes_out) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        bytes_out -= min_size;</span><br><span style="color: hsl(0, 100%, 40%);">-                  dout = (const uint8_t *)dout + min_size;</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (bytes_in) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 bytes_in -= min_size;</span><br><span style="color: hsl(0, 100%, 40%);">-                   din = (uint8_t *)din + min_size;</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void spi_ctrlr_release_bus(const struct spi_slave *slave)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave);</span><br><span style="color: hsl(0, 100%, 40%);">-      struct mtk_spi_regs *regs = mtk_slave->regs;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- clrbits_le32(&regs->spi_cmd_reg, SPI_CMD_PAUSE_EN);</span><br><span style="color: hsl(0, 100%, 40%);">-      spi_sw_reset(regs);</span><br><span style="color: hsl(0, 100%, 40%);">-     mtk_slave->state = MTK_SPI_IDLE;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int spi_ctrlr_setup(const struct spi_slave *slave)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct mtk_spi_bus *eslave = to_mtk_spi(slave);</span><br><span style="color: hsl(0, 100%, 40%);">- assert(read32(&eslave->regs->spi_cfg0_reg) != 0);</span><br><span style="color: hsl(0, 100%, 40%);">-     spi_sw_reset(eslave->regs);</span><br><span style="color: hsl(0, 100%, 40%);">-  return 0;</span><br><span> }</span><br><span> </span><br><span> static const struct spi_ctrlr spi_flash_ctrlr = {</span><br><span>@@ -305,19 +54,11 @@</span><br><span>       .flash_probe = mtk_spi_flash_probe,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static const struct spi_ctrlr spi_ctrlr = {</span><br><span style="color: hsl(0, 100%, 40%);">-        .setup = spi_ctrlr_setup,</span><br><span style="color: hsl(0, 100%, 40%);">-       .claim_bus = spi_ctrlr_claim_bus,</span><br><span style="color: hsl(0, 100%, 40%);">-       .release_bus = spi_ctrlr_release_bus,</span><br><span style="color: hsl(0, 100%, 40%);">-   .xfer = spi_ctrlr_xfer,</span><br><span style="color: hsl(0, 100%, 40%);">- .max_xfer_size = 65535,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {</span><br><span>    {</span><br><span>            .ctrlr = &spi_ctrlr,</span><br><span>             .bus_start = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-         .bus_end = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+         .bus_end = SPI_BUS_NUMBER - 1,</span><br><span>       },</span><br><span>   {</span><br><span>            .ctrlr = &spi_flash_ctrlr,</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/27497">change 27497</a>. To unsubscribe, or for help writing mail filters, 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/27497"/><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: If5a6c554dc8361e729cf5c464325b97b2bfb7098 </div>
<div style="display:none"> Gerrit-Change-Number: 27497 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Tristan Hsieh <tristan.shieh@mediatek.com> </div>