Skip to content

Commit 2cd6f00

Browse files
committed
[ot] hw/opentitan: ot_dma: add a property to define the DMA transfer block size
The property expects a value between 8 (256 bytes) and 20 (1MiB). The higher the value, the faster the DMA transfer, the higher the latency to handle other device requests using the I/O thread. Signed-off-by: Emmanuel Blot <[email protected]> (cherry picked from commit da26c59)
1 parent ae66b6e commit 2cd6f00

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

hw/opentitan/ot_dma.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,15 @@ struct OtDMAState {
256256
OtDMAOp op;
257257
OtDMASHA sha;
258258
uint32_t *regs;
259+
unsigned tb_size; /* DMA transfer block size */
259260
OtDMAControl control; /* captured regs on initial IDLE-GO transition */
260261
bool abort;
261262

262263
char *ot_id;
263264
char *ot_as_name; /* private AS unique name */
264265
char *ctn_as_name; /* externel port AS unique name */
265266
char *sys_as_name; /* external system AS unique name */
267+
uint8_t block_size_lg2; /* log2 of DMA transfer block size */
266268
#ifdef OT_DMA_HAS_ROLE
267269
uint8_t role;
268270
#endif
@@ -288,8 +290,8 @@ struct OtDMAState {
288290
#define DMA_ERROR(_err_) (1u << (_err_))
289291

290292
/* the following values are arbitrary end may be changed if needed */
291-
#define DMA_PACE_NS 10000u /* 10us: slow down DMA, handle aborts */
292-
#define DMA_TRANSFER_BLOCK_SIZE 4096u /* size of a single DMA block */
293+
#define DMA_PACE_NS 10000u /* 10us: slow down DMA, handle aborts */
294+
#define DMA_TRANSFER_BLOCK_LG2 12u /* log2(size) of a single DMA block */
293295

294296
#define REG_NAME_ENTRY(_reg_) [R_##_reg_] = stringify(_reg_)
295297
static const char *REG_NAMES[REGS_COUNT] = {
@@ -1037,7 +1039,7 @@ static void ot_dma_transfer(void *opaque)
10371039

10381040
smp_mb();
10391041

1040-
hwaddr size = MIN(op->size, DMA_TRANSFER_BLOCK_SIZE);
1042+
hwaddr size = MIN(op->size, s->tb_size);
10411043

10421044
CHANGE_STATE(s, SEND_WRITE);
10431045

@@ -1313,6 +1315,8 @@ static Property ot_dma_properties[] = {
13131315
DEFINE_PROP_STRING("ot_as_name", OtDMAState, ot_as_name),
13141316
DEFINE_PROP_STRING("ctn_as_name", OtDMAState, ctn_as_name),
13151317
DEFINE_PROP_STRING("sys_as_name", OtDMAState, sys_as_name),
1318+
DEFINE_PROP_UINT8("block_size_lg2", OtDMAState, block_size_lg2,
1319+
DMA_TRANSFER_BLOCK_LG2),
13161320
#ifdef OT_DMA_HAS_ROLE
13171321
DEFINE_PROP_UINT8("role", OtDMAState, role, UINT8_MAX),
13181322
#endif
@@ -1376,6 +1380,20 @@ static void ot_dma_reset(DeviceState *dev)
13761380
}
13771381
}
13781382

1383+
static void ot_dma_realize(DeviceState *dev, Error **errp)
1384+
{
1385+
OtDMAState *s = OT_DMA(dev);
1386+
(void)errp;
1387+
1388+
if (s->block_size_lg2 < 8u || s->block_size_lg2 > 20u) {
1389+
error_setg(&error_fatal, "%s: invalid DMA transfer block size: %u",
1390+
__func__, 1u << s->block_size_lg2);
1391+
return;
1392+
}
1393+
1394+
s->tb_size = 1u << s->block_size_lg2;
1395+
}
1396+
13791397
static void ot_dma_init(Object *obj)
13801398
{
13811399
OtDMAState *s = OT_DMA(obj);
@@ -1401,6 +1419,7 @@ static void ot_dma_class_init(ObjectClass *klass, void *data)
14011419
DeviceClass *dc = DEVICE_CLASS(klass);
14021420
(void)data;
14031421

1422+
dc->realize = &ot_dma_realize;
14041423
dc->reset = &ot_dma_reset;
14051424
device_class_set_props(dc, ot_dma_properties);
14061425
set_bit(DEVICE_CATEGORY_MISC, dc->categories);

0 commit comments

Comments
 (0)