summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQii Wang <qii.wang@mediatek.com>2021-02-05 10:32:25 +0800
committerHung-Te Lin <hungte@chromium.org>2021-05-05 07:36:57 +0000
commitf46e2caebec91d83bd729e6812e51ca960a24f38 (patch)
tree07e3835379ed0b5e8c922a7b32d94393a009ded8 /src
parent47095d5ec35b4cbff9d4660cfe9521ed17a0d1ed (diff)
downloadcoreboot-f46e2caebec91d83bd729e6812e51ca960a24f38.tar.xz
soc/mediatek/mt8195: Add SPI driver support
Add SPI controller driver code. Signed-off-by: Qii Wang <qii.wang@mediatek.com> Change-Id: I674763cdb0f338e123c121ede52278cfe96df091 Reviewed-on: https://review.coreboot.org/c/coreboot/+/52669 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/soc/mediatek/mt8195/Makefile.inc8
-rw-r--r--src/soc/mediatek/mt8195/include/soc/pll.h2
-rw-r--r--src/soc/mediatek/mt8195/include/soc/spi.h17
-rw-r--r--src/soc/mediatek/mt8195/spi.c92
4 files changed, 114 insertions, 5 deletions
diff --git a/src/soc/mediatek/mt8195/Makefile.inc b/src/soc/mediatek/mt8195/Makefile.inc
index 1f2d1de474..04f4572e35 100644
--- a/src/soc/mediatek/mt8195/Makefile.inc
+++ b/src/soc/mediatek/mt8195/Makefile.inc
@@ -4,13 +4,13 @@ bootblock-y += bootblock.c
bootblock-y += ../common/gpio.c gpio.c
bootblock-y += ../common/mmu_operations.c
bootblock-y += ../common/pll.c pll.c
-bootblock-$(CONFIG_SPI_FLASH) += spi.c
+bootblock-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c
bootblock-y += ../common/timer.c timer.c
bootblock-y += ../common/uart.c
bootblock-y += ../common/wdt.c
verstage-y += ../common/gpio.c gpio.c
-verstage-$(CONFIG_SPI_FLASH) += spi.c
+verstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c
verstage-y += ../common/timer.c timer.c
verstage-y += ../common/uart.c
verstage-y += ../common/wdt.c
@@ -19,7 +19,7 @@ romstage-y += ../common/cbmem.c
romstage-y += emi.c
romstage-y += ../common/gpio.c gpio.c
romstage-y += ../common/pll.c pll.c
-romstage-$(CONFIG_SPI_FLASH) += spi.c
+romstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c
romstage-y += ../common/timer.c timer.c
romstage-y += ../common/uart.c
romstage-y += ../common/wdt.c
@@ -31,7 +31,7 @@ romstage-y += ../common/mt6359p.c mt6359p.c
ramstage-y += emi.c
ramstage-y += ../common/gpio.c gpio.c
-ramstage-$(CONFIG_SPI_FLASH) += spi.c
+ramstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c
ramstage-y += soc.c
ramstage-y += ../common/timer.c timer.c
ramstage-y += ../common/uart.c
diff --git a/src/soc/mediatek/mt8195/include/soc/pll.h b/src/soc/mediatek/mt8195/include/soc/pll.h
index 6d836f7e8f..60fcbd9884 100644
--- a/src/soc/mediatek/mt8195/include/soc/pll.h
+++ b/src/soc/mediatek/mt8195/include/soc/pll.h
@@ -562,10 +562,12 @@ enum {
/* top_div rate */
enum {
CLK26M_HZ = 26 * MHz,
+ UNIVPLL_D6_D2_HZ = UNIVPLL_HZ / 6 / 2,
};
/* top_mux rate */
enum {
+ SPI_HZ = UNIVPLL_D6_D2_HZ,
UART_HZ = CLK26M_HZ,
};
diff --git a/src/soc/mediatek/mt8195/include/soc/spi.h b/src/soc/mediatek/mt8195/include/soc/spi.h
index cfa4f43a13..a74ed56439 100644
--- a/src/soc/mediatek/mt8195/include/soc/spi.h
+++ b/src/soc/mediatek/mt8195/include/soc/spi.h
@@ -3,6 +3,21 @@
#ifndef MTK_MT8195_SPI_H
#define MTK_MT8195_SPI_H
-#include <spi-generic.h>
+#include <soc/spi_common.h>
+
+#define SPI_BUS_NUMBER 6
+
+#define GET_SCK_REG(x) x->spi_cfg2_reg
+
+DEFINE_BITFIELD(SPI_CFG_CS_HOLD, 15, 0)
+DEFINE_BITFIELD(SPI_CFG_CS_SETUP, 31, 16)
+
+DEFINE_BITFIELD(SPI_CFG_SCK_LOW, 15, 0)
+DEFINE_BITFIELD(SPI_CFG_SCK_HIGH, 31, 16)
+
+DEFINE_BITFIELD(SPI_CFG1_CS_IDLE, 7, 0)
+DEFINE_BITFIELD(SPI_CFG1_PACKET_LOOP, 15, 8)
+DEFINE_BITFIELD(SPI_CFG1_PACKET_LENGTH, 28, 16)
+DEFINE_BITFIELD(SPI_CFG1_TICK_DLY, 31, 29)
#endif
diff --git a/src/soc/mediatek/mt8195/spi.c b/src/soc/mediatek/mt8195/spi.c
index 459e46a150..bc02aa0e60 100644
--- a/src/soc/mediatek/mt8195/spi.c
+++ b/src/soc/mediatek/mt8195/spi.c
@@ -1,15 +1,107 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <assert.h>
#include <device/mmio.h>
#include <soc/addressmap.h>
+#include <soc/gpio.h>
#include <soc/spi.h>
+struct mtk_spi_bus spi_bus[SPI_BUS_NUMBER] = {
+ {
+ .regs = (void *)SPI0_BASE,
+ .cs_gpio = GPIO(SPIM0_CSB),
+ },
+ {
+ .regs = (void *)SPI1_BASE,
+ .cs_gpio = GPIO(SPIM1_CSB),
+ },
+ {
+ .regs = (void *)SPI2_BASE,
+ .cs_gpio = GPIO(SPIM2_CSB),
+ },
+ {
+ .regs = (void *)SPI3_BASE,
+ .cs_gpio = GPIO(PWRAP_SPI_CSN),
+ },
+ {
+ .regs = (void *)SPI4_BASE,
+ .cs_gpio = GPIO(DGI_D2),
+ },
+ {
+ .regs = (void *)SPI5_BASE,
+ .cs_gpio = GPIO(DGI_D6),
+ },
+};
+
+struct pad_func {
+ u8 pin_id;
+ u8 func;
+};
+
+#define PAD_FUNC(name, func) {PAD_##name##_ID, PAD_##name##_FUNC_##func}
+#define PAD_FUNC_GPIO(name) {PAD_##name##_ID, 0}
+
+static const struct pad_func pad0_funcs[SPI_BUS_NUMBER][4] = {
+ {
+ PAD_FUNC(SPIM0_MI, SPIM0_MI),
+ PAD_FUNC_GPIO(SPIM0_CSB),
+ PAD_FUNC(SPIM0_MO, SPIM0_MO),
+ PAD_FUNC(SPIM0_CLK, SPIM0_CLK),
+ },
+ {
+ PAD_FUNC(SPIM1_MI, SPIM1_MI),
+ PAD_FUNC_GPIO(SPIM1_CSB),
+ PAD_FUNC(SPIM1_MO, SPIM1_MO),
+ PAD_FUNC(SPIM1_CLK, SPIM1_CLK),
+ },
+ {
+ PAD_FUNC(SPIM2_MI, PIM2_MI),
+ PAD_FUNC_GPIO(SPIM2_CSB),
+ PAD_FUNC(SPIM2_MO, SPIM2_MO),
+ PAD_FUNC(SPIM2_CLK, SPIM2_CLK),
+ },
+ {
+ PAD_FUNC(PWRAP_SPI_MI, SPIM3_MI),
+ PAD_FUNC_GPIO(PWRAP_SPI_CSN),
+ PAD_FUNC(PWRAP_SPI_MO, SPIM3_MO),
+ PAD_FUNC(PWRAP_SPI_CK, SPIM3_CLK),
+ },
+ {
+ PAD_FUNC(DGI_D3, SPIM4_MI),
+ PAD_FUNC_GPIO(DGI_D2),
+ PAD_FUNC(DGI_D1, SPIM4_MO),
+ PAD_FUNC(DGI_D0, SPIM4_CLK),
+ },
+ {
+ PAD_FUNC(DGI_D7, SPIM5_MI),
+ PAD_FUNC_GPIO(DGI_D6),
+ PAD_FUNC(DGI_D5, SPIM5_MO),
+ PAD_FUNC(DGI_D4, SPIM5_CLK),
+ },
+};
+
+void mtk_spi_set_gpio_pinmux(unsigned int bus, enum spi_pad_mask pad_select)
+{
+ assert(bus < SPI_BUS_NUMBER);
+ assert(pad_select == SPI_PAD0_MASK);
+ const struct pad_func *ptr = NULL;
+
+ ptr = pad0_funcs[bus];
+ for (int i = 0; i < 4; i++)
+ gpio_set_mode((gpio_t){.id = ptr[i].pin_id}, ptr[i].func);
+}
+
static const struct spi_ctrlr spi_flash_ctrlr = {
.max_xfer_size = 65535,
};
const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
{
+ .ctrlr = &spi_ctrlr,
+ .bus_start = 0,
+ .bus_end = SPI_BUS_NUMBER - 1,
+ },
+ {
.ctrlr = &spi_flash_ctrlr,
},
};