mmc: fsl_esdhc: Fix SDR104 and HS200 support
[oweals/u-boot.git] / include / sdhci.h
index 144570f2be9662d43015f1a817adaa7ac6b97c79..94fc3ed56acefb605ec7bc0192a5d2557545a5dd 100644 (file)
@@ -1,15 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright 2011, Marvell Semiconductor Inc.
  * Lei Wen <leiwen@marvell.com>
  *
- * SPDX-License-Identifier:    GPL-2.0+
- *
  * Back ported to the 8xx platform (from the 8260 platform) by
  * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
  */
 #ifndef __SDHCI_HW_H
 #define __SDHCI_HW_H
 
+#include <linux/bitops.h>
+#include <linux/types.h>
 #include <asm/io.h>
 #include <mmc.h>
 #include <asm/gpio.h>
 #define SDHCI_ARGUMENT         0x08
 
 #define SDHCI_TRANSFER_MODE    0x0C
-#define  SDHCI_TRNS_DMA                0x01
-#define  SDHCI_TRNS_BLK_CNT_EN 0x02
-#define  SDHCI_TRNS_ACMD12     0x04
-#define  SDHCI_TRNS_READ       0x10
-#define  SDHCI_TRNS_MULTI      0x20
+#define  SDHCI_TRNS_DMA                BIT(0)
+#define  SDHCI_TRNS_BLK_CNT_EN BIT(1)
+#define  SDHCI_TRNS_ACMD12     BIT(2)
+#define  SDHCI_TRNS_READ       BIT(4)
+#define  SDHCI_TRNS_MULTI      BIT(5)
 
 #define SDHCI_COMMAND          0x0E
 #define  SDHCI_CMD_RESP_MASK   0x03
 #define SDHCI_BUFFER           0x20
 
 #define SDHCI_PRESENT_STATE    0x24
-#define  SDHCI_CMD_INHIBIT     0x00000001
-#define  SDHCI_DATA_INHIBIT    0x00000002
-#define  SDHCI_DOING_WRITE     0x00000100
-#define  SDHCI_DOING_READ      0x00000200
-#define  SDHCI_SPACE_AVAILABLE 0x00000400
-#define  SDHCI_DATA_AVAILABLE  0x00000800
-#define  SDHCI_CARD_PRESENT    0x00010000
-#define  SDHCI_CARD_STATE_STABLE       0x00020000
-#define  SDHCI_CARD_DETECT_PIN_LEVEL   0x00040000
-#define  SDHCI_WRITE_PROTECT   0x00080000
+#define  SDHCI_CMD_INHIBIT     BIT(0)
+#define  SDHCI_DATA_INHIBIT    BIT(1)
+#define  SDHCI_DOING_WRITE     BIT(8)
+#define  SDHCI_DOING_READ      BIT(9)
+#define  SDHCI_SPACE_AVAILABLE BIT(10)
+#define  SDHCI_DATA_AVAILABLE  BIT(11)
+#define  SDHCI_CARD_PRESENT    BIT(16)
+#define  SDHCI_CARD_STATE_STABLE       BIT(17)
+#define  SDHCI_CARD_DETECT_PIN_LEVEL   BIT(18)
+#define  SDHCI_WRITE_PROTECT   BIT(19)
 
 #define SDHCI_HOST_CONTROL     0x28
-#define  SDHCI_CTRL_LED                0x01
-#define  SDHCI_CTRL_4BITBUS    0x02
-#define  SDHCI_CTRL_HISPD      0x04
+#define  SDHCI_CTRL_LED                BIT(0)
+#define  SDHCI_CTRL_4BITBUS    BIT(1)
+#define  SDHCI_CTRL_HISPD      BIT(2)
 #define  SDHCI_CTRL_DMA_MASK   0x18
 #define   SDHCI_CTRL_SDMA      0x00
 #define   SDHCI_CTRL_ADMA1     0x08
 #define   SDHCI_CTRL_ADMA32    0x10
 #define   SDHCI_CTRL_ADMA64    0x18
