Skip to content

Commit fc6a121

Browse files
committed
Progress with eMMC/SD Read simple DMA support
1 parent e02d38b commit fc6a121

3 files changed

Lines changed: 117 additions & 56 deletions

File tree

config/examples/polarfire_mpfs250.config

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ WOLFBOOT_LOAD_ADDRESS?=0x8E000000
4848
WOLFBOOT_NO_PARTITIONS=1
4949
CFLAGS_EXTRA+=-DBOOT_PART_A=1
5050
CFLAGS_EXTRA+=-DBOOT_PART_B=2
51-
# Speed up disk partition read (1MB chunks)
52-
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x100000
51+
# Speed up disk partition read (512KB chunks)
52+
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000
5353

5454
# DTS (Device Tree)
5555
WOLFBOOT_LOAD_DTS_ADDRESS?=0x8A000000

hal/mpfs250.c

Lines changed: 113 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static int mmc_set_power(uint32_t voltage)
241241
}
242242
/* should be - 0xf06 */
243243
EMMC_SD_SRS10 = reg;
244-
mmc_delay(DEFAULT_DELAY); /* delay after bus power is applied */
244+
//mmc_delay(DEFAULT_DELAY); /* delay after bus power is applied */
245245
}
246246
return 0;
247247
}
@@ -300,7 +300,7 @@ static uint32_t mmc_set_clock(uint32_t clock_khz)
300300
clock_khz, freq_khz);
301301
#endif
302302

303-
mmc_delay(DEFAULT_DELAY); /* delay after clock changed */
303+
//mmc_delay(DEFAULT_DELAY); /* delay after clock changed */
304304

305305
return freq_khz;
306306
}
@@ -349,27 +349,21 @@ static uint32_t mmc_get_response_type(uint8_t resp_type)
349349
return cmd_reg;
350350
}
351351

352-
#define DEVICE_BUSY 1
353-
int mmc_send_cmd(uint32_t cmd_index, uint32_t cmd_arg, uint8_t resp_type)
352+
static int mmc_send_cmd_internal(uint32_t cmd_type,
353+
uint32_t cmd_index, uint32_t cmd_arg, uint8_t resp_type)
354354
{
355355
int status = 0;
356356
uint32_t cmd_reg;
357-
uint32_t cmd_type = EMMC_SD_SRS03_CMD_NORMAL;
357+
uint32_t timeout = 0x000FFFFF;
358358

359359
#ifdef DEBUG_MMC
360360
wolfBoot_printf("mmc_send_cmd: cmd_index: %d, cmd_arg: %08X, resp_type: %d\n",
361361
cmd_index, cmd_arg, resp_type);
362362
#endif
363363

364-
/* wait for command line to be idle - TODO: Add timeout */
364+
/* wait for command line to be idle */
365365
while ((EMMC_SD_SRS09 & EMMC_SD_SRS09_CICMD) != 0);
366366

367-
/* clear all status interrupts (except current limit, card interrupt/removal/insert) */
368-
EMMC_SD_SRS12 = ~(EMMC_SD_SRS12_ECL |
369-
EMMC_SD_SRS12_CINT |
370-
EMMC_SD_SRS12_CR |
371-
EMMC_SD_SRS12_CIN);
372-
373367
/* set command argument and command transfer registers */
374368
EMMC_SD_SRS02 = cmd_arg;
375369
cmd_reg =
@@ -379,19 +373,41 @@ int mmc_send_cmd(uint32_t cmd_index, uint32_t cmd_arg, uint8_t resp_type)
379373

380374
EMMC_SD_SRS03 = cmd_reg;
381375

382-
/* wait for command complete or error - TODO: Add timeout */
383-
while ((EMMC_SD_SRS12 & (EMMC_SD_SRS12_CC | EMMC_SD_SRS12_EINT)) == 0);
376+
/* wait for command complete or error */
377+
while ((EMMC_SD_SRS12 & (EMMC_SD_SRS12_CC | EMMC_SD_SRS12_TC |
378+
EMMC_SD_SRS12_EINT)) == 0 && --timeout > 0);
379+
380+
if (timeout == 0 || (EMMC_SD_SRS12 & EMMC_SD_SRS12_EINT)) {
381+
wolfBoot_printf("mmc_send_cmd:%s error SRS12: 0x%08X\n",
382+
(timeout == 0) ? " timeout" : "", EMMC_SD_SRS12);
383+
status = -1; /* error */
384+
}
385+
386+
EMMC_SD_SRS12 = EMMC_SD_SRS12_CC; /* clear command complete */
387+
while ((EMMC_SD_SRS09 & EMMC_SD_SRS09_CICMD) != 0);
388+
389+
return status;
390+
}
384391

