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>
This commit is contained in:
Qii Wang 2021-02-05 10:32:25 +08:00 committed by Hung-Te Lin
parent 47095d5ec3
commit f46e2caebe
4 changed files with 114 additions and 5 deletions

View File

@ -4,13 +4,13 @@ bootblock-y += bootblock.c
bootblock-y += ../common/gpio.c gpio.c bootblock-y += ../common/gpio.c gpio.c
bootblock-y += ../common/mmu_operations.c bootblock-y += ../common/mmu_operations.c
bootblock-y += ../common/pll.c pll.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/timer.c timer.c
bootblock-y += ../common/uart.c bootblock-y += ../common/uart.c
bootblock-y += ../common/wdt.c bootblock-y += ../common/wdt.c
verstage-y += ../common/gpio.c gpio.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/timer.c timer.c
verstage-y += ../common/uart.c verstage-y += ../common/uart.c
verstage-y += ../common/wdt.c verstage-y += ../common/wdt.c
@ -19,7 +19,7 @@ romstage-y += ../common/cbmem.c
romstage-y += emi.c romstage-y += emi.c
romstage-y += ../common/gpio.c gpio.c romstage-y += ../common/gpio.c gpio.c
romstage-y += ../common/pll.c pll.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/timer.c timer.c
romstage-y += ../common/uart.c romstage-y += ../common/uart.c
romstage-y += ../common/wdt.c romstage-y += ../common/wdt.c
@ -31,7 +31,7 @@ romstage-y += ../common/mt6359p.c mt6359p.c
ramstage-y += emi.c ramstage-y += emi.c
ramstage-y += ../common/gpio.c gpio.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 += soc.c
ramstage-y += ../common/timer.c timer.c ramstage-y += ../common/timer.c timer.c
ramstage-y += ../common/uart.c ramstage-y += ../common/uart.c

View File

@ -562,10 +562,12 @@ enum {
/* top_div rate */ /* top_div rate */
enum { enum {
CLK26M_HZ = 26 * MHz, CLK26M_HZ = 26 * MHz,
UNIVPLL_D6_D2_HZ = UNIVPLL_HZ / 6 / 2,
}; };
/* top_mux rate */ /* top_mux rate */
enum { enum {
SPI_HZ = UNIVPLL_D6_D2_HZ,
UART_HZ = CLK26M_HZ, UART_HZ = CLK26M_HZ,
}; };

View File

@ -3,6 +3,21 @@
#ifndef MTK_MT8195_SPI_H #ifndef MTK_MT8195_SPI_H
#define 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 #endif

View File

@ -1,14 +1,106 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h>
#include <device/mmio.h> #include <device/mmio.h>
#include <soc/addressmap.h> #include <soc/addressmap.h>
#include <soc/gpio.h>
#include <soc/spi.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 = { static const struct spi_ctrlr spi_flash_ctrlr = {
.max_xfer_size = 65535, .max_xfer_size = 65535,
}; };
const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { 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, .ctrlr = &spi_flash_ctrlr,
}, },