[components][sdio] Support DDR mode

This commit is contained in:
tyx 2022-04-02 19:03:00 +08:00 committed by guo
parent 556b14ed47
commit 782b9dd45a
4 changed files with 118 additions and 81 deletions

View File

@ -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 */

View File

@ -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,19 +326,33 @@ 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) &&
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 ||
ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8)))
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,
ext_csd_bits[idx]);
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;

View File

@ -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)