fusee: SDMMC driver re-design:

- Based on hekate's, linux's and u-boot's source code;
- Full support for SD and MMC;
- Fixes multiple issues;
- Deployed first in fusee-primary.

fusee: Code cleanup and style fixes.
This commit is contained in:
hexkyz
2018-07-04 21:55:27 +01:00
parent 83c9747e5f
commit ddbbb0b758
30 changed files with 5077 additions and 4709 deletions

View File

@@ -0,0 +1,448 @@
/*
* Header for MultiMediaCard (MMC)
*
* Copyright 2002 Hewlett-Packard Company
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
* preserved in its entirety in all copies and derived works.
*
* HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
* FITNESS FOR ANY PARTICULAR PURPOSE.
*
* Many thanks to Alessandro Rubini and Jonathan Corbet!
*
* Based strongly on code by:
*
* Author: Yong-iL Joh <tolkien@mizi.com>
*
* Author: Andrew Christian
* 15 May 2002
*/
#ifndef LINUX_MMC_MMC_H
#define LINUX_MMC_MMC_H
/* Standard MMC commands (4.1) type argument response */
/* class 1 */
#define MMC_GO_IDLE_STATE 0 /* bc */
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define MMC_BUS_TEST_R 14 /* adtc R1 */
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define MMC_BUS_TEST_W 19 /* adtc R1 */
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
/* class 2 */
#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
/* class 4 */
#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define MMC_PROGRAM_CID 26 /* adtc R1 */
#define MMC_PROGRAM_CSD 27 /* adtc R1 */
/* class 6 */
#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
#define MMC_ERASE 38 /* ac R1b */
/* class 9 */
#define MMC_FAST_IO 39 /* ac <Complex> R4 */
#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
/* class 7 */
#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
/* class 8 */
#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */
/* class 11 */
#define MMC_QUE_TASK_PARAMS 44 /* ac [20:16] task id R1 */
#define MMC_QUE_TASK_ADDR 45 /* ac [31:0] data addr R1 */
#define MMC_EXECUTE_READ_TASK 46 /* adtc [20:16] task id R1 */
#define MMC_EXECUTE_WRITE_TASK 47 /* adtc [20:16] task id R1 */
#define MMC_CMDQ_TASK_MGMT 48 /* ac [20:16] task id R1b */
/*
* MMC_SWITCH argument format:
*
* [31:26] Always 0
* [25:24] Access Mode
* [23:16] Location of target Byte in EXT_CSD
* [15:08] Value Byte
* [07:03] Always 0
* [02:00] Command Set
*/
/*
MMC status in R1, for native mode (SPI bits are different)
Type
e : error bit
s : status bit
r : detected and set for the actual command response
x : detected and set during command execution. the host must poll
the card by sending status command in order to read these bits.
Clear condition
a : according to the card state
b : always related to the previous command. Reception of
a valid command will clear it (with a delay of one command)
c : clear by read
*/
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
#define R1_CC_ERROR (1 << 20) /* erx, c */
#define R1_ERROR (1 << 19) /* erx, c */
#define R1_UNDERRUN (1 << 18) /* ex, c */
#define R1_OVERRUN (1 << 17) /* ex, c */
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) (x & 0xFFFFE000)
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
#define R1_EXCEPTION_EVENT (1 << 6) /* sr, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
#define R1_STATE_IDLE 0
#define R1_STATE_READY 1
#define R1_STATE_IDENT 2
#define R1_STATE_STBY 3
#define R1_STATE_TRAN 4
#define R1_STATE_DATA 5
#define R1_STATE_RCV 6
#define R1_STATE_PRG 7
#define R1_STATE_DIS 8
/*
* MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
* R1 is the low order byte; R2 is the next highest byte, when present.
*/
#define R1_SPI_IDLE (1 << 0)
#define R1_SPI_ERASE_RESET (1 << 1)
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
#define R1_SPI_COM_CRC (1 << 3)
#define R1_SPI_ERASE_SEQ (1 << 4)
#define R1_SPI_ADDRESS (1 << 5)
#define R1_SPI_PARAMETER (1 << 6)
/* R1 bit 7 is always zero */
#define R2_SPI_CARD_LOCKED (1 << 8)
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
#define R2_SPI_ERROR (1 << 10)
#define R2_SPI_CC_ERROR (1 << 11)
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
#define R2_SPI_WP_VIOLATION (1 << 13)
#define R2_SPI_ERASE_PARAM (1 << 14)
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
/*
* OCR bits are mostly in host.h
*/
#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
#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 */
/*
* Card Command Classes (CCC)
*/
#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */
/* (CMD0,1,2,3,4,7,9,10,12,13,15) */
/* (and for SPI, CMD58,59) */
#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */
/* (CMD11) */
#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */
/* (CMD16,17,18) */
#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */
/* (CMD20) */
#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */
/* (CMD16,24,25,26,27) */
#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */
/* (CMD32,33,34,35,36,37,38,39) */
#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */
/* (CMD28,29,30) */
#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */
/* (CMD16,CMD42) */
#define CCC_APP_SPEC (1<<8) /* (8) Application specific */
/* (CMD55,56,57,ACMD*) */
#define CCC_IO_MODE (1<<9) /* (9) I/O mode */
/* (CMD5,39,40,52,53) */
#define CCC_SWITCH (1<<10) /* (10) High speed switch */
/* (CMD6,34,35,36,37,50) */
/* (11) Reserved */
/* (CMD?) */
/*
* CSD field definitions
*/
#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */
#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */
#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */
/*
* EXT_CSD fields
*/
#define EXT_CSD_CMDQ_MODE_EN 15 /* R/W */
#define EXT_CSD_FLUSH_CACHE 32 /* W */
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
#define EXT_CSD_BKOPS_EN 163 /* R/W */
#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
#define EXT_CSD_RPMB_MULT 168 /* RO */
#define EXT_CSD_FW_CONFIG 169 /* R/W */
#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_DRIVER_STRENGTH 197 /* RO */
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_TRIM_MULT 232 /* RO */
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
#define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */
#define EXT_CSD_PRE_EOL_INFO 267 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */
#define EXT_CSD_CMDQ_DEPTH 307 /* RO */
#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */
#define EXT_CSD_SUPPORTED_MODE 493 /* RO */
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_HPI_FEATURES 503 /* RO */
/*
* EXT_CSD field definitions
*/
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
#define EXT_CSD_CMD_SET_SECURE (1<<1)
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
EXT_CSD_CARD_TYPE_HS_52)
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
/* SDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
EXT_CSD_CARD_TYPE_HS200_1_2V)
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
#define EXT_CSD_BUS_WIDTH_STROBE BIT(7) /* Enhanced strobe mode */
#define EXT_CSD_TIMING_BC 0 /* Backwards compatility */
#define EXT_CSD_TIMING_HS 1 /* High speed */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_DRV_STR_SHIFT 4 /* Driver Strength shift */
#define EXT_CSD_SEC_ER_EN BIT(0)
#define EXT_CSD_SEC_BD_BLK_EN BIT(2)
#define EXT_CSD_SEC_GB_CL_EN BIT(4)
#define EXT_CSD_SEC_SANITIZE BIT(6) /* v4.5 only */
#define EXT_CSD_RST_N_EN_MASK 0x3
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
#define EXT_CSD_NO_POWER_NOTIFICATION 0
#define EXT_CSD_POWER_ON 1
#define EXT_CSD_POWER_OFF_SHORT 2
#define EXT_CSD_POWER_OFF_LONG 3
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
#define EXT_CSD_PACKED_EVENT_EN BIT(3)
/*
* EXCEPTION_EVENT_STATUS field
*/
#define EXT_CSD_URGENT_BKOPS BIT(0)
#define EXT_CSD_DYNCAP_NEEDED BIT(1)
#define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2)
#define EXT_CSD_PACKED_FAILURE BIT(3)
#define EXT_CSD_PACKED_GENERIC_ERROR BIT(0)
#define EXT_CSD_PACKED_INDEXED_ERROR BIT(1)
/*
* BKOPS status level
*/
#define EXT_CSD_BKOPS_LEVEL_2 0x2
/*
* BKOPS modes
*/
#define EXT_CSD_MANUAL_BKOPS_MASK 0x01
#define EXT_CSD_AUTO_BKOPS_MASK 0x02
/*
* Command Queue
*/
#define EXT_CSD_CMDQ_MODE_ENABLED BIT(0)
#define EXT_CSD_CMDQ_DEPTH_MASK GENMASK(4, 0)
#define EXT_CSD_CMDQ_SUPPORTED BIT(0)
/*
* MMC_SWITCH access modes
*/
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
/*
* Erase/trim/discard
*/
#define MMC_ERASE_ARG 0x00000000
#define MMC_SECURE_ERASE_ARG 0x80000000
#define MMC_TRIM_ARG 0x00000001
#define MMC_DISCARD_ARG 0x00000003
#define MMC_SECURE_TRIM1_ARG 0x80000001
#define MMC_SECURE_TRIM2_ARG 0x80008000
#define MMC_SECURE_ARGS 0x80000000
#define MMC_TRIM_ARGS 0x00008001
#endif /* LINUX_MMC_MMC_H */

