254 lines
8.9 KiB
C
254 lines
8.9 KiB
C
|
/*
|
||
|
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||
|
*
|
||
|
* SPDX-License-Identifier: Apache-2.0
|
||
|
*
|
||
|
* Change Logs:
|
||
|
* Date Author Notes
|
||
|
* 2020-10-27 bigmagic first version
|
||
|
*/
|
||
|
|
||
|
#ifndef __DRV_SDIO_H__
|
||
|
#define __DRV_SDIO_H__
|
||
|
|
||
|
#include <rtthread.h>
|
||
|
#include <rtdevice.h>
|
||
|
#include <drivers/mmcsd_core.h>
|
||
|
|
||
|
#include "board.h"
|
||
|
#include "raspi4.h"
|
||
|
|
||
|
/* Struct for Intrrrupt Information */
|
||
|
#define SDXC_CmdDone BIT(0)
|
||
|
#define SDXC_DataDone BIT(1)
|
||
|
#define SDXC_BlockGap BIT(2)
|
||
|
#define SDXC_WriteRdy BIT(4)
|
||
|
#define SDXC_ReadRdy BIT(5)
|
||
|
#define SDXC_Card BIT(8)
|
||
|
#define SDXC_Retune BIT(12)
|
||
|
#define SDXC_BootAck BIT(13)
|
||
|
#define SDXC_EndBoot BIT(14)
|
||
|
#define SDXC_Err BIT(15)
|
||
|
#define SDXC_CTOErr BIT(16)
|
||
|
#define SDXC_CCRCErr BIT(17)
|
||
|
#define SDXC_CENDErr BIT(18)
|
||
|
#define SDXC_CBADErr BIT(19)
|
||
|
#define SDXC_DTOErr BIT(20)
|
||
|
#define SDXC_DCRCErr BIT(21)
|
||
|
#define SDXC_DENDErr BIT(22)
|
||
|
#define SDXC_ACMDErr BIT(24)
|
||
|
|
||
|
#define SDXC_BLKCNT_EN BIT(1)
|
||
|
#define SDXC_AUTO_CMD12_EN BIT(2)
|
||
|
#define SDXC_AUTO_CMD23_EN BIT(3)
|
||
|
#define SDXC_DAT_DIR BIT(4) //from card to host
|
||
|
#define SDXC_MULTI_BLOCK BIT(5)
|
||
|
#define SDXC_CMD_RSPNS_136 BIT(16)
|
||
|
#define SDXC_CMD_RSPNS_48 BIT(17)
|
||
|
#define SDXC_CMD_RSPNS_48busy BIT(16)|BIT(17)
|
||
|
#define SDXC_CHECK_CRC_CMD BIT(19)
|
||
|
#define SDXC_CMD_IXCHK_EN BIT(20)
|
||
|
#define SDXC_CMD_ISDATA BIT(21)
|
||
|
#define SDXC_CMD_SUSPEND BIT(22)
|
||
|
#define SDXC_CMD_RESUME BIT(23)
|
||
|
#define SDXC_CMD_ABORT BIT(23)|BIT(22)
|
||
|
|
||
|
#define SDXC_CMD_INHIBIT BIT(0)
|
||
|
#define SDXC_DAT_INHIBIT BIT(1)
|
||
|
#define SDXC_DAT_ACTIVE BIT(2)
|
||
|
#define SDXC_WRITE_TRANSFER BIT(8)
|
||
|
#define SDXC_READ_TRANSFER BIT(9)
|
||
|
|
||
|
struct sdhci_cmd_t
|
||
|
{
|
||
|
rt_uint32_t cmdidx;
|
||
|
rt_uint32_t cmdarg;
|
||
|
rt_uint32_t resptype;
|
||
|
rt_uint32_t datarw;
|
||
|
#define DATA_READ 1
|
||
|
#define DATA_WRITE 2
|
||
|
rt_uint32_t response[4];
|
||
|
};
|
||
|
|
||
|
struct sdhci_data_t
|
||
|
{
|
||
|
rt_uint8_t * buf;
|
||
|
rt_uint32_t flag;
|
||
|
rt_uint32_t blksz;
|
||
|
rt_uint32_t blkcnt;
|
||
|
};
|
||
|
|
||
|
struct sdhci_t
|
||
|
{
|
||
|
char * name;
|
||
|
rt_uint32_t voltages;
|
||
|
rt_uint32_t width;
|
||
|
rt_uint32_t clock;
|
||
|
rt_err_t removeable;
|
||
|
void * sdcard;
|
||
|
|
||
|
rt_err_t (*detect)(struct sdhci_t * sdhci);
|
||
|
rt_err_t (*setwidth)(struct sdhci_t * sdhci, rt_uint32_t width);
|
||
|
rt_err_t (*setclock)(struct sdhci_t * sdhci, rt_uint32_t clock);
|
||
|
rt_err_t (*transfer)(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat);
|
||
|
void * priv;
|
||
|
};
|
||
|
|
||
|
struct sdhci_pdata_t
|
||
|
{
|
||
|
rt_uint32_t virt;
|
||
|
};
|
||
|
|
||
|
// EMMC command flags
|
||
|
#define CMD_TYPE_NORMAL (0x00000000)
|
||
|
#define CMD_TYPE_SUSPEND (0x00400000)
|
||
|
#define CMD_TYPE_RESUME (0x00800000)
|
||
|
#define CMD_TYPE_ABORT (0x00c00000)
|
||
|
#define CMD_IS_DATA (0x00200000)
|
||
|
#define CMD_IXCHK_EN (0x00100000)
|
||
|
#define CMD_CRCCHK_EN (0x00080000)
|
||
|
#define CMD_RSPNS_NO (0x00000000)
|
||
|
#define CMD_RSPNS_136 (0x00010000)
|
||
|
#define CMD_RSPNS_48 (0x00020000)
|
||
|
#define CMD_RSPNS_48B (0x00030000)
|
||
|
#define TM_MULTI_BLOCK (0x00000020)
|
||
|
#define TM_DAT_DIR_HC (0x00000000)
|
||
|
#define TM_DAT_DIR_CH (0x00000010)
|
||
|
#define TM_AUTO_CMD23 (0x00000008)
|
||
|
#define TM_AUTO_CMD12 (0x00000004)
|
||
|
#define TM_BLKCNT_EN (0x00000002)
|
||
|
#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
|
||
|
|
||
|
#define RCA_NO (1)
|
||
|
#define RCA_YES (2)
|
||
|
|
||
|
// INTERRUPT register settings
|
||
|
#define INT_AUTO_ERROR (0x01000000)
|
||
|
#define INT_DATA_END_ERR (0x00400000)
|
||
|
#define INT_DATA_CRC_ERR (0x00200000)
|
||
|
#define INT_DATA_TIMEOUT (0x00100000)
|
||
|
#define INT_INDEX_ERROR (0x00080000)
|
||
|
#define INT_END_ERROR (0x00040000)
|
||
|
#define INT_CRC_ERROR (0x00020000)
|
||
|
#define INT_CMD_TIMEOUT (0x00010000)
|
||
|
#define INT_ERR (0x00008000)
|
||
|
#define INT_ENDBOOT (0x00004000)
|
||
|
#define INT_BOOTACK (0x00002000)
|
||
|
#define INT_RETUNE (0x00001000)
|
||
|
#define INT_CARD (0x00000100)
|
||
|
#define INT_READ_RDY (0x00000020)
|
||
|
#define INT_WRITE_RDY (0x00000010)
|
||
|
#define INT_BLOCK_GAP (0x00000004)
|
||
|
#define INT_DATA_DONE (0x00000002)
|
||
|
#define INT_CMD_DONE (0x00000001)
|
||
|
#define INT_ERROR_MASK (INT_CRC_ERROR|INT_END_ERROR|INT_INDEX_ERROR| \
|
||
|
INT_DATA_TIMEOUT|INT_DATA_CRC_ERR|INT_DATA_END_ERR| \
|
||
|
INT_ERR|INT_AUTO_ERROR)
|
||
|
#define INT_ALL_MASK (INT_CMD_DONE|INT_DATA_DONE|INT_READ_RDY|INT_WRITE_RDY|INT_ERROR_MASK)
|
||
|
|
||
|
#define EMMC_ARG2 (0x00)
|
||
|
#define EMMC_BLKSIZECNT (0x04)
|
||
|
#define EMMC_ARG1 (0x08)
|
||
|
#define EMMC_CMDTM (0x0c)
|
||
|
#define EMMC_RESP0 (0x10)
|
||
|
#define EMMC_RESP1 (0x14)
|
||
|
#define EMMC_RESP2 (0x18)
|
||
|
#define EMMC_RESP3 (0x1c)
|
||
|
#define EMMC_DATA (0x20)
|
||
|
#define EMMC_STATUS (0x24)
|
||
|
#define EMMC_CONTROL0 (0x28)
|
||
|
#define EMMC_CONTROL1 (0x2c)
|
||
|
#define EMMC_INTERRUPT (0x30)
|
||
|
#define EMMC_IRPT_MASK (0x34)
|
||
|
#define EMMC_IRPT_EN (0x38)
|
||
|
#define EMMC_CONTROL2 (0x3c)
|
||
|
#define EMMC_CAPABILITIES_0 (0x40)
|
||
|
#define EMMC_CAPABILITIES_1 (0x44)
|
||
|
#define EMMC_BOOT_TIMEOUT (0x70)
|
||
|
#define EMMC_EXRDFIFO_EN (0x84)
|
||
|
#define EMMC_SPI_INT_SPT (0xf0)
|
||
|
#define EMMC_SLOTISR_VER (0xfc)
|
||
|
|
||
|
// CONTROL register settings
|
||
|
#define C0_SPI_MODE_EN (0x00100000)
|
||
|
#define C0_HCTL_HS_EN (0x00000004)
|
||
|
#define C0_HCTL_DWITDH (0x00000002)
|
||
|
|
||
|
#define C1_SRST_DATA (0x04000000)
|
||
|
#define C1_SRST_CMD (0x02000000)
|
||
|
#define C1_SRST_HC (0x01000000)
|
||
|
#define C1_TOUNIT_DIS (0x000f0000)
|
||
|
#define C1_TOUNIT_MAX (0x000e0000)
|
||
|
#define C1_CLK_GENSEL (0x00000020)
|
||
|
#define C1_CLK_EN (0x00000004)
|
||
|
#define C1_CLK_STABLE (0x00000002)
|
||
|
#define C1_CLK_INTLEN (0x00000001)
|
||
|
|
||
|
#define FREQ_SETUP (400000) // 400 Khz
|
||
|
#define FREQ_NORMAL (25000000) // 25 Mhz
|
||
|
|
||
|
// SLOTISR_VER values
|
||
|
#define HOST_SPEC_NUM 0x00ff0000
|
||
|
#define HOST_SPEC_NUM_SHIFT 16
|
||
|
#define HOST_SPEC_V3 2
|
||
|
#define HOST_SPEC_V2 1
|
||
|
#define HOST_SPEC_V1 0
|
||
|
|
||
|
// STATUS register settings
|
||
|
#define SR_DAT_LEVEL1 (0x1e000000)
|
||
|
#define SR_CMD_LEVEL (0x01000000)
|
||
|
#define SR_DAT_LEVEL0 (0x00f00000)
|
||
|
#define SR_DAT3 (0x00800000)
|
||
|
#define SR_DAT2 (0x00400000)
|
||
|
#define SR_DAT1 (0x00200000)
|
||
|
#define SR_DAT0 (0x00100000)
|
||
|
#define SR_WRITE_PROT (0x00080000) // From SDHC spec v2, BCM says reserved
|
||
|
#define SR_READ_AVAILABLE (0x00000800) // ???? undocumented
|
||
|
#define SR_WRITE_AVAILABLE (0x00000400) // ???? undocumented
|
||
|
#define SR_READ_TRANSFER (0x00000200)
|
||
|
#define SR_WRITE_TRANSFER (0x00000100)
|
||
|
#define SR_DAT_ACTIVE (0x00000004)
|
||
|
#define SR_DAT_INHIBIT (0x00000002)
|
||
|
#define SR_CMD_INHIBIT (0x00000001)
|
||
|
|
||
|
#define CONFIG_MMC_USE_DMA
|
||
|
#define DMA_ALIGN (32U)
|
||
|
|
||
|
#define SD_CMD_INDEX(a) ((a) << 24)
|
||
|
#define SD_CMD_RESERVED(a) (0xffffffff)
|
||
|
#define SD_CMD_INDEX(a) ((a) << 24)
|
||
|
#define SD_CMD_TYPE_NORMAL (0x0)
|
||
|
#define SD_CMD_TYPE_SUSPEND (1 << 22)
|
||
|
#define SD_CMD_TYPE_RESUME (2 << 22)
|
||
|
#define SD_CMD_TYPE_ABORT (3 << 22)
|
||
|
#define SD_CMD_TYPE_MASK (3 << 22)
|
||
|
#define SD_CMD_ISDATA (1 << 21)
|
||
|
#define SD_CMD_IXCHK_EN (1 << 20)
|
||
|
#define SD_CMD_CRCCHK_EN (1 << 19)
|
||
|
#define SD_CMD_RSPNS_TYPE_NONE (0) // For no response
|
||
|
#define SD_CMD_RSPNS_TYPE_136 (1 << 16) // For response R2 (with CRC), R3,4 (no CRC)
|
||
|
#define SD_CMD_RSPNS_TYPE_48 (2 << 16) // For responses R1, R5, R6, R7 (with CRC)
|
||
|
#define SD_CMD_RSPNS_TYPE_48B (3 << 16) // For responses R1b, R5b (with CRC)
|
||
|
#define SD_CMD_RSPNS_TYPE_MASK (3 << 16)
|
||
|
#define SD_CMD_MULTI_BLOCK (1 << 5)
|
||
|
#define SD_CMD_DAT_DIR_HC (0)
|
||
|
#define SD_CMD_DAT_DIR_CH (1 << 4)
|
||
|
#define SD_CMD_AUTO_CMD_EN_NONE (0)
|
||
|
#define SD_CMD_AUTO_CMD_EN_CMD12 (1 << 2)
|
||
|
#define SD_CMD_AUTO_CMD_EN_CMD23 (2 << 2)
|
||
|
#define SD_CMD_BLKCNT_EN (1 << 1)
|
||
|
#define SD_CMD_DMA (1)
|
||
|
#define SD_RESP_NONE SD_CMD_RSPNS_TYPE_NONE
|
||
|
#define SD_RESP_R1 (SD_CMD_RSPNS_TYPE_48) // | SD_CMD_CRCCHK_EN)
|
||
|
#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B) // | SD_CMD_CRCCHK_EN)
|
||
|
#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136) // | SD_CMD_CRCCHK_EN)
|
||
|
#define SD_RESP_R3 SD_CMD_RSPNS_TYPE_48
|
||
|
#define SD_RESP_R4 SD_CMD_RSPNS_TYPE_136
|
||
|
#define SD_RESP_R5 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
|
||
|
#define SD_RESP_R5b (SD_CMD_RSPNS_TYPE_48B | SD_CMD_CRCCHK_EN)
|
||
|
#define SD_RESP_R6 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
|
||
|
#define SD_RESP_R7 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
|
||
|
#define SD_DATA_READ (SD_CMD_ISDATA | SD_CMD_DAT_DIR_CH)
|
||
|
#define SD_DATA_WRITE (SD_CMD_ISDATA | SD_CMD_DAT_DIR_HC)
|
||
|
#endif
|