<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(®s->spi_cmd_reg, SPI_CMD_RST_EN);</span><br><span style="color: hsl(120, 100%, 40%);">+ clrbits_le32(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->spi_cmd_reg, SPI_CMD_RST_EN);</span><br><span style="color: hsl(0, 100%, 40%);">- clrbits_le32(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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>