From 782b9dd45a10e5e68ac5687fb57649e6c07de93e Mon Sep 17 00:00:00 2001 From: tyx <462747508@qq.com> Date: Sat, 2 Apr 2022 19:03:00 +0800 Subject: [PATCH] [components][sdio] Support DDR mode --- components/drivers/include/drivers/mmc.h | 136 +++++++++--------- .../drivers/include/drivers/mmcsd_host.h | 6 +- components/drivers/sdio/mmc.c | 51 +++++-- components/drivers/sdio/sdio.c | 6 +- 4 files changed, 118 insertions(+), 81 deletions(-) diff --git a/components/drivers/include/drivers/mmc.h b/components/drivers/include/drivers/mmc.h index d472bbbc5d..60915c55ff 100644 --- a/components/drivers/include/drivers/mmc.h +++ b/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 */ diff --git a/components/drivers/include/drivers/mmcsd_host.h b/components/drivers/include/drivers/mmcsd_host.h index 68e38c38ab..7d987d4aa4 100644 --- a/components/drivers/include/drivers/mmcsd_host.h +++ b/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 */ diff --git a/components/drivers/sdio/mmc.c b/components/drivers/sdio/mmc.c index ac01726577..8e392909e3 100644 --- a/components/drivers/sdio/mmc.c +++ b/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,14 +365,20 @@ 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: + case EXT_CSD_DDR_BUS_WIDTH_4: + LOG_E("switch to bus width DDR 4 bit failed!"); + break; + 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 2: - LOG_E("switch to bus width 8 bit failed!"); + case EXT_CSD_BUS_WIDTH_1: + LOG_E("switch to bus width 1 bit failed!"); break; default: break; diff --git a/components/drivers/sdio/sdio.c b/components/drivers/sdio/sdio.c index 1263f205b5..2ba1ddb51f 100644 --- a/components/drivers/sdio/sdio.c +++ b/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)