-#define  SDHCI_CTRL_8BITBUS    0x20
-#define  SDHCI_CTRL_CD_TEST_INS        0x40
-#define  SDHCI_CTRL_CD_TEST    0x80
+#define  SDHCI_CTRL_8BITBUS    BIT(5)
+#define  SDHCI_CTRL_CD_TEST_INS        BIT(6)
+#define  SDHCI_CTRL_CD_TEST    BIT(7)
 
 #define SDHCI_POWER_CONTROL    0x29
 #define  SDHCI_POWER_ON                0x01
@@ -87,9 +88,9 @@
 #define SDHCI_BLOCK_GAP_CONTROL        0x2A
 
 #define SDHCI_WAKE_UP_CONTROL  0x2B
-#define  SDHCI_WAKE_ON_INT     0x01
-#define  SDHCI_WAKE_ON_INSERT  0x02
-#define  SDHCI_WAKE_ON_REMOVE  0x04
+#define  SDHCI_WAKE_ON_INT     BIT(0)
+#define  SDHCI_WAKE_ON_INSERT  BIT(1)
+#define  SDHCI_WAKE_ON_REMOVE  BIT(2)
 
 #define SDHCI_CLOCK_CONTROL    0x2C
 #define  SDHCI_DIVIDER_SHIFT   8
 #define  SDHCI_DIV_MASK        0xFF
 #define  SDHCI_DIV_MASK_LEN    8
 #define  SDHCI_DIV_HI_MASK     0x300
-#define  SDHCI_PROG_CLOCK_MODE  0x0020
-#define  SDHCI_CLOCK_CARD_EN   0x0004
-#define  SDHCI_CLOCK_INT_STABLE        0x0002
-#define  SDHCI_CLOCK_INT_EN    0x0001
+#define  SDHCI_PROG_CLOCK_MODE  BIT(5)
+#define  SDHCI_CLOCK_CARD_EN   BIT(2)
+#define  SDHCI_CLOCK_INT_STABLE        BIT(1)
+#define  SDHCI_CLOCK_INT_EN    BIT(0)
 
 #define SDHCI_TIMEOUT_CONTROL  0x2E
 
 #define SDHCI_INT_STATUS       0x30
 #define SDHCI_INT_ENABLE       0x34
 #define SDHCI_SIGNAL_ENABLE    0x38
-#define  SDHCI_INT_RESPONSE    0x00000001
-#define  SDHCI_INT_DATA_END    0x00000002
-#define  SDHCI_INT_DMA_END     0x00000008
-#define  SDHCI_INT_SPACE_AVAIL 0x00000010
-#define  SDHCI_INT_DATA_AVAIL  0x00000020
-#define  SDHCI_INT_CARD_INSERT 0x00000040
-#define  SDHCI_INT_CARD_REMOVE 0x00000080
-#define  SDHCI_INT_CARD_INT    0x00000100
-#define  SDHCI_INT_ERROR       0x00008000
-#define  SDHCI_INT_TIMEOUT     0x00010000
-#define  SDHCI_INT_CRC         0x00020000
-#define  SDHCI_INT_END_BIT     0x00040000
-#define  SDHCI_INT_INDEX       0x00080000
-#define  SDHCI_INT_DATA_TIMEOUT        0x00100000
-#define  SDHCI_INT_DATA_CRC    0x00200000
-#define  SDHCI_INT_DATA_END_BIT        0x00400000
-#define  SDHCI_INT_BUS_POWER   0x00800000
-#define  SDHCI_INT_ACMD12ERR   0x01000000
-#define  SDHCI_INT_ADMA_ERROR  0x02000000
+#define  SDHCI_INT_RESPONSE    BIT(0)
+#define  SDHCI_INT_DATA_END    BIT(1)
+#define  SDHCI_INT_DMA_END     BIT(3)
+#define  SDHCI_INT_SPACE_AVAIL BIT(4)
+#define  SDHCI_INT_DATA_AVAIL  BIT(5)
+#define  SDHCI_INT_CARD_INSERT BIT(6)
+#define  SDHCI_INT_CARD_REMOVE BIT(7)
+#define  SDHCI_INT_CARD_INT    BIT(8)
+#define  SDHCI_INT_ERROR       BIT(15)
+#define  SDHCI_INT_TIMEOUT     BIT(16)
+#define  SDHCI_INT_CRC         BIT(17)
+#define  SDHCI_INT_END_BIT     BIT(18)
+#define  SDHCI_INT_INDEX       BIT(19)
+#define  SDHCI_INT_DATA_TIMEOUT        BIT(20)
+#define  SDHCI_INT_DATA_CRC    BIT(21)
+#define  SDHCI_INT_DATA_END_BIT        BIT(22)
+#define  SDHCI_INT_BUS_POWER   BIT(23)
+#define  SDHCI_INT_ACMD12ERR   BIT(24)
+#define  SDHCI_INT_ADMA_ERROR  BIT(25)
 
 #define  SDHCI_INT_NORMAL_MASK 0x00007FFF
 #define  SDHCI_INT_ERROR_MASK  0xFFFF8000
 
 #define SDHCI_ACMD12_ERR       0x3C
 
