1 /* 2 * (C) Copyright 2009 3 * Marvell Semiconductor <www.marvell.com> 4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com> 5 * 6 * Derived from drivers/spi/mpc8xxx_spi.c 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <malloc.h> 13 #include <spi.h> 14 #include <asm/io.h> 15 #include <asm/arch/soc.h> 16 #ifdef CONFIG_KIRKWOOD 17 #include <asm/arch/mpp.h> 18 #endif 19 #include <asm/arch-mvebu/spi.h> 20 21 static struct kwspi_registers *spireg = (struct kwspi_registers *)KW_SPI_BASE; 22 23 #ifdef CONFIG_KIRKWOOD 24 static u32 cs_spi_mpp_back[2]; 25 #endif 26 27 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, 28 unsigned int max_hz, unsigned int mode) 29 { 30 struct spi_slave *slave; 31 u32 data; 32 #ifdef CONFIG_KIRKWOOD 33 static const u32 kwspi_mpp_config[2][2] = { 34 { MPP0_SPI_SCn, 0 }, /* if cs == 0 */ 35 { MPP7_SPI_SCn, 0 } /* if cs != 0 */ 36 }; 37 #endif 38 39 if (!spi_cs_is_valid(bus, cs)) 40 return NULL; 41 42 slave = spi_alloc_slave_base(bus, cs); 43 if (!slave) 44 return NULL; 45 46 writel(KWSPI_SMEMRDY, &spireg->ctrl); 47 48 /* calculate spi clock prescaller using max_hz */ 49 data = ((CONFIG_SYS_TCLK / 2) / max_hz) + 0x10; 50 data = data < KWSPI_CLKPRESCL_MIN ? KWSPI_CLKPRESCL_MIN : data; 51 data = data > KWSPI_CLKPRESCL_MASK ? KWSPI_CLKPRESCL_MASK : data; 52 53 /* program spi clock prescaller using max_hz */ 54 writel(KWSPI_ADRLEN_3BYTE | data, &spireg->cfg); 55 debug("data = 0x%08x\n", data); 56 57 writel(KWSPI_SMEMRDIRQ, &spireg->irq_cause); 58 writel(KWSPI_IRQMASK, &spireg->irq_mask); 59 60 #ifdef CONFIG_KIRKWOOD 61 /* program mpp registers to select SPI_CSn */ 62 kirkwood_mpp_conf(kwspi_mpp_config[cs ? 1 : 0], cs_spi_mpp_back); 63 #endif 64 65 return slave; 66 } 67 68 void spi_free_slave(struct spi_slave *slave) 69 { 70 #ifdef CONFIG_KIRKWOOD 71 kirkwood_mpp_conf(cs_spi_mpp_back, NULL); 72 #endif 73 free(slave); 74 } 75 76 #if defined(CONFIG_SYS_KW_SPI_MPP) 77 u32 spi_mpp_backup[4]; 78 #endif 79 80 __attribute__((weak)) int board_spi_claim_bus(struct spi_slave *slave) 81 { 82 return 0; 83 } 84 85 int spi_claim_bus(struct spi_slave *slave) 86 { 87 #if defined(CONFIG_SYS_KW_SPI_MPP) 88 u32 config; 89 u32 spi_mpp_config[4]; 90 91 config = CONFIG_SYS_KW_SPI_MPP; 92 93 if (config & MOSI_MPP6) 94 spi_mpp_config[0] = MPP6_SPI_MOSI; 95 else 96 spi_mpp_config[0] = MPP1_SPI_MOSI; 97 98 if (config & SCK_MPP10) 99 spi_mpp_config[1] = MPP10_SPI_SCK; 100 else 101 spi_mpp_config[1] = MPP2_SPI_SCK; 102 103 if (config & MISO_MPP11) 104 spi_mpp_config[2] = MPP11_SPI_MISO; 105 else 106 spi_mpp_config[2] = MPP3_SPI_MISO; 107 108 spi_mpp_config[3] = 0; 109 spi_mpp_backup[3] = 0; 110 111 /* set new spi mpp and save current mpp config */ 112 kirkwood_mpp_conf(spi_mpp_config, spi_mpp_backup); 113 #endif 114 115 return board_spi_claim_bus(slave); 116 } 117 118 __attribute__((weak)) void board_spi_release_bus(struct spi_slave *slave) 119 { 120 } 121 122 void spi_release_bus(struct spi_slave *slave) 123 { 124 #if defined(CONFIG_SYS_KW_SPI_MPP) 125 kirkwood_mpp_conf(spi_mpp_backup, NULL); 126 #endif 127 128 board_spi_release_bus(slave); 129 } 130 131 #ifndef CONFIG_SPI_CS_IS_VALID 132 /* 133 * you can define this function board specific 134 * define above CONFIG in board specific config file and 135 * provide the function in board specific src file 136 */ 137 int spi_cs_is_valid(unsigned int bus, unsigned int cs) 138 { 139 return bus == 0 && (cs == 0 || cs == 1); 140 } 141 #endif 142 143 void spi_init(void) 144 { 145 } 146 147 void spi_cs_activate(struct spi_slave *slave) 148 { 149 setbits_le32(&spireg->ctrl, KWSPI_CSN_ACT); 150 } 151 152 void spi_cs_deactivate(struct spi_slave *slave) 153 { 154 clrbits_le32(&spireg->ctrl, KWSPI_CSN_ACT); 155 } 156 157 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, 158 void *din, unsigned long flags) 159 { 160 unsigned int tmpdout, tmpdin; 161 int tm, isread = 0; 162 163 debug("spi_xfer: slave %u:%u dout %p din %p bitlen %u\n", 164 slave->bus, slave->cs, dout, din, bitlen); 165 166 if (flags & SPI_XFER_BEGIN) 167 spi_cs_activate(slave); 168 169 /* 170 * handle data in 8-bit chunks 171 * TBD: 2byte xfer mode to be enabled 172 */ 173 clrsetbits_le32(&spireg->cfg, KWSPI_XFERLEN_MASK, KWSPI_XFERLEN_1BYTE); 174 175 while (bitlen > 4) { 176 debug("loopstart bitlen %d\n", bitlen); 177 tmpdout = 0; 178 179 /* Shift data so it's msb-justified */ 180 if (dout) 181 tmpdout = *(u32 *)dout & 0xff; 182 183 clrbits_le32(&spireg->irq_cause, KWSPI_SMEMRDIRQ); 184 writel(tmpdout, &spireg->dout); /* Write the data out */ 185 debug("*** spi_xfer: ... %08x written, bitlen %d\n", 186 tmpdout, bitlen); 187 188 /* 189 * Wait for SPI transmit to get out 190 * or time out (1 second = 1000 ms) 191 * The NE event must be read and cleared first 192 */ 193 for (tm = 0, isread = 0; tm < KWSPI_TIMEOUT; ++tm) { 194 if (readl(&spireg->irq_cause) & KWSPI_SMEMRDIRQ) { 195 isread = 1; 196 tmpdin = readl(&spireg->din); 197 debug("spi_xfer: din %p..%08x read\n", 198 din, tmpdin); 199 200 if (din) { 201 *((u8 *)din) = (u8)tmpdin; 202 din += 1; 203 } 204 if (dout) 205 dout += 1; 206 bitlen -= 8; 207 } 208 if (isread) 209 break; 210 } 211 if (tm >= KWSPI_TIMEOUT) 212 printf("*** spi_xfer: Time out during SPI transfer\n"); 213 214 debug("loopend bitlen %d\n", bitlen); 215 } 216 217 if (flags & SPI_XFER_END) 218 spi_cs_deactivate(slave); 219 220 return 0; 221 } 222