Files
E3/20250218-ETH-CAN_loadV1.3/e3_176_ref/drivers/include/sdrv_sdhci.h
2025-11-14 21:41:29 +08:00

693 lines
22 KiB
C

/**
* @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 <reg.h>
#include <udelay/udelay.h>
#if CONFIG_OS_FREERTOS
#include <FreeRTOS.h>
#include <queue.h>
#include <semphr.h>
#include <task.h>
#include <irq.h>
#include <timers.h>
#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_ */