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