1 /* 2 * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com> 3 * 4 * Driver for McSPI controller on OMAP3. Based on davinci_spi.c 5 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 6 * 7 * Copyright (C) 2007 Atmel Corporation 8 * 9 * Parts taken from linux/drivers/spi/omap2_mcspi.c 10 * Copyright (C) 2005, 2006 Nokia Corporation 11 * 12 * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com> 13 * 14 * SPDX-License-Identifier: GPL-2.0+ 15 */ 16 17 #include <common.h> 18 #include <spi.h> 19 #include <malloc.h> 20 #include <asm/io.h> 21 #include "omap3_spi.h" 22 23 #define WORD_LEN 8 24 #define SPI_WAIT_TIMEOUT 3000000; 25 26 static void spi_reset(struct omap3_spi_slave *ds) 27 { 28 unsigned int tmp; 29 30 writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &ds->regs->sysconfig); 31 do { 32 tmp = readl(&ds->regs->sysstatus); 33 } while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE)); 34 35 writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE | 36 OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP | 37 OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, 38 &ds->regs->sysconfig); 39 40 writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &ds->regs->wakeupenable); 41 } 42 43 static void omap3_spi_write_chconf(struct omap3_spi_slave *ds, int val) 44 { 45 writel(val, &ds->regs->channel[ds->slave.cs].chconf); 46 /* Flash post writes to make immediate effect */ 47 readl(&ds->regs->channel[ds->slave.cs].chconf); 48 } 49 50 static void omap3_spi_set_enable(struct omap3_spi_slave *ds, int enable) 51 { 52 writel(enable, &ds->regs->channel[ds->slave.cs].chctrl); 53 /* Flash post writes to make immediate effect */ 54 readl(&ds->regs->channel[ds->slave.cs].chctrl); 55 } 56 57 void spi_init() 58 { 59 /* do nothing */ 60 } 61 62 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, 63 unsigned int max_hz, unsigned int mode) 64 { 65 struct omap3_spi_slave *ds; 66 struct mcspi *regs; 67 68 /* 69 * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules) 70 * with different number of chip selects (CS, channels): 71 * McSPI1 has 4 CS (bus 0, cs 0 - 3) 72 * McSPI2 has 2 CS (bus 1, cs 0 - 1) 73 * McSPI3 has 2 CS (bus 2, cs 0 - 1) 74 * McSPI4 has 1 CS (bus 3, cs 0) 75 */ 76 77 switch (bus) { 78 case 0: 79 regs = (struct mcspi *)OMAP3_MCSPI1_BASE; 80 break; 81 #ifdef OMAP3_MCSPI2_BASE 82 case 1: 83 regs = (struct mcspi *)OMAP3_MCSPI2_BASE; 84 break; 85 #endif 86 #ifdef OMAP3_MCSPI3_BASE 87 case 2: 88 regs = (struct mcspi *)OMAP3_MCSPI3_BASE; 89 break; 90 #endif 91 #ifdef OMAP3_MCSPI4_BASE 92 case 3: 93 regs = (struct mcspi *)OMAP3_MCSPI4_BASE; 94 break; 95 #endif 96 default: 97 printf("SPI error: unsupported bus %i. \ 98 Supported busses 0 - 3\n", bus); 99 return NULL; 100 } 101 102 if (((bus == 0) && (cs > 3)) || 103 ((bus == 1) && (cs > 1)) || 104 ((bus == 2) && (cs > 1)) || 105 ((bus == 3) && (cs > 0))) { 106 printf("SPI error: unsupported chip select %i \ 107 on bus %i\n", cs, bus); 108 return NULL; 109 } 110 111 if (max_hz > OMAP3_MCSPI_MAX_FREQ) { 112 printf("SPI error: unsupported frequency %i Hz. \ 113 Max frequency is 48 Mhz\n", max_hz); 114 return NULL; 115 } 116 117 if (mode > SPI_MODE_3) { 118 printf("SPI error: unsupported SPI mode %i\n", mode); 119 return NULL; 120 } 121 122 ds = spi_alloc_slave(struct omap3_spi_slave, bus, cs); 123 if (!ds) { 124 printf("SPI error: malloc of SPI structure failed\n"); 125 return NULL; 126 } 127 128 ds->regs = regs; 129 ds->freq = max_hz; 130 ds->mode = mode; 131 132 return &ds->slave; 133 } 134 135 void spi_free_slave(struct spi_slave *slave) 136 { 137 struct omap3_spi_slave *ds = to_omap3_spi(slave); 138 139 free(ds); 140 } 141 142 int spi_claim_bus(struct spi_slave *slave) 143 { 144 struct omap3_spi_slave *ds = to_omap3_spi(slave); 145 unsigned int conf, div = 0; 146 147 /* McSPI global module configuration */ 148 149 /* 150 * setup when switching from (reset default) slave mode 151 * to single-channel master mode 152 */ 153 spi_reset(ds); 154 conf = readl(&ds->regs->modulctrl); 155 conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS); 156 conf |= OMAP3_MCSPI_MODULCTRL_SINGLE; 157 writel(conf, &ds->regs->modulctrl); 158 159 /* McSPI individual channel configuration */ 160 161 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */ 162 if (ds->freq) { 163 while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div)) 164 > ds->freq) 165 div++; 166 } else 167 div = 0xC; 168 169 conf = readl(&ds->regs->channel[ds->slave.cs].chconf); 170 171 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS 172 * REVISIT: this controller could support SPI_3WIRE mode. 173 */ 174 #ifdef CONFIG_OMAP3_SPI_D0_D1_SWAPPED 175 /* 176 * Some boards have D0 wired as MOSI / D1 as MISO instead of 177 * The normal D0 as MISO / D1 as MOSI. 178 */ 179 conf &= ~OMAP3_MCSPI_CHCONF_DPE0; 180 conf |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1; 181 #else 182 conf &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1); 183 conf |= OMAP3_MCSPI_CHCONF_DPE0; 184 #endif 185 186 /* wordlength */ 187 conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK; 188 conf |= (WORD_LEN - 1) << 7; 189 190 /* set chipselect polarity; manage with FORCE */ 191 if (!(ds->mode & SPI_CS_HIGH)) 192 conf |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */ 193 else 194 conf &= ~OMAP3_MCSPI_CHCONF_EPOL; 195 196 /* set clock divisor */ 197 conf &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK; 198 conf |= div << 2; 199 200 /* set SPI mode 0..3 */ 201 if (ds->mode & SPI_CPOL) 202 conf |= OMAP3_MCSPI_CHCONF_POL; 203 else 204 conf &= ~OMAP3_MCSPI_CHCONF_POL; 205 if (ds->mode & SPI_CPHA) 206 conf |= OMAP3_MCSPI_CHCONF_PHA; 207 else 208 conf &= ~OMAP3_MCSPI_CHCONF_PHA; 209 210 /* Transmit & receive mode */ 211 conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 212 213 omap3_spi_write_chconf(ds,conf); 214 215 return 0; 216 } 217 218 void spi_release_bus(struct spi_slave *slave) 219 { 220 struct omap3_spi_slave *ds = to_omap3_spi(slave); 221 222 /* Reset the SPI hardware */ 223 spi_reset(ds); 224 } 225 226 int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp, 227 unsigned long flags) 228 { 229 struct omap3_spi_slave *ds = to_omap3_spi(slave); 230 int i; 231 int timeout = SPI_WAIT_TIMEOUT; 232 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 233 234 /* Enable the channel */ 235 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 236 237 chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 238 chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY; 239 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 240 omap3_spi_write_chconf(ds,chconf); 241 242 for (i = 0; i < len; i++) { 243 /* wait till TX register is empty (TXS == 1) */ 244 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 245 OMAP3_MCSPI_CHSTAT_TXS)) { 246 if (--timeout <= 0) { 247 printf("SPI TXS timed out, status=0x%08x\n", 248 readl(&ds->regs->channel[ds->slave.cs].chstat)); 249 return -1; 250 } 251 } 252 /* Write the data */ 253 writel(txp[i], &ds->regs->channel[ds->slave.cs].tx); 254 } 255 256 /* wait to finish of transfer */ 257 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 258 OMAP3_MCSPI_CHSTAT_EOT)); 259 260 /* Disable the channel otherwise the next immediate RX will get affected */ 261 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 262 263 if (flags & SPI_XFER_END) { 264 265 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 266 omap3_spi_write_chconf(ds,chconf); 267 } 268 return 0; 269 } 270 271 int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp, 272 unsigned long flags) 273 { 274 struct omap3_spi_slave *ds = to_omap3_spi(slave); 275 int i; 276 int timeout = SPI_WAIT_TIMEOUT; 277 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 278 279 /* Enable the channel */ 280 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 281 282 chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 283 chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY; 284 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 285 omap3_spi_write_chconf(ds,chconf); 286 287 writel(0, &ds->regs->channel[ds->slave.cs].tx); 288 289 for (i = 0; i < len; i++) { 290 /* Wait till RX register contains data (RXS == 1) */ 291 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 292 OMAP3_MCSPI_CHSTAT_RXS)) { 293 if (--timeout <= 0) { 294 printf("SPI RXS timed out, status=0x%08x\n", 295 readl(&ds->regs->channel[ds->slave.cs].chstat)); 296 return -1; 297 } 298 } 299 300 /* Disable the channel to prevent furher receiving */ 301 if(i == (len - 1)) 302 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 303 304 /* Read the data */ 305 rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx); 306 } 307 308 if (flags & SPI_XFER_END) { 309 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 310 omap3_spi_write_chconf(ds,chconf); 311 } 312 313 return 0; 314 } 315 316 /*McSPI Transmit Receive Mode*/ 317 int omap3_spi_txrx(struct spi_slave *slave, 318 unsigned int len, const u8 *txp, u8 *rxp, unsigned long flags) 319 { 320 struct omap3_spi_slave *ds = to_omap3_spi(slave); 321 int timeout = SPI_WAIT_TIMEOUT; 322 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 323 int irqstatus = readl(&ds->regs->irqstatus); 324 int i=0; 325 326 /*Enable SPI channel*/ 327 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 328 329 /*set TRANSMIT-RECEIVE Mode*/ 330 chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 331 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 332 omap3_spi_write_chconf(ds,chconf); 333 334 /*Shift in and out 1 byte at time*/ 335 for (i=0; i < len; i++){ 336 /* Write: wait for TX empty (TXS == 1)*/ 337 irqstatus |= (1<< (4*(ds->slave.bus))); 338 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 339 OMAP3_MCSPI_CHSTAT_TXS)) { 340 if (--timeout <= 0) { 341 printf("SPI TXS timed out, status=0x%08x\n", 342 readl(&ds->regs->channel[ds->slave.cs].chstat)); 343 return -1; 344 } 345 } 346 /* Write the data */ 347 writel(txp[i], &ds->regs->channel[ds->slave.cs].tx); 348 349 /*Read: wait for RX containing data (RXS == 1)*/ 350 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 351 OMAP3_MCSPI_CHSTAT_RXS)) { 352 if (--timeout <= 0) { 353 printf("SPI RXS timed out, status=0x%08x\n", 354 readl(&ds->regs->channel[ds->slave.cs].chstat)); 355 return -1; 356 } 357 } 358 /* Read the data */ 359 rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx); 360 } 361 /* Disable the channel */ 362 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 363 364 /*if transfer must be terminated disable the channel*/ 365 if (flags & SPI_XFER_END) { 366 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 367 omap3_spi_write_chconf(ds,chconf); 368 } 369 370 return 0; 371 } 372 373 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, 374 const void *dout, void *din, unsigned long flags) 375 { 376 struct omap3_spi_slave *ds = to_omap3_spi(slave); 377 unsigned int len; 378 const u8 *txp = dout; 379 u8 *rxp = din; 380 int ret = -1; 381 382 if (bitlen % 8) 383 return -1; 384 385 len = bitlen / 8; 386 387 if (bitlen == 0) { /* only change CS */ 388 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 389 390 if (flags & SPI_XFER_BEGIN) { 391 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 392 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 393 omap3_spi_write_chconf(ds,chconf); 394 } 395 if (flags & SPI_XFER_END) { 396 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 397 omap3_spi_write_chconf(ds,chconf); 398 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 399 } 400 ret = 0; 401 } else { 402 if (dout != NULL && din != NULL) 403 ret = omap3_spi_txrx(slave, len, txp, rxp, flags); 404 else if (dout != NULL) 405 ret = omap3_spi_write(slave, len, txp, flags); 406 else if (din != NULL) 407 ret = omap3_spi_read(slave, len, rxp, flags); 408 } 409 return ret; 410 } 411 412 int spi_cs_is_valid(unsigned int bus, unsigned int cs) 413 { 414 return 1; 415 } 416 417 void spi_cs_activate(struct spi_slave *slave) 418 { 419 } 420 421 void spi_cs_deactivate(struct spi_slave *slave) 422 { 423 } 424