+/* 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 ENHNCD_SUPPORT (0x2)
#define PART_ENH_ATTRIB (0x1f)
+#define MMC_QUIRK_RETRY_SEND_CID BIT(0)
+#define MMC_QUIRK_RETRY_SET_BLOCKLEN BIT(1)
+
enum mmc_voltage {
MMC_SIGNAL_VOLTAGE_000 = 0,
- MMC_SIGNAL_VOLTAGE_120,
- MMC_SIGNAL_VOLTAGE_180,
- MMC_SIGNAL_VOLTAGE_330
+ MMC_SIGNAL_VOLTAGE_120 = 1,
+ MMC_SIGNAL_VOLTAGE_180 = 2,
+ MMC_SIGNAL_VOLTAGE_330 = 4,
};
+#define MMC_ALL_SIGNAL_VOLTAGE (MMC_SIGNAL_VOLTAGE_120 |\
+ MMC_SIGNAL_VOLTAGE_180 |\
+ MMC_SIGNAL_VOLTAGE_330)
+
/* Maximum block size for MMC */
#define MMC_MAX_BLOCK_LEN 512
*/
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_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
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
#endif
#endif
u8 *ext_csd;
- enum bus_mode selected_mode;
+ u32 cardtype; /* cardtype read from the MMC */
+ enum mmc_voltage current_voltage;
+ enum bus_mode selected_mode; /* mode currently used */
+ enum bus_mode best_mode; /* best mode is the supported mode with the
+ * highest bandwidth. It may not always be the
+ * operating mode due to limitations when
+ * accessing the boot partitions
+ */
+ u32 quirks;
};
struct mmc_hwpart_conf {
int mmc_unbind(struct udevice *dev);
int mmc_initialize(bd_t *bis);
int mmc_init(struct mmc *mmc);
+int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
+
+/**
+ * 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);
+/**
+ * mmc_voltage_to_mv() - Convert a mmc_voltage in mV
+ *
+ * @voltage: The mmc_voltage to convert
+ * @return the value in mV if OK, -EINVAL on error (invalid mmc_voltage value)
+ */
+int mmc_voltage_to_mv(enum mmc_voltage voltage);
+
/**
* mmc_set_clock() - change the bus clock
* @mmc: MMC struct
*/
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);