From 159b6f0e119962ce5da645f548cefe9196c8778e Mon Sep 17 00:00:00 2001 From: Olaf Baehring Date: Wed, 21 May 2025 08:03:40 -0300 Subject: caam: Fix CAAM error on startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Fabio Estevam --- drivers/crypto/fsl/jr.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers/crypto/fsl/jr.c') diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index 8f7a821ebf3..1d95d2bff27 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -217,13 +217,6 @@ static int jr_enqueue(uint32_t *desc_addr, 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 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) #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 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) 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 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) } /* 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 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) */ 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 @@ static int jr_sw_cleanup(uint8_t sec_idx, struct caam_regs *caam) 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)); -- cgit v1.2.3