1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2019 Intel Corporation 3 */ 4 5 #include "opae_spi.h" 6 #include "ifpga_compat.h" 7 8 /*transaction opcodes*/ 9 #define SPI_TRAN_SEQ_WRITE 0x04 /* SPI transaction sequential write */ 10 #define SPI_TRAN_SEQ_READ 0x14 /* SPI transaction sequential read */ 11 #define SPI_TRAN_NON_SEQ_WRITE 0x00 /* SPI transaction non-sequential write */ 12 #define SPI_TRAN_NON_SEQ_READ 0x10 /* SPI transaction non-sequential read*/ 13 14 /*specail packet characters*/ 15 #define SPI_PACKET_SOP 0x7a 16 #define SPI_PACKET_EOP 0x7b 17 #define SPI_PACKET_CHANNEL 0x7c 18 #define SPI_PACKET_ESC 0x7d 19 20 /*special byte characters*/ 21 #define SPI_BYTE_IDLE 0x4a 22 #define SPI_BYTE_ESC 0x4d 23 24 #define SPI_REG_BYTES 4 25 26 #define INIT_SPI_TRAN_HEADER(trans_type, size, address) \ 27 __extension__ ({ \ 28 header.trans_type = trans_type; \ 29 header.reserve = 0; \ 30 header.size = cpu_to_be16(size); \ 31 header.addr = cpu_to_be32(addr); \ 32 }) 33 34 #ifdef OPAE_SPI_DEBUG 35 static void print_buffer(const char *string, void *buffer, int len) 36 { 37 int i; 38 unsigned char *p = buffer; 39 40 printf("%s print buffer, len=%d\n", string, len); 41 42 for (i = 0; i < len; i++) 43 printf("%02x ", *(p+i)); 44 printf("\n"); 45 } 46 #else 47 static void print_buffer(const char *string, void *buffer, int len) 48 { 49 UNUSED(string); 50 UNUSED(buffer); 51 UNUSED(len); 52 } 53 #endif 54 55 static unsigned char xor_20(unsigned char val) 56 { 57 return val^0x20; 58 } 59 60 static void reorder_phy_data(u8 bits_per_word, 61 void *buf, unsigned int len) 62 { 63 unsigned int count = len / (bits_per_word/8); 64 u32 *p; 65 66 if (bits_per_word == 32) { 67 p = (u32 *)buf; 68 while (count--) { 69 *p = cpu_to_be32(*p); 70 p++; 71 } 72 } 73 } 74 75 static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len, 76 unsigned int *aligned_len) 77 { 78 unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p; 79 80 *aligned_len = IFPGA_ALIGN(phy_buf_len, 4); 81 82 if (*aligned_len == phy_buf_len) 83 return; 84 85 dst_p = &phy_buf[*aligned_len - 1]; 86 87 /* move EOP and bytes after EOP to the end of aligned size */ 88 while (p > phy_buf) { 89 *dst_p = *p; 90 91 if (*p == SPI_PACKET_EOP) 92 break; 93 94 p--; 95 dst_p--; 96 } 97 98 /* fill the hole with PHY_IDLE */ 99 while (p < dst_p) 100 *p++ = SPI_BYTE_IDLE; 101 } 102 103 #define RX_ALL_IDLE_DATA (SPI_BYTE_IDLE << 24 | SPI_BYTE_IDLE << 16 | \ 104 SPI_BYTE_IDLE << 8 | SPI_BYTE_IDLE) 105 106 static bool all_idle_data(u8 *rxbuf) 107 { 108 return *(u32 *)rxbuf == RX_ALL_IDLE_DATA; 109 } 110 111 static unsigned char *find_eop(u8 *rxbuf, u32 BPW) 112 { 113 return memchr(rxbuf, SPI_PACKET_EOP, BPW); 114 } 115 116 static int do_spi_txrx(struct spi_transaction_dev *dev, 117 unsigned char *tx_buffer, 118 unsigned int tx_len, unsigned char *rx_buffer, 119 unsigned int rx_len, 120 unsigned int *actual_rx) 121 { 122 unsigned int rx_cnt = 0; 123 int ret = 0; 124 unsigned int BPW = 4; 125 bool eop_found = false; 126 unsigned char *eop; 127 unsigned char *ptr; 128 unsigned char *rxbuf = rx_buffer; 129 int add_byte = 0; 130 unsigned long ticks; 131 unsigned long timeout; 132 133 /* send command */ 134 ret = spi_write(dev->dev, dev->chipselect, tx_len, tx_buffer); 135 if (ret) 136 return -EBUSY; 137 138 timeout = rte_get_timer_cycles() + 139 msecs_to_timer_cycles(2000); 140 141 /* read out data */ 142 while (rx_cnt < rx_len) { 143 ret = spi_read(dev->dev, dev->chipselect, BPW, rxbuf); 144 if (ret) 145 return -EBUSY; 146 147 /* skip all of invalid data */ 148 if (!eop_found && all_idle_data(rxbuf)) { 149 ticks = rte_get_timer_cycles(); 150 if (!time_after(ticks, timeout)) { 151 continue; 152 } else { 153 dev_err(dev, "read spi data timeout\n"); 154 return -ETIMEDOUT; 155 } 156 } 157 158 rx_cnt += BPW; 159 if (!eop_found) { 160 /* EOP is found, we read 2 more bytes and exit. */ 161 eop = find_eop(rxbuf, BPW); 162 if (eop) { 163 if ((BPW + rxbuf - eop) > 2) { 164 /* 165 * check if the last 2 bytes are already 166 * received in current word. 167 */ 168 break; 169 } else if ((BPW + rxbuf - eop) == 2) { 170 /* 171 * skip if last byte is not SPI_BYTE_ESC 172 * or SPI_PACKET_ESC. this is the valid 173 * end of a response too. 174 */ 175 ptr = eop + 1; 176 177 if (*ptr != SPI_BYTE_ESC && 178 *ptr != SPI_PACKET_ESC) 179 break; 180 181 add_byte = 1; 182 } else { 183 add_byte = 2; 184 } 185 186 rx_len = min(rx_len, 187 IFPGA_ALIGN(rx_cnt + 188 add_byte, BPW)); 189 eop_found = true; 190 } 191 } 192 rxbuf += BPW; 193 } 194 195 *actual_rx = rx_cnt; 196 print_buffer("found valid data:", rx_buffer, rx_cnt); 197 198 return ret; 199 } 200 201 static int byte_to_core_convert(struct spi_transaction_dev *dev, 202 unsigned int send_len, unsigned char *send_data, 203 unsigned int resp_len, unsigned char *resp_data, 204 unsigned int *valid_resp_len) 205 { 206 unsigned int i; 207 int ret = 0; 208 unsigned char *send_packet = dev->buffer->bytes_send; 209 unsigned char *resp_packet = dev->buffer->bytes_resp; 210 unsigned char *p; 211 unsigned char current_byte; 212 unsigned int tx_len = 0; 213 unsigned int resp_max_len = 2 * resp_len; 214 unsigned int actual_rx; 215 216 print_buffer("before bytes:", send_data, send_len); 217 218 p = send_packet; 219 220 for (i = 0; i < send_len; i++) { 221 current_byte = send_data[i]; 222 switch (current_byte) { 223 case SPI_BYTE_IDLE: 224 *p++ = SPI_BYTE_ESC; 225 *p++ = xor_20(current_byte); 226 break; 227 case SPI_BYTE_ESC: 228 *p++ = SPI_BYTE_ESC; 229 *p++ = xor_20(current_byte); 230 break; 231 default: 232 *p++ = current_byte; 233 break; 234 } 235 } 236 237 tx_len = p - send_packet; 238 239 print_buffer("before spi:", send_packet, tx_len); 240 241 phy_tx_pad(send_packet, tx_len, &tx_len); 242 print_buffer("after pad:", send_packet, tx_len); 243 244 reorder_phy_data(32, send_packet, tx_len); 245 246 print_buffer("after order to spi:", send_packet, tx_len); 247 248 ret = do_spi_txrx(dev, send_packet, tx_len, resp_packet, 249 resp_max_len, &actual_rx); 250 if (ret) 251 return ret; 252 253 /* analyze response packet */ 254 i = 0; 255 p = resp_data; 256 while (i < actual_rx) { 257 current_byte = resp_packet[i]; 258 switch (current_byte) { 259 case SPI_BYTE_IDLE: 260 i++; 261 break; 262 case SPI_BYTE_ESC: 263 i++; 264 current_byte = resp_packet[i]; 265 *p++ = xor_20(current_byte); 266 i++; 267 break; 268 default: 269 *p++ = current_byte; 270 i++; 271 break; 272 } 273 } 274 275 /* receive "4a" means the SPI is idle, not valid data */ 276 *valid_resp_len = p - resp_data; 277 if (*valid_resp_len == 0) { 278 dev_err(NULL, "error: repond package without valid data\n"); 279 return -EINVAL; 280 } 281 282 return 0; 283 } 284 285 static int packet_to_byte_conver(struct spi_transaction_dev *dev, 286 unsigned int send_len, unsigned char *send_buf, 287 unsigned int resp_len, unsigned char *resp_buf, 288 unsigned int *valid) 289 { 290 int ret = 0; 291 unsigned int i; 292 unsigned char current_byte; 293 unsigned int resp_max_len; 294 unsigned char *send_packet = dev->buffer->packet_send; 295 unsigned char *resp_packet = dev->buffer->packet_resp; 296 unsigned char *p; 297 unsigned int valid_resp_len = 0; 298 299 print_buffer("before packet:", send_buf, send_len); 300 301 resp_max_len = 2 * resp_len + 4; 302 303 p = send_packet; 304 305 /* SOP header */ 306 *p++ = SPI_PACKET_SOP; 307 308 *p++ = SPI_PACKET_CHANNEL; 309 *p++ = 0; 310 311 /* append the data into a packet */ 312 for (i = 0; i < send_len; i++) { 313 current_byte = send_buf[i]; 314 315 /* EOP for last byte */ 316 if (i == send_len - 1) 317 *p++ = SPI_PACKET_EOP; 318 319 switch (current_byte) { 320 case SPI_PACKET_SOP: 321 case SPI_PACKET_EOP: 322 case SPI_PACKET_CHANNEL: 323 case SPI_PACKET_ESC: 324 *p++ = SPI_PACKET_ESC; 325 *p++ = xor_20(current_byte); 326 break; 327 default: 328 *p++ = current_byte; 329 } 330 } 331 332 ret = byte_to_core_convert(dev, p - send_packet, 333 send_packet, resp_max_len, resp_packet, 334 &valid_resp_len); 335 if (ret) 336 return -EBUSY; 337 338 print_buffer("after byte conver:", resp_packet, valid_resp_len); 339 340 /* analyze the response packet */ 341 p = resp_buf; 342 343 /* look for SOP */ 344 for (i = 0; i < valid_resp_len; i++) { 345 if (resp_packet[i] == SPI_PACKET_SOP) 346 break; 347 } 348 349 if (i == valid_resp_len) { 350 dev_err(NULL, "error on analyze response packet 0x%x\n", 351 resp_packet[i]); 352 return -EINVAL; 353 } 354 355 i++; 356 357 /* continue parsing data after SOP */ 358 while (i < valid_resp_len) { 359 current_byte = resp_packet[i]; 360 361 switch (current_byte) { 362 case SPI_PACKET_SOP: 363 dev_err(dev, "error on get SOP after SOP\n"); 364 return -EINVAL; 365 case SPI_PACKET_CHANNEL: 366 i += 2; 367 break; 368 case SPI_PACKET_ESC: 369 i++; 370 current_byte = resp_packet[i]; 371 *p++ = xor_20(current_byte); 372 i++; 373 break; 374 case SPI_PACKET_EOP: 375 i++; 376 current_byte = resp_packet[i]; 377 switch (current_byte) { 378 case SPI_PACKET_ESC: 379 i++; 380 current_byte = resp_packet[i]; 381 *p++ = xor_20(current_byte); 382 break; 383 case SPI_PACKET_CHANNEL: 384 case SPI_PACKET_SOP: 385 case SPI_PACKET_EOP: 386 dev_err(dev, "error get SOP/EOP after EOP\n"); 387 return -EINVAL; 388 default: 389 *p++ = current_byte; 390 break; 391 } 392 goto done; 393 394 default: 395 *p++ = current_byte; 396 i++; 397 } 398 } 399 400 done: 401 *valid = p - resp_buf; 402 403 print_buffer("after packet:", resp_buf, *valid); 404 405 return ret; 406 } 407 408 static int do_transaction(struct spi_transaction_dev *dev, unsigned int addr, 409 unsigned int size, unsigned char *data, 410 unsigned int trans_type) 411 { 412 413 struct spi_tran_header header; 414 unsigned char *transaction = dev->buffer->tran_send; 415 unsigned char *response = dev->buffer->tran_resp; 416 unsigned char *p; 417 int ret = 0; 418 unsigned int i; 419 unsigned int valid_len = 0; 420 421 /* make transacation header */ 422 INIT_SPI_TRAN_HEADER(trans_type, size, addr); 423 424 /* fill the header */ 425 p = transaction; 426 opae_memcpy(p, &header, sizeof(struct spi_tran_header)); 427 p = p + sizeof(struct spi_tran_header); 428 429 switch (trans_type) { 430 case SPI_TRAN_SEQ_WRITE: 431 case SPI_TRAN_NON_SEQ_WRITE: 432 for (i = 0; i < size; i++) 433 *p++ = *data++; 434 435 ret = packet_to_byte_conver(dev, size + HEADER_LEN, 436 transaction, RESPONSE_LEN, response, 437 &valid_len); 438 if (ret) 439 return -EBUSY; 440 441 /* check the result */ 442 if (size != ((unsigned int)(response[2] & 0xff) << 8 | 443 (unsigned int)(response[3] & 0xff))) 444 ret = -EBUSY; 445 446 break; 447 case SPI_TRAN_SEQ_READ: 448 case SPI_TRAN_NON_SEQ_READ: 449 ret = packet_to_byte_conver(dev, HEADER_LEN, 450 transaction, size, response, 451 &valid_len); 452 if (ret || valid_len != size) 453 return -EBUSY; 454 455 for (i = 0; i < size; i++) 456 *data++ = *response++; 457 458 ret = 0; 459 break; 460 } 461 462 return ret; 463 } 464 465 int spi_transaction_read(struct spi_transaction_dev *dev, unsigned int addr, 466 unsigned int size, unsigned char *data) 467 { 468 int ret; 469 470 pthread_mutex_lock(dev->mutex); 471 ret = do_transaction(dev, addr, size, data, 472 (size > SPI_REG_BYTES) ? 473 SPI_TRAN_SEQ_READ : SPI_TRAN_NON_SEQ_READ); 474 pthread_mutex_unlock(dev->mutex); 475 476 return ret; 477 } 478 479 int spi_transaction_write(struct spi_transaction_dev *dev, unsigned int addr, 480 unsigned int size, unsigned char *data) 481 { 482 int ret; 483 484 pthread_mutex_lock(dev->mutex); 485 ret = do_transaction(dev, addr, size, data, 486 (size > SPI_REG_BYTES) ? 487 SPI_TRAN_SEQ_WRITE : SPI_TRAN_NON_SEQ_WRITE); 488 pthread_mutex_unlock(dev->mutex); 489 490 return ret; 491 } 492 493 struct spi_transaction_dev *spi_transaction_init(struct altera_spi_device *dev, 494 int chipselect) 495 { 496 struct spi_transaction_dev *spi_tran_dev; 497 498 spi_tran_dev = opae_malloc(sizeof(struct spi_transaction_dev)); 499 if (!spi_tran_dev) 500 return NULL; 501 502 spi_tran_dev->dev = dev; 503 spi_tran_dev->chipselect = chipselect; 504 505 spi_tran_dev->buffer = opae_malloc(sizeof(struct spi_tran_buffer)); 506 if (!spi_tran_dev->buffer) 507 goto err; 508 509 pthread_mutex_init(&spi_tran_dev->lock, NULL); 510 if (dev->mutex) { 511 dev_info(NULL, "use multi-process mutex in spi\n"); 512 spi_tran_dev->mutex = dev->mutex; 513 } else { 514 dev_info(NULL, "use multi-thread mutex in spi\n"); 515 spi_tran_dev->mutex = &spi_tran_dev->lock; 516 } 517 518 return spi_tran_dev; 519 520 err: 521 opae_free(spi_tran_dev); 522 return NULL; 523 } 524 525 void spi_transaction_remove(struct spi_transaction_dev *dev) 526 { 527 if (dev && dev->buffer) 528 opae_free(dev->buffer); 529 if (dev) { 530 pthread_mutex_destroy(&dev->lock); 531 opae_free(dev); 532 } 533 } 534