1 /* 2 * sfc driver for rockchip 3 * 4 * (C) Copyright 2008-2016 Rockchip Electronics 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 #include "rockchip_sfc.h" 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 enum rockchip_sfc_if_type { 27 IF_TYPE_STD, 28 IF_TYPE_DUAL, 29 IF_TYPE_QUAD, 30 }; 31 32 struct rockchip_sfc_platdata { 33 s32 frequency; 34 fdt_addr_t base; 35 }; 36 37 struct rockchip_sfc { 38 struct rockchip_sfc_reg *regbase; 39 struct clk clk; 40 unsigned int max_freq; 41 unsigned int mode; 42 unsigned int speed_hz; 43 u32 cmd; 44 u32 addr; 45 u8 addr_bits; 46 u8 dummy_bits; 47 u8 rw; 48 u32 trb; 49 }; 50 51 static int rockchip_sfc_ofdata_to_platdata(struct udevice *bus) 52 { 53 struct rockchip_sfc_platdata *plat = dev_get_platdata(bus); 54 struct rockchip_sfc *sfc = dev_get_priv(bus); 55 const void *blob = gd->fdt_blob; 56 int node = dev_of_offset(bus); 57 int subnode; 58 int ret; 59 60 plat->base = devfdt_get_addr(bus); 61 62 ret = clk_get_by_index(bus, 0, &sfc->clk); 63 if (ret < 0) { 64 debug("Could not get clock for %s: %d\n", bus->name, ret); 65 return ret; 66 } 67 68 subnode = fdt_first_subnode(blob, node); 69 if (subnode < 0) { 70 debug("Error: subnode with SPI flash config missing!\n"); 71 return -ENODEV; 72 } 73 74 plat->frequency = fdtdec_get_int(blob, subnode, "spi-max-frequency", 75 100000000); 76 77 return 0; 78 } 79 80 static int rockchip_sfc_probe(struct udevice *bus) 81 { 82 struct rockchip_sfc_platdata *plat = dev_get_platdata(bus); 83 struct rockchip_sfc *sfc = dev_get_priv(bus); 84 int ret; 85 86 sfc->regbase = (struct rockchip_sfc_reg *)plat->base; 87 88 sfc->max_freq = plat->frequency; 89 90 ret = clk_set_rate(&sfc->clk, sfc->max_freq); 91 if (ret < 0) { 92 debug("%s: Failed to set clock: %d\n", __func__, ret); 93 return ret; 94 } 95 96 return 0; 97 } 98 99 static int rockchip_sfc_reset(struct rockchip_sfc *sfc) 100 { 101 struct rockchip_sfc_reg *regs = sfc->regbase; 102 int tbase = get_timer(0); 103 u32 rcvr; 104 int ret = 0; 105 106 writel(SFC_RESET, ®s->rcvr); 107 do { 108 rcvr = readl(®s->rcvr); 109 if (get_timer(tbase) > 1000) { 110 debug("sfc reset timeout\n"); 111 ret = -ETIMEDOUT; 112 break; 113 } 114 udelay(1); 115 } while (rcvr); 116 117 writel(0xFFFFFFFF, ®s->iclr); 118 119 debug("sfc reset\n"); 120 121 return ret; 122 } 123 124 /* The SFC_CTRL register is a global control register, 125 * when the controller is in busy state(SFC_SR), 126 * SFC_CTRL cannot be set. 127 */ 128 static int rockchip_sfc_wait_idle(struct rockchip_sfc *sfc, 129 u32 timeout_ms) 130 { 131 struct rockchip_sfc_reg *regs = sfc->regbase; 132 unsigned long tbase = get_timer(0); 133 u32 sr, fsr; 134 135 while (1) { 136 sr = readl(®s->sr); 137 fsr = readl(®s->fsr); 138 if ((fsr & SFC_TX_EMPTY) && (fsr & SFC_RX_EMPTY) && !(sr & SFC_BUSY)) 139 break; 140 if (get_timer(tbase) > timeout_ms) { 141 printf("waite sfc idle timeout(sr:0x%08x fsr:0x%08x)\n", 142 sr, fsr); 143 rockchip_sfc_reset(sfc); 144 return -ETIMEDOUT; 145 } 146 udelay(100); 147 } 148 149 return 0; 150 } 151 152 static u8 rockchip_sfc_get_if_type(struct rockchip_sfc *sfc) 153 { 154 int type = IF_TYPE_STD; 155 156 if (sfc->rw == SFC_WR) { 157 if (sfc->mode & SPI_TX_QUAD) 158 type = IF_TYPE_QUAD; 159 else if (sfc->mode & SPI_TX_DUAL) 160 type = IF_TYPE_DUAL; 161 else 162 type = IF_TYPE_STD; 163 } else { 164 if (sfc->mode & SPI_RX_QUAD) 165 type = IF_TYPE_QUAD; 166 else if (sfc->mode & SPI_RX_DUAL) 167 type = IF_TYPE_DUAL; 168 else 169 type = IF_TYPE_STD; 170 } 171 172 return type; 173 } 174 175 static void rockchip_sfc_setup_xfer(struct rockchip_sfc *sfc, u32 trb) 176 { 177 struct rockchip_sfc_reg *regs = sfc->regbase; 178 u32 val = 0x02; 179 u8 data_width = IF_TYPE_STD; 180 181 if (sfc->addr_bits & SFC_ADDR_XBITS) 182 data_width = rockchip_sfc_get_if_type(sfc); 183 184 val |= (data_width << SFC_DATA_WIDTH_SHIFT); 185 186 rockchip_sfc_wait_idle(sfc, 10); 187 188 writel(val, ®s->ctrl); 189 190 val = sfc->cmd; 191 val |= trb << SFC_TRB_SHIFT; 192 val |= sfc->rw << SFC_RW_SHIFT; 193 val |= sfc->addr_bits << SFC_ADDR_BITS_SHIFT; 194 val |= sfc->dummy_bits << SFC_DUMMY_BITS_SHIFT; 195 196 writel(val, ®s->cmd); 197 198 if (sfc->addr_bits & SFC_ADDR_XBITS) 199 writel(sfc->addr, ®s->addr); 200 } 201 202 static int rockchip_sfc_dma_xfer(struct rockchip_sfc *sfc, void *buffer, size_t trb) 203 { 204 struct rockchip_sfc_reg *regs = sfc->regbase; 205 struct bounce_buffer bb; 206 unsigned int bb_flags; 207 int timeout = 1000; 208 int ret = 0; 209 int risr; 210 unsigned long tbase; 211 212 if (sfc->rw == SFC_WR) 213 bb_flags = GEN_BB_READ; 214 else 215 bb_flags = GEN_BB_WRITE; 216 217 ret = bounce_buffer_start(&bb, buffer, trb, bb_flags); 218 if (ret) 219 return ret; 220 221 rockchip_sfc_setup_xfer(sfc, bb.len_aligned); 222 223 writel(0xFFFFFFFF, ®s->iclr); 224 writel((u32)bb.bounce_buffer, ®s->dmaaddr); 225 writel(SFC_DMA_START, ®s->dmatr); 226 227 tbase = get_timer(0); 228 do { 229 udelay(1); 230 risr = readl(®s->risr); 231 if (get_timer(tbase) > timeout) { 232 debug("dma timeout\n"); 233 ret = -ETIMEDOUT; 234 break; 235 } 236 } while (!(risr & TRANS_FINISH_INT)); 237 238 writel(0xFFFFFFFF, ®s->iclr); 239 240 bounce_buffer_stop(&bb); 241 242 return ret; 243 } 244 245 static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int rw, 246 u32 timeout) 247 { 248 struct rockchip_sfc_reg *regs = sfc->regbase; 249 unsigned long tbase = get_timer(0); 250 u8 level; 251 u32 fsr; 252 253 do { 254 fsr = readl(®s->fsr); 255 if (rw == SFC_WR) 256 level = (fsr & SFC_TXLV_MASK) >> SFC_TXLV_SHIFT; 257 else 258 level = (fsr & SFC_RXLV_MASK) >> SFC_RXLV_SHIFT; 259 if (get_timer(tbase) > timeout) 260 return -ETIMEDOUT; 261 udelay(1); 262 } while (!level); 263 264 return level; 265 } 266 267 static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, u32 *buf, u32 len) 268 { 269 struct rockchip_sfc_reg *regs = sfc->regbase; 270 u32 bytes = len & 0x3; 271 u32 words = len >> 2; 272 int tx_level = 0; 273 u32 val = 0; 274 u8 count; 275 276 while (words) { 277 tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_WR, 1000); 278 if (tx_level <= 0) 279 return tx_level; 280 count = min(words, (u32)tx_level); 281 writesl(®s->data, buf, count); 282 buf += count; 283 words -= count; 284 } 285 286 /* handle the last non 4byte aligned bytes */ 287 if (bytes) { 288 tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_WR, 1000); 289 if (tx_level <= 0) 290 return tx_level; 291 memcpy(&val, buf, bytes); 292 writel(val, ®s->data); 293 } 294 295 return 0; 296 } 297 298 static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u32 *buf, u32 len) 299 { 300 struct rockchip_sfc_reg *regs = sfc->regbase; 301 u32 bytes = len & 0x3; 302 u32 words = len >> 2; 303 int rx_level = 0; 304 u32 count; 305 u32 val; 306 307 while (words) { 308 rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_RD, 1000); 309 if (rx_level <= 0) 310 return rx_level; 311 count = min(words, (u32)rx_level); 312 readsl(®s->data, buf, count); 313 buf += count; 314 words -= count; 315 } 316 317 /* handle the last non 4 bytes aligned bytes */ 318 if (bytes) { 319 rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_RD, 1000); 320 if (rx_level <= 0) 321 return rx_level; 322 val = readl(®s->data); 323 memcpy(buf, &val, bytes); 324 } 325 326 return 0; 327 } 328 329 static int rockchip_sfc_pio_xfer(struct rockchip_sfc *sfc, void *buf, u32 len) 330 { 331 int ret = 0; 332 333 rockchip_sfc_setup_xfer(sfc, len); 334 335 if (len) { 336 if (sfc->rw == SFC_WR) 337 ret = rockchip_sfc_write_fifo(sfc, (u32 *)buf, len); 338 else 339 ret = rockchip_sfc_read_fifo(sfc, (u32 *)buf, len); 340 } 341 342 return ret; 343 } 344 345 static int rockchip_sfc_read(struct rockchip_sfc *sfc, u32 offset, 346 void *buf, size_t len) 347 { 348 u32 dma_trans; 349 u32 trb; 350 u8 bytes; 351 int ret; 352 353 if (len >= ARCH_DMA_MINALIGN) { 354 bytes = len & (ARCH_DMA_MINALIGN - 1); 355 dma_trans = len - bytes; 356 } else { 357 dma_trans = 0; 358 bytes = len; 359 } 360 361 while (dma_trans) { 362 trb = min_t(size_t, dma_trans, SFC_MAX_TRB); 363 ret = rockchip_sfc_dma_xfer(sfc, buf, trb); 364 if (ret < 0) 365 return ret; 366 dma_trans -= trb; 367 sfc->addr += trb; 368 buf += trb; 369 } 370 371 /* 372 * transfer the last non dma anligned byte by pio mode 373 */ 374 if (bytes) 375 ret = rockchip_sfc_pio_xfer(sfc, buf, bytes); 376 377 return 0; 378 } 379 380 static int rockchip_sfc_write(struct rockchip_sfc *sfc, u32 offset, 381 void *buf, size_t len) 382 { 383 384 if (len > SFC_MAX_TRB) { 385 printf("out of the max sfc trb"); 386 return -EINVAL; 387 } 388 389 if (len && !(len & (ARCH_DMA_MINALIGN - 1))) 390 return rockchip_sfc_dma_xfer(sfc, buf, len); 391 else 392 return rockchip_sfc_pio_xfer(sfc, buf,len); 393 394 return 0; 395 } 396 397 static int rockchip_sfc_do_xfer(struct rockchip_sfc *sfc, void *buf, size_t len) 398 { 399 400 if (sfc->rw) 401 return rockchip_sfc_write(sfc, sfc->addr, buf, len); 402 else 403 return rockchip_sfc_read(sfc, sfc->addr, buf, len); 404 } 405 406 static int rockchip_sfc_xfer(struct udevice *dev, unsigned int bitlen, 407 const void *dout, void *din, unsigned long flags) 408 { 409 struct udevice *bus = dev->parent; 410 struct rockchip_sfc *sfc = dev_get_priv(bus); 411 int len = bitlen >> 3; 412 u8 *pcmd = (u8 *)dout; 413 void *data_buf; 414 int ret = 0; 415 416 if (flags & SPI_XFER_BEGIN) { 417 sfc->cmd = pcmd[0]; 418 if (len >= 4) { 419 sfc->addr_bits = SFC_ADDR_24BITS; 420 sfc->dummy_bits = (len - 4) << 3; 421 sfc->addr = pcmd[3] | (pcmd[2] << 8) | (pcmd[1] << 16); 422 } else { 423 sfc->addr_bits = 0; 424 sfc->dummy_bits = 0; 425 sfc->addr = 0; 426 } 427 } 428 429 if (flags & SPI_XFER_END) { 430 431 if (din) { 432 sfc->rw = SFC_RD; 433 data_buf = din; 434 } else { 435 sfc->rw = SFC_WR; 436 data_buf = (void *)dout; 437 } 438 439 if (flags == (SPI_XFER_BEGIN | SPI_XFER_END)) { 440 len = 0; 441 data_buf = NULL; 442 } 443 444 ret = rockchip_sfc_do_xfer(sfc, data_buf, len); 445 } 446 447 return ret; 448 } 449 450 static int rockchip_sfc_set_speed(struct udevice *bus, uint speed) 451 { 452 struct rockchip_sfc *sfc = dev_get_priv(bus); 453 454 if (speed > sfc->max_freq) 455 speed = sfc->max_freq; 456 457 sfc->speed_hz = speed; 458 459 return 0; 460 } 461 462 static int rockchip_sfc_set_mode(struct udevice *bus, uint mode) 463 { 464 struct rockchip_sfc *sfc = dev_get_priv(bus); 465 466 sfc->mode = mode; 467 468 return 0; 469 } 470 471 static const struct dm_spi_ops rockchip_sfc_ops = { 472 .xfer = rockchip_sfc_xfer, 473 .set_speed = rockchip_sfc_set_speed, 474 .set_mode = rockchip_sfc_set_mode, 475 }; 476 477 static const struct udevice_id rockchip_sfc_ids[] = { 478 { .compatible = "rockchip,sfc" }, 479 { } 480 }; 481 482 U_BOOT_DRIVER(rockchip_sfc_driver) = { 483 .name = "rockchip_sfc", 484 .id = UCLASS_SPI, 485 .of_match = rockchip_sfc_ids, 486 .ops = &rockchip_sfc_ops, 487 .ofdata_to_platdata = rockchip_sfc_ofdata_to_platdata, 488 .platdata_auto_alloc_size = sizeof(struct rockchip_sfc_platdata), 489 .priv_auto_alloc_size = sizeof(struct rockchip_sfc), 490 .probe = rockchip_sfc_probe, 491 }; 492