sd: MMC API, and MMC Spec

- Adds the declaration of the MMC API
- Adds MMC spec related declarations
- Adds some properties to sdhc dts binding for mmc

Signed-off-by: Declan Snyder <declan.snyder@nxp.com>
This commit is contained in:
Declan Snyder 2022-08-30 11:04:08 -05:00 committed by Carles Cufí
commit 3bc095a810
5 changed files with 227 additions and 4 deletions

View file

@ -49,3 +49,13 @@ properties:
description: | description: |
time in ms for SDHC to delay when toggling power to the SD card. This time in ms for SDHC to delay when toggling power to the SD card. This
delay gives the card time to power up or down fully delay gives the card time to power up or down fully
mmc-hs200-1_8v:
type: boolean
description: |
The host controller supports HS200 at 1.8V
mmc-hs400-1_8v:
type: boolean
description: |
The host controller supports HS400 at 1.8V

View file

@ -165,6 +165,7 @@ struct sdhc_host_caps {
unsigned int sd_base_clk: 8; unsigned int sd_base_clk: 8;
unsigned int max_blk_len: 2; unsigned int max_blk_len: 2;
unsigned int bus_8_bit_support: 1; unsigned int bus_8_bit_support: 1;
unsigned int bus_4_bit_support: 1;
unsigned int adma_2_support: 1; unsigned int adma_2_support: 1;
unsigned int _rsvd_20: 1; unsigned int _rsvd_20: 1;
unsigned int high_spd_support: 1; unsigned int high_spd_support: 1;
@ -193,6 +194,8 @@ struct sdhc_host_caps {
unsigned int adma3_support: 1; unsigned int adma3_support: 1;
unsigned int vdd2_180_support: 1; unsigned int vdd2_180_support: 1;
unsigned int _rsvd_61: 3; unsigned int _rsvd_61: 3;
unsigned int hs200_support: 1;
unsigned int hs400_support: 1;
}; };
/** /**

76
include/zephyr/sd/mmc.h Normal file
View file

@ -0,0 +1,76 @@
/*
* Copyright 2022 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Public API for MMC memory card subsystem
*/
#ifndef ZEPHYR_INCLUDE_SD_MMC_H_
#define ZEPHYR_INCLUDE_SD_MMC_H_
#include <zephyr/device.h>
#include <zephyr/drivers/sdhc.h>
#include <zephyr/sd/sd.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Write blocks to MMC card from buffer
*
* Writes blocks from MMC buffer to MMC card. For best performance, this buffer
* should be aligned to CONFIG_SDHC_BUFFER_ALIGNMENT
* @param card MMC card to write from
* @param wbuf write buffer
* @param start_block first block to write to
* @param num_blocks number of blocks to write
* @retval 0 write succeeded
* @retval -EBUSY: card is busy with another request
* @retval -ETIMEDOUT: card write timed out
* @retval -EIO: I/O error
*/
int mmc_write_blocks(struct sd_card *card, const uint8_t *wbuf,
uint32_t start_block, uint32_t num_blocks);
/**
* @brief Read block from MMC card to buffer
*
* Reads blocks into MMC buffer from MMC card. For best performance, this buffer
* should be aligned to CONFIG_SDHC_BUFFER_ALIGNMENT
* @param card MMC card to read from
* @param rbuf read buffer
* @param start_block first block to read from
* @param num_blocks number of blocks to read
* @retval 0 read succeeded
* @retval -EBUSY: card is busy with another request
* @retval -ETIMEDOUT: card read timed out
* @retval -EIO: I/O error
*/
int mmc_read_blocks(struct sd_card *card, uint8_t *rbuf,
uint32_t start_block, uint32_t num_blocks);
/**
* @brief Get I/O control data from MMC card
*
* Sends I/O control commands to MMC card.
* @param card MMC card
* @param cmd I/O control command
* Mirrors disk subsystem,
* see include/zephyr/drivers/disk.h for list of possible commands.
* @param buf I/O control buf
* @retval 0 IOCTL command succeeded
* @retval -ENOTSUP: IOCTL command not supported
* @retval -EIO: I/O failure
*/
int mmc_ioctl(struct sd_card *card, uint8_t cmd, void *buf);
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_SD_MMC_H_ */

View file

@ -36,6 +36,7 @@ enum card_type {
CARD_SDMMC = 0, /*!< SD memory card */ CARD_SDMMC = 0, /*!< SD memory card */
CARD_SDIO = 1, /*!< SD I/O card */ CARD_SDIO = 1, /*!< SD I/O card */
CARD_COMBO = 2, /*!< SD memory and I/O card */ CARD_COMBO = 2, /*!< SD memory and I/O card */
CARD_MMC = 3, /*!< MMC memory card */
}; };
@ -59,7 +60,7 @@ struct sd_card {
uint32_t block_count; /*!< Number of blocks in SD card */ uint32_t block_count; /*!< Number of blocks in SD card */
uint32_t block_size; /*!< SD block size */ uint32_t block_size; /*!< SD block size */
uint32_t sd_version; /*!< SD specification version */ uint32_t sd_version; /*!< SD specification version */
enum sd_timing_mode card_speed; /*!< Card timing mode */ uint32_t card_speed; /*!< Card timing mode */
enum card_status status; /*!< Card status */ enum card_status status; /*!< Card status */
enum card_type type; /*!< Card type */ enum card_type type; /*!< Card type */
uint32_t flags; /*!< Card flags */ uint32_t flags; /*!< Card flags */

View file

@ -26,22 +26,28 @@ extern "C" {
*/ */
enum sd_opcode { enum sd_opcode {
SD_GO_IDLE_STATE = 0, SD_GO_IDLE_STATE = 0,
MMC_SEND_OP_COND = 1,
SD_ALL_SEND_CID = 2, SD_ALL_SEND_CID = 2,
SD_SEND_RELATIVE_ADDR = 3, SD_SEND_RELATIVE_ADDR = 3,
MMC_SEND_RELATIVE_ADDR = 3,
SDIO_SEND_OP_COND = 5, /* SDIO cards only */ SDIO_SEND_OP_COND = 5, /* SDIO cards only */
SD_SWITCH = 6, SD_SWITCH = 6,
SD_SELECT_CARD = 7, SD_SELECT_CARD = 7,
SD_SEND_IF_COND = 8, SD_SEND_IF_COND = 8,
MMC_SEND_EXT_CSD = 8,
SD_SEND_CSD = 9, SD_SEND_CSD = 9,
SD_SEND_CID = 10, SD_SEND_CID = 10,
SD_VOL_SWITCH = 11, SD_VOL_SWITCH = 11,
SD_STOP_TRANSMISSION = 12, SD_STOP_TRANSMISSION = 12,
SD_SEND_STATUS = 13, SD_SEND_STATUS = 13,
MMC_CHECK_BUS_TEST = 14,
SD_GO_INACTIVE_STATE = 15, SD_GO_INACTIVE_STATE = 15,
SD_SET_BLOCK_SIZE = 16, SD_SET_BLOCK_SIZE = 16,
SD_READ_SINGLE_BLOCK = 17, SD_READ_SINGLE_BLOCK = 17,
SD_READ_MULTIPLE_BLOCK = 18, SD_READ_MULTIPLE_BLOCK = 18,
SD_SEND_TUNING_BLOCK = 19, SD_SEND_TUNING_BLOCK = 19,
MMC_SEND_BUS_TEST = 19,
MMC_SEND_TUNING_BLOCK = 21,
SD_SET_BLOCK_COUNT = 23, SD_SET_BLOCK_COUNT = 23,
SD_WRITE_SINGLE_BLOCK = 24, SD_WRITE_SINGLE_BLOCK = 24,
SD_WRITE_MULTIPLE_BLOCK = 25, SD_WRITE_MULTIPLE_BLOCK = 25,
@ -278,6 +284,20 @@ enum sd_ocr_flag {
/*!< VDD 3.4-3.5 */ /*!< VDD 3.4-3.5 */
}; };
/**
* @brief MMC OCR bit flags
*
* bit flags present in MMC OCR response. Used to determine status and
* supported functions of MMC card.
*/
enum mmc_ocr_flag {
MMC_OCR_VDD170_195FLAG = BIT(7),
MMC_OCR_VDD20_26FLAG = 0x7F << 8,
MMC_OCR_VDD27_36FLAG = 0x1FF << 15,
MMC_OCR_SECTOR_MODE = BIT(30),
MMC_OCR_PWR_BUSY_FLAG = BIT(31)
};
#define SDIO_OCR_IO_NUMBER_SHIFT (28U) #define SDIO_OCR_IO_NUMBER_SHIFT (28U)
/* Lower 24 bits hold SDIO I/O OCR */ /* Lower 24 bits hold SDIO I/O OCR */
#define SDIO_IO_OCR_MASK (0xFFFFFFU) #define SDIO_IO_OCR_MASK (0xFFFFFFU)
@ -397,7 +417,7 @@ enum sdhc_clock_speed {
MMC_CLOCK_52MHZ = 52000000U, MMC_CLOCK_52MHZ = 52000000U,
MMC_CLOCK_DDR52 = 52000000U, MMC_CLOCK_DDR52 = 52000000U,
MMC_CLOCK_HS200 = 200000000U, MMC_CLOCK_HS200 = 200000000U,
MMC_CLOCK_HS400 = 400000000U, MMC_CLOCK_HS400 = 200000000U, /* Same clock freq as HS200, just DDR */
}; };
/** /**
@ -525,7 +545,6 @@ struct sd_csd {
/*!< Maximum write current at VDD max [52:50] */ /*!< Maximum write current at VDD max [52:50] */
uint8_t dev_size_mul; uint8_t dev_size_mul;
/*!< Device size multiplier [49:47] */ /*!< Device size multiplier [49:47] */
uint8_t erase_size; uint8_t erase_size;
/*!< Erase sector size [45:39] */ /*!< Erase sector size [45:39] */
uint8_t write_prtect_size; uint8_t write_prtect_size;
@ -538,6 +557,120 @@ struct sd_csd {
/*!< File format [11:10] */ /*!< File format [11:10] */
}; };
/**
* @brief MMC Maximum Frequency
*
* Max freq in MMC csd
*/
enum mmc_csd_freq {
MMC_MAXFREQ_100KHZ = 0U << 0U,
MMC_MAXFREQ_1MHZ = 1U << 0U,
MMC_MAXFREQ_10MHZ = 2U << 0U,
MMC_MAXFREQ_100MHZ = 3U << 0U,
MMC_MAXFREQ_MULT_10 = 1U << 3U,
MMC_MAXFREQ_MULT_12 = 2U << 3U,
MMC_MAXFREQ_MULT_13 = 3U << 3U,
MMC_MAXFREQ_MULT_15 = 4U << 3U,
MMC_MAXFREQ_MULT_20 = 5U << 3U,
MMC_MAXFREQ_MULT_26 = 6U << 3U,
MMC_MAXFREQ_MULT_30 = 7U << 3U,
MMC_MAXFREQ_MULT_35 = 8U << 3U,
MMC_MAXFREQ_MULT_40 = 9U << 3U,
MMC_MAXFREQ_MULT_45 = 0xAU << 3U,
MMC_MAXFREQ_MULT_52 = 0xBU << 3U,
MMC_MAXFREQ_MULT_55 = 0xCU << 3U,
MMC_MAXFREQ_MULT_60 = 0xDU << 3U,
MMC_MAXFREQ_MULT_70 = 0xEU << 3U,
MMC_MAXFREQ_MULT_80 = 0xFU << 3u
};
/**
* @brief MMC Timing Modes
*
* MMC Timing Mode, encoded in EXT_CSD
*/
enum mmc_timing_mode {
MMC_LEGACY_TIMING = 0U,
MMC_HS_TIMING = 1U,
MMC_HS200_TIMING = 2U,
MMC_HS400_TIMING = 3U
};
/**
* @brief MMC Driver Strengths
*
* Encoded in EXT_CSD
*/
enum mmc_driver_strengths {
mmc_driv_type0 = 0U,
mmc_driv_type1 = 1U,
mmc_driv_type2 = 2U,
mmc_driv_type3 = 3U,
mmc_driv_type4 = 4U
};
/**
* @brief MMC Device Type
*
* Encoded in EXT_CSD
*/
struct mmc_device_type {
bool MMC_HS400_DDR_1200MV;
bool MMC_HS400_DDR_1800MV;
bool MMC_HS200_SDR_1200MV;
bool MMC_HS200_SDR_1800MV;
bool MMC_HS_DDR_1200MV;
bool MMC_HS_DDR_1800MV;
bool MMC_HS_52_DV;
bool MMC_HS_26_DV;
};
/**
* @brief CSD Revision
*
* Value of CSD rev in EXT_CSD
*/
enum mmc_ext_csd_rev {
MMC_5_1 = 8U,
MMC_5_0 = 7U,
MMC_4_5 = 6U,
MMC_4_4 = 5U,
MMC_4_3 = 3U,
MMC_4_2 = 2U,
MMC_4_1 = 1U,
MMC_4_0 = 0U
};
/**
* @brief MMC extended card specific data register
*
* Extended card specific data register.
* Contains additional additional data about MMC card.
*/
struct mmc_ext_csd {
uint32_t sec_count;
/*!< Sector Count [215:212] >*/
uint8_t bus_width;
/*!< Bus Width Mode [183] >*/
enum mmc_timing_mode hs_timing;
/*!< High Speed Timing Mode [185] >*/
struct mmc_device_type device_type;
/*!< Device Type [196] >*/
enum mmc_ext_csd_rev rev;
/*!< Extended CSD Revision [192] >*/
uint8_t power_class;
/*!< Selected power class [187]>*/
uint8_t mmc_driver_strengths;
/*!< Driver strengths [197] >*/
uint8_t pwr_class_200MHZ_VCCQ195;
/*!< Power class information for HS200 at VCC!=1.95V [237] >*/
uint8_t pwr_class_HS400;
/*!< Power class information for HS400 [253] >*/
uint32_t cache_size;
/*!< Size of eMMC cache [252:249]>*/
};
/** /**
* @brief SD card specific data flags * @brief SD card specific data flags
* *
@ -622,7 +755,7 @@ enum sd_spec_version {
#define SDMMC_DEFAULT_BLOCK_SIZE (512U) #define SDMMC_DEFAULT_BLOCK_SIZE (512U)
#define MMC_EXT_CSD_BYTES 512
#ifdef __cplusplus #ifdef __cplusplus
} }