625 lines
26 KiB
C
625 lines
26 KiB
C
|
/*
|
|||
|
* Copyright : (C) 2022 Phytium Information Technology, Inc.
|
|||
|
* All Rights Reserved.
|
|||
|
*
|
|||
|
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
|
|||
|
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
|
|||
|
* either version 1.0 of the License, or (at your option) any later version.
|
|||
|
*
|
|||
|
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
|
|||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|||
|
* See the Phytium Public License for more details.
|
|||
|
*
|
|||
|
*
|
|||
|
* FilePath: fsdio_hw.h
|
|||
|
* Date: 2022-05-26 15:32:34
|
|||
|
* LastEditTime: 2022-05-26 15:32:35
|
|||
|
* Description: This files is for SDIO register function definition
|
|||
|
*
|
|||
|
* Modify History:
|
|||
|
* Ver Who Date Changes
|
|||
|
* ----- ------ -------- --------------------------------------
|
|||
|
* 1.0 zhugengyu 2021/12/2 init
|
|||
|
* 1.1 zhugengyu 2022/5/26 modify according to tech manual.
|
|||
|
*/
|
|||
|
|
|||
|
#ifndef DRIVERS_FSDIO_HW_H
|
|||
|
#define DRIVERS_FSDIO_HW_H
|
|||
|
|
|||
|
#ifdef __cplusplus
|
|||
|
extern "C"
|
|||
|
{
|
|||
|
#endif
|
|||
|
/***************************** Include Files *********************************/
|
|||
|
#include "fparameters.h"
|
|||
|
#include "fio.h"
|
|||
|
#include "ftypes.h"
|
|||
|
#include "fassert.h"
|
|||
|
#include "fkernel.h"
|
|||
|
|
|||
|
/************************** Constant Definitions *****************************/
|
|||
|
|
|||
|
/** @name Register Map
|
|||
|
*
|
|||
|
* Register offsets from the base address of an SD device.
|
|||
|
* @{
|
|||
|
*/
|
|||
|
#define FSDIO_CNTRL_OFFSET 0x00U /* the controller config reg */
|
|||
|
#define FSDIO_PWREN_OFFSET 0x04U /* the power enable reg */
|
|||
|
#define FSDIO_CLKDIV_OFFSET 0x08U /* the clock divider reg */
|
|||
|
#define FSDIO_CLKENA_OFFSET 0x10U /* the clock enable reg */
|
|||
|
#define FSDIO_TMOUT_OFFSET 0x14U /* the timeout reg */
|
|||
|
#define FSDIO_CTYPE_OFFSET 0x18U /* the card type reg */
|
|||
|
#define FSDIO_BLK_SIZ_OFFSET 0x1CU /* the block size reg */
|
|||
|
#define FSDIO_BYT_CNT_OFFSET 0x20U /* the byte count reg */
|
|||
|
#define FSDIO_INT_MASK_OFFSET 0x24U /* the interrupt mask reg */
|
|||
|
#define FSDIO_CMD_ARG_OFFSET 0x28U /* the command argument reg */
|
|||
|
#define FSDIO_CMD_OFFSET 0x2CU /* the command reg */
|
|||
|
#define FSDIO_RESP0_OFFSET 0x30U /* the response reg0 */
|
|||
|
#define FSDIO_RESP1_OFFSET 0x34U /* the response reg1 */
|
|||
|
#define FSDIO_RESP2_OFFSET 0x38U /* the response reg2 */
|
|||
|
#define FSDIO_RESP3_OFFSET 0x3CU /* the response reg3 */
|
|||
|
#define FSDIO_MASKED_INTS_OFFSET 0x40U /* the masked interrupt status reg */
|
|||
|
#define FSDIO_RAW_INTS_OFFSET 0x44U /* the raw interrupt status reg */
|
|||
|
#define FSDIO_STATUS_OFFSET 0x48U /* the status reg */
|
|||
|
#define FSDIO_FIFOTH_OFFSET 0x4CU /* the FIFO threshold watermark reg */
|
|||
|
#define FSDIO_CARD_DETECT_OFFSET 0x50U /* the card detect reg */
|
|||
|
#define FSDIO_CARD_WRTPRT_OFFSET 0x54U /* the card write protect reg */
|
|||
|
#define FSDIO_GPIO_OFFSET 0x58U /* the ciu ready */
|
|||
|
#define FSDIO_TRAN_CARD_CNT_OFFSET 0x5CU /* the transferred CIU card byte count reg */
|
|||
|
#define FSDIO_TRAN_FIFO_CNT_OFFSET 0x60U /* the transferred host to FIFO byte count reg */
|
|||
|
#define FSDIO_DEBNCE_OFFSET 0x64U /* the debounce count reg */
|
|||
|
#define FSDIO_UID_OFFSET 0x68U /* the user ID reg */
|
|||
|
#define FSDIO_VID_OFFSET 0x6CU /* the controller version ID reg */
|
|||
|
#define FSDIO_HWCONF_OFFSET 0x70U /* the hardware configuration reg */
|
|||
|
#define FSDIO_UHS_REG_OFFSET 0x74U /* the UHS-I reg */
|
|||
|
#define FSDIO_CARD_RESET_OFFSET 0x78U /* the card reset reg */
|
|||
|
#define FSDIO_BUS_MODE_OFFSET 0x80U /* the bus mode reg */
|
|||
|
#define FSDIO_DESC_LIST_ADDRL_OFFSET 0x88U /* the descriptor list low base address reg */
|
|||
|
#define FSDIO_DESC_LIST_ADDRH_OFFSET 0x8CU /* the descriptor list high base address reg */
|
|||
|
#define FSDIO_DMAC_STATUS_OFFSET 0x90U /* the internal DMAC status reg */
|
|||
|
#define FSDIO_DMAC_INT_EN_OFFSET 0x94U /* the internal DMAC interrupt enable reg */
|
|||
|
#define FSDIO_CUR_DESC_ADDRL_OFFSET 0x98U /* the current host descriptor low address reg */
|
|||
|
#define FSDIO_CUR_DESC_ADDRH_OFFSET 0x9CU /* the current host descriptor high address reg */
|
|||
|
#define FSDIO_CUR_BUF_ADDRL_OFFSET 0xA0U /* the current buffer low address reg */
|
|||
|
#define FSDIO_CUR_BUF_ADDRH_OFFSET 0xA4U /* the current buffer high address reg */
|
|||
|
#define FSDIO_CARD_THRCTL_OFFSET 0x100U /* the card threshold control reg */
|
|||
|
#define FSDIO_UHS_REG_EXT_OFFSET 0x108U /* the UHS register extension */
|
|||
|
#define FSDIO_EMMC_DDR_REG_OFFSET 0x10CU /* the EMMC DDR reg */
|
|||
|
#define FSDIO_ENABLE_SHIFT_OFFSET 0x110U /* the enable phase shift reg */
|
|||
|
#define FSDIO_DATA_OFFSET 0x200U /* the data FIFO access */
|
|||
|
|
|||
|
/** @name FSDIO_CNTRL_OFFSET x0 Register
|
|||
|
*/
|
|||
|
#define FSDIO_CNTRL_CONTROLLER_RESET BIT(0) /* RW 复位控制器,除 DMA,FIFO */
|
|||
|
#define FSDIO_CNTRL_FIFO_RESET BIT(1) /* RW 复位 FIFO, 1 有效 */
|
|||
|
#define FSDIO_CNTRL_DMA_RESET BIT(2) /* RW 复位内部 DMA, 1 有效 */
|
|||
|
#define FSDIO_CNTRL_INT_ENABLE BIT(4) /* RW 全局中断使能配置, 1 使能 */
|
|||
|
#define FSDIO_CNTRL_DMA_ENABLE BIT(5) /* RW 外部 DMA 模式使能 */
|
|||
|
#define FSDIO_CNTRL_READ_WAIT BIT(6) /* RW SDIO 读等待 1 有效 */
|
|||
|
#define FSDIO_CNTRL_SEND_IRQ_RESPONSE BIT(7) /* RW MMC 中断自动响应配置 1 有效 */
|
|||
|
#define FSDIO_CNTRL_ABORT_READ_DATA BIT(8) /* RW 读暂停异常清除 */
|
|||
|
#define FSDIO_CNTRL_SEND_CCSD BIT(9) /* RW 发送CCD (NOT USED) */
|
|||
|
#define FSDIO_CNTRL_SEND_AUTO_STOP_CCSD BIT(10) /* RW 发送CCD,自动STOP (NOT USED) */
|
|||
|
#define FSDIO_CNTRL_ENDIAN BIT(11) /* RW 0:小端,1:大端 */
|
|||
|
#define FSDIO_CNTRL_CARD_VOLTAGE_A_MASK GENMASK(19, 16) /* RW A电压选择 */
|
|||
|
#define FSDIO_CNTRL_CARD_VOLTAGE_B_MASK GENMASK(23, 20) /* RW B电压选择 */
|
|||
|
#define FSDIO_CNTRL_ENABLE_OD_PULLUP BIT(24) /* RW 外部开漏输出 */
|
|||
|
#define FSDIO_CNTRL_USE_INTERNAL_DMAC BIT(25) /* RW 使用内部DMA */
|
|||
|
|
|||
|
/** @name FSDIO_PWREN_OFFSET 0x4 Register
|
|||
|
*/
|
|||
|
#define FSDIO_PWREN_ENABLE BIT(0) /* RW 卡供电开关, 0:关;1:开*/
|
|||
|
|
|||
|
/** @name FSDIO_CLKDIV_OFFSET 0x8 Register
|
|||
|
*/
|
|||
|
/* CLK_SAMPLE 和 CLK_SAMPLE 必须小于 CLK_DIVIDER */
|
|||
|
#define FSDIO_CLK_SAMPLE_SET(x) SET_REG32_BITS((x), 23, 16)
|
|||
|
#define FSDIO_CLK_DRV_SET(x) SET_REG32_BITS((x), 15, 8)
|
|||
|
#define FSDIO_CLK_DIVIDER_SET(x) SET_REG32_BITS((x), 7, 0) /* 分频系数 = 2 * bit[7:0] */
|
|||
|
#define FSDIO_CLK_DIV(samp, drv, div) FSDIO_CLK_SAMPLE_SET(samp) | \
|
|||
|
FSDIO_CLK_DRV_SET(drv) | \
|
|||
|
FSDIO_CLK_DIVIDER_SET(div)
|
|||
|
|
|||
|
/** @name FSDIO_CLKENA_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CLKENA_CCLK_ENABLE BIT(0) /* RW 0:Clock disabled;1:Clock enabled */
|
|||
|
#define FSDIO_CLKENA_CCLK_LOW_POWER BIT(16) /* RW 0x0:非低功耗;0x1:低功耗 */
|
|||
|
|
|||
|
/** @name FSDIO_TMOUT_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_MAX_DATA_TIMEOUT 0xffffff /* RW 读卡超时(以卡时钟为单位) */
|
|||
|
#define FSDIO_MAX_RESP_TIMEOUT 0xff /* RW 响应超时(以卡时钟为单位) */
|
|||
|
#define FSDIO_TIMEOUT_DATA(data_timeout, resp_timeout) \
|
|||
|
((GENMASK(31, 8) & ((data_timeout) << 8)) | \
|
|||
|
(GENMASK(7, 0) & ((resp_timeout))))
|
|||
|
|
|||
|
/** @name FSDIO_CTYPE_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CARD0_WIDTH1_8BIT BIT(16) /* 1: 8-bit mode */
|
|||
|
#define FSDIO_CARD0_WIDTH2_4BIT BIT(0) /* 1: 4-bit mode */
|
|||
|
#define FSDIO_CARD0_WIDTH2_1BIT 0x0U /* 0: 1-bit mode */
|
|||
|
|
|||
|
/** @name FSDIO_INT_MASK_OFFSET Register
|
|||
|
* @name FSDIO_MASKED_INTS_OFFSET Register
|
|||
|
* @name FSDIO_RAW_INTS_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_INT_CD_BIT BIT(0) /* RW Card detect (CD) */
|
|||
|
#define FSDIO_INT_RE_BIT BIT(1) /* RW Response error (RE) */
|
|||
|
#define FSDIO_INT_CMD_BIT BIT(2) /* RW Command done (CD) */
|
|||
|
#define FSDIO_INT_DTO_BIT BIT(3) /* RW Data transfer over (DTO) */
|
|||
|
#define FSDIO_INT_TXDR_BIT BIT(4) /* RW Transmit FIFO data request (TXDR) */
|
|||
|
#define FSDIO_INT_RXDR_BIT BIT(5) /* RW Receive FIFO data request (RXDR) */
|
|||
|
#define FSDIO_INT_RCRC_BIT BIT(6) /* RW Response CRC error (RCRC) */
|
|||
|
#define FSDIO_INT_DCRC_BIT BIT(7) /* RW Data CRC error (DCRC) */
|
|||
|
#define FSDIO_INT_RTO_BIT BIT(8) /* RW Response timeout (RTO) */
|
|||
|
#define FSDIO_INT_DRTO_BIT BIT(9) /* RW Data read timeout (DRTO) */
|
|||
|
#define FSDIO_INT_HTO_BIT BIT(10) /* RW Data starvation-by-host timeout (HTO) */
|
|||
|
#define FSDIO_INT_FRUN_BIT BIT(11) /* RW FIFO underrun/overrun error (FRUN) */
|
|||
|
#define FSDIO_INT_HLE_BIT BIT(12) /* RW Hardware locked write error (HLE) */
|
|||
|
#define FSDIO_INT_SBE_BCI_BIT BIT(13) /* RW Start-bit error (SBE) */
|
|||
|
#define FSDIO_INT_ACD_BIT BIT(14) /* RW Auto command done (ACD) */
|
|||
|
#define FSDIO_INT_EBE_BIT BIT(15) /* RW End-bit error (read)/Write no CRC (EBE) */
|
|||
|
#define FSDIO_INT_SDIO_BIT BIT(16) /* RW SDIO interrupt for card */
|
|||
|
|
|||
|
#define FSDIO_INT_ALL_BITS GENMASK(16, 0)
|
|||
|
#define FSDIO_INTS_CMD_MASK (FSDIO_INT_RE_BIT | FSDIO_INT_CMD_BIT | FSDIO_INT_RCRC_BIT | \
|
|||
|
FSDIO_INT_RTO_BIT | FSDIO_INT_HTO_BIT | FSDIO_INT_HLE_BIT)
|
|||
|
|
|||
|
#define FSDIO_INTS_DATA_MASK (FSDIO_INT_DTO_BIT | FSDIO_INT_DCRC_BIT | FSDIO_INT_DRTO_BIT | \
|
|||
|
FSDIO_INT_SBE_BCI_BIT)
|
|||
|
|
|||
|
/** @name FSDIO_CMD_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CMD_START BIT(31) /* 启动命令 */
|
|||
|
#define FSDIO_CMD_USE_HOLD_REG BIT(29) /* 0: 旁路HOLD寄存器,1: 使能HOLD寄存器 */
|
|||
|
#define FSDIO_CMD_VOLT_SWITCH BIT(28) /* 0: 无电压转换,1: 有电压转换 */
|
|||
|
#define FSDIO_CMD_BOOT_MODE BIT(27) /* 0: Mandatory boot, 1: Alternate boot */
|
|||
|
#define FSDIO_CMD_DISABLE_BOOT BIT(26) /* 中止boot进程 */
|
|||
|
#define FSDIO_CMD_EXPECT_BOOT_ACK BIT(25) /* 1: Expect book ack */
|
|||
|
#define FSDIO_CMD_ENABLE_BOOT BIT(24) /* 1: 使能 boot for mandatory */
|
|||
|
#define FSDIO_CMD_UPD_CLK BIT(21) /* 1:不发送指令,仅更新时钟寄存器的值到卡时钟域内 */
|
|||
|
#define FSDIO_CMD_CARD_NUM_SET(num) SET_REG32_BITS((num), 20, 16)
|
|||
|
#define FSDIO_CMD_INIT BIT(15) /* 0:在发送指令前不发送初始化序列(80 个周期) 1: 发送 */
|
|||
|
#define FSDIO_CMD_STOP_ABORT BIT(14) /* 1:停止或中止命令,用于停止当前的数据传输 */
|
|||
|
#define FSDIO_CMD_WAIT_PRVDATA_COMPLETE BIT(13) /* 1:等待前面的数据传输完成后再发送指令 0: 立即发送命令 */
|
|||
|
#define FSDIO_CMD_SEND_AUTO_STOP BIT(12) /* 1:在数据传送结束时发送停止命令 */
|
|||
|
#define FSDIO_CMD_TRANSF_MODE_SET(mode) SET_REG32_BITS((mode), 12, 11) /* 1: 流数据传输指令 */
|
|||
|
#define FSDIO_CMD_DAT_WRITE BIT(10) /* 0:读卡 1:写卡 */
|
|||
|
#define FSDIO_CMD_DAT_EXP BIT(9) /* 0:不等待数据传输, 1:等待数据传输 */
|
|||
|
#define FSDIO_CMD_RESP_CRC BIT(8) /* 1:检查响应 CRC */
|
|||
|
#define FSDIO_CMD_RESP_LONG BIT(7) /* 0:等待卡的短响应 1:等待卡的长响应 */
|
|||
|
#define FSDIO_CMD_RESP_EXP BIT(6) /* 1:等待卡的响应,0:命令不需要卡响应 */
|
|||
|
#define FSDIO_CMD_INDX_SET(ind) SET_REG32_BITS((ind), 5, 0) /* 命令索引号 */
|
|||
|
|
|||
|
/** @name FSDIO_STATUS_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_STATUS_FIFO_RX BIT(0) /* RO, 达到 FIFO_RX 标记 */
|
|||
|
#define FSDIO_STATUS_FIFO_TX BIT(1) /* RO, 达到 FIFO_TX 标记 */
|
|||
|
#define FSDIO_STATUS_FIFO_EMPTY BIT(2) /* RO, FIFO empty */
|
|||
|
#define FSDIO_STATUS_FIFO_FULL BIT(3) /* RO, FIFO full */
|
|||
|
#define FSDIO_STATUS_CMD_FSM_GET(reg_val) GET_REG32_BITS((reg_val), 7, 4)
|
|||
|
#define FSDIO_STATUS_DATA3_STATUS BIT(8) /* RO DATA[3] 卡在位检测,1:在位 */
|
|||
|
#define FSDIO_STATUS_DATA_BUSY BIT(9) /* RO 1: 卡 busy */
|
|||
|
#define FSDIO_STATUS_DATA_STATE_MC_BUSY BIT(10) /* RO DATA TX|RX FSM busy */
|
|||
|
#define FSDIO_STATUS_RESP_INDEX_GET(reg_val) GET_REG32_BITS((reg_val), 16, 11)
|
|||
|
#define FSDIO_STATUS_FIFO_CNT_GET(reg_val) GET_REG32_BITS((reg_val), 29, 17) /* RO: FIFO 填充计数器 */
|
|||
|
#define FSDIO_STATUS_DMA_ACK BIT(30) /* RO DMA 确认 */
|
|||
|
#define FSDIO_STATUS_DMA_REQ BIT(31) /* RO DMA 请求 */
|
|||
|
|
|||
|
/** @name FSDIO_FIFOTH_OFFSET Register
|
|||
|
*/
|
|||
|
enum
|
|||
|
{
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_1 = 0b000,
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_4 = 0b001,
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_8 = 0b010,
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_16 = 0b011,
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_32 = 0b100,
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_64 = 0b101,
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_128 = 0b110,
|
|||
|
FSDIO_FIFOTH_DMA_TRANS_256 = 0b111
|
|||
|
};
|
|||
|
|
|||
|
#define FSDIO_FIFOTH_DMA_TRANS_MASK GENMASK(30, 28) /* 多次传输的突发大小 */
|
|||
|
#define FSDIO_FIFOTH_RX_WMARK_MASK GENMASK(27, 16) /* 当接收数据给卡时FIFO的阈值 */
|
|||
|
#define FSDIO_FIFOTH_TX_WMARK_MASK GENMASK(11, 0) /* 当发送数据给卡时FIFO的阈值 */
|
|||
|
|
|||
|
#define FSDIO_RX_WMARK 0x7U
|
|||
|
#define FSDIO_TX_WMARK 0x100U
|
|||
|
|
|||
|
/*
|
|||
|
trans_size: Burst size of multiple transaction;
|
|||
|
rx_wmark: FIFO threshold watermark level when receiving data to card.
|
|||
|
tx_wmark: FIFO threshold watermark level when transmitting data to card
|
|||
|
*/
|
|||
|
#define FSDIO_FIFOTH(trans_size, rx_wmark, tx_wmark) \
|
|||
|
(((FSDIO_FIFOTH_DMA_TRANS_MASK) & ((trans_size) << 28)) | \
|
|||
|
((FSDIO_FIFOTH_RX_WMARK_MASK) & ((rx_wmark) << 16)) | \
|
|||
|
((FSDIO_FIFOTH_TX_WMARK_MASK) & (tx_wmark)))
|
|||
|
|
|||
|
#define FSDIO_DMA_TRANS_SIZE_SET(x) SET_REG32_BITS((x), 30, 28)
|
|||
|
#define FSDIO_RX_MARK_SIZE_SET(x) SET_REG32_BITS((x), 27, 16)
|
|||
|
#define FSDIO_TX_MARK_SIZE_SET(x) SET_REG32_BITS((x), 11, 0)
|
|||
|
|
|||
|
/** @name FSDIO_CARD_DETECT_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CARD_DETECTED BIT(0) /* 1:卡不在位;0:卡在位 */
|
|||
|
|
|||
|
/** @name FSDIO_CARD_WRTPRT_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CARD_WRITE_PROTECTED BIT(0) /* 1:写保护;0:无写保护 */
|
|||
|
|
|||
|
/** @name FSDIO_GPIO_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CLK_READY BIT(0) /* CIU 时钟 ready */
|
|||
|
|
|||
|
/** @name FSDIO_UHS_REG_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_UHS_REG_VOLT_180 BIT(0) /* RW 外部调压器接口电压 0: 3.3v, 1: 1.8v */
|
|||
|
#define FSDIO_UHS_REG_VOLT_330 0U
|
|||
|
#define FSDIO_UHS_REG_DDR BIT(16) /* RW DDR 模式 */
|
|||
|
|
|||
|
/** @name FSDIO_CARD_RESET_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CARD_RESET_ENABLE BIT(0) /* RW 1:运行;0:复位 */
|
|||
|
|
|||
|
/** @name FSDIO_BUS_MODE_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_BUS_MODE_SWR BIT(0) /* RW 软复位,复位idma内部寄存器 */
|
|||
|
#define FSDIO_BUS_MODE_FB BIT(1) /* RW 固定burst */
|
|||
|
#define FSDIO_BUS_MODE_DE BIT(7) /* RW idma使能 */
|
|||
|
#define FSDIO_BUS_MODE_PBL_GET(reg_val) GET_REG32_BITS((reg_val), 10, 8) /* burst LEN */
|
|||
|
|
|||
|
/** @name FSDIO_DMAC_STATUS_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_DMAC_STATUS_TI BIT(0) /* RW 发送中断。表示链表的数据发送完成 */
|
|||
|
#define FSDIO_DMAC_STATUS_RI BIT(1) /* RW 接收中断。表示链表的数据接收完成 */
|
|||
|
#define FSDIO_DMAC_STATUS_FBE BIT(2) /* RW 致命总线错误中断 */
|
|||
|
#define FSDIO_DMAC_STATUS_DU BIT(4) /* RW 链表不可用中断 */
|
|||
|
#define FSDIO_DMAC_STATUS_CES BIT(5) /* RW 卡错误汇总 */
|
|||
|
#define FSDIO_DMAC_STATUS_NIS BIT(8) /* RW 正常中断汇总 */
|
|||
|
#define FSDIO_DMAC_STATUS_AIS BIT(9) /* RW 异常中断汇总 */
|
|||
|
#define FSDIO_DMAC_STATUS_EB_GET(reg_val) GET_REG32_BITS((reg_val), 12, 10)
|
|||
|
#define FSDIO_DMAC_STATUS_ALL_BITS GENMASK(9, 0)
|
|||
|
|
|||
|
#define FSDIO_DMAC_STATUS_EB_TX 0b001
|
|||
|
#define FSDIO_DMAC_STATUS_EB_RX 0b010
|
|||
|
|
|||
|
/** @name FSDIO_DMAC_INT_EN_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_DMAC_INT_ENA_TI BIT(0) /* RW 发送完成中断使能 */
|
|||
|
#define FSDIO_DMAC_INT_ENA_RI BIT(1) /* RW 接收完成中断使能 */
|
|||
|
#define FSDIO_DMAC_INT_ENA_FBE BIT(2) /* RW 总线错误中断使能 */
|
|||
|
#define FSDIO_DMAC_INT_ENA_DU BIT(4) /* RW 描述符不可读中断使能 */
|
|||
|
#define FSDIO_DMAC_INT_ENA_CES BIT(5) /* RW 卡错误中断使能 */
|
|||
|
#define FSDIO_DMAC_INT_ENA_NIS BIT(8) /* RW 正常中断汇总使能 */
|
|||
|
#define FSDIO_DMAC_INT_ENA_AIS BIT(9) /* RW 异常中断汇总使能 */
|
|||
|
#define FSDIO_DMAC_INT_ENA_ALL GENMASK(9, 0)
|
|||
|
|
|||
|
#define FSDIO_DMAC_INTS_MASK (FSDIO_DMAC_INT_ENA_FBE | FSDIO_DMAC_INT_ENA_DU | \
|
|||
|
FSDIO_DMAC_INT_ENA_NIS | FSDIO_DMAC_INT_ENA_AIS)
|
|||
|
|
|||
|
/** @name FSDIO_CARD_THRCTL_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_CARD_THRCTL_CARDRD BIT(0) /* RW 读卡threshold使能 */
|
|||
|
#define FSDIO_CARD_THRCTL_BUSY_CLR BIT(1) /* RW busy清中断 */
|
|||
|
#define FSDIO_CARD_THRCTL_CARDWR BIT(2) /* RO 写卡threshold使能 */
|
|||
|
enum
|
|||
|
{
|
|||
|
FSDIO_FIFO_DEPTH_8 = 23,
|
|||
|
FSDIO_FIFO_DEPTH_16 = 24,
|
|||
|
FSDIO_FIFO_DEPTH_32 = 25,
|
|||
|
FSDIO_FIFO_DEPTH_64 = 26,
|
|||
|
FSDIO_FIFO_DEPTH_128 = 27
|
|||
|
};
|
|||
|
|
|||
|
#define FSDIO_CARD_THRCTL_THRESHOLD(n) BIT(n) /* 读卡 Threshold */
|
|||
|
|
|||
|
/** @name FSDIO_UHS_REG_EXT_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_UHS_EXT_MMC_VOLT BIT(0) /* RW 1.2V供电选择 */
|
|||
|
#define FSDIO_UHS_EXT_CLK_ENA BIT(1) /* RW 外部时钟,CIU时钟使能 */
|
|||
|
#define FSDIO_UHS_CLK_DIV_MASK GENMASK(14, 8) /* RW 分频系数,ciu_f = clk_div_ctrl + 1, min=1*/
|
|||
|
#define FSDIO_UHS_CLK_DIV(x) (FSDIO_UHS_CLK_DIV_MASK & ((x) << 8))
|
|||
|
#define FSDIO_UHS_CLK_SAMP_MASK GENMASK(22, 16) /* RW 采样相位参数,相对于ciu时钟相位点 */
|
|||
|
#define FSDIO_UHS_CLK_SAMP(x) (FSDIO_UHS_CLK_SAMP_MASK & ((x) << 16))
|
|||
|
#define FSDIO_UHS_CLK_DRV_MASK GENMASK(30, 24) /* RW 输出相位参数,相对于ciu时钟相位点 */
|
|||
|
#define FSDIO_UHS_CLK_DRV(x) (FSDIO_UHS_CLK_DRV_MASK & ((x) << 24))
|
|||
|
#define FSDIO_UHS_EXT_CLK_MUX BIT(31)
|
|||
|
|
|||
|
/* FSDIO_UHS_REG_EXT_OFFSET 和 FSDIO_CLKDIV_OFFSET 两个寄存器配合完成卡时钟和驱动采样相位调整
|
|||
|
UHS_REG_EXT 配置一级分频,CLK_DIV 决定CARD工作时钟频率, DRV 和 SAMP 分别控制驱动相位和采样相位粗调
|
|||
|
分配系数 = bit [14 : 8] + 1
|
|||
|
CLKDIV 配置二级分频, DIVIDER , DRV 和 SAMP 分别控制驱动相位和采样相位精调
|
|||
|
分配系数 = bit [7: 0] * 2
|
|||
|
*/
|
|||
|
#define FSDIO_UHS_REG(drv_phase, samp_phase, clk_div) \
|
|||
|
(FSDIO_UHS_CLK_DRV(drv_phase) | \
|
|||
|
FSDIO_UHS_CLK_SAMP(samp_phase) | \
|
|||
|
FSDIO_UHS_CLK_DIV(clk_div))
|
|||
|
|
|||
|
#define FSDIO_UHS_CLK_DIV_SET(x) SET_REG32_BITS((x), 14, 8)
|
|||
|
#define FSDIO_UHS_CLK_DIV_GET(reg_val) GET_REG32_BITS((reg_val), 14, 8)
|
|||
|
#define FSDIO_UHS_CLK_SAMP_SET(x) SET_REG32_BITS((x), 22, 16)
|
|||
|
#define FSDIO_UHS_CLK_DRV_SET(x) SET_REG32_BITS((x), 30, 24)
|
|||
|
|
|||
|
/** @name FSDIO_REG_EMMC_DDR_REG_OFFSET Register
|
|||
|
*/
|
|||
|
#define FSDIO_EMMC_DDR_CYCLE BIT(0) /* RW 1: start bit小于一个周期,0:start bit 为一个周期 */
|
|||
|
|
|||
|
#define FSDIO_TIMEOUT (50000) /* timeout for retries */
|
|||
|
#define FSDIO_DELAY_US (5)
|
|||
|
#define FSDIO_400_KHZ (400000UL)
|
|||
|
#define FSDIO_25_MHZ (25000000UL)
|
|||
|
#define FSDIO_MAX_FIFO_CNT (0x800U)
|
|||
|
|
|||
|
/************************** Variable Definitions *****************************/
|
|||
|
|
|||
|
/***************** Macros (Inline Functions) Definitions *********************/
|
|||
|
#define FSDIO_READ_REG(addr, reg_off) FtIn32((addr) + (u32)(reg_off))
|
|||
|
#define FSDIO_WRITE_REG(addr, reg_off, reg_val) FtOut32((addr) + (u32)(reg_off), (u32)(reg_val))
|
|||
|
#define FSDIO_CLR_BIT(addr, reg_off, bits) FtClearBit32((addr) + (u32)(reg_off), bits)
|
|||
|
#define FSDIO_SET_BIT(addr, reg_off, bits) FtSetBit32((addr) + (u32)(reg_off), bits)
|
|||
|
|
|||
|
/************************** Function Prototypes ******************************/
|
|||
|
FError FSdioSendPrivateCmd(uintptr base_addr, u32 cmd, u32 arg);
|
|||
|
FError FSdioResetCtrl(uintptr base_addr, u32 reset_bits);
|
|||
|
|
|||
|
/*****************************************************************************/
|
|||
|
/**
|
|||
|
* @name: FSdioSetClock
|
|||
|
* @msg: Enable/Disable controller clock
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
* @param {boolean} enable, TRUE: enable clock
|
|||
|
*/
|
|||
|
static inline void FSdioSetClock(uintptr base_addr, boolean enable)
|
|||
|
{
|
|||
|
u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_CLKENA_OFFSET);
|
|||
|
if (enable)
|
|||
|
reg_val |= FSDIO_CLKENA_CCLK_ENABLE;
|
|||
|
else
|
|||
|
reg_val &= ~FSDIO_CLKENA_CCLK_ENABLE;
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_CLKENA_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
static inline void FSdioSetPower(uintptr base_addr, boolean enable)
|
|||
|
{
|
|||
|
u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_PWREN_OFFSET);
|
|||
|
if (enable)
|
|||
|
reg_val |= FSDIO_PWREN_ENABLE;
|
|||
|
else
|
|||
|
reg_val &= ~FSDIO_PWREN_ENABLE;
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_PWREN_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
static inline void FSdioSetExtClock(uintptr base_addr, boolean enable)
|
|||
|
{
|
|||
|
u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_EXT_OFFSET);
|
|||
|
if (enable)
|
|||
|
reg_val |= FSDIO_UHS_EXT_CLK_ENA;
|
|||
|
else
|
|||
|
reg_val &= ~FSDIO_UHS_EXT_CLK_ENA;
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_UHS_REG_EXT_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
static inline void FSdioSetVoltage1_8V(uintptr base_addr, boolean v1_8)
|
|||
|
{
|
|||
|
u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_OFFSET);
|
|||
|
if (v1_8)
|
|||
|
reg_val |= FSDIO_UHS_REG_VOLT_180;
|
|||
|
else
|
|||
|
reg_val &= ~FSDIO_UHS_REG_VOLT_180; /* 3.3v */
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_UHS_REG_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioGetRawStatus
|
|||
|
* @msg: Get raw interrupt status of controller
|
|||
|
* @return {u32} raw interrupt status
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline u32 FSdioGetRawStatus(uintptr base_addr)
|
|||
|
{
|
|||
|
return FSDIO_READ_REG(base_addr, FSDIO_RAW_INTS_OFFSET);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioClearRawStatus
|
|||
|
* @msg: Clear raw interrupt status of controller
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline void FSdioClearRawStatus(uintptr base_addr)
|
|||
|
{
|
|||
|
u32 reg_val = FSdioGetRawStatus(base_addr);
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_RAW_INTS_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioGetStatus
|
|||
|
* @msg: Get status of controller
|
|||
|
* @return {u32} controller status
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline u32 FSdioGetStatus(uintptr base_addr)
|
|||
|
{
|
|||
|
return FSDIO_READ_REG(base_addr, FSDIO_STATUS_OFFSET);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioGetDMAStatus
|
|||
|
* @msg: Get interrupt status of DMA
|
|||
|
* @return {u32} DMA interrupt status
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline u32 FSdioGetDMAStatus(uintptr base_addr)
|
|||
|
{
|
|||
|
return FSDIO_READ_REG(base_addr, FSDIO_DMAC_STATUS_OFFSET);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioClearDMAStatus
|
|||
|
* @msg: Clear interrupt status of DMA
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline void FSdioClearDMAStatus(uintptr base_addr)
|
|||
|
{
|
|||
|
u32 reg_val = FSdioGetDMAStatus(base_addr);
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_DMAC_STATUS_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioSetDescriptor
|
|||
|
* @msg: Set base address of DMA descriptors
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
* @param {uintptr} descriptor, base address of DMA descriptors
|
|||
|
*/
|
|||
|
static inline void FSdioSetDescriptor(uintptr base_addr, uintptr descriptor)
|
|||
|
{
|
|||
|
#ifdef __aarch64___
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_DESC_LIST_ADDRH_OFFSET, UPPER_32_BITS(descriptor));
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_DESC_LIST_ADDRL_OFFSET, LOWER_32_BITS(descriptor));
|
|||
|
#else
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_DESC_LIST_ADDRH_OFFSET, 0x0U);
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_DESC_LIST_ADDRL_OFFSET, (u32)(descriptor));
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioSetTransBytes
|
|||
|
* @msg: Set number of bytes to transfer
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
* @param {u32} bytes, number of bytes to transfer
|
|||
|
*/
|
|||
|
static inline void FSdioSetTransBytes(uintptr base_addr, u32 bytes)
|
|||
|
{
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_BYT_CNT_OFFSET, bytes);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioSetBlockSize
|
|||
|
* @msg: Set size of blocks in card
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
* @param {u32} block_size, size of blocks in card
|
|||
|
*/
|
|||
|
static inline void FSdioSetBlockSize(uintptr base_addr, u32 block_size)
|
|||
|
{
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_BLK_SIZ_OFFSET, block_size);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioSetBusWidth
|
|||
|
* @msg: Set bus width of card
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
* @param {u32} width, bus width of card 1-bit, 4-bit, 8-bit
|
|||
|
*/
|
|||
|
static inline void FSdioSetBusWidth(uintptr base_addr, u32 width)
|
|||
|
{
|
|||
|
u32 reg_val;
|
|||
|
|
|||
|
switch (width)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
reg_val = FSDIO_CARD0_WIDTH2_1BIT;
|
|||
|
break;
|
|||
|
case 4:
|
|||
|
reg_val = FSDIO_CARD0_WIDTH2_4BIT;
|
|||
|
break;
|
|||
|
case 8:
|
|||
|
reg_val = FSDIO_CARD0_WIDTH1_8BIT;
|
|||
|
break;
|
|||
|
default:
|
|||
|
FASSERT_MSG(0, "invalid bus width %d", width);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_CTYPE_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioGetBusWidth
|
|||
|
* @msg: Get bus width for card
|
|||
|
* @return {u32} current bus width setting
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline u32 FSdioGetBusWidth(uintptr base_addr)
|
|||
|
{
|
|||
|
u32 bus_width = 1;
|
|||
|
u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_CTYPE_OFFSET);
|
|||
|
|
|||
|
if (FSDIO_CARD0_WIDTH2_4BIT & reg_val)
|
|||
|
{
|
|||
|
bus_width = 4;
|
|||
|
}
|
|||
|
else if (FSDIO_CARD0_WIDTH1_8BIT & reg_val)
|
|||
|
{
|
|||
|
bus_width = 8;
|
|||
|
}
|
|||
|
|
|||
|
return bus_width;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioResetIDMA
|
|||
|
* @msg: Reset for internal DMA
|
|||
|
* @return {NONE}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline void FSdioResetIDMA(uintptr base_addr)
|
|||
|
{
|
|||
|
u32 reg_val = FSDIO_READ_REG(base_addr, FSDIO_BUS_MODE_OFFSET);
|
|||
|
reg_val |= FSDIO_BUS_MODE_SWR; /* 写1软复位idma,复位完成后硬件自动清0 */
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_BUS_MODE_OFFSET, reg_val);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioSetDDRMode
|
|||
|
* @msg: Enable/Disable DDR mode
|
|||
|
* @return {*}
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
* @param {boolean} enable, TRUE: enable DDR mode
|
|||
|
*/
|
|||
|
static inline void FSdioSetDDRMode(uintptr base_addr, boolean enable)
|
|||
|
{
|
|||
|
u32 uhs_val = FSDIO_READ_REG(base_addr, FSDIO_UHS_REG_OFFSET);
|
|||
|
u32 emmc_val = FSDIO_READ_REG(base_addr, FSDIO_EMMC_DDR_REG_OFFSET);
|
|||
|
if (enable)
|
|||
|
{
|
|||
|
uhs_val |= FSDIO_UHS_REG_DDR;
|
|||
|
emmc_val |= FSDIO_EMMC_DDR_CYCLE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
uhs_val &= ~FSDIO_UHS_REG_DDR;
|
|||
|
emmc_val &= ~FSDIO_EMMC_DDR_CYCLE;
|
|||
|
}
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_UHS_REG_OFFSET, uhs_val);
|
|||
|
FSDIO_WRITE_REG(base_addr, FSDIO_EMMC_DDR_REG_OFFSET, emmc_val);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @name: FSdioCheckIfCardExists
|
|||
|
* @msg: Check if card inserted
|
|||
|
* @return {boolean} TRUE: inserted, FALSE: not-found
|
|||
|
* @param {uintptr} base_addr, base address of SDIO controller
|
|||
|
*/
|
|||
|
static inline boolean FSdioCheckIfCardExists(uintptr base_addr)
|
|||
|
{
|
|||
|
return (FSDIO_READ_REG(base_addr, FSDIO_CARD_DETECT_OFFSET) & FSDIO_CARD_DETECTED) ?
|
|||
|
FALSE : TRUE;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef __cplusplus
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#endif
|