View File

@@ -0,0 +1,153 @@
/*
* include/linux/mmc/sd.h
*
* Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#ifndef LINUX_MMC_SD_H
#define LINUX_MMC_SD_H
/* SD commands type argument response */
/* class 0 */
/* This is basically the same command as for MMC with some quirks. */
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
#define SD_SWITCH_VOLTAGE 11 /* ac R1 */
/* class 10 */
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
/* class 5 */
#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */
#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */
/* Application commands */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_SD_STATUS 13 /* adtc R1 */
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SET_CLR_CARD_DETECT 42 /* ac [0] set cd R1 */
#define SD_APP_SEND_SCR 51 /* adtc R1 */
/* OCR bit definitions */
#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
#define SD_OCR_XPC (1 << 28) /* SDXC power control */
#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
#define SD_OCR_VDD_LOW (1 << 7) /* SD: Reserved for Low Voltage Range */
#define SD_OCR_VDD_20_21 (1 << 8)
#define SD_OCR_VDD_21_22 (1 << 9)
#define SD_OCR_VDD_22_23 (1 << 10)
#define SD_OCR_VDD_23_24 (1 << 11)
#define SD_OCR_VDD_24_25 (1 << 12)
#define SD_OCR_VDD_25_26 (1 << 13)
#define SD_OCR_VDD_26_27 (1 << 14)
#define SD_OCR_VDD_27_28 (1 << 15)
#define SD_OCR_VDD_28_29 (1 << 16)
#define SD_OCR_VDD_29_30 (1 << 17)
#define SD_OCR_VDD_30_31 (1 << 18)
#define SD_OCR_VDD_31_32 (1 << 19)
#define SD_OCR_VDD_32_33 (1 << 20)
#define SD_OCR_VDD_33_34 (1 << 21)
#define SD_OCR_VDD_34_35 (1 << 22)
#define SD_OCR_VDD_35_36 (1 << 23)
/*
* SD_SWITCH argument format:
*
* [31] Check (0) or switch (1)
* [30:24] Reserved (0)
* [23:20] Function group 6
* [19:16] Function group 5
* [15:12] Function group 4
* [11:8] Function group 3
* [7:4] Function group 2
* [3:0] Function group 1
*/
/*
* SD_SEND_IF_COND argument format:
*
* [31:12] Reserved (0)
* [11:8] Host Voltage Supply Flags
* [7:0] Check Pattern (0xAA)
*/
/*
* SCR field definitions
*/
#define SD_SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
#define SD_SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
#define SD_SCR_SPEC_VER_2 2 /* Implements system specification 2.00-3.0X */
#define SD_SCR_BUS_WIDTH_1 1
#define SD_SCR_BUS_WIDTH_4 4
#define SD_SCR_CMD20_SUPPORT 1
#define SD_SCR_CMD23_SUPPORT 2
/*
* SD bus widths
*/
#define SD_BUS_WIDTH_1 0
#define SD_BUS_WIDTH_4 2
/*
* SD bus speed modes
*/
#define UHS_SDR12_BUS_SPEED 0
#define HIGH_SPEED_BUS_SPEED 1
#define UHS_SDR25_BUS_SPEED 1
#define UHS_SDR50_BUS_SPEED 2
#define UHS_SDR104_BUS_SPEED 3
#define UHS_DDR50_BUS_SPEED 4
#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED)
#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED)
#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED)
#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED)
#define SD_MODE_UHS_SDR104 (1 << UHS_SDR104_BUS_SPEED)
#define SD_MODE_UHS_DDR50 (1 << UHS_DDR50_BUS_SPEED)
/*
* SD bus driver types
*/
#define SD_DRIVER_TYPE_B 0x01
#define SD_DRIVER_TYPE_A 0x02
#define SD_DRIVER_TYPE_C 0x04
#define SD_DRIVER_TYPE_D 0x08
/*
* SD bus current limits
*/
#define SD_SET_CURRENT_LIMIT_200 0
#define SD_SET_CURRENT_LIMIT_400 1
#define SD_SET_CURRENT_LIMIT_600 2
#define SD_SET_CURRENT_LIMIT_800 3
#define SD_SET_CURRENT_NO_CHANGE (-1)
#define SD_MAX_CURRENT_200 (1 << SD_SET_CURRENT_LIMIT_200)
#define SD_MAX_CURRENT_400 (1 << SD_SET_CURRENT_LIMIT_400)
#define SD_MAX_CURRENT_600 (1 << SD_SET_CURRENT_LIMIT_600)
#define SD_MAX_CURRENT_800 (1 << SD_SET_CURRENT_LIMIT_800)
/*
* SD_SWITCH mode
*/
#define SD_SWITCH_CHECK 0
#define SD_SWITCH_SET 1
/*
* SD_SWITCH function groups
*/
#define SD_SWITCH_GRP_ACCESS 0
/*
* SD_SWITCH access modes
*/
#define SD_SWITCH_ACCESS_DEF 0
#define SD_SWITCH_ACCESS_HS 1
#endif /* LINUX_MMC_SD_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
#ifndef FUSEE_SDMMC_H
#define FUSEE_SDMMC_H
#include "sdmmc_core.h"
/* Structure for storing the MMC CID (adapted from Linux headers) */
typedef struct {
uint32_t manfid;
uint8_t prod_name[8];
uint8_t prv;
uint32_t serial;
uint16_t oemid;
uint16_t year;
uint8_t hwrev;
uint8_t fwrev;
uint8_t month;
} mmc_cid_t;
/* Structure for storing the MMC CSD (adapted from Linux headers) */
typedef struct {
uint8_t structure;
uint8_t mmca_vsn;
uint16_t cmdclass;
uint16_t taac_clks;
uint32_t taac_ns;
uint32_t c_size;
uint32_t r2w_factor;
uint32_t max_dtr;
uint32_t erase_size; /* In sectors */
uint32_t read_blkbits;
uint32_t write_blkbits;
uint32_t capacity;
uint32_t read_partial:1,
read_misalign:1,
write_partial:1,
write_misalign:1,
dsr_imp:1;
} mmc_csd_t;
/* Structure for storing the MMC extended CSD (adapted from Linux headers) */
typedef struct {
uint8_t rev;
uint8_t erase_group_def;
uint8_t sec_feature_support;
uint8_t rel_sectors;
uint8_t rel_param;
uint8_t part_config;
uint8_t cache_ctrl;
uint8_t rst_n_function;
uint8_t max_packed_writes;
uint8_t max_packed_reads;
uint8_t packed_event_en;
uint32_t part_time; /* Units: ms */
uint32_t sa_timeout; /* Units: 100ns */
uint32_t generic_cmd6_time; /* Units: 10ms */
uint32_t power_off_longtime; /* Units: ms */
uint8_t power_off_notification; /* state */
uint32_t hs_max_dtr;
uint32_t hs200_max_dtr;
uint32_t sectors;
uint32_t hc_erase_size; /* In sectors */
uint32_t hc_erase_timeout; /* In milliseconds */
uint32_t sec_trim_mult; /* Secure trim multiplier */
uint32_t sec_erase_mult; /* Secure erase multiplier */
uint32_t trim_timeout; /* In milliseconds */
uint32_t partition_setting_completed; /* enable bit */
uint64_t enhanced_area_offset; /* Units: Byte */
uint32_t enhanced_area_size; /* Units: KB */
uint32_t cache_size; /* Units: KB */
uint32_t hpi_en; /* HPI enablebit */
uint32_t hpi; /* HPI support bit */
uint32_t hpi_cmd; /* cmd used as HPI */
uint32_t bkops; /* background support bit */
uint32_t man_bkops_en; /* manual bkops enable bit */
uint32_t auto_bkops_en; /* auto bkops enable bit */
uint32_t data_sector_size; /* 512 bytes or 4KB */
uint32_t data_tag_unit_size; /* DATA TAG UNIT size */
uint32_t boot_ro_lock; /* ro lock support */
uint32_t boot_ro_lockable;
uint32_t ffu_capable; /* Firmware upgrade support */
uint32_t cmdq_en; /* Command Queue enabled */
uint32_t cmdq_support; /* Command Queue supported */
uint32_t cmdq_depth; /* Command Queue depth */
uint8_t fwrev[8]; /* FW version */
uint8_t raw_exception_status; /* 54 */
uint8_t raw_partition_support; /* 160 */
uint8_t raw_rpmb_size_mult; /* 168 */
uint8_t raw_erased_mem_count; /* 181 */
uint8_t strobe_support; /* 184 */
uint8_t raw_ext_csd_structure; /* 194 */
uint8_t raw_card_type; /* 196 */
uint8_t raw_driver_strength; /* 197 */
uint8_t out_of_int_time; /* 198 */
uint8_t raw_pwr_cl_52_195; /* 200 */
uint8_t raw_pwr_cl_26_195; /* 201 */
uint8_t raw_pwr_cl_52_360; /* 202 */
uint8_t raw_pwr_cl_26_360; /* 203 */
uint8_t raw_s_a_timeout; /* 217 */
uint8_t raw_hc_erase_gap_size; /* 221 */
uint8_t raw_erase_timeout_mult; /* 223 */
uint8_t raw_hc_erase_grp_size; /* 224 */
uint8_t raw_sec_trim_mult; /* 229 */
uint8_t raw_sec_erase_mult; /* 230 */
uint8_t raw_sec_feature_support; /* 231 */
uint8_t raw_trim_mult; /* 232 */
uint8_t raw_pwr_cl_200_195; /* 236 */
uint8_t raw_pwr_cl_200_360; /* 237 */
uint8_t raw_pwr_cl_ddr_52_195; /* 238 */
uint8_t raw_pwr_cl_ddr_52_360; /* 239 */
uint8_t raw_pwr_cl_ddr_200_360; /* 253 */
uint8_t raw_bkops_status; /* 246 */
uint8_t raw_sectors[4]; /* 212 - 4 bytes */
uint8_t pre_eol_info; /* 267 */
uint8_t device_life_time_est_typ_a; /* 268 */
uint8_t device_life_time_est_typ_b; /* 269 */
uint32_t feature_support;
} mmc_ext_csd_t;
/* Structure for storing the SD SCR (adapted from Linux headers) */
typedef struct {
uint8_t sda_vsn;
uint8_t sda_spec3;
uint8_t bus_widths;
uint8_t cmds;
} sd_scr_t;
/* Structure for storing the SD SSR (adapted from Linux headers) */
typedef struct {
uint8_t dat_bus_width;
uint8_t secured_mode;
uint16_t sd_card_type;
uint8_t speed_class;
uint8_t uhs_speed_grade;
uint8_t uhs_au_size;
uint8_t video_speed_class;
uint8_t app_perf_class;
} sd_ssr_t;
/* Structure describing a SDMMC device's context. */
typedef struct {
/* Underlying driver context. */
sdmmc_t *sdmmc;
bool is_180v;
bool is_block_sdhc;
uint32_t rca;
mmc_cid_t cid;
mmc_csd_t csd;
mmc_ext_csd_t ext_csd;
sd_scr_t scr;
sd_ssr_t ssr;
} sdmmc_device_t;
int sdmmc_device_sd_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed);
int sdmmc_device_mmc_init(sdmmc_device_t *device, sdmmc_t *sdmmc, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed);
int sdmmc_device_read(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data);
int sdmmc_device_write(sdmmc_device_t *device, uint32_t sector, uint32_t num_sectors, void *data);
int sdmmc_device_finish(sdmmc_device_t *device);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,287 @@
#ifndef FUSEE_SDMMC_CORE_H
#define FUSEE_SDMMC_CORE_H
#include "sdmmc_tegra.h"
/* Present state */
#define SDHCI_CMD_INHIBIT 0x00000001
#define SDHCI_DATA_INHIBIT 0x00000002
#define SDHCI_DOING_WRITE 0x00000100
#define SDHCI_DOING_READ 0x00000200
#define SDHCI_SPACE_AVAILABLE 0x00000400
#define SDHCI_DATA_AVAILABLE 0x00000800
#define SDHCI_CARD_PRESENT 0x00010000
#define SDHCI_WRITE_PROTECT 0x00080000
#define SDHCI_DATA_LVL_MASK 0x00F00000
#define SDHCI_DATA_LVL_SHIFT 20
#define SDHCI_DATA_0_LVL_MASK 0x00100000
#define SDHCI_CMD_LVL 0x01000000
/* SDHCI clock control */
#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_PROG_CLOCK_MODE 0x0020
#define SDHCI_CLOCK_CARD_EN 0x0004
#define SDHCI_CLOCK_INT_STABLE 0x0002
#define SDHCI_CLOCK_INT_EN 0x0001
/* SDHCI host control */
#define SDHCI_CTRL_LED 0x01
#define SDHCI_CTRL_4BITBUS 0x02
#define SDHCI_CTRL_HISPD 0x04
#define SDHCI_CTRL_DMA_MASK 0x18
#define SDHCI_CTRL_SDMA 0x00
#define SDHCI_CTRL_ADMA1 0x08
#define SDHCI_CTRL_ADMA32 0x10
#define SDHCI_CTRL_ADMA64 0x18
#define SDHCI_CTRL_8BITBUS 0x20
#define SDHCI_CTRL_CDTEST_INS 0x40
#define SDHCI_CTRL_CDTEST_EN 0x80
/* SDHCI host control 2 */
#define SDHCI_CTRL_UHS_MASK 0x0007
#define SDHCI_CTRL_UHS_SDR12 0x0000
#define SDHCI_CTRL_UHS_SDR25 0x0001
#define SDHCI_CTRL_UHS_SDR50 0x0002
#define SDHCI_CTRL_UHS_SDR104 0x0003
#define SDHCI_CTRL_UHS_DDR50 0x0004
#define SDHCI_CTRL_HS400 0x0005
#define SDHCI_CTRL_VDD_180 0x0008
#define SDHCI_CTRL_DRV_TYPE_MASK 0x0030
#define SDHCI_CTRL_DRV_TYPE_B 0x0000
#define SDHCI_CTRL_DRV_TYPE_A 0x0010
#define SDHCI_CTRL_DRV_TYPE_C 0x0020
#define SDHCI_CTRL_DRV_TYPE_D 0x0030
#define SDHCI_CTRL_EXEC_TUNING 0x0040
#define SDHCI_CTRL_TUNED_CLK 0x0080
#define SDHCI_UHS2_IF_EN 0x0100
#define SDHCI_HOST_VERSION_4_EN 0x1000
#define SDHCI_ADDRESSING_64BIT_EN 0x2000
#define SDHCI_ASYNC_INTR_EN 0x4000
#define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000
/* SDHCI capabilities */
#define SDHCI_CAN_DO_8BIT 0x00040000
#define SDHCI_CAN_DO_ADMA2 0x00080000
#define SDHCI_CAN_DO_ADMA1 0x00100000
#define SDHCI_CAN_DO_HISPD 0x00200000
#define SDHCI_CAN_DO_SDMA 0x00400000
#define SDHCI_CAN_VDD_330 0x01000000
#define SDHCI_CAN_VDD_300 0x02000000
#define SDHCI_CAN_VDD_180 0x04000000
#define SDHCI_CAN_64BIT 0x10000000
#define SDHCI_ASYNC_INTR 0x20000000
/* Vendor clock control */
#define SDMMC_CLOCK_TAP_MASK (0xFF << 16)
#define SDMMC_CLOCK_TAP_SDMMC1 (0x04 << 16)
#define SDMMC_CLOCK_TAP_SDMMC2 (0x00 << 16)
#define SDMMC_CLOCK_TAP_SDMMC3 (0x03 << 16)
#define SDMMC_CLOCK_TAP_SDMMC4 (0x00 << 16)
#define SDMMC_CLOCK_TRIM_MASK (0xFF << 24)
#define SDMMC_CLOCK_TRIM_SDMMC1 (0x02 << 24)
#define SDMMC_CLOCK_TRIM_SDMMC2 (0x08 << 24)
#define SDMMC_CLOCK_TRIM_SDMMC3 (0x03 << 24)
#define SDMMC_CLOCK_TRIM_SDMMC4 (0x08 << 24)
#define SDMMC_CLOCK_PADPIPE_CLKEN_OVERRIDE (1 << 3)
/* Autocal configuration */
#define SDMMC_AUTOCAL_PDPU_CONFIG_MASK 0x7F7F
#define SDMMC_AUTOCAL_PDPU_SDMMC1_1V8 0x7B7B
#define SDMMC_AUTOCAL_PDPU_SDMMC1_3V3 0x7D00
#define SDMMC_AUTOCAL_PDPU_SDMMC4_1V8 0x0505
#define SDMMC_AUTOCAL_START (1 << 31)
#define SDMMC_AUTOCAL_ENABLE (1 << 29)
/* Autocal status */
#define SDMMC_AUTOCAL_ACTIVE (1 << 31)
/* Vendor tuning control 0*/
#define SDMMC_VENDOR_TUNING_TRIES_MASK (0x7 << 13)
#define SDMMC_VENDOR_TUNING_TRIES_SHIFT 13
#define SDMMC_VENDOR_TUNING_MULTIPLIER_MASK (0x7F << 6)
#define SDMMC_VENDOR_TUNING_MULTIPLIER_UNITY (1 << 6)
#define SDMMC_VENDOR_TUNING_DIVIDER_MASK (0x7 << 3)
#define SDMMC_VENDOR_TUNING_SET_BY_HW (1 << 17)
/* Vendor tuning control 1*/
#define SDMMC_VENDOR_TUNING_STEP_SIZE_SDR50_DEFAULT (0 << 0)
#define SDMMC_VENDOR_TUNING_STEP_SIZE_SDR104_DEFAULT (0 << 4)
/* Vendor capability overrides */
#define SDMMC_VENDOR_CAPABILITY_DQS_TRIM_MASK (0x3F << 8)
#define SDMMC_VENDOR_CAPABILITY_DQS_TRIM_HS400 (0x11 << 8)
/* Timeouts */
#define SDMMC_AUTOCAL_TIMEOUT (10 * 1000)
#define SDMMC_TUNING_TIMEOUT (150 * 1000)
/* Command response flags */
#define SDMMC_RSP_PRESENT (1 << 0)
#define SDMMC_RSP_136 (1 << 1)
#define SDMMC_RSP_CRC (1 << 2)
#define SDMMC_RSP_BUSY (1 << 3)
#define SDMMC_RSP_OPCODE (1 << 4)
/* Command types */
#define SDMMC_CMD_MASK (3 << 5)
#define SDMMC_CMD_AC (0 << 5)
#define SDMMC_CMD_ADTC (1 << 5)
#define SDMMC_CMD_BC (2 << 5)
#define SDMMC_CMD_BCR (3 << 5)
/* SPI command response flags */
#define SDMMC_RSP_SPI_S1 (1 << 7)
#define SDMMC_RSP_SPI_S2 (1 << 8)
#define SDMMC_RSP_SPI_B4 (1 << 9)
#define SDMMC_RSP_SPI_BUSY (1 << 10)
/* Native response types for commands */
#define SDMMC_RSP_NONE (0)
#define SDMMC_RSP_R1 (SDMMC_RSP_PRESENT|SDMMC_RSP_CRC|SDMMC_RSP_OPCODE)
#define SDMMC_RSP_R1B (SDMMC_RSP_PRESENT|SDMMC_RSP_CRC|SDMMC_RSP_OPCODE|SDMMC_RSP_BUSY)
#define SDMMC_RSP_R2 (SDMMC_RSP_PRESENT|SDMMC_RSP_136|SDMMC_RSP_CRC)
#define SDMMC_RSP_R3 (SDMMC_RSP_PRESENT)
#define SDMMC_RSP_R4 (SDMMC_RSP_PRESENT)
#define SDMMC_RSP_R5 (SDMMC_RSP_PRESENT|SDMMC_RSP_CRC|SDMMC_RSP_OPCODE)
#define SDMMC_RSP_R6 (SDMMC_RSP_PRESENT|SDMMC_RSP_CRC|SDMMC_RSP_OPCODE)
#define SDMMC_RSP_R7 (SDMMC_RSP_PRESENT|SDMMC_RSP_CRC|SDMMC_RSP_OPCODE)
#define SDMMC_RSP_R1_NO_CRC (SDMMC_RSP_PRESENT|SDMMC_RSP_OPCODE)
/* SPI response types for commands */
#define SDMMC_RSP_SPI_R1 (SDMMC_RSP_SPI_S1)
#define SDMMC_RSP_SPI_R1B (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_BUSY)
#define SDMMC_RSP_SPI_R2 (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_S2)
#define SDMMC_RSP_SPI_R3 (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_B4)
#define SDMMC_RSP_SPI_R4 (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_B4)
#define SDMMC_RSP_SPI_R5 (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_S2)
#define SDMMC_RSP_SPI_R7 (SDMMC_RSP_SPI_S1|SDMMC_RSP_SPI_B4)
/* Internal logging */
typedef enum {
SDMMC_LOG_NONE = 0,
SDMMC_LOG_ERROR = 1,
SDMMC_LOG_WARN = 2,
SDMMC_LOG_INFO = 3,
SDMMC_LOG_DEBUG = 4
} SdmmcLogLevel;
/* SDMMC controllers */
typedef enum {
SDMMC_1 = 0,
SDMMC_2 = 1,
SDMMC_3 = 2,
SDMMC_4 = 3
} SdmmcControllerNum;
typedef enum {
SDMMC_VOLTAGE_NONE = 0,
SDMMC_VOLTAGE_1V8 = 1,
SDMMC_VOLTAGE_3V3 = 2
} SdmmcBusVoltage;
typedef enum {
SDMMC_BUS_WIDTH_1BIT = 0,
SDMMC_BUS_WIDTH_4BIT = 1,
SDMMC_BUS_WIDTH_8BIT = 2
} SdmmcBusWidth;
typedef enum {
SDMMC_SPEED_INIT_HS = 0,
SDMMC_SPEED_HS26 = 1,
SDMMC_SPEED_HS52 = 2,
SDMMC_SPEED_HS200 = 3,
SDMMC_SPEED_HS400 = 4,
SDMMC_SPEED_INIT_SDR = 5,
SDMMC_SPEED_UNK6 = 6,
SDMMC_SPEED_SDR25 = 7,
SDMMC_SPEED_SDR12 = 8,
SDMMC_SPEED_UNK9 = 9,
SDMMC_SPEED_SDR50 = 10,
SDMMC_SPEED_SDR104 = 11,
SDMMC_SPEED_UNK12 = 12,
SDMMC_SPEED_DDR50 = 13,
SDMMC_SPEED_UNK14 = 14,
} SdmmcBusSpeed;
typedef enum {
SDMMC_CAR_DIVIDER_SDR12 = 31, // (16.5 * 2) - 2
SDMMC_CAR_DIVIDER_SDR25 = 15, // (8.5 * 2) - 2
SDMMC_CAR_DIVIDER_SDR50 = 7, // (4.5 * 2) - 2
SDMMC_CAR_DIVIDER_SDR104 = 2, // (2 * 2) - 2
SDMMC_CAR_DIVIDER_DDR50 = 18, // (5 * 2 * 2) - 2
SDMMC_CAR_DIVIDER_HS26 = 30, // (16 * 2) - 2
SDMMC_CAR_DIVIDER_HS52 = 14, // (8 * 2) - 2
SDMMC_CAR_DIVIDER_HS200 = 3, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ
SDMMC_CAR_DIVIDER_HS400 = 3, // 1 -- NOTE THIS IS WITH RESPECT TO PLLC4_OUT2_LJ
} SdmmcCarDivider;
/* Structure for describing a SDMMC device. */
typedef struct {
/* Controller number */
SdmmcControllerNum controller;
/* Backing register space */
volatile tegra_sdmmc_t *regs;
/* Controller properties */
const char *name;
bool has_sd;
bool is_clk_running;
bool is_sd_clk_enabled;
bool is_tuning_tap_val_set;
bool use_adma;
uint32_t tap_val;
uint32_t internal_divider;
uint32_t resp[4];
uint32_t resp_auto_cmd12;
uint32_t next_dma_addr;
uint8_t* dma_bounce_buf;
SdmmcBusVoltage bus_voltage;
SdmmcBusWidth bus_width;
/* Per-controller operations. */
int (*sdmmc_config)();
} sdmmc_t;
/* Structure for describing a SDMMC command. */
typedef struct {
uint32_t opcode;
uint32_t arg;
uint32_t resp[4];
uint32_t flags; /* expected response type */
} sdmmc_command_t;
/* Structure for describing a SDMMC request. */
typedef struct {
void* data;
uint32_t blksz;
uint32_t num_blocks;
bool is_multi_block;
bool is_read;
bool is_auto_cmd12;
} sdmmc_request_t;
int sdmmc_init(sdmmc_t *sdmmc, SdmmcControllerNum controller, SdmmcBusVoltage bus_voltage, SdmmcBusWidth bus_width, SdmmcBusSpeed bus_speed);
void sdmmc_finish(sdmmc_t *sdmmc);
int sdmmc_select_speed(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed);
void sdmmc_select_bus_width(sdmmc_t *sdmmc, SdmmcBusWidth width);
void sdmmc_select_voltage(sdmmc_t *sdmmc, SdmmcBusVoltage voltage);
void sdmmc_adjust_sd_clock(sdmmc_t *sdmmc);
int sdmmc_switch_voltage(sdmmc_t *sdmmc);
void sdmmc_set_tuning_tap_val(sdmmc_t *sdmmc);
int sdmmc_execute_tuning(sdmmc_t *sdmmc, SdmmcBusSpeed bus_speed, uint32_t opcode);
int sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_command_t *cmd, sdmmc_request_t *req, uint32_t *num_blocks_out);
int sdmmc_load_response(sdmmc_t *sdmmc, uint32_t flags, uint32_t *resp);
int sdmmc_abort(sdmmc_t *sdmmc, uint32_t opcode);
void sdmmc_set_log_level(SdmmcLogLevel log_level);
void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...);
void sdmmc_warn(sdmmc_t *sdmmc, char *fmt, ...);
void sdmmc_info(sdmmc_t *sdmmc, char *fmt, ...);
void sdmmc_debug(sdmmc_t *sdmmc, char *fmt, ...);
void sdmmc_dump_regs(sdmmc_t *sdmmc);
#endif

