[components][sdio] Support DDR mode
This commit is contained in:
parent
556b14ed47
commit
782b9dd45a
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue