File indexing completed on 2025-05-11 08:22:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <stdio.h>
0038 #include <bsp/alt_dma.h>
0039 #include <bsp/socal/socal.h>
0040 #include <bsp/socal/hps.h>
0041 #include <bsp/socal/alt_rstmgr.h>
0042 #include <bsp/socal/alt_sysmgr.h>
0043
0044 #if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
0045 #include <bsp/alt_16550_uart.h>
0046 #include <bsp/socal/alt_uart.h>
0047 #endif
0048
0049 #if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
0050 #include <bsp/socal/alt_qspi.h>
0051 #endif
0052
0053
0054
0055 #ifndef MIN
0056 #define MIN(a, b) ((a) > (b) ? (b) : (a))
0057 #endif
0058
0059 #ifndef ARRAY_COUNT
0060 #define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
0061 #endif
0062
0063
0064
0065 #define dprintf(...)
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 #define ALT_DMA_DSR_OFST 0x0
0082 #define ALT_DMA_DSR_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DSR_OFST))
0083 #define ALT_DMA_DSR_DMASTATUS_SET_MSK 0x0000000f
0084 #define ALT_DMA_DSR_DMASTATUS_GET(value) ((value) & 0x0000000f)
0085
0086
0087 #define ALT_DMA_DPC_OFST 0x4
0088 #define ALT_DMA_DPC_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DPC_OFST))
0089
0090
0091 #define ALT_DMA_INTEN_OFST 0x20
0092 #define ALT_DMA_INTEN_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INTEN_OFST))
0093
0094
0095 #define ALT_DMA_INT_EVENT_RIS_OFST 0x24
0096 #define ALT_DMA_INT_EVENT_RIS_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INT_EVENT_RIS_OFST))
0097
0098
0099 #define ALT_DMA_INTMIS_OFST 0x28
0100 #define ALT_DMA_INTMIS_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INTMIS_OFST))
0101
0102
0103 #define ALT_DMA_INTCLR_OFST 0x2c
0104 #define ALT_DMA_INTCLR_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_INTCLR_OFST))
0105
0106
0107 #define ALT_DMA_FSRD_OFST 0x30
0108 #define ALT_DMA_FSRD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FSRD_OFST))
0109
0110
0111 #define ALT_DMA_FSRC_OFST 0x34
0112 #define ALT_DMA_FSRC_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FSRC_OFST))
0113
0114
0115 #define ALT_DMA_FTRD_OFST 0x38
0116 #define ALT_DMA_FTRD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FSRD_OFST))
0117
0118
0119 #define ALT_DMA_FTRx_OFST(channel) (0x40 + 0x4 * (channel))
0120 #define ALT_DMA_FTRx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_FTRx_OFST(channel)))
0121
0122
0123 #define ALT_DMA_CSRx_OFST(channel) (0x100 + 0x8 * (channel))
0124 #define ALT_DMA_CSRx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CSRx_OFST(channel)))
0125 #define ALT_DMA_CSRx_CHANNELSTATUS_SET_MSK 0x0000000f
0126 #define ALT_DMA_CSRx_CHANNELSTATUS_GET(value) ((value) & 0x0000000f)
0127
0128
0129 #define ALT_DMA_CPCx_OFST(channel) (0x104 + 0x8 * (channel))
0130 #define ALT_DMA_CPCx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CPCx_OFST(channel)))
0131
0132
0133 #define ALT_DMA_SARx_OFST(channel) (0x400 + 0x20 * (channel))
0134 #define ALT_DMA_SARx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_SARx_OFST(channel)))
0135
0136
0137 #define ALT_DMA_DARx_OFST(channel) (0x404 + 0x20 * (channel))
0138 #define ALT_DMA_DARx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DARx_OFST(channel)))
0139
0140
0141 #define ALT_DMA_CCRx_OFST(channel) (0x408 + 0x20 * (channel))
0142 #define ALT_DMA_CCRx_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CCRx_OFST(channel)))
0143
0144
0145 #define ALT_DMA_LC0_x_OFST(channel) (0x40c + 0x20 * (channel))
0146 #define ALT_DMA_LC0_x_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_LC0_x_OFST(channel)))
0147
0148
0149 #define ALT_DMA_LC1_x_OFST(channel) (0x410 + 0x20 * (channel))
0150 #define ALT_DMA_LC1_x_ADDR(base, channel) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_LC1_x_OFST(channel)))
0151
0152
0153 #define ALT_DMA_DBGSTATUS_OFST 0xd00
0154 #define ALT_DMA_DBGSTATUS_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGSTATUS_OFST))
0155
0156
0157 #define ALT_DMA_DBGCMD_OFST 0xd04
0158 #define ALT_DMA_DBGCMD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGCMD_OFST))
0159
0160
0161 #define ALT_DMA_DBGINST0_OFST 0xd08
0162 #define ALT_DMA_DBGINST0_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGINST0_OFST))
0163 #define ALT_DMA_DBGINST0_CHANNELNUMBER_SET(value) (((value) & 0x7) << 8)
0164 #define ALT_DMA_DBGINST0_DEBUGTHREAD_SET(value) ((value) & 0x1)
0165 #define ALT_DMA_DBGINST0_DEBUGTHREAD_E_MANAGER 0
0166 #define ALT_DMA_DBGINST0_DEBUGTHREAD_E_CHANNEL 1
0167 #define ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(value) (((value) & 0xff) << 16)
0168 #define ALT_DMA_DBGINST0_INSTRUCTIONBYTE1_SET(value) (((value) & 0xff) << 24)
0169
0170
0171 #define ALT_DMA_DBGINST1_OFST 0xd0c
0172 #define ALT_DMA_DBGINST1_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_DBGINST1_OFST))
0173
0174
0175 #define ALT_DMA_CR0_OFST 0xe00
0176 #define ALT_DMA_CR1_OFST 0xe04
0177 #define ALT_DMA_CR2_OFST 0xe08
0178 #define ALT_DMA_CR3_OFST 0xe0c
0179 #define ALT_DMA_CR4_OFST 0xe10
0180 #define ALT_DMA_CR0_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR0_OFST))
0181 #define ALT_DMA_CR1_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR1_OFST))
0182 #define ALT_DMA_CR2_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR2_OFST))
0183 #define ALT_DMA_CR3_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR3_OFST))
0184 #define ALT_DMA_CR4_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CR4_OFST))
0185
0186
0187 #define ALT_DMA_CRD_OFST 0xe14
0188 #define ALT_DMA_CRD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_CRD_OFST))
0189
0190
0191 #define ALT_DMA_WD_OFST 0xe80
0192 #define ALT_DMA_WD_ADDR(base) ALT_CAST(void *, (ALT_CAST(char *, (base)) + ALT_DMA_WD_OFST))
0193
0194
0195
0196
0197
0198
0199
0200
0201 #define ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED (1 << 0)
0202
0203 typedef struct ALT_DMA_CHANNEL_INFO_s
0204 {
0205 uint8_t flag;
0206 }
0207 ALT_DMA_CHANNEL_INFO_t;
0208
0209 static ALT_DMA_CHANNEL_INFO_t channel_info_array[8];
0210
0211
0212
0213 ALT_STATUS_CODE alt_dma_init(const ALT_DMA_CFG_t * dma_cfg)
0214 {
0215
0216 for (int i = 0; i < 8; ++i)
0217 {
0218 channel_info_array[i].flag = 0;
0219 }
0220
0221
0222
0223 uint32_t dmactrl = 0;
0224
0225
0226 for (int i = 0; i < 4; ++i)
0227 {
0228
0229 switch (dma_cfg->periph_mux[i])
0230 {
0231 case ALT_DMA_PERIPH_MUX_DEFAULT:
0232 case ALT_DMA_PERIPH_MUX_FPGA:
0233 break;
0234 case ALT_DMA_PERIPH_MUX_CAN:
0235 dmactrl |= (ALT_SYSMGR_DMA_CTL_CHANSEL_0_SET_MSK << i);
0236 break;
0237 default:
0238 return ALT_E_ERROR;
0239 }
0240 }
0241
0242
0243
0244 switch (dma_cfg->manager_sec)
0245 {
0246 case ALT_DMA_SECURITY_DEFAULT:
0247 case ALT_DMA_SECURITY_SECURE:
0248 break;
0249 case ALT_DMA_SECURITY_NONSECURE:
0250 dmactrl |= ALT_SYSMGR_DMA_CTL_MGRNONSECURE_SET_MSK;
0251 break;
0252 default:
0253 return ALT_E_ERROR;
0254 }
0255
0256
0257 for (int i = 0; i < ALT_SYSMGR_DMA_CTL_IRQNONSECURE_WIDTH; ++i)
0258 {
0259
0260 switch (dma_cfg->irq_sec[i])
0261 {
0262 case ALT_DMA_SECURITY_DEFAULT:
0263 case ALT_DMA_SECURITY_SECURE:
0264 break;
0265 case ALT_DMA_SECURITY_NONSECURE:
0266 dmactrl |= (1 << (i + ALT_SYSMGR_DMA_CTL_IRQNONSECURE_LSB));
0267 break;
0268 default:
0269 return ALT_E_ERROR;
0270 }
0271 }
0272
0273 alt_write_word(ALT_SYSMGR_DMA_CTL_ADDR, dmactrl);
0274
0275
0276
0277 uint32_t dmapersecurity = 0;
0278
0279 for (int i = 0; i < 32; ++i)
0280 {
0281
0282 switch (dma_cfg->periph_sec[i])
0283 {
0284 case ALT_DMA_SECURITY_DEFAULT:
0285 case ALT_DMA_SECURITY_SECURE:
0286 break;
0287 case ALT_DMA_SECURITY_NONSECURE:
0288 dmapersecurity |= (1 << i);
0289 break;
0290 default:
0291 return ALT_E_ERROR;
0292 }
0293 }
0294
0295 alt_write_word(ALT_SYSMGR_DMA_PERSECURITY_ADDR, dmapersecurity);
0296
0297
0298
0299 alt_clrbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_DMA_SET_MSK);
0300
0301 return ALT_E_SUCCESS;
0302 }
0303
0304 ALT_STATUS_CODE alt_dma_uninit(void)
0305 {
0306
0307 for (int i = 0; i < 8; ++i)
0308 {
0309 if (channel_info_array[i].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED)
0310 {
0311 alt_dma_channel_kill((ALT_DMA_CHANNEL_t)i);
0312 alt_dma_channel_free((ALT_DMA_CHANNEL_t)i);
0313 }
0314 }
0315
0316
0317
0318 alt_setbits_word(ALT_RSTMGR_PERMODRST_ADDR, ALT_RSTMGR_PERMODRST_DMA_SET_MSK);
0319
0320 return ALT_E_SUCCESS;
0321 }
0322
0323 ALT_STATUS_CODE alt_dma_channel_alloc(ALT_DMA_CHANNEL_t channel)
0324 {
0325
0326 switch (channel)
0327 {
0328 case ALT_DMA_CHANNEL_0:
0329 case ALT_DMA_CHANNEL_1:
0330 case ALT_DMA_CHANNEL_2:
0331 case ALT_DMA_CHANNEL_3:
0332 case ALT_DMA_CHANNEL_4:
0333 case ALT_DMA_CHANNEL_5:
0334 case ALT_DMA_CHANNEL_6:
0335 case ALT_DMA_CHANNEL_7:
0336 break;
0337 default:
0338 return ALT_E_BAD_ARG;
0339 }
0340
0341
0342
0343 if (channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED)
0344 {
0345 return ALT_E_ERROR;
0346 }
0347
0348
0349
0350 channel_info_array[channel].flag |= ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED;
0351
0352 return ALT_E_SUCCESS;
0353 }
0354
0355 ALT_STATUS_CODE alt_dma_channel_alloc_any(ALT_DMA_CHANNEL_t * allocated)
0356 {
0357
0358
0359 for (int i = 0; i < 8; ++i)
0360 {
0361 if (!(channel_info_array[i].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
0362 {
0363
0364
0365 ALT_STATUS_CODE status = alt_dma_channel_alloc((ALT_DMA_CHANNEL_t)i);
0366 if (status == ALT_E_SUCCESS)
0367 {
0368 *allocated = (ALT_DMA_CHANNEL_t)i;
0369 }
0370 return status;
0371 }
0372 }
0373
0374
0375
0376 return ALT_E_ERROR;
0377 }
0378
0379 ALT_STATUS_CODE alt_dma_channel_free(ALT_DMA_CHANNEL_t channel)
0380 {
0381
0382 switch (channel)
0383 {
0384 case ALT_DMA_CHANNEL_0:
0385 case ALT_DMA_CHANNEL_1:
0386 case ALT_DMA_CHANNEL_2:
0387 case ALT_DMA_CHANNEL_3:
0388 case ALT_DMA_CHANNEL_4:
0389 case ALT_DMA_CHANNEL_5:
0390 case ALT_DMA_CHANNEL_6:
0391 case ALT_DMA_CHANNEL_7:
0392 break;
0393 default:
0394 return ALT_E_BAD_ARG;
0395 }
0396
0397
0398
0399 if (!(channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
0400 {
0401 return ALT_E_ERROR;
0402 }
0403
0404
0405
0406 ALT_DMA_CHANNEL_STATE_t state;
0407 ALT_STATUS_CODE status = alt_dma_channel_state_get(channel, &state);
0408 if (status != ALT_E_SUCCESS)
0409 {
0410 return status;
0411 }
0412 if (state != ALT_DMA_CHANNEL_STATE_STOPPED)
0413 {
0414 return ALT_E_ERROR;
0415 }
0416
0417
0418
0419 channel_info_array[channel].flag &= ~ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED;
0420
0421 return ALT_E_SUCCESS;
0422 }
0423
0424 ALT_STATUS_CODE alt_dma_channel_exec(ALT_DMA_CHANNEL_t channel, ALT_DMA_PROGRAM_t * pgm)
0425 {
0426
0427 switch (channel)
0428 {
0429 case ALT_DMA_CHANNEL_0:
0430 case ALT_DMA_CHANNEL_1:
0431 case ALT_DMA_CHANNEL_2:
0432 case ALT_DMA_CHANNEL_3:
0433 case ALT_DMA_CHANNEL_4:
0434 case ALT_DMA_CHANNEL_5:
0435 case ALT_DMA_CHANNEL_6:
0436 case ALT_DMA_CHANNEL_7:
0437 break;
0438 default:
0439 return ALT_E_BAD_ARG;
0440 }
0441
0442
0443
0444 if (!(channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
0445 {
0446 return ALT_E_ERROR;
0447 }
0448
0449
0450
0451 ALT_DMA_CHANNEL_STATE_t state;
0452 ALT_STATUS_CODE status = alt_dma_channel_state_get(channel, &state);
0453 if (status != ALT_E_SUCCESS)
0454 {
0455 return status;
0456 }
0457 if (state != ALT_DMA_CHANNEL_STATE_STOPPED)
0458 {
0459 return ALT_E_ERROR;
0460 }
0461
0462
0463
0464 if (alt_dma_program_validate(pgm) != ALT_E_SUCCESS)
0465 {
0466 return ALT_E_ERROR;
0467 }
0468
0469
0470
0471
0472
0473
0474
0475 uint32_t start = (uint32_t) &pgm->program[pgm->buffer_start];
0476
0477 dprintf("DMA[exec]: pgm->program = %p.\n", pgm->program);
0478 dprintf("DMA[exec]: start = %p.\n", (void *)start);
0479
0480
0481
0482
0483
0484
0485
0486 alt_write_word(ALT_DMA_DBGINST0_ADDR(ALT_DMASECURE_ADDR),
0487 ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(0xa0) |
0488 ALT_DMA_DBGINST0_INSTRUCTIONBYTE1_SET(channel));
0489
0490 alt_write_word(ALT_DMA_DBGINST1_ADDR(ALT_DMASECURE_ADDR), start);
0491
0492
0493
0494
0495
0496 alt_write_word(ALT_DMA_DBGCMD_ADDR(ALT_DMASECURE_ADDR), 0);
0497
0498 return ALT_E_SUCCESS;
0499 }
0500
0501 ALT_STATUS_CODE alt_dma_channel_kill(ALT_DMA_CHANNEL_t channel)
0502 {
0503
0504 switch (channel)
0505 {
0506 case ALT_DMA_CHANNEL_0:
0507 case ALT_DMA_CHANNEL_1:
0508 case ALT_DMA_CHANNEL_2:
0509 case ALT_DMA_CHANNEL_3:
0510 case ALT_DMA_CHANNEL_4:
0511 case ALT_DMA_CHANNEL_5:
0512 case ALT_DMA_CHANNEL_6:
0513 case ALT_DMA_CHANNEL_7:
0514 break;
0515 default:
0516 return ALT_E_BAD_ARG;
0517 }
0518
0519
0520
0521 if (!(channel_info_array[channel].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED))
0522 {
0523 return ALT_E_ERROR;
0524 }
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537 alt_write_word(ALT_DMA_DBGINST0_ADDR(ALT_DMASECURE_ADDR),
0538 ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(0x1) |
0539 ALT_DMA_DBGINST0_CHANNELNUMBER_SET(channel) |
0540 ALT_DMA_DBGINST0_DEBUGTHREAD_SET(ALT_DMA_DBGINST0_DEBUGTHREAD_E_CHANNEL));
0541
0542
0543
0544
0545
0546 alt_write_word(ALT_DMA_DBGCMD_ADDR(ALT_DMASECURE_ADDR), 0);
0547
0548
0549
0550
0551
0552 ALT_STATUS_CODE status = ALT_E_SUCCESS;
0553 ALT_DMA_CHANNEL_STATE_t current;
0554 uint32_t i = 20000;
0555
0556 while (--i)
0557 {
0558 status = alt_dma_channel_state_get(channel, ¤t);
0559 if (status != ALT_E_SUCCESS)
0560 {
0561 break;
0562 }
0563 if ( (current == ALT_DMA_CHANNEL_STATE_KILLING)
0564 || (current == ALT_DMA_CHANNEL_STATE_STOPPED))
0565 {
0566 break;
0567 }
0568 }
0569
0570 if (i == 0)
0571 {
0572 status = ALT_E_TMO;
0573 }
0574
0575 return status;
0576 }
0577
0578 ALT_STATUS_CODE alt_dma_channel_reg_get(ALT_DMA_CHANNEL_t channel,
0579 ALT_DMA_PROGRAM_REG_t reg, uint32_t * val)
0580 {
0581
0582 switch (channel)
0583 {
0584 case ALT_DMA_CHANNEL_0:
0585 case ALT_DMA_CHANNEL_1:
0586 case ALT_DMA_CHANNEL_2:
0587 case ALT_DMA_CHANNEL_3:
0588 case ALT_DMA_CHANNEL_4:
0589 case ALT_DMA_CHANNEL_5:
0590 case ALT_DMA_CHANNEL_6:
0591 case ALT_DMA_CHANNEL_7:
0592 break;
0593 default:
0594 return ALT_E_BAD_ARG;
0595 }
0596
0597
0598
0599
0600
0601 switch (reg)
0602 {
0603 case ALT_DMA_PROGRAM_REG_SAR:
0604 *val = alt_read_word(ALT_DMA_SARx_ADDR(ALT_DMASECURE_ADDR, channel));
0605 break;
0606 case ALT_DMA_PROGRAM_REG_DAR:
0607 *val = alt_read_word(ALT_DMA_DARx_ADDR(ALT_DMASECURE_ADDR, channel));
0608 break;
0609 case ALT_DMA_PROGRAM_REG_CCR:
0610 *val = alt_read_word(ALT_DMA_CCRx_ADDR(ALT_DMASECURE_ADDR, channel));
0611 break;
0612 default:
0613 return ALT_E_BAD_ARG;
0614 }
0615
0616 return ALT_E_SUCCESS;
0617 }
0618
0619 ALT_STATUS_CODE alt_dma_send_event(ALT_DMA_EVENT_t evt_num)
0620 {
0621
0622
0623 switch (evt_num)
0624 {
0625 case ALT_DMA_EVENT_0:
0626 case ALT_DMA_EVENT_1:
0627 case ALT_DMA_EVENT_2:
0628 case ALT_DMA_EVENT_3:
0629 case ALT_DMA_EVENT_4:
0630 case ALT_DMA_EVENT_5:
0631 case ALT_DMA_EVENT_6:
0632 case ALT_DMA_EVENT_7:
0633 case ALT_DMA_EVENT_ABORT:
0634 break;
0635 default:
0636 return ALT_E_BAD_ARG;
0637 }
0638
0639
0640
0641
0642
0643
0644
0645
0646 alt_write_word(ALT_DMA_DBGINST0_ADDR(ALT_DMASECURE_ADDR),
0647 ALT_DMA_DBGINST0_INSTRUCTIONBYTE0_SET(0x34) |
0648 ALT_DMA_DBGINST0_INSTRUCTIONBYTE1_SET(evt_num << 3) |
0649 ALT_DMA_DBGINST0_DEBUGTHREAD_SET(ALT_DMA_DBGINST0_DEBUGTHREAD_E_MANAGER)
0650 );
0651
0652
0653
0654
0655
0656 alt_write_word(ALT_DMA_DBGCMD_ADDR(ALT_DMASECURE_ADDR), 0);
0657
0658 return ALT_E_SUCCESS;
0659 }
0660
0661 ALT_STATUS_CODE alt_dma_manager_state_get(ALT_DMA_MANAGER_STATE_t * state)
0662 {
0663
0664
0665 uint32_t raw_state = alt_read_word(ALT_DMA_DSR_ADDR(ALT_DMASECURE_ADDR));
0666
0667 *state = (ALT_DMA_MANAGER_STATE_t)ALT_DMA_DSR_DMASTATUS_GET(raw_state);
0668
0669 return ALT_E_SUCCESS;
0670 }
0671
0672 ALT_STATUS_CODE alt_dma_channel_state_get(ALT_DMA_CHANNEL_t channel,
0673 ALT_DMA_CHANNEL_STATE_t * state)
0674 {
0675
0676 switch (channel)
0677 {
0678 case ALT_DMA_CHANNEL_0:
0679 case ALT_DMA_CHANNEL_1:
0680 case ALT_DMA_CHANNEL_2:
0681 case ALT_DMA_CHANNEL_3:
0682 case ALT_DMA_CHANNEL_4:
0683 case ALT_DMA_CHANNEL_5:
0684 case ALT_DMA_CHANNEL_6:
0685 case ALT_DMA_CHANNEL_7:
0686 break;
0687 default:
0688 return ALT_E_BAD_ARG;
0689 }
0690
0691
0692
0693 uint32_t raw_state = alt_read_word(ALT_DMA_CSRx_ADDR(ALT_DMASECURE_ADDR, channel));
0694
0695 *state = (ALT_DMA_CHANNEL_STATE_t)ALT_DMA_CSRx_CHANNELSTATUS_GET(raw_state);
0696
0697 return ALT_E_SUCCESS;
0698 }
0699
0700 ALT_STATUS_CODE alt_dma_manager_fault_status_get(ALT_DMA_MANAGER_FAULT_t * fault)
0701 {
0702
0703
0704 *fault = (ALT_DMA_MANAGER_FAULT_t)alt_read_word(ALT_DMA_FTRD_ADDR(ALT_DMASECURE_ADDR));
0705
0706 return ALT_E_SUCCESS;
0707 }
0708
0709 ALT_STATUS_CODE alt_dma_channel_fault_status_get(ALT_DMA_CHANNEL_t channel,
0710 ALT_DMA_CHANNEL_FAULT_t * fault)
0711 {
0712
0713 switch (channel)
0714 {
0715 case ALT_DMA_CHANNEL_0:
0716 case ALT_DMA_CHANNEL_1:
0717 case ALT_DMA_CHANNEL_2:
0718 case ALT_DMA_CHANNEL_3:
0719 case ALT_DMA_CHANNEL_4:
0720 case ALT_DMA_CHANNEL_5:
0721 case ALT_DMA_CHANNEL_6:
0722 case ALT_DMA_CHANNEL_7:
0723 break;
0724 default:
0725 return ALT_E_BAD_ARG;
0726 }
0727
0728
0729
0730 *fault = (ALT_DMA_CHANNEL_FAULT_t)alt_read_word(ALT_DMA_FTRx_ADDR(ALT_DMASECURE_ADDR, channel));
0731
0732 return ALT_E_SUCCESS;
0733 }
0734
0735 ALT_STATUS_CODE alt_dma_event_int_select(ALT_DMA_EVENT_t evt_num,
0736 ALT_DMA_EVENT_SELECT_t opt)
0737 {
0738
0739 switch (evt_num)
0740 {
0741 case ALT_DMA_EVENT_0:
0742 case ALT_DMA_EVENT_1:
0743 case ALT_DMA_EVENT_2:
0744 case ALT_DMA_EVENT_3:
0745 case ALT_DMA_EVENT_4:
0746 case ALT_DMA_EVENT_5:
0747 case ALT_DMA_EVENT_6:
0748 case ALT_DMA_EVENT_7:
0749 case ALT_DMA_EVENT_ABORT:
0750 break;
0751 default:
0752 return ALT_E_BAD_ARG;
0753 }
0754
0755
0756
0757 switch (opt)
0758 {
0759 case ALT_DMA_EVENT_SELECT_SEND_EVT:
0760 alt_clrbits_word(ALT_DMA_INTEN_ADDR(ALT_DMASECURE_ADDR), 1 << evt_num);
0761 break;
0762 case ALT_DMA_EVENT_SELECT_SIG_IRQ:
0763 alt_setbits_word(ALT_DMA_INTEN_ADDR(ALT_DMASECURE_ADDR), 1 << evt_num);
0764 break;
0765 default:
0766 return ALT_E_BAD_ARG;
0767 }
0768
0769 return ALT_E_SUCCESS;
0770 }
0771
0772 ALT_STATUS_CODE alt_dma_event_int_status_get_raw(ALT_DMA_EVENT_t evt_num)
0773 {
0774
0775 switch (evt_num)
0776 {
0777 case ALT_DMA_EVENT_0:
0778 case ALT_DMA_EVENT_1:
0779 case ALT_DMA_EVENT_2:
0780 case ALT_DMA_EVENT_3:
0781 case ALT_DMA_EVENT_4:
0782 case ALT_DMA_EVENT_5:
0783 case ALT_DMA_EVENT_6:
0784 case ALT_DMA_EVENT_7:
0785 case ALT_DMA_EVENT_ABORT:
0786 break;
0787 default:
0788 return ALT_E_BAD_ARG;
0789 }
0790
0791
0792
0793 uint32_t status_raw = alt_read_word(ALT_DMA_INT_EVENT_RIS_ADDR(ALT_DMASECURE_ADDR));
0794
0795 if (status_raw & (1 << evt_num))
0796 {
0797 return ALT_E_TRUE;
0798 }
0799 else
0800 {
0801 return ALT_E_FALSE;
0802 }
0803 }
0804
0805 ALT_STATUS_CODE alt_dma_int_status_get(ALT_DMA_EVENT_t irq_num)
0806 {
0807
0808 switch (irq_num)
0809 {
0810 case ALT_DMA_EVENT_0:
0811 case ALT_DMA_EVENT_1:
0812 case ALT_DMA_EVENT_2:
0813 case ALT_DMA_EVENT_3:
0814 case ALT_DMA_EVENT_4:
0815 case ALT_DMA_EVENT_5:
0816 case ALT_DMA_EVENT_6:
0817 case ALT_DMA_EVENT_7:
0818 case ALT_DMA_EVENT_ABORT:
0819 break;
0820 default:
0821 return ALT_E_BAD_ARG;
0822 }
0823
0824
0825
0826 uint32_t int_status = alt_read_word(ALT_DMA_INTMIS_ADDR(ALT_DMASECURE_ADDR));
0827
0828 if (int_status & (1 << irq_num))
0829 {
0830 return ALT_E_TRUE;
0831 }
0832 else
0833 {
0834 return ALT_E_FALSE;
0835 }
0836 }
0837
0838 ALT_STATUS_CODE alt_dma_int_clear(ALT_DMA_EVENT_t irq_num)
0839 {
0840
0841 switch (irq_num)
0842 {
0843 case ALT_DMA_EVENT_0:
0844 case ALT_DMA_EVENT_1:
0845 case ALT_DMA_EVENT_2:
0846 case ALT_DMA_EVENT_3:
0847 case ALT_DMA_EVENT_4:
0848 case ALT_DMA_EVENT_5:
0849 case ALT_DMA_EVENT_6:
0850 case ALT_DMA_EVENT_7:
0851 case ALT_DMA_EVENT_ABORT:
0852 break;
0853 default:
0854 return ALT_E_BAD_ARG;
0855 }
0856
0857
0858
0859 alt_write_word(ALT_DMA_INTCLR_ADDR(ALT_DMASECURE_ADDR), 1 << irq_num);
0860
0861 return ALT_E_SUCCESS;
0862 }
0863
0864
0865
0866 ALT_STATUS_CODE alt_dma_memory_to_memory(ALT_DMA_CHANNEL_t channel,
0867 ALT_DMA_PROGRAM_t * program,
0868 void * dst,
0869 const void * src,
0870 size_t size,
0871 bool send_evt,
0872 ALT_DMA_EVENT_t evt)
0873 {
0874 ALT_STATUS_CODE status = ALT_E_SUCCESS;
0875
0876
0877 if ((size == 0) && (send_evt == false))
0878 {
0879 return status;
0880 }
0881
0882 if (status == ALT_E_SUCCESS)
0883 {
0884 status = alt_dma_program_init(program);
0885 }
0886
0887 if (size != 0)
0888 {
0889 uintptr_t udst = (uintptr_t)dst;
0890 uintptr_t usrc = (uintptr_t)src;
0891
0892 dprintf("DMA[M->M]: dst = %p.\n", dst);
0893 dprintf("DMA[M->M]: src = %p.\n", src);
0894 dprintf("DMA[M->M]: size = 0x%x.\n", size);
0895
0896
0897
0898 if (udst + size - 1 < udst)
0899 {
0900 return ALT_E_BAD_ARG;
0901 }
0902 if (usrc + size - 1 < usrc)
0903 {
0904 return ALT_E_BAD_ARG;
0905 }
0906
0907
0908
0909 if (udst > usrc)
0910 {
0911 if (usrc + size - 1 > udst)
0912 {
0913 return ALT_E_BAD_ARG;
0914 }
0915 }
0916 else
0917 {
0918 if (udst + size - 1 > usrc)
0919 {
0920 return ALT_E_BAD_ARG;
0921 }
0922 }
0923
0924 if (status == ALT_E_SUCCESS)
0925 {
0926 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, usrc);
0927 }
0928 if (status == ALT_E_SUCCESS)
0929 {
0930 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, udst);
0931 }
0932
0933 size_t sizeleft = size;
0934
0935
0936
0937
0938
0939
0940
0941 if (usrc & 0x7)
0942 {
0943 uint32_t aligncount = MIN(8 - (usrc & 0x7), sizeleft);
0944 sizeleft -= aligncount;
0945
0946 dprintf("DMA[M->M]: Total pre-alignment 1-byte burst size tranfer(s): %lu.\n", aligncount);
0947
0948
0949
0950
0951
0952
0953
0954
0955 if (status == ALT_E_SUCCESS)
0956 {
0957 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
0958 ( ((aligncount - 1) << 4)
0959 | ALT_DMA_CCR_OPT_SS8
0960 | ALT_DMA_CCR_OPT_SA_DEFAULT
0961 | ALT_DMA_CCR_OPT_SP_DEFAULT
0962 | ALT_DMA_CCR_OPT_SC_DEFAULT
0963 | ((aligncount - 1) << 18)
0964 | ALT_DMA_CCR_OPT_DS8
0965 | ALT_DMA_CCR_OPT_DA_DEFAULT
0966 | ALT_DMA_CCR_OPT_DP_DEFAULT
0967 | ALT_DMA_CCR_OPT_DC_DEFAULT
0968 | ALT_DMA_CCR_OPT_ES_DEFAULT
0969 )
0970 );
0971 }
0972 if (status == ALT_E_SUCCESS)
0973 {
0974 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
0975 }
0976 if (status == ALT_E_SUCCESS)
0977 {
0978 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
0979 }
0980 }
0981
0982
0983 uint32_t burstcount = sizeleft >> 3;
0984
0985 bool correction = (burstcount != 0);
0986
0987
0988 sizeleft &= 0x7;
0989
0990 dprintf("DMA[M->M]: Total Main 8-byte burst size transfer(s): %lu.\n", burstcount);
0991 dprintf("DMA[M->M]: Total Main 1-byte burst size transfer(s): %u.\n", sizeleft);
0992
0993
0994
0995 if (burstcount >> 4)
0996 {
0997 uint32_t length16burstcount = burstcount >> 4;
0998 burstcount &= 0xf;
0999
1000 dprintf("DMA[M->M]: Number of 16 burst length 8-byte transfer(s): %lu.\n", length16burstcount);
1001 dprintf("DMA[M->M]: Number of remaining 8-byte transfer(s): %lu.\n", burstcount);
1002
1003
1004
1005
1006
1007
1008
1009
1010 if (status == ALT_E_SUCCESS)
1011 {
1012 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1013 ( ALT_DMA_CCR_OPT_SB16
1014 | ALT_DMA_CCR_OPT_SS64
1015 | ALT_DMA_CCR_OPT_SA_DEFAULT
1016 | ALT_DMA_CCR_OPT_SP_DEFAULT
1017 | ALT_DMA_CCR_OPT_SC_DEFAULT
1018 | ALT_DMA_CCR_OPT_DB16
1019 | ALT_DMA_CCR_OPT_DS64
1020 | ALT_DMA_CCR_OPT_DA_DEFAULT
1021 | ALT_DMA_CCR_OPT_DP_DEFAULT
1022 | ALT_DMA_CCR_OPT_DC_DEFAULT
1023 | ALT_DMA_CCR_OPT_ES_DEFAULT
1024 )
1025 );
1026 }
1027
1028 while (length16burstcount > 0)
1029 {
1030 if (status != ALT_E_SUCCESS)
1031 {
1032 break;
1033 }
1034
1035 uint32_t loopcount = MIN(length16burstcount, 256);
1036 length16burstcount -= loopcount;
1037
1038 dprintf("DMA[M->M]: Looping %lux 16 burst length 8-byte transfer(s).\n", loopcount);
1039
1040 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1041 {
1042 status = alt_dma_program_DMALP(program, loopcount);
1043 }
1044 if (status == ALT_E_SUCCESS)
1045 {
1046 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1047 }
1048 if (status == ALT_E_SUCCESS)
1049 {
1050 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1051 }
1052 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1053 {
1054 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1055 }
1056 }
1057 }
1058
1059
1060
1061
1062
1063
1064 if (burstcount)
1065 {
1066
1067
1068
1069
1070
1071
1072
1073 if (status == ALT_E_SUCCESS)
1074 {
1075 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1076 ( ((burstcount - 1) << 4)
1077 | ALT_DMA_CCR_OPT_SS64
1078 | ALT_DMA_CCR_OPT_SA_DEFAULT
1079 | ALT_DMA_CCR_OPT_SP_DEFAULT
1080 | ALT_DMA_CCR_OPT_SC_DEFAULT
1081 | ((burstcount - 1) << 18)
1082 | ALT_DMA_CCR_OPT_DS64
1083 | ALT_DMA_CCR_OPT_DA_DEFAULT
1084 | ALT_DMA_CCR_OPT_DP_DEFAULT
1085 | ALT_DMA_CCR_OPT_DC_DEFAULT
1086 | ALT_DMA_CCR_OPT_ES_DEFAULT
1087 )
1088 );
1089 }
1090 if (status == ALT_E_SUCCESS)
1091 {
1092 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1093 }
1094 if (status == ALT_E_SUCCESS)
1095 {
1096 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1097 }
1098 }
1099
1100
1101
1102
1103 if ( (correction == true)
1104 && ((usrc & 0x7) != (udst & 0x7))
1105 )
1106 {
1107 if (status == ALT_E_SUCCESS)
1108 {
1109
1110
1111
1112
1113
1114
1115 uint32_t ccr;
1116
1117 if ((usrc & 0x3) == (udst & 0x3))
1118 {
1119 dprintf("DMA[M->M]: Single correction 4-byte burst size tranfer.\n");
1120
1121
1122
1123
1124
1125
1126
1127
1128 ccr = ( ALT_DMA_CCR_OPT_SB1
1129 | ALT_DMA_CCR_OPT_SS32
1130 | ALT_DMA_CCR_OPT_SA_DEFAULT
1131 | ALT_DMA_CCR_OPT_SP_DEFAULT
1132 | ALT_DMA_CCR_OPT_SC_DEFAULT
1133 | ALT_DMA_CCR_OPT_DB1
1134 | ALT_DMA_CCR_OPT_DS32
1135 | ALT_DMA_CCR_OPT_DA_DEFAULT
1136 | ALT_DMA_CCR_OPT_DP_DEFAULT
1137 | ALT_DMA_CCR_OPT_DC_DEFAULT
1138 | ALT_DMA_CCR_OPT_ES_DEFAULT
1139 );
1140 }
1141 else if ((usrc & 0x1) == (udst & 0x1))
1142 {
1143 dprintf("DMA[M->M]: Single correction 2-byte burst size tranfer.\n");
1144
1145
1146
1147
1148
1149
1150
1151
1152 ccr = ( ALT_DMA_CCR_OPT_SB1
1153 | ALT_DMA_CCR_OPT_SS16
1154 | ALT_DMA_CCR_OPT_SA_DEFAULT
1155 | ALT_DMA_CCR_OPT_SP_DEFAULT
1156 | ALT_DMA_CCR_OPT_SC_DEFAULT
1157 | ALT_DMA_CCR_OPT_DB1
1158 | ALT_DMA_CCR_OPT_DS16
1159 | ALT_DMA_CCR_OPT_DA_DEFAULT
1160 | ALT_DMA_CCR_OPT_DP_DEFAULT
1161 | ALT_DMA_CCR_OPT_DC_DEFAULT
1162 | ALT_DMA_CCR_OPT_ES_DEFAULT
1163 );
1164 }
1165 else
1166 {
1167 dprintf("DMA[M->M]: Single correction 1-byte burst size tranfer.\n");
1168
1169
1170
1171
1172
1173
1174
1175
1176 ccr = ( ALT_DMA_CCR_OPT_SB1
1177 | ALT_DMA_CCR_OPT_SS8
1178 | ALT_DMA_CCR_OPT_SA_DEFAULT
1179 | ALT_DMA_CCR_OPT_SP_DEFAULT
1180 | ALT_DMA_CCR_OPT_SC_DEFAULT
1181 | ALT_DMA_CCR_OPT_DB1
1182 | ALT_DMA_CCR_OPT_DS8
1183 | ALT_DMA_CCR_OPT_DA_DEFAULT
1184 | ALT_DMA_CCR_OPT_DP_DEFAULT
1185 | ALT_DMA_CCR_OPT_DC_DEFAULT
1186 | ALT_DMA_CCR_OPT_ES_DEFAULT
1187 );
1188 }
1189
1190 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1191 ccr);
1192 }
1193 if (status == ALT_E_SUCCESS)
1194 {
1195 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1196 }
1197 }
1198
1199
1200
1201 if (sizeleft)
1202 {
1203 dprintf("DMA[M->M]: Total post 1-byte burst size tranfer(s): %u.\n", sizeleft);
1204
1205
1206
1207
1208
1209
1210
1211
1212 if (status == ALT_E_SUCCESS)
1213 {
1214 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1215 ( ((sizeleft - 1) << 4)
1216 | ALT_DMA_CCR_OPT_SS8
1217 | ALT_DMA_CCR_OPT_SA_DEFAULT
1218 | ALT_DMA_CCR_OPT_SP_DEFAULT
1219 | ALT_DMA_CCR_OPT_SC_DEFAULT
1220 | ((sizeleft - 1) << 18)
1221 | ALT_DMA_CCR_OPT_DS8
1222 | ALT_DMA_CCR_OPT_DA_DEFAULT
1223 | ALT_DMA_CCR_OPT_DP_DEFAULT
1224 | ALT_DMA_CCR_OPT_DC_DEFAULT
1225 | ALT_DMA_CCR_OPT_ES_DEFAULT
1226 )
1227 );
1228 }
1229 if (status == ALT_E_SUCCESS)
1230 {
1231 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1232 }
1233 if (status == ALT_E_SUCCESS)
1234 {
1235 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1236 }
1237 }
1238 }
1239
1240
1241 if (send_evt)
1242 {
1243 if (status == ALT_E_SUCCESS)
1244 {
1245 dprintf("DMA[M->M]: Adding event ...\n");
1246 status = alt_dma_program_DMASEV(program, evt);
1247 }
1248 }
1249
1250
1251 if (status == ALT_E_SUCCESS)
1252 {
1253 status = alt_dma_program_DMAEND(program);
1254 }
1255
1256
1257 if (status != ALT_E_SUCCESS)
1258 {
1259
1260
1261 alt_dma_program_clear(program);
1262 return status;
1263 }
1264
1265
1266 return alt_dma_channel_exec(channel, program);
1267 }
1268
1269 ALT_STATUS_CODE alt_dma_zero_to_memory(ALT_DMA_CHANNEL_t channel,
1270 ALT_DMA_PROGRAM_t * program,
1271 void * buf,
1272 size_t size,
1273 bool send_evt,
1274 ALT_DMA_EVENT_t evt)
1275 {
1276 ALT_STATUS_CODE status = ALT_E_SUCCESS;
1277
1278
1279 if ((size == 0) && (send_evt == false))
1280 {
1281 return status;
1282 }
1283
1284 if (status == ALT_E_SUCCESS)
1285 {
1286 status = alt_dma_program_init(program);
1287 }
1288
1289 if (size != 0)
1290 {
1291 if (status == ALT_E_SUCCESS)
1292 {
1293 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)buf);
1294 }
1295
1296 dprintf("DMA[Z->M]: buf = %p.\n", buf);
1297 dprintf("DMA[Z->M]: size = 0x%x.\n", size);
1298
1299 size_t sizeleft = size;
1300
1301
1302 if ((uint32_t)buf & 0x7)
1303 {
1304 uint32_t aligncount = MIN(8 - ((uint32_t)buf & 0x7), sizeleft);
1305 sizeleft -= aligncount;
1306
1307 dprintf("DMA[Z->M]: Total pre-alignment 1-byte burst size tranfer(s): %lu.\n", aligncount);
1308
1309
1310
1311
1312
1313
1314 if (status == ALT_E_SUCCESS)
1315 {
1316 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1317 ( ALT_DMA_CCR_OPT_SB_DEFAULT
1318 | ALT_DMA_CCR_OPT_SS_DEFAULT
1319 | ALT_DMA_CCR_OPT_SA_DEFAULT
1320 | ALT_DMA_CCR_OPT_SP_DEFAULT
1321 | ALT_DMA_CCR_OPT_SC_DEFAULT
1322 | ((aligncount - 1) << 18)
1323 | ALT_DMA_CCR_OPT_DS8
1324 | ALT_DMA_CCR_OPT_DA_DEFAULT
1325 | ALT_DMA_CCR_OPT_DP_DEFAULT
1326 | ALT_DMA_CCR_OPT_DC_DEFAULT
1327 | ALT_DMA_CCR_OPT_ES_DEFAULT
1328 )
1329 );
1330 }
1331 if (status == ALT_E_SUCCESS)
1332 {
1333 status = alt_dma_program_DMASTZ(program);
1334 }
1335 }
1336
1337
1338 uint32_t burstcount = sizeleft >> 3;
1339
1340
1341 sizeleft &= 0x7;
1342
1343 dprintf("DMA[Z->M]: Total Main 8-byte burst size transfer(s): %lu.\n", burstcount);
1344 dprintf("DMA[Z->M]: Total Main 1-byte burst size transfer(s): %u.\n", sizeleft);
1345
1346
1347 if (burstcount >> 4)
1348 {
1349 uint32_t length16burstcount = burstcount >> 4;
1350 burstcount &= 0xf;
1351
1352 dprintf("DMA[Z->M]: Number of 16 burst length 8-byte transfer(s): %lu.\n", length16burstcount);
1353 dprintf("DMA[Z->M]: Number of remaining 8-byte transfer(s): %lu.\n", burstcount);
1354
1355
1356
1357
1358
1359
1360 if (status == ALT_E_SUCCESS)
1361 {
1362 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1363 ( ALT_DMA_CCR_OPT_SB_DEFAULT
1364 | ALT_DMA_CCR_OPT_SS_DEFAULT
1365 | ALT_DMA_CCR_OPT_SA_DEFAULT
1366 | ALT_DMA_CCR_OPT_SP_DEFAULT
1367 | ALT_DMA_CCR_OPT_SC_DEFAULT
1368 | ALT_DMA_CCR_OPT_DB16
1369 | ALT_DMA_CCR_OPT_DS64
1370 | ALT_DMA_CCR_OPT_DA_DEFAULT
1371 | ALT_DMA_CCR_OPT_DP_DEFAULT
1372 | ALT_DMA_CCR_OPT_DC_DEFAULT
1373 | ALT_DMA_CCR_OPT_ES_DEFAULT
1374 )
1375 );
1376 }
1377
1378 while (length16burstcount > 0)
1379 {
1380 if (status != ALT_E_SUCCESS)
1381 {
1382 break;
1383 }
1384
1385 uint32_t loopcount = MIN(length16burstcount, 256);
1386 length16burstcount -= loopcount;
1387
1388 dprintf("DMA[Z->M]: Looping %lux 16 burst length 8-byte transfer(s).\n", loopcount);
1389
1390 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1391 {
1392 status = alt_dma_program_DMALP(program, loopcount);
1393 }
1394 if (status == ALT_E_SUCCESS)
1395 {
1396 status = alt_dma_program_DMASTZ(program);
1397 }
1398 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1399 {
1400 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1401 }
1402 }
1403 }
1404
1405
1406
1407
1408
1409
1410 if (burstcount)
1411 {
1412
1413
1414
1415
1416
1417 if (status == ALT_E_SUCCESS)
1418 {
1419 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1420 ( ALT_DMA_CCR_OPT_SB_DEFAULT
1421 | ALT_DMA_CCR_OPT_SS_DEFAULT
1422 | ALT_DMA_CCR_OPT_SA_DEFAULT
1423 | ALT_DMA_CCR_OPT_SP_DEFAULT
1424 | ALT_DMA_CCR_OPT_SC_DEFAULT
1425 | ((burstcount - 1) << 18)
1426 | ALT_DMA_CCR_OPT_DS64
1427 | ALT_DMA_CCR_OPT_DA_DEFAULT
1428 | ALT_DMA_CCR_OPT_DP_DEFAULT
1429 | ALT_DMA_CCR_OPT_DC_DEFAULT
1430 | ALT_DMA_CCR_OPT_ES_DEFAULT
1431 )
1432 );
1433 }
1434 if (status == ALT_E_SUCCESS)
1435 {
1436 status = alt_dma_program_DMASTZ(program);
1437 }
1438 }
1439
1440
1441
1442 if (sizeleft)
1443 {
1444 dprintf("DMA[Z->M]: Total post 1-byte burst size tranfer(s): %u.\n", sizeleft);
1445
1446
1447
1448
1449
1450
1451 if (status == ALT_E_SUCCESS)
1452 {
1453 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1454 ( ALT_DMA_CCR_OPT_SB_DEFAULT
1455 | ALT_DMA_CCR_OPT_SS_DEFAULT
1456 | ALT_DMA_CCR_OPT_SA_DEFAULT
1457 | ALT_DMA_CCR_OPT_SP_DEFAULT
1458 | ALT_DMA_CCR_OPT_SC_DEFAULT
1459 | ((sizeleft - 1) << 18)
1460 | ALT_DMA_CCR_OPT_DS8
1461 | ALT_DMA_CCR_OPT_DA_DEFAULT
1462 | ALT_DMA_CCR_OPT_DP_DEFAULT
1463 | ALT_DMA_CCR_OPT_DC_DEFAULT
1464 | ALT_DMA_CCR_OPT_ES_DEFAULT
1465 )
1466 );
1467 }
1468 if (status == ALT_E_SUCCESS)
1469 {
1470 status = alt_dma_program_DMASTZ(program);
1471 }
1472 }
1473 }
1474
1475
1476 if (send_evt)
1477 {
1478 if (status == ALT_E_SUCCESS)
1479 {
1480 dprintf("DMA[Z->M]: Adding event ...\n");
1481 status = alt_dma_program_DMASEV(program, evt);
1482 }
1483 }
1484
1485
1486 if (status == ALT_E_SUCCESS)
1487 {
1488 status = alt_dma_program_DMAEND(program);
1489 }
1490
1491
1492 if (status != ALT_E_SUCCESS)
1493 {
1494
1495
1496 alt_dma_program_clear(program);
1497 return status;
1498 }
1499
1500
1501 return alt_dma_channel_exec(channel, program);
1502 }
1503
1504 ALT_STATUS_CODE alt_dma_memory_to_register(ALT_DMA_CHANNEL_t channel,
1505 ALT_DMA_PROGRAM_t * program,
1506 void * dst_reg,
1507 const void * src_buf,
1508 size_t count,
1509 uint32_t register_width_bits,
1510 bool send_evt,
1511 ALT_DMA_EVENT_t evt)
1512 {
1513 ALT_STATUS_CODE status = ALT_E_SUCCESS;
1514
1515
1516 if ((count == 0) && (send_evt == false))
1517 {
1518 return status;
1519 }
1520
1521 if (status == ALT_E_SUCCESS)
1522 {
1523 status = alt_dma_program_init(program);
1524 }
1525
1526 if (count != 0)
1527 {
1528
1529 uint32_t ccr_ss_ds_mask = 0;
1530
1531 if (status == ALT_E_SUCCESS)
1532 {
1533 switch (register_width_bits)
1534 {
1535 case 8:
1536
1537
1538
1539 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS8 | ALT_DMA_CCR_OPT_DS8;
1540 break;
1541 case 16:
1542
1543
1544
1545 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS16 | ALT_DMA_CCR_OPT_DS16;
1546 break;
1547 case 32:
1548
1549
1550
1551 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS32 | ALT_DMA_CCR_OPT_DS32;
1552 break;
1553 case 64:
1554
1555
1556
1557 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS64 | ALT_DMA_CCR_OPT_DS64;
1558 break;
1559 default:
1560 status = ALT_E_BAD_ARG;
1561 break;
1562 }
1563 }
1564
1565
1566 if (status == ALT_E_SUCCESS)
1567 {
1568 if (((uintptr_t)dst_reg & ((register_width_bits >> 3) - 1)) != 0)
1569 {
1570 status = ALT_E_BAD_ARG;
1571 }
1572 else if (((uintptr_t)src_buf & ((register_width_bits >> 3) - 1)) != 0)
1573 {
1574 status = ALT_E_BAD_ARG;
1575 }
1576 else
1577 {
1578 dprintf("DMA[M->R]: dst_reg = %p.\n", dst_reg);
1579 dprintf("DMA[M->R]: src_buf = %p.\n", src_buf);
1580 dprintf("DMA[M->R]: count = 0x%x.\n", count);
1581 }
1582 }
1583
1584 if (status == ALT_E_SUCCESS)
1585 {
1586 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, (uint32_t)src_buf);
1587 }
1588 if (status == ALT_E_SUCCESS)
1589 {
1590 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)dst_reg);
1591 }
1592
1593
1594 uint32_t countleft = count;
1595
1596
1597 if (countleft >> 4)
1598 {
1599
1600
1601
1602
1603
1604
1605
1606
1607 if (status == ALT_E_SUCCESS)
1608 {
1609 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1610 ( ccr_ss_ds_mask
1611 | ALT_DMA_CCR_OPT_SB16
1612 | ALT_DMA_CCR_OPT_SA_DEFAULT
1613 | ALT_DMA_CCR_OPT_SP_DEFAULT
1614 | ALT_DMA_CCR_OPT_SC_DEFAULT
1615 | ALT_DMA_CCR_OPT_DB16
1616 | ALT_DMA_CCR_OPT_DAF
1617 | ALT_DMA_CCR_OPT_DP_DEFAULT
1618 | ALT_DMA_CCR_OPT_DC_DEFAULT
1619 | ALT_DMA_CCR_OPT_ES_DEFAULT
1620 )
1621 );
1622 }
1623
1624 uint32_t length16burst = countleft >> 4;
1625 countleft &= 0xf;
1626
1627 dprintf("DMA[M->R]: Number of 16 burst length transfer(s): %lu.\n", length16burst);
1628 dprintf("DMA[M->R]: Number of remaining transfer(s): %lu.\n", countleft);
1629
1630
1631 if (length16burst >> 8)
1632 {
1633 uint32_t loop256length16burst = length16burst >> 8;
1634 length16burst &= ((1 << 8) - 1);
1635
1636 dprintf("DMA[M->R]: Number of 256-looped 16 burst length transfer(s): %lu.\n", loop256length16burst);
1637 dprintf("DMA[M->R]: Number of remaining 16 burst length transfer(s): %lu.\n", length16burst);
1638
1639 while (loop256length16burst > 0)
1640 {
1641 if (status != ALT_E_SUCCESS)
1642 {
1643 break;
1644 }
1645
1646 uint32_t loopcount = MIN(loop256length16burst, 256);
1647 loop256length16burst -= loopcount;
1648
1649 dprintf("DMA[M->R]: Looping %lux super loop transfer(s).\n", loopcount);
1650
1651 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1652 {
1653 status = alt_dma_program_DMALP(program, loopcount);
1654 }
1655
1656 if (status == ALT_E_SUCCESS)
1657 {
1658 status = alt_dma_program_DMALP(program, 256);
1659 }
1660 if (status == ALT_E_SUCCESS)
1661 {
1662 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1663 }
1664 if (status == ALT_E_SUCCESS)
1665 {
1666 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1667 }
1668 if (status == ALT_E_SUCCESS)
1669 {
1670 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1671 }
1672
1673 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1674 {
1675 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1676 }
1677 }
1678 }
1679
1680
1681 if (length16burst > 0)
1682 {
1683 uint32_t loopcount = length16burst;
1684 length16burst = 0;
1685
1686 dprintf("DMA[M->R]: Looping %lux 16 burst length transfer(s).\n", loopcount);
1687
1688 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1689 {
1690 status = alt_dma_program_DMALP(program, loopcount);
1691 }
1692 if (status == ALT_E_SUCCESS)
1693 {
1694 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1695 }
1696 if (status == ALT_E_SUCCESS)
1697 {
1698 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1699 }
1700 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1701 {
1702 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1703 }
1704 }
1705 }
1706
1707
1708
1709
1710 if (countleft)
1711 {
1712
1713
1714
1715
1716
1717
1718
1719
1720 if (status == ALT_E_SUCCESS)
1721 {
1722 dprintf("DMA[M->R]: Tail end %lux transfer(s).\n", countleft);
1723
1724 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1725 ( ccr_ss_ds_mask
1726 | ((countleft - 1) << 4)
1727 | ALT_DMA_CCR_OPT_SA_DEFAULT
1728 | ALT_DMA_CCR_OPT_SP_DEFAULT
1729 | ALT_DMA_CCR_OPT_SC_DEFAULT
1730 | ((countleft - 1) << 18)
1731 | ALT_DMA_CCR_OPT_DAF
1732 | ALT_DMA_CCR_OPT_DP_DEFAULT
1733 | ALT_DMA_CCR_OPT_DC_DEFAULT
1734 | ALT_DMA_CCR_OPT_ES_DEFAULT
1735 )
1736 );
1737 }
1738 if (status == ALT_E_SUCCESS)
1739 {
1740 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1741 }
1742 if (status == ALT_E_SUCCESS)
1743 {
1744 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1745 }
1746 }
1747
1748 }
1749
1750
1751 if (send_evt)
1752 {
1753 if (status == ALT_E_SUCCESS)
1754 {
1755 dprintf("DMA[M->R]: Adding event ...\n");
1756 status = alt_dma_program_DMASEV(program, evt);
1757 }
1758 }
1759
1760
1761 if (status == ALT_E_SUCCESS)
1762 {
1763 dprintf("DMA[M->R]: DMAEND program.\n");
1764 status = alt_dma_program_DMAEND(program);
1765 }
1766
1767
1768 if (status != ALT_E_SUCCESS)
1769 {
1770
1771
1772 alt_dma_program_clear(program);
1773 return status;
1774 }
1775
1776
1777 return alt_dma_channel_exec(channel, program);
1778 }
1779
1780 ALT_STATUS_CODE alt_dma_register_to_memory(ALT_DMA_CHANNEL_t channel,
1781 ALT_DMA_PROGRAM_t * program,
1782 void * dst_buf,
1783 const void * src_reg,
1784 size_t count,
1785 uint32_t register_width_bits,
1786 bool send_evt,
1787 ALT_DMA_EVENT_t evt)
1788 {
1789 ALT_STATUS_CODE status = ALT_E_SUCCESS;
1790
1791
1792 if ((count == 0) && (send_evt == false))
1793 {
1794 return status;
1795 }
1796
1797 if (status == ALT_E_SUCCESS)
1798 {
1799 status = alt_dma_program_init(program);
1800 }
1801
1802 if (count != 0)
1803 {
1804
1805 uint32_t ccr_ss_ds_mask = 0;
1806
1807 if (status == ALT_E_SUCCESS)
1808 {
1809 switch (register_width_bits)
1810 {
1811 case 8:
1812
1813
1814
1815 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS8 | ALT_DMA_CCR_OPT_DS8;
1816 break;
1817 case 16:
1818
1819
1820
1821 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS16 | ALT_DMA_CCR_OPT_DS16;
1822 break;
1823 case 32:
1824
1825
1826
1827 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS32 | ALT_DMA_CCR_OPT_DS32;
1828 break;
1829 case 64:
1830
1831
1832
1833 ccr_ss_ds_mask = ALT_DMA_CCR_OPT_SS64 | ALT_DMA_CCR_OPT_DS64;
1834 break;
1835 default:
1836 dprintf("DMA[R->M]: Invalid register width.\n");
1837 status = ALT_E_BAD_ARG;
1838 break;
1839 }
1840 }
1841
1842
1843 if (status == ALT_E_SUCCESS)
1844 {
1845 if (((uintptr_t)dst_buf & ((register_width_bits >> 3) - 1)) != 0)
1846 {
1847 status = ALT_E_BAD_ARG;
1848 }
1849 else if (((uintptr_t)src_reg & ((register_width_bits >> 3) - 1)) != 0)
1850 {
1851 status = ALT_E_BAD_ARG;
1852 }
1853 else
1854 {
1855 dprintf("DMA[R->M]: dst_reg = %p.\n", dst_buf);
1856 dprintf("DMA[R->M]: src_buf = %p.\n", src_reg);
1857 dprintf("DMA[R->M]: count = 0x%x.\n", count);
1858 }
1859 }
1860
1861 if (status == ALT_E_SUCCESS)
1862 {
1863 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, (uint32_t)src_reg);
1864 }
1865 if (status == ALT_E_SUCCESS)
1866 {
1867 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)dst_buf);
1868 }
1869
1870
1871 uint32_t countleft = count;
1872
1873
1874 if (countleft >> 4)
1875 {
1876 uint32_t length16burst = countleft >> 4;
1877 countleft &= 0xf;
1878
1879 dprintf("DMA[R->M]: Number of 16 burst length transfer(s): %lu.\n", length16burst);
1880 dprintf("DMA[R->M]: Number of remaining transfer(s): %lu.\n", countleft);
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895 if (status == ALT_E_SUCCESS)
1896 {
1897 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
1898 ( ccr_ss_ds_mask
1899 | ALT_DMA_CCR_OPT_SB16
1900 | ALT_DMA_CCR_OPT_SAF
1901 | ALT_DMA_CCR_OPT_SP_DEFAULT
1902 | ALT_DMA_CCR_OPT_SC_DEFAULT
1903 | ALT_DMA_CCR_OPT_DB16
1904 | ALT_DMA_CCR_OPT_DA_DEFAULT
1905 | ALT_DMA_CCR_OPT_DP_DEFAULT
1906 | ALT_DMA_CCR_OPT_DC_DEFAULT
1907 | ALT_DMA_CCR_OPT_ES_DEFAULT
1908 )
1909 );
1910 }
1911
1912
1913 if (length16burst >> 8)
1914 {
1915 uint32_t loop256length16burst = length16burst >> 8;
1916 length16burst &= ((1 << 8) - 1);
1917
1918 dprintf("DMA[R->M]: Number of 256-looped 16 burst length transfer(s): %lu.\n", loop256length16burst);
1919 dprintf("DMA[R->M]: Number of remaining 16 burst length transfer(s): %lu.\n", length16burst);
1920
1921 while (loop256length16burst > 0)
1922 {
1923 if (status != ALT_E_SUCCESS)
1924 {
1925 break;
1926 }
1927
1928 uint32_t loopcount = MIN(loop256length16burst, 256);
1929 loop256length16burst -= loopcount;
1930
1931 dprintf("DMA[R->M]: Looping %lux super loop transfer(s).\n", loopcount);
1932
1933 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1934 {
1935 status = alt_dma_program_DMALP(program, loopcount);
1936 }
1937
1938 if (status == ALT_E_SUCCESS)
1939 {
1940 status = alt_dma_program_DMALP(program, 256);
1941 }
1942 if (status == ALT_E_SUCCESS)
1943 {
1944 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1945 }
1946 if (status == ALT_E_SUCCESS)
1947 {
1948 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1949 }
1950 if (status == ALT_E_SUCCESS)
1951 {
1952 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1953 }
1954
1955 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1956 {
1957 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1958 }
1959 }
1960 }
1961
1962
1963 if (length16burst > 0)
1964 {
1965 uint32_t loopcount = length16burst;
1966 length16burst = 0;
1967
1968 dprintf("DMA[R->M]: Looping %lux 16 burst length transfer(s).\n", loopcount);
1969
1970 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1971 {
1972 status = alt_dma_program_DMALP(program, loopcount);
1973 }
1974 if (status == ALT_E_SUCCESS)
1975 {
1976 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1977 }
1978 if (status == ALT_E_SUCCESS)
1979 {
1980 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1981 }
1982 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
1983 {
1984 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
1985 }
1986 }
1987 }
1988
1989
1990
1991
1992 if (countleft)
1993 {
1994 dprintf("DMA[R->M]: Tail end %lux transfer(s).\n", countleft);
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004 if (status == ALT_E_SUCCESS)
2005 {
2006 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2007 ( ccr_ss_ds_mask
2008 | ((countleft - 1) << 4)
2009 | ALT_DMA_CCR_OPT_SAF
2010 | ALT_DMA_CCR_OPT_SP_DEFAULT
2011 | ALT_DMA_CCR_OPT_SC_DEFAULT
2012 | ((countleft - 1) << 18)
2013 | ALT_DMA_CCR_OPT_DA_DEFAULT
2014 | ALT_DMA_CCR_OPT_DP_DEFAULT
2015 | ALT_DMA_CCR_OPT_DC_DEFAULT
2016 | ALT_DMA_CCR_OPT_ES_DEFAULT
2017 )
2018 );
2019 }
2020
2021 if (status == ALT_E_SUCCESS)
2022 {
2023 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2024 }
2025 if (status == ALT_E_SUCCESS)
2026 {
2027 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2028 }
2029 }
2030
2031 }
2032
2033
2034 if (send_evt)
2035 {
2036 if (status == ALT_E_SUCCESS)
2037 {
2038 dprintf("DMA[R->M]: Adding event ...\n");
2039 status = alt_dma_program_DMASEV(program, evt);
2040 }
2041 }
2042
2043
2044 if (status == ALT_E_SUCCESS)
2045 {
2046 status = alt_dma_program_DMAEND(program);
2047 }
2048
2049
2050 if (status != ALT_E_SUCCESS)
2051 {
2052
2053
2054 alt_dma_program_clear(program);
2055 return status;
2056 }
2057
2058
2059 return alt_dma_channel_exec(channel, program);
2060 }
2061
2062 #if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
2063 static ALT_STATUS_CODE alt_dma_memory_to_qspi(ALT_DMA_PROGRAM_t * program,
2064 const char * src,
2065 size_t size)
2066 {
2067 if ((uintptr_t)src & 0x3)
2068 {
2069 return ALT_E_ERROR;
2070 }
2071
2072 if (size & 0x3)
2073 {
2074 return ALT_E_ERROR;
2075 }
2076
2077
2078
2079 ALT_STATUS_CODE status = ALT_E_SUCCESS;
2080
2081 if (status == ALT_E_SUCCESS)
2082 {
2083 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR,
2084 (uint32_t)ALT_QSPIDATA_ADDR);
2085 }
2086 if (status == ALT_E_SUCCESS)
2087 {
2088 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR,
2089 (uint32_t)src);
2090 }
2091
2092
2093
2094 uint32_t dmaper = alt_read_word(ALT_QSPI_DMAPER_ADDR);
2095 uint32_t qspi_single_size_log2 = ALT_QSPI_DMAPER_NUMSGLREQBYTES_GET(dmaper);
2096 uint32_t qspi_burst_size_log2 = ALT_QSPI_DMAPER_NUMBURSTREQBYTES_GET(dmaper);
2097 uint32_t qspi_single_size = 1 << qspi_single_size_log2;
2098 uint32_t qspi_burst_size = 1 << qspi_burst_size_log2;
2099
2100 dprintf("DMA[M->P][QSPI]: QSPI Single = %lu; Burst = %lu.\n", qspi_single_size, qspi_burst_size);
2101
2102
2103
2104
2105 if (size & (qspi_single_size - 1))
2106 {
2107 dprintf("DMA[M->P][QSPI]: QSPI DMA size configuration not suitable for transfer request.\n");
2108 return ALT_E_ERROR;
2109 }
2110
2111
2112
2113 if ((uintptr_t)src & 0x7)
2114 {
2115
2116
2117 dprintf("DMA[M->P][QSPI]: Creating 1x 4-byte aligning transfer.\n");
2118
2119 if (status == ALT_E_SUCCESS)
2120 {
2121 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2122 ( ALT_DMA_CCR_OPT_SAI
2123 | ALT_DMA_CCR_OPT_SS32
2124 | ALT_DMA_CCR_OPT_SB1
2125 | ALT_DMA_CCR_OPT_SP_DEFAULT
2126 | ALT_DMA_CCR_OPT_SC_DEFAULT
2127 | ALT_DMA_CCR_OPT_DAF
2128 | ALT_DMA_CCR_OPT_DS32
2129 | ALT_DMA_CCR_OPT_DB1
2130 | ALT_DMA_CCR_OPT_DP_DEFAULT
2131 | ALT_DMA_CCR_OPT_DC_DEFAULT
2132 | ALT_DMA_CCR_OPT_ES_DEFAULT
2133 )
2134 );
2135 }
2136
2137 if (status == ALT_E_SUCCESS)
2138 {
2139 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX);
2140 }
2141
2142 if (status == ALT_E_SUCCESS)
2143 {
2144 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2145 }
2146
2147 if (status == ALT_E_SUCCESS)
2148 {
2149 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2150 }
2151
2152 if (status == ALT_E_SUCCESS)
2153 {
2154 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2155 }
2156
2157 size -= sizeof(uint32_t);
2158 }
2159
2160 uint32_t qspi_single_count = 0;
2161 uint32_t qspi_burst_count = size >> qspi_burst_size_log2;
2162
2163
2164
2165
2166
2167 if ( (qspi_burst_size_log2 > qspi_single_size_log2)
2168 && (qspi_burst_count != 0)
2169 )
2170 {
2171
2172 qspi_single_count = (size & (qspi_burst_size - 1)) >> qspi_single_size_log2;
2173
2174 dprintf("DMA[M->P][QSPI][B]: Burst size = %lu bytes, count = %lu.\n", qspi_burst_size, qspi_burst_count);
2175
2176
2177 uint32_t src_size_log2 = MIN(3, qspi_burst_size_log2);
2178
2179 uint32_t src_length = 0;
2180 uint32_t src_multiple = 0;
2181
2182 if ((qspi_burst_size >> src_size_log2) <= 16)
2183 {
2184 src_length = qspi_burst_size >> src_size_log2;
2185 src_multiple = 1;
2186 }
2187 else
2188 {
2189 src_length = 16;
2190 src_multiple = (qspi_burst_size >> src_size_log2) >> 4;
2191
2192 if (src_multiple == 0)
2193 {
2194 dprintf("DEBUG[QSPI][B]: src_multiple is 0.\n");
2195 status = ALT_E_ERROR;
2196 }
2197 }
2198
2199
2200 uint32_t dst_multiple = qspi_burst_size >> 2;
2201
2202 dprintf("DMA[M->P][QSPI][B]: dst_size = %u bits, dst_length = %u, dst_multiple = %lu.\n",
2203 32, 1, dst_multiple);
2204 dprintf("DMA[M->P][QSPI][B]: src_size = %u bits, src_length = %lu, src_multiple = %lu.\n",
2205 (1 << src_size_log2) * 8, src_length, src_multiple);
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218 if (status == ALT_E_SUCCESS)
2219 {
2220 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2221 ( ALT_DMA_CCR_OPT_SAI
2222 | (src_size_log2 << 1)
2223 | ((src_length - 1) << 4)
2224 | ALT_DMA_CCR_OPT_SP_DEFAULT
2225 | ALT_DMA_CCR_OPT_SC_DEFAULT
2226 | ALT_DMA_CCR_OPT_DAF
2227 | ALT_DMA_CCR_OPT_DS32
2228 | ALT_DMA_CCR_OPT_DB1
2229 | ALT_DMA_CCR_OPT_DP_DEFAULT
2230 | ALT_DMA_CCR_OPT_DC_DEFAULT
2231 | ALT_DMA_CCR_OPT_ES_DEFAULT
2232 )
2233 );
2234 }
2235
2236
2237
2238
2239 while (qspi_burst_count > 0)
2240 {
2241 if (status != ALT_E_SUCCESS)
2242 {
2243 break;
2244 }
2245
2246 uint32_t loopcount = MIN(qspi_burst_count, 256);
2247 qspi_burst_count -= loopcount;
2248
2249 dprintf("DMA[M->P][QSPI][B]: Creating %lu burst-type transfer(s).\n", loopcount);
2250
2251 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2252 {
2253 status = alt_dma_program_DMALP(program, loopcount);
2254 }
2255
2256 if (status == ALT_E_SUCCESS)
2257 {
2258 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX);
2259 }
2260 if (status == ALT_E_SUCCESS)
2261 {
2262 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX, ALT_DMA_PROGRAM_INST_MOD_BURST);
2263 }
2264 for (uint32_t j = 0; j < src_multiple; ++j)
2265 {
2266 if (status == ALT_E_SUCCESS)
2267 {
2268 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
2269 }
2270 }
2271 for (uint32_t k = 0; k < dst_multiple; ++k)
2272 {
2273 if (status == ALT_E_SUCCESS)
2274 {
2275 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
2276 }
2277 }
2278
2279 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2280 {
2281 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2282 }
2283 }
2284 }
2285 else
2286 {
2287 qspi_single_count = size >> qspi_single_size_log2;
2288 }
2289
2290
2291 if (qspi_single_count)
2292 {
2293 dprintf("DMA[M->P][QSPI][S]: Single size = %lu bytes, count = %lu.\n", qspi_single_size, qspi_single_count);
2294
2295
2296 uint32_t src_size_log2 = MIN(3, qspi_single_size_log2);
2297
2298 uint32_t src_length = 0;
2299 uint32_t src_multiple = 0;
2300
2301 if ((qspi_single_size >> src_size_log2) <= 16)
2302 {
2303 src_length = qspi_single_size >> src_size_log2;
2304 src_multiple = 1;
2305 }
2306 else
2307 {
2308 src_length = 16;
2309 src_multiple = (qspi_single_size >> src_size_log2) >> 4;
2310
2311 if (src_multiple == 0)
2312 {
2313 dprintf("DEBUG[QSPI][S]: src_multiple is 0.\n");
2314 status = ALT_E_ERROR;
2315 }
2316 }
2317
2318
2319 uint32_t dst_multiple = qspi_single_size >> 2;
2320
2321 dprintf("DMA[M->P][QSPI][S]: dst_size = %u bits, dst_length = %u, dst_multiple = %lu.\n",
2322 32, 1, dst_multiple);
2323 dprintf("DMA[M->P][QSPI][S]: src_size = %u bits, src_length = %lu, src_multiple = %lu.\n",
2324 (1 <<src_size_log2) * 8, src_length, src_multiple);
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337 if (status == ALT_E_SUCCESS)
2338 {
2339 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2340 ( ALT_DMA_CCR_OPT_SAI
2341 | (src_size_log2 << 1)
2342 | ((src_length - 1) << 4)
2343 | ALT_DMA_CCR_OPT_SP_DEFAULT
2344 | ALT_DMA_CCR_OPT_SC_DEFAULT
2345 | ALT_DMA_CCR_OPT_DAF
2346 | ALT_DMA_CCR_OPT_DS32
2347 | ALT_DMA_CCR_OPT_DB1
2348 | ALT_DMA_CCR_OPT_DP_DEFAULT
2349 | ALT_DMA_CCR_OPT_DC_DEFAULT
2350 | ALT_DMA_CCR_OPT_ES_DEFAULT
2351 )
2352 );
2353 }
2354
2355
2356
2357
2358 while (qspi_single_count > 0)
2359 {
2360 if (status != ALT_E_SUCCESS)
2361 {
2362 break;
2363 }
2364
2365 uint32_t loopcount = MIN(qspi_single_count, 256);
2366 qspi_single_count -= loopcount;
2367
2368 dprintf("DMA[M->P][QSPI][S]: Creating %lu single-type transfer(s).\n", loopcount);
2369
2370 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2371 {
2372 status = alt_dma_program_DMALP(program, loopcount);
2373 }
2374
2375 if (status == ALT_E_SUCCESS)
2376 {
2377 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX);
2378 }
2379 if (status == ALT_E_SUCCESS)
2380 {
2381 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_TX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2382 }
2383 for (uint32_t j = 0; j < src_multiple; ++j)
2384 {
2385 if (status == ALT_E_SUCCESS)
2386 {
2387 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2388 }
2389 }
2390 for (uint32_t k = 0; k < dst_multiple; ++k)
2391 {
2392 if (status == ALT_E_SUCCESS)
2393 {
2394 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2395 }
2396 }
2397
2398 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2399 {
2400 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2401 }
2402 }
2403
2404 }
2405
2406 return status;
2407 }
2408
2409 static ALT_STATUS_CODE alt_dma_qspi_to_memory(ALT_DMA_PROGRAM_t * program,
2410 char * dst,
2411 size_t size)
2412 {
2413 if ((uintptr_t)dst & 0x3)
2414 {
2415 return ALT_E_ERROR;
2416 }
2417
2418 if (size & 0x3)
2419 {
2420 return ALT_E_ERROR;
2421 }
2422
2423
2424
2425 ALT_STATUS_CODE status = ALT_E_SUCCESS;
2426
2427 if (status == ALT_E_SUCCESS)
2428 {
2429 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR,
2430 (uint32_t)dst);
2431 }
2432 if (status == ALT_E_SUCCESS)
2433 {
2434 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR,
2435 (uint32_t)ALT_QSPIDATA_ADDR);
2436 }
2437
2438
2439
2440 uint32_t dmaper = alt_read_word(ALT_QSPI_DMAPER_ADDR);
2441 uint32_t qspi_single_size_log2 = ALT_QSPI_DMAPER_NUMSGLREQBYTES_GET(dmaper);
2442 uint32_t qspi_burst_size_log2 = ALT_QSPI_DMAPER_NUMBURSTREQBYTES_GET(dmaper);
2443 uint32_t qspi_single_size = 1 << qspi_single_size_log2;
2444 uint32_t qspi_burst_size = 1 << qspi_burst_size_log2;
2445
2446 dprintf("DMA[P->M][QSPI]: QSPI Single = %lu; Burst = %lu.\n", qspi_single_size, qspi_burst_size);
2447
2448
2449
2450
2451 if (size & (qspi_single_size - 1))
2452 {
2453 dprintf("DMA[P->M][QSPI]: QSPI DMA size configuration not suitable for transfer request.\n");
2454 return ALT_E_ERROR;
2455 }
2456
2457
2458
2459 if ((uintptr_t)dst & 0x7)
2460 {
2461
2462
2463 dprintf("DMA[P->M][QSPI]: Creating 1x 4-byte aligning transfer.\n");
2464
2465 if (status == ALT_E_SUCCESS)
2466 {
2467 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2468 ( ALT_DMA_CCR_OPT_SAF
2469 | ALT_DMA_CCR_OPT_SS32
2470 | ALT_DMA_CCR_OPT_SB1
2471 | ALT_DMA_CCR_OPT_SP_DEFAULT
2472 | ALT_DMA_CCR_OPT_SC_DEFAULT
2473 | ALT_DMA_CCR_OPT_DAI
2474 | ALT_DMA_CCR_OPT_DS32
2475 | ALT_DMA_CCR_OPT_DB1
2476 | ALT_DMA_CCR_OPT_DP_DEFAULT
2477 | ALT_DMA_CCR_OPT_DC_DEFAULT
2478 | ALT_DMA_CCR_OPT_ES_DEFAULT
2479 )
2480 );
2481 }
2482
2483 if (status == ALT_E_SUCCESS)
2484 {
2485 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
2486 }
2487
2488 if (status == ALT_E_SUCCESS)
2489 {
2490 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2491 }
2492
2493 if (status == ALT_E_SUCCESS)
2494 {
2495 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2496 }
2497
2498 if (status == ALT_E_SUCCESS)
2499 {
2500 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2501 }
2502
2503 size -= sizeof(uint32_t);
2504 }
2505
2506 uint32_t qspi_single_count = 0;
2507 uint32_t qspi_burst_count = size >> qspi_burst_size_log2;
2508
2509
2510
2511
2512
2513 if ( (qspi_burst_size_log2 > qspi_single_size_log2)
2514 && (qspi_burst_count != 0)
2515 )
2516 {
2517
2518 qspi_single_count = (size & (qspi_burst_size - 1)) >> qspi_single_size_log2;
2519
2520 dprintf("DMA[P->M][QSPI][B]: Burst size = %lu bytes, count = %lu.\n", qspi_burst_size, qspi_burst_count);
2521
2522
2523 uint32_t dst_size_log2 = MIN(3, qspi_burst_size_log2);
2524
2525 uint32_t dst_length = 0;
2526 uint32_t dst_multiple = 0;
2527
2528 if ((qspi_burst_size >> dst_size_log2) <= 16)
2529 {
2530 dst_length = qspi_burst_size >> dst_size_log2;
2531 dst_multiple = 1;
2532 }
2533 else
2534 {
2535 dst_length = 16;
2536 dst_multiple = (qspi_burst_size >> dst_size_log2) >> 4;
2537
2538 if (dst_multiple == 0)
2539 {
2540 dprintf("DEBUG[QSPI][B]: dst_multiple is 0.\n");
2541 status = ALT_E_ERROR;
2542 }
2543 }
2544
2545
2546 uint32_t src_multiple = qspi_burst_size >> 2;
2547
2548 dprintf("DMA[P->M][QSPI][B]: dst_size = %u bits, dst_length = %lu, dst_multiple = %lu.\n",
2549 (1 << dst_size_log2) * 8, dst_length, dst_multiple);
2550 dprintf("DMA[P->M][QSPI][B]: src_size = %u bits, src_length = %u, src_multiple = %lu.\n",
2551 32, 1, src_multiple);
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564 if (status == ALT_E_SUCCESS)
2565 {
2566 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2567 ( ALT_DMA_CCR_OPT_SAF
2568 | ALT_DMA_CCR_OPT_SS32
2569 | ALT_DMA_CCR_OPT_SB1
2570 | ALT_DMA_CCR_OPT_SP_DEFAULT
2571 | ALT_DMA_CCR_OPT_SC_DEFAULT
2572 | ALT_DMA_CCR_OPT_DAI
2573 | (dst_size_log2 << 15)
2574 | ((dst_length - 1) << 18)
2575 | ALT_DMA_CCR_OPT_DP_DEFAULT
2576 | ALT_DMA_CCR_OPT_DC_DEFAULT
2577 | ALT_DMA_CCR_OPT_ES_DEFAULT
2578 )
2579 );
2580 }
2581
2582
2583
2584 if (qspi_burst_count >> 8)
2585 {
2586 uint32_t qspi_burst256_count = qspi_burst_count >> 8;
2587 qspi_burst_count &= (1 << 8) - 1;
2588
2589 while (qspi_burst256_count > 0)
2590 {
2591 if (status != ALT_E_SUCCESS)
2592 {
2593 break;
2594 }
2595
2596 uint32_t loopcount = MIN(qspi_burst256_count, 256);
2597 qspi_burst256_count -= loopcount;
2598
2599 dprintf("DMA[P->M][QSPI][B]: Creating %lu 256x burst-type transfer(s).\n", loopcount);
2600
2601
2602
2603 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2604 {
2605 status = alt_dma_program_DMALP(program, loopcount);
2606 }
2607
2608
2609
2610 if (status == ALT_E_SUCCESS)
2611 {
2612 status = alt_dma_program_DMALP(program, 256);
2613 }
2614
2615 if (status == ALT_E_SUCCESS)
2616 {
2617 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
2618 }
2619 if (status == ALT_E_SUCCESS)
2620 {
2621 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_BURST);
2622 }
2623 for (uint32_t j = 0; j < src_multiple; ++j)
2624 {
2625 if (status == ALT_E_SUCCESS)
2626 {
2627 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
2628 }
2629 }
2630 for (uint32_t k = 0; k < dst_multiple; ++k)
2631 {
2632 if (status == ALT_E_SUCCESS)
2633 {
2634 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
2635 }
2636 }
2637
2638 if (status == ALT_E_SUCCESS)
2639 {
2640 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2641 }
2642
2643
2644
2645 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2646 {
2647 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2648 }
2649
2650
2651 }
2652 }
2653
2654 while (qspi_burst_count > 0)
2655 {
2656 if (status != ALT_E_SUCCESS)
2657 {
2658 break;
2659 }
2660
2661 uint32_t loopcount = MIN(qspi_burst_count, 256);
2662 qspi_burst_count -= loopcount;
2663
2664 dprintf("DMA[P->M][QSPI][B]: Creating %lu burst-type transfer(s).\n", loopcount);
2665
2666 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2667 {
2668 status = alt_dma_program_DMALP(program, loopcount);
2669 }
2670
2671 if (status == ALT_E_SUCCESS)
2672 {
2673 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
2674 }
2675 if (status == ALT_E_SUCCESS)
2676 {
2677 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_BURST);
2678 }
2679 for (uint32_t j = 0; j < src_multiple; ++j)
2680 {
2681 if (status == ALT_E_SUCCESS)
2682 {
2683 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
2684 }
2685 }
2686 for (uint32_t k = 0; k < dst_multiple; ++k)
2687 {
2688 if (status == ALT_E_SUCCESS)
2689 {
2690 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
2691 }
2692 }
2693
2694 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2695 {
2696 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2697 }
2698 }
2699 }
2700 else
2701 {
2702 qspi_single_count = size >> qspi_single_size_log2;
2703 }
2704
2705
2706 if (qspi_single_count)
2707 {
2708 dprintf("DMA[P->M][QSPI][S]: Single size = %lu bytes, count = %lu.\n", qspi_single_size, qspi_single_count);
2709
2710
2711 uint32_t dst_size_log2 = MIN(3, qspi_single_size_log2);
2712
2713 uint32_t dst_length = 0;
2714 uint32_t dst_multiple = 0;
2715
2716 if ((qspi_single_size >> dst_size_log2) <= 16)
2717 {
2718 dst_length = qspi_single_size >> dst_size_log2;
2719 dst_multiple = 1;
2720 }
2721 else
2722 {
2723 dst_length = 16;
2724 dst_multiple = (qspi_single_size >> dst_size_log2) >> 4;
2725
2726 if (dst_multiple == 0)
2727 {
2728 dprintf("DEBUG[QSPI][S]: dst_multiple is 0.\n");
2729 status = ALT_E_ERROR;
2730 }
2731 }
2732
2733
2734 uint32_t src_multiple = qspi_single_size >> 2;
2735
2736 dprintf("DMA[P->M][QSPI][S]: dst_size = %u bits, dst_length = %lu, dst_multiple = %lu.\n",
2737 (1 << dst_size_log2) * 8, dst_length, dst_multiple);
2738 dprintf("DMA[P->M][QSPI][S]: src_size = %u bits, src_length = %u, src_multiple = %lu.\n",
2739 32, 1, src_multiple);
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752 if (status == ALT_E_SUCCESS)
2753 {
2754 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2755 ( ALT_DMA_CCR_OPT_SAF
2756 | ALT_DMA_CCR_OPT_SS32
2757 | ALT_DMA_CCR_OPT_SB1
2758 | ALT_DMA_CCR_OPT_SP_DEFAULT
2759 | ALT_DMA_CCR_OPT_SC_DEFAULT
2760 | ALT_DMA_CCR_OPT_DAI
2761 | (dst_size_log2 << 15)
2762 | ((dst_length - 1) << 18)
2763 | ALT_DMA_CCR_OPT_DP_DEFAULT
2764 | ALT_DMA_CCR_OPT_DC_DEFAULT
2765 | ALT_DMA_CCR_OPT_ES_DEFAULT
2766 )
2767 );
2768 }
2769
2770
2771
2772 if (qspi_single_count >> 8)
2773 {
2774 uint32_t qspi_single256_count = qspi_single_count >> 8;
2775 qspi_single_count &= (1 << 8) - 1;
2776
2777 while (qspi_single256_count > 0)
2778 {
2779 if (status != ALT_E_SUCCESS)
2780 {
2781 break;
2782 }
2783
2784 uint32_t loopcount = MIN(qspi_single256_count, 256);
2785 qspi_single256_count -= loopcount;
2786
2787 dprintf("DMA[P->M][QSPI][S]: Creating %lu 256x single-type transfer(s).\n", loopcount);
2788
2789
2790
2791 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2792 {
2793 status = alt_dma_program_DMALP(program, loopcount);
2794 }
2795
2796
2797
2798 if (status == ALT_E_SUCCESS)
2799 {
2800 status = alt_dma_program_DMALP(program, 256);
2801 }
2802
2803 if (status == ALT_E_SUCCESS)
2804 {
2805 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
2806 }
2807 if (status == ALT_E_SUCCESS)
2808 {
2809 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2810 }
2811 for (uint32_t j = 0; j < src_multiple; ++j)
2812 {
2813 if (status == ALT_E_SUCCESS)
2814 {
2815 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2816 }
2817 }
2818 for (uint32_t k = 0; k < dst_multiple; ++k)
2819 {
2820 if (status == ALT_E_SUCCESS)
2821 {
2822 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2823 }
2824 }
2825
2826 if (status == ALT_E_SUCCESS)
2827 {
2828 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2829 }
2830
2831
2832
2833 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2834 {
2835 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2836 }
2837
2838
2839 }
2840 }
2841
2842 while (qspi_single_count > 0)
2843 {
2844 if (status != ALT_E_SUCCESS)
2845 {
2846 break;
2847 }
2848
2849 uint32_t loopcount = MIN(qspi_single_count, 256);
2850 qspi_single_count -= loopcount;
2851
2852 dprintf("DMA[P->M][QSPI][S]: Creating %lu single-type transfer(s).\n", loopcount);
2853
2854 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2855 {
2856 status = alt_dma_program_DMALP(program, loopcount);
2857 }
2858
2859 if (status == ALT_E_SUCCESS)
2860 {
2861 status = alt_dma_program_DMAFLUSHP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX);
2862 }
2863 if (status == ALT_E_SUCCESS)
2864 {
2865 status = alt_dma_program_DMAWFP(program, ALT_DMA_PERIPH_QSPI_FLASH_RX, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2866 }
2867 for (uint32_t j = 0; j < src_multiple; ++j)
2868 {
2869 if (status == ALT_E_SUCCESS)
2870 {
2871 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2872 }
2873 }
2874 for (uint32_t k = 0; k < dst_multiple; ++k)
2875 {
2876 if (status == ALT_E_SUCCESS)
2877 {
2878 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2879 }
2880 }
2881
2882 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2883 {
2884 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_NONE);
2885 }
2886 }
2887
2888 }
2889
2890 return status;
2891 }
2892 #endif
2893
2894 #if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
2895 static ALT_STATUS_CODE alt_dma_memory_to_16550_single(ALT_DMA_PROGRAM_t * program,
2896 ALT_DMA_PERIPH_t periph,
2897 size_t size)
2898 {
2899 ALT_STATUS_CODE status = ALT_E_SUCCESS;
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909 if (status == ALT_E_SUCCESS)
2910 {
2911 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2912 ( ALT_DMA_CCR_OPT_SB1
2913 | ALT_DMA_CCR_OPT_SS8
2914 | ALT_DMA_CCR_OPT_SA_DEFAULT
2915 | ALT_DMA_CCR_OPT_SP_DEFAULT
2916 | ALT_DMA_CCR_OPT_SC_DEFAULT
2917 | ALT_DMA_CCR_OPT_DB1
2918 | ALT_DMA_CCR_OPT_DS8
2919 | ALT_DMA_CCR_OPT_DAF
2920 | ALT_DMA_CCR_OPT_DP_DEFAULT
2921 | ALT_DMA_CCR_OPT_DC_DEFAULT
2922 | ALT_DMA_CCR_OPT_ES_DEFAULT
2923 )
2924 );
2925 }
2926
2927 uint32_t sizeleft = size;
2928
2929 while (sizeleft > 0)
2930 {
2931 if (status != ALT_E_SUCCESS)
2932 {
2933 break;
2934 }
2935
2936 uint32_t loopcount = MIN(sizeleft, 256);
2937 sizeleft -= loopcount;
2938
2939 dprintf("DMA[M->P][16550][S]: Creating %lu transfer(s).\n", loopcount);
2940
2941 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2942 {
2943 status = alt_dma_program_DMALP(program, loopcount);
2944 }
2945
2946 if (status == ALT_E_SUCCESS)
2947 {
2948 status = alt_dma_program_DMAFLUSHP(program, periph);
2949 }
2950 if (status == ALT_E_SUCCESS)
2951 {
2952 status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2953 }
2954 if (status == ALT_E_SUCCESS)
2955 {
2956 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2957 }
2958 if (status == ALT_E_SUCCESS)
2959 {
2960 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2961 }
2962
2963 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
2964 {
2965 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
2966 }
2967 }
2968
2969 return status;
2970 }
2971
2972 static ALT_STATUS_CODE alt_dma_memory_to_16550_burst(ALT_DMA_PROGRAM_t * program,
2973 ALT_DMA_PERIPH_t periph,
2974 size_t burst_size,
2975 size_t burst_count)
2976 {
2977 ALT_STATUS_CODE status = ALT_E_SUCCESS;
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987 if (status == ALT_E_SUCCESS)
2988 {
2989 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
2990 ( ALT_DMA_CCR_OPT_SB16
2991 | ALT_DMA_CCR_OPT_SS8
2992 | ALT_DMA_CCR_OPT_SA_DEFAULT
2993 | ALT_DMA_CCR_OPT_SP_DEFAULT
2994 | ALT_DMA_CCR_OPT_SC_DEFAULT
2995 | ALT_DMA_CCR_OPT_DB16
2996 | ALT_DMA_CCR_OPT_DS8
2997 | ALT_DMA_CCR_OPT_DAF
2998 | ALT_DMA_CCR_OPT_DP_DEFAULT
2999 | ALT_DMA_CCR_OPT_DC_DEFAULT
3000 | ALT_DMA_CCR_OPT_ES_DEFAULT
3001 )
3002 );
3003 }
3004
3005 while (burst_count > 0)
3006 {
3007 if (status != ALT_E_SUCCESS)
3008 {
3009 break;
3010 }
3011
3012 uint32_t loopcount = MIN(burst_count, 256);
3013 burst_count -= loopcount;
3014
3015 dprintf("DMA[M->P][16550][B]: Creating outer %lu inner loop(s).\n", loopcount);
3016
3017
3018
3019 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
3020 {
3021 status = alt_dma_program_DMALP(program, loopcount);
3022 }
3023 if (status == ALT_E_SUCCESS)
3024 {
3025 status = alt_dma_program_DMAFLUSHP(program, periph);
3026 }
3027 if (status == ALT_E_SUCCESS)
3028 {
3029 status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_BURST);
3030 }
3031
3032
3033
3034
3035
3036
3037
3038 dprintf("DMA[M->P][16550][B]: Creating inner %u transfer(s).\n", burst_size >> 4);
3039
3040 if (status == ALT_E_SUCCESS)
3041 {
3042 status = alt_dma_program_DMALP(program, burst_size >> 4);
3043 }
3044 if (status == ALT_E_SUCCESS)
3045 {
3046 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3047 }
3048 if (status == ALT_E_SUCCESS)
3049 {
3050 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3051 }
3052 if (status == ALT_E_SUCCESS)
3053 {
3054 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3055 }
3056
3057
3058
3059 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
3060 {
3061 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3062 }
3063
3064
3065 }
3066
3067 return status;
3068 }
3069
3070 static ALT_STATUS_CODE alt_dma_memory_to_16550(ALT_DMA_PROGRAM_t * program,
3071 ALT_DMA_PERIPH_t periph,
3072 ALT_16550_HANDLE_t * handle,
3073 const void * src,
3074 size_t size)
3075 {
3076 ALT_STATUS_CODE status = ALT_E_SUCCESS;
3077
3078 if (status == ALT_E_SUCCESS)
3079 {
3080 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR,
3081 (uint32_t)ALT_UART_RBR_THR_DLL_ADDR(handle->location));
3082 }
3083 if (status == ALT_E_SUCCESS)
3084 {
3085 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR,
3086 (uint32_t)src);
3087 }
3088
3089
3090
3091 if (ALT_UART_FCR_FIFOE_GET(handle->fcr) != 0)
3092 {
3093 dprintf("DMA[M->P][16550]: FIFOs enabled.\n");
3094
3095
3096
3097
3098
3099 uint32_t tx_size;
3100 uint32_t burst_size;
3101 ALT_16550_FIFO_TRIGGER_TX_t trig_tx;
3102
3103
3104
3105 tx_size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
3106
3107
3108 trig_tx = (ALT_16550_FIFO_TRIGGER_TX_t)ALT_UART_FCR_TET_GET(handle->fcr);
3109
3110 switch (trig_tx)
3111 {
3112 case ALT_16550_FIFO_TRIGGER_TX_EMPTY:
3113 burst_size = tx_size;
3114 break;
3115 case ALT_16550_FIFO_TRIGGER_TX_ALMOST_EMPTY:
3116 burst_size = tx_size - 2;
3117 break;
3118 case ALT_16550_FIFO_TRIGGER_TX_QUARTER_FULL:
3119 burst_size = 3 * (tx_size >> 2);
3120 break;
3121 case ALT_16550_FIFO_TRIGGER_TX_HALF_FULL:
3122 burst_size = tx_size >> 1;
3123 break;
3124 default:
3125
3126 return ALT_E_ERROR;
3127 }
3128
3129 if (burst_size < 16)
3130 {
3131
3132 if (status == ALT_E_SUCCESS)
3133 {
3134 status = alt_dma_memory_to_16550_single(program,
3135 periph,
3136 size);
3137 }
3138 }
3139 else
3140 {
3141 uint32_t sizeleft = size;
3142
3143
3144
3145 dprintf("DMA[M->P][16550]: Untrimmed burst size = %lu.\n", burst_size);
3146 burst_size &= ~0xf;
3147 dprintf("DMA[M->P][16550]: Trimmed burst size = %lu.\n", burst_size);
3148
3149
3150 uint32_t burst_count = 0;
3151
3152 burst_count = sizeleft / burst_size;
3153 sizeleft -= burst_count * burst_size;
3154
3155 if (burst_count == 0)
3156 {
3157
3158 if (status == ALT_E_SUCCESS)
3159 {
3160 status = alt_dma_memory_to_16550_single(program,
3161 periph,
3162 sizeleft);
3163 }
3164 }
3165 else
3166 {
3167
3168 if (status == ALT_E_SUCCESS)
3169 {
3170 status = alt_dma_memory_to_16550_burst(program,
3171 periph,
3172 burst_size,
3173 burst_count);
3174 }
3175
3176
3177 if (status == ALT_E_SUCCESS)
3178 {
3179 status = alt_dma_memory_to_16550_single(program,
3180 periph,
3181 sizeleft);
3182 }
3183
3184 }
3185 }
3186 }
3187 else
3188 {
3189 dprintf("DMA[M->P][16550]: FIFOs disabled.\n");
3190
3191
3192
3193
3194
3195 status = alt_dma_memory_to_16550_single(program,
3196 periph,
3197 size);
3198 }
3199
3200 return status;
3201 }
3202
3203 static ALT_STATUS_CODE alt_dma_16550_to_memory_single(ALT_DMA_PROGRAM_t * program,
3204 ALT_DMA_PERIPH_t periph,
3205 size_t size)
3206 {
3207 ALT_STATUS_CODE status = ALT_E_SUCCESS;
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217 if (status == ALT_E_SUCCESS)
3218 {
3219 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
3220 ( ALT_DMA_CCR_OPT_SB1
3221 | ALT_DMA_CCR_OPT_SS8
3222 | ALT_DMA_CCR_OPT_SAF
3223 | ALT_DMA_CCR_OPT_SP_DEFAULT
3224 | ALT_DMA_CCR_OPT_SC_DEFAULT
3225 | ALT_DMA_CCR_OPT_DB1
3226 | ALT_DMA_CCR_OPT_DS8
3227 | ALT_DMA_CCR_OPT_DA_DEFAULT
3228 | ALT_DMA_CCR_OPT_DP_DEFAULT
3229 | ALT_DMA_CCR_OPT_DC_DEFAULT
3230 | ALT_DMA_CCR_OPT_ES_DEFAULT
3231 )
3232 );
3233 }
3234
3235 uint32_t sizeleft = size;
3236
3237 while (sizeleft > 0)
3238 {
3239 if (status != ALT_E_SUCCESS)
3240 {
3241 break;
3242 }
3243
3244 uint32_t loopcount = MIN(sizeleft, 256);
3245 sizeleft -= loopcount;
3246
3247 dprintf("DMA[P->M][16550][S]: Creating %lu transfer(s).\n", loopcount);
3248
3249 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
3250 {
3251 status = alt_dma_program_DMALP(program, loopcount);
3252 }
3253 if (status == ALT_E_SUCCESS)
3254 {
3255 status = alt_dma_program_DMAFLUSHP(program, periph);
3256 }
3257 if (status == ALT_E_SUCCESS)
3258 {
3259 status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
3260 }
3261 if (status == ALT_E_SUCCESS)
3262 {
3263 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
3264 }
3265 if (status == ALT_E_SUCCESS)
3266 {
3267 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
3268 }
3269 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
3270 {
3271 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_SINGLE);
3272 }
3273 }
3274
3275 return status;
3276 }
3277
3278 static ALT_STATUS_CODE alt_dma_16550_to_memory_burst(ALT_DMA_PROGRAM_t * program,
3279 ALT_DMA_PERIPH_t periph,
3280 size_t burst_size,
3281 size_t burst_count)
3282 {
3283 ALT_STATUS_CODE status = ALT_E_SUCCESS;
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293 if (status == ALT_E_SUCCESS)
3294 {
3295 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_CCR,
3296 ( ALT_DMA_CCR_OPT_SB16
3297 | ALT_DMA_CCR_OPT_SS8
3298 | ALT_DMA_CCR_OPT_SAF
3299 | ALT_DMA_CCR_OPT_SP_DEFAULT
3300 | ALT_DMA_CCR_OPT_SC_DEFAULT
3301 | ALT_DMA_CCR_OPT_DB16
3302 | ALT_DMA_CCR_OPT_DS8
3303 | ALT_DMA_CCR_OPT_DA_DEFAULT
3304 | ALT_DMA_CCR_OPT_DP_DEFAULT
3305 | ALT_DMA_CCR_OPT_DC_DEFAULT
3306 | ALT_DMA_CCR_OPT_ES_DEFAULT
3307 )
3308 );
3309 }
3310
3311 while (burst_count > 0)
3312 {
3313 if (status != ALT_E_SUCCESS)
3314 {
3315 break;
3316 }
3317
3318 uint32_t loopcount = MIN(burst_count, 256);
3319 burst_count -= loopcount;
3320
3321 dprintf("DMA[P->M][16550][B]: Creating outer %lu inner loop(s).\n", loopcount);
3322
3323
3324
3325 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
3326 {
3327 status = alt_dma_program_DMALP(program, loopcount);
3328 }
3329 if (status == ALT_E_SUCCESS)
3330 {
3331 status = alt_dma_program_DMAFLUSHP(program, periph);
3332 }
3333 if (status == ALT_E_SUCCESS)
3334 {
3335 status = alt_dma_program_DMAWFP(program, periph, ALT_DMA_PROGRAM_INST_MOD_BURST);
3336 }
3337
3338
3339
3340
3341
3342
3343
3344 dprintf("DMA[P->M][16550][B]: Creating inner %u transfer(s).\n", burst_size >> 4);
3345
3346 if (status == ALT_E_SUCCESS)
3347 {
3348 status = alt_dma_program_DMALP(program, burst_size >> 4);
3349 }
3350 if (status == ALT_E_SUCCESS)
3351 {
3352 status = alt_dma_program_DMALD(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3353 }
3354 if (status == ALT_E_SUCCESS)
3355 {
3356 status = alt_dma_program_DMAST(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3357 }
3358 if (status == ALT_E_SUCCESS)
3359 {
3360 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3361 }
3362
3363
3364
3365 if ((status == ALT_E_SUCCESS) && (loopcount > 1))
3366 {
3367 status = alt_dma_program_DMALPEND(program, ALT_DMA_PROGRAM_INST_MOD_BURST);
3368 }
3369
3370
3371 }
3372
3373 return status;
3374 }
3375
3376 static ALT_STATUS_CODE alt_dma_16550_to_memory(ALT_DMA_PROGRAM_t * program,
3377 ALT_DMA_PERIPH_t periph,
3378 ALT_16550_HANDLE_t * handle,
3379 void * dst,
3380 size_t size)
3381 {
3382 ALT_STATUS_CODE status = ALT_E_SUCCESS;
3383
3384 if (status == ALT_E_SUCCESS)
3385 {
3386 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_DAR, (uint32_t)dst);
3387 }
3388 if (status == ALT_E_SUCCESS)
3389 {
3390 status = alt_dma_program_DMAMOV(program, ALT_DMA_PROGRAM_REG_SAR, (uint32_t)ALT_UART_RBR_THR_DLL_ADDR(handle->location));
3391 }
3392
3393
3394
3395 if (ALT_UART_FCR_FIFOE_GET(handle->fcr) != 0)
3396 {
3397 dprintf("DMA[P->M][16550]: FIFOs enabled.\n");
3398
3399
3400
3401
3402
3403 uint32_t rx_size;
3404 uint32_t burst_size;
3405 ALT_16550_FIFO_TRIGGER_RX_t trig_rx;
3406
3407
3408
3409 rx_size = ALT_UART_CPR_FIFO_MOD_GET(alt_read_word(ALT_UART_CPR_ADDR(handle->location))) << 4;
3410
3411
3412 trig_rx = (ALT_16550_FIFO_TRIGGER_RX_t)ALT_UART_FCR_RT_GET(handle->fcr);
3413
3414 switch (trig_rx)
3415 {
3416 case ALT_16550_FIFO_TRIGGER_RX_ANY:
3417 burst_size = 1;
3418 break;
3419 case ALT_16550_FIFO_TRIGGER_RX_QUARTER_FULL:
3420 burst_size = rx_size >> 2;
3421 break;
3422 case ALT_16550_FIFO_TRIGGER_RX_HALF_FULL:
3423 burst_size = rx_size >> 1;
3424 break;
3425 case ALT_16550_FIFO_TRIGGER_RX_ALMOST_FULL:
3426 burst_size = rx_size - 2;
3427 break;
3428 default:
3429
3430 return ALT_E_ERROR;
3431 }
3432
3433 if (burst_size < 16)
3434 {
3435
3436 if (status == ALT_E_SUCCESS)
3437 {
3438 status = alt_dma_16550_to_memory_single(program,
3439 periph,
3440 size);
3441 }
3442 }
3443 else
3444 {
3445 uint32_t sizeleft = size;
3446
3447
3448
3449 dprintf("DMA[P->M][16550]: Untrimmed burst size = %lu.\n", burst_size);
3450 burst_size &= ~0xf;
3451 dprintf("DMA[P->M][16550]: Trimmed burst size = %lu.\n", burst_size);
3452
3453
3454 uint32_t burst_count = 0;
3455
3456 burst_count = sizeleft / burst_size;
3457 sizeleft -= burst_count * burst_size;
3458
3459 if (burst_count == 0)
3460 {
3461
3462 if (status == ALT_E_SUCCESS)
3463 {
3464 status = alt_dma_16550_to_memory_single(program,
3465 periph,
3466 sizeleft);
3467 }
3468 }
3469 else
3470 {
3471
3472 if (status == ALT_E_SUCCESS)
3473 {
3474 status = alt_dma_16550_to_memory_burst(program,
3475 periph,
3476 burst_size,
3477 burst_count);
3478 }
3479
3480
3481 if (status == ALT_E_SUCCESS)
3482 {
3483 status = alt_dma_16550_to_memory_single(program,
3484 periph,
3485 sizeleft);
3486 }
3487
3488 }
3489 }
3490 }
3491 else
3492 {
3493 dprintf("DMA[P->M][16550]: FIFOs disabled.\n");
3494
3495
3496
3497
3498
3499 status = alt_dma_16550_to_memory_single(program,
3500 periph,
3501 size);
3502 }
3503
3504 return status;
3505 }
3506 #endif
3507
3508 ALT_STATUS_CODE alt_dma_memory_to_periph(ALT_DMA_CHANNEL_t channel,
3509 ALT_DMA_PROGRAM_t * program,
3510 ALT_DMA_PERIPH_t dstp,
3511 const void * src,
3512 size_t size,
3513 void * periph_info,
3514 bool send_evt,
3515 ALT_DMA_EVENT_t evt)
3516 {
3517 ALT_STATUS_CODE status = ALT_E_SUCCESS;
3518
3519 if ((size == 0) && (send_evt == false))
3520 {
3521 return status;
3522 }
3523
3524 if (status == ALT_E_SUCCESS)
3525 {
3526 dprintf("DMA[M->P]: Init Program.\n");
3527 status = alt_dma_program_init(program);
3528 }
3529
3530 if ((status == ALT_E_SUCCESS) && (size != 0))
3531 {
3532 switch (dstp)
3533 {
3534 #if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
3535 case ALT_DMA_PERIPH_QSPI_FLASH_TX:
3536 status = alt_dma_memory_to_qspi(program, src, size);
3537 break;
3538 #endif
3539
3540 #if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
3541 case ALT_DMA_PERIPH_UART0_TX:
3542 case ALT_DMA_PERIPH_UART1_TX:
3543 status = alt_dma_memory_to_16550(program, dstp,
3544 (ALT_16550_HANDLE_t *)periph_info, src, size);
3545 break;
3546 #endif
3547
3548 case ALT_DMA_PERIPH_FPGA_0:
3549 case ALT_DMA_PERIPH_FPGA_1:
3550 case ALT_DMA_PERIPH_FPGA_2:
3551 case ALT_DMA_PERIPH_FPGA_3:
3552 case ALT_DMA_PERIPH_FPGA_4:
3553 case ALT_DMA_PERIPH_FPGA_5:
3554 case ALT_DMA_PERIPH_FPGA_6:
3555 case ALT_DMA_PERIPH_FPGA_7:
3556 case ALT_DMA_PERIPH_I2C0_TX:
3557 case ALT_DMA_PERIPH_I2C1_TX:
3558 case ALT_DMA_PERIPH_I2C2_TX:
3559 case ALT_DMA_PERIPH_I2C3_TX:
3560 case ALT_DMA_PERIPH_SPI0_MASTER_TX:
3561 case ALT_DMA_PERIPH_SPI0_SLAVE_TX:
3562 case ALT_DMA_PERIPH_SPI1_MASTER_TX:
3563 case ALT_DMA_PERIPH_SPI1_SLAVE_TX:
3564
3565 default:
3566 status = ALT_E_BAD_ARG;
3567 break;
3568 }
3569 }
3570
3571
3572 if (send_evt)
3573 {
3574 if (status == ALT_E_SUCCESS)
3575 {
3576 dprintf("DMA[M->P]: Adding event.\n");
3577 status = alt_dma_program_DMASEV(program, evt);
3578 }
3579 }
3580
3581
3582 if (status == ALT_E_SUCCESS)
3583 {
3584 status = alt_dma_program_DMAEND(program);
3585 }
3586
3587
3588 if (status != ALT_E_SUCCESS)
3589 {
3590
3591
3592 alt_dma_program_clear(program);
3593 return status;
3594 }
3595
3596
3597
3598 return alt_dma_channel_exec(channel, program);
3599 }
3600
3601 ALT_STATUS_CODE alt_dma_periph_to_memory(ALT_DMA_CHANNEL_t channel,
3602 ALT_DMA_PROGRAM_t * program,
3603 void * dst,
3604 ALT_DMA_PERIPH_t srcp,
3605 size_t size,
3606 void * periph_info,
3607 bool send_evt,
3608 ALT_DMA_EVENT_t evt)
3609 {
3610 ALT_STATUS_CODE status = ALT_E_SUCCESS;
3611
3612 if ((size == 0) && (send_evt == false))
3613 {
3614 return ALT_E_SUCCESS;
3615 }
3616
3617 if (status == ALT_E_SUCCESS)
3618 {
3619 dprintf("DMA[P->M]: Init Program.\n");
3620 status = alt_dma_program_init(program);
3621 }
3622
3623 if ((status == ALT_E_SUCCESS) && (size != 0))
3624 {
3625 switch (srcp)
3626 {
3627 #if ALT_DMA_PERIPH_PROVISION_QSPI_SUPPORT
3628 case ALT_DMA_PERIPH_QSPI_FLASH_RX:
3629 status = alt_dma_qspi_to_memory(program, dst, size);
3630 break;
3631 #endif
3632
3633 #if ALT_DMA_PERIPH_PROVISION_16550_SUPPORT
3634 case ALT_DMA_PERIPH_UART0_RX:
3635 case ALT_DMA_PERIPH_UART1_RX:
3636 status = alt_dma_16550_to_memory(program, srcp,
3637 (ALT_16550_HANDLE_t *)periph_info, dst, size);
3638 break;
3639 #endif
3640
3641 case ALT_DMA_PERIPH_FPGA_0:
3642 case ALT_DMA_PERIPH_FPGA_1:
3643 case ALT_DMA_PERIPH_FPGA_2:
3644 case ALT_DMA_PERIPH_FPGA_3:
3645 case ALT_DMA_PERIPH_FPGA_4:
3646 case ALT_DMA_PERIPH_FPGA_5:
3647 case ALT_DMA_PERIPH_FPGA_6:
3648 case ALT_DMA_PERIPH_FPGA_7:
3649 case ALT_DMA_PERIPH_I2C0_RX:
3650 case ALT_DMA_PERIPH_I2C1_RX:
3651 case ALT_DMA_PERIPH_I2C2_RX:
3652 case ALT_DMA_PERIPH_I2C3_RX:
3653 case ALT_DMA_PERIPH_SPI0_MASTER_RX:
3654 case ALT_DMA_PERIPH_SPI0_SLAVE_RX:
3655 case ALT_DMA_PERIPH_SPI1_MASTER_RX:
3656 case ALT_DMA_PERIPH_SPI1_SLAVE_RX:
3657
3658 default:
3659 status = ALT_E_BAD_ARG;
3660 break;
3661 }
3662 }
3663
3664
3665 if (send_evt)
3666 {
3667 if (status == ALT_E_SUCCESS)
3668 {
3669 dprintf("DMA[P->M]: Adding event.\n");
3670 status = alt_dma_program_DMASEV(program, evt);
3671 }
3672 }
3673
3674
3675 if (status == ALT_E_SUCCESS)
3676 {
3677 status = alt_dma_program_DMAEND(program);
3678 }
3679
3680
3681 if (status != ALT_E_SUCCESS)
3682 {
3683
3684
3685 alt_dma_program_clear(program);
3686 return status;
3687 }
3688
3689
3690
3691 return alt_dma_channel_exec(channel, program);
3692 }
3693
3694
3695
3696 static bool alt_dma_is_init(void)
3697 {
3698 uint32_t permodrst = alt_read_word(ALT_RSTMGR_PERMODRST_ADDR);
3699
3700 if (permodrst & ALT_RSTMGR_PERMODRST_DMA_SET_MSK)
3701 {
3702 return false;
3703 }
3704 else
3705 {
3706 return true;
3707 }
3708 }
3709
3710 ALT_STATUS_CODE alt_dma_ecc_start(void * block, size_t size)
3711 {
3712 if (alt_dma_is_init() == false)
3713 {
3714 return ALT_E_ERROR;
3715 }
3716
3717 if ((uintptr_t)block & (sizeof(uint64_t) - 1))
3718 {
3719 return ALT_E_ERROR;
3720 }
3721
3722
3723
3724 for (int i = 0; i < ARRAY_COUNT(channel_info_array); ++i)
3725 {
3726 if (channel_info_array[i].flag & ALT_DMA_CHANNEL_INFO_FLAG_ALLOCED)
3727 {
3728 ALT_DMA_CHANNEL_STATE_t state;
3729 alt_dma_channel_state_get((ALT_DMA_CHANNEL_t)i, &state);
3730
3731 if (state != ALT_DMA_CHANNEL_STATE_STOPPED)
3732 {
3733 dprintf("DMA[ECC]: Error: Channel %d state is non-stopped (%d).\n", i, (int)state);
3734 return ALT_E_ERROR;
3735 }
3736 }
3737 }
3738
3739
3740
3741
3742
3743 dprintf("DEBUG[DMA][ECC]: Enable ECC in SysMgr.\n");
3744 alt_write_word(ALT_SYSMGR_ECC_DMA_ADDR, ALT_SYSMGR_ECC_DMA_EN_SET_MSK);
3745
3746
3747
3748 dprintf("DEBUG[DMA][ECC]: Clear any pending spurious ECC status in SysMgr.\n");
3749 alt_write_word(ALT_SYSMGR_ECC_DMA_ADDR,
3750 ALT_SYSMGR_ECC_DMA_EN_SET_MSK
3751 | ALT_SYSMGR_ECC_DMA_SERR_SET_MSK
3752 | ALT_SYSMGR_ECC_DMA_DERR_SET_MSK);
3753
3754 return ALT_E_SUCCESS;
3755 }