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 ({ \
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
print_buffer(const char * string,void * buffer,int len)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
print_buffer(const char * string,void * buffer,int len)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
xor_20(unsigned char val)55 static unsigned char xor_20(unsigned char val)
56 {
57 return val^0x20;
58 }
59
reorder_phy_data(u8 bits_per_word,void * buf,unsigned int len)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
phy_tx_pad(unsigned char * phy_buf,unsigned int phy_buf_len,unsigned int * aligned_len)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
all_idle_data(u8 * rxbuf)106 static bool all_idle_data(u8 *rxbuf)
107 {
108 return *(u32 *)rxbuf == RX_ALL_IDLE_DATA;
109 }
110
find_eop(u8 * rxbuf,u32 BPW)111 static unsigned char *find_eop(u8 *rxbuf, u32 BPW)
112 {
113 return memchr(rxbuf, SPI_PACKET_EOP, BPW);
114 }
115
do_spi_txrx(struct spi_transaction_dev * dev,unsigned char * tx_buffer,unsigned int tx_len,unsigned char * rx_buffer,unsigned int rx_len,unsigned int * actual_rx)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
byte_to_core_convert(struct spi_transaction_dev * dev,unsigned int send_len,unsigned char * send_data,unsigned int resp_len,unsigned char * resp_data,unsigned int * valid_resp_len)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
packet_to_byte_conver(struct spi_transaction_dev * dev,unsigned int send_len,unsigned char * send_buf,unsigned int resp_len,unsigned char * resp_buf,unsigned int * valid)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
do_transaction(struct spi_transaction_dev * dev,unsigned int addr,unsigned int size,unsigned char * data,unsigned int trans_type)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
spi_transaction_read(struct spi_transaction_dev * dev,unsigned int addr,unsigned int size,unsigned char * data)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
spi_transaction_write(struct spi_transaction_dev * dev,unsigned int addr,unsigned int size,unsigned char * data)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
spi_transaction_init(struct altera_spi_device * dev,int chipselect)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 int ret;
498
499 spi_tran_dev = opae_malloc(sizeof(struct spi_transaction_dev));
500 if (!spi_tran_dev)
501 return NULL;
502
503 spi_tran_dev->dev = dev;
504 spi_tran_dev->chipselect = chipselect;
505
506 spi_tran_dev->buffer = opae_malloc(sizeof(struct spi_tran_buffer));
507 if (!spi_tran_dev->buffer)
508 goto err;
509
510 ret = pthread_mutex_init(&spi_tran_dev->lock, NULL);
511 if (ret) {
512 dev_err(spi_tran_dev, "fail to init mutex lock\n");
513 goto err;
514 }
515 if (dev->mutex) {
516 dev_info(NULL, "use multi-process mutex in spi\n");
517 spi_tran_dev->mutex = dev->mutex;
518 } else {
519 dev_info(NULL, "use multi-thread mutex in spi\n");
520 spi_tran_dev->mutex = &spi_tran_dev->lock;
521 }
522
523 return spi_tran_dev;
524
525 err:
526 opae_free(spi_tran_dev);
527 return NULL;
528 }
529
spi_transaction_remove(struct spi_transaction_dev * dev)530 void spi_transaction_remove(struct spi_transaction_dev *dev)
531 {
532 if (dev && dev->buffer)
533 opae_free(dev->buffer);
534 if (dev) {
535 pthread_mutex_destroy(&dev->lock);
536 opae_free(dev);
537 }
538 }
539