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