385-
/* check for device busy */
386-
if (resp_type == EMMC_SD_RESP_R1 || resp_type == EMMC_SD_RESP_R1B) {
387-
uint32_t resp = EMMC_SD_SRS04;
388-
#define CARD_STATUS_READY_FOR_DATA (1U << 8)
389-
if ((resp & CARD_STATUS_READY_FOR_DATA) == 0) {
390-
status = DEVICE_BUSY; /* card is busy */
392+
#define DEVICE_BUSY 1
393+
int mmc_send_cmd(uint32_t cmd_index, uint32_t cmd_arg, uint8_t resp_type)
394+
{
395+
/* send command */
396+
int status = mmc_send_cmd_internal(EMMC_SD_SRS03_CMD_NORMAL, cmd_index,
397+
cmd_arg, resp_type);
398+
if (status == 0) {
399+
/* check for device busy */
400+
if (resp_type == EMMC_SD_RESP_R1 || resp_type == EMMC_SD_RESP_R1B) {
401+
uint32_t resp = EMMC_SD_SRS04;
402+
#define CARD_STATUS_READY_FOR_DATA (1U << 8)
403+
if ((resp & CARD_STATUS_READY_FOR_DATA) == 0) {
404+
status = DEVICE_BUSY; /* card is busy */
405+
}
391406
}
392407
}
393408

394-
/* clear all status interrupts (except current limit, card interrupt/removal/insert) */
409+
/* clear all status interrupts
410+
* (except current limit, card interrupt/removal/insert) */
395411
EMMC_SD_SRS12 = ~(EMMC_SD_SRS12_ECL |
396412
EMMC_SD_SRS12_CINT |
397413
EMMC_SD_SRS12_CR |
@@ -425,7 +441,7 @@ int mmc_power_init_seq(uint32_t voltage)
425441
status = mmc_send_cmd(MMC_CMD0_GO_IDLE, 0, EMMC_SD_RESP_NONE);
426442
}
427443
if (status == 0) {
428-
mmc_delay(DEFAULT_DELAY);
444+
//mmc_delay(DEFAULT_DELAY);
429445

430446
/* send the operating conditions command */
431447
status = mmc_send_cmd(SD_CMD8_SEND_IF_COND, IF_COND_27V_33V,
@@ -458,6 +474,15 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
458474
uint32_t block_count;
459475
uint32_t reg, cmd_reg;
460476

477+
/* get block count (round up) */
478+
block_count = (sz + (EMMC_SD_BLOCK_SIZE - 1)) / EMMC_SD_BLOCK_SIZE;
479+
480+
#ifdef DEBUG_MMC
481+
wolfBoot_printf("mmc_read: cmd_index: %d, block_addr: %08X, dst %p, sz: %d (%d blocks)\n",
482+
cmd_index, block_addr, dst, sz, block_count);
483+
wolfBoot_printf("EMMC_SD IN: SRS12: 0x%08X, SRS09: 0x%08X\n", EMMC_SD_SRS12, EMMC_SD_SRS09);
484+
#endif
485+
461486
/* wait for idle */
462487
status = mmc_wait_busy(0);
463488

@@ -468,8 +493,6 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
468493
/* wait for command and data line busy to clear */
469494
while ((EMMC_SD_SRS09 & (EMMC_SD_SRS09_CICMD | EMMC_SD_SRS09_CIDAT)) != 0);
470495

471-
/* get block count (round up) */
472-
block_count = (sz + (EMMC_SD_BLOCK_SIZE - 1)) / EMMC_SD_BLOCK_SIZE;
473496
/* set transfer block count */
474497
EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT) | sz;
475498

@@ -488,56 +511,93 @@ int mmc_read(uint32_t cmd_index, uint32_t block_addr, uint32_t* dst,
488511
}
489512
else if (cmd_index == MMC_CMD18_READ_MULTIPLE) {
490513
cmd_reg |= EMMC_SD_SRS03_MSBS; /* enable multi-block select */
514+
cmd_reg |= EMMC_SD_SRS03_DMAE; /* enable DMA */
515+
491516
EMMC_SD_SRS01 = (block_count << EMMC_SD_SRS01_BCCT_SHIFT) |
492-
EMMC_SD_BLOCK_SIZE;
517+
EMMC_SD_SRS01_DMA_BUFF_512KB;
518+
519+
/* SDMA mode (for 32-bit transfers) */
520+
EMMC_SD_SRS10 |= EMMC_SD_SRS10_DMA_SDMA;
521+
EMMC_SD_SRS15 |= EMMC_SD_SRS15_HV4E;
522+
EMMC_SD_SRS16 &= ~EMMC_SD_SRS16_A64S;
523+
/* set SDMA destination address */
524+
EMMC_SD_SRS22 = (uint32_t)(uintptr_t)dst;
525+
EMMC_SD_SRS23 = (uint32_t)(((uint64_t)(uintptr_t)dst) >> 32);
493526
}
494527

495-
#ifdef DEBUG_MMC
496-
wolfBoot_printf("mmc_read: cmd_index: %d, block_addr: %08X, dst %p, sz: %d (%d blocks)\n",
497-
cmd_index, block_addr, dst, sz, block_count);
498-
#endif
499-
500528
EMMC_SD_SRS02 = block_addr; /* cmd argument */
501529
EMMC_SD_SRS03 = cmd_reg; /* execute command */
502-
while (sz > 0) {
503-
/* wait for buffer read ready */
504-
while (((reg = EMMC_SD_SRS12) &
505-
(EMMC_SD_SRS12_BRR | EMMC_SD_SRS12_EINT)) == 0);
506-
507-
/* read in buffer - read 4 bytes at a time */
508-
if (reg & EMMC_SD_SRS12_BRR) {
509-
uint32_t i, read_sz = sz;
510-
if (read_sz > EMMC_SD_BLOCK_SIZE) {
511-
read_sz = EMMC_SD_BLOCK_SIZE;
530+
531+
if (cmd_reg & EMMC_SD_SRS03_DMAE) {
532+
while (1) { /* DMA mode */
533+
/* wait for DMA interrupt or error */
534+
while (((reg = EMMC_SD_SRS12) &
535+
(EMMC_SD_SRS12_DMAINT | EMMC_SD_SRS12_TC | EMMC_SD_SRS12_EINT)) == 0);
536+
/* read updated DMA address - engine will increment */
537+
dst = (uint32_t*)(uintptr_t)((((uint64_t)EMMC_SD_SRS23) << 32) | EMMC_SD_SRS22);
538+
if (reg & EMMC_SD_SRS12_DMAINT) {
539+
/* clear interrupt and set new DMA address */
540+
EMMC_SD_SRS12 = EMMC_SD_SRS12_DMAINT;
541+
EMMC_SD_SRS22 = (uint32_t)(uintptr_t)dst;
542+
EMMC_SD_SRS23 = (uint32_t)(((uint64_t)(uintptr_t)dst) >> 32);
512543
}
513-
for (i=0; i<read_sz; i+=4) {
514-
*dst = EMMC_SD_SRS08;
515-
dst++;
544+
else {
545+
break; /* error or transfer complete */
516546
}
517-
sz -= read_sz;
518547
}
519548
}
520-
521-
if (cmd_index == MMC_CMD18_READ_MULTIPLE) {
522-
/* send CMD12 to stop transfer - ignore response */
523-
(void)mmc_send_cmd(MMC_CMD12_STOP_TRANS, (g_rca << SD_RCA_SHIFT),
524-
EMMC_SD_RESP_R1);
549+
else {
550+
while (sz > 0) { /* blocking mode */
551+
/* wait for buffer read ready (or error) */
552+
while (((reg = EMMC_SD_SRS12) &
553+
(EMMC_SD_SRS12_BRR | EMMC_SD_SRS12_EINT)) == 0);
554+
555+
/* read in buffer - read 4 bytes at a time */
556+
if (reg & EMMC_SD_SRS12_BRR) {
557+
uint32_t i, read_sz = sz;
558+
if (read_sz > EMMC_SD_BLOCK_SIZE) {
559+
read_sz = EMMC_SD_BLOCK_SIZE;
560+
}
561+
for (i=0; i<read_sz; i+=4) {
562+
*dst = EMMC_SD_SRS08;
563+
dst++;
564+
}
565+
sz -= read_sz;
566+
}
567+
}
525568
}
526569

527-
/* check for any errors and wait for idle */
570+
/* check for any errors */
528571
reg = EMMC_SD_SRS12;
529-
if ((reg & EMMC_SD_SRS12_ERR_STAT) == 0) {
530-
mmc_delay(0xFFF);
572+
if ((reg & EMMC_SD_SRS12_ERR_STAT) == 0) { /* no errors */
573+
/* if multi-block read, send CMD12 to stop transfer */
574+
if (cmd_index == MMC_CMD18_READ_MULTIPLE) {
575+
(void)mmc_send_cmd_internal(EMMC_SD_SRS03_CMD_ABORT,
576+
MMC_CMD12_STOP_TRANS, (g_rca << SD_RCA_SHIFT),
577+
EMMC_SD_RESP_R1); /* use R1B for write */
578+
}
579+
580+
/* wait for idle */
581+
mmc_delay(0xFF);
531582
status = mmc_wait_busy(0);
532583
}
533584
else {
585+
wolfBoot_printf("mmc_read: error SRS12: 0x%08X\n", reg);
534586
status = -1; /* error */
535587
}
536588

537589
#ifdef DEBUG_MMC
590+
wolfBoot_printf("EMMC_SD OUT: SRS12: 0x%08X, SRS09: 0x%08X\n", EMMC_SD_SRS12, EMMC_SD_SRS09);
538591
wolfBoot_printf("mmc_read: status: %d\n", status);
539592
#endif
540593

594+
/* clear all status interrupts
595+
* (except current limit, card interrupt/removal/insert) */
596+
EMMC_SD_SRS12 = ~(EMMC_SD_SRS12_ECL |
597+
EMMC_SD_SRS12_CINT |
598+
EMMC_SD_SRS12_CR |
599+
EMMC_SD_SRS12_CIN);
600+
541601
return status;
542602
}
543603

@@ -860,7 +920,7 @@ int mmc_init(void)
860920
/* disable card insert interrupt while changing bus width to avoid false triggers */
861921
irq_restore = EMMC_SD_SRS13;
862922
EMMC_SD_SRS13 = (irq_restore & ~EMMC_SD_SRS13_CINT_SE);
863-
mmc_delay(DEFAULT_DELAY);
923+
//mmc_delay(DEFAULT_DELAY);
864924

865925
status = mmc_set_bus_width(4);
866926
}

hal/mpfs250.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#define REGBYTES (1 << 3)
6464

6565
/* Machine Information Registers */
66+
#define CSR_TIME 0xC01
6667
#define CSR_MVENDORID 0xF11
6768
#define CSR_MARCHID 0xF12
6869
#define CSR_MIMPID 0xF13
@@ -862,7 +863,7 @@
862863
#define EMMC_SD_DEBOUNCE_TIME 0x300000U
863864

864865
/* Timeout values */
865-
#define EMMC_SD_DATA_TIMEOUT_US 500000U /* 500ms data timeout */
866+
#define EMMC_SD_DATA_TIMEOUT_US 750000U /* 750ms data timeout */
866867
#define EMMC_SD_CMD_TIMEOUT_MS 3000U /* 3s command timeout */
867868

868869
#define WOLFBOOT_CARDTYPE_SD 1

0 commit comments

Comments
 (0)