1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2019 Intel Corporation
6 #include "ifpga_compat.h"
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*/
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
20 /*special byte characters*/
21 #define SPI_BYTE_IDLE 0x4a
22 #define SPI_BYTE_ESC 0x4d
24 #define SPI_REG_BYTES 4
26 #define INIT_SPI_TRAN_HEADER(trans_type, size, address) \
28 header.trans_type = trans_type; \
30 header.size = cpu_to_be16(size); \
31 header.addr = cpu_to_be32(addr); \
35 static void print_buffer(const char *string, void *buffer, int len)
38 unsigned char *p = buffer;
40 printf("%s print buffer, len=%d\n", string, len);
42 for (i = 0; i < len; i++)
43 printf("%x ", *(p+i));
47 static void print_buffer(const char *string, void *buffer, int len)
55 static unsigned char xor_20(unsigned char val)
60 static void reorder_phy_data(u8 bits_per_word,
61 void *buf, unsigned int len)
63 unsigned int count = len / (bits_per_word/8);
66 if (bits_per_word == 32) {
81 static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
84 int ret = SPI_NOT_FOUND;
86 unsigned char *b = resp;
89 if (flags != SPI_FOUND_SOP) {
90 while (b < resp + len && *b != SPI_PACKET_SOP)
93 if (*b != SPI_PACKET_SOP)
100 while (b < resp + len && *b != SPI_PACKET_EOP)
103 if (*b != SPI_PACKET_EOP)
112 static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
113 unsigned int *aligned_len)
115 unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
117 *aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
119 if (*aligned_len == phy_buf_len)
122 dst_p = &phy_buf[*aligned_len - 1];
124 /* move EOP and bytes after EOP to the end of aligned size */
125 while (p > phy_buf) {
128 if (*p == SPI_PACKET_EOP)
135 /* fill the hole with PHY_IDLE */
137 *p++ = SPI_BYTE_IDLE;
140 static int byte_to_core_convert(struct spi_transaction_dev *dev,
141 unsigned int send_len, unsigned char *send_data,
142 unsigned int resp_len, unsigned char *resp_data,
143 unsigned int *valid_resp_len)
147 unsigned char *send_packet = dev->buffer->bytes_send;
148 unsigned char *resp_packet = dev->buffer->bytes_resp;
150 unsigned char current_byte;
151 unsigned char *tx_buffer;
152 unsigned int tx_len = 0;
153 unsigned char *rx_buffer;
154 unsigned int rx_len = 0;
157 unsigned int resp_max_len = 2 * resp_len;
159 print_buffer("before bytes:", send_data, send_len);
163 for (i = 0; i < send_len; i++) {
164 current_byte = send_data[i];
165 switch (current_byte) {
167 *p++ = SPI_BYTE_IDLE;
168 *p++ = xor_20(current_byte);
172 *p++ = xor_20(current_byte);
180 tx_len = p - send_packet;
182 print_buffer("before spi:", send_packet, tx_len);
184 phy_tx_pad(send_packet, tx_len, &tx_len);
185 print_buffer("after pad:", send_packet, tx_len);
187 reorder_phy_data(32, send_packet, tx_len);
189 print_buffer("after order to spi:", send_packet, tx_len);
192 tx_buffer = send_packet;
193 rx_buffer = resp_packet;
194 rx_len = resp_max_len;
195 spi_flags = SPI_NOT_FOUND;
198 ret = spi_command(dev->dev, dev->chipselect, tx_len, tx_buffer,
203 print_buffer("read from spi:", rx_buffer, rx_len);
205 /* look for SOP firstly*/
206 ret = resp_find_sop_eop(rx_buffer, rx_len - 1, spi_flags);
207 if (ret != SPI_FOUND_EOP) {
211 dev_err(NULL, "cannot found valid data from SPI\n");
215 if (ret == SPI_FOUND_SOP) {
217 resp_max_len += rx_len;
224 print_buffer("found valid data:", resp_packet, resp_max_len);
226 /* analyze response packet */
229 while (i < resp_max_len) {
230 current_byte = resp_packet[i];
231 switch (current_byte) {
237 current_byte = resp_packet[i];
238 *p++ = xor_20(current_byte);
248 /* receive "4a" means the SPI is idle, not valid data */
249 *valid_resp_len = p - resp_data;
250 if (*valid_resp_len == 0) {
251 dev_err(NULL, "error: repond package without valid data\n");
258 static int packet_to_byte_conver(struct spi_transaction_dev *dev,
259 unsigned int send_len, unsigned char *send_buf,
260 unsigned int resp_len, unsigned char *resp_buf,
265 unsigned char current_byte;
266 unsigned int resp_max_len;
267 unsigned char *send_packet = dev->buffer->packet_send;
268 unsigned char *resp_packet = dev->buffer->packet_resp;
270 unsigned int valid_resp_len = 0;
272 print_buffer("before packet:", send_buf, send_len);
274 resp_max_len = 2 * resp_len + 4;
279 *p++ = SPI_PACKET_SOP;
281 *p++ = SPI_PACKET_CHANNEL;
284 /* append the data into a packet */
285 for (i = 0; i < send_len; i++) {
286 current_byte = send_buf[i];
288 /* EOP for last byte */
289 if (i == send_len - 1)
290 *p++ = SPI_PACKET_EOP;
292 switch (current_byte) {
295 case SPI_PACKET_CHANNEL:
297 *p++ = SPI_PACKET_ESC;
298 *p++ = xor_20(current_byte);
305 ret = byte_to_core_convert(dev, p - send_packet,
306 send_packet, resp_max_len, resp_packet,
311 print_buffer("after byte conver:", resp_packet, valid_resp_len);
313 /* analyze the response packet */
317 for (i = 0; i < valid_resp_len; i++) {
318 if (resp_packet[i] == SPI_PACKET_SOP)
322 if (i == valid_resp_len) {
323 dev_err(NULL, "error on analyze response packet 0x%x\n",
330 /* continue parsing data after SOP */
331 while (i < valid_resp_len) {
332 current_byte = resp_packet[i];
334 switch (current_byte) {
336 case SPI_PACKET_CHANNEL:
339 current_byte = resp_packet[i];
340 *p++ = xor_20(current_byte);
345 current_byte = resp_packet[i];
346 if (current_byte == SPI_PACKET_ESC ||
347 current_byte == SPI_PACKET_CHANNEL ||
348 current_byte == SPI_PACKET_SOP) {
350 current_byte = resp_packet[i];
351 *p++ = xor_20(current_byte);
363 *valid = p - resp_buf;
365 print_buffer("after packet:", resp_buf, *valid);
370 static int do_transaction(struct spi_transaction_dev *dev, unsigned int addr,
371 unsigned int size, unsigned char *data,
372 unsigned int trans_type)
375 struct spi_tran_header header;
376 unsigned char *transaction = dev->buffer->tran_send;
377 unsigned char *response = dev->buffer->tran_resp;
381 unsigned int valid_len = 0;
383 /* make transacation header */
384 INIT_SPI_TRAN_HEADER(trans_type, size, addr);
386 /* fill the header */
388 opae_memcpy(p, &header, sizeof(struct spi_tran_header));
389 p = p + sizeof(struct spi_tran_header);
391 switch (trans_type) {
392 case SPI_TRAN_SEQ_WRITE:
393 case SPI_TRAN_NON_SEQ_WRITE:
394 for (i = 0; i < size; i++)
397 ret = packet_to_byte_conver(dev, size + HEADER_LEN,
398 transaction, RESPONSE_LEN, response,
403 /* check the result */
404 if (size != ((unsigned int)(response[2] & 0xff) << 8 |
405 (unsigned int)(response[3] & 0xff)))
409 case SPI_TRAN_SEQ_READ:
410 case SPI_TRAN_NON_SEQ_READ:
411 ret = packet_to_byte_conver(dev, HEADER_LEN,
412 transaction, size, response,
414 if (ret || valid_len != size)
417 for (i = 0; i < size; i++)
418 *data++ = *response++;
427 int spi_transaction_read(struct spi_transaction_dev *dev, unsigned int addr,
428 unsigned int size, unsigned char *data)
430 return do_transaction(dev, addr, size, data,
431 (size > SPI_REG_BYTES) ?
432 SPI_TRAN_SEQ_READ : SPI_TRAN_NON_SEQ_READ);
435 int spi_transaction_write(struct spi_transaction_dev *dev, unsigned int addr,
436 unsigned int size, unsigned char *data)
438 return do_transaction(dev, addr, size, data,
439 (size > SPI_REG_BYTES) ?
440 SPI_TRAN_SEQ_WRITE : SPI_TRAN_NON_SEQ_WRITE);
443 struct spi_transaction_dev *spi_transaction_init(struct altera_spi_device *dev,
446 struct spi_transaction_dev *spi_tran_dev;
448 spi_tran_dev = opae_malloc(sizeof(struct spi_transaction_dev));
452 spi_tran_dev->dev = dev;
453 spi_tran_dev->chipselect = chipselect;
455 spi_tran_dev->buffer = opae_malloc(sizeof(struct spi_tran_buffer));
456 if (!spi_tran_dev->buffer) {
457 opae_free(spi_tran_dev);
464 void spi_transaction_remove(struct spi_transaction_dev *dev)
466 if (dev && dev->buffer)
467 opae_free(dev->buffer);