mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-14 19:26:58 +02:00
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>
This commit is contained in:
parent
b7b301c906
commit
159b6f0e11
@ -217,13 +217,6 @@ static int jr_enqueue(uint32_t *desc_addr,
|
|||||||
|
|
||||||
jr->head = (head + 1) & (jr->size - 1);
|
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);
|
sec_out32(®s->irja, 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -243,6 +236,7 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
|
|||||||
#else
|
#else
|
||||||
uint32_t *addr;
|
uint32_t *addr;
|
||||||
#endif
|
#endif
|
||||||
|
unsigned long start, end;
|
||||||
|
|
||||||
while (sec_in32(®s->orsf) && CIRC_CNT(jr->head, jr->tail,
|
while (sec_in32(®s->orsf) && CIRC_CNT(jr->head, jr->tail,
|
||||||
jr->size)) {
|
jr->size)) {
|
||||||
@ -250,6 +244,11 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
|
|||||||
found = 0;
|
found = 0;
|
||||||
|
|
||||||
caam_dma_addr_t op_desc;
|
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
|
#ifdef CONFIG_CAAM_64BIT
|
||||||
/* Read the 64 bit Descriptor address from Output Ring.
|
/* Read the 64 bit Descriptor address from Output Ring.
|
||||||
* The 32 bit hign and low part of the address will
|
* 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 */
|
/* 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;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
jr->info[idx].op_done = 1;
|
jr->info[idx].op_done = 1;
|
||||||
callback = (void *)jr->info[idx].callback;
|
callback = (void *)jr->info[idx].callback;
|
||||||
@ -296,14 +300,14 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
|
|||||||
*/
|
*/
|
||||||
if (idx == tail)
|
if (idx == tail)
|
||||||
do {
|
do {
|
||||||
|
jr->info[tail].op_done = 0;
|
||||||
tail = (tail + 1) & (jr->size - 1);
|
tail = (tail + 1) & (jr->size - 1);
|
||||||
} while (jr->info[tail].op_done);
|
} while (jr->info[tail].op_done);
|
||||||
|
|
||||||
jr->tail = tail;
|
jr->tail = tail;
|
||||||
jr->read_idx = (jr->read_idx + 1) & (jr->size - 1);
|
|
||||||
|
|
||||||
sec_out32(®s->orjr, 1);
|
sec_out32(®s->orjr, 1);
|
||||||
jr->info[idx].op_done = 0;
|
|
||||||
|
|
||||||
callback(status, arg);
|
callback(status, arg);
|
||||||
}
|
}
|
||||||
@ -378,7 +382,6 @@ static int jr_sw_cleanup(uint8_t sec_idx, struct caam_regs *caam)
|
|||||||
|
|
||||||
jr->head = 0;
|
jr->head = 0;
|
||||||
jr->tail = 0;
|
jr->tail = 0;
|
||||||
jr->read_idx = 0;
|
|
||||||
jr->write_idx = 0;
|
jr->write_idx = 0;
|
||||||
memset(jr->info, 0, sizeof(jr->info));
|
memset(jr->info, 0, sizeof(jr->info));
|
||||||
memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t));
|
memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t));
|
||||||
|
@ -83,10 +83,6 @@ struct jobring {
|
|||||||
* in-order job completion
|
* in-order job completion
|
||||||
*/
|
*/
|
||||||
int tail;
|
int tail;
|
||||||
/* Read index of the output ring. It may not match with tail in case
|
|
||||||
* of out of order completetion
|
|
||||||
*/
|
|
||||||
int read_idx;
|
|
||||||
/* Write index to input ring. Would be always equal to head */
|
/* Write index to input ring. Would be always equal to head */
|
||||||
int write_idx;
|
int write_idx;
|
||||||
/* Size of the rings. */
|
/* Size of the rings. */
|
||||||
|
Loading…
Reference in New Issue
Block a user