/** * @file sdrv_sdhci.h * @brief SemiDrive SDHCI driver header file. * * @copyright Copyright (c) 2022 Semidrive Semiconductor. * All rights reserved. */ #ifndef SDRV_SDHCI_H_ #define SDRV_SDHCI_H_ #include #include #if CONFIG_OS_FREERTOS #include #include #include #include #include #include #endif #include "sdrv_common.h" #undef BIT #define BIT(nr) (1U << (nr)) #define SDHCI_CMD_SW_TIMEOUT 0x100 #define SDHCI_DATA_SW_TIMEOUT 0x1000 #define SDHCI_INHIBIT_COUNT 0x100 #define ADMA_DESC_LIST_SIZE (64) #define SDHCI_HW_TUNING_MIN_COUNT 40 #ifdef SDHCI_DESC_ADDR_64BITS #define desc_entry desc_entry_a64 #else #define desc_entry desc_entry_a32 #endif #define SDHCI_MMC_RETRY #ifdef SDHCI_MMC_RETRY #define MMC_CMD_RETRIES 0x3 #else #define MMC_CMD_RETRIES 0x0 #endif #define SDHCI_TRANS_COUNT_MAX 0x10 /** * @brief Capabilities for the host controller * These values are read from the capabilities * egister in the controller */ struct host_caps { uint32_t base_clk_rate; /**< Max clock rate supported */ uint32_t max_blk_len; /**< Max block len supported */ uint8_t bus_width_8bit; /**< 8 Bit mode supported */ uint8_t spec_version; /**< spec version num in sdhci controller */ uint8_t adma2_support; /**< Adma2 support */ uint8_t addr_64bit_v3; /**< addr 64bit for v3 support */ uint8_t addr_64bit_v4; /**< addr 64bit for v3 support */ uint8_t voltage; /**< Supported voltage */ uint8_t sdr_support; /**< Single Data rate */ uint8_t ddr_support; /**< Dual Data rate */ uint8_t sdr50_support; /**< UHS mode, with 100 MHZ clock */ uint8_t sdr104_support; /**< UHS mode, with 200 MHZ clock */ uint8_t hs200_support; /**< Hs200 mode, with 200 MHZ clock */ uint8_t hs400_support; /**< Hs400 mode, with 400 MHZ clock */ uint8_t hw_reset_support; /**< SDHC hardware reset supported or not */ uint8_t uhs_support; /**< SDHC hardware supported uhs mode */ }; /** @brief Data pointer to be read/written */ struct mmc_data { void *data_ptr; /**< Points to stream of data */ struct desc_entry *sg_list; uint32_t blk_sz; /**< Block size for the data */ uint32_t num_blocks; /**< num of blocks, each always of size SDHCI_MMC_BLK_SZ */ }; /** @brief mmc command structure as per the spec */ struct mmc_command { uint16_t cmd_index; /**< Command index */ uint32_t argument; /**< Command argument */ uint8_t data_present; /**< Command has data */ uint8_t cmd_type; /**< command type */ uint16_t resp_type; /**< Response type of the command */ uint32_t resp[4]; /**< 128 bit response value */ uint32_t trans_mode; /**< Transfer mode, read/write */ uint32_t cmd_retry; /**< Retry the command, if card is busy */ uint32_t cmd23_support; /**< If card supports cmd23 */ uint64_t cmd_timeout; /**< Command timeout in us */ bool write_flag; /**< Write flag, for reliable write cases */ uint32_t error; uint32_t retries; struct mmc_data data; /**< Data pointer */ // uint32_t data_complete; /**< non zero: complete*/ }; /** @brief sdhci host structure, holding information about host controller parameters*/ struct sdhci_host { uint32_t slot; addr_t base; /**< Base address for the host */ uint32_t irq; /**< sdhci host irq num */ #define SDHCI_SYNC_MODE (0) #define SDHCI_ASYNC_MODE (1) uint32_t async_mode; #if CONFIG_OS_FREERTOS SemaphoreHandle_t cmd_sema; SemaphoreHandle_t data_sema; SemaphoreHandle_t data_complete_sema; SemaphoreHandle_t timer_sema; TimerHandle_t data_timer; uint32_t data_end_trans_count; #endif //spin_lock_t spin_lock; /**< reverse */ uint32_t cur_clk_rate; /**< Running clock rate */ uint32_t max_clk_rate; /**< Max clock rate host surpport */ uint32_t timing; /**< current timing for the host */ uint32_t card_type; uint32_t bus_width; uint8_t tuning_in_progress; uint8_t sw_tuning_in_progress; struct mmc_command *cmd; struct mmc_command data_cmd; struct host_caps caps; /**< Host capabilities */ void *priv_data; /**< Specific host info */ void *parent; /**< hal mmc handle*/ struct sdhci_ops *ops; }; /** @brief sdhci platform ops, hw Specific interface controller parameters */ struct sdhci_ops { void (*priv_init)(struct sdhci_host *host); void (*hw_reset)(struct sdhci_host *host); status_t (*set_clock)(struct sdhci_host *host, unsigned int clock); void (*set_power)(struct sdhci_host *host); void (*config_pin)(struct sdhci_host *host); void (*set_uhs_mode)(struct sdhci_host *host, uint32_t mode); bool (*mmc_ending_trans)(struct sdhci_host *host); status_t (*platform_execute_tuning)(struct sdhci_host *host, uint32_t opcode, uint32_t bus_width); }; /** @brief Descriptor table for adma */ struct desc_entry_a32 { uint32_t tran_att; /**< Attribute for transfer data and length of data */ uint32_t addr; /**< Address of the data */ }; /** @brief Descriptor table for adma */ struct desc_entry_a64 { uint32_t tran_att; /**< Attribute for transfer data */ uint32_t addr_l; /**< Address of the data */ uint32_t addr_h; uint32_t rsvd; }; /** @brief Card types for sdhci */ typedef enum { SDHCI_EMMC_CARD = 0, SDHCI_SD_CARD, SDHCI_UHS2_CARD, SDHCI_SDIO_CARD, SDHCI_CARD_TYPE_ABORT, } sdhci_card_type; /** @brief Command types for sdhci */ typedef enum { SDHCI_CMD_TYPE_NORMAL = 0, SDHCI_CMD_TYPE_SUSPEND, SDHCI_CMD_TYPE_RESUME, SDHCI_CMD_TYPE_ABORT, } sdhci_cmd_type; /** @brief Response type values for sdhci */ typedef enum { SDHCI_CMD_RESP_NONE = 0, SDHCI_CMD_RESP_136, SDHCI_CMD_RESP_48, SDHCI_CMD_RESP_48_BUSY, } sdhci_resp_type; /** @name writing byte, word & long registers * Helper macros for writing byte, word & long registers */ #define readhw(a) (*REG16(a)) #define writehw(v, a) (*REG16(a) = (v)) #define REG_READ8(host, a) readb(((host)->base) + (a)) #define REG_WRITE8(host, v, a) writeb((v), (((host)->base) + (a))) #define REG_READ32(host, a) readl(((host)->base) + (a)) #define REG_WRITE32(host, v, a) writel((v), (((host)->base) + (a))) #define REG_RMW32(host, a, s, w, v) RMWREG32((((host)->base) + (a)), (s), (w), (v)) #define REG_READ16(host, a) readhw(((host)->base) + (a)) #define REG_WRITE16(host, v, a) writehw((v), (((host)->base) + (a))) /** @name SDHCI event flag for cmsis api * SDHCI event flag for cmsis api macros definitions */ #define SDHCI_CMD_EVENT_FLAG 0x1u #define SDHCI_DATA_EVENT_FLAG 0x1u #define SDHCI_DATA_COMPLETE_EVENT_FLAG 0x1u /** @name SDHCI registers, as per the host controller spec v 3.0 * SDHCI registers, as per the host controller spec v 3.0 macros definitions */ #define SDHCI_SDMASA_BLKCNT_REG (0x000) #define SDHCI_BLKSZ_REG (0x004) #define SDHCI_BLK_CNT_REG (0x006) #define SDHCI_ARGUMENT_REG (0x008) #define SDHCI_TRANS_MODE_REG (0x00C) #define SDHCI_CMD_REG (0x00E) #define SDHCI_RESP_REG (0x010) #define SDHCI_BUF_DATA (0x020) #define SDHCI_PRESENT_STATE_REG (0x024) #define SDHCI_HOST_CTRL1_REG (0x028) #define SDHCI_PWR_CTRL_REG (0x029) #define SDHCI_CLK_CTRL_REG (0x02C) #define SDHCI_TIMEOUT_REG (0x02E) #define SDHCI_RESET_REG (0x02F) #define SDHCI_NRML_INT_STS_REG (0x030) #define SDHCI_ERR_INT_STS_REG (0x032) #define SDHCI_NRML_INT_STS_EN_REG (0x034) #define SDHCI_ERR_INT_STS_EN_REG (0x036) #define SDHCI_NRML_INT_SIG_EN_REG (0x038) #define SDHCI_ERR_INT_SIG_EN_REG (0x03A) #define SDHCI_AUTO_CMD_ERR (0x03C) #define SDHCI_HOST_CTRL2_REG (0x03E) #define SDHCI_CAPS_REG1 (0x040) #define SDHCI_CAPS_REG2 (0x044) #define SDHCI_ADM_ERR_REG (0x054) #define SDHCI_ADM_ADDR_REG (0x058) #define SDHCI_VENDOR_BASE_REG (0xE8) #define SDHCI_SPEC_VERSION_REG (0xFE) #define SDHCI_VENDER_AT_CTRL_REG (0x40) #define SDHCI_TUNE_SWIN_TH_VAL_MASK 0xFF #define SDHCI_TUNE_SWIN_TH_VAL_LSB (24) #define SDHCI_TUNE_CLK_STOP_EN_MASK BIT(16) /** @name Helper macros for register writes * Helper macros for register writes macros definitions */ #define SDHCI_SOFT_RESET BIT(0) #define SOFT_RESET_CMD BIT(1) #define SOFT_RESET_DATA BIT(2) #define SDHCI_RESET_MAX_TIMEOUT 0x64 #define SDHCI_1_8_VOL_SET BIT(3) /** @name Interrupt related * Interrupt related macros definitions */ #define SDHCI_NRML_INT_STS_EN 0x003B #define SDHCI_ERR_INT_STS_EN 0xFFFF #define SDHCI_NRML_INT_SIG_EN 0x003B #define SDHCI_ERR_INT_SIG_EN 0xFFFF #define SDCC_HC_INT_CARD_REMOVE BIT(7) #define SDCC_HC_INT_CARD_INSERT BIT(6) #define SDHCI_INT_RESPONSE BIT(0) #define SDHCI_INT_DATA_END BIT(1) #define SDHCI_INT_BLK_GAP BIT(2) #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_RETUNE BIT(12) #define SDHCI_INT_CQE BIT(14) #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_INT_CMD_MASK \ (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | \ SDHCI_INT_END_BIT | SDHCI_INT_INDEX | SDHCI_INT_ACMD12ERR) #define SDHCI_INT_DATA_MASK \ (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | SDHCI_INT_DATA_AVAIL | \ SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | SDHCI_INT_BLK_GAP) #define SDHCI_INT_ABORT_MASK \ (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | SDHCI_INT_END_BIT | \ SDHCI_INT_INDEX) /** @name HC mode enable/disable * HC mode enable/disable macros definitions */ #define SDHCI_HC_MODE_EN BIT(0) #define SDHCI_HC_MODE_DIS (0 << 1) /** @name Clk control related * Clk control related macros definitions */ #define SDHCI_CLK_MAX_DIV 2046 #define SDHCI_SDCLK_FREQ_SEL 8 #define SDHCI_SDCLK_UP_BIT_SEL 6 #define SDHCI_SDCLK_FREQ_MASK 0xFF #define SDHC_SDCLK_UP_BIT_MASK 0x300 #define SDHCI_INT_CLK_EN BIT(0) #define SDHCI_CLK_STABLE_MASK BIT(1) #define SDHCI_CLK_STABLE BIT(1) #define SDHCI_CLK_EN BIT(2) #define SDHCI_CLK_DIS (0 << 2) #define SDHCI_CLK_PLL_EN BIT(3) #define SDHCI_CLK_RATE_MASK 0x0000FF00 #define SDHCI_CLK_RATE_BIT 8 #define SDHCI_CMD_ACT BIT(0) #define SDHCI_DAT_ACT BIT(1) /** @name Bus voltage related * Bus voltage related macros macros definitions */ #define SDHCI_BUS_VOL_SEL 1 #define SDHCI_BUS_PWR_EN BIT(0) #define SDHCI_VOL_1_8 5 #define SDHCI_VOL_3_0 6 #define SDHCI_EMMC_VOL_1_8 5 #define SDHCI_EMMC_VOL_3_0 6 #define SDHCI_VOL_3_3 7 #define SDHCI_3_3_VOL_MASK 0x01000000 #define SDHCI_3_0_VOL_MASK 0x02000000 #define SDHCI_1_8_VOL_MASK 0x04000000 /** @name Bus width related * Bus width related macros definitions */ #define SDHCI_8BIT_WIDTH_MASK 0x00040000 #define SDHCI_BUS_WITDH_1BIT (0) #define SDHCI_BUS_WITDH_4BIT BIT(1) #define SDHCI_BUS_WITDH_8BIT BIT(5) /** @name Adma related * Adma related macros definitions */ #define SDHCI_BLK_LEN_MASK 0x00030000 #define SDHCI_BLK_LEN_BIT 16 #define SDHCI_BLK_ADMA_MASK 0x00080000 #define SDHCI_INT_STS_TRANS_COMPLETE BIT(1) #define SDHCI_STATE_CMD_MASK BIT(0) #define SDHCI_STATE_DAT_MASK BIT(1) #define SDHCI_STATE_CMD_DAT_MASK 0x0003 #define SDHCI_INT_STS_CMD_COMPLETE BIT(0) #define SDHCI_ERR_INT_STAT_MASK 0x8000 #define SDHCI_ADMA_DESC_LINE_SZ 0x10000 #define SDHCI_ADMA_MAX_TRANS_SZ (0xFFFFFFFFF * 512) #define SDHCI_ADMA_TRANS_VALID BIT(0) #define SDHCI_ADMA_TRANS_END BIT(1) #define SDHCI_ADMA_TRANS_INT BIT(2) #define SDHCI_ADMA_TRANS_DATA BIT(5) #define SDHCI_ADMA_DATA_VALID SDHCI_ADMA_TRANS_DATA | SDHCI_ADMA_TRANS_VALID #define SDHCI_ADMA_DATA_VALID_END SDHCI_ADMA_TRANS_DATA | SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_END #define SDHCI_ADMA_NOP_END_VALID SDHCI_ADMA_TRANS_END | SDHCI_ADMA_TRANS_VALID #define SDHCI_MMC_BLK_SZ 512 #define SDHCI_MMC_CUR_BLK_CNT_BIT 16 #define SDHCI_MMC_BLK_SZ_BIT 0 #define SDHCI_TRANS_MULTI BIT(5) #define SDHCI_TRANS_SINGLE (0 << 5) #define SDHCI_BLK_CNT_EN BIT(1) #define SDHCI_DMA_EN BIT(0) #define SDHCI_AUTO_CMD23_EN BIT(3) #define SDHCI_AUTO_CMD12_EN BIT(2) #define SDHCI_ADMA_32BIT BIT(4) #define SDHCI_ADMA_64BIT (BIT(3) | BIT(4)) #define SDHCI_ADMA2_SEL BIT(4) #define SDHCI_ADMA23_SEL (BIT(3) | BIT(4)) #define SDHCI_ADMA_SEL_MASK (BIT(3) | BIT(4)) /** @name Adma2 v4 spec related * AAdma2 v4 spec related macros definitions */ #define SDHCI_SPEC_VER4_NUM (0x3) #define SDHCI_CAP_ADDR_64BIT_V3 BIT(28) #define SDHCI_CAP_ADDR_64BIT_V4 BIT(27) #define SDHCI_ADMA_64BIT_V4 BIT(13) #define SDHCI_VER4_ENABLE BIT(12) #define SDHCI_ADMA2_26BIT_LEN_MODE BIT(10) #define SDHCI_ADMA2_DESC_LINE_SZ_V4 0x1000000 #define SDHCI_ADMA2_MAX_TRANS_SZ_V4 (0xFFFFFFFF * 512) #define SDHCI_ADMA2_DESC_26BIT_LEN_LSB (6) #define SDHCI_ADMA2_DESC_16BIT_LEN_LSB (16) /** @name Command related * Command related macros definitions */ #define SDHCI_CMD_RESP_TYPE_SEL_BIT 0 #define SDHCI_CMD_CRC_CHECK_BIT 3 #define SDHCI_CMD_IDX_CHECK_BIT 4 #define SDHCI_CMD_DATA_PRESENT_BIT 5 #define SDHCI_CMD_CMD_TYPE_BIT 6 #define SDHCI_CMD_CMD_IDX_BIT 8 #define SDHCI_CMD_TIMEOUT_MASK BIT(0) #define SDHCI_CMD_CRC_MASK BIT(1) #define SDHCI_CMD_END_BIT_MASK BIT(2) #define SDHCI_CMD_IDX_MASK BIT(3) #define SDHCI_DAT_TIMEOUT_MASK BIT(4) #define SDHCI_DAT_CRC_MASK BIT(5) #define SDHCI_DAT_END_BIT_MASK BIT(6) #define SDHCI_CUR_LIM_MASK BIT(7) #define SDHCI_AUTO_CMD12_MASK BIT(8) #define SDHCI_CMD_SW_TIMEOUT_MASK BIT(16) #define SDHCI_DAT_SW_TIMEOUT_MASK BIT(17) #define SDHCI_ADMA_MASK BIT(9) #define SDHCI_READ_MODE BIT(4) #define SDHCI_SWITCH_CMD 6 #define SDHCI_CMD_TIMEOUT 0xE #define SDHCI_MAX_CMD_RETRY 5000000 #define SDHCI_MAX_TRANS_RETRY 10000000 #define SDHCI_CMD_ERR_MASK \ (SDHCI_CMD_TIMEOUT_MASK | SDHCI_CMD_CRC_MASK | SDHCI_CMD_END_BIT_MASK | \ SDHCI_CMD_IDX_MASK | SDHCI_AUTO_CMD12_MASK) #define SDHCI_DATA_ERR_MASK \ (SDHCI_DAT_TIMEOUT_MASK | SDHCI_DAT_CRC_MASK | SDHCI_DAT_END_BIT_MASK | \ SDHCI_ADMA_MASK) /*! * @} */ /* end of Command related */ #define SDHCI_HIGH_SPEED_EN BIT(2) #define SDHCI_SAMPLE_CLK_SEL BIT(7) #define SDHCI_EXEC_TUNING BIT(6) #define SDHCI_PREP_CMD(c, f) ((((c)&0xff) << 8) | ((f)&0xff)) /** @name command response related * command response related macros definitions */ #define SDHCI_RESP_LSHIFT 8 #define SDHCI_RESP_RSHIFT 24 /** @name Power control relatd * Power control relatd macros definitions */ #define SDCC_HC_PWR_CTRL_INT 0xF #define SDCC_HC_BUS_ON BIT(0) #define SDCC_HC_BUS_OFF BIT(1) #define SDCC_HC_BUS_ON_OFF_SUCC BIT(0) #define SDCC_HC_IO_SIG_LOW BIT(2) #define SDCC_HC_IO_SIG_HIGH BIT(3) #define SDCC_HC_IO_SIG_SUCC BIT(2) /** @name Command respons * Command respons macros definitions */ #define SDHCI_CMD_RESP_NONE 0 #define SDHCI_CMD_RESP_R1 BIT(0) #define SDHCI_CMD_RESP_R1B BIT(1) #define SDHCI_CMD_RESP_R2 BIT(2) #define SDHCI_CMD_RESP_R3 BIT(3) #define SDHCI_CMD_RESP_R6 BIT(6) #define SDHCI_CMD_RESP_R7 BIT(7) /** @name Clock Divider values * Clock Divider values macros definitions */ #define SDHCI_CLK_400KHZ 400000 #define SDHCI_CLK_25MHZ 25000000 #define SDHCI_CLK_50MHZ 50000000 #define SDHCI_CLK_100MHZ 100000000 #define SDHCI_CLK_200MHZ 200000000 #define SDHCI_CLK_400MHZ 400000000 /** @brief UHS macros */ #define SDHCI_UHS_MODE_MASK 0x0007 /** @name uhs mode related * uhs mode related macros definitions */ #define SDHCI_SDR50_MODE_MASK BIT(0) #define SDHCI_SDR104_MODE_MASK BIT(1) #define SDHCI_DDR50_MODE_MASK BIT(2) #define SDHCI_UHS_SDR104_MODE 0x3 #define SDHCI_UHS_SDR50_MODE 0x2 #define SDHCI_UHS_DDR50_MODE 0x4 #define SDHCI_UHS_SDR25_MODE 0x1 #define SDHCI_UHS_SDR12_MODE 0x0 #define SDHCI_EMMC_HS400_MODE 0x7 #define SDHCI_EMMC_DDR52_MODE 0x4 #define SDHCI_EMMC_HS200_MODE 0x3 #define SDHCI_EMMC_HISPEED_MODE 0x1 #define SDHCI_EMMC_LEGACY_MODE 0x0 /** @name mmc bus width * mmc bus width macros definitions */ #define MMC_BUS_WIDTH_1BIT 0 #define MMC_BUS_WIDTH_4BIT 1 #define MMC_BUS_WIDTH_8BIT 2 /** @name PRESENT STATE * PRESENT STATE macros definitions */ #define SDHCI_PSTATE_DAT_3_0_MASK 0x00f00000 #define SDHCI_PSTATE_DAT_7_4_MASK 0x000000f0 #define SDHCI_PSTATE_CMD_INHIBIT_DAT_MASK BIT(1) #define SDHCI_PSTATE_CMD_INHIBIT_MASK BIT(0) #define SDHCI_PRESENT_STATE_DAT_MASK (SDHCI_PSTATE_DAT_3_0_MASK | SDHCI_PSTATE_DAT_7_4_MASK) #define SDHCI_PRESENT_STATE_DAT_8BIT_MASK (SDHCI_PSTATE_DAT_3_0_MASK | SDHCI_PSTATE_DAT_7_4_MASK) #define SDHCI_PRESENT_STATE_DAT_4BIT_MASK (SDHCI_PSTATE_DAT_3_0_MASK) #define SDHCI_PRESENT_STATE_DAT_1BIT_MASK (SDHCI_PSTATE_DAT_3_0_MASK & 0x00100000) /** @name APIs and macros exposed for mmc/sd drivers * APIs and macros exposed for mmc/sd drivers macros definitions */ #define SDHCI_MMC_WRITE 0 #define SDHCI_MMC_READ 1 /** @name mmc data bus width * mmc data bus width macros definitions */ #define MMC_DATA_BUS_WIDTH_1BIT 0 #define MMC_DATA_BUS_WIDTH_4BIT 1 #define MMC_DATA_BUS_WIDTH_8BIT 2 #define MMC_DATA_DDR_BUS_WIDTH_4BIT 5 #define MMC_DATA_DDR_BUS_WIDTH_8BIT 6 #ifndef DETAIL_PRINTF #define DETAIL_PRINTF(level, x...) \ { \ ssdk_printf(level, "[%s|%d|%s]\n",__FILE__,__LINE__,__func__); \ ssdk_printf(level,x); \ } #endif /*! * @} */ /* end of group mmc data bus width */ #define FV_ADMA2_ATTR_LEN(v) \ ((((v)&0xffffU) << 16) | ((((v)&0x3ff0000U)) >> 10)) /** @brief sdhci wait for bit mask*/ inline static status_t sdrv_sdhci_wait_for_bit(struct sdhci_host *host, addr_t reg, uint16_t mask, bool clear, uint32_t ms) { uint32_t val; uint32_t timeout; timeout = ms * 1000; //reserve //timeout = current_time() + ms; while (timeout --) { val = REG_READ16(host, reg); if (clear) val = ~val; val &= mask; if (val == mask) return SDRV_STATUS_OK; //if (current_time() > timeout) if (timeout == 0) return SDRV_STATUS_TIMEOUT; udelay(1); } return SDRV_STATUS_FAIL; } /** * @brief initialize the controller. * @param[in] host sdhci host structure * @details reset the controller, read the capabilities register and set initial bus width */ void sdrv_sdhci_init(struct sdhci_host *host); /** * @brief sdhci send command * @details prepare the command register and run the command * @param[in] host sdhci host structure * @param[in] cmd mmc command structure * @details reset the controller, read the capabilities register and set initial bus width * @return uint32_t * @retval 0: success * @retval other: failed */ status_t sdrv_sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd); /** * @brief set the bus width for controller * @param[in] host sdhci host structure * @param[in] width mmc bus witdh * @return uint8_t * @retval 0: success * @retval other: failed */ status_t sdrv_sdhci_set_bus_width(struct sdhci_host *host, uint16_t width); /** * @brief sdhci execute tuning * @details start sdhci tuning and execute sdhci tuning sequence * @param[in] host sdhci host structure * @param[in] opcode tuning opcode * @param[in] bus_width mmc bus witdh * @return uint32_t * @retval 0: success * @retval other: failed */ status_t sdrv_sdhci_execute_tuning(struct sdhci_host *host, uint32_t opcode, uint32_t bus_width); /** * @brief sdhci clk supply * @param[in] host sdhci host structure * @param[in] type clk supply type * @return uint32_t * @retval 0: success * @retval other: failed */ uint32_t sdrv_sdhci_clk_supply(struct sdhci_host *host, uint32_t type); /** * @brief sdhci clk supply * @details sdhci set uhs mode, needs to be used together with set clock api * @param[in] host sdhci host structure * @param[in] mode UHS mode */ void sdrv_sdhci_set_uhs_mode(struct sdhci_host *host, uint32_t mode); /** * @brief Soft reset for the controller * @param[in] host sdhci host structure * @param[in] mask write to reset register */ status_t sdrv_sdhci_reset(struct sdhci_host *host, uint8_t mask); /** * @brief start tuning * @param[in] host sdhci host structure */ void sdrv_sdhci_start_tuning(struct sdhci_host *host); /** * @brief sdhci reset tuning * @param[in] host sdhci host structure */ void sdrv_sdhci_reset_tuning(struct sdhci_host *host); /** * @brief sdhci abort tuning * @param[in] host sdhci host structure */ void sdrv_sdhci_abort_tuning(struct sdhci_host *host); /** * @brief sdhci clk supply * @param[in] host sdhci host structure * @param[in] opcode tuning opcode * @param[in] bus_width Bus width used * @return uint32_t * @retval 0: success * @retval other: failed */ status_t sdrv_sdhci_tuning_sequence(struct sdhci_host *host, uint32_t opcode, uint32_t bus_width); #endif /* SDRV_SDHCI_H_ */