1 /* 2 * Andestech ATCSPI200 SPI controller driver. 3 * 4 * Copyright 2017 Andes Technology, Inc. 5 * Author: Rick Chen (rick@andestech.com) 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <clk.h> 11 #include <common.h> 12 #include <malloc.h> 13 #include <spi.h> 14 #include <asm/io.h> 15 #include <dm.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 #define MAX_TRANSFER_LEN 512 20 #define CHUNK_SIZE 1 21 #define SPI_TIMEOUT 0x100000 22 #define SPI0_BUS 0 23 #define SPI1_BUS 1 24 #define SPI0_BASE 0xf0b00000 25 #define SPI1_BASE 0xf0f00000 26 #define NSPI_MAX_CS_NUM 1 27 28 struct atcspi200_spi_regs { 29 u32 rev; 30 u32 reserve1[3]; 31 u32 format; /* 0x10 */ 32 #define DATA_LENGTH(x) ((x-1)<<8) 33 u32 pio; 34 u32 reserve2[2]; 35 u32 tctrl; /* 0x20 */ 36 #define TRAMODE_OFFSET 24 37 #define TRAMODE_MASK (0x0F<<TRAMODE_OFFSET) 38 #define TRAMODE_WR_SYNC (0<<TRAMODE_OFFSET) 39 #define TRAMODE_WO (1<<TRAMODE_OFFSET) 40 #define TRAMODE_RO (2<<TRAMODE_OFFSET) 41 #define TRAMODE_WR (3<<TRAMODE_OFFSET) 42 #define TRAMODE_RW (4<<TRAMODE_OFFSET) 43 #define TRAMODE_WDR (5<<TRAMODE_OFFSET) 44 #define TRAMODE_RDW (6<<TRAMODE_OFFSET) 45 #define TRAMODE_NONE (7<<TRAMODE_OFFSET) 46 #define TRAMODE_DW (8<<TRAMODE_OFFSET) 47 #define TRAMODE_DR (9<<TRAMODE_OFFSET) 48 #define WCNT_OFFSET 12 49 #define WCNT_MASK (0x1FF<<WCNT_OFFSET) 50 #define RCNT_OFFSET 0 51 #define RCNT_MASK (0x1FF<<RCNT_OFFSET) 52 u32 cmd; 53 u32 addr; 54 u32 data; 55 u32 ctrl; /* 0x30 */ 56 #define TXFTH_OFFSET 16 57 #define RXFTH_OFFSET 8 58 #define TXDMAEN (1<<4) 59 #define RXDMAEN (1<<3) 60 #define TXFRST (1<<2) 61 #define RXFRST (1<<1) 62 #define SPIRST (1<<0) 63 u32 status; 64 #define TXFFL (1<<23) 65 #define TXEPTY (1<<22) 66 #define TXFVE_MASK (0x1F<<16) 67 #define RXFEM (1<<14) 68 #define RXFVE_OFFSET (8) 69 #define RXFVE_MASK (0x1F<<RXFVE_OFFSET) 70 #define SPIBSY (1<<0) 71 u32 inten; 72 u32 intsta; 73 u32 timing; /* 0x40 */ 74 #define SCLK_DIV_MASK 0xFF 75 }; 76 77 struct nds_spi_slave { 78 #ifndef CONFIG_DM_SPI 79 struct spi_slave slave; 80 #endif 81 volatile struct atcspi200_spi_regs *regs; 82 int to; 83 unsigned int freq; 84 ulong clock; 85 unsigned int mode; 86 u8 num_cs; 87 unsigned int mtiming; 88 size_t cmd_len; 89 u8 cmd_buf[16]; 90 size_t data_len; 91 size_t tran_len; 92 u8 *din; 93 u8 *dout; 94 unsigned int max_transfer_length; 95 }; 96 97 static int __atcspi200_spi_set_speed(struct nds_spi_slave *ns) 98 { 99 u32 tm; 100 u8 div; 101 tm = ns->regs->timing; 102 tm &= ~SCLK_DIV_MASK; 103 104 if(ns->freq >= ns->clock) 105 div =0xff; 106 else{ 107 for (div = 0; div < 0xff; div++) { 108 if (ns->freq >= ns->clock / (2 * (div + 1))) 109 break; 110 } 111 } 112 113 tm |= div; 114 ns->regs->timing = tm; 115 116 return 0; 117 118 } 119 120 static int __atcspi200_spi_claim_bus(struct nds_spi_slave *ns) 121 { 122 unsigned int format=0; 123 ns->regs->ctrl |= (TXFRST|RXFRST|SPIRST); 124 while((ns->regs->ctrl &(TXFRST|RXFRST|SPIRST))&&(ns->to--)) 125 if(!ns->to) 126 return -EINVAL; 127 128 ns->cmd_len = 0; 129 format = ns->mode|DATA_LENGTH(8); 130 ns->regs->format = format; 131 __atcspi200_spi_set_speed(ns); 132 133 return 0; 134 } 135 136 static int __atcspi200_spi_release_bus(struct nds_spi_slave *ns) 137 { 138 /* do nothing */ 139 return 0; 140 } 141 142 static int __atcspi200_spi_start(struct nds_spi_slave *ns) 143 { 144 int i,olen=0; 145 int tc = ns->regs->tctrl; 146 147 tc &= ~(WCNT_MASK|RCNT_MASK|TRAMODE_MASK); 148 if ((ns->din)&&(ns->cmd_len)) 149 tc |= TRAMODE_WR; 150 else if (ns->din) 151 tc |= TRAMODE_RO; 152 else 153 tc |= TRAMODE_WO; 154 155 if(ns->dout) 156 olen = ns->tran_len; 157 tc |= (ns->cmd_len+olen-1) << WCNT_OFFSET; 158 159 if(ns->din) 160 tc |= (ns->tran_len-1) << RCNT_OFFSET; 161 162 ns->regs->tctrl = tc; 163 ns->regs->cmd = 1; 164 165 for (i=0;i<ns->cmd_len;i++) 166 ns->regs->data = ns->cmd_buf[i]; 167 168 return 0; 169 } 170 171 static int __atcspi200_spi_stop(struct nds_spi_slave *ns) 172 { 173 ns->regs->timing = ns->mtiming; 174 while ((ns->regs->status & SPIBSY)&&(ns->to--)) 175 if (!ns->to) 176 return -EINVAL; 177 178 return 0; 179 } 180 181 static void __nspi_espi_tx(struct nds_spi_slave *ns, const void *dout) 182 { 183 ns->regs->data = *(u8 *)dout; 184 } 185 186 static int __nspi_espi_rx(struct nds_spi_slave *ns, void *din, unsigned int bytes) 187 { 188 *(u8 *)din = ns->regs->data; 189 return bytes; 190 } 191 192 193 static int __atcspi200_spi_xfer(struct nds_spi_slave *ns, 194 unsigned int bitlen, const void *data_out, void *data_in, 195 unsigned long flags) 196 { 197 unsigned int event, rx_bytes; 198 const void *dout = NULL; 199 void *din = NULL; 200 int num_blks, num_chunks, max_tran_len, tran_len; 201 int num_bytes; 202 u8 *cmd_buf = ns->cmd_buf; 203 size_t cmd_len = ns->cmd_len; 204 size_t data_len = bitlen / 8; 205 int rf_cnt; 206 int ret = 0; 207 208 max_tran_len = ns->max_transfer_length; 209 switch (flags) { 210 case SPI_XFER_BEGIN: 211 cmd_len = ns->cmd_len = data_len; 212 memcpy(cmd_buf, data_out, cmd_len); 213 return 0; 214 215 case 0: 216 case SPI_XFER_END: 217 if (bitlen == 0) { 218 return 0; 219 } 220 ns->data_len = data_len; 221 ns->din = (u8 *)data_in; 222 ns->dout = (u8 *)data_out; 223 break; 224 225 case SPI_XFER_BEGIN | SPI_XFER_END: 226 ns->data_len = 0; 227 ns->din = 0; 228 ns->dout = 0; 229 cmd_len = ns->cmd_len = data_len; 230 memcpy(cmd_buf, data_out, cmd_len); 231 data_out = 0; 232 data_len = 0; 233 __atcspi200_spi_start(ns); 234 break; 235 } 236 debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n", 237 *(uint *)data_out, data_out, *(uint *)data_in, data_in, data_len); 238 num_chunks = DIV_ROUND_UP(data_len, max_tran_len); 239 din = data_in; 240 dout = data_out; 241 while (num_chunks--) { 242 tran_len = min(data_len, (size_t)max_tran_len); 243 ns->tran_len = tran_len; 244 num_blks = DIV_ROUND_UP(tran_len , CHUNK_SIZE); 245 num_bytes = (tran_len) % CHUNK_SIZE; 246 if(num_bytes == 0) 247 num_bytes = CHUNK_SIZE; 248 __atcspi200_spi_start(ns); 249 250 while (num_blks) { 251 event = in_le32(&ns->regs->status); 252 if ((event & TXEPTY) && (data_out)) { 253 __nspi_espi_tx(ns, dout); 254 num_blks -= CHUNK_SIZE; 255 dout += CHUNK_SIZE; 256 } 257 258 if ((event & RXFVE_MASK) && (data_in)) { 259 rf_cnt = ((event & RXFVE_MASK)>> RXFVE_OFFSET); 260 if (rf_cnt >= CHUNK_SIZE) 261 rx_bytes = CHUNK_SIZE; 262 else if (num_blks == 1 && rf_cnt == num_bytes) 263 rx_bytes = num_bytes; 264 else 265 continue; 266 267 if (__nspi_espi_rx(ns, din, rx_bytes) == rx_bytes) { 268 num_blks -= CHUNK_SIZE; 269 din = (unsigned char *)din + rx_bytes; 270 } 271 } 272 } 273 274 data_len -= tran_len; 275 if(data_len) 276 { 277 ns->cmd_buf[1] += ((tran_len>>16)&0xff); 278 ns->cmd_buf[2] += ((tran_len>>8)&0xff); 279 ns->cmd_buf[3] += ((tran_len)&0xff); 280 ns->data_len = data_len; 281 } 282 ret = __atcspi200_spi_stop(ns); 283 } 284 ret = __atcspi200_spi_stop(ns); 285 286 return ret; 287 } 288 289 #ifndef CONFIG_DM_SPI 290 #define to_nds_spi_slave(s) container_of(s, struct nds_spi_slave, slave) 291 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, 292 unsigned int max_hz, unsigned int mode) 293 { 294 struct nds_spi_slave *ns; 295 296 if (!spi_cs_is_valid(bus, cs)) 297 return NULL; 298 299 ns = spi_alloc_slave(struct nds_spi_slave, bus, cs); 300 if (!ns) 301 return NULL; 302 303 switch (bus) { 304 case SPI0_BUS: 305 ns->regs = (struct atcspi200_spi_regs *)SPI0_BASE; 306 break; 307 308 case SPI1_BUS: 309 ns->regs = (struct atcspi200_spi_regs *)SPI1_BASE; 310 break; 311 312 default: 313 return NULL; 314 } 315 316 ns->freq= max_hz; 317 ns->mode = mode; 318 ns->to = SPI_TIMEOUT; 319 ns->max_transfer_length = MAX_TRANSFER_LEN; 320 ns->slave.max_write_size = MAX_TRANSFER_LEN; 321 322 return &ns->slave; 323 } 324 325 void spi_free_slave(struct spi_slave *slave) 326 { 327 struct nds_spi_slave *ns = to_nds_spi_slave(slave); 328 free(ns); 329 } 330 331 void spi_init(void) 332 { 333 /* do nothing */ 334 } 335 336 int spi_claim_bus(struct spi_slave *slave) 337 { 338 struct nds_spi_slave *ns = to_nds_spi_slave(slave); 339 return __atcspi200_spi_claim_bus(ns); 340 } 341 342 void spi_release_bus(struct spi_slave *slave) 343 { 344 struct nds_spi_slave *ns = to_nds_spi_slave(slave); 345 __atcspi200_spi_release_bus(ns); 346 } 347 348 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, 349 void *data_in, unsigned long flags) 350 { 351 struct nds_spi_slave *ns = to_nds_spi_slave(slave); 352 return __atcspi200_spi_xfer(ns, bitlen, data_out, data_in, flags); 353 } 354 355 int spi_cs_is_valid(unsigned int bus, unsigned int cs) 356 { 357 return bus == 0 && cs < NSPI_MAX_CS_NUM; 358 } 359 360 void spi_cs_activate(struct spi_slave *slave) 361 { 362 struct nds_spi_slave *ns = to_nds_spi_slave(slave); 363 __atcspi200_spi_start(ns); 364 } 365 366 void spi_cs_deactivate(struct spi_slave *slave) 367 { 368 struct nds_spi_slave *ns = to_nds_spi_slave(slave); 369 __atcspi200_spi_stop(ns); 370 } 371 #else 372 static int atcspi200_spi_set_speed(struct udevice *bus, uint max_hz) 373 { 374 struct nds_spi_slave *ns = dev_get_priv(bus); 375 376 debug("%s speed %u\n", __func__, max_hz); 377 378 ns->freq = max_hz; 379 __atcspi200_spi_set_speed(ns); 380 381 return 0; 382 } 383 384 static int atcspi200_spi_set_mode(struct udevice *bus, uint mode) 385 { 386 struct nds_spi_slave *ns = dev_get_priv(bus); 387 388 debug("%s mode %u\n", __func__, mode); 389 ns->mode = mode; 390 391 return 0; 392 } 393 394 static int atcspi200_spi_claim_bus(struct udevice *dev) 395 { 396 struct dm_spi_slave_platdata *slave_plat = 397 dev_get_parent_platdata(dev); 398 struct udevice *bus = dev->parent; 399 struct nds_spi_slave *ns = dev_get_priv(bus); 400 401 if (slave_plat->cs >= ns->num_cs) { 402 printf("Invalid SPI chipselect\n"); 403 return -EINVAL; 404 } 405 406 return __atcspi200_spi_claim_bus(ns); 407 } 408 409 static int atcspi200_spi_release_bus(struct udevice *dev) 410 { 411 struct nds_spi_slave *ns = dev_get_priv(dev->parent); 412 413 return __atcspi200_spi_release_bus(ns); 414 } 415 416 static int atcspi200_spi_xfer(struct udevice *dev, unsigned int bitlen, 417 const void *dout, void *din, 418 unsigned long flags) 419 { 420 struct udevice *bus = dev->parent; 421 struct nds_spi_slave *ns = dev_get_priv(bus); 422 423 return __atcspi200_spi_xfer(ns, bitlen, dout, din, flags); 424 } 425 426 static int atcspi200_spi_get_clk(struct udevice *bus) 427 { 428 struct nds_spi_slave *ns = dev_get_priv(bus); 429 struct clk clk; 430 ulong clk_rate; 431 int ret; 432 433 ret = clk_get_by_index(bus, 0, &clk); 434 if (ret) 435 return -EINVAL; 436 437 clk_rate = clk_get_rate(&clk); 438 if (!clk_rate) 439 return -EINVAL; 440 441 ns->clock = clk_rate; 442 clk_free(&clk); 443 444 return 0; 445 } 446 447 static int atcspi200_spi_probe(struct udevice *bus) 448 { 449 struct nds_spi_slave *ns = dev_get_priv(bus); 450 451 ns->to = SPI_TIMEOUT; 452 ns->max_transfer_length = MAX_TRANSFER_LEN; 453 ns->mtiming = ns->regs->timing; 454 atcspi200_spi_get_clk(bus); 455 456 return 0; 457 } 458 459 static int atcspi200_ofdata_to_platadata(struct udevice *bus) 460 { 461 struct nds_spi_slave *ns = dev_get_priv(bus); 462 const void *blob = gd->fdt_blob; 463 int node = dev_of_offset(bus); 464 465 ns->regs = map_physmem(devfdt_get_addr(bus), 466 sizeof(struct atcspi200_spi_regs), 467 MAP_NOCACHE); 468 if (!ns->regs) { 469 printf("%s: could not map device address\n", __func__); 470 return -EINVAL; 471 } 472 ns->num_cs = fdtdec_get_int(blob, node, "num-cs", 4); 473 474 return 0; 475 } 476 477 static const struct dm_spi_ops atcspi200_spi_ops = { 478 .claim_bus = atcspi200_spi_claim_bus, 479 .release_bus = atcspi200_spi_release_bus, 480 .xfer = atcspi200_spi_xfer, 481 .set_speed = atcspi200_spi_set_speed, 482 .set_mode = atcspi200_spi_set_mode, 483 }; 484 485 static const struct udevice_id atcspi200_spi_ids[] = { 486 { .compatible = "andestech,atcspi200" }, 487 { } 488 }; 489 490 U_BOOT_DRIVER(atcspi200_spi) = { 491 .name = "atcspi200_spi", 492 .id = UCLASS_SPI, 493 .of_match = atcspi200_spi_ids, 494 .ops = &atcspi200_spi_ops, 495 .ofdata_to_platdata = atcspi200_ofdata_to_platadata, 496 .priv_auto_alloc_size = sizeof(struct nds_spi_slave), 497 .probe = atcspi200_spi_probe, 498 }; 499 #endif 500