Просмотр исходного кода

!522 优化raspberry sd卡读写速度,改为DMA poll方式
Merge pull request !522 from wsljy2021/rt-smart

bernard 3 лет назад
Родитель
Сommit
213599c360

+ 292 - 100
bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.c

@@ -11,16 +11,26 @@
 #include "mbox.h"
 #include "raspi4.h"
 #include "drv_sdio.h"
-
+#include "rthw.h"
+void *virtual_to_physical(void *v)
+{
+    return (void *)((uint64_t)v + PV_OFFSET);
+}
+void *physical_to_virtual(void *p)
+{
+    return (void *)((uint64_t)p - PV_OFFSET);
+}
 static rt_uint32_t mmc_base_clock = 0;
 
-static rt_uint32_t sdCommandTable[] = {
+static sdhci_adma2_descriptor32 adma2_descr_tbl[32] __attribute__((aligned(32)));
+
+static rt_uint32_t sd_command_table[] = {
     SD_CMD_INDEX(0),
     SD_CMD_RESERVED(1),
     SD_CMD_INDEX(2) | SD_RESP_R2,
     SD_CMD_INDEX(3) | SD_RESP_R1,
     SD_CMD_INDEX(4),
-    SD_CMD_RESERVED(5), //SD_CMD_INDEX(5) | SD_RESP_R4,
+    SD_CMD_RESERVED(5), // SD_CMD_INDEX(5) | SD_RESP_R4,
     SD_CMD_INDEX(6) | SD_RESP_R1,
     SD_CMD_INDEX(7) | SD_RESP_R1b,
     SD_CMD_INDEX(8) | SD_RESP_R1,
@@ -41,7 +51,7 @@ static rt_uint32_t sdCommandTable[] = {
     SD_CMD_INDEX(23) | SD_RESP_R1,
     SD_CMD_INDEX(24) | SD_RESP_R1 | SD_DATA_WRITE,
     SD_CMD_INDEX(25) | SD_RESP_R1 | SD_DATA_WRITE | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
-    SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE, //add
+    SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE, // add
     SD_CMD_INDEX(27) | SD_RESP_R1 | SD_DATA_WRITE,
     SD_CMD_INDEX(28) | SD_RESP_R1b,
     SD_CMD_INDEX(29) | SD_RESP_R1b,
@@ -50,13 +60,13 @@ static rt_uint32_t sdCommandTable[] = {
     SD_CMD_INDEX(32) | SD_RESP_R1,
     SD_CMD_INDEX(33) | SD_RESP_R1,
     SD_CMD_RESERVED(34),
-    SD_CMD_INDEX(35) | SD_RESP_R1, //add
-    SD_CMD_INDEX(36) | SD_RESP_R1, //add
+    SD_CMD_INDEX(35) | SD_RESP_R1, // add
+    SD_CMD_INDEX(36) | SD_RESP_R1, // add
     SD_CMD_RESERVED(37),
     SD_CMD_INDEX(38) | SD_RESP_R1b,
-    SD_CMD_INDEX(39) | SD_RESP_R4, //add
-    SD_CMD_INDEX(40) | SD_RESP_R5, //add
-    SD_CMD_INDEX(41) | SD_RESP_R3, //add, mov from harbote
+    SD_CMD_INDEX(39) | SD_RESP_R4, // add
+    SD_CMD_INDEX(40) | SD_RESP_R5, // add
+    SD_CMD_INDEX(41) | SD_RESP_R3, // add, mov from harbote
     SD_CMD_RESERVED(42) | SD_RESP_R1,
     SD_CMD_RESERVED(43),
     SD_CMD_RESERVED(44),
@@ -78,45 +88,155 @@ static rt_uint32_t sdCommandTable[] = {
     SD_CMD_RESERVED(60),
     SD_CMD_RESERVED(61),
     SD_CMD_RESERVED(62),
-    SD_CMD_RESERVED(63)
-};
+    SD_CMD_RESERVED(63)};
+
+static inline void write8(size_t addr, rt_uint8_t value)
+{
+    (*((volatile unsigned char *)(addr))) = value;
+}
+
+static inline rt_uint8_t read8(size_t addr)
+{
+    return (*((volatile unsigned char *)(addr)));
+}
+
+static inline rt_uint16_t read16(size_t addr)
+{
+    return (*((volatile unsigned short *)(addr)));
+}
+
+static inline rt_uint16_t write16(size_t addr, rt_uint16_t value)
+{
+    return (*((volatile unsigned short *)(addr))) = value;
+}
 
 static inline rt_uint32_t read32(size_t addr)
 {
-    return (*((volatile unsigned int*)(addr)));
+    return (*((volatile unsigned int *)(addr)));
 }
 
 static inline void write32(size_t addr, rt_uint32_t value)
 {
-    (*((volatile unsigned int*)(addr))) = value;
+    (*((volatile unsigned int *)(addr))) = value;
 }
 
-rt_err_t sd_int(struct sdhci_pdata_t * pdat, rt_uint32_t mask)
+rt_err_t sd_int(struct sdhci_pdata_t *pdat, rt_uint32_t mask)
 {
     rt_uint32_t r;
     rt_uint32_t m = mask | INT_ERROR_MASK;
     int cnt = 1000000;
     while (!(read32(pdat->virt + EMMC_INTERRUPT) & (m | INT_ERROR_MASK)) && cnt--)
+    {
         DELAY_MICROS(1);
+        if (cnt % 10000 == 0)
+            mmcsd_dbg("wait %d\n", cnt);
+    }
     r = read32(pdat->virt + EMMC_INTERRUPT);
     if (cnt <= 0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT))
     {
         write32(pdat->virt + EMMC_INTERRUPT, r);
-        //qemu maybe can not use sdcard
-        rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n",mask, r, read32(pdat->virt + EMMC_STATUS));
+        // qemu maybe can not use sdcard
+        rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n", mask, r, read32(pdat->virt + EMMC_STATUS));
         return -RT_ETIMEOUT;
     }
     else if (r & INT_ERROR_MASK)
     {
         write32(pdat->virt + EMMC_INTERRUPT, r);
-        rt_kprintf("send cmd/data error %x -> %x\n",r, read32(pdat->virt + EMMC_INTERRUPT));
+        rt_kprintf("send cmd/data error %x -> %x\n", r, read32(pdat->virt + EMMC_INTERRUPT));
         return -RT_ERROR;
     }
     write32(pdat->virt + EMMC_INTERRUPT, mask);
     return RT_EOK;
 }
 
-rt_err_t sd_status(struct sdhci_pdata_t * pdat, unsigned int mask)
+/*****************************************************************************/
+/**
+ *
+ * @brief
+ * API to setup ADMA2 descriptor table for 32-bit DMA
+ *
+ *
+ * @param	instance_ptr is a pointer to the XSdPs instance.
+ * @param	blkcnt - block count.
+ * @param	buff pointer to data buffer.
+ *
+ * @return	None
+ *
+ * @note		None.
+ *
+ ******************************************************************************/
+void sdhci_setup_32adma2_desc_tbl(size_t base_addr, const uint8_t *buff, uint32_t blksize, uint32_t blkcnt)
+{
+    uint32_t total_desc_lines;
+    uint32_t desc_num;
+
+    void *adma2_descrtbl_p = virtual_to_physical(adma2_descr_tbl);
+    const uint8_t *buff_p = (const uint8_t *)virtual_to_physical(buff);
+
+    /* Setup ADMA2 - Write descriptor table and point ADMA SAR to it */
+
+    if ((blkcnt * blksize) < SDHCI_DESC_MAX_LENGTH)
+    {
+        total_desc_lines = 1U;
+    }
+    else
+    {
+        total_desc_lines = ((blkcnt * blksize) / SDHCI_DESC_MAX_LENGTH);
+        if (((blkcnt * blksize) % SDHCI_DESC_MAX_LENGTH) != 0U)
+        {
+            total_desc_lines += 1U;
+        }
+    }
+
+    for (desc_num = 0U; desc_num < (total_desc_lines - 1); desc_num++)
+    {
+        adma2_descr_tbl[desc_num].address =
+            (uint32_t)((uintptr_t)buff_p + (desc_num * SDHCI_DESC_MAX_LENGTH));
+        adma2_descr_tbl[desc_num].attribute =
+            SDHCI_DESC_TRAN | SDHCI_DESC_VALID | SDHCI_DESC_INT;
+        adma2_descr_tbl[desc_num].length = 0U;
+        rt_kprintf("Adma2_desc: %x\n", adma2_descr_tbl[desc_num].address);
+    }
+    adma2_descr_tbl[total_desc_lines - 1].address = (uint32_t)((uintptr_t)buff_p + (desc_num * SDHCI_DESC_MAX_LENGTH));
+
+    adma2_descr_tbl[total_desc_lines - 1].attribute =
+        SDHCI_DESC_TRAN | SDHCI_DESC_END | SDHCI_DESC_VALID | SDHCI_DESC_INT;
+
+    adma2_descr_tbl[total_desc_lines - 1].length =
+        (uint16_t)((blkcnt * blksize) - (uint32_t)(desc_num * SDHCI_DESC_MAX_LENGTH));
+
+    write32(base_addr + EMMC_ADMA_SAR_OFFSET, (uint32_t)((uintptr_t)adma2_descrtbl_p & (uint32_t)~0x0));
+    rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, adma2_descr_tbl, sizeof(sdhci_adma2_descriptor32) * 32U);
+}
+
+/*****************************************************************************/
+/**
+ * @brief
+ * This function is used to do the DMA transfer to or from SD card.
+ *
+ * @param	instance_ptr is a pointer to the instance to be worked on.
+ * @param	blkcnt - Block count passed by the user.
+ * @param	blksize - Block size passed by the user.
+ * @param	buff - Pointer to the data buffer for a DMA transfer.
+ *
+ * @return
+ * 		- XST_SUCCESS if initialization was successful
+ * 		- XST_FAILURE if failure - could be because another transfer
+ * 			is in progress or command or data inhibit is set
+ *
+ ******************************************************************************/
+void xsdps_setup_rw_dma(size_t base_addr, uint8_t *buff)
+{
+    uint32_t blksize;
+    uint32_t blkcnt;
+
+    blksize = (uint32_t)read16(base_addr + EMMC_BLKSIZECNT) & SDHCI_BLK_SIZE_MASK;
+    blkcnt = (uint32_t)read16(base_addr + EMMC_BLKCOUNT) & SDHCI_BLK_CNT_MASK;
+    sdhci_setup_32adma2_desc_tbl(base_addr, buff, blksize, blkcnt);
+    rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, buff, blkcnt * blksize);
+}
+
+rt_err_t sd_status(struct sdhci_pdata_t *pdat, unsigned int mask)
 {
     int cnt = 500000;
     while ((read32(pdat->virt + EMMC_STATUS) & mask) && !(read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK) && cnt--)
@@ -127,33 +247,52 @@ rt_err_t sd_status(struct sdhci_pdata_t * pdat, unsigned int mask)
     }
     else if (read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK)
     {
-        return  -RT_ERROR;
-    } 
+        return -RT_ERROR;
+    }
 
     return RT_EOK;
 }
 
