/******************************************************************************* Copyright (C) 2016 Marvell International Ltd. SPDX-License-Identifier: BSD-2-Clause-Patent *******************************************************************************/ #include #include #include #include #include #include "XenonPciHci.h" #define SD_BAR_INDEX 0 #define SIZE_512B 0x200 /* Register Offset of SD Host Controller */ #define SDHC_SDMA_ADDR 0x0000 #define SDHC_ARG2 0x0000 #define SDHC_BLK_SIZE 0x0004 #define SDHC_BLK_COUNT 0x0006 #define SDHC_ARG1 0x0008 #define SDHC_TRANS_MOD 0x000C #define SDHC_COMMAND 0x000E #define SDHC_RESPONSE 0x0010 #define SDHC_BUF_DAT_PORT 0x0020 #define SDHC_PRESENT_STATE 0x0024 #define SDHC_HOST_CTRL1 0x0028 #define SDHC_POWER_CTRL 0x0029 #define SDHC_BLK_GAP_CTRL 0x002A #define SDHC_WAKEUP_CTRL 0x002B #define SDHC_CLOCK_CTRL 0x002C #define SDHC_TIMEOUT_CTRL 0x002E #define SDHC_SW_RST 0x002F #define SDHC_NOR_INT_STS 0x0030 #define SDHC_ERR_INT_STS 0x0032 #define SDHC_NOR_INT_STS_EN 0x0034 #define SDHC_ERR_INT_STS_EN 0x0036 #define SDHC_NOR_INT_SIG_EN 0x0038 #define SDHC_ERR_INT_SIG_EN 0x003A #define SDHC_AUTO_CMD_ERR_STS 0x003C #define SDHC_HOST_CTRL2 0x003E #define UHS_MODE_SELECT_MASK 0x7 #define SDHC_CAP 0x0040 #define SDHC_CAP_BUS_WIDTH8 BIT18 #define SDHC_CAP_VOLTAGE_33 BIT24 #define SDHC_CAP_VOLTAGE_30 BIT25 #define SDHC_CAP_VOLTAGE_18 BIT26 #define SDHC_CAP_SLOT_TYPE_OFFSET 30 #define SDHC_CAP_SLOT_TYPE_MASK (BIT30 | BIT31) #define SDHC_CAP_SDR50 BIT32 #define SDHC_CAP_SDR104 BIT33 #define SDHC_CAP_DDR50 BIT34 #define SDHC_CAP_HS400 BIT63 #define SDHC_MAX_CURRENT_CAP 0x0048 #define SDHC_FORCE_EVT_AUTO_CMD 0x0050 #define SDHC_FORCE_EVT_ERR_INT 0x0052 #define SDHC_ADMA_ERR_STS 0x0054 #define SDHC_ADMA_SYS_ADDR 0x0058 #define SDHC_PRESET_VAL 0x0060 #define SDHC_SHARED_BUS_CTRL 0x00E0 #define SDHC_SLOT_INT_STS 0x00FC #define SDHC_CTRL_VER 0x00FE #define SDHC_IPID 0x0100 #define SDHC_SYS_CFG_INFO 0x0104 #define SLOT_TYPE_SDIO_SHIFT 24 #define SLOT_TYPE_EMMC_MASK 0xff #define SLOT_TYPE_EMMC_SHIFT 16 #define SLOT_TYPE_SD_SDIO_MMC_MASK 0xff #define SLOT_TYPE_SD_SDIO_MMC_SHIFT 8 #define SDHC_SYS_OP_CTRL 0x0108 #define AUTO_CLKGATE_DISABLE_MASK (0x1<<20) #define SDCLK_IDLEOFF_ENABLE_MASK (1 << 8) #define SLOT_ENABLE_SHIFT 0 #define SDHC_SYS_EXT_OP_CTRL 0x010c #define MASK_CMD_CONFLICT_ERR (1 << 8) #define SDHC_TEST_OUT 0x0110 #define SDHC_TESTOUT_MUXSEL 0x0114 #define SDHC_SLOT_EXT_INT_STATUS 0x0120 #define SDHC_SLOT_EXT_ERR_STATUS 0x0122 #define SDHC_SLOT_EXT_INT_STATUS_EN 0x0124 #define SDHC_SLOT_EXT_ERR_STATUS_EN 0x0126 #define SDHC_SLOT_OP_STATUS_CTRL 0x0128 #define TUNING_PROG_FIXED_DELAY_MASK 0x7ff #define FORCE_SEL_INVERSE_CLK_SHIFT 11 #define SDHC_SLOT_FIFO_CTRL 0x012c #define SDHC_SLOT_FIFO_DEFAULT_CONFIG 0x315 #define SDHC_SLOT_eMMC_CTRL 0x0130 #define ENABLE_DATA_STROBE_SHIFT 24 #define SET_EMMC_RSTN_SHIFT 16 #define eMMC_VCCQ_MASK 0x3 #define eMMC_VCCQ_1_8V 0x1 #define eMMC_VCCQ_1_2V 0x2 #define eMMC_VCCQ_3_3V 0x3 #define SDHC_SLOT_OUTPUT_DLY_CTRL 0x0134 #define SDHC_SLOT_DCM_CTRL 0x0137 #define SDHC_SLOT_DLL_CTRL 0x0138 #define SELECT_DEF_DLL 0x1 #define SDHC_SLOT_DLL_PHASE_SEL 0x013c #define DLL_UPDATE_STROBE 7 #define SDHC_SLOT_STROBE_DLY_CTRL 0x0140 #define STROBE_DELAY_FIXED_MASK 0xffff #define SDHC_SLOT_RETUNING_REQ_CTRL 0x0144 #define RETUNING_COMPATIBLE 0x1 #define SDHC_SLOT_AUTO_RETUNING_CTRL 0x0148 #define ENABLE_AUTO_RETUNING 0x1 #define SDHC_SLOT_EXT_PRESENT_STATE 0x014c #define SDHC_SLOT_DLL_CUR_DLY_VAL 0x0150 #define SDHC_SLOT_TUNING_CUR_DLY_VAL 0x0154 #define SDHC_SLOT_STROBE_CUR_DLY_VAL 0x0158 #define SDHC_SLOT_SUB_CMD_STRL 0x015c #define SDHC_SLOT_CQ_TASK_INFO 0x0160 #define SDHC_SLOT_TUNING_DEBUG_INFO 0x01f0 #define SDHC_SLOT_DATAIN_DEBUG_INFO 0x01f4 #define SDHC_CMD_RESET_BIT (1 << 1) #define SDHC_DATA_RESET_BIT (1 << 2) #define SDHC_CMD_INHIBIT (1 << 0) #define SDHC_DATA_INHIBIT (1 << 1) #define SDHC_REG_SIZE_1B 1 #define SDHC_REG_SIZE_2B 2 #define SDHC_REG_SIZE_4B 4 #define SDHC_DAT_BUF_PORT_ADDR 0xF06E0020 /* Command register bits description */ #define RESP_TYPE_136_BITS (1 << 0) #define RESP_TYPE_48_BITS (1 << 1) #define RESP_TYPE_48_BITS_NO_CRC ((1 << 0) | (1 << 1)) #define CMD_CRC_CHK_EN (1 << 3) #define CMD_INDEX_CHK_EN (1 << 4) #define DATA_PRESENT (1 << 5) /* Transfer mode register bits description */ #define SDHC_TRNS_BLK_CNT_EN (1 << 1) #define SDHC_TRNS_MULTI_BLK_SEL (1 << 5) #define SDHC_TRNS_TO_HOST_DIR (1 << 4) /* Block size register bits description */ #define BLK_SIZE_HOST_DMA_BDRY_OFFSET 12 #define BLK_SIZE_512KB 0x7 /* Int status register bits description */ #define NOR_INT_STS_CMD_COMPLETE (1 << 0) #define NOR_INT_STS_XFER_COMPLETE (1 << 1) #define NOR_INT_STS_TX_RDY (1 << 4) #define NOR_INT_STS_RX_RDY (1 << 5) #define NOR_INT_STS_CARD_INS (1 << 6) #define NOR_INT_STS_CARD_INT (1 << 8) #define NOR_INT_STS_ERR_INT (1 << 15) #define ERR_INT_STS_CMD_TIMEOUT_ERR (1 << 16) #define ERR_INT_STS_DATA_TIMEOUT_ERR (1 << 20) #define NOR_INT_SIG_EN_CARD_INT (1 << 8) #define PRESENT_STATE_BUFFER_RD_EN (1 << 11) #define PRESENT_STATE_BUFFER_WR_EN (1 << 10) #define SDHC_CLR_IRQ_STS_MASK 0xFFFF #define SDHC_CLR_ALL_IRQ_MASK 0xFFFFFFFFUL /* Max clock in Hz */ #define XENON_MMC_MAX_CLK 400000000 #define XENON_MMC_CLK_RATIO 2046 #define XENON_MMC_BASE_CLK XENON_MMC_MAX_CLK / XENON_MMC_CLK_RATIO #define XENON_MMC_MIN_CLK 100000 #define XENON_MMC_CMD_MAX_TIMEOUT 3200 #define XENON_MMC_CMD_DEFAULT_TIMEOUT 100 /* Tuning Parameter */ #define TMR_RETUN_NO_PRESENT 0xf #define XENON_MAX_TUN_COUNT 0xb #define XENON_SLOT_OP_STATUS_CTRL 0x0128 #define TUN_CONSECUTIVE_TIMES_SHIFT 16 #define TUN_CONSECUTIVE_TIMES_MASK 0x7 #define TUN_CONSECUTIVE_TIMES 0x4 #define TUNING_STEP_SHIFT 12 #define TUNING_STEP_MASK 0xF #define XENON_SLOT_EMMC_CTRL 0x130 #define ENABLE_DATA_STROBE (1 << 24) #define XENON_SLOT_EXT_PRESENT_STATE 0x014C #define DLL_LOCK_STATE 0x1 #define XENON_SLOT_DLL_CUR_DLY_VAL 0x0150 #define EMMC_PHY_REG_BASE 0x170 #define EMMC_PHY_TIMING_ADJUST EMMC_PHY_REG_BASE #define OUTPUT_QSN_PHASE_SELECT (1 << 17) #define SAMPL_INV_QSP_PHASE_SELECT (1 << 18) #define SAMPL_INV_QSP_PHASE_SELECT_SHIFT 18 #define QSN_PHASE_SLOW_MODE_BIT (1 << 29) #define PHY_INITIALIZAION (1 << 31) #define WAIT_CYCLE_BEFORE_USING_MASK 0xf #define WAIT_CYCLE_BEFORE_USING_SHIFT 12 #define FC_SYNC_EN_DURATION_MASK 0xf #define FC_SYNC_EN_DURATION_SHIFT 8 #define FC_SYNC_RST_EN_DURATION_MASK 0xf #define FC_SYNC_RST_EN_DURATION_SHIFT 4 #define FC_SYNC_RST_DURATION_MASK 0xf #define FC_SYNC_RST_DURATION_SHIFT 0 #define EMMC_PHY_FUNC_CONTROL (EMMC_PHY_REG_BASE + 0x4) #define DQ_ASYNC_MODE (1 << 4) #define DQ_DDR_MODE_SHIFT 8 #define DQ_DDR_MODE_MASK 0xff #define CMD_DDR_MODE (1 << 16) #define EMMC_PHY_PAD_CONTROL (EMMC_PHY_REG_BASE + 0x8) #define REC_EN_SHIFT 24 #define REC_EN_MASK 0xf #define FC_DQ_RECEN (1 << 24) #define FC_CMD_RECEN (1 << 25) #define FC_QSP_RECEN (1 << 26) #define FC_QSN_RECEN (1 << 27) #define OEN_QSN (1 << 28) #define AUTO_RECEN_CTRL (1 << 30) #define FC_ALL_CMOS_RECEIVER 0xF000 #define EMMC_PHY_PAD_CONTROL1 (EMMC_PHY_REG_BASE + 0xc) #define EMMC5_1_FC_QSP_PD (1 << 9) #define EMMC5_1_FC_QSP_PU (1 << 25) #define EMMC5_1_FC_CMD_PD (1 << 8) #define EMMC5_1_FC_CMD_PU (1 << 24) #define EMMC5_1_FC_DQ_PD 0xFF #define EMMC5_1_FC_DQ_PU (0xFF << 16) #define EMMC_PHY_PAD_CONTROL2 (EMMC_PHY_REG_BASE + 0x10) #define ZNR_MASK 0x1F #define ZNR_SHIFT 8 #define ZPR_MASK 0x1F #define ZNR_DEF_VALUE 0xF #define ZPR_DEF_VALUE 0xF #define EMMC_PHY_DLL_CONTROL (EMMC_PHY_REG_BASE + 0x14) #define DLL_ENABLE (1 << 31) #define DLL_UPDATE_STROBE_5_0 (1 << 30) #define DLL_REFCLK_SEL (1 << 30) #define DLL_UPDATE (1 << 23) #define DLL_PHSEL1_SHIFT 24 #define DLL_PHSEL0_SHIFT 16 #define DLL_PHASE_MASK 0x3F #define DLL_PHASE_90_DEGREE 0x1F #define DLL_FAST_LOCK (1 << 5) #define DLL_GAIN2X (1 << 3) #define DLL_BYPASS_EN (1 << 0) #define EMMC_LOGIC_TIMING_ADJUST (EMMC_PHY_REG_BASE + 0x18) #define EMMC_LOGIC_TIMING_ADJUST_LOW (EMMC_PHY_REG_BASE + 0x1c) #define LOGIC_TIMING_VALUE 0x5a54 /* Recommend by HW team */ #define TUNING_STEP_DIVIDER_SHIFT 6 /* XENON only have one slot 0 */ #define XENON_MMC_SLOT_ID (0) #define MMC_TIMING_LEGACY 0 #define MMC_TIMING_MMC_HS 1 #define MMC_TIMING_SD_HS 2 #define MMC_TIMING_UHS_SDR12 3 #define MMC_TIMING_UHS_SDR25 4 #define MMC_TIMING_UHS_SDR50 5 #define MMC_TIMING_UHS_SDR104 6 #define MMC_TIMING_UHS_DDR50 7 #define MMC_TIMING_MMC_HS200 8 #define MMC_TIMING_MMC_HS400 10 #define MMC_TIMING_MMC_DDR52 11 /* Custom UHS signaling field values */ #define XENON_SD_MMC_HC_CTRL_HS200 0x5 #define XENON_SD_MMC_HC_CTRL_HS400 0x6 /* Data time out default value 0xE: TMCLK x 227 */ #define DATA_TIMEOUT_DEF_VAL 0xE /* Max retry count for INT status ready */ #define SDHC_INT_STATUS_POLL_RETRY 1000 #define SDHC_INT_STATUS_POLL_RETRY_DATA_TRAN 100000 /* Take 2.5 seconds as generic time out value, 1 microsecond as unit */ #define SD_GENERIC_TIMEOUT 2500 * 1000 /* SDMA start address should allign with 0x8, align mask 0x7 */ #define DMA_START_ADDR_ALIGN_MASK 0x7 #define SDHCI_RETUNE_EVT_INTSIG 0x00001000 /* MMC modes */ #define XENON_MMC_MODE_EMMC 0 #define XENON_MMC_MODE_SD_SDIO 1 /* MMC Voltage */ #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ #define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ #define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ #define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ #define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ #define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ #define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ #define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ #define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ #define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ #define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ #define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ #define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ #define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ #define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ #define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ /* SDHCI FLAGS */ #define SDHCI_POWER_ON 0x01 #define SDHCI_POWER_180 0x0A #define SDHCI_POWER_300 0x0C #define SDHCI_POWER_330 0x0E #define SDHCI_DIVIDER_SHIFT 8 #define SDHCI_DIVIDER_HI_SHIFT 6 #define SDHCI_DIV_MASK 0xFF #define SDHCI_DIV_MASK_LEN 8 #define SDHCI_DIV_HI_MASK 0x300 #define SDHCI_CLOCK_CARD_EN 0x0004 #define SDHCI_CLOCK_INT_STABLE 0x0002 #define SDHCI_CLOCK_INT_EN 0x0001 #define SDHCI_VENDOR_VER_MASK 0xFF00 #define SDHCI_VENDOR_VER_SHIFT 8 #define SDHCI_SPEC_VER_MASK 0x00FF #define SDHCI_SPEC_VER_SHIFT 0 #define SDHCI_SPEC_100 0 #define SDHCI_SPEC_200 1 #define SDHCI_SPEC_300 2 #define SDHCI_SIGNAL_ENABLE 0x38 #define SDHCI_MAX_DIV_SPEC_200 256 #define SDHCI_MAX_DIV_SPEC_300 2046 /* SD DEVICE STATUS FLAGS */ #define CURRENT_STATE_MASK (0xF << 9) #define CURRENT_STATE_N_READY_MASK (7 << 9) #define READY_FOR_DATA (1 << 8) #define CARD_STATUS_ERROR_MASK (~0x0206BF7F) #define RCA_BITS_OFFSET 16 UINTN XenonSetClk ( IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT32 Clock ); VOID XenonPhyInit ( IN EFI_PCI_IO_PROTOCOL *PciIo ); VOID XenonReset ( IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT8 Slot, IN UINT8 Mask ); EFI_STATUS XenonTransferData ( IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT8 Slot, IN OUT VOID *Buffer, IN UINT32 DataLen, IN UINT16 BlockSize, IN UINT16 Blocks, IN BOOLEAN Read ); EFI_STATUS XenonInit ( IN EFI_PCI_IO_PROTOCOL *PciIo, IN BOOLEAN Support1v8, IN BOOLEAN SlowMode, IN UINT8 TuningStepDivisor ); EFI_STATUS XenonSetPhy ( IN EFI_PCI_IO_PROTOCOL *PciIo, IN BOOLEAN SlowMode, IN UINT8 TuningStepDivisor, IN SD_MMC_BUS_MODE Timing );