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 84 ds = malloc(sizeof(struct omap3_spi_slave)); 85 if (!ds) { 86 printf("SPI error: malloc of SPI structure failed\n"); 87 return NULL; 88 } 89 90 /* 91 * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules) 92 * with different number of chip selects (CS, channels): 93 * McSPI1 has 4 CS (bus 0, cs 0 - 3) 94 * McSPI2 has 2 CS (bus 1, cs 0 - 1) 95 * McSPI3 has 2 CS (bus 2, cs 0 - 1) 96 * McSPI4 has 1 CS (bus 3, cs 0) 97 */ 98 99 switch (bus) { 100 case 0: 101 ds->regs = (struct mcspi *)OMAP3_MCSPI1_BASE; 102 break; 103 #ifdef OMAP3_MCSPI2_BASE 104 case 1: 105 ds->regs = (struct mcspi *)OMAP3_MCSPI2_BASE; 106 break; 107 #endif 108 #ifdef OMAP3_MCSPI3_BASE 109 case 2: 110 ds->regs = (struct mcspi *)OMAP3_MCSPI3_BASE; 111 break; 112 #endif 113 #ifdef OMAP3_MCSPI4_BASE 114 case 3: 115 ds->regs = (struct mcspi *)OMAP3_MCSPI4_BASE; 116 break; 117 #endif 118 default: 119 printf("SPI error: unsupported bus %i. \ 120 Supported busses 0 - 3\n", bus); 121 return NULL; 122 } 123 ds->slave.bus = bus; 124 125 if (((bus == 0) && (cs > 3)) || 126 ((bus == 1) && (cs > 1)) || 127 ((bus == 2) && (cs > 1)) || 128 ((bus == 3) && (cs > 0))) { 129 printf("SPI error: unsupported chip select %i \ 130 on bus %i\n", cs, bus); 131 return NULL; 132 } 133 ds->slave.cs = cs; 134 135 if (max_hz > OMAP3_MCSPI_MAX_FREQ) { 136 printf("SPI error: unsupported frequency %i Hz. \ 137 Max frequency is 48 Mhz\n", max_hz); 138 return NULL; 139 } 140 ds->freq = max_hz; 141 142 if (mode > SPI_MODE_3) { 143 printf("SPI error: unsupported SPI mode %i\n", mode); 144 return NULL; 145 } 146 ds->mode = mode; 147 148 return &ds->slave; 149 } 150 151 void spi_free_slave(struct spi_slave *slave) 152 { 153 struct omap3_spi_slave *ds = to_omap3_spi(slave); 154 155 free(ds); 156 } 157 158 int spi_claim_bus(struct spi_slave *slave) 159 { 160 struct omap3_spi_slave *ds = to_omap3_spi(slave); 161 unsigned int conf, div = 0; 162 163 /* McSPI global module configuration */ 164 165 /* 166 * setup when switching from (reset default) slave mode 167 * to single-channel master mode 168 */ 169 spi_reset(ds); 170 conf = readl(&ds->regs->modulctrl); 171 conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS); 172 conf |= OMAP3_MCSPI_MODULCTRL_SINGLE; 173 writel(conf, &ds->regs->modulctrl); 174 175 /* McSPI individual channel configuration */ 176 177 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */ 178 if (ds->freq) { 179 while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div)) 180 > ds->freq) 181 div++; 182 } else 183 div = 0xC; 184 185 conf = readl(&ds->regs->channel[ds->slave.cs].chconf); 186 187 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS 188 * REVISIT: this controller could support SPI_3WIRE mode. 189 */ 190 #ifdef CONFIG_OMAP3_SPI_D0_D1_SWAPPED 191 /* 192 * Some boards have D0 wired as MOSI / D1 as MISO instead of 193 * The normal D0 as MISO / D1 as MOSI. 194 */ 195 conf &= ~OMAP3_MCSPI_CHCONF_DPE0; 196 conf |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1; 197 #else 198 conf &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1); 199 conf |= OMAP3_MCSPI_CHCONF_DPE0; 200 #endif 201 202 /* wordlength */ 203 conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK; 204 conf |= (WORD_LEN - 1) << 7; 205 206 /* set chipselect polarity; manage with FORCE */ 207 if (!(ds->mode & SPI_CS_HIGH)) 208 conf |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */ 209 else 210 conf &= ~OMAP3_MCSPI_CHCONF_EPOL; 211 212 /* set clock divisor */ 213 conf &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK; 214 conf |= div << 2; 215 216 /* set SPI mode 0..3 */ 217 if (ds->mode & SPI_CPOL) 218 conf |= OMAP3_MCSPI_CHCONF_POL; 219 else 220 conf &= ~OMAP3_MCSPI_CHCONF_POL; 221 if (ds->mode & SPI_CPHA) 222 conf |= OMAP3_MCSPI_CHCONF_PHA; 223 else 224 conf &= ~OMAP3_MCSPI_CHCONF_PHA; 225 226 /* Transmit & receive mode */ 227 conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 228 229 omap3_spi_write_chconf(ds,conf); 230 231 return 0; 232 } 233 234 void spi_release_bus(struct spi_slave *slave) 235 { 236 struct omap3_spi_slave *ds = to_omap3_spi(slave); 237 238 /* Reset the SPI hardware */ 239 spi_reset(ds); 240 } 241 242 int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp, 243 unsigned long flags) 244 { 245 struct omap3_spi_slave *ds = to_omap3_spi(slave); 246 int i; 247 int timeout = SPI_WAIT_TIMEOUT; 248 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 249 250 /* Enable the channel */ 251 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 252 253 chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 254 chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY; 255 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 256 omap3_spi_write_chconf(ds,chconf); 257 258 for (i = 0; i < len; i++) { 259 /* wait till TX register is empty (TXS == 1) */ 260 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 261 OMAP3_MCSPI_CHSTAT_TXS)) { 262 if (--timeout <= 0) { 263 printf("SPI TXS timed out, status=0x%08x\n", 264 readl(&ds->regs->channel[ds->slave.cs].chstat)); 265 return -1; 266 } 267 } 268 /* Write the data */ 269 writel(txp[i], &ds->regs->channel[ds->slave.cs].tx); 270 } 271 272 /* wait to finish of transfer */ 273 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 274 OMAP3_MCSPI_CHSTAT_EOT)); 275 276 /* Disable the channel otherwise the next immediate RX will get affected */ 277 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 278 279 if (flags & SPI_XFER_END) { 280 281 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 282 omap3_spi_write_chconf(ds,chconf); 283 } 284 return 0; 285 } 286 287 int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp, 288 unsigned long flags) 289 { 290 struct omap3_spi_slave *ds = to_omap3_spi(slave); 291 int i; 292 int timeout = SPI_WAIT_TIMEOUT; 293 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 294 295 /* Enable the channel */ 296 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 297 298 chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 299 chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY; 300 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 301 omap3_spi_write_chconf(ds,chconf); 302 303 writel(0, &ds->regs->channel[ds->slave.cs].tx); 304 305 for (i = 0; i < len; i++) { 306 /* Wait till RX register contains data (RXS == 1) */ 307 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 308 OMAP3_MCSPI_CHSTAT_RXS)) { 309 if (--timeout <= 0) { 310 printf("SPI RXS timed out, status=0x%08x\n", 311 readl(&ds->regs->channel[ds->slave.cs].chstat)); 312 return -1; 313 } 314 } 315 316 /* Disable the channel to prevent furher receiving */ 317 if(i == (len - 1)) 318 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 319 320 /* Read the data */ 321 rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx); 322 } 323 324 if (flags & SPI_XFER_END) { 325 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 326 omap3_spi_write_chconf(ds,chconf); 327 } 328 329 return 0; 330 } 331 332 /*McSPI Transmit Receive Mode*/ 333 int omap3_spi_txrx(struct spi_slave *slave, 334 unsigned int len, const u8 *txp, u8 *rxp, unsigned long flags) 335 { 336 struct omap3_spi_slave *ds = to_omap3_spi(slave); 337 int timeout = SPI_WAIT_TIMEOUT; 338 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 339 int irqstatus = readl(&ds->regs->irqstatus); 340 int i=0; 341 342 /*Enable SPI channel*/ 343 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 344 345 /*set TRANSMIT-RECEIVE Mode*/ 346 chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 347 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 348 omap3_spi_write_chconf(ds,chconf); 349 350 /*Shift in and out 1 byte at time*/ 351 for (i=0; i < len; i++){ 352 /* Write: wait for TX empty (TXS == 1)*/ 353 irqstatus |= (1<< (4*(ds->slave.bus))); 354 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 355 OMAP3_MCSPI_CHSTAT_TXS)) { 356 if (--timeout <= 0) { 357 printf("SPI TXS timed out, status=0x%08x\n", 358 readl(&ds->regs->channel[ds->slave.cs].chstat)); 359 return -1; 360 } 361 } 362 /* Write the data */ 363 writel(txp[i], &ds->regs->channel[ds->slave.cs].tx); 364 365 /*Read: wait for RX containing data (RXS == 1)*/ 366 while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & 367 OMAP3_MCSPI_CHSTAT_RXS)) { 368 if (--timeout <= 0) { 369 printf("SPI RXS timed out, status=0x%08x\n", 370 readl(&ds->regs->channel[ds->slave.cs].chstat)); 371 return -1; 372 } 373 } 374 /* Read the data */ 375 rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx); 376 } 377 /* Disable the channel */ 378 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 379 380 /*if transfer must be terminated disable the channel*/ 381 if (flags & SPI_XFER_END) { 382 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 383 omap3_spi_write_chconf(ds,chconf); 384 } 385 386 return 0; 387 } 388 389 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, 390 const void *dout, void *din, unsigned long flags) 391 { 392 struct omap3_spi_slave *ds = to_omap3_spi(slave); 393 unsigned int len; 394 const u8 *txp = dout; 395 u8 *rxp = din; 396 int ret = -1; 397 398 if (bitlen % 8) 399 return -1; 400 401 len = bitlen / 8; 402 403 if (bitlen == 0) { /* only change CS */ 404 int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); 405 406 if (flags & SPI_XFER_BEGIN) { 407 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); 408 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 409 omap3_spi_write_chconf(ds,chconf); 410 } 411 if (flags & SPI_XFER_END) { 412 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 413 omap3_spi_write_chconf(ds,chconf); 414 omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); 415 } 416 ret = 0; 417 } else { 418 if (dout != NULL && din != NULL) 419 ret = omap3_spi_txrx(slave, len, txp, rxp, flags); 420 else if (dout != NULL) 421 ret = omap3_spi_write(slave, len, txp, flags); 422 else if (din != NULL) 423 ret = omap3_spi_read(slave, len, rxp, flags); 424 } 425 return ret; 426 } 427 428 int spi_cs_is_valid(unsigned int bus, unsigned int cs) 429 { 430 return 1; 431 } 432 433 void spi_cs_activate(struct spi_slave *slave) 434 { 435 } 436 437 void spi_cs_deactivate(struct spi_slave *slave) 438 { 439 } 440