-static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd)
+static rt_err_t raspi_transfer_command(struct sdhci_pdata_t *pdat, struct sdhci_cmd_t *cmd)
 {
     rt_uint32_t cmdidx;
     rt_err_t ret = RT_EOK;
     ret = sd_status(pdat, SR_CMD_INHIBIT);
     if (ret)
     {
-        rt_kprintf("ERROR: EMMC busy %d\n", ret);
+        rt_kprintf("ERROR: EMMC cmd busy %d\n", ret);
         return ret;
     }
 
-    cmdidx = sdCommandTable[cmd->cmdidx];
+    cmdidx = sd_command_table[cmd->cmdidx];
     if (cmdidx == 0xFFFFFFFF)
         return -RT_EINVAL;
     if (cmd->datarw == DATA_READ)
+    {
         cmdidx |= SD_DATA_READ;
+        cmdidx |= SDHCI_TM_DMA_EN_MASK;
+        cmdidx |= (SD_CMD_IXCHK_EN | SD_CMD_CRCCHK_EN | SD_CMD_BLKCNT_EN);
+        if (cmd->cmdidx == READ_MULTIPLE_BLOCK)
+        {
+            cmdidx |= (SD_CMD_AUTO_CMD_EN_CMD23 | SDHCI_TM_MUL_SIN_BLK_SEL_MASK);
+        }
+    }
     if (cmd->datarw == DATA_WRITE)
+    {
         cmdidx |= SD_DATA_WRITE;
-    mmcsd_dbg("transfer cmd %x(%d) %x %x\n", cmdidx, cmd->cmdidx, cmd->cmdarg, read32(pdat->virt + EMMC_INTERRUPT));
-    write32(pdat->virt + EMMC_INTERRUPT,read32(pdat->virt + EMMC_INTERRUPT));
+        cmdidx |= SDHCI_TM_DMA_EN_MASK;
+        cmdidx |= (SD_CMD_IXCHK_EN | SD_CMD_CRCCHK_EN | SD_CMD_BLKCNT_EN);
+        if (cmd->cmdidx == WRITE_MULTIPLE_BLOCK)
+        {
+            cmdidx |= (SD_CMD_AUTO_CMD_EN_CMD23 | SDHCI_TM_MUL_SIN_BLK_SEL_MASK);
+        }
+    }
+    write8(pdat->virt + EMMC_TIMECTL, 0xEU);
     write32(pdat->virt + EMMC_ARG1, cmd->cmdarg);
+
+    write16(pdat->virt + EMMC_INTERRUPT, SDHCI_NORM_INTR_ALL_MASK);
+    write16(pdat->virt + EMMC_ERR_INTERRUPT, SDHCI_ERROR_INTR_ALL_MASK);
+
     write32(pdat->virt + EMMC_CMDTM, cmdidx);
     if (cmd->cmdidx == SD_APP_OP_COND)
         DELAY_MICROS(1000);
@@ -177,10 +316,10 @@ static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci
             resp[3] = read32(pdat->virt + EMMC_RESP3);
             if (cmd->resptype == RESP_R2)
             {
-                cmd->response[0] = resp[3]<<8 |((resp[2]>>24)&0xff);
-                cmd->response[1] = resp[2]<<8 |((resp[1]>>24)&0xff);
-                cmd->response[2] = resp[1]<<8 |((resp[0]>>24)&0xff);
-                cmd->response[3] = resp[0]<<8 ;
+                cmd->response[0] = resp[3] << 8 | ((resp[2] >> 24) & 0xff);
+                cmd->response[1] = resp[2] << 8 | ((resp[1] >> 24) & 0xff);
+                cmd->response[2] = resp[1] << 8 | ((resp[0] >> 24) & 0xff);
+                cmd->response[3] = resp[0] << 8;
             }
             else
             {
@@ -193,11 +332,12 @@ static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci
         else
             cmd->response[0] = read32(pdat->virt + EMMC_RESP0);
     }
-    mmcsd_dbg("response: %x: %x %x %x %x (%x, %x)\n", cmd->resptype, cmd->response[0], cmd->response[1], cmd->response[2], cmd->response[3], read32(pdat->virt + EMMC_STATUS),read32(pdat->virt + EMMC_INTERRUPT));
+    mmcsd_dbg("response: %x: %x %x %x %x (%x, %x)\n", cmd->resptype, cmd->response[0], cmd->response[1], cmd->response[2], cmd->response[3], read32(pdat->virt + EMMC_STATUS), read32(pdat->virt + EMMC_INTERRUPT));
+    mmcsd_dbg("response: %x: %x \n", cmd->resptype, cmd->response[0]);
     return ret;
 }
 
-static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+static rt_err_t read_bytes(struct sdhci_pdata_t *pdat, rt_uint32_t *buf, rt_uint32_t blkcount, rt_uint32_t blksize)
 {
     int c = 0;
     rt_err_t ret;
@@ -206,10 +346,10 @@ static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_ui
     {
         if ((ret = sd_int(pdat, INT_READ_RDY)))
         {
-            rt_kprintf("timeout happens when reading block %d\n",c);
+            rt_kprintf("timeout happens when reading block %d\n", c);
             return ret;
         }
-        for (d=0; d < blksize / 4; d++)
+        for (d = 0; d < blksize / 4; d++)
             if (read32(pdat->virt + EMMC_STATUS) & SR_READ_AVAILABLE)
                 buf[d] = read32(pdat->virt + EMMC_DATA);
         c++;
@@ -218,7 +358,7 @@ static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_ui
     return RT_EOK;
 }
 
-static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+static rt_err_t write_bytes(struct sdhci_pdata_t *pdat, rt_uint32_t *buf, rt_uint32_t blkcount, rt_uint32_t blksize)
 {
     int c = 0;
     rt_err_t ret;
@@ -229,7 +369,7 @@ static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_u
         {
             return ret;
         }
-        for (d=0; d < blksize / 4; d++)
+        for (d = 0; d < blksize / 4; d++)
             write32(pdat->virt + EMMC_DATA, buf[d]);
         c++;
         buf += blksize / 4;
@@ -242,13 +382,13 @@ static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_u
     return RT_EOK;
 }
 
-static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
+static rt_err_t raspi_transfer_data(struct sdhci_pdata_t *pdat, struct sdhci_cmd_t *cmd, struct sdhci_data_t *dat)
 {
     rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz);
     rt_err_t ret = sd_status(pdat, SR_DAT_INHIBIT);
     if (ret)
     {
-        rt_kprintf("ERROR: EMMC busy\n");
+        rt_kprintf("ERROR: EMMC data busy\n");
         return ret;
     }
     if (dat->blkcnt > 1)
@@ -258,10 +398,11 @@ static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cm
         newcmd.cmdarg = dat->blkcnt;
         newcmd.resptype = RESP_R1;
         ret = raspi_transfer_command(pdat, &newcmd);
-        if (ret) return ret;
+        if (ret)
+            return ret;
     }
 
-    if(dlen < 512)
+    if (dlen < 512)
     {
         write32(pdat->virt + EMMC_BLKSIZECNT, dlen | 1 << 16);
     }
@@ -269,28 +410,37 @@ static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cm
     {
         write32(pdat->virt + EMMC_BLKSIZECNT, 512 | (dat->blkcnt) << 16);
     }