-/* 3E-3F reserved */
+#define SDHCI_HOST_CONTROL2    0x3E
+#define  SDHCI_CTRL_UHS_MASK   0x0007
+#define  SDHCI_CTRL_UHS_SDR12  0x0000
+#define  SDHCI_CTRL_UHS_SDR25  0x0001
+#define  SDHCI_CTRL_UHS_SDR50  0x0002
+#define  SDHCI_CTRL_UHS_SDR104 0x0003
+#define  SDHCI_CTRL_UHS_DDR50  0x0004
+#define  SDHCI_CTRL_HS400      0x0005 /* Non-standard */
+#define  SDHCI_CTRL_VDD_180    0x0008
+#define  SDHCI_CTRL_DRV_TYPE_MASK      0x0030
+#define  SDHCI_CTRL_DRV_TYPE_B 0x0000
+#define  SDHCI_CTRL_DRV_TYPE_A 0x0010
+#define  SDHCI_CTRL_DRV_TYPE_C 0x0020
+#define  SDHCI_CTRL_DRV_TYPE_D 0x0030
+#define  SDHCI_CTRL_EXEC_TUNING        0x0040
+#define  SDHCI_CTRL_TUNED_CLK  0x0080
+#define  SDHCI_CTRL_PRESET_VAL_ENABLE  0x8000
 
 #define SDHCI_CAPABILITIES     0x40
 #define  SDHCI_TIMEOUT_CLK_MASK        0x0000003F
 #define  SDHCI_CLOCK_BASE_SHIFT        8
 #define  SDHCI_MAX_BLOCK_MASK  0x00030000
 #define  SDHCI_MAX_BLOCK_SHIFT  16
-#define  SDHCI_CAN_DO_8BIT     0x00040000
-#define  SDHCI_CAN_DO_ADMA2    0x00080000
-#define  SDHCI_CAN_DO_ADMA1    0x00100000
-#define  SDHCI_CAN_DO_HISPD    0x00200000
-#define  SDHCI_CAN_DO_SDMA     0x00400000
-#define  SDHCI_CAN_VDD_330     0x01000000
-#define  SDHCI_CAN_VDD_300     0x02000000
-#define  SDHCI_CAN_VDD_180     0x04000000
-#define  SDHCI_CAN_64BIT       0x10000000
+#define  SDHCI_CAN_DO_8BIT     BIT(18)
+#define  SDHCI_CAN_DO_ADMA2    BIT(19)
+#define  SDHCI_CAN_DO_ADMA1    BIT(20)
+#define  SDHCI_CAN_DO_HISPD    BIT(21)
+#define  SDHCI_CAN_DO_SDMA     BIT(22)
+#define  SDHCI_CAN_VDD_330     BIT(24)
+#define  SDHCI_CAN_VDD_300     BIT(25)
+#define  SDHCI_CAN_VDD_180     BIT(26)
+#define  SDHCI_CAN_64BIT       BIT(28)
 
 #define SDHCI_CAPABILITIES_1   0x44
