1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2016 Jagan Teki <jteki@openedev.com> 4 * Christophe Ricard <christophe.ricard@gmail.com> 5 * 6 * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com> 7 * 8 * Driver for McSPI controller on OMAP3. Based on davinci_spi.c 9 * Copyright (C) 2009 Texas Instruments Incorporated - https://www.ti.com/ 10 * 11 * Copyright (C) 2007 Atmel Corporation 12 * 13 * Parts taken from linux/drivers/spi/omap2_mcspi.c 14 * Copyright (C) 2005, 2006 Nokia Corporation 15 * 16 * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com> 17 */ 18 19#include <common.h> 20#include <dm.h> 21#include <spi.h> 22#include <malloc.h> 23#include <asm/global_data.h> 24#include <asm/io.h> 25#include <linux/bitops.h> 26#include <omap3_spi.h> 27 28DECLARE_GLOBAL_DATA_PTR; 29 30struct omap2_mcspi_platform_config { 31 unsigned int regs_offset; 32}; 33 34struct omap3_spi_priv { 35 struct mcspi *regs; 36 unsigned int cs; 37 unsigned int freq; 38 unsigned int mode; 39 unsigned int wordlen; 40 unsigned int pin_dir:1; 41 42 bool bus_claimed; 43}; 44 45static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val) 46{ 47 writel(val, &priv->regs->channel[priv->cs].chconf); 48 /* Flash post writes to make immediate effect */ 49 readl(&priv->regs->channel[priv->cs].chconf); 50} 51 52static void omap3_spi_set_enable(struct omap3_spi_priv *priv, int enable) 53{ 54 writel(enable, &priv->regs->channel[priv->cs].chctrl); 55 /* Flash post writes to make immediate effect */ 56 readl(&priv->regs->channel[priv->cs].chctrl); 57} 58 59static int omap3_spi_write(struct omap3_spi_priv *priv, unsigned int len, 60 const void *txp, unsigned long flags) 61{ 62 ulong start; 63 int i, chconf; 64 65 chconf = readl(&priv->regs->channel[priv->cs].chconf); 66 67 /* Enable the channel */ 68 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 69 70 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 71 chconf |= (priv->wordlen - 1) << 7; 72 chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY; 73 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 74 omap3_spi_write_chconf(priv, chconf); 75 76 for (i = 0; i < len; i++) { 77 /* wait till TX register is empty (TXS == 1) */ 78 start = get_timer(0); 79 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 80 OMAP3_MCSPI_CHSTAT_TXS)) { 81 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 82 printf("SPI TXS timed out, status=0x%08x\n", 83 readl(&priv->regs->channel[priv->cs].chstat)); 84 return -1; 85 } 86 } 87 /* Write the data */ 88 unsigned int *tx = &priv->regs->channel[priv->cs].tx; 89 if (priv->wordlen > 16) 90 writel(((u32 *)txp)[i], tx); 91 else if (priv->wordlen > 8) 92 writel(((u16 *)txp)[i], tx); 93 else 94 writel(((u8 *)txp)[i], tx); 95 } 96 97 /* wait to finish of transfer */ 98 while ((readl(&priv->regs->channel[priv->cs].chstat) & 99 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) != 100 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) 101 ; 102 103 /* Disable the channel otherwise the next immediate RX will get affected */ 104 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 105 106 if (flags & SPI_XFER_END) { 107 108 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 109 omap3_spi_write_chconf(priv, chconf); 110 } 111 return 0; 112} 113 114static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len, 115 void *rxp, unsigned long flags) 116{ 117 int i, chconf; 118 ulong start; 119 120 chconf = readl(&priv->regs->channel[priv->cs].chconf); 121 122 /* Enable the channel */ 123 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 124 125 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 126 chconf |= (priv->wordlen - 1) << 7; 127 chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY; 128 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 129 omap3_spi_write_chconf(priv, chconf); 130 131 writel(0, &priv->regs->channel[priv->cs].tx); 132 133 for (i = 0; i < len; i++) { 134 start = get_timer(0); 135 /* Wait till RX register contains data (RXS == 1) */ 136 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 137 OMAP3_MCSPI_CHSTAT_RXS)) { 138 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 139 printf("SPI RXS timed out, status=0x%08x\n", 140 readl(&priv->regs->channel[priv->cs].chstat)); 141 return -1; 142 } 143 } 144 145 /* Disable the channel to prevent further receiving */ 146 if (i == (len - 1)) 147 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 148 149 /* Read the data */ 150 unsigned int *rx = &priv->regs->channel[priv->cs].rx; 151 if (priv->wordlen > 16) 152 ((u32 *)rxp)[i] = readl(rx); 153 else if (priv->wordlen > 8) 154 ((u16 *)rxp)[i] = (u16)readl(rx); 155 else 156 ((u8 *)rxp)[i] = (u8)readl(rx); 157 } 158 159 if (flags & SPI_XFER_END) { 160 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 161 omap3_spi_write_chconf(priv, chconf); 162 } 163 164 return 0; 165} 166 167/*McSPI Transmit Receive Mode*/ 168static int omap3_spi_txrx(struct omap3_spi_priv *priv, unsigned int len, 169 const void *txp, void *rxp, unsigned long flags) 170{ 171 ulong start; 172 int chconf, i = 0; 173 174 chconf = readl(&priv->regs->channel[priv->cs].chconf); 175 176 /*Enable SPI channel*/ 177 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 178 179 /*set TRANSMIT-RECEIVE Mode*/ 180 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 181 chconf |= (priv->wordlen - 1) << 7; 182 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 183 omap3_spi_write_chconf(priv, chconf); 184 185 /*Shift in and out 1 byte at time*/ 186 for (i=0; i < len; i++){ 187 /* Write: wait for TX empty (TXS == 1)*/ 188 start = get_timer(0); 189 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 190 OMAP3_MCSPI_CHSTAT_TXS)) { 191 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 192 printf("SPI TXS timed out, status=0x%08x\n", 193 readl(&priv->regs->channel[priv->cs].chstat)); 194 return -1; 195 } 196 } 197 /* Write the data */ 198 unsigned int *tx = &priv->regs->channel[priv->cs].tx; 199 if (priv->wordlen > 16) 200 writel(((u32 *)txp)[i], tx); 201 else if (priv->wordlen > 8) 202 writel(((u16 *)txp)[i], tx); 203 else 204 writel(((u8 *)txp)[i], tx); 205 206 /*Read: wait for RX containing data (RXS == 1)*/ 207 start = get_timer(0); 208 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 209 OMAP3_MCSPI_CHSTAT_RXS)) { 210 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 211 printf("SPI RXS timed out, status=0x%08x\n", 212 readl(&priv->regs->channel[priv->cs].chstat)); 213 return -1; 214 } 215 } 216 /* Read the data */ 217 unsigned int *rx = &priv->regs->channel[priv->cs].rx; 218 if (priv->wordlen > 16) 219 ((u32 *)rxp)[i] = readl(rx); 220 else if (priv->wordlen > 8) 221 ((u16 *)rxp)[i] = (u16)readl(rx); 222 else 223 ((u8 *)rxp)[i] = (u8)readl(rx); 224 } 225 /* Disable the channel */ 226 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 227 228 /*if transfer must be terminated disable the channel*/ 229 if (flags & SPI_XFER_END) { 230 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 231 omap3_spi_write_chconf(priv, chconf); 232 } 233 234 return 0; 235} 236 237static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen, 238 const void *dout, void *din, unsigned long flags) 239{ 240 unsigned int len; 241 int ret = -1; 242 243 if (priv->wordlen < 4 || priv->wordlen > 32) { 244 printf("omap3_spi: invalid wordlen %d\n", priv->wordlen); 245 return -1; 246 } 247 248 if (bitlen % priv->wordlen) 249 return -1; 250 251 len = bitlen / priv->wordlen; 252 253 if (bitlen == 0) { /* only change CS */ 254 int chconf = readl(&priv->regs->channel[priv->cs].chconf); 255 256 if (flags & SPI_XFER_BEGIN) { 257 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 258 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 259 omap3_spi_write_chconf(priv, chconf); 260 } 261 if (flags & SPI_XFER_END) { 262 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 263 omap3_spi_write_chconf(priv, chconf); 264 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 265 } 266 ret = 0; 267 } else { 268 if (dout != NULL && din != NULL) 269 ret = omap3_spi_txrx(priv, len, dout, din, flags); 270 else if (dout != NULL) 271 ret = omap3_spi_write(priv, len, dout, flags); 272 else if (din != NULL) 273 ret = omap3_spi_read(priv, len, din, flags); 274 } 275 return ret; 276} 277 278static void _omap3_spi_set_speed(struct omap3_spi_priv *priv) 279{ 280 uint32_t confr, div = 0; 281 282 confr = readl(&priv->regs->channel[priv->cs].chconf); 283 284 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */ 285 if (priv->freq) { 286 while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div)) 287 > priv->freq) 288 div++; 289 } else { 290 div = 0xC; 291 } 292 293 /* set clock divisor */ 294 confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK; 295 confr |= div << 2; 296 297 omap3_spi_write_chconf(priv, confr); 298} 299 300static void _omap3_spi_set_mode(struct omap3_spi_priv *priv) 301{ 302 uint32_t confr; 303 304 confr = readl(&priv->regs->channel[priv->cs].chconf); 305 306 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS 307 * REVISIT: this controller could support SPI_3WIRE mode. 308 */ 309 if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) { 310 confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1); 311 confr |= OMAP3_MCSPI_CHCONF_DPE0; 312 } else { 313 confr &= ~OMAP3_MCSPI_CHCONF_DPE0; 314 confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1; 315 } 316 317 /* set SPI mode 0..3 */ 318 confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA); 319 if (priv->mode & SPI_CPHA) 320 confr |= OMAP3_MCSPI_CHCONF_PHA; 321 if (priv->mode & SPI_CPOL) 322 confr |= OMAP3_MCSPI_CHCONF_POL; 323 324 /* set chipselect polarity; manage with FORCE */ 325 if (!(priv->mode & SPI_CS_HIGH)) 326 confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */ 327 else 328 confr &= ~OMAP3_MCSPI_CHCONF_EPOL; 329 330 /* Transmit & receive mode */ 331 confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 332 333 omap3_spi_write_chconf(priv, confr); 334} 335 336static void _omap3_spi_set_wordlen(struct omap3_spi_priv *priv) 337{ 338 unsigned int confr; 339 340 /* McSPI individual channel configuration */ 341 confr = readl(&priv->regs->channel[priv->cs].chconf); 342 343 /* wordlength */ 344 confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK; 345 confr |= (priv->wordlen - 1) << 7; 346 347 omap3_spi_write_chconf(priv, confr); 348} 349 350static void spi_reset(struct omap3_spi_priv *priv) 351{ 352 unsigned int tmp; 353 354 writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &priv->regs->sysconfig); 355 do { 356 tmp = readl(&priv->regs->sysstatus); 357 } while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE)); 358 359 writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE | 360 OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP | 361 OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, &priv->regs->sysconfig); 362 363 writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &priv->regs->wakeupenable); 364 365 /* 366 * Set the same default mode for each channel, especially CS polarity 367 * which must be common for all SPI slaves before any transfer. 368 */ 369 for (priv->cs = 0 ; priv->cs < OMAP4_MCSPI_CHAN_NB ; priv->cs++) 370 _omap3_spi_set_mode(priv); 371 priv->cs = 0; 372} 373 374static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv) 375{ 376 unsigned int conf; 377 /* 378 * setup when switching from (reset default) slave mode 379 * to single-channel master mode 380 */ 381 conf = readl(&priv->regs->modulctrl); 382 conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS); 383 conf |= OMAP3_MCSPI_MODULCTRL_SINGLE; 384 385 writel(conf, &priv->regs->modulctrl); 386 387 priv->bus_claimed = true; 388} 389 390static int omap3_spi_claim_bus(struct udevice *dev) 391{ 392 struct udevice *bus = dev->parent; 393 struct omap3_spi_priv *priv = dev_get_priv(bus); 394 struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); 395 396 priv->cs = slave_plat->cs; 397 if (!priv->freq) 398 priv->freq = slave_plat->max_hz; 399 400 _omap3_spi_claim_bus(priv); 401 _omap3_spi_set_speed(priv); 402 _omap3_spi_set_mode(priv); 403 404 return 0; 405} 406 407static int omap3_spi_release_bus(struct udevice *dev) 408{ 409 struct udevice *bus = dev->parent; 410 struct omap3_spi_priv *priv = dev_get_priv(bus); 411 412 writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl); 413 414 priv->bus_claimed = false; 415 416 return 0; 417} 418 419static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen) 420{ 421 struct udevice *bus = dev->parent; 422 struct omap3_spi_priv *priv = dev_get_priv(bus); 423 struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); 424 425 priv->cs = slave_plat->cs; 426 priv->wordlen = wordlen; 427 _omap3_spi_set_wordlen(priv); 428 429 return 0; 430} 431 432static int omap3_spi_probe(struct udevice *dev) 433{ 434 struct omap3_spi_priv *priv = dev_get_priv(dev); 435 struct omap3_spi_plat *plat = dev_get_plat(dev); 436 437 priv->regs = plat->regs; 438 priv->pin_dir = plat->pin_dir; 439 priv->wordlen = SPI_DEFAULT_WORDLEN; 440 441 spi_reset(priv); 442 443 return 0; 444} 445 446static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen, 447 const void *dout, void *din, unsigned long flags) 448{ 449 struct udevice *bus = dev->parent; 450 struct omap3_spi_priv *priv = dev_get_priv(bus); 451 452 return _spi_xfer(priv, bitlen, dout, din, flags); 453} 454 455static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed) 456{ 457 458 struct omap3_spi_priv *priv = dev_get_priv(dev); 459 460 priv->freq = speed; 461 if (priv->bus_claimed) 462 _omap3_spi_set_speed(priv); 463 464 return 0; 465} 466 467static int omap3_spi_set_mode(struct udevice *dev, uint mode) 468{ 469 struct omap3_spi_priv *priv = dev_get_priv(dev); 470 471 priv->mode = mode; 472 473 if (priv->bus_claimed) 474 _omap3_spi_set_mode(priv); 475 476 return 0; 477} 478 479static const struct dm_spi_ops omap3_spi_ops = { 480 .claim_bus = omap3_spi_claim_bus, 481 .release_bus = omap3_spi_release_bus, 482 .set_wordlen = omap3_spi_set_wordlen, 483 .xfer = omap3_spi_xfer, 484 .set_speed = omap3_spi_set_speed, 485 .set_mode = omap3_spi_set_mode, 486 /* 487 * cs_info is not needed, since we require all chip selects to be 488 * in the device tree explicitly 489 */ 490}; 491 492#if CONFIG_IS_ENABLED(OF_REAL) 493static struct omap2_mcspi_platform_config omap2_pdata = { 494 .regs_offset = 0, 495}; 496 497static struct omap2_mcspi_platform_config omap4_pdata = { 498 .regs_offset = OMAP4_MCSPI_REG_OFFSET, 499}; 500 501static int omap3_spi_of_to_plat(struct udevice *dev) 502{ 503 struct omap2_mcspi_platform_config *data = 504 (struct omap2_mcspi_platform_config *)dev_get_driver_data(dev); 505 struct omap3_spi_plat *plat = dev_get_plat(dev); 506 507 plat->regs = (struct mcspi *)(dev_read_addr(dev) + data->regs_offset); 508 509 if (dev_read_bool(dev, "ti,pindir-d0-out-d1-in")) 510 plat->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; 511 else 512 plat->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT; 513 514 return 0; 515} 516 517static const struct udevice_id omap3_spi_ids[] = { 518 { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata }, 519 { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata }, 520 { } 521}; 522#endif 523U_BOOT_DRIVER(omap3_spi) = { 524 .name = "omap3_spi", 525 .id = UCLASS_SPI, 526 .flags = DM_FLAG_PRE_RELOC, 527#if CONFIG_IS_ENABLED(OF_REAL) 528 .of_match = omap3_spi_ids, 529 .of_to_plat = omap3_spi_of_to_plat, 530 .plat_auto = sizeof(struct omap3_spi_plat), 531#endif 532 .probe = omap3_spi_probe, 533 .ops = &omap3_spi_ops, 534 .priv_auto = sizeof(struct omap3_spi_priv), 535}; 536