summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Rawling <mwr@google.com>2021-10-04 13:10:48 -0700
committerAndrew Evans <andrewevans@google.com>2022-04-19 10:16:03 -0700
commit01cfc37c8acbba6eb05accef0fa6bbb73616b674 (patch)
treefdbc30553cef1a84edc4d4b9aa2070f76353a04c
parent8cd026832d2f4d8f4f94a5e2772f2b01cce57bd5 (diff)
downloadnanohub-01cfc37c8acbba6eb05accef0fa6bbb73616b674.tar.gz
DMA support for Nanohub
- ensures burst mode operation for fast, continuous clock - adjusts the timeout padding to maintain similar timing to the MCU - relies on the new exponential back-off flow control for overall reliability DMA is critically dependent on burst mode operation, and is essentially unusable without it. Burst mode ensures a solid clock that doesn't stutter under system load or governor control. DMA has advantages and disadvantages: - continuous clock in burst mode versus 64 bytes on/64 bytes off in non-dma mode - less cpu load and interrupt driven without the spinlocks used in non-DMA mode - slower transaction setup and hold times which limits performance, we will improve this further - non-burst mode degrades markedly with mif qos so we won't be using it The timing is set to approximate the current transaciton timing. It will be tuned and customized for optimal timing with DMA in follow up CLs. See go/rh-nanohub-mcu-architecture Test: manual, with induced retries and continuous stress tests Bug: 185406845 Bug: 169772504 Bug: 200616501 Change-Id: I7f90f250f9c902ee473606ee2ec2383b409ec874
-rw-r--r--spi.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/spi.c b/spi.c
index c47f9ea..4ca10c2 100644
--- a/spi.c
+++ b/spi.c
@@ -25,6 +25,9 @@
#define SPI_TIMEOUT 65535
#define SPI_MIN_DMA 48
#define SPI_MAX_SPEED_HZ 10000000
+#define SPI_BITS_PER_WORD 8
+#define DMA_BURST_WIDTH 4
+#define DMA_PAD 3
struct nanohub_spi_data {
struct nanohub_data data;
@@ -246,6 +249,7 @@ int nanohub_spi_write(void *data, uint8_t *tx, int length, int timeout)
.rx_buf = comms->rx_buffer,
.cs_change = 1,
};
+ xfer.len = (xfer.len + DMA_PAD) & ~DMA_PAD;
spi_data->rx_offset = max_len;
spi_data->rx_length = max_len + timeout;
memcpy(comms->tx_buffer, tx, length);
@@ -315,6 +319,7 @@ int nanohub_spi_read(void *data, uint8_t *rx, int max_length, int timeout)
}
}
+ xfer.len = (xfer.len + DMA_PAD) & ~DMA_PAD;
if (xfer.len != 1 && xfer.len < SPI_MIN_DMA)
xfer.len = SPI_MIN_DMA;
memset(comms->tx_buffer, 0xFF, xfer.len);
@@ -380,7 +385,7 @@ static int nanohub_spi_open(void *data)
spi_bus_lock(spi_data->device->master);
spi_data->device->max_speed_hz = spi_data->data.max_speed_hz;
spi_data->device->mode = SPI_MODE_0;
- spi_data->device->bits_per_word = 8;
+ spi_data->device->bits_per_word = SPI_BITS_PER_WORD;
ret = spi_setup(spi_data->device);
if (!ret) {
udelay(40);
@@ -407,7 +412,7 @@ void nanohub_spi_comms_init(struct nanohub_spi_data *spi_data)
sizeof(struct nanohub_packet_crc);
comms->seq = 1;
- comms->timeout_write = 544;
+ comms->timeout_write = 760;
comms->timeout_ack = 272;
comms->timeout_reply = 512;
comms->open = nanohub_spi_open;
@@ -418,6 +423,7 @@ void nanohub_spi_comms_init(struct nanohub_spi_data *spi_data)
max_len += comms->timeout_write;
max_len = max(max_len, comms->timeout_ack);
max_len = max(max_len, comms->timeout_reply);
+ max_len = (max_len + DMA_PAD) & ~DMA_PAD;
comms->tx_buffer = kmalloc(max_len, GFP_KERNEL | GFP_DMA);
comms->rx_buffer = kmalloc(max_len, GFP_KERNEL | GFP_DMA);