+#define  SDHCI_SUPPORT_SDR50   0x00000001
+#define  SDHCI_SUPPORT_SDR104  0x00000002
+#define  SDHCI_SUPPORT_DDR50   0x00000004
+#define  SDHCI_USE_SDR50_TUNING        0x00002000
+
 #define  SDHCI_CLOCK_MUL_MASK  0x00FF0000
 #define  SDHCI_CLOCK_MUL_SHIFT 16
 
 /* 55-57 reserved */
 
 #define SDHCI_ADMA_ADDRESS     0x58
+#define SDHCI_ADMA_ADDRESS_HI  0x5c
 
 /* 60-FB reserved */
 
 #define SDHCI_QUIRK_BROKEN_R1B         (1 << 2)
 #define SDHCI_QUIRK_NO_HISPD_BIT       (1 << 3)
 #define SDHCI_QUIRK_BROKEN_VOLTAGE     (1 << 4)
-#define SDHCI_QUIRK_NO_CD              (1 << 5)
+/*
+ * SDHCI_QUIRK_BROKEN_HISPD_MODE
+ * the hardware cannot operate correctly in high-speed mode,
+ * this quirk forces the sdhci host-controller to non high-speed mode
+ */
+#define SDHCI_QUIRK_BROKEN_HISPD_MODE  BIT(5)
 #define SDHCI_QUIRK_WAIT_SEND_CMD      (1 << 6)
-#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1 << 7)
 #define SDHCI_QUIRK_USE_WIDE8          (1 << 8)
 
 /* to make gcc happy */
@@ -228,21 +255,61 @@ struct sdhci_host;
 #define SDHCI_DEFAULT_BOUNDARY_ARG     (7)
 struct sdhci_ops {
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
-       u32             (*read_l)(struct sdhci_host *host, int reg);
-       u16             (*read_w)(struct sdhci_host *host, int reg);
-       u8              (*read_b)(struct sdhci_host *host, int reg);
-       void            (*write_l)(struct sdhci_host *host, u32 val, int reg);
-       void            (*write_w)(struct sdhci_host *host, u16 val, int reg);
-       void            (*write_b)(struct sdhci_host *host, u8 val, int reg);
+       u32     (*read_l)(struct sdhci_host *host, int reg);
+       u16     (*read_w)(struct sdhci_host *host, int reg);
+       u8      (*read_b)(struct sdhci_host *host, int reg);
+       void    (*write_l)(struct sdhci_host *host, u32 val, int reg);
+       void    (*write_w)(struct sdhci_host *host, u16 val, int reg);
+       void    (*write_b)(struct sdhci_host *host, u8 val, int reg);
 #endif
+       int     (*get_cd)(struct sdhci_host *host);
+       void    (*set_control_reg)(struct sdhci_host *host);
+       int     (*set_ios_post)(struct sdhci_host *host);
+       void    (*set_clock)(struct sdhci_host *host, u32 div);
+       int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
+       void (*set_delay)(struct sdhci_host *host);
+       int     (*deferred_probe)(struct sdhci_host *host);
 };
 
