blob: 87362dc33c85ed36e6c2f110cc8bea834d42c815 [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Tristan Shieh3ddf57e2018-05-31 09:20:53 +08002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
mengqi.zhang9faa5842018-07-02 23:23:00 +08004#include <assert.h>
5#include <spi_flash.h>
6#include <soc/addressmap.h>
Tristan Shieh3ddf57e2018-05-31 09:20:53 +08007#include <soc/flash_controller.h>
mengqi.zhang9faa5842018-07-02 23:23:00 +08008#include <soc/gpio.h>
9#include <soc/spi.h>
Tristan Shieh3ddf57e2018-05-31 09:20:53 +080010
mengqi.zhang9faa5842018-07-02 23:23:00 +080011struct mtk_spi_bus spi_bus[SPI_BUS_NUMBER] = {
12 {
13 .regs = (void *)SPI0_BASE,
Yu-Ping Wu4b304782019-08-16 13:38:32 +080014 .cs_gpio = GPIO(SPI_CSB),
mengqi.zhang9faa5842018-07-02 23:23:00 +080015 },
16 {
17 .regs = (void *)SPI1_BASE,
Yu-Ping Wu4b304782019-08-16 13:38:32 +080018 .cs_gpio = GPIO(SPI1_CSB),
mengqi.zhang9faa5842018-07-02 23:23:00 +080019 },
20 {
21 .regs = (void *)SPI2_BASE,
Yu-Ping Wu4b304782019-08-16 13:38:32 +080022 .cs_gpio = GPIO(EINT0),
mengqi.zhang9faa5842018-07-02 23:23:00 +080023 },
24 {
25 .regs = (void *)SPI3_BASE,
Yu-Ping Wu4b304782019-08-16 13:38:32 +080026 .cs_gpio = GPIO(DPI_D9),
mengqi.zhang9faa5842018-07-02 23:23:00 +080027 },
28 {
29 .regs = (void *)SPI4_BASE,
Yu-Ping Wu4b304782019-08-16 13:38:32 +080030 .cs_gpio = GPIO(DPI_D5),
mengqi.zhang9faa5842018-07-02 23:23:00 +080031 },
32 {
33 .regs = (void *)SPI5_BASE,
Yu-Ping Wu4b304782019-08-16 13:38:32 +080034 .cs_gpio = GPIO(DPI_D1),
mengqi.zhang9faa5842018-07-02 23:23:00 +080035 }
Tristan Shieh3ddf57e2018-05-31 09:20:53 +080036};
37
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080038struct pad_func {
39 u8 pin_id;
40 u8 func;
41};
42
43#define PAD_FUNC(name, func) {PAD_##name##_ID, PAD_##name##_FUNC_##func}
Yu-Ping Wu4b304782019-08-16 13:38:32 +080044#define PAD_FUNC_GPIO(name) {PAD_##name##_ID, 0}
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080045
46static const struct pad_func pad0_funcs[SPI_BUS_NUMBER][4] = {
47 {
48 PAD_FUNC(SPI_MI, SPI0_MI),
Yu-Ping Wu4b304782019-08-16 13:38:32 +080049 PAD_FUNC_GPIO(SPI_CSB),
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080050 PAD_FUNC(SPI_MO, SPI0_MO),
51 PAD_FUNC(SPI_CLK, SPI0_CLK),
52 },
53 {
54 PAD_FUNC(SPI1_MI, SPI1_A_MI),
Yu-Ping Wu4b304782019-08-16 13:38:32 +080055 PAD_FUNC_GPIO(SPI1_CSB),
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080056 PAD_FUNC(SPI1_MO, SPI1_A_MO),
57 PAD_FUNC(SPI1_CLK, SPI1_A_CLK),
58 },
59 {
60 PAD_FUNC(KPCOL1, SPI2_MI),
Yu-Ping Wu4b304782019-08-16 13:38:32 +080061 PAD_FUNC_GPIO(EINT0),
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080062 PAD_FUNC(EINT1, SPI2_MO),
63 PAD_FUNC(EINT2, SPI2_CLK),
64 },
65 {
66 PAD_FUNC(DPI_D8, SPI3_MI),
Yu-Ping Wu4b304782019-08-16 13:38:32 +080067 PAD_FUNC_GPIO(DPI_D9),
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080068 PAD_FUNC(DPI_D10, SPI3_MO),
69 PAD_FUNC(DPI_D11, SPI3_CLK),
70 },
71 {
72 PAD_FUNC(DPI_D4, SPI4_MI),
Yu-Ping Wu4b304782019-08-16 13:38:32 +080073 PAD_FUNC_GPIO(DPI_D5),
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080074 PAD_FUNC(DPI_D6, SPI4_MO),
75 PAD_FUNC(DPI_D7, SPI4_CLK),
76 },
77 {
78 PAD_FUNC(DPI_D0, SPI5_MI),
Yu-Ping Wu4b304782019-08-16 13:38:32 +080079 PAD_FUNC_GPIO(DPI_D1),
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080080 PAD_FUNC(DPI_D2, SPI5_MO),
81 PAD_FUNC(DPI_D3, SPI5_CLK),
mengqi.zhang9faa5842018-07-02 23:23:00 +080082 }
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080083};
84
85static const struct pad_func bus1_pad1_funcs[4] = {
86 PAD_FUNC(EINT7, SPI1_B_MI),
Yu-Ping Wu4b304782019-08-16 13:38:32 +080087 PAD_FUNC_GPIO(EINT8),
You-Cheng Syu14df2ef2018-12-20 15:41:25 +080088 PAD_FUNC(EINT9, SPI1_B_MO),
89 PAD_FUNC(EINT10, SPI1_B_CLK),
90};
91
92void mtk_spi_set_gpio_pinmux(unsigned int bus, enum spi_pad_mask pad_select)
93{
94 assert(bus < SPI_BUS_NUMBER);
95 const struct pad_func *ptr;
96 if (pad_select == SPI_PAD0_MASK) {
97 ptr = pad0_funcs[bus];
98 } else {
99 assert(bus == 1 && pad_select == SPI_PAD1_MASK);
100 ptr = bus1_pad1_funcs;
101 }
102 for (int i = 0; i < 4; i++)
103 gpio_set_mode((gpio_t){.id = ptr[i].pin_id}, ptr[i].func);
mengqi.zhang9faa5842018-07-02 23:23:00 +0800104}
105
Mengqi Zhang026be3d2019-04-24 11:11:52 +0800106void mtk_spi_set_timing(struct mtk_spi_regs *regs, u32 sck_ticks, u32 cs_ticks,
107 unsigned int tick_dly)
mengqi.zhang9faa5842018-07-02 23:23:00 +0800108{
109 write32(&regs->spi_cfg0_reg,
110 ((cs_ticks - 1) << SPI_CFG0_CS_HOLD_SHIFT) |
111 ((cs_ticks - 1) << SPI_CFG0_CS_SETUP_SHIFT));
112
113 write32(&regs->spi_cfg2_reg,
114 ((sck_ticks - 1) << SPI_CFG2_SCK_HIGH_SHIFT) |
115 ((sck_ticks - 1) << SPI_CFG2_SCK_LOW_SHIFT));
116
Julius Werner55009af2019-12-02 22:03:27 -0800117 clrsetbits32(&regs->spi_cfg1_reg, SPI_CFG1_TICK_DLY_MASK |
118 SPI_CFG1_CS_IDLE_MASK,
119 (tick_dly << SPI_CFG1_TICK_DLY_SHIFT) |
120 ((cs_ticks - 1) << SPI_CFG1_CS_IDLE_SHIFT));
mengqi.zhang9faa5842018-07-02 23:23:00 +0800121}
122
Tristan Shieh3ddf57e2018-05-31 09:20:53 +0800123const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
124 {
mengqi.zhang9faa5842018-07-02 23:23:00 +0800125 .ctrlr = &spi_ctrlr,
126 .bus_start = 0,
127 .bus_end = SPI_BUS_NUMBER - 1,
Tristan Shieh3ddf57e2018-05-31 09:20:53 +0800128 },
129};
130
131const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);