View File

@@ -0,0 +1,154 @@
#ifndef FUSEE_SDMMC_TEGRA_H
#define FUSEE_SDMMC_TEGRA_H
#include <stdbool.h>
#include <stdint.h>
#define TEGRA_MMC_PWRCTL_SD_BUS_POWER (1 << 0)
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 (5 << 1)
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 (6 << 1)
#define TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 (7 << 1)
#define TEGRA_MMC_HOSTCTL_DMASEL_MASK (3 << 3)
#define TEGRA_MMC_HOSTCTL_DMASEL_SDMA (0 << 3)
#define TEGRA_MMC_HOSTCTL_DMASEL_ADMA2_32BIT (2 << 3)
#define TEGRA_MMC_HOSTCTL_DMASEL_ADMA2_64BIT (3 << 3)
#define TEGRA_MMC_TRNMOD_DMA_ENABLE (1 << 0)
#define TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE (1 << 1)
#define TEGRA_MMC_TRNMOD_AUTO_CMD12 (1 << 2)
#define TEGRA_MMC_TRNMOD_AUTO_CMD23 (1 << 3)
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE (0 << 4)
#define TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ (1 << 4)
#define TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT (1 << 5)
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_MASK (3 << 0)
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE (0 << 0)
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 (1 << 0)
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 (2 << 0)
#define TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY (3 << 0)
#define TEGRA_MMC_TRNMOD_CMD_CRC_CHECK (1 << 3)
#define TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK (1 << 4)
#define TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER (1 << 5)
#define TEGRA_MMC_PRNSTS_CMD_INHIBIT_CMD (1 << 0)
#define TEGRA_MMC_PRNSTS_CMD_INHIBIT_DAT (1 << 1)
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE (1 << 0)
#define TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE (1 << 1)
#define TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE (1 << 2)
#define TEGRA_MMC_CLKCON_PROG_CLOCK_MODE (1 << 5)
#define TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_SHIFT 8
#define TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_MASK (0xff << 8)
#define TEGRA_MMC_SWRST_SW_RESET_FOR_ALL (1 << 0)
#define TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE (1 << 1)
#define TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE (1 << 2)
#define TEGRA_MMC_NORINTSTS_CMD_COMPLETE (1 << 0)
#define TEGRA_MMC_NORINTSTS_XFER_COMPLETE (1 << 1)
#define TEGRA_MMC_NORINTSTS_DMA_INTERRUPT (1 << 3)
#define TEGRA_MMC_NORINTSTS_ERR_INTERRUPT (1 << 15)
#define TEGRA_MMC_NORINTSTS_CMD_TIMEOUT (1 << 16)
#define TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE (1 << 0)
#define TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE (1 << 1)
#define TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT (1 << 3)
#define TEGRA_MMC_NORINTSTSEN_BUFFER_WRITE_READY (1 << 4)
#define TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY (1 << 5)
#define TEGRA_MMC_NORINTSIGEN_XFER_COMPLETE (1 << 1)
typedef struct {
/* SDHCI standard registers */
uint32_t dma_address;
uint16_t block_size;
uint16_t block_count;
uint32_t argument;
uint16_t transfer_mode;
uint16_t command;
uint32_t response[0x4];
uint32_t buffer;
uint32_t present_state;
uint8_t host_control;
uint8_t power_control;
uint8_t block_gap_control;
uint8_t wake_up_control;
uint16_t clock_control;
uint8_t timeout_control;
uint8_t software_reset;
uint32_t int_status;
uint32_t int_enable;
uint32_t signal_enable;
uint16_t acmd12_err;
uint16_t host_control2;
uint32_t capabilities;
uint32_t capabilities_1;
uint32_t max_current;
uint32_t _0x4c;
uint16_t set_acmd12_error;
uint16_t set_int_error;
uint8_t adma_error;
uint8_t _0x56[0x3];
uint32_t adma_address;
uint32_t upper_adma_address;
uint16_t preset_for_init;
uint16_t preset_for_default;
uint16_t preset_for_high;
uint16_t preset_for_sdr12;
uint16_t preset_for_sdr25;
uint16_t preset_for_sdr50;
uint16_t preset_for_sdr104;
uint16_t preset_for_ddr50;
uint32_t _0x70[0x23];
uint16_t slot_int_status;
uint16_t host_version;
/* vendor specific registers */
uint32_t vendor_clock_cntrl;
uint32_t vendor_sys_sw_cntrl;
uint32_t vendor_err_intr_status;
uint32_t vendor_cap_overrides;
uint32_t vendor_boot_cntrl;
uint32_t vendor_boot_ack_timeout;
uint32_t vendor_boot_dat_timeout;
uint32_t vendor_debounce_count;
uint32_t vendor_misc_cntrl;
uint32_t max_current_override;
uint32_t max_current_override_hi;
uint32_t _0x12c[0x20];
uint32_t vendor_io_trim_cntrl;
/* start of sdmmc2/sdmmc4 only */
uint32_t vendor_dllcal_cfg;
uint32_t vendor_dll_ctrl0;
uint32_t vendor_dll_ctrl1;
uint32_t vendor_dllcal_cfg_sta;
/* end of sdmmc2/sdmmc4 only */
uint32_t vendor_tuning_cntrl0;
uint32_t vendor_tuning_cntrl1;
uint32_t vendor_tuning_status0;
uint32_t vendor_tuning_status1;
uint32_t vendor_clk_gate_hysteresis_count;
uint32_t vendor_preset_val0;
uint32_t vendor_preset_val1;
uint32_t vendor_preset_val2;
uint32_t sdmemcomppadctrl;
uint32_t auto_cal_config;
uint32_t auto_cal_interval;
uint32_t auto_cal_status;
uint32_t io_spare;
uint32_t sdmmca_mccif_fifoctrl;
uint32_t timeout_wcoal_sdmmca;
uint32_t _0x1fc;
} tegra_sdmmc_t;
static inline volatile tegra_sdmmc_t *sdmmc_get_regs(uint32_t idx)
{
return (volatile tegra_sdmmc_t *)(0x700B0000 + (idx * 0x200));
}
#endif