+#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
+#define ADMA_MAX_LEN   65532
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+#define ADMA_DESC_LEN  16
+#else
+#define ADMA_DESC_LEN  8
+#endif
+#define ADMA_TABLE_NO_ENTRIES (CONFIG_SYS_MMC_MAX_BLK_COUNT * \
+                              MMC_MAX_BLOCK_LEN) / ADMA_MAX_LEN
+
+#define ADMA_TABLE_SZ (ADMA_TABLE_NO_ENTRIES * ADMA_DESC_LEN)
+
+/* Decriptor table defines */
+#define ADMA_DESC_ATTR_VALID           BIT(0)
+#define ADMA_DESC_ATTR_END             BIT(1)
+#define ADMA_DESC_ATTR_INT             BIT(2)
+#define ADMA_DESC_ATTR_ACT1            BIT(4)
+#define ADMA_DESC_ATTR_ACT2            BIT(5)
+
+#define ADMA_DESC_TRANSFER_DATA                ADMA_DESC_ATTR_ACT2
+#define ADMA_DESC_LINK_DESC    (ADMA_DESC_ATTR_ACT1 | ADMA_DESC_ATTR_ACT2)
+
+struct sdhci_adma_desc {
+       u8 attr;
+       u8 reserved;
+       u16 len;
+       u32 addr_lo;
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+       u32 addr_hi;
+#endif
+} __packed;
+#endif
 struct sdhci_host {
        const char *name;
        void *ioaddr;
        unsigned int quirks;
        unsigned int host_caps;
        unsigned int version;
+       unsigned int max_clk;   /* Maximum Base Clock frequency */
        unsigned int clk_mul;   /* Clock Multiplier value */
        unsigned int clock;
        struct mmc *mmc;
@@ -253,11 +320,22 @@ struct sdhci_host {
        struct gpio_desc pwr_gpio;      /* Power GPIO */
        struct gpio_desc cd_gpio;               /* Card Detect GPIO */
 
-       void (*set_control_reg)(struct sdhci_host *host);
-       void (*set_clock)(int dev_index, unsigned int div);
        uint    voltages;
 
        struct mmc_config cfg;
+       void *align_buffer;
+       bool force_align_buffer;
+       dma_addr_t start_addr;
+       int flags;
+#define USE_SDMA       (0x1 << 0)
+#define USE_ADMA       (0x1 << 1)
+#define USE_ADMA64     (0x1 << 2)
+#define USE_DMA                (USE_SDMA | USE_ADMA | USE_ADMA64)
+       dma_addr_t adma_addr;
+#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
+       struct sdhci_adma_desc *adma_desc_table;
+       uint desc_slot;
+#endif
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
@@ -372,11 +450,11 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
  *
  * @cfg:       Configuration structure to fill in (generally &plat->mmc)
  * @host:      SDHCI host structure
- * @max_clk:   Maximum supported clock speed in HZ (0 for default)
- * @min_clk:   Minimum supported clock speed in HZ (0 for default)
+ * @f_max:     Maximum supported clock frequency in HZ (0 for default)
+ * @f_min:     Minimum supported clock frequency in HZ (0 for default)
  */
 int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
-                   u32 max_clk, u32 min_clk);
+                   u32 f_max, u32 f_min);
 
 /**
  * sdhci_bind() - Set up a new MMC block device
@@ -402,16 +480,18 @@ int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
  * This is used when you are not using CONFIG_BLK. Convert your driver over!
  *
  * @host:      SDHCI host structure
- * @max_clk:   Maximum supported clock speed in HZ (0 for default)
- * @min_clk:   Minimum supported clock speed in HZ (0 for default)
+ * @f_max:     Maximum supported clock frequency in HZ (0 for default)
+ * @f_min:     Minimum supported clock frequency in HZ (0 for default)
  * @return 0 if OK, -ve on error
  */
-int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk);
+int add_sdhci(struct sdhci_host *host, u32 f_max, u32 f_min);
 #endif /* !CONFIG_BLK */
 
-#ifdef CONFIG_DM_MMC_OPS
+void sdhci_set_uhs_timing(struct sdhci_host *host);
+#ifdef CONFIG_DM_MMC
 /* Export the operations to drivers */
 int sdhci_probe(struct udevice *dev);
+int sdhci_set_clock(struct mmc *mmc, unsigned int clock);
 extern const struct dm_mmc_ops sdhci_ops;
 #else
 #endif