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: |
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
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 max_blk_len: 2;
unsigned int bus_8_bit_support: 1;
unsigned int bus_4_bit_support: 1;
unsigned int adma_2_support: 1;
unsigned int _rsvd_20: 1;
unsigned int high_spd_support: 1;
@ -193,6 +194,8 @@ struct sdhc_host_caps {
unsigned int adma3_support: 1;
unsigned int vdd2_180_support: 1;
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_SDIO = 1, /*!< SD 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_size; /*!< SD block size */
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_type type; /*!< Card type */
uint32_t flags; /*!< Card flags */

View file

@ -26,22 +26,28 @@ extern "C" {
*/
enum sd_opcode {
SD_GO_IDLE_STATE = 0,
MMC_SEND_OP_COND = 1,
SD_ALL_SEND_CID = 2,
SD_SEND_RELATIVE_ADDR = 3,
MMC_SEND_RELATIVE_ADDR = 3,
SDIO_SEND_OP_COND = 5, /* SDIO cards only */
SD_SWITCH = 6,
SD_SELECT_CARD = 7,
SD_SEND_IF_COND = 8,
MMC_SEND_EXT_CSD = 8,
SD_SEND_CSD = 9,
SD_SEND_CID = 10,
SD_VOL_SWITCH = 11,
SD_STOP_TRANSMISSION = 12,
SD_SEND_STATUS = 13,
MMC_CHECK_BUS_TEST = 14,
SD_GO_INACTIVE_STATE = 15,
SD_SET_BLOCK_SIZE = 16,
SD_READ_SINGLE_BLOCK = 17,
SD_READ_MULTIPLE_BLOCK = 18,
SD_SEND_TUNING_BLOCK = 19,
MMC_SEND_BUS_TEST = 19,
MMC_SEND_TUNING_BLOCK = 21,
SD_SET_BLOCK_COUNT = 23,
SD_WRITE_SINGLE_BLOCK = 24,
SD_WRITE_MULTIPLE_BLOCK = 25,
@ -278,6 +284,20 @@ enum sd_ocr_flag {
/*!< 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)
/* Lower 24 bits hold SDIO I/O OCR */
#define SDIO_IO_OCR_MASK (0xFFFFFFU)
@ -397,7 +417,7 @@ enum sdhc_clock_speed {
MMC_CLOCK_52MHZ = 52000000U,
MMC_CLOCK_DDR52 = 52000000U,
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] */
uint8_t dev_size_mul;
/*!< Device size multiplier [49:47] */
uint8_t erase_size;
/*!< Erase sector size [45:39] */
uint8_t write_prtect_size;
@ -538,6 +557,120 @@ struct sd_csd {
/*!< 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
*
@ -622,7 +755,7 @@ enum sd_spec_version {
#define SDMMC_DEFAULT_BLOCK_SIZE (512U)
#define MMC_EXT_CSD_BYTES 512
#ifdef __cplusplus
}