+
     if (dat->flag & DATA_DIR_READ)
     {
         cmd->datarw = DATA_READ;
+        xsdps_setup_rw_dma(pdat->virt, dat->buf);
         ret = raspi_transfer_command(pdat, cmd);
-        if (ret) return ret;
-        mmcsd_dbg("read_block %d, %d\n", dat->blkcnt, dat->blksz );
-        ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+        if (ret)
+            return ret;
+        rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, dat->buf, dat->blkcnt * dat->blksz);
+        mmcsd_dbg("read_block %d, %d\n", dat->blkcnt, dat->blksz);
     }
     else if (dat->flag & DATA_DIR_WRITE)
     {
         cmd->datarw = DATA_WRITE;
+        xsdps_setup_rw_dma(pdat->virt, dat->buf);
         ret = raspi_transfer_command(pdat, cmd);
-        if (ret) return ret;
-        mmcsd_dbg("write_block %d, %d", dat->blkcnt, dat->blksz );
-        ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+        if (ret)
+            return ret;
+        mmcsd_dbg("write_block %d, %d\n", dat->blkcnt, dat->blksz);
+    }
+    ret = sd_int(pdat, INT_DATA_DONE);
+    if (ret)
+    {
+        return ret;
     }
     return ret;
 }
 
-static rt_err_t sdhci_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
+static rt_err_t sdhci_transfer(struct sdhci_t *sdhci, struct sdhci_cmd_t *cmd, struct sdhci_data_t *dat)
 {
-    struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)sdhci->priv;
     if (!dat)
         return raspi_transfer_command(pdat, cmd);
 
@@ -309,7 +459,7 @@ static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *re
 
     cmd.cmdidx = req->cmd->cmd_code;
     cmd.cmdarg = req->cmd->arg;
-    cmd.resptype =resp_type(req->cmd);
+    cmd.resptype = resp_type(req->cmd);
     if (req->data)
     {
         dat.buf = (rt_uint8_t *)req->data->buf;
@@ -333,7 +483,7 @@ static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *re
     {
         stop.cmdidx = req->stop->cmd_code;
         stop.cmdarg = req->stop->arg;
-        cmd.resptype =resp_type(req->stop);
+        cmd.resptype = resp_type(req->stop);
         req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
     }
 
@@ -345,40 +495,43 @@ rt_int32_t mmc_card_status(struct rt_mmcsd_host *host)
     return 0;
 }
 
-static rt_err_t sdhci_detect(struct sdhci_t * sdhci)
+static rt_err_t sdhci_detect(struct sdhci_t *sdhci)
 {
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)sdhci->priv;
+    // sdhci_version
+    sdhci->sdhci_version4 = read16(pdat->virt + EMMC_MY_CONTROL2) & SDHCI_CTL2_SHCVER_MASK;
+    sdhci->dma_64bit_addr = read16(pdat->virt + EMMC_MY_CONTROL2) & SDHCI_CTL2_BITADDR_MASK;
     return RT_EOK;
 }
 
-static rt_err_t sdhci_setwidth(struct sdhci_t * sdhci, rt_uint32_t width)
+static rt_err_t sdhci_setwidth(struct sdhci_t *sdhci, rt_uint32_t width)
 {
     rt_uint32_t temp = 0;
-    struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)sdhci->priv;
     if (width == MMCSD_BUS_WIDTH_4)
     {
         temp = read32((pdat->virt + EMMC_CONTROL0));
         temp |= C0_HCTL_HS_EN;
-        temp |= C0_HCTL_DWITDH;   // always use 4 data lines:
+        temp |= C0_HCTL_DWITDH; // always use 4 data lines:
         write32((pdat->virt + EMMC_CONTROL0), temp);
     }
     return RT_EOK;
 }
 
-
-static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer ,rt_uint32_t base_clock, rt_uint32_t target_rate)
+static uint32_t sd_get_clock_divider(rt_uint32_t sd_host_ver, rt_uint32_t base_clock, rt_uint32_t target_rate)
 {
     rt_uint32_t targetted_divisor = 0;
     rt_uint32_t freq_select = 0;
     rt_uint32_t upper_bits = 0;
     rt_uint32_t ret = 0;
 
-    if(target_rate > base_clock)
+    if (target_rate > base_clock)
         targetted_divisor = 1;
     else
     {
         targetted_divisor = base_clock / target_rate;
         rt_uint32_t mod = base_clock % target_rate;
-        if(mod)
+        if (mod)
             targetted_divisor--;
     }
 
@@ -391,14 +544,14 @@ static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer ,rt_uint32_t base_clo
 
     // Find the first bit set
     int divisor = -1;
-    for(int first_bit = 31; first_bit >= 0; first_bit--)
+    for (int first_bit = 31; first_bit >= 0; first_bit--)
     {
         rt_uint32_t bit_test = (1 << first_bit);
-        if(targetted_divisor & bit_test)
+        if (targetted_divisor & bit_test)
         {
             divisor = first_bit;
             targetted_divisor &= ~bit_test;
-            if(targetted_divisor)
+            if (targetted_divisor)
             {
                 // The divisor is not a power-of-two, increase it
                 divisor++;
@@ -407,15 +560,15 @@ static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer ,rt_uint32_t base_clo
         }
     }
 
-    if(divisor == -1)
+    if (divisor == -1)
         divisor = 31;
-    if(divisor >= 32)
+    if (divisor >= 32)
         divisor = 31;
 
-    if(divisor != 0)
+    if (divisor != 0)
         divisor = (1 << (divisor - 1));
 
-    if(divisor >= 0x400)
+    if (divisor >= 0x400)
         divisor = 0x3ff;
 
     freq_select = divisor & 0xff;
@@ -425,43 +578,43 @@ static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer ,rt_uint32_t base_clo
     return ret;
 }
 
-static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock)
+static rt_err_t sdhci_setclock(struct sdhci_t *sdhci, rt_uint32_t clock)
 {
     rt_uint32_t temp = 0;
-    rt_uint32_t sdHostVer = 0;
+    rt_uint32_t sd_host_ver = 0;
     int count = 100000;
-    struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)(sdhci->priv);
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)(sdhci->priv);
 
     while ((read32(pdat->virt + EMMC_STATUS) & (SR_CMD_INHIBIT | SR_DAT_INHIBIT)) && (--count))
         DELAY_MICROS(1);
     if (count <= 0)
     {
-        rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n",read32(pdat->virt + EMMC_STATUS));
+        rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n", read32(pdat->virt + EMMC_STATUS));
         return RT_ERROR;
     }
 
     // Switch clock off.
     temp = read32((pdat->virt + EMMC_CONTROL1));
     temp &= ~C1_CLK_EN;
-    write32((pdat->virt + EMMC_CONTROL1),temp);
+    write32((pdat->virt + EMMC_CONTROL1), temp);
     DELAY_MICROS(10);
     // Request the new clock setting and enable the clock
     temp = read32(pdat->virt + EMMC_SLOTISR_VER);
-    sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
-    int cdiv = sd_get_clock_divider(sdHostVer, mmc_base_clock, clock);
+    sd_host_ver = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
+    int cdiv = sd_get_clock_divider(sd_host_ver, mmc_base_clock, clock);
     temp = read32((pdat->virt + EMMC_CONTROL1));
-    temp |= 1;    
+    temp |= 1;
     temp |= cdiv;
     temp |= (7 << 16);
 
     temp = (temp & 0xffff003f) | cdiv;
-    write32((pdat->virt + EMMC_CONTROL1),temp);
+    write32((pdat->virt + EMMC_CONTROL1), temp);
     DELAY_MICROS(10);
 
     // Enable the clock.
     temp = read32(pdat->virt + EMMC_CONTROL1);
     temp |= C1_CLK_EN;
-    write32((pdat->virt + EMMC_CONTROL1),temp);
+    write32((pdat->virt + EMMC_CONTROL1), temp);
     DELAY_MICROS(10);
 
     // Wait for clock to be stable.
@@ -473,44 +626,51 @@ static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock)
         rt_kprintf("EMMC: ERROR: failed to get stable clock %d.\n", clock);
         return RT_ERROR;
     }
-
     mmcsd_dbg("set stable clock %d.\n", clock);
     return RT_EOK;
 }
 
 static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
 {
-    struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data;
+    struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
     sdhci_setclock(sdhci, io_cfg->clock);
     sdhci_setwidth(sdhci, io_cfg->bus_width);
 }
 
-static const struct rt_mmcsd_host_ops ops =
+static rt_uint32_t mmc_get_adma_ver(struct rt_mmcsd_host *host)
 {
-    mmc_request_send,
-    mmc_set_iocfg,
-    RT_NULL,
-    RT_NULL,
+    struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
+    struct sdhci_pdata_t *pdat = (struct sdhci_pdata_t *)(sdhci->priv);
+    return read32(pdat->virt + EMMC_CAPABILITIES_0);
+}
+
+static const struct rt_mmcsd_host_ops ops =
+    {
+        mmc_request_send,
+        mmc_set_iocfg,
+        RT_NULL,
+        RT_NULL,
+        mmc_get_adma_ver,
 };
 
-static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
+static rt_err_t reset_emmc(struct sdhci_pdata_t *pdat)
 {
     rt_uint32_t control1;
 
-    //Reset the controller
+    // Reset the controller
     control1 = read32((pdat->virt + EMMC_CONTROL1));
     control1 |= (1 << 24);
     // Disable clock
     control1 &= ~(1 << 2);
     control1 &= ~(1 << 0);
-    //temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
-    write32((pdat->virt + EMMC_CONTROL1),control1);
+    // temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
+    write32((pdat->virt + EMMC_CONTROL1), control1);
     int cnt = 10000;
     do
     {
         DELAY_MICROS(10);
         cnt = cnt - 1;
-        if(cnt == 0)
+        if (cnt == 0)
         {
             break;
         }
@@ -522,8 +682,6 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
     write32(pdat->virt + EMMC_CONTROL0, control0);
 
     rt_thread_delay(100);
-    //usleep(2000);
-
 
     // Check for a valid card
     mmcsd_dbg("EMMC: checking for an inserted card\n");
@@ -532,7 +690,7 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
     {
         DELAY_MICROS(10);
         cnt = cnt - 1;
-        if(cnt == 0)
+        if (cnt == 0)
         {
             break;
         }
@@ -540,7 +698,7 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
 
     rt_uint32_t status_reg = read32(pdat->virt + EMMC_STATUS);
 
-    if((status_reg & (1 << 16)) == 0)
+    if ((status_reg & (1 << 16)) == 0)
     {
         rt_kprintf("EMMC: no card inserted\n");
         return -1;
@@ -554,7 +712,7 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
     write32(pdat->virt + EMMC_CONTROL2, 0);
     // Get the base clock rate //12
     mmc_base_clock = bcm271x_mbox_clock_get_rate(EMMC_CLK_ID);
-    if(mmc_base_clock == 0)
+    if (mmc_base_clock == 0)
     {
         rt_kprintf("EMMC: assuming clock rate to be 100MHz\n");
         mmc_base_clock = 100000000;
@@ -563,8 +721,28 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
     return RT_EOK;
 }
 
+/*****************************************************************************/
+/**
+ * @brief
+ * This function is used configure the Interrupts.
+ *
+ * @param	instance_ptr is a pointer to the instance to be worked on.
+ *
+ * @return	None
+ *
+ ******************************************************************************/
+void sdhci_config_interrupt(struct sdhci_pdata_t *pdat)
+{
+    /* Enable all interrupt status except card interrupt initially */
+    write16(pdat->virt + EMMC_NOR_IRTR_STS_EN_OFFSET, SDHCI_NORM_INTR_ALL_MASK);
+    write16(pdat->virt + EMMC_ERR_INTR_STS_EN_OFFSET, SDHCI_ERROR_INTR_ALL_MASK);
+
+    write16(pdat->virt + EMMC_IRPT_EN, 0x13b);
+    write16(pdat->virt + SDHCI_ERR_INTR_SIG_EN_OFFSET, 0x13b);
+}
+
 #ifdef RT_MMCSD_DBG
-void dump_registers(struct sdhci_pdata_t * pdat)
+void dump_registers(struct sdhci_pdata_t *pdat)
 {
     rt_kprintf("EMMC registers:");
     int i = EMMC_ARG2;
@@ -586,9 +764,9 @@ void dump_registers(struct sdhci_pdata_t * pdat)
 int raspi_sdmmc_init(void)
 {
     size_t virt;
-    struct rt_mmcsd_host * host = RT_NULL;
-    struct sdhci_pdata_t * pdat = RT_NULL;
-    struct sdhci_t * sdhci = RT_NULL;
+    struct rt_mmcsd_host *host = RT_NULL;
+    struct sdhci_pdata_t *pdat = RT_NULL;
+    struct sdhci_t *sdhci = RT_NULL;
 
 #ifdef BSP_USING_SDIO0
     host = mmcsd_alloc_host();
@@ -622,6 +800,14 @@ int raspi_sdmmc_init(void)
     sdhci->setclock = sdhci_setclock;
     sdhci->transfer = sdhci_transfer;
     sdhci->priv = pdat;
+    sdhci->detect(sdhci);
+
+    /* Enable ADMA2 in 32bit mode. */
+    rt_uint8_t tmp = read8(pdat->virt + EMMC_CONTROL0);
+    write8(pdat->virt + EMMC_CONTROL0, 0x10 | tmp);
+    tmp = read8(pdat->virt + EMMC_HOST_CONTROL2);
+    write8(pdat->virt + EMMC_HOST_CONTROL2, 0x4000 | tmp);
+
     host->ops = &ops;
     host->freq_min = 400000;
     host->freq_max = 50000000;
@@ -630,11 +816,11 @@ int raspi_sdmmc_init(void)
     host->max_seg_size = 2048;
     host->max_dma_segs = 10;
     host->max_blk_size = 512;
-    host->max_blk_count = 1;
+    host->max_blk_count = 16;
 
     host->private_data = sdhci;
-    write32((pdat->virt + EMMC_IRPT_EN),0xffffffff);
-    write32((pdat->virt + EMMC_IRPT_MASK),0xffffffff);
+
+    sdhci_config_interrupt(pdat);
 #ifdef RT_MMCSD_DBG
     dump_registers(pdat);
 #endif
@@ -642,9 +828,15 @@ int raspi_sdmmc_init(void)
 #endif
     return RT_EOK;
 err:
-    if (host)  rt_free(host);
-    if (sdhci) rt_free(sdhci);
+    if (host)
+    {
+        rt_free(host);
+    }
 
+    if (sdhci)
+    {
+        rt_free(sdhci);
+    }
     return -RT_EIO;
 }
 

+ 256 - 183
bsp/raspberry-pi/raspi4-64/drivers/drv_sdio.h

@@ -19,45 +19,45 @@
 #include "raspi4.h"
 
 /* Struct for Intrrrupt Information */
-#define SDXC_CmdDone       BIT(0)
-#define SDXC_DataDone      BIT(1)
-#define SDXC_BlockGap      BIT(2)
-#define SDXC_WriteRdy      BIT(4)
-#define SDXC_ReadRdy       BIT(5)
-#define SDXC_Card          BIT(8)
-#define SDXC_Retune        BIT(12)
-#define SDXC_BootAck       BIT(13)
-#define SDXC_EndBoot       BIT(14)
-#define SDXC_Err           BIT(15)
-#define SDXC_CTOErr        BIT(16)
-#define SDXC_CCRCErr       BIT(17)
-#define SDXC_CENDErr       BIT(18)
-#define SDXC_CBADErr       BIT(19)
-#define SDXC_DTOErr        BIT(20)
-#define SDXC_DCRCErr       BIT(21)
-#define SDXC_DENDErr       BIT(22)
-#define SDXC_ACMDErr       BIT(24)
-
-#define SDXC_BLKCNT_EN          BIT(1)
-#define SDXC_AUTO_CMD12_EN      BIT(2)
-#define SDXC_AUTO_CMD23_EN      BIT(3)
-#define SDXC_DAT_DIR            BIT(4)   //from card to host
-#define SDXC_MULTI_BLOCK        BIT(5)
-#define SDXC_CMD_RSPNS_136      BIT(16)
-#define SDXC_CMD_RSPNS_48       BIT(17)
-#define SDXC_CMD_RSPNS_48busy   BIT(16)|BIT(17)
-#define SDXC_CHECK_CRC_CMD      BIT(19)
-#define SDXC_CMD_IXCHK_EN       BIT(20)
-#define SDXC_CMD_ISDATA         BIT(21)
-#define SDXC_CMD_SUSPEND        BIT(22)
-#define SDXC_CMD_RESUME         BIT(23)
-#define SDXC_CMD_ABORT          BIT(23)|BIT(22)
-
-#define SDXC_CMD_INHIBIT        BIT(0)
-#define SDXC_DAT_INHIBIT        BIT(1)
-#define SDXC_DAT_ACTIVE         BIT(2)
-#define SDXC_WRITE_TRANSFER     BIT(8)
-#define SDXC_READ_TRANSFER      BIT(9)
+#define SDXC_CmdDone BIT(0)
+#define SDXC_DataDone BIT(1)
+#define SDXC_BlockGap BIT(2)
+#define SDXC_WriteRdy BIT(4)
+#define SDXC_ReadRdy BIT(5)
+#define SDXC_Card BIT(8)
+#define SDXC_Retune BIT(12)
+#define SDXC_BootAck BIT(13)
+#define SDXC_EndBoot BIT(14)
+#define SDXC_Err BIT(15)
+#define SDXC_CTOErr BIT(16)
+#define SDXC_CCRCErr BIT(17)
+#define SDXC_CENDErr BIT(18)
+#define SDXC_CBADErr BIT(19)
+#define SDXC_DTOErr BIT(20)
+#define SDXC_DCRCErr BIT(21)
+#define SDXC_DENDErr BIT(22)
+#define SDXC_ACMDErr BIT(24)
+
+#define SDXC_BLKCNT_EN BIT(1)
+#define SDXC_AUTO_CMD12_EN BIT(2)
+#define SDXC_AUTO_CMD23_EN BIT(3)
+#define SDXC_DAT_DIR BIT(4) // from card to host
+#define SDXC_MULTI_BLOCK BIT(5)
+#define SDXC_CMD_RSPNS_136 BIT(16)
+#define SDXC_CMD_RSPNS_48 BIT(17)
+#define SDXC_CMD_RSPNS_48busy BIT(16) | BIT(17)
+#define SDXC_CHECK_CRC_CMD BIT(19)
+#define SDXC_CMD_IXCHK_EN BIT(20)
+#define SDXC_CMD_ISDATA BIT(21)
+#define SDXC_CMD_SUSPEND BIT(22)
+#define SDXC_CMD_RESUME BIT(23)
+#define SDXC_CMD_ABORT BIT(23) | BIT(22)
+
+#define SDXC_CMD_INHIBIT BIT(0)
+#define SDXC_DAT_INHIBIT BIT(1)
+#define SDXC_DAT_ACTIVE BIT(2)
+#define SDXC_WRITE_TRANSFER BIT(8)
+#define SDXC_READ_TRANSFER BIT(9)
 
 struct sdhci_cmd_t
 {
@@ -72,7 +72,7 @@ struct sdhci_cmd_t
 
 struct sdhci_data_t
 {
-    rt_uint8_t * buf;
+    rt_uint8_t *buf;
     rt_uint32_t flag;
     rt_uint32_t blksz;
     rt_uint32_t blkcnt;
@@ -80,18 +80,24 @@ struct sdhci_data_t
 
 struct sdhci_t
 {
-    char * name;
+    char *name;
     rt_uint32_t voltages;
     rt_uint32_t width;
     rt_uint32_t clock;
     rt_err_t removeable;
-    void * sdcard; 
+    void *sdcard;
+    int dma_64bit_addr;
+    int sdhci_version4;
+    int support_adma2;
+    int support_adma3;
+    int support_v4addr64;
+    sdhci_adma2_descriptor32 *adma32dec;
 
-    rt_err_t (*detect)(struct sdhci_t * sdhci);
-    rt_err_t (*setwidth)(struct sdhci_t * sdhci, rt_uint32_t width);
-    rt_err_t (*setclock)(struct sdhci_t * sdhci, rt_uint32_t clock);
-    rt_err_t (*transfer)(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat);
-    void * priv;
+    rt_err_t (*detect)(struct sdhci_t *sdhci);
+    rt_err_t (*setwidth)(struct sdhci_t *sdhci, rt_uint32_t width);
+    rt_err_t (*setclock)(struct sdhci_t *sdhci, rt_uint32_t clock);
+    rt_err_t (*transfer)(struct sdhci_t *sdhci, struct sdhci_cmd_t *cmd, struct sdhci_data_t *dat);
+    void *priv;
 };
 
 struct sdhci_pdata_t
@@ -100,154 +106,221 @@ struct sdhci_pdata_t
 };
 
 // EMMC command flags
-#define CMD_TYPE_NORMAL  (0x00000000)
+#define CMD_TYPE_NORMAL (0x00000000)
 #define CMD_TYPE_SUSPEND (0x00400000)
-#define CMD_TYPE_RESUME  (0x00800000)
-#define CMD_TYPE_ABORT   (0x00c00000)
-#define CMD_IS_DATA      (0x00200000)
-#define CMD_IXCHK_EN     (0x00100000)
-#define CMD_CRCCHK_EN    (0x00080000)
-#define CMD_RSPNS_NO     (0x00000000)
-#define CMD_RSPNS_136    (0x00010000)
-#define CMD_RSPNS_48     (0x00020000)
-#define CMD_RSPNS_48B    (0x00030000)
-#define TM_MULTI_BLOCK   (0x00000020)
-#define TM_DAT_DIR_HC    (0x00000000)
-#define TM_DAT_DIR_CH    (0x00000010)
-#define TM_AUTO_CMD23    (0x00000008)
-#define TM_AUTO_CMD12    (0x00000004)
-#define TM_BLKCNT_EN     (0x00000002)
-#define TM_MULTI_DATA    (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
-
-#define RCA_NO              (1)
-#define RCA_YES             (2)
+#define CMD_TYPE_RESUME (0x00800000)
+#define CMD_TYPE_ABORT (0x00c00000)
+#define CMD_IS_DATA (0x00200000)
+#define CMD_IXCHK_EN (0x00100000)
+#define CMD_CRCCHK_EN (0x00080000)
+#define CMD_RSPNS_NO (0x00000000)
+#define CMD_RSPNS_136 (0x00010000)
+#define CMD_RSPNS_48 (0x00020000)
+#define CMD_RSPNS_48B (0x00030000)
+#define TM_MULTI_BLOCK (0x00000020)
+#define TM_DAT_DIR_HC (0x00000000)
+#define TM_DAT_DIR_CH (0x00000010)
+#define TM_AUTO_CMD23 (0x00000008)
+#define TM_AUTO_CMD12 (0x00000004)
+#define TM_BLKCNT_EN (0x00000002)
+#define TM_MULTI_DATA (CMD_IS_DATA | TM_MULTI_BLOCK | TM_BLKCNT_EN)
+
+#define RCA_NO (1)
+#define RCA_YES (2)
 
 // INTERRUPT register settings
-#define INT_AUTO_ERROR   (0x01000000)
+#define INT_AUTO_ERROR (0x01000000)
 #define INT_DATA_END_ERR (0x00400000)
 #define INT_DATA_CRC_ERR (0x00200000)
 #define INT_DATA_TIMEOUT (0x00100000)
-#define INT_INDEX_ERROR  (0x00080000)
-#define INT_END_ERROR    (0x00040000)
-#define INT_CRC_ERROR    (0x00020000)
-#define INT_CMD_TIMEOUT  (0x00010000)
-#define INT_ERR          (0x00008000)
-#define INT_ENDBOOT      (0x00004000)
-#define INT_BOOTACK      (0x00002000)
-#define INT_RETUNE       (0x00001000)
-#define INT_CARD         (0x00000100)
-#define INT_READ_RDY     (0x00000020)
-#define INT_WRITE_RDY    (0x00000010)
-#define INT_BLOCK_GAP    (0x00000004)
-#define INT_DATA_DONE    (0x00000002)
-#define INT_CMD_DONE     (0x00000001)
-#define INT_ERROR_MASK   (INT_CRC_ERROR|INT_END_ERROR|INT_INDEX_ERROR| \
-                          INT_DATA_TIMEOUT|INT_DATA_CRC_ERR|INT_DATA_END_ERR| \
-                          INT_ERR|INT_AUTO_ERROR)
-#define INT_ALL_MASK     (INT_CMD_DONE|INT_DATA_DONE|INT_READ_RDY|INT_WRITE_RDY|INT_ERROR_MASK)
-
-#define EMMC_ARG2               (0x00)
-#define EMMC_BLKSIZECNT         (0x04)
-#define EMMC_ARG1               (0x08)
-#define EMMC_CMDTM              (0x0c)
-#define EMMC_RESP0              (0x10)
-#define EMMC_RESP1              (0x14)
-#define EMMC_RESP2              (0x18)
-#define EMMC_RESP3              (0x1c)
-#define EMMC_DATA               (0x20)
-#define EMMC_STATUS             (0x24)
-#define EMMC_CONTROL0           (0x28)
-#define EMMC_CONTROL1           (0x2c)
-#define EMMC_INTERRUPT          (0x30)
-#define EMMC_IRPT_MASK          (0x34)
-#define EMMC_IRPT_EN            (0x38)
-#define EMMC_CONTROL2           (0x3c)
-#define EMMC_CAPABILITIES_0     (0x40)
-#define EMMC_CAPABILITIES_1     (0x44)
-#define EMMC_BOOT_TIMEOUT       (0x70)
-#define EMMC_EXRDFIFO_EN        (0x84)
-#define EMMC_SPI_INT_SPT        (0xf0)
-#define EMMC_SLOTISR_VER        (0xfc)
+#define INT_INDEX_ERROR (0x00080000)
+#define INT_END_ERROR (0x00040000)
+#define INT_CRC_ERROR (0x00020000)
+#define INT_CMD_TIMEOUT (0x00010000)
+#define INT_ERR (0x00008000)
+#define INT_ENDBOOT (0x00004000)
+#define INT_BOOTACK (0x00002000)
+#define INT_RETUNE (0x00001000)
+#define INT_CARD (0x00000100)
+#define INT_READ_RDY (0x00000020)
+#define INT_WRITE_RDY (0x00000010)
+#define INT_BLOCK_GAP (0x00000004)
+#define INT_DATA_DONE (0x00000002)
+#define INT_CMD_DONE (0x00000001)
+#define INT_ERROR_MASK (INT_CRC_ERROR | INT_END_ERROR | INT_INDEX_ERROR |        \
+                        INT_DATA_TIMEOUT | INT_DATA_CRC_ERR | INT_DATA_END_ERR | \
+                        INT_ERR | INT_AUTO_ERROR)
+#define INT_ALL_MASK (INT_CMD_DONE | INT_DATA_DONE | INT_READ_RDY | INT_WRITE_RDY | INT_ERROR_MASK)
+
+#define EMMC_ARG2 (0x00)
+#define EMMC_BLKSIZECNT (0x04)
+#define EMMC_BLKCOUNT (0x06)
+
+#define EMMC_ARG1 (0x08)
+#define EMMC_CMDTM (0x0c)
+#define EMMC_RESP0 (0x10)
+#define EMMC_RESP1 (0x14)
+#define EMMC_RESP2 (0x18)
+#define EMMC_RESP3 (0x1c)
+#define EMMC_DATA (0x20)
+#define EMMC_STATUS (0x24)
+#define EMMC_CONTROL0 (0x28)
+#define EMMC_BLKGAP_CTL (0x2a)
+#define EMMC_WAKE_CONTROL (0x2B)
+#define EMMC_CONTROL1 (0x2c)
+#define EMMC_TIMECTL (0x2e)
+#define EMMC_INTERRUPT (0x30)
+#define EMMC_ERR_INTERRUPT (0x32)
+
+#define EMMC_NOR_IRTR_STS_EN_OFFSET (0x34)
+#define EMMC_ERR_INTR_STS_EN_OFFSET (0x36U)
+
+#define EMMC_IRPT_EN (0x38)
+#define SDHCI_ERR_INTR_SIG_EN_OFFSET 0x3AU /**< Error Interrupt \
+                   Signal Enable Register */
+
+#define EMMC_CONTROL2 (0x3c)
+#define EMMC_HOST_CONTROL2 (0x3e)
+
+#define EMMC_CAPABILITIES_0 (0x40)
+#define EMMC_CAPABILITIES_1 (0x44)
+#define EMMC_ADMA_SAR_OFFSET (0x58)
+#define EMMC_BOOT_TIMEOUT (0x70)
+#define EMMC_EXRDFIFO_EN (0x84)
+#define EMMC_SPI_INT_SPT (0xf0)
+#define EMMC_SLOTISR_VER (0xfc)
+#define EMMC_HOST_VERSION (0xfe)
+#define EMMC_MY_CONTROL2 (0x3e)
+
+// CONTROL2 MASK
+#define SDHCI_CTL2_SHCVER_MASK (1 << 12)
+#define SDHCI_CTL2_BITADDR_MASK (1 << 13)
+
+// Capabilities1 MASK
+#define SDHCI_CAPA_ADMA2_MASK (1 << 19)
+
+// Capabilities2 MASK
+#define SDHCI_CAPA_ADMA3_MASK (1 << 27)
+
+#define SDHCI_BLK_SIZE_MASK 0x00000FFFU
+#define SDHCI_BLK_CNT_MASK 0x00000FFFU
+
+// Interrupt
+#define SDHCI_INTR_ALL_MASK 0xFFFFFFFFU
+#define SDHCI_NORM_INTR_ALL_MASK 0x0000FFFFU
+#define SDHCI_ERROR_INTR_ALL_MASK 0x0000F3FFU /**< Mask for error bits */
+#define SDHCI_INTR_CARD_MASK 0x00000100U      /**< Card Interrupt */
+
+/** @} */
+
+/** @name Transfer Mode and Command Register
+ *
+ * The Transfer Mode register is used to control the data transfers and
+ * Command register is used for command generation
+ * Read/Write except for reserved bits.
+ * @{
+ */
+
+#define SDHCI_TM_DMA_EN_MASK 0x00000001U          /**< DMA Enable */
+#define SDHCI_TM_BLK_CNT_EN_MASK 0x00000002U      /**< Block Count Enable */
+#define SDHCI_TM_AUTO_CMD12_EN_MASK 0x00000004U   /**< Auto CMD12 Enable */
+#define SDHCI_TM_DAT_DIR_SEL_MASK 0x00000010U     /**< Data Transfer \
+                              Direction Select */
+#define SDHCI_TM_MUL_SIN_BLK_SEL_MASK 0x00000020U /**< Multi/Single \
+                          Block Select */
+/**
+ *@name ADMA2 Descriptor related definitions
+ * @{
+ */
+/**
+ * ADMA2 Descriptor related definitions
+ */
+#define SDHCI_DESC_MAX_LENGTH 65536U
+
+#define SDHCI_DESC_VALID (0x1U << 0)
+#define SDHCI_DESC_END (0x1U << 1)
+#define SDHCI_DESC_INT (0x1U << 2)
+#define SDHCI_DESC_TRAN (0x2U << 4)
 
 // CONTROL register settings
-#define C0_SPI_MODE_EN          (0x00100000)
-#define C0_HCTL_HS_EN           (0x00000004)
-#define C0_HCTL_DWITDH          (0x00000002)
-
-#define C1_SRST_DATA            (0x04000000)
-#define C1_SRST_CMD             (0x02000000)
-#define C1_SRST_HC              (0x01000000)
-#define C1_TOUNIT_DIS           (0x000f0000)
-#define C1_TOUNIT_MAX           (0x000e0000)
-#define C1_CLK_GENSEL           (0x00000020)
-#define C1_CLK_EN               (0x00000004)
-#define C1_CLK_STABLE           (0x00000002)
-#define C1_CLK_INTLEN           (0x00000001)
-
-#define FREQ_SETUP           (400000)  // 400 Khz
-#define FREQ_NORMAL        (25000000)  // 25 Mhz
+#define C0_SPI_MODE_EN (0x00100000)
+#define C0_HCTL_HS_EN (0x00000004)
+#define C0_HCTL_DWITDH (0x00000002)
+
+#define C1_SRST_DATA (0x04000000)
+#define C1_SRST_CMD (0x02000000)
+#define C1_SRST_HC (0x01000000)
+#define C1_TOUNIT_DIS (0x000f0000)
+#define C1_TOUNIT_MAX (0x000e0000)
+#define C1_CLK_GENSEL (0x00000020)
+#define C1_CLK_EN (0x00000004)
+#define C1_CLK_STABLE (0x00000002)
+#define C1_CLK_INTLEN (0x00000001)
+
+#define FREQ_SETUP (400000)    // 400 Khz
+#define FREQ_NORMAL (25000000) // 25 Mhz
 
 // SLOTISR_VER values
-#define HOST_SPEC_NUM              0x00ff0000
-#define HOST_SPEC_NUM_SHIFT        16
-#define HOST_SPEC_V3               2
-#define HOST_SPEC_V2               1
-#define HOST_SPEC_V1               0
+#define HOST_SPEC_NUM 0x00ff0000
+#define HOST_SPEC_NUM_SHIFT 16
+#define HOST_SPEC_V3 2
+#define HOST_SPEC_V2 1
+#define HOST_SPEC_V1 0
 
 // STATUS register settings
-#define SR_DAT_LEVEL1        (0x1e000000)
-#define SR_CMD_LEVEL         (0x01000000)
-#define SR_DAT_LEVEL0        (0x00f00000)
-#define SR_DAT3              (0x00800000)
-#define SR_DAT2              (0x00400000)
-#define SR_DAT1              (0x00200000)
-#define SR_DAT0              (0x00100000)
-#define SR_WRITE_PROT        (0x00080000)  // From SDHC spec v2, BCM says reserved
-#define SR_READ_AVAILABLE    (0x00000800)  // ???? undocumented
-#define SR_WRITE_AVAILABLE   (0x00000400)  // ???? undocumented
-#define SR_READ_TRANSFER     (0x00000200)
-#define SR_WRITE_TRANSFER    (0x00000100)
-#define SR_DAT_ACTIVE        (0x00000004)
-#define SR_DAT_INHIBIT       (0x00000002)
-#define SR_CMD_INHIBIT       (0x00000001)
+#define SR_DAT_LEVEL1 (0x1e000000)
+#define SR_CMD_LEVEL (0x01000000)
+#define SR_DAT_LEVEL0 (0x00f00000)
+#define SR_DAT3 (0x00800000)
+#define SR_DAT2 (0x00400000)
+#define SR_DAT1 (0x00200000)
+#define SR_DAT0 (0x00100000)
+#define SR_WRITE_PROT (0x00080000)      // From SDHC spec v2, BCM says reserved
+#define SR_READ_AVAILABLE (0x00000800)  // ???? undocumented
+#define SR_WRITE_AVAILABLE (0x00000400) // ???? undocumented
+#define SR_READ_TRANSFER (0x00000200)
+#define SR_WRITE_TRANSFER (0x00000100)
+#define SR_DAT_ACTIVE (0x00000004)
+#define SR_DAT_INHIBIT (0x00000002)
+#define SR_CMD_INHIBIT (0x00000001)
 
 #define CONFIG_MMC_USE_DMA
-#define DMA_ALIGN            (32U)
-
-#define SD_CMD_INDEX(a)         ((a) << 24)
-#define SD_CMD_RESERVED(a)      (0xffffffff)
-#define SD_CMD_INDEX(a)         ((a) << 24)
-#define SD_CMD_TYPE_NORMAL      (0x0)
-#define SD_CMD_TYPE_SUSPEND     (1 << 22)
-#define SD_CMD_TYPE_RESUME      (2 << 22)
-#define SD_CMD_TYPE_ABORT       (3 << 22)
-#define SD_CMD_TYPE_MASK        (3 << 22)
-#define SD_CMD_ISDATA           (1 << 21)
-#define SD_CMD_IXCHK_EN         (1 << 20)
-#define SD_CMD_CRCCHK_EN        (1 << 19)
-#define SD_CMD_RSPNS_TYPE_NONE  (0)              // For no response
-#define SD_CMD_RSPNS_TYPE_136   (1 << 16)        // For response R2 (with CRC), R3,4 (no CRC)
-#define SD_CMD_RSPNS_TYPE_48    (2 << 16)        // For responses R1, R5, R6, R7 (with CRC)
-#define SD_CMD_RSPNS_TYPE_48B   (3 << 16)        // For responses R1b, R5b (with CRC)
-#define SD_CMD_RSPNS_TYPE_MASK  (3 << 16)
-#define SD_CMD_MULTI_BLOCK      (1 << 5)
-#define SD_CMD_DAT_DIR_HC       (0)
-#define SD_CMD_DAT_DIR_CH       (1 << 4)
-#define SD_CMD_AUTO_CMD_EN_NONE     (0)
-#define SD_CMD_AUTO_CMD_EN_CMD12    (1 << 2)
-#define SD_CMD_AUTO_CMD_EN_CMD23    (2 << 2)
-#define SD_CMD_BLKCNT_EN            (1 << 1)
-#define SD_CMD_DMA                  (1)
-#define SD_RESP_NONE                SD_CMD_RSPNS_TYPE_NONE
-#define SD_RESP_R1                  (SD_CMD_RSPNS_TYPE_48)            // | SD_CMD_CRCCHK_EN)
-#define SD_RESP_R1b                 (SD_CMD_RSPNS_TYPE_48B)           // | SD_CMD_CRCCHK_EN)
-#define SD_RESP_R2                  (SD_CMD_RSPNS_TYPE_136)           // | SD_CMD_CRCCHK_EN)
-#define SD_RESP_R3                  SD_CMD_RSPNS_TYPE_48
-#define SD_RESP_R4                  SD_CMD_RSPNS_TYPE_136
-#define SD_RESP_R5                  (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
-#define SD_RESP_R5b                 (SD_CMD_RSPNS_TYPE_48B | SD_CMD_CRCCHK_EN)
-#define SD_RESP_R6                  (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
-#define SD_RESP_R7                  (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
-#define SD_DATA_READ                (SD_CMD_ISDATA | SD_CMD_DAT_DIR_CH)
-#define SD_DATA_WRITE               (SD_CMD_ISDATA | SD_CMD_DAT_DIR_HC)
+#define DMA_ALIGN (32U)
+
+#define SD_CMD_INDEX(a) ((a) << 24)
+#define SD_CMD_RESERVED(a) (0xffffffff)
+#define SD_CMD_INDEX(a) ((a) << 24)
+#define SD_CMD_TYPE_NORMAL (0x0)
+#define SD_CMD_TYPE_SUSPEND (1 << 22)
+#define SD_CMD_TYPE_RESUME (2 << 22)
+#define SD_CMD_TYPE_ABORT (3 << 22)
+#define SD_CMD_TYPE_MASK (3 << 22)
+#define SD_CMD_ISDATA (1 << 21)
+#define SD_CMD_IXCHK_EN (1 << 20)
+#define SD_CMD_CRCCHK_EN (1 << 19)
+#define SD_CMD_RSPNS_TYPE_NONE (0)      // For no response
+#define SD_CMD_RSPNS_TYPE_136 (1 << 16) // For response R2 (with CRC), R3,4 (no CRC)
+#define SD_CMD_RSPNS_TYPE_48 (2 << 16)  // For responses R1, R5, R6, R7 (with CRC)
+#define SD_CMD_RSPNS_TYPE_48B (3 << 16) // For responses R1b, R5b (with CRC)
+#define SD_CMD_RSPNS_TYPE_MASK (3 << 16)
+#define SD_CMD_MULTI_BLOCK (1 << 5)
+#define SD_CMD_DAT_DIR_HC (0)
+#define SD_CMD_DAT_DIR_CH (1 << 4)
+#define SD_CMD_AUTO_CMD_EN_NONE (0)
+#define SD_CMD_AUTO_CMD_EN_CMD12 (1 << 2)
+#define SD_CMD_AUTO_CMD_EN_CMD23 (2 << 2)
+#define SD_CMD_BLKCNT_EN (1 << 1)
+#define SD_CMD_DMA (1)
+#define SD_RESP_NONE SD_CMD_RSPNS_TYPE_NONE
+#define SD_RESP_R1 (SD_CMD_RSPNS_TYPE_48)   // | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B) // | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136)  // | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R3 SD_CMD_RSPNS_TYPE_48
+#define SD_RESP_R4 SD_CMD_RSPNS_TYPE_136
+#define SD_RESP_R5 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R5b (SD_CMD_RSPNS_TYPE_48B | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R6 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R7 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_DATA_READ (SD_CMD_ISDATA | SD_CMD_DAT_DIR_CH)
+#define SD_DATA_WRITE (SD_CMD_ISDATA | SD_CMD_DAT_DIR_HC)
 #endif

+ 130 - 110
bsp/raspberry-pi/raspi4-64/drivers/raspi4.h

@@ -1,82 +1,81 @@
 #ifndef __RASPI4_H__
 #define __RASPI4_H__
 
-//https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0.pdf
+// https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0.pdf
 
-#define __REG32(x)  (*((volatile unsigned int *)(x)))
-#define __REG16(x)  (*((volatile unsigned short *)(x)))
+#define __REG32(x) (*((volatile unsigned int *)(x)))
+#define __REG16(x) (*((volatile unsigned short *)(x)))
 
 /* GIC IRQ MAX */
-#define MAX_HANDLERS                (256)
+#define MAX_HANDLERS (256)
 
 /* base address */
-#define PER_BASE                    (0xFE000000)
+#define PER_BASE (0xFE000000)
 
-//gpio offset
-#define GPIO_BASE_OFFSET            (0x00200000)
+// gpio offset
+#define GPIO_BASE_OFFSET (0x00200000)
 
+#define PL011_UART_BASE_OFFSET (0x00201000)
+// pl011 offset
+#define PL011_UART0_BASE_OFFSET (0x00201000)
+#define PL011_UART2_BASE_OFFSET (0x00201400)
+#define PL011_UART3_BASE_OFFSET (0x00201600)
+#define PL011_UART4_BASE_OFFSET (0x00201800)
+#define PL011_UART5_BASE_OFFSET (0x00201A00)
 
-#define PL011_UART_BASE_OFFSET      (0x00201000)
-//pl011 offset
-#define PL011_UART0_BASE_OFFSET     (0x00201000)
-#define PL011_UART2_BASE_OFFSET     (0x00201400)
-#define PL011_UART3_BASE_OFFSET     (0x00201600)
-#define PL011_UART4_BASE_OFFSET     (0x00201800)
-#define PL011_UART5_BASE_OFFSET     (0x00201A00)
+// pactl cs offset
+#define PACTL_CS_OFFSET (0x00204E00)
 
-//pactl cs offset
-#define PACTL_CS_OFFSET             (0x00204E00)
-
-//aux offset
-#define AUX_BASE_OFFSET             (0x00215000)
+// aux offset
+#define AUX_BASE_OFFSET (0x00215000)
 
 /* GPIO */
-#define GPIO_BASE_ADDR              (PER_BASE + GPIO_BASE_OFFSET)
+#define GPIO_BASE_ADDR (PER_BASE + GPIO_BASE_OFFSET)
 extern size_t gpio_base_addr;
-#define GPIO_BASE                   (gpio_base_addr)
-#define GPIO_IRQ_NUM                (3)   //40 pin mode
-#define IRQ_GPIO0                   (96 + 49) //bank0 (0 to 27)
-#define IRQ_GPIO1                   (96 + 50) //bank1 (28 to 45)
-#define IRQ_GPIO2                   (96 + 51) //bank2 (46 to 57)
-#define IRQ_GPIO3                   (96 + 52) //bank3
+#define GPIO_BASE (gpio_base_addr)
+#define GPIO_IRQ_NUM (3)    // 40 pin mode
+#define IRQ_GPIO0 (96 + 49) // bank0 (0 to 27)
+#define IRQ_GPIO1 (96 + 50) // bank1 (28 to 45)
+#define IRQ_GPIO2 (96 + 51) // bank2 (46 to 57)
+#define IRQ_GPIO3 (96 + 52) // bank3
 
 /* Timer (ARM side) */
-#define ARM_TIMER_IRQ       (64)
+#define ARM_TIMER_IRQ (64)
 extern size_t arm_timer_base;
-#define ARM_TIMER_BASE      (PER_BASE + 0xB000)
-#define ARM_TIMER_LOAD      HWREG32(arm_timer_base + 0x400)
-#define ARM_TIMER_VALUE     HWREG32(arm_timer_base + 0x404)
-#define ARM_TIMER_CTRL      HWREG32(arm_timer_base + 0x408)
-#define ARM_TIMER_IRQCLR    HWREG32(arm_timer_base + 0x40C)
-#define ARM_TIMER_RAWIRQ    HWREG32(arm_timer_base + 0x410)
-#define ARM_TIMER_MASKIRQ   HWREG32(arm_timer_base + 0x414)
-#define ARM_TIMER_RELOAD    HWREG32(arm_timer_base + 0x418)
-#define ARM_TIMER_PREDIV    HWREG32(arm_timer_base + 0x41C)
-#define ARM_TIMER_CNTR      HWREG32(arm_timer_base + 0x420)
+#define ARM_TIMER_BASE (PER_BASE + 0xB000)
+#define ARM_TIMER_LOAD HWREG32(arm_timer_base + 0x400)
+#define ARM_TIMER_VALUE HWREG32(arm_timer_base + 0x404)
+#define ARM_TIMER_CTRL HWREG32(arm_timer_base + 0x408)
+#define ARM_TIMER_IRQCLR HWREG32(arm_timer_base + 0x40C)
+#define ARM_TIMER_RAWIRQ HWREG32(arm_timer_base + 0x410)
+#define ARM_TIMER_MASKIRQ HWREG32(arm_timer_base + 0x414)
+#define ARM_TIMER_RELOAD HWREG32(arm_timer_base + 0x418)
+#define ARM_TIMER_PREDIV HWREG32(arm_timer_base + 0x41C)
+#define ARM_TIMER_CNTR HWREG32(arm_timer_base + 0x420)
 
 /* UART PL011 */
-#define UART_BASE                   (PER_BASE + PL011_UART_BASE_OFFSET)
-//extern uint32_t uart_base_addr;
-#define UART0_BASE                  (UART_BASE + 0x0)
-#define UART2_BASE                  (UART_BASE + 0x400)
-#define UART3_BASE                  (UART_BASE + 0x600)
-#define UART4_BASE                  (UART_BASE + 0x800)
-#define UART5_BASE                  (UART_BASE + 0xA00)
-#define IRQ_AUX_UART                (96 + 29)
-#define UART_REFERENCE_CLOCK        (48000000)
+#define UART_BASE (PER_BASE + PL011_UART_BASE_OFFSET)
+// extern uint32_t uart_base_addr;
+#define UART0_BASE (UART_BASE + 0x0)
+#define UART2_BASE (UART_BASE + 0x400)
+#define UART3_BASE (UART_BASE + 0x600)
+#define UART4_BASE (UART_BASE + 0x800)
+#define UART5_BASE (UART_BASE + 0xA00)
+#define IRQ_AUX_UART (96 + 29)
+#define UART_REFERENCE_CLOCK (48000000)
 
 /* AUX */
 //#define AUX_BASE_ADDR               (PER_BASE + AUX_BASE_OFFSET)
-//extern uint32_t aux_addr;
+// extern uint32_t aux_addr;
 //#define AUX_BASE                    (aux_addr + 0x0)
 
-#define AUX_BASE                    (PER_BASE + AUX_BASE_OFFSET)
-#define IRQ_PL011                   (96 + 57)
+#define AUX_BASE (PER_BASE + AUX_BASE_OFFSET)
+#define IRQ_PL011 (96 + 57)
 
 /* Peripheral IRQ OR-ing */
-#define PACTL_CS_ADDR               (PER_BASE + PACTL_CS_OFFSET)
-extern size_t     pactl_cs_base;
-#define PACTL_CS                    HWREG32(pactl_cs_base)
+#define PACTL_CS_ADDR (PER_BASE + PACTL_CS_OFFSET)
+extern size_t pactl_cs_base;
+#define PACTL_CS HWREG32(pactl_cs_base)
 typedef enum
 {
     IRQ_SPI0 = 0x00000000,
@@ -102,78 +101,79 @@ typedef enum
 } PACTL_CS_VAL;
 
 // 0x40, 0x44, 0x48, 0x4c: Core 0~3 Timers interrupt control
-#define CORE0_TIMER_IRQ_CTRL        HWREG32(0xFF800040)
-#define TIMER_IRQ                   30
-#define NON_SECURE_TIMER_IRQ        (1 << 1)
+#define CORE0_TIMER_IRQ_CTRL HWREG32(0xFF800040)
+#define TIMER_IRQ 30
+#define NON_SECURE_TIMER_IRQ (1 << 1)
 
 /* GIC */
-#define INTC_BASE                   (0xff800000)
-#define ARM_GIC_NR_IRQS             (512)
-#define ARM_GIC_MAX_NR              (512)
-#define GIC_V2_BASE                 (INTC_BASE + 0x00040000)
+#define INTC_BASE (0xff800000)
+#define ARM_GIC_NR_IRQS (512)
+#define ARM_GIC_MAX_NR (512)
+#define GIC_V2_BASE (INTC_BASE + 0x00040000)
 extern size_t gic_base_addr;
-#define GIC_V2_DISTRIBUTOR_BASE     (gic_base_addr + 0x1000)
-#define GIC_V2_CPU_INTERFACE_BASE   (gic_base_addr + 0x2000)
-#define GIC_V2_HYPERVISOR_BASE      (gic_base_addr + 0x4000)
-#define GIC_V2_VIRTUAL_CPU_BASE     (gic_base_addr + 0x6000)
-
-#define GIC_PL400_DISTRIBUTOR_PPTR  GIC_V2_DISTRIBUTOR_BASE
-#define GIC_PL400_CONTROLLER_PPTR   GIC_V2_CPU_INTERFACE_BASE
-
-#define GIC_IRQ_START   0
-
-#define GIC_ACK_INTID_MASK  0x000003ff
-
-
-//watchdog
-#define WDT_BASE        (PER_BASE + 0x00100000)
-extern size_t         wdt_base_addr;
-#define PM_RSTC         HWREG32(wdt_base_addr + 0x1c)
-#define PM_RSTS         HWREG32(wdt_base_addr + 0x20)
-#define PM_WDOG         HWREG32(wdt_base_addr + 0x24)
-
-#define PM_PASSWORD                 (0x5A000000)
-#define PM_WDOG_TIME_SET            (0x000fffff)
-#define PM_RSTS_HADWRH_SET          (0x00000040)
-#define PM_RSTC_WRCFG_FULL_RESET    (0x00000020)
-#define PM_RSTC_WRCFG_CLR           (0xffffffcf)
-#define PM_RSTC_RESET               (0x00000102)
-
-//timer
-#define ST_BASE_OFFSET     (0x003000)
-#define STIMER_BASE  (PER_BASE  + ST_BASE_OFFSET)
+#define GIC_V2_DISTRIBUTOR_BASE (gic_base_addr + 0x1000)
+#define GIC_V2_CPU_INTERFACE_BASE (gic_base_addr + 0x2000)
+#define GIC_V2_HYPERVISOR_BASE (gic_base_addr + 0x4000)
+#define GIC_V2_VIRTUAL_CPU_BASE (gic_base_addr + 0x6000)
+
+#define GIC_PL400_DISTRIBUTOR_PPTR GIC_V2_DISTRIBUTOR_BASE
+#define GIC_PL400_CONTROLLER_PPTR GIC_V2_CPU_INTERFACE_BASE
+
+#define GIC_IRQ_START 0
+
+#define GIC_ACK_INTID_MASK 0x000003ff
+
+// watchdog
+#define WDT_BASE (PER_BASE + 0x00100000)
+extern size_t wdt_base_addr;
+#define PM_RSTC HWREG32(wdt_base_addr + 0x1c)
+#define PM_RSTS HWREG32(wdt_base_addr + 0x20)
+#define PM_WDOG HWREG32(wdt_base_addr + 0x24)
+
+#define PM_PASSWORD (0x5A000000)
+#define PM_WDOG_TIME_SET (0x000fffff)
+#define PM_RSTS_HADWRH_SET (0x00000040)
+#define PM_RSTC_WRCFG_FULL_RESET (0x00000020)
+#define PM_RSTC_WRCFG_CLR (0xffffffcf)
+#define PM_RSTC_RESET (0x00000102)
+
+// timer
+#define ST_BASE_OFFSET (0x003000)
+#define STIMER_BASE (PER_BASE + ST_BASE_OFFSET)
 extern size_t stimer_base_addr;
-#define STIMER_CS    __REG32(stimer_base_addr + 0x0000)
-#define STIMER_CLO   __REG32(stimer_base_addr + 0x0004)
-#define STIMER_CHI   __REG32(stimer_base_addr + 0x0008)
-#define STIMER_C0    __REG32(stimer_base_addr + 0x000C)
-#define STIMER_C1    __REG32(stimer_base_addr + 0x0010)
-#define STIMER_C2    __REG32(stimer_base_addr + 0x0014)
-#define STIMER_C3    __REG32(stimer_base_addr + 0x0018)
+#define STIMER_CS __REG32(stimer_base_addr + 0x0000)
+#define STIMER_CLO __REG32(stimer_base_addr + 0x0004)
+#define STIMER_CHI __REG32(stimer_base_addr + 0x0008)
+#define STIMER_C0 __REG32(stimer_base_addr + 0x000C)
+#define STIMER_C1 __REG32(stimer_base_addr + 0x0010)
+#define STIMER_C2 __REG32(stimer_base_addr + 0x0014)
+#define STIMER_C3 __REG32(stimer_base_addr + 0x0018)
 
 #define DELAY_MICROS(micros)                            \
-    do{                                                 \
+    do                                                  \
+    {                                                   \
         rt_uint32_t compare = STIMER_CLO + micros * 25; \
-        while (STIMER_CLO < compare);                   \
+        while (STIMER_CLO < compare)                    \
+            ;                                           \
     } while (0)
 
-//External Mass Media Controller (SD Card)
-#define MMC0_BASE_ADDR    (PER_BASE+0x300000)
-extern size_t mmc0_base_addr; 
-#define MMC2_BASE_ADDR    (PER_BASE+0x340000)
+// External Mass Media Controller (SD Card)
+#define MMC0_BASE_ADDR (PER_BASE + 0x300000)
+extern size_t mmc0_base_addr;
+#define MMC2_BASE_ADDR (PER_BASE + 0x340000)
 extern size_t mmc2_base_addr;
 
-//mac
-#define MAC_REG                 (void *)(0xfd580000)
-extern uint8_t *                mac_reg_base_addr;
+// mac
+#define MAC_REG (void *)(0xfd580000)
+extern uint8_t *mac_reg_base_addr;
 
-#define ETH_IRQ                 (160+29)
+#define ETH_IRQ (160 + 29)
 
-#define SEND_DATA_NO_CACHE      (0x08200000)
-extern uint8_t *                eth_send_no_cache;
+#define SEND_DATA_NO_CACHE (0x08200000)
+extern uint8_t *eth_send_no_cache;
 
-#define RECV_DATA_NO_CACHE      (0x08400000)
-extern uint8_t *                eth_recv_no_cache;
+#define RECV_DATA_NO_CACHE (0x08400000)
+extern uint8_t *eth_recv_no_cache;
 
 /* the basic constants and interfaces needed by gic */
 rt_inline size_t platform_get_gic_dist_base(void)
@@ -186,4 +186,24 @@ rt_inline size_t platform_get_gic_cpu_base(void)
     return GIC_PL400_CONTROLLER_PPTR;
 }
 
+/**
+ * ADMA2 64-Bit descriptor table
+ */
+typedef struct
+{
+    uint16_t attribute; /**< Attributes of descriptor */
+    uint16_t aength;    /**< Length of current dma transfer */
+    uint64_t address;   /**< Address of current dma transfer */
+} sdhci_adma2_descriptor64;
+
+/**
+ * ADMA2 32-Bit descriptor table
+ */
+typedef struct
+{
+    uint16_t attribute; /**< Attributes of descriptor */
+    uint16_t length;    /**< Length of current dma transfer */
+    uint32_t address;   /**< Address of current dma transfer */
+} sdhci_adma2_descriptor32;
+
 #endif