Angel Pons | e67ab18 | 2020-04-04 18:51:11 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Tristan Shieh | 3ddf57e | 2018-05-31 09:20:53 +0800 | [diff] [blame] | 2 | |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 3 | #include <device/mmio.h> |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 4 | #include <assert.h> |
| 5 | #include <spi_flash.h> |
| 6 | #include <soc/addressmap.h> |
Tristan Shieh | 3ddf57e | 2018-05-31 09:20:53 +0800 | [diff] [blame] | 7 | #include <soc/flash_controller.h> |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 8 | #include <soc/gpio.h> |
| 9 | #include <soc/spi.h> |
Tristan Shieh | 3ddf57e | 2018-05-31 09:20:53 +0800 | [diff] [blame] | 10 | |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 11 | struct mtk_spi_bus spi_bus[SPI_BUS_NUMBER] = { |
| 12 | { |
| 13 | .regs = (void *)SPI0_BASE, |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 14 | .cs_gpio = GPIO(SPI_CSB), |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 15 | }, |
| 16 | { |
| 17 | .regs = (void *)SPI1_BASE, |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 18 | .cs_gpio = GPIO(SPI1_CSB), |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 19 | }, |
| 20 | { |
| 21 | .regs = (void *)SPI2_BASE, |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 22 | .cs_gpio = GPIO(EINT0), |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 23 | }, |
| 24 | { |
| 25 | .regs = (void *)SPI3_BASE, |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 26 | .cs_gpio = GPIO(DPI_D9), |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 27 | }, |
| 28 | { |
| 29 | .regs = (void *)SPI4_BASE, |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 30 | .cs_gpio = GPIO(DPI_D5), |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 31 | }, |
| 32 | { |
| 33 | .regs = (void *)SPI5_BASE, |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 34 | .cs_gpio = GPIO(DPI_D1), |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 35 | } |
Tristan Shieh | 3ddf57e | 2018-05-31 09:20:53 +0800 | [diff] [blame] | 36 | }; |
| 37 | |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 38 | struct 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 Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 44 | #define PAD_FUNC_GPIO(name) {PAD_##name##_ID, 0} |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 45 | |
| 46 | static const struct pad_func pad0_funcs[SPI_BUS_NUMBER][4] = { |
| 47 | { |
| 48 | PAD_FUNC(SPI_MI, SPI0_MI), |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 49 | PAD_FUNC_GPIO(SPI_CSB), |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 50 | 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 Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 55 | PAD_FUNC_GPIO(SPI1_CSB), |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 56 | 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 Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 61 | PAD_FUNC_GPIO(EINT0), |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 62 | PAD_FUNC(EINT1, SPI2_MO), |
| 63 | PAD_FUNC(EINT2, SPI2_CLK), |
| 64 | }, |
| 65 | { |
| 66 | PAD_FUNC(DPI_D8, SPI3_MI), |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 67 | PAD_FUNC_GPIO(DPI_D9), |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 68 | PAD_FUNC(DPI_D10, SPI3_MO), |
| 69 | PAD_FUNC(DPI_D11, SPI3_CLK), |
| 70 | }, |
| 71 | { |
| 72 | PAD_FUNC(DPI_D4, SPI4_MI), |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 73 | PAD_FUNC_GPIO(DPI_D5), |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 74 | PAD_FUNC(DPI_D6, SPI4_MO), |
| 75 | PAD_FUNC(DPI_D7, SPI4_CLK), |
| 76 | }, |
| 77 | { |
| 78 | PAD_FUNC(DPI_D0, SPI5_MI), |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 79 | PAD_FUNC_GPIO(DPI_D1), |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 80 | PAD_FUNC(DPI_D2, SPI5_MO), |
| 81 | PAD_FUNC(DPI_D3, SPI5_CLK), |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 82 | } |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 83 | }; |
| 84 | |
| 85 | static const struct pad_func bus1_pad1_funcs[4] = { |
| 86 | PAD_FUNC(EINT7, SPI1_B_MI), |
Yu-Ping Wu | 4b30478 | 2019-08-16 13:38:32 +0800 | [diff] [blame] | 87 | PAD_FUNC_GPIO(EINT8), |
You-Cheng Syu | 14df2ef | 2018-12-20 15:41:25 +0800 | [diff] [blame] | 88 | PAD_FUNC(EINT9, SPI1_B_MO), |
| 89 | PAD_FUNC(EINT10, SPI1_B_CLK), |
| 90 | }; |
| 91 | |
| 92 | void 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.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 104 | } |
| 105 | |
Mengqi Zhang | 026be3d | 2019-04-24 11:11:52 +0800 | [diff] [blame] | 106 | void mtk_spi_set_timing(struct mtk_spi_regs *regs, u32 sck_ticks, u32 cs_ticks, |
| 107 | unsigned int tick_dly) |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 108 | { |
| 109 | write32(®s->spi_cfg0_reg, |
| 110 | ((cs_ticks - 1) << SPI_CFG0_CS_HOLD_SHIFT) | |
| 111 | ((cs_ticks - 1) << SPI_CFG0_CS_SETUP_SHIFT)); |
| 112 | |
| 113 | write32(®s->spi_cfg2_reg, |
| 114 | ((sck_ticks - 1) << SPI_CFG2_SCK_HIGH_SHIFT) | |
| 115 | ((sck_ticks - 1) << SPI_CFG2_SCK_LOW_SHIFT)); |
| 116 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 117 | clrsetbits32(®s->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.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 121 | } |
| 122 | |
Tristan Shieh | 3ddf57e | 2018-05-31 09:20:53 +0800 | [diff] [blame] | 123 | const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { |
| 124 | { |
mengqi.zhang | 9faa584 | 2018-07-02 23:23:00 +0800 | [diff] [blame] | 125 | .ctrlr = &spi_ctrlr, |
| 126 | .bus_start = 0, |
| 127 | .bus_end = SPI_BUS_NUMBER - 1, |
Tristan Shieh | 3ddf57e | 2018-05-31 09:20:53 +0800 | [diff] [blame] | 128 | }, |
| 129 | }; |
| 130 | |
| 131 | const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); |