mmc: When switching partition, use the timeout specified in the ext_csd
[oweals/u-boot.git] / include / mmc.h
index d9611a0e9b5d1536ff3d946c058badc09252821d..032873c2ff9b43266a138087dfa2a440bb873cb3 100644 (file)
 #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_CAP_NONREMOVABLE   BIT(14)
+#define MMC_CAP_NEEDS_POLL     BIT(15)
+#define MMC_CAP_CD_ACTIVE_HIGH  BIT(16)
 
 #define MMC_MODE_8BIT          BIT(30)
 #define MMC_MODE_4BIT          BIT(29)
@@ -221,10 +226,12 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_HS_TIMING              185     /* R/W */
 #define EXT_CSD_REV                    192     /* RO */
 #define EXT_CSD_CARD_TYPE              196     /* RO */
+#define EXT_CSD_PART_SWITCH_TIME       199     /* RO */
 #define EXT_CSD_SEC_CNT                        212     /* RO, 4 bytes */
 #define EXT_CSD_HC_WP_GRP_SIZE         221     /* RO */
 #define EXT_CSD_HC_ERASE_GRP_SIZE      224     /* RO */
 #define EXT_CSD_BOOT_MULT              226     /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME       248     /* RO */
 #define EXT_CSD_BKOPS_SUPPORT          502     /* RO */
 
 /*
@@ -248,6 +255,10 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
                                                /* 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 */
@@ -259,6 +270,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #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)
@@ -408,14 +420,6 @@ struct dm_mmc_ops {
         */
        int (*set_ios)(struct udevice *dev);
 
-       /**
-        * send_init_stream() - send the initialization stream: 74 clock cycles
-        * This is used after power up before sending the first command
-        *
-        * @dev:        Device to update
-        */
-       void (*send_init_stream)(struct udevice *dev);
-
        /**
         * get_cd() - See whether a card is present
         *
@@ -443,7 +447,6 @@ struct dm_mmc_ops {
        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)
@@ -454,7 +457,6 @@ struct dm_mmc_ops {
         * @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)
@@ -462,7 +464,6 @@ struct dm_mmc_ops {
 int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
                    struct mmc_data *data);
 int dm_mmc_set_ios(struct udevice *dev);
-void dm_mmc_send_init_stream(struct udevice *dev);
 int dm_mmc_get_cd(struct udevice *dev);
 int dm_mmc_get_wp(struct udevice *dev);
 int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
@@ -470,7 +471,6 @@ int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout);
 
 /* Transition functions for compatibility */
 int mmc_set_ios(struct mmc *mmc);
-void mmc_send_init_stream(struct mmc *mmc);
 int mmc_getcd(struct mmc *mmc);
 int mmc_getwp(struct mmc *mmc);
 int mmc_execute_tuning(struct mmc *mmc, uint opcode);
@@ -519,6 +519,7 @@ enum bus_mode {
        UHS_DDR50,
        UHS_SDR104,
        MMC_HS_200,
+       MMC_HS_400,
        MMC_MODES_END
 };
 
@@ -532,6 +533,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode)
 #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;
@@ -582,6 +587,8 @@ struct mmc {
        u8 part_attr;
        u8 wr_rel_set;
        u8 part_config;
+       u8 gen_cmd6_time;
+       u8 part_switch_time;
        uint tran_speed;
        uint legacy_speed; /* speed for the legacy mode provided by the card */
        uint read_bl_len;
@@ -679,6 +686,12 @@ int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
 
+#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
  *
@@ -707,6 +720,9 @@ int mmc_voltage_to_mv(enum mmc_voltage voltage);
  */
 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);
@@ -745,10 +761,39 @@ int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk,
                  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
@@ -756,7 +801,7 @@ int mmc_set_bkops_enable(struct mmc *mmc);
  * 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);
 
@@ -785,8 +830,14 @@ void board_mmc_power_init(void);
 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);
 
+/* Minimum partition switch timeout in units of 10-milliseconds */
+#define MMC_MIN_PART_SWITCH_TIME       30 /* 300 ms */
+
 /* Set block count limit because of 16 bit register limit on some hardware*/
 #ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
 #define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535