1 /* 2 * SFC driver for rockchip 3 * 4 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 5 * Yifeng.zhao, Software Engineering, <zhao0116@gmail.com>. 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <bouncebuf.h> 12 #include <clk.h> 13 #include <dm.h> 14 #include <dt-structs.h> 15 #include <errno.h> 16 #include <spi.h> 17 #include <linux/errno.h> 18 #include <asm/io.h> 19 #include <asm/arch/clock.h> 20 #include <asm/arch/periph.h> 21 #include <dm/pinctrl.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 #ifdef SFC_DEBUG 26 #define SFC_DBG printf 27 #else 28 #define SFC_DBG(args...) 29 #endif 30 31 struct rockchip_sfc_reg { 32 u32 ctrl; 33 u32 imr; 34 u32 iclr; 35 u32 ftlr; 36 u32 rcvr; 37 u32 ax; 38 u32 abit; 39 u32 isr; 40 u32 fsr; 41 u32 sr; 42 u32 risr; 43 u32 reserved[21]; 44 u32 dmatr; 45 u32 dmaaddr; 46 u32 reserved1[30]; 47 u32 cmd; 48 u32 addr; 49 u32 data; 50 }; 51 52 check_member(rockchip_sfc_reg, data, 0x108); 53 54 /*SFC_CTRL*/ 55 #define SFC_DATA_WIDTH_SHIFT 12 56 #define SFC_DATA_WIDTH_MASK GENMASK(13, 12) 57 #define SFC_ADDR_WIDTH_SHIFT 10 58 #define SFC_ADDR_WIDTH_MASK GENMASK(11, 10) 59 #define SFC_CMD_WIDTH_SHIFT 8 60 #define SFC_CMD_WIDTH_MASK GENMASK(9, 8) 61 #define SFC_DATA_SHIFT_NEGETIVE BIT(1) 62 63 /*SFC_CMD*/ 64 #define SFC_DUMMY_BITS_SHIFT 8 65 #define SFC_RW_SHIFT 12 66 #define SFC_WR 1 67 #define SFC_RD 0 68 #define SFC_ADDR_BITS_SHIFT 14 69 #define SFC_ADDR_BITS_MASK GENMASK(15, 14) 70 #define SFC_ADDR_0BITS 0 71 #define SFC_ADDR_24BITS 1 72 #define SFC_ADDR_32BITS 2 73 #define SFC_ADDR_XBITS 3 74 #define SFC_TRB_SHIFT (16) 75 #define SFC_TRB_MASK GENMASK(29, 16) 76 77 /* Dma start trigger signal. Auto cleared after write */ 78 #define SFC_DMA_START BIT(0) 79 80 #define SFC_RESET BIT(0) 81 82 /*SFC_FSR*/ 83 #define SFC_RXLV_SHIFT (16) 84 #define SFC_RXLV_MASK GENMASK(20, 16) 85 #define SFC_TXLV_SHIFT (8) 86 #define SFC_TXLV_MASK GENMASK(12, 8) 87 #define SFC_RX_FULL BIT(3) /* rx fifo full */ 88 #define SFC_RX_EMPTY BIT(2) /* rx fifo empty */ 89 #define SFC_TX_EMPTY BIT(1) /* tx fifo empty */ 90 #define SFC_TX_FULL BIT(0) /* tx fifo full */ 91 92 #define SFC_BUSY BIT(0) /* sfc busy flag */ 93 94 /*SFC_RISR*/ 95 #define DMA_FINISH_INT BIT(7) /* dma interrupt */ 96 #define SPI_ERR_INT BIT(6) /* Nspi error interrupt */ 97 #define AHB_ERR_INT BIT(5) /* Ahb bus error interrupt */ 98 #define TRANS_FINISH_INT BIT(4) /* Transfer finish interrupt */ 99 #define TX_EMPTY_INT BIT(3) /* Tx fifo empty interrupt */ 100 #define TX_OF_INT BIT(2) /* Tx fifo overflow interrupt */ 101 #define RX_UF_INT BIT(1) /* Rx fifo underflow interrupt */ 102 #define RX_FULL_INT BIT(0) /* Rx fifo full interrupt */ 103 104 #define SFC_MAX_TRB (512 * 31) 105 106 enum rockchip_sfc_if_type { 107 IF_TYPE_STD, 108 IF_TYPE_DUAL, 109 IF_TYPE_QUAD, 110 }; 111 112 struct rockchip_sfc_platdata { 113 s32 frequency; 114 void *base; 115 }; 116 117 struct rockchip_sfc { 118 struct rockchip_sfc_reg *regbase; 119 struct clk clk; 120 unsigned int max_freq; 121 unsigned int mode; 122 unsigned int speed_hz; 123 u32 cmd; 124 u32 addr; 125 u8 addr_bits; 126 u8 dummy_bits; 127 u8 rw; 128 u32 trb; 129 }; 130 131 static int rockchip_sfc_ofdata_to_platdata(struct udevice *bus) 132 { 133 struct rockchip_sfc_platdata *plat = dev_get_platdata(bus); 134 struct rockchip_sfc *sfc = dev_get_priv(bus); 135 ofnode subnode; 136 int ret; 137 138 plat->base = dev_read_addr_ptr(bus); 139 ret = clk_get_by_index(bus, 0, &sfc->clk); 140 if (ret < 0) { 141 printf("Could not get clock for %s: %d\n", bus->name, ret); 142 return ret; 143 } 144 145 subnode = dev_read_first_subnode(bus); 146 if (!ofnode_valid(subnode)) { 147 printf("Error: subnode with SPI flash config missing!\n"); 148 return -ENODEV; 149 } 150 151 plat->frequency = ofnode_read_u32_default(subnode, "spi-max-frequency", 152 100000000); 153 154 return 0; 155 } 156 157 static int rockchip_sfc_probe(struct udevice *bus) 158 { 159 struct rockchip_sfc_platdata *plat = dev_get_platdata(bus); 160 struct rockchip_sfc *sfc = dev_get_priv(bus); 161 162 sfc->regbase = (struct rockchip_sfc_reg *)plat->base; 163 164 return 0; 165 } 166 167 static int rockchip_sfc_reset(struct rockchip_sfc *sfc) 168 { 169 struct rockchip_sfc_reg *regs = sfc->regbase; 170 int tbase = get_timer(0); 171 u32 rcvr; 172 int ret = 0; 173 174 writel(SFC_RESET, ®s->rcvr); 175 do { 176 rcvr = readl(®s->rcvr); 177 if (get_timer(tbase) > 1000) { 178 debug("sfc reset timeout\n"); 179 ret = -ETIMEDOUT; 180 break; 181 } 182 udelay(1); 183 } while (rcvr); 184 185 writel(0xFFFFFFFF, ®s->iclr); 186 187 debug("sfc reset\n"); 188 189 return ret; 190 } 191 192 /* The SFC_CTRL register is a global control register, 193 * when the controller is in busy state(SFC_SR), 194 * SFC_CTRL cannot be set. 195 */ 196 static int rockchip_sfc_wait_idle(struct rockchip_sfc *sfc, 197 u32 timeout_ms) 198 { 199 struct rockchip_sfc_reg *regs = sfc->regbase; 200 unsigned long tbase = get_timer(0); 201 u32 sr, fsr; 202 203 while (1) { 204 sr = readl(®s->sr); 205 fsr = readl(®s->fsr); 206 if ((fsr & SFC_TX_EMPTY) && 207 (fsr & SFC_RX_EMPTY) && 208 !(sr & SFC_BUSY)) 209 break; 210 if (get_timer(tbase) > timeout_ms) { 211 printf("waite sfc idle timeout(sr:0x%08x fsr:0x%08x)\n", 212 sr, fsr); 213 rockchip_sfc_reset(sfc); 214 return -ETIMEDOUT; 215 } 216 udelay(100); 217 } 218 219 return 0; 220 } 221 222 static u8 rockchip_sfc_get_if_type(struct rockchip_sfc *sfc) 223 { 224 int type = IF_TYPE_STD; 225 226 if (sfc->rw == SFC_WR) { 227 if (sfc->mode & SPI_TX_QUAD) 228 type = IF_TYPE_QUAD; 229 else if (sfc->mode & SPI_TX_DUAL) 230 type = IF_TYPE_DUAL; 231 else 232 type = IF_TYPE_STD; 233 } else { 234 if (sfc->mode & SPI_RX_QUAD) 235 type = IF_TYPE_QUAD; 236 else if (sfc->mode & SPI_RX_DUAL) 237 type = IF_TYPE_DUAL; 238 else 239 type = IF_TYPE_STD; 240 } 241 242 return type; 243 } 244 245 static void rockchip_sfc_setup_xfer(struct rockchip_sfc *sfc, u32 trb) 246 { 247 struct rockchip_sfc_reg *regs = sfc->regbase; 248 u32 val = 0x02; 249 u8 data_width = IF_TYPE_STD; 250 251 SFC_DBG("--- sfc.addr_bit %x\n", sfc->addr_bits); 252 253 if (sfc->addr_bits == SFC_ADDR_24BITS || 254 sfc->addr_bits == SFC_ADDR_32BITS) 255 data_width = rockchip_sfc_get_if_type(sfc); 256 257 val |= (data_width << SFC_DATA_WIDTH_SHIFT); 258 259 rockchip_sfc_wait_idle(sfc, 10); 260 261 SFC_DBG("--- sfc.ctrl %x\n", val); 262 writel(val, ®s->ctrl); 263 264 val = sfc->cmd; 265 val |= trb << SFC_TRB_SHIFT; 266 val |= sfc->rw << SFC_RW_SHIFT; 267 val |= sfc->addr_bits << SFC_ADDR_BITS_SHIFT; 268 val |= sfc->dummy_bits << SFC_DUMMY_BITS_SHIFT; 269 270 SFC_DBG("--- sfc.cmd %x\n", val); 271 writel(val, ®s->cmd); 272 273 if (sfc->addr_bits & SFC_ADDR_XBITS) { 274 SFC_DBG("--- sfc.addr %x\n", sfc->addr); 275 writel(sfc->addr, ®s->addr); 276 } 277 } 278 279 static int rockchip_sfc_dma_xfer(struct rockchip_sfc *sfc, void *buffer, size_t trb) 280 { 281 struct rockchip_sfc_reg *regs = sfc->regbase; 282 struct bounce_buffer bb; 283 unsigned int bb_flags; 284 int timeout = 1000; 285 int ret = 0; 286 int risr; 287 unsigned long tbase; 288 289 if (sfc->rw == SFC_WR) 290 bb_flags = GEN_BB_READ; 291 else 292 bb_flags = GEN_BB_WRITE; 293 294 ret = bounce_buffer_start(&bb, buffer, trb, bb_flags); 295 if (ret) 296 return ret; 297 298 rockchip_sfc_setup_xfer(sfc, bb.len_aligned); 299 300 writel(0xFFFFFFFF, ®s->iclr); 301 writel((unsigned long)bb.bounce_buffer, ®s->dmaaddr); 302 writel(SFC_DMA_START, ®s->dmatr); 303 304 tbase = get_timer(0); 305 do { 306 udelay(1); 307 risr = readl(®s->risr); 308 if (get_timer(tbase) > timeout) { 309 debug("dma timeout\n"); 310 ret = -ETIMEDOUT; 311 break; 312 } 313 } while (!(risr & TRANS_FINISH_INT)); 314 315 writel(0xFFFFFFFF, ®s->iclr); 316 317 bounce_buffer_stop(&bb); 318 319 return ret; 320 } 321 322 static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int rw, 323 u32 timeout) 324 { 325 struct rockchip_sfc_reg *regs = sfc->regbase; 326 unsigned long tbase = get_timer(0); 327 u8 level; 328 u32 fsr; 329 330 do { 331 fsr = readl(®s->fsr); 332 if (rw == SFC_WR) 333 level = (fsr & SFC_TXLV_MASK) >> SFC_TXLV_SHIFT; 334 else 335 level = (fsr & SFC_RXLV_MASK) >> SFC_RXLV_SHIFT; 336 if (get_timer(tbase) > timeout) 337 return -ETIMEDOUT; 338 udelay(1); 339 } while (!level); 340 341 return level; 342 } 343 344 static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, u32 *buf, u32 len) 345 { 346 struct rockchip_sfc_reg *regs = sfc->regbase; 347 u32 bytes = len & 0x3; 348 u32 words = len >> 2; 349 int tx_level = 0; 350 u32 val = 0; 351 u8 count; 352 353 while (words) { 354 tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_WR, 1000); 355 if (tx_level <= 0) 356 return tx_level; 357 count = min(words, (u32)tx_level); 358 writesl(®s->data, buf, count); 359 buf += count; 360 words -= count; 361 } 362 363 /* handle the last non 4byte aligned bytes */ 364 if (bytes) { 365 tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_WR, 1000); 366 if (tx_level <= 0) 367 return tx_level; 368 memcpy(&val, buf, bytes); 369 writel(val, ®s->data); 370 } 371 372 return 0; 373 } 374 375 static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u32 *buf, u32 len) 376 { 377 struct rockchip_sfc_reg *regs = sfc->regbase; 378 u32 bytes = len & 0x3; 379 u32 words = len >> 2; 380 int rx_level = 0; 381 u32 count; 382 u32 val; 383 384 while (words) { 385 rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_RD, 1000); 386 if (rx_level <= 0) 387 return rx_level; 388 count = min(words, (u32)rx_level); 389 readsl(®s->data, buf, count); 390 buf += count; 391 words -= count; 392 } 393 394 /* handle the last non 4 bytes aligned bytes */ 395 if (bytes) { 396 rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_RD, 1000); 397 if (rx_level <= 0) 398 return rx_level; 399 val = readl(®s->data); 400 memcpy(buf, &val, bytes); 401 } 402 403 return 0; 404 } 405 406 static int rockchip_sfc_pio_xfer(struct rockchip_sfc *sfc, void *buf, u32 len) 407 { 408 int ret = 0; 409 410 rockchip_sfc_setup_xfer(sfc, len); 411 412 if (len) { 413 if (sfc->rw == SFC_WR) 414 ret = rockchip_sfc_write_fifo(sfc, (u32 *)buf, len); 415 else 416 ret = rockchip_sfc_read_fifo(sfc, (u32 *)buf, len); 417 } 418 419 return ret; 420 } 421 422 static int rockchip_sfc_read(struct rockchip_sfc *sfc, u32 offset, 423 void *buf, size_t len) 424 { 425 u32 dma_trans; 426 u32 trb; 427 u8 bytes; 428 int ret; 429 430 if (len >= ARCH_DMA_MINALIGN) { 431 bytes = len & (ARCH_DMA_MINALIGN - 1); 432 dma_trans = len - bytes; 433 } else { 434 dma_trans = 0; 435 bytes = len; 436 } 437 438 while (dma_trans) { 439 trb = min_t(size_t, dma_trans, SFC_MAX_TRB); 440 ret = rockchip_sfc_dma_xfer(sfc, buf, trb); 441 if (ret < 0) 442 return ret; 443 dma_trans -= trb; 444 sfc->addr += trb; 445 buf += trb; 446 } 447 448 /* 449 * transfer the last non dma anligned byte by pio mode 450 */ 451 if (bytes) 452 ret = rockchip_sfc_pio_xfer(sfc, buf, bytes); 453 454 return 0; 455 } 456 457 static int rockchip_sfc_write(struct rockchip_sfc *sfc, u32 offset, 458 void *buf, size_t len) 459 { 460 if (len > SFC_MAX_TRB) { 461 printf("out of the max sfc trb"); 462 return -EINVAL; 463 } 464 465 if (len && !(len & (ARCH_DMA_MINALIGN - 1))) 466 return rockchip_sfc_dma_xfer(sfc, buf, len); 467 else 468 return rockchip_sfc_pio_xfer(sfc, buf, len); 469 470 return 0; 471 } 472 473 static int rockchip_sfc_do_xfer(struct rockchip_sfc *sfc, void *buf, size_t len) 474 { 475 if (sfc->rw) 476 return rockchip_sfc_write(sfc, sfc->addr, buf, len); 477 else 478 return rockchip_sfc_read(sfc, sfc->addr, buf, len); 479 } 480 481 static int rockchip_sfc_xfer(struct udevice *dev, unsigned int bitlen, 482 const void *dout, void *din, unsigned long flags) 483 { 484 struct udevice *bus = dev->parent; 485 struct rockchip_sfc *sfc = dev_get_priv(bus); 486 int len = bitlen >> 3; 487 u8 *pcmd = (u8 *)dout; 488 void *data_buf; 489 int ret = 0; 490 491 if (flags & SPI_XFER_BEGIN) { 492 sfc->cmd = pcmd[0]; 493 switch (len) { 494 case 6: /* Nor >16MB 0x6b dummy op */ 495 sfc->addr_bits = SFC_ADDR_32BITS; 496 sfc->dummy_bits = 8; 497 sfc->addr = pcmd[4] | (pcmd[3] << 8) | (pcmd[2] << 16) | (pcmd[1] << 24); 498 break; 499 case 5: /* Nor <=16MB 0x6b dummy op, Nor >16MB no dummy op */ 500 if (sfc->cmd == 0x6b) { 501 sfc->addr_bits = SFC_ADDR_24BITS; 502 sfc->dummy_bits = 8; 503 sfc->addr = pcmd[3] | (pcmd[2] << 8) | (pcmd[1] << 16); 504 } else { 505 sfc->addr_bits = SFC_ADDR_32BITS; 506 sfc->dummy_bits = 0; 507 sfc->addr = pcmd[4] | (pcmd[3] << 8) | (pcmd[2] << 16) | (pcmd[1] << 24); 508 } 509 break; 510 case 4: /* Nand erase and read, Nor <=16MB no dummy op */ 511 sfc->addr_bits = SFC_ADDR_24BITS; 512 sfc->dummy_bits = 0; 513 sfc->addr = pcmd[3] | (pcmd[2] << 8) | (pcmd[1] << 16); 514 break; 515 case 3: /* Nand prog, */ 516 sfc->addr_bits = SFC_ADDR_XBITS; 517 sfc->dummy_bits = 0; 518 sfc->addr = pcmd[2] | pcmd[1] << 8; 519 break; 520 case 2: /* Nand read/write feature */ 521 sfc->addr_bits = SFC_ADDR_XBITS; 522 sfc->dummy_bits = 0; 523 sfc->addr = pcmd[1]; 524 break; 525 default: /* Nand/Nor Read/Write status */ 526 sfc->addr_bits = SFC_ADDR_0BITS; 527 sfc->dummy_bits = 0; 528 sfc->addr = 0; 529 break; 530 } 531 SFC_DBG("%s %d %x %d %d %x\n", __func__, len, sfc->cmd, sfc->addr_bits, 532 sfc->dummy_bits, sfc->addr); 533 } 534 if (flags & SPI_XFER_END) { 535 if (din) { 536 sfc->rw = SFC_RD; 537 data_buf = din; 538 } else { 539 sfc->rw = SFC_WR; 540 data_buf = (void *)dout; 541 } 542 543 if (flags == (SPI_XFER_BEGIN | SPI_XFER_END)) { 544 len = 0; 545 data_buf = NULL; 546 } 547 548 ret = rockchip_sfc_do_xfer(sfc, data_buf, len); 549 } 550 551 return ret; 552 } 553 554 static int rockchip_sfc_set_speed(struct udevice *bus, uint speed) 555 { 556 struct rockchip_sfc *sfc = dev_get_priv(bus); 557 558 if (speed > sfc->max_freq) 559 speed = sfc->max_freq; 560 561 sfc->speed_hz = speed; 562 563 return 0; 564 } 565 566 static int rockchip_sfc_set_mode(struct udevice *bus, uint mode) 567 { 568 struct rockchip_sfc *sfc = dev_get_priv(bus); 569 570 sfc->mode = mode; 571 572 return 0; 573 } 574 575 static const struct dm_spi_ops rockchip_sfc_ops = { 576 .xfer = rockchip_sfc_xfer, 577 .set_speed = rockchip_sfc_set_speed, 578 .set_mode = rockchip_sfc_set_mode, 579 }; 580 581 static const struct udevice_id rockchip_sfc_ids[] = { 582 { .compatible = "rockchip,sfc" }, 583 { } 584 }; 585 586 U_BOOT_DRIVER(rockchip_sfc_driver) = { 587 .name = "rockchip_sfc", 588 .id = UCLASS_SPI, 589 .of_match = rockchip_sfc_ids, 590 .ops = &rockchip_sfc_ops, 591 .ofdata_to_platdata = rockchip_sfc_ofdata_to_platdata, 592 .platdata_auto_alloc_size = sizeof(struct rockchip_sfc_platdata), 593 .priv_auto_alloc_size = sizeof(struct rockchip_sfc), 594 .probe = rockchip_sfc_probe, 595 }; 596