caam: Fix CAAM error on startup
In rare cases U-Boot returns an error message when intantiating the RNG
of the CAAM device:
“SEC0: RNG4 SH0 instantiation failed with error 0xffffffff”
This means, that even when the CAAM device reports a finished
descriptor, none is found in the output ring.
This might be caused by a missing cache invalidation before
reading the memory of the output ring
This patch moves the cache invalidation of the output ring from start of
the job to immediately after the notification from hardware where the
output ring will be read.
Signed-off-by: Olaf Baehring <olaf.baehring@draeger.com>
Signed-off-by: Fabio Estevam <festevam@gmail.com>
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index 8f7a821..1d95d2b 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -217,13 +217,6 @@
jr->head = (head + 1) & (jr->size - 1);
- /* Invalidate output ring */
- start = (unsigned long)jr->output_ring &
- ~(ARCH_DMA_MINALIGN - 1);
- end = ALIGN((unsigned long)jr->output_ring + jr->op_size,
- ARCH_DMA_MINALIGN);
- invalidate_dcache_range(start, end);
-
sec_out32(®s->irja, 1);
return 0;
@@ -243,6 +236,7 @@
#else
uint32_t *addr;
#endif
+ unsigned long start, end;
while (sec_in32(®s->orsf) && CIRC_CNT(jr->head, jr->tail,
jr->size)) {
@@ -250,6 +244,11 @@
found = 0;
caam_dma_addr_t op_desc;
+
+ /* Invalidate output ring */
+ start = (unsigned long)jr->output_ring & ~(ARCH_DMA_MINALIGN - 1);
+ end = ALIGN((unsigned long)jr->output_ring + jr->op_size, ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(start, end);
#ifdef CONFIG_CAAM_64BIT
/* Read the 64 bit Descriptor address from Output Ring.
* The 32 bit hign and low part of the address will
@@ -283,8 +282,13 @@
}
/* Error condition if match not found */
- if (!found)
+ if (!found) {
+ int slots_full = sec_in32(®s->orsf);
+
+ jr->tail = (jr->tail + slots_full) & (jr->size - 1);
+ sec_out32(®s->orjr, slots_full);
return -1;
+ }
jr->info[idx].op_done = 1;
callback = (void *)jr->info[idx].callback;
@@ -296,14 +300,14 @@
*/
if (idx == tail)
do {
+ jr->info[tail].op_done = 0;
tail = (tail + 1) & (jr->size - 1);
} while (jr->info[tail].op_done);
jr->tail = tail;
- jr->read_idx = (jr->read_idx + 1) & (jr->size - 1);
+
sec_out32(®s->orjr, 1);
- jr->info[idx].op_done = 0;
callback(status, arg);
}
@@ -378,7 +382,6 @@
jr->head = 0;
jr->tail = 0;
- jr->read_idx = 0;
jr->write_idx = 0;
memset(jr->info, 0, sizeof(jr->info));
memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t));