浏览代码

[components][sdio] Support DDR mode

tyx 3 年之前
父节点
当前提交
782b9dd45a

+ 68 - 68
components/drivers/include/drivers/mmc.h

@@ -22,82 +22,82 @@ extern "C" {
  * EXT_CSD fields
  */
 
-#define EXT_CSD_FLUSH_CACHE     32      /* W */
-#define EXT_CSD_CACHE_CTRL      33      /* R/W */
+#define EXT_CSD_FLUSH_CACHE             32      /* W */
+#define EXT_CSD_CACHE_CTRL              33      /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION  34  /* R/W */
 #define EXT_CSD_PACKED_FAILURE_INDEX    35  /* RO */
-#define EXT_CSD_PACKED_CMD_STATUS   36  /* RO */
-#define EXT_CSD_EXP_EVENTS_STATUS   54  /* RO, 2 bytes */
-#define EXT_CSD_EXP_EVENTS_CTRL     56  /* R/W, 2 bytes */
-#define EXT_CSD_DATA_SECTOR_SIZE    61  /* R */
-#define EXT_CSD_GP_SIZE_MULT        143 /* R/W */
-#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
-#define EXT_CSD_PARTITION_SUPPORT   160 /* RO */
-#define EXT_CSD_HPI_MGMT        161 /* R/W */
-#define EXT_CSD_RST_N_FUNCTION      162 /* R/W */
-#define EXT_CSD_BKOPS_EN        163 /* R/W */
-#define EXT_CSD_BKOPS_START     164 /* W */
-#define EXT_CSD_SANITIZE_START      165     /* W */
-#define EXT_CSD_WR_REL_PARAM        166 /* RO */
-#define EXT_CSD_RPMB_MULT       168 /* RO */
-#define EXT_CSD_BOOT_WP         173 /* R/W */
-#define EXT_CSD_ERASE_GROUP_DEF     175 /* R/W */
-#define EXT_CSD_PART_CONFIG     179 /* R/W */
-#define EXT_CSD_ERASED_MEM_CONT     181 /* RO */
-#define EXT_CSD_BUS_WIDTH       183 /* R/W */
-#define EXT_CSD_HS_TIMING       185 /* R/W */
-#define EXT_CSD_POWER_CLASS     187 /* R/W */
-#define EXT_CSD_REV         192 /* RO */
-#define EXT_CSD_STRUCTURE       194 /* RO */
-#define EXT_CSD_CARD_TYPE       196 /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS       36  /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS       54  /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL         56  /* R/W, 2 bytes */
+#define EXT_CSD_DATA_SECTOR_SIZE        61  /* R */
+#define EXT_CSD_GP_SIZE_MULT            143 /* R/W */
+#define EXT_CSD_PARTITION_ATTRIBUTE     156 /* R/W */
+#define EXT_CSD_PARTITION_SUPPORT       160 /* RO */
+#define EXT_CSD_HPI_MGMT                161 /* R/W */
+#define EXT_CSD_RST_N_FUNCTION          162 /* R/W */
+#define EXT_CSD_BKOPS_EN                163 /* R/W */
+#define EXT_CSD_BKOPS_START             164 /* W */
+#define EXT_CSD_SANITIZE_START          165     /* W */
+#define EXT_CSD_WR_REL_PARAM            166 /* RO */
+#define EXT_CSD_RPMB_MULT               168 /* RO */
+#define EXT_CSD_BOOT_WP                 173 /* R/W */
+#define EXT_CSD_ERASE_GROUP_DEF         175 /* R/W */
+#define EXT_CSD_PART_CONFIG             179 /* R/W */
+#define EXT_CSD_ERASED_MEM_CONT         181 /* RO */
+#define EXT_CSD_BUS_WIDTH               183 /* R/W */
+#define EXT_CSD_HS_TIMING               185 /* R/W */
+#define EXT_CSD_POWER_CLASS             187 /* R/W */
+#define EXT_CSD_REV                     192 /* RO */
+#define EXT_CSD_STRUCTURE               194 /* RO */
+#define EXT_CSD_CARD_TYPE               196 /* RO */
 #define EXT_CSD_OUT_OF_INTERRUPT_TIME   198 /* RO */
 #define EXT_CSD_PART_SWITCH_TIME        199     /* RO */
-#define EXT_CSD_PWR_CL_52_195       200 /* RO */
-#define EXT_CSD_PWR_CL_26_195       201 /* RO */
-#define EXT_CSD_PWR_CL_52_360       202 /* RO */
-#define EXT_CSD_PWR_CL_26_360       203 /* RO */
-#define EXT_CSD_SEC_CNT         212 /* RO, 4 bytes */
-#define EXT_CSD_S_A_TIMEOUT     217 /* RO */
-#define EXT_CSD_REL_WR_SEC_C        222 /* RO */
-#define EXT_CSD_HC_WP_GRP_SIZE      221 /* RO */
-#define EXT_CSD_ERASE_TIMEOUT_MULT  223 /* RO */
-#define EXT_CSD_HC_ERASE_GRP_SIZE   224 /* RO */
-#define EXT_CSD_BOOT_MULT       226 /* RO */
-#define EXT_CSD_SEC_TRIM_MULT       229 /* RO */
-#define EXT_CSD_SEC_ERASE_MULT      230 /* RO */
-#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
-#define EXT_CSD_TRIM_MULT       232 /* RO */
-#define EXT_CSD_PWR_CL_200_195      236 /* RO */
-#define EXT_CSD_PWR_CL_200_360      237 /* RO */
-#define EXT_CSD_PWR_CL_DDR_52_195   238 /* RO */
-#define EXT_CSD_PWR_CL_DDR_52_360   239 /* RO */
-#define EXT_CSD_BKOPS_STATUS        246 /* RO */
-#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
-#define EXT_CSD_GENERIC_CMD6_TIME   248 /* RO */
-#define EXT_CSD_CACHE_SIZE      249 /* RO, 4 bytes */
-#define EXT_CSD_PWR_CL_DDR_200_360  253 /* RO */
-#define EXT_CSD_TAG_UNIT_SIZE       498 /* RO */
-#define EXT_CSD_DATA_TAG_SUPPORT    499 /* RO */
-#define EXT_CSD_MAX_PACKED_WRITES   500 /* RO */
-#define EXT_CSD_MAX_PACKED_READS    501 /* RO */
-#define EXT_CSD_BKOPS_SUPPORT       502 /* RO */
-#define EXT_CSD_HPI_FEATURES        503 /* RO */
+#define EXT_CSD_PWR_CL_52_195           200 /* RO */
+#define EXT_CSD_PWR_CL_26_195           201 /* RO */
+#define EXT_CSD_PWR_CL_52_360           202 /* RO */
+#define EXT_CSD_PWR_CL_26_360           203 /* RO */
+#define EXT_CSD_SEC_CNT                 212 /* RO, 4 bytes */
+#define EXT_CSD_S_A_TIMEOUT             217 /* RO */
+#define EXT_CSD_REL_WR_SEC_C            222 /* RO */
+#define EXT_CSD_HC_WP_GRP_SIZE          221 /* RO */
+#define EXT_CSD_ERASE_TIMEOUT_MULT      223 /* RO */
+#define EXT_CSD_HC_ERASE_GRP_SIZE       224 /* RO */
+#define EXT_CSD_BOOT_MULT               226 /* RO */
+#define EXT_CSD_SEC_TRIM_MULT           229 /* RO */
+#define EXT_CSD_SEC_ERASE_MULT          230 /* RO */
+#define EXT_CSD_SEC_FEATURE_SUPPORT     231 /* RO */
+#define EXT_CSD_TRIM_MULT               232 /* RO */
+#define EXT_CSD_PWR_CL_200_195          236 /* RO */
+#define EXT_CSD_PWR_CL_200_360          237 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_195       238 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_360       239 /* RO */
+#define EXT_CSD_BKOPS_STATUS            246 /* RO */
+#define EXT_CSD_POWER_OFF_LONG_TIME     247 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME       248 /* RO */
+#define EXT_CSD_CACHE_SIZE              249 /* RO, 4 bytes */
+#define EXT_CSD_PWR_CL_DDR_200_360      253 /* RO */
+#define EXT_CSD_TAG_UNIT_SIZE           498 /* RO */
+#define EXT_CSD_DATA_TAG_SUPPORT        499 /* RO */
+#define EXT_CSD_MAX_PACKED_WRITES       500 /* RO */
+#define EXT_CSD_MAX_PACKED_READS        501 /* RO */
+#define EXT_CSD_BKOPS_SUPPORT           502 /* RO */
+#define EXT_CSD_HPI_FEATURES            503 /* RO */
 
 /*
  * EXT_CSD field definitions
  */
 
-#define EXT_CSD_WR_REL_PARAM_EN     (1<<2)
+#define EXT_CSD_WR_REL_PARAM_EN         (1<<2)
 
 #define EXT_CSD_BOOT_WP_B_PWR_WP_DIS    (0x40)
 #define EXT_CSD_BOOT_WP_B_PERM_WP_DIS   (0x10)
 #define EXT_CSD_BOOT_WP_B_PERM_WP_EN    (0x04)
-#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
+#define EXT_CSD_BOOT_WP_B_PWR_WP_EN     (0x01)
 
 #define EXT_CSD_PART_CONFIG_ACC_MASK    (0x7)
 #define EXT_CSD_PART_CONFIG_ACC_BOOT0   (0x1)
 #define EXT_CSD_PART_CONFIG_ACC_RPMB    (0x3)
-#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
+#define EXT_CSD_PART_CONFIG_ACC_GP0     (0x4)
 
 #define EXT_CSD_PART_SUPPORT_PART_EN    (0x1)
 
@@ -125,18 +125,18 @@ extern "C" {
 #define EXT_CSD_CARD_TYPE_HS400     (EXT_CSD_CARD_TYPE_HS400_1_8V | \
                      EXT_CSD_CARD_TYPE_HS400_1_2V)
 
-#define EXT_CSD_BUS_WIDTH_1         0   /* Card is in 1 bit mode */
-#define EXT_CSD_BUS_WIDTH_4         1   /* Card is in 4 bit mode */
-#define EXT_CSD_BUS_WIDTH_8         2   /* Card is in 8 bit mode */
+#define EXT_CSD_BUS_WIDTH_1             0   /* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4             1   /* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8             2   /* Card is in 8 bit mode */
 #define EXT_CSD_DDR_BUS_WIDTH_4         5   /* Card is in 4 bit DDR mode */
 #define EXT_CSD_DDR_BUS_WIDTH_8         6   /* Card is in 8 bit DDR mode */
 
-#define EXT_CSD_TIMING_BC           0   /* Backwards compatility */
-#define EXT_CSD_TIMING_HS           1   /* High speed */
+#define EXT_CSD_TIMING_BC               0   /* Backwards compatility */
+#define EXT_CSD_TIMING_HS               1   /* High speed */
 #define EXT_CSD_TIMING_HS200            2   /* HS200 */
 #define EXT_CSD_TIMING_HS400            3   /* HS400 */
 
-#define EXT_CSD_SEC_ER_EN           BIT(0)
+#define EXT_CSD_SEC_ER_EN               BIT(0)
 #define EXT_CSD_SEC_BD_BLK_EN           BIT(2)
 #define EXT_CSD_SEC_GB_CL_EN            BIT(4)
 #define EXT_CSD_SEC_SANITIZE            BIT(6)  /* v4.5 only */
@@ -145,9 +145,9 @@ extern "C" {
 #define EXT_CSD_RST_N_ENABLED           1   /* RST_n is enabled on card */
 
 #define EXT_CSD_NO_POWER_NOTIFICATION   0
-#define EXT_CSD_POWER_ON        1
-#define EXT_CSD_POWER_OFF_SHORT     2
-#define EXT_CSD_POWER_OFF_LONG      3
+#define EXT_CSD_POWER_ON                1
+#define EXT_CSD_POWER_OFF_SHORT         2
+#define EXT_CSD_POWER_OFF_LONG          3
 
 #define EXT_CSD_PWR_CL_8BIT_MASK    0xF0    /* 8 bit PWR CLS */
 #define EXT_CSD_PWR_CL_4BIT_MASK    0x0F    /* 8 bit PWR CLS */

+ 5 - 1
components/drivers/include/drivers/mmcsd_host.h

@@ -45,7 +45,8 @@ struct rt_mmcsd_io_cfg {
 #define MMCSD_BUS_WIDTH_1       0
 #define MMCSD_BUS_WIDTH_4       2
 #define MMCSD_BUS_WIDTH_8       3
-
+#define MMCSD_DDR_BUS_WIDTH_4   4
+#define MMCSD_DDR_BUS_WIDTH_8   5
 };
 
 struct rt_mmcsd_host;
@@ -90,6 +91,9 @@ struct rt_mmcsd_host {
 #define controller_is_spi(host) (host->flags & MMCSD_HOST_IS_SPI)
 #define MMCSD_SUP_SDIO_IRQ  (1 << 4)    /* support signal pending SDIO IRQs */
 #define MMCSD_SUP_HIGHSPEED (1 << 5)    /* support high speed */
+#define MMCSD_SUP_HIGHSPEED_DDR     (1 << 6)    /* support high speed(DDR) */
+#define MMCSD_SUP_HIGHSPEED_HS200   (1 << 7)    /* support high speed HS200 */
+#define MMCSD_SUP_HIGHSPEED_HS400   (1 << 8)    /* support high speed HS400 */
 
     rt_uint32_t max_seg_size;   /* maximum size of one dma segment */
     rt_uint32_t max_dma_segs;   /* maximum number of dma segments in one request */

+ 40 - 11
components/drivers/sdio/mmc.c

@@ -290,10 +290,19 @@ out:
 static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
 {
   rt_uint32_t ext_csd_bits[] = {
+    EXT_CSD_DDR_BUS_WIDTH_8,
+    EXT_CSD_DDR_BUS_WIDTH_4,
     EXT_CSD_BUS_WIDTH_8,
     EXT_CSD_BUS_WIDTH_4,
     EXT_CSD_BUS_WIDTH_1
   };
+  rt_uint32_t bus_widths[] = {
+    MMCSD_DDR_BUS_WIDTH_8,
+    MMCSD_DDR_BUS_WIDTH_4,
+    MMCSD_BUS_WIDTH_8,
+    MMCSD_BUS_WIDTH_4,
+    MMCSD_BUS_WIDTH_1
+  };
   struct rt_mmcsd_host *host = card->host;
   unsigned idx, trys, bus_width = 0;
   int err = 0;
@@ -317,12 +326,25 @@ static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
     * bail out early if corresponding bus capable wasn't
     * set by drivers.
     */
-     if ((!(host->flags & MMCSD_BUSWIDTH_8) &&
-      ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8) ||
-         (!(host->flags & MMCSD_BUSWIDTH_4) &&
-      (ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_4 ||
-      ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8)))
-         continue;
+    if ((!((host->flags & MMCSD_BUSWIDTH_8) &&
+           (host->flags & MMCSD_SUP_HIGHSPEED_DDR)) &&
+         ext_csd_bits[idx] == EXT_CSD_DDR_BUS_WIDTH_8) ||
+        (!((host->flags & MMCSD_BUSWIDTH_4) &&
+           (host->flags & MMCSD_SUP_HIGHSPEED_DDR)) &&
+         ext_csd_bits[idx] == EXT_CSD_DDR_BUS_WIDTH_4) ||
+        (!(host->flags & MMCSD_BUSWIDTH_8) &&
+         ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8) ||
+        (!(host->flags & MMCSD_BUSWIDTH_4) &&
+         ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_4))
+        continue;
+
+    if (host->flags & MMCSD_SUP_HIGHSPEED_DDR)
+    {
+        /* HS_TIMING must be set to "0x1" before setting BUS_WIDTH for dual-data-rate(DDR) operation */
+        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS);
+        if (err)
+            LOG_E("switch to speed mode width hight speed failed!");
+    }
 
     err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                      EXT_CSD_BUS_WIDTH,
@@ -330,6 +352,7 @@ static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
     if (err)
       continue;
 
+    bus_width = bus_widths[idx];
     for(trys = 0; trys < 5; trys++){
         mmcsd_set_bus_width(host, bus_width);
         mmcsd_delay_ms(10);
@@ -342,15 +365,21 @@ static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
       break;
     } else {
       switch(ext_csd_bits[idx]){
-          case 0:
-            LOG_E("switch to bus width 1 bit failed!");
+          case EXT_CSD_DDR_BUS_WIDTH_8:
+            LOG_E("switch to bus width DDR 8 bit failed!");
             break;
-          case 1:
-            LOG_E("switch to bus width 4 bit failed!");
+          case EXT_CSD_DDR_BUS_WIDTH_4:
+            LOG_E("switch to bus width DDR 4 bit failed!");
             break;
-          case 2:
+          case EXT_CSD_BUS_WIDTH_8:
             LOG_E("switch to bus width 8 bit failed!");
             break;
+          case EXT_CSD_BUS_WIDTH_4:
+            LOG_E("switch to bus width 4 bit failed!");
+            break;
+          case EXT_CSD_BUS_WIDTH_1:
+            LOG_E("switch to bus width 1 bit failed!");
+            break;
           default:
             break;
       }

+ 5 - 1
components/drivers/sdio/sdio.c

@@ -743,7 +743,11 @@ static rt_int32_t sdio_set_highspeed(struct rt_mmcsd_card *card)
     rt_int32_t ret;
     rt_uint8_t speed;
 
-    if (!(card->host->flags & MMCSD_SUP_HIGHSPEED))
+    if (!(card->host->flags &
+        (MMCSD_SUP_HIGHSPEED |
+         MMCSD_SUP_HIGHSPEED_DDR |
+         MMCSD_SUP_HIGHSPEED_HS200 |
+         MMCSD_SUP_HIGHSPEED_HS400)))
         return 0;
 
     if (!card->cccr.high_speed)