From 9faa584cc94e4254d8cba7672671e11f9dc0c893 Mon Sep 17 00:00:00 2001 From: "mengqi.zhang" Date: Mon, 2 Jul 2018 23:23:00 +0800 Subject: mediatek/mt8183: Add SPI support This patch implements SOC-specific code of mt8183 and link the common code to support SPI bus. BUG=b:80501386 BRANCH=none TEST=Boots correctly on Kukui Signed-off-by: mengqi.zhang Change-Id: I544e850299c74861313c2425721479fe5b91639e Reviewed-on: https://review.coreboot.org/27498 Tested-by: build bot (Jenkins) Reviewed-by: Hung-Te Lin Reviewed-by: Julius Werner --- src/soc/mediatek/mt8183/Makefile.inc | 8 +- src/soc/mediatek/mt8183/include/soc/addressmap.h | 6 ++ src/soc/mediatek/mt8183/include/soc/pll.h | 7 ++ src/soc/mediatek/mt8183/include/soc/spi.h | 53 +++++++++++ src/soc/mediatek/mt8183/spi.c | 111 ++++++++++++++++++++++- 5 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 src/soc/mediatek/mt8183/include/soc/spi.h (limited to 'src/soc/mediatek') diff --git a/src/soc/mediatek/mt8183/Makefile.inc b/src/soc/mediatek/mt8183/Makefile.inc index 1b3f9d57b7..bd0e54fc80 100644 --- a/src/soc/mediatek/mt8183/Makefile.inc +++ b/src/soc/mediatek/mt8183/Makefile.inc @@ -3,7 +3,7 @@ ifeq ($(CONFIG_SOC_MEDIATEK_MT8183),y) bootblock-y += bootblock.c bootblock-y += ../common/gpio.c gpio.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 ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y) bootblock-$(CONFIG_DRIVERS_UART) += ../common/uart.c @@ -15,7 +15,7 @@ decompressor-y += ../common/mmu_operations.c decompressor-y += ../common/timer.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 verstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c verstage-y += ../common/wdt.c @@ -23,7 +23,7 @@ verstage-y += ../common/wdt.c romstage-y += emi.c romstage-y += ../common/gpio.c gpio.c romstage-y += ../common/mmu_operations.c mmu_operations.c -romstage-$(CONFIG_SPI_FLASH) += spi.c +romstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c romstage-y += ../common/timer.c romstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c romstage-y += ../common/wdt.c @@ -33,7 +33,7 @@ ramstage-y += ../common/gpio.c gpio.c ramstage-y += ../common/mmu_operations.c mmu_operations.c ramstage-y += ../common/mtcmos.c mtcmos.c ramstage-y += soc.c -ramstage-$(CONFIG_SPI_FLASH) += spi.c +ramstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c ramstage-y += ../common/timer.c ramstage-$(CONFIG_DRIVERS_UART) += ../common/uart.c ramstage-y += ../common/wdt.c diff --git a/src/soc/mediatek/mt8183/include/soc/addressmap.h b/src/soc/mediatek/mt8183/include/soc/addressmap.h index d6f54cf5dd..de7eb1f1cb 100644 --- a/src/soc/mediatek/mt8183/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8183/include/soc/addressmap.h @@ -31,6 +31,12 @@ enum { GPT_BASE = IO_PHYS + 0x00008000, APMIXED_BASE = IO_PHYS + 0x0000C000, UART0_BASE = IO_PHYS + 0x01002000, + SPI0_BASE = IO_PHYS + 0x0100A000, + SPI1_BASE = IO_PHYS + 0x01010000, + SPI2_BASE = IO_PHYS + 0x01012000, + SPI3_BASE = IO_PHYS + 0x01013000, + SPI4_BASE = IO_PHYS + 0x01014000, + SPI5_BASE = IO_PHYS + 0x01015000, IOCFG_RT_BASE = IO_PHYS + 0x01C50000, IOCFG_RM_BASE = IO_PHYS + 0x01D20000, IOCFG_RB_BASE = IO_PHYS + 0x01D30000, diff --git a/src/soc/mediatek/mt8183/include/soc/pll.h b/src/soc/mediatek/mt8183/include/soc/pll.h index d1ceded812..8c0d4e3a2d 100644 --- a/src/soc/mediatek/mt8183/include/soc/pll.h +++ b/src/soc/mediatek/mt8183/include/soc/pll.h @@ -260,6 +260,13 @@ enum { /* top_div rate */ enum { CLK26M_HZ = 26 * MHz, + MAINPLL_D5_HZ = MAINPLL_HZ / 5, + MAINPLL_D5_D2_HZ = MAINPLL_D5_HZ / 2, +}; + +/* top_mux rate */ +enum { + SPI_HZ = MAINPLL_D5_D2_HZ, }; #endif /* SOC_MEDIATEK_MT8183_PLL_H */ diff --git a/src/soc/mediatek/mt8183/include/soc/spi.h b/src/soc/mediatek/mt8183/include/soc/spi.h new file mode 100644 index 0000000000..9bc7121847 --- /dev/null +++ b/src/soc/mediatek/mt8183/include/soc/spi.h @@ -0,0 +1,53 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018 MediaTek Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MTK_MT8183_SPI_H +#define MTK_MT8183_SPI_H + +#include + +#define SPI_BUS_NUMBER 6 + +/* SPI peripheral register map. */ +typedef struct mtk_spi_regs { + uint32_t spi_cfg0_reg; + uint32_t spi_cfg1_reg; + uint32_t spi_tx_src_reg; + uint32_t spi_rx_dst_reg; + uint32_t spi_tx_data_reg; + uint32_t spi_rx_data_reg; + uint32_t spi_cmd_reg; + uint32_t spi_status0_reg; + uint32_t spi_status1_reg; + uint32_t spi_pad_macro_sel_reg; + uint32_t spi_cfg2_reg; + uint32_t spi_tx_src_64_reg; + uint32_t spi_rx_dst_64_reg; +} mtk_spi_regs; + +check_member(mtk_spi_regs, spi_pad_macro_sel_reg, 0x24); + +enum { + SPI_CFG0_CS_HOLD_SHIFT = 0, + SPI_CFG0_CS_SETUP_SHIFT = 16, +}; + +enum { + SPI_CFG2_SCK_LOW_SHIFT = 0, + SPI_CFG2_SCK_HIGH_SHIFT = 16, +}; + + +#endif diff --git a/src/soc/mediatek/mt8183/spi.c b/src/soc/mediatek/mt8183/spi.c index d85138cfb0..0088d46a02 100644 --- a/src/soc/mediatek/mt8183/spi.c +++ b/src/soc/mediatek/mt8183/spi.c @@ -13,16 +13,119 @@ * GNU General Public License for more details. */ +#include +#include +#include +#include #include -#include +#include +#include -static const struct spi_ctrlr spi_flash_ctrlr = { - .max_xfer_size = 65535, +struct mtk_spi_bus spi_bus[SPI_BUS_NUMBER] = { + { + .regs = (void *)SPI0_BASE, + }, + { + .regs = (void *)SPI1_BASE, + }, + { + .regs = (void *)SPI2_BASE, + }, + { + .regs = (void *)SPI3_BASE, + }, + { + .regs = (void *)SPI4_BASE, + }, + { + .regs = (void *)SPI5_BASE, + } }; +void mtk_spi_set_gpio_pinmux(unsigned int bus, + enum spi_pad_mask pad_select) +{ + switch (bus) { + case 0: + if (pad_select == SPI_PAD0_MASK) { + gpio_set_mode(GPIO(SPI_MI), PAD_SPI_MI_FUNC_SPI0_MI); + gpio_set_mode(GPIO(SPI_CSB), PAD_SPI_CSB_FUNC_SPI0_CSB); + gpio_set_mode(GPIO(SPI_MO), PAD_SPI_MO_FUNC_SPI0_MO); + gpio_set_mode(GPIO(SPI_CLK), PAD_SPI_CLK_FUNC_SPI0_CLK); + } + break; + case 1: + if (pad_select == SPI_PAD0_MASK) { + gpio_set_mode(GPIO(SPI1_MI), + PAD_SPI1_MI_FUNC_SPI1_A_MI); + gpio_set_mode(GPIO(SPI1_CSB), + PAD_SPI1_CSB_FUNC_SPI1_A_CSB); + gpio_set_mode(GPIO(SPI1_MO), + PAD_SPI1_MO_FUNC_SPI1_A_MO); + gpio_set_mode(GPIO(SPI1_CLK), + PAD_SPI1_CLK_FUNC_SPI1_A_CLK); + } + if (pad_select == SPI_PAD1_MASK) { + gpio_set_mode(GPIO(EINT7), PAD_EINT7_FUNC_SPI1_B_MI); + gpio_set_mode(GPIO(EINT8), PAD_EINT8_FUNC_SPI1_B_CSB); + gpio_set_mode(GPIO(EINT9), PAD_EINT9_FUNC_SPI1_B_MO); + gpio_set_mode(GPIO(EINT10), PAD_EINT10_FUNC_SPI1_B_CLK); + } + break; + case 2: + if (pad_select == SPI_PAD0_MASK) { + gpio_set_mode(GPIO(KPCOL1), PAD_KPCOL1_FUNC_SPI2_MI); + gpio_set_mode(GPIO(EINT0), PAD_EINT0_FUNC_SPI2_CSB); + gpio_set_mode(GPIO(EINT1), PAD_EINT1_FUNC_SPI2_MO); + gpio_set_mode(GPIO(EINT2), PAD_EINT2_FUNC_SPI2_CLK); + } + break; + case 3: + if (pad_select == SPI_PAD0_MASK) { + gpio_set_mode(GPIO(DPI_D8), PAD_DPI_D8_FUNC_SPI3_MI); + gpio_set_mode(GPIO(DPI_D9), PAD_DPI_D9_FUNC_SPI3_CSB); + gpio_set_mode(GPIO(DPI_D10), PAD_DPI_D10_FUNC_SPI3_MO); + gpio_set_mode(GPIO(DPI_D11), PAD_DPI_D11_FUNC_SPI3_CLK); + } + break; + case 4: + if (pad_select == SPI_PAD0_MASK) { + gpio_set_mode(GPIO(DPI_D4), PAD_DPI_D4_FUNC_SPI4_MI); + gpio_set_mode(GPIO(DPI_D5), PAD_DPI_D5_FUNC_SPI4_CSB); + gpio_set_mode(GPIO(DPI_D6), PAD_DPI_D6_FUNC_SPI4_MO); + gpio_set_mode(GPIO(DPI_D7), PAD_DPI_D7_FUNC_SPI4_CLK); + } + break; + case 5: + if (pad_select == SPI_PAD0_MASK) { + gpio_set_mode(GPIO(DPI_D0), PAD_DPI_D0_FUNC_SPI5_MI); + gpio_set_mode(GPIO(DPI_D1), PAD_DPI_D1_FUNC_SPI5_CSB); + gpio_set_mode(GPIO(DPI_D2), PAD_DPI_D2_FUNC_SPI5_MO); + gpio_set_mode(GPIO(DPI_D3), PAD_DPI_D3_FUNC_SPI5_CLK); + } + break; + } +} + +void mtk_spi_set_timing(struct mtk_spi_regs *regs, u32 sck_ticks, u32 cs_ticks) +{ + write32(®s->spi_cfg0_reg, + ((cs_ticks - 1) << SPI_CFG0_CS_HOLD_SHIFT) | + ((cs_ticks - 1) << SPI_CFG0_CS_SETUP_SHIFT)); + + write32(®s->spi_cfg2_reg, + ((sck_ticks - 1) << SPI_CFG2_SCK_HIGH_SHIFT) | + ((sck_ticks - 1) << SPI_CFG2_SCK_LOW_SHIFT)); + + clrsetbits_le32(®s->spi_cfg1_reg, SPI_CFG1_CS_IDLE_MASK, + ((cs_ticks - 1) << SPI_CFG1_CS_IDLE_SHIFT)); +} + const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { { - .ctrlr = &spi_flash_ctrlr, + .ctrlr = &spi_ctrlr, + .bus_start = 0, + .bus_end = SPI_BUS_NUMBER - 1, }, }; -- cgit v1.2.3