From 73c111d21273417a60fb18fe6eeba7e95bc249a1 Mon Sep 17 00:00:00 2001 From: heyuanjie87 <943313837@qq.com> Date: Fri, 23 Sep 2022 11:38:09 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[sdio]=E6=B7=BB=E5=8A=A0mmc=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=88=B0hs200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../drivers/include/drivers/mmcsd_core.h | 8 ++ .../drivers/include/drivers/mmcsd_host.h | 25 ++++- components/drivers/sdio/block_dev.c | 91 ++++++++++++++----- components/drivers/sdio/mmc.c | 65 +++++++++++-- components/drivers/sdio/mmcsd_core.c | 39 ++++++-- 5 files changed, 184 insertions(+), 44 deletions(-) diff --git a/components/drivers/include/drivers/mmcsd_core.h b/components/drivers/include/drivers/mmcsd_core.h index 70337c36b1..3b4d5c8321 100644 --- a/components/drivers/include/drivers/mmcsd_core.h +++ b/components/drivers/include/drivers/mmcsd_core.h @@ -32,6 +32,7 @@ struct rt_mmcsd_data { rt_uint32_t blksize; rt_uint32_t blks; rt_uint32_t *buf; + void *dma_addr; rt_int32_t err; rt_uint32_t flags; #define DATA_DIR_WRITE (1 << 0) @@ -45,6 +46,7 @@ struct rt_mmcsd_data { rt_uint32_t timeout_ns; rt_uint32_t timeout_clks; + long host_cookie; /* host driver private data */ }; struct rt_mmcsd_cmd { @@ -96,6 +98,7 @@ struct rt_mmcsd_cmd { rt_int32_t retries; /* max number of retries */ rt_int32_t err; + unsigned int busy_timeout; /* busy detect timeout in ms */ struct rt_mmcsd_data *data; struct rt_mmcsd_req *mrq; /* associated request */ @@ -105,6 +108,9 @@ struct rt_mmcsd_req { struct rt_mmcsd_data *data; struct rt_mmcsd_cmd *cmd; struct rt_mmcsd_cmd *stop; + struct rt_mmcsd_cmd *sbc; /* SET_BLOCK_COUNT for multiblock */ + /* Allow other commands during this ongoing data transfer or busy wait */ + int cap_cmd_during_tfr; }; /*the following is response bit*/ @@ -210,6 +216,7 @@ rt_inline rt_uint32_t __rt_fls(rt_uint32_t val) #define MMCSD_HOST_PLUGED 0 #define MMCSD_HOST_UNPLUGED 1 +rt_int32_t mmcsd_excute_tuning(struct rt_mmcsd_card *card); int mmcsd_wait_cd_changed(rt_int32_t timeout); void mmcsd_host_lock(struct rt_mmcsd_host *host); void mmcsd_host_unlock(struct rt_mmcsd_host *host); @@ -233,6 +240,7 @@ void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_ca rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr); void mmcsd_change(struct rt_mmcsd_host *host); void mmcsd_detect(void *param); +void mmcsd_host_init(struct rt_mmcsd_host *host); struct rt_mmcsd_host *mmcsd_alloc_host(void); void mmcsd_free_host(struct rt_mmcsd_host *host); int rt_mmcsd_core_init(void); diff --git a/components/drivers/include/drivers/mmcsd_host.h b/components/drivers/include/drivers/mmcsd_host.h index ddb37802ca..e3bd5d7187 100644 --- a/components/drivers/include/drivers/mmcsd_host.h +++ b/components/drivers/include/drivers/mmcsd_host.h @@ -59,6 +59,19 @@ struct rt_mmcsd_io_cfg { #define MMCSD_TIMING_MMC_DDR52 8 #define MMCSD_TIMING_MMC_HS200 9 #define MMCSD_TIMING_MMC_HS400 10 + + unsigned char drv_type; /* driver type (A, B, C, D) */ + +#define MMCSD_SET_DRIVER_TYPE_B 0 +#define MMCSD_SET_DRIVER_TYPE_A 1 +#define MMCSD_SET_DRIVER_TYPE_C 2 +#define MMCSD_SET_DRIVER_TYPE_D 3 + + unsigned char signal_voltage; + +#define MMCSD_SIGNAL_VOLTAGE_330 0 +#define MMCSD_SIGNAL_VOLTAGE_180 1 +#define MMCSD_SIGNAL_VOLTAGE_120 2 }; struct rt_mmcsd_host; @@ -69,7 +82,7 @@ struct rt_mmcsd_host_ops { void (*set_iocfg)(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg); rt_int32_t (*get_card_status)(struct rt_mmcsd_host *host); void (*enable_sdio_irq)(struct rt_mmcsd_host *host, rt_int32_t en); - void (*execute_tuning)(struct rt_mmcsd_host *host, rt_int32_t opcode); + rt_int32_t (*execute_tuning)(struct rt_mmcsd_host *host, rt_int32_t opcode); }; struct rt_mmcsd_host { @@ -105,8 +118,14 @@ 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 SDR*/ -#define MMCSD_SUP_HIGHSPEED_DDR (1 << 6)/* HIGH SPEED DDR*/ -#define MMCSD_SUP_HS200 (1 << 7) +#define MMCSD_SUP_DDR_3V3 (1 << 6) +#define MMCSD_SUP_DDR_1V8 (1 << 7) +#define MMCSD_SUP_DDR_1V2 (1 << 8) +#define MMCSD_SUP_HIGHSPEED_DDR (MMCSD_SUP_DDR_3V3 | MMCSD_SUP_DDR_1V8 | MMCSD_SUP_DDR_1V2)/* HIGH SPEED DDR*/ +#define MMCSD_SUP_HS200_1V8 (1 << 9) +#define MMCSD_SUP_HS200_1V2 (1 << 10) +#define MMCSD_SUP_HS200 (MMCSD_SUP_HS200_1V2 | MMCSD_SUP_HS200_1V8) /* hs200 sdr */ +#define MMCSD_SUP_NONREMOVABLE (1 << 11) 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/block_dev.c b/components/drivers/sdio/block_dev.c index 104ac3e075..e9d87c6826 100644 --- a/components/drivers/sdio/block_dev.c +++ b/components/drivers/sdio/block_dev.c @@ -41,6 +41,64 @@ struct mmcsd_blk_device #endif #define RT_GPT_PARTITION_MAX 128 +static int __send_status(struct rt_mmcsd_card *card, rt_uint32_t *status, unsigned retries) +{ + int err; + struct rt_mmcsd_cmd cmd; + + cmd.cmd_code = SEND_STATUS; + cmd.arg = card->rca << 16; + cmd.flags = RESP_R1 | CMD_AC; + err = mmcsd_send_cmd(card->host, &cmd, retries); + if (err) + return err; + + if (status) + *status = cmd.resp[0]; + + return 0; +} + +static int card_busy_detect(struct rt_mmcsd_card *card, unsigned int timeout_ms, + rt_uint32_t *resp_errs) +{ + int timeout = rt_tick_from_millisecond(timeout_ms); + int err = 0; + rt_uint32_t status; + rt_tick_t start; + + start = rt_tick_get(); + do + { + rt_bool_t out = (int)(rt_tick_get() - start) > timeout; + + err = __send_status(card, &status, 5); + if (err) + { + LOG_E("error %d requesting status", err); + return err; + } + + /* Accumulate any response error bits seen */ + if (resp_errs) + *resp_errs |= status; + + if (out) + { + LOG_E("wait card busy timeout"); + return -RT_ETIMEOUT; + } + /* + * Some cards mishandle the status bits, + * so make sure to check both the busy + * indication and the card state. + */ + } while (!(status & R1_READY_FOR_DATA) || + (R1_CURRENT_STATE(status) == 7)); + + return err; +} + rt_int32_t mmcsd_num_wr_blocks(struct rt_mmcsd_card *card) { rt_int32_t err; @@ -151,45 +209,30 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, w_cmd = WRITE_BLOCK; } + if (!controller_is_spi(card->host) && (card->flags & 0x8000)) + { + /* last request is WRITE,need check busy */ + card_busy_detect(card, 10000, RT_NULL); + } + if (!dir) { cmd.cmd_code = r_cmd; data.flags |= DATA_DIR_READ; + card->flags &= 0x7fff; } else { cmd.cmd_code = w_cmd; data.flags |= DATA_DIR_WRITE; + card->flags |= 0x8000; } mmcsd_set_data_timeout(&data, card); data.buf = buf; + mmcsd_send_request(host, &req); - if (!controller_is_spi(card->host) && dir != 0) - { - do - { - rt_int32_t err; - - cmd.cmd_code = SEND_STATUS; - cmd.arg = card->rca << 16; - cmd.flags = RESP_R1 | CMD_AC; - err = mmcsd_send_cmd(card->host, &cmd, 5); - if (err) - { - LOG_E("error %d requesting status", err); - break; - } - /* - * Some cards mishandle the status bits, - * so make sure to check both the busy - * indication and the card state. - */ - } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || - (R1_CURRENT_STATE(cmd.resp[0]) == 7)); - } - mmcsd_host_unlock(host); if (cmd.err || data.err || stop.err) diff --git a/components/drivers/sdio/mmc.c b/components/drivers/sdio/mmc.c index d7c2f4e929..c9e227327e 100644 --- a/components/drivers/sdio/mmc.c +++ b/components/drivers/sdio/mmc.c @@ -190,7 +190,12 @@ static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd) } host = card->host; - if (host->flags & MMCSD_SUP_HIGHSPEED_DDR) + if (host->flags & MMCSD_SUP_HS200) + { + card->flags |= CARD_FLAG_HS200; + card->hs_max_data_rate = 200000000; + } + else if (host->flags & MMCSD_SUP_HIGHSPEED_DDR) { card->flags |= CARD_FLAG_HIGHSPEED_DDR; card->hs_max_data_rate = 52000000; @@ -456,6 +461,45 @@ static rt_err_t mmc_set_card_addr(struct rt_mmcsd_host *host, rt_uint32_t rca) return 0; } +static int mmc_select_hs200(struct rt_mmcsd_card *card) +{ + int ret; + + ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200); + if (ret) + return ret; + + mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_HS200); + mmcsd_set_clock(card->host, 200000000); + + ret = mmcsd_excute_tuning(card); + + return ret; +} + +static int mmc_select_timing(struct rt_mmcsd_card *card) +{ + int ret = 0; + + if (card->flags & CARD_FLAG_HS200) + { + ret = mmc_select_hs200(card); + } + else if (card->flags & CARD_FLAG_HIGHSPEED_DDR) + { + mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_DDR52); + mmcsd_set_clock(card->host, card->hs_max_data_rate); + } + else + { + mmcsd_set_timing(card->host, MMCSD_TIMING_UHS_SDR50); + mmcsd_set_clock(card->host, card->hs_max_data_rate); + } + + return ret; +} + static rt_int32_t mmcsd_mmc_init_card(struct rt_mmcsd_host *host, rt_uint32_t ocr) { @@ -554,22 +598,27 @@ static rt_int32_t mmcsd_mmc_init_card(struct rt_mmcsd_host *host, max_data_rate = card->max_data_rate; /*switch bus width and bus mode*/ - mmc_select_bus_width(card, ext_csd); - if (card->flags & CARD_FLAG_HIGHSPEED_DDR) + err = mmc_select_bus_width(card, ext_csd); + if (err) { - mmcsd_set_timing(host, MMCSD_TIMING_MMC_DDR52); + LOG_E("mmc select buswidth fail"); + goto err0; } - else + + err = mmc_select_timing(card); + if (err) { - mmcsd_set_timing(host, MMCSD_TIMING_UHS_SDR50); + LOG_E("mmc select timing fail"); + goto err0; } - - mmcsd_set_clock(host, max_data_rate); + host->card = card; rt_free(ext_csd); return 0; +err0: + rt_free(ext_csd); err1: rt_free(card); err: diff --git a/components/drivers/sdio/mmcsd_core.c b/components/drivers/sdio/mmcsd_core.c index 6e3949ba70..c1d95741ae 100644 --- a/components/drivers/sdio/mmcsd_core.c +++ b/components/drivers/sdio/mmcsd_core.c @@ -696,6 +696,19 @@ void mmcsd_detect(void *param) } } +void mmcsd_host_init(struct rt_mmcsd_host *host) +{ + rt_memset(host, 0, sizeof(struct rt_mmcsd_host)); + strncpy(host->name, "sd", sizeof(host->name)-1); + host->max_seg_size = 65535; + host->max_dma_segs = 1; + host->max_blk_size = 512; + host->max_blk_count = 4096; + + rt_mutex_init(&host->bus_lock, "sd_bus_lock", RT_IPC_FLAG_FIFO); + rt_sem_init(&host->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO); +} + struct rt_mmcsd_host *mmcsd_alloc_host(void) { struct rt_mmcsd_host *host; @@ -708,15 +721,7 @@ struct rt_mmcsd_host *mmcsd_alloc_host(void) return RT_NULL; } - rt_memset(host, 0, sizeof(struct rt_mmcsd_host)); - strncpy(host->name, "sd", sizeof(host->name)-1); - host->max_seg_size = 65535; - host->max_dma_segs = 1; - host->max_blk_size = 512; - host->max_blk_count = 4096; - - rt_mutex_init(&host->bus_lock, "sd_bus_lock", RT_IPC_FLAG_FIFO); - rt_sem_init(&host->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO); + mmcsd_host_init(host); return host; } @@ -728,6 +733,22 @@ void mmcsd_free_host(struct rt_mmcsd_host *host) rt_free(host); } +rt_int32_t mmcsd_excute_tuning(struct rt_mmcsd_card *card) +{ + struct rt_mmcsd_host *host = card->host; + rt_int32_t opcode; + + if (!host->ops->execute_tuning) + return RT_EOK; + + if (card->card_type == CARD_TYPE_MMC) + opcode = SEND_TUNING_BLOCK_HS200; + else + opcode = SEND_TUNING_BLOCK; + + return host->ops->execute_tuning(host, opcode);; +} + int rt_mmcsd_core_init(void) { rt_err_t ret; -- Gitee From 433797521d0f1b07c98fecc5e3e58a6440946c04 Mon Sep 17 00:00:00 2001 From: heyuanjie87 <943313837@qq.com> Date: Sat, 24 Sep 2022 00:55:16 +0800 Subject: [PATCH 2/2] =?UTF-8?q?[sdio]=E4=BF=AE=E5=A4=8D=E6=9C=AA=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/sdio/block_dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c index e9d87c6826..911d46b963 100644 --- a/components/drivers/sdio/block_dev.c +++ b/components/drivers/sdio/block_dev.c @@ -46,6 +46,7 @@ static int __send_status(struct rt_mmcsd_card *card, rt_uint32_t *status, unsign int err; struct rt_mmcsd_cmd cmd; + cmd.busy_timeout = 0; cmd.cmd_code = SEND_STATUS; cmd.arg = card->rca << 16; cmd.flags = RESP_R1 | CMD_AC; -- Gitee