+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2008,2010 Freescale Semiconductor, Inc
* Andy Fleming
*
* Based (loosely) on the Linux code
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _MMC_H_
#include <linux/compiler.h>
#include <part.h>
+#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
+#define MMC_SUPPORTS_TUNING
+#endif
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
+#define MMC_SUPPORTS_TUNING
+#endif
+
/* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */
#define SD_VERSION_SD (1U << 31)
#define MMC_VERSION_MMC (1U << 30)
#define MMC_VERSION_4_1 MAKE_MMC_VERSION(4, 1, 0)
#define MMC_VERSION_4_2 MAKE_MMC_VERSION(4, 2, 0)
#define MMC_VERSION_4_3 MAKE_MMC_VERSION(4, 3, 0)
+#define MMC_VERSION_4_4 MAKE_MMC_VERSION(4, 4, 0)
#define MMC_VERSION_4_41 MAKE_MMC_VERSION(4, 4, 1)
#define MMC_VERSION_4_5 MAKE_MMC_VERSION(4, 5, 0)
#define MMC_VERSION_5_0 MAKE_MMC_VERSION(5, 0, 0)
#define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52)
#define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52)
#define MMC_MODE_HS200 MMC_CAP(MMC_HS_200)
+#define MMC_MODE_HS400 MMC_CAP(MMC_HS_400)
#define MMC_MODE_8BIT BIT(30)
#define MMC_MODE_4BIT BIT(29)
/* SDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
EXT_CSD_CARD_TYPE_HS200_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400_1_8V BIT(6)
+#define EXT_CSD_CARD_TYPE_HS400_1_2V BIT(7)
+#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
+ EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_TIMING_LEGACY 0 /* no high speed */
#define EXT_CSD_TIMING_HS 1 /* HS */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
+#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)
*/
int (*get_wp)(struct udevice *dev);
+#ifdef MMC_SUPPORTS_TUNING
/**
* execute_tuning() - Start the tuning process
*
* @return 0 if OK, -ve on error
*/
int (*execute_tuning)(struct udevice *dev, uint opcode);
+#endif
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
/**
* wait_dat0() - wait until dat0 is in the target state
* (CLK must be running during the wait)
* @return 0 if dat0 is in the target state, -ve on error
*/
int (*wait_dat0)(struct udevice *dev, int state, int timeout);
+#endif
};
#define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops)
SD_LEGACY,
MMC_HS,
SD_HS,
+ MMC_HS_52,
+ MMC_DDR_52,
UHS_SDR12,
UHS_SDR25,
UHS_SDR50,
- UHS_SDR104,
UHS_DDR50,
- MMC_HS_52,
- MMC_DDR_52,
+ UHS_SDR104,
MMC_HS_200,
+ MMC_HS_400,
MMC_MODES_END
};
static inline bool mmc_is_mode_ddr(enum bus_mode mode)
{
- if ((mode == MMC_DDR_52) || (mode == UHS_DDR50))
+ if (mode == MMC_DDR_52)
return true;
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
+ else if (mode == UHS_DDR50)
+ return true;
+#endif
+#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+ else if (mode == MMC_HS_400)
+ return true;
+#endif
else
return false;
}
static inline bool supports_uhs(uint caps)
{
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
return (caps & UHS_CAPS) ? true : false;
+#else
+ return false;
+#endif
}
/*
uint tran_speed;
uint legacy_speed; /* speed for the legacy mode provided by the card */
uint read_bl_len;
+#if CONFIG_IS_ENABLED(MMC_WRITE)
uint write_bl_len;
uint erase_grp_size; /* in 512-byte sectors */
+#endif
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
uint hc_wp_grp_size; /* in 512-byte sectors */
+#endif
+#if CONFIG_IS_ENABLED(MMC_WRITE)
struct sd_ssr ssr; /* SD status register */
+#endif
u64 capacity;
u64 capacity_user;
u64 capacity_boot;
u64 capacity_rpmb;
u64 capacity_gp[4];
+#ifndef CONFIG_SPL_BUILD
u64 enh_user_start;
u64 enh_user_size;
+#endif
#if !CONFIG_IS_ENABLED(BLK)
struct blk_desc block_dev;
#endif
int mmc_initialize(bd_t *bis);
int mmc_init(struct mmc *mmc);
int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
-int mmc_of_parse(const void *fdt, int node, struct mmc_config *cfg);
+
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+ CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+ CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+int mmc_deinit(struct mmc *mmc);
+#endif
+
+/**
+ * mmc_of_parse() - Parse the device tree to get the capabilities of the host
+ *
+ * @dev: MMC device
+ * @cfg: MMC configuration
+ * @return 0 if OK, -ve on error
+ */
+int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg);
+
int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
/**
*/
int mmc_set_clock(struct mmc *mmc, uint clock, bool disable);
+#define MMC_CLK_ENABLE false
+#define MMC_CLK_DISABLE true
+
struct mmc *find_mmc_device(int dev_num);
int mmc_set_dev(int dev_num);
void print_mmc_devices(char separator);
unsigned short cnt, unsigned char *key);
int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk,
unsigned short cnt, unsigned char *key);
+
+/**
+ * mmc_rpmb_route_frames() - route RPMB data frames
+ * @mmc Pointer to a MMC device struct
+ * @req Request data frames
+ * @reqlen Length of data frames in bytes
+ * @rsp Supplied buffer for response data frames
+ * @rsplen Length of supplied buffer for response data frames
+ *
+ * The RPMB data frames are routed to/from some external entity, for
+ * example a Trusted Exectuion Environment in an arm TrustZone protected
+ * secure world. It's expected that it's the external entity who is in
+ * control of the RPMB key.
+ *
+ * Returns 0 on success, < 0 on error.
+ */
+int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen,
+ void *rsp, unsigned long rsplen);
+
#ifdef CONFIG_CMD_BKOPS_ENABLE
int mmc_set_bkops_enable(struct mmc *mmc);
#endif
/**
* Start device initialization and return immediately; it does not block on
+ * polling OCR (operation condition register) status. Useful for checking
+ * the presence of SD/eMMC when no card detect logic is available.
+ *
+ * @param mmc Pointer to a MMC device struct
+ * @return 0 on success, <0 on error.
+ */
+int mmc_get_op_cond(struct mmc *mmc);
+
+/**
+ * Start device initialization and return immediately; it does not block on
* polling OCR (operation condition register) status. Then you should call
* mmc_init, which would block on polling OCR status and complete the device
* initializatin.
*
* @param mmc Pointer to a MMC device struct
- * @return 0 on success, IN_PROGRESS on waiting for OCR status, <0 on error.
+ * @return 0 on success, <0 on error.
*/
int mmc_start_init(struct mmc *mmc);
int board_mmc_init(bd_t *bis);
int cpu_mmc_init(bd_t *bis);
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
+# ifdef CONFIG_SYS_MMC_ENV_PART
+extern uint mmc_get_env_part(struct mmc *mmc);
+# endif
int mmc_get_env_dev(void);
/* Set block count limit because of 16 bit register limit on some hardware*/