2023-10-14 17:49:00 +08:00

251 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
/*
* This file is part of open_agb_firm
* Copyright (C) 2021 derrek, profi200
*
* 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 3 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Based on JEDEC eMMC Card Product Standard V4.41.
#include "drivers/tmio.h"
// Controller specific macros. Add controller specific bits here.
// MMC_CMD_[response type]_[transfer type]
// Transfer type: R = read, W = write.
#define MMC_CMD_NONE(id) (CMD_RESP_NONE | (id))
#define MMC_CMD_R1(id) (CMD_RESP_R1 | (id))
#define MMC_CMD_R1b(id) (CMD_RESP_R1b | (id))
#define MMC_CMD_R2(id) (CMD_RESP_R2 | (id))
#define MMC_CMD_R3(id) (CMD_RESP_R3 | (id))
#define MMC_CMD_R4(id) (CMD_RESP_R4 | (id))
#define MMC_CMD_R5(id) (CMD_RESP_R5 | (id))
#define MMC_CMD_R1_R(id) (CMD_DATA_R | CMD_DATA_EN | CMD_RESP_R1 | (id))
#define MMC_CMD_R1_W(id) (CMD_DATA_W | CMD_DATA_EN | CMD_RESP_R1 | (id))
// Basic commands and read-stream command (class 0 and class 1).
#define MMC_GO_IDLE_STATE MMC_CMD_NONE(0u) // -, [31:0] 0x00000000 GO_IDLE_STATE, 0xF0F0F0F0 GO_PRE_IDLE_STATE, 0xFFFFFFFA BOOT_INITIATION.
#define MMC_SEND_OP_COND MMC_CMD_R3(1u) // R3, [31:0] OCR with-out busy.
#define MMC_ALL_SEND_CID MMC_CMD_R2(2u) // R2, [31:0] stuff bits.
#define MMC_SET_RELATIVE_ADDR MMC_CMD_R1(3u) // R1, [31:16] RCA [15:0] stuff bits.
#define MMC_SET_DSR MMC_CMD_NONE(4u) // -, [31:16] DSR [15:0] stuff bits.
#define MMC_SLEEP_AWAKE MMC_CMD_R1b(5u) // R1b, [31:16] RCA [15] Sleep/Awake [14:0] stuff bits.
#define MMC_SWITCH MMC_CMD_R1b(6u) // R1b, [31:26] Set to 0 [25:24] Access [23:16] Index [15:8] Value [7:3] Set to 0 [2:0] Cmd Set.
#define MMC_SELECT_CARD MMC_CMD_R1b(7u) // R1/R1b, [31:16] RCA [15:0] stuff bits. Note: "R1b while selecting from Disconnected State to Programming State."
#define MMC_DESELECT_CARD MMC_CMD_NONE(7u) // -, [31:16] RCA [15:0] stuff bits.
#define MMC_SEND_EXT_CSD MMC_CMD_R1_R(8u) // R1, [31:0] stuff bits.
#define MMC_SEND_CSD MMC_CMD_R2(9u) // R2, [31:16] RCA [15:0] stuff bits.
#define MMC_SEND_CID MMC_CMD_R2(10u) // R2, [31:16] RCA [15:0] stuff bits.
#define MMC_READ_DAT_UNTIL_STOP MMC_CMD_R1_R(11u) // R1, [31:0] data address.
#define MMC_STOP_TRANSMISSION MMC_CMD_R1b(12u) // R1/R1b, [31:16] RCA [15:1] stuff bits [0] HPI. Note: "RCA in CMD12 is used only if HPI bit is set." Note 2: "R1 for read cases and R1b for write cases."
#define MMC_SEND_STATUS MMC_CMD_R1(13u) // R1, [31:16] RCA [15:1] stuff bits [0] HPI.
#define MMC_BUSTEST_R MMC_CMD_R1_R(14u) // R1, [31:0] stuff bits.
#define MMC_GO_INACTIVE_STATE MMC_CMD_NONE(15u) // -, [31:16] RCA [15:0] stuff bits.
#define MMC_BUSTEST_W MMC_CMD_R1_W(19u) // R1, [31:0] stuff bits.
// Block-oriented read commands (class 2).
#define MMC_SET_BLOCKLEN MMC_CMD_R1(16u) // R1, [31:0] block length.
#define MMC_READ_SINGLE_BLOCK MMC_CMD_R1_R(17u) // R1, [31:0] data address.
#define MMC_READ_MULTIPLE_BLOCK MMC_CMD_R1_R(18u) // R1, [31:0] data address.
// Stream write commands (class 3).
#define MMC_WRITE_DAT_UNTIL_STOP MMC_CMD_R1_W(20u) // R1, [31:0] data address.
// Block-oriented write commands (class 4).
#define MMC_SET_BLOCK_COUNT MMC_CMD_R1(23u) // R1, [31] Reliable Write Request [30:16] set to 0 [15:0] number of blocks.
#define MMC_WRITE_BLOCK MMC_CMD_R1_W(24u) // R1, [31:0] data address.
#define MMC_WRITE_MULTIPLE_BLOCK MMC_CMD_R1_W(25u) // R1, [31:0] data address.
#define MMC_PROGRAM_CID MMC_CMD_R1_W(26u) // R1, [31:0] stuff bits.
#define MMC_PROGRAM_CSD MMC_CMD_R1_W(27u) // R1, [31:0] stuff bits.
// Block-oriented write protection commands (class 6).
#define MMC_SET_WRITE_PROT MMC_CMD_R1b(28u) // R1b, [31:0] data address.
#define MMC_CLR_WRITE_PROT MMC_CMD_R1b(29u) // R1b, [31:0] data address.
#define MMC_SEND_WRITE_PROT MMC_CMD_R1_R(30u) // R1, [31:0] write protect data address.
#define MMC_SEND_WRITE_PROT_TYPE MMC_CMD_R1_R(31u) // R1, [31:0] write protect data address.
// Erase commands (class 5).
#define MMC_ERASE_GROUP_START MMC_CMD_R1(35u) // R1, [31:0] data address.
#define MMC_ERASE_GROUP_END MMC_CMD_R1(36u) // R1, [31:0] data address.
#define MMC_ERASE MMC_CMD_R1b(38u) // R1b, [31] Secure request [30:16] set to 0 [15] Force Garbage Collect request [14:1] set to 0 [0] Identify Write block for Erase.
// I/O mode commands (class 9).
#define MMC_FAST_IO MMC_CMD_R4(39u) // R4, [31:16] RCA [15:15] register write flag [14:8] register address [7:0] register data.
#define MMC_GO_IRQ_STATE MMC_CMD_R5(40u) // R5, [31:0] stuff bits.
// Lock card commands (class 7).
#define MMC_LOCK_UNLOCK MMC_CMD_R1_W(42u) // R1, [31:0] stuff bits.
// Application-specific commands (class 8).
#define MMC_APP_CMD MMC_CMD_R1(55u) // R1, [31:16] RCA [15:0] stuff bits.
#define MMC_GEN_CMD_R MMC_CMD_R1_R(56u) // R1, [31:1] stuff bits [0] RD/WR = 1.
#define MMC_GEN_CMD_W MMC_CMD_R1_W(56u) // R1, [31:1] stuff bits [0] RD/WR = 0.
// 7.13 Card status.
// 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 can get the status by issuing a command with R1 response.
//
// Clear Condition:
// A: These bits are persistent, they are set and cleared in accordance with the card status.
// B: These bits are cleared as soon as the response (reporting the error) is sent out.
#define MMC_R1_APP_CMD (1u<<5) // S R A, The card will expect ACMD, or indication that the command has been interpreted as ACMD.
#define MMC_R1_URGENT_BKOPS (1u<<6) // S R A, If set, device needs to perform backgroundoperations urgently. Host can check EXT_CSD field BKOPS_STATUS for the detailed level.
#define MMC_R1_SWITCH_ERROR (1u<<7) // E X B, If set, the card did not switch to the expected mode as requested by the SWITCH command.
#define MMC_R1_READY_FOR_DATA (1u<<8) // S R A, Corresponds to buffer empty signalling on the bus.
#define MMC_R1_STATE_IDLE (0u<<9) // S R A
#define MMC_R1_STATE_READY (1u<<9) // S R A
#define MMC_R1_STATE_IDENT (2u<<9) // S R A
#define MMC_R1_STATE_STBY (3u<<9) // S R A
#define MMC_R1_STATE_TRAN (4u<<9) // S R A
#define MMC_R1_STATE_DATA (5u<<9) // S R A
#define MMC_R1_STATE_RCV (6u<<9) // S R A
#define MMC_R1_STATE_PRG (7u<<9) // S R A
#define MMC_R1_STATE_DIS (8u<<9) // S R A
#define MMC_R1_STATE_BTST (9u<<9) // S R A
#define MMC_R1_STATE_SLP (10u<<9) // S R A
#define MMC_R1_ERASE_RESET (1u<<13) // E R B, An erase sequence was cleared before executing because an out of erase sequence command was received (commands other than CMD35, CMD36, CMD38 or CMD13.
#define MMC_R1_WP_ERASE_SKIP (1u<<15) // E X B, Only partial address space was erased due to existing write protected blocks.
#define MMC_R1_CXD_OVERWRITE (1u<<16) // E X B, Can be either one of the following errors: - The CID register has been already written and can not be overwritten - The read only section of the CSD does not match the card content. - An attempt to reverse the copy (set as original) or permanent WP (unprotected) bits was made.
#define MMC_R1_OVERRUN (1u<<17) // E X B, The card could not sustain data programming in stream write mode.
#define MMC_R1_UNDERRUN (1u<<18) // E X B, The card could not sustain data transfer in stream read mode.
#define MMC_R1_ERROR (1u<<19) // E X B, (Undefined by the standard) A generic card error related to the (and detected during) execution of the last host command (e.g. read or write failures).
#define MMC_R1_CC_ERROR (1u<<20) // E R B, (Undefined by the standard) A card error occurred, which is not related to the host command.
#define MMC_R1_CARD_ECC_FAILED (1u<<21) // E X B, Card internal ECC was applied but failed to correct the data.
#define MMC_R1_ILLEGAL_COMMAND (1u<<22) // E R B, Command not legal for the card state.
#define MMC_R1_COM_CRC_ERROR (1u<<23) // E R B, The CRC check of the previous command failed.
#define MMC_R1_LOCK_UNLOCK_FAILED (1u<<24) // E X B, Set when a sequence or password error has been detected in lock/unlock card command.
#define MMC_R1_CARD_IS_LOCKED (1u<<25) // S R A, When set, signals that the card is locked by the host.
#define MMC_R1_WP_VIOLATION (1u<<26) // E X B, Attempt to program a write protected block.
#define MMC_R1_ERASE_PARAM (1u<<27) // E X B, An invalid selection of erase groups for erase occurred.
#define MMC_R1_ERASE_SEQ_ERROR (1u<<28) // E R B, An error in the sequence of erase commands occurred.
#define MMC_R1_BLOCK_LEN_ERROR (1u<<29) // E R B, Either the argument of a SET_BLOCKLEN command exceeds the maximum value allowed for the card, or the previously defined block length is illegal for the current command (e.g. the host issues a write command, the current block length is smaller than the cards maximum and write partial blocks is not allowed).
#define MMC_R1_ADDRESS_MISALIGN (1u<<30) // E R/X B, The command s address argument (in accordance with the currently set block length) positions the first data block misaligned to the card physical blocks. A multiple block read/write operation (although started with a valid address/blocklength combination) is attempting to read or write a data block which does not align with the physical blocks of the card.
#define MMC_R1_ADDRESS_OUT_OF_RANGE (1u<<31) // E R/X B, The commands address argument was out of the allowed range for this card. A multiple block or stream read/write operation is (although started in a valid address) attempting to read or write beyond the card capacity.
#define MMC_R1_ERR_ALL (MMC_R1_ADDRESS_OUT_OF_RANGE | MMC_R1_ADDRESS_MISALIGN | \
MMC_R1_BLOCK_LEN_ERROR | MMC_R1_ERASE_SEQ_ERROR | \
MMC_R1_ERASE_PARAM | MMC_R1_WP_VIOLATION | MMC_R1_LOCK_UNLOCK_FAILED | \
MMC_R1_COM_CRC_ERROR | MMC_R1_ILLEGAL_COMMAND | MMC_R1_CARD_ECC_FAILED | \
MMC_R1_CC_ERROR | MMC_R1_ERROR | MMC_R1_UNDERRUN | MMC_R1_OVERRUN | \
MMC_R1_CXD_OVERWRITE | MMC_R1_WP_ERASE_SKIP | MMC_R1_ERASE_RESET | \
MMC_R1_SWITCH_ERROR)
// 8.1 OCR register.
// Same bits for CMD1 argument.
#define MMC_OCR_1_7_1_95V (1u<<7) // 1.701.95V.
#define MMC_OCR_2_0_2_1V (1u<<8) // 2.0-2.1V.
#define MMC_OCR_2_1_2_2V (1u<<9) // 2.1-2.2V.
#define MMC_OCR_2_2_2_3V (1u<<10) // 2.2-2.3V.
#define MMC_OCR_2_3_2_4V (1u<<11) // 2.3-2.4V.
#define MMC_OCR_2_4_2_5V (1u<<12) // 2.4-2.5V.
#define MMC_OCR_2_5_2_6V (1u<<13) // 2.5-2.6V.
#define MMC_OCR_2_6_2_7V (1u<<14) // 2.6-2.7V.
#define MMC_OCR_2_7_2_8V (1u<<15) // 2.7-2.8V.
#define MMC_OCR_2_8_2_9V (1u<<16) // 2.8-2.9V.
#define MMC_OCR_2_9_3_0V (1u<<17) // 2.9-3.0V.
#define MMC_OCR_3_0_3_1V (1u<<18) // 3.0-3.1V.
#define MMC_OCR_3_1_3_2V (1u<<19) // 3.1-3.2V.
#define MMC_OCR_3_2_3_3V (1u<<20) // 3.2-3.3V.
#define MMC_OCR_3_3_3_4V (1u<<21) // 3.3-3.4V.
#define MMC_OCR_3_4_3_5V (1u<<22) // 3.4-3.5V.
#define MMC_OCR_3_5_3_6V (1u<<23) // 3.5-3.6V.
#define MMC_OCR_BYTE_MODE (0u<<29) // Access mode = byte mode.
#define MMC_OCR_SECT_MODE (2u<<29) // Access mode = sector mode.
#define MMC_OCR_READY (1u<<31) // Card power up status bit (busy). 0 = busy.
// 7.6.1 Command sets and extended settings.
#define MMC_SWITCH_ACC_CMD_SET (0u)
#define MMC_SWITCH_ACC_SET_BITS (1u)
#define MMC_SWITCH_ACC_CLR_BITS (2u)
#define MMC_SWITCH_ACC_WR_BYTE (3u)
#define MMC_SWITCH_ARG(acc, idx, val, cmdSet) (((acc)&3u)<<24 | ((idx)&0xFFu)<<16 | ((val)&0xFFu)<<8 | ((cmdSet)&7u))
// 8.4 Extended CSD register.
// size in bytes, access, description.
#define EXT_CSD_SEC_BAD_BLK_MGMNT (134u) // 1, R/W, Bad Block Management mode.
#define EXT_CSD_ENH_START_ADDR (136u) // 4, R/W, Enhanced User Data Start Address.
#define EXT_CSD_ENH_SIZE_MULT (140u) // 3, R/W, Enhanced User Data Area Size.
#define EXT_CSD_GP_SIZE_MULT (143u) // 12, R/W, General Purpose Partition Size.
#define EXT_CSD_PARTITION_SETTING_COMPLETED (155u) // 1, R/W, Paritioning Setting.
#define EXT_CSD_PARTITIONS_ATTRIBUTE (156u) // 1, R/W, Partitions attribute.
#define EXT_CSD_MAX_ENH_SIZE_MULT (157u) // 3, R, Max Enhanced Area Size.
#define EXT_CSD_PARTITIONING_SUPPORT (160u) // 1, R, Partitioning Support.
#define EXT_CSD_HPI_MGMT (161u) // 1, R/W/E_P, HPI management.
#define EXT_CSD_RST_n_FUNCTION (162u) // 1, R/W, H/W reset function.
#define EXT_CSD_BKOPS_EN (163u) // 1, R/W, Enable background operations handshake.
#define EXT_CSD_BKOPS_START (164u) // 1, W/E_P, Manually start background operations.
#define EXT_CSD_WR_REL_PARAM (166u) // 1, R, Write reliability parameter register.
#define EXT_CSD_WR_REL_SET (167u) // 1, R/W, Write reliability setting register.
#define EXT_CSD_RPMB_SIZE_MULT (168u) // 1, R, RPMB Size.
#define EXT_CSD_FW_CONFIG (169u) // 1, R/W, FW configuration.
#define EXT_CSD_USER_WP (171u) // 1, R/W, R/W/C_P & R/W/E_P, User area write protection register.
#define EXT_CSD_BOOT_WP (173u) // 1, R/W & R/W/C_P, Boot area write protection register.
#define EXT_CSD_ERASE_GROUP_DEF (175u) // 1, R/W/E_P, High-density erase group definition.
#define EXT_CSD_BOOT_BUS_WIDTH (177u) // 1, R/W/E, Boot bus width1.
#define EXT_CSD_BOOT_CONFIG_PROT (178u) // 1, R/W & R/W/C_P, Boot config protection.
#define EXT_CSD_PARTITION_CONFIG (179u) // 1, R/W/E & R/W/E_P, Partition configuration.
#define EXT_CSD_ERASED_MEM_CONT (181u) // 1, R, Erased memory content.
#define EXT_CSD_BUS_WIDTH (183u) // 1, W/E_P, Bus width mode.
#define EXT_CSD_HS_TIMING (185u) // 1, R/W/E_P, High-speed interface timing.
#define EXT_CSD_POWER_CLASS (187u) // 1, R/W/E_P, Power class.
#define EXT_CSD_CMD_SET_REV (189u) // 1, R, Command set revision.
#define EXT_CSD_CMD_SET (191u) // 1, R/W/E_P, Command set.
#define EXT_CSD_EXT_CSD_REV (192u) // 1, R, Extended CSD revision.
#define EXT_CSD_CSD_STRUCTURE (194u) // 1, R, CSD structure version.
#define EXT_CSD_CARD_TYPE (196u) // 1, R, Card type.
#define EXT_CSD_OUT_OF_INTERRUPT_TIME (198u) // 1, R, Out-of-interrupt busy timing.
#define EXT_CSD_PARTITION_SWITCH_TIME (199u) // 1, R, Partition switching timing.
#define EXT_CSD_PWR_CL_52_195 (200u) // 1, R, Power class for 52MHz at 1.95V.
#define EXT_CSD_PWR_CL_26_195 (201u) // 1, R, Power class for 26MHz at 1.95V.
#define EXT_CSD_PWR_CL_52_360 (202u) // 1, R, Power class for 52MHz at 3.6V.
#define EXT_CSD_PWR_CL_26_360 (203u) // 1, R, Power class for 26MHz at 3.6V.
#define EXT_CSD_MIN_PERF_R_4_26 (205u) // 1, R, Minimum Read Performance for 4bit at 26MHz.
#define EXT_CSD_MIN_PERF_W_4_26 (206u) // 1, R, Minimum Write Performance for 4bit at 26MHz.
#define EXT_CSD_MIN_PERF_R_8_26_4_52 (207u) // 1, R, Minimum Read Performance for 8bit at 26MHz, for 4bit at 52MHz.
#define EXT_CSD_MIN_PERF_W_8_26_4_52 (208u) // 1, R, Minimum Write Performance for 8bit at 26MHz, for 4bit at 52MHz.
#define EXT_CSD_MIN_PERF_R_8_52 (209u) // 1, R, Minimum Read Performance for 8bit at 52MHz.
#define EXT_CSD_MIN_PERF_W_8_52 (210u) // 1, R, Minimum Write Performance for 8bit at 52MHz.
#define EXT_CSD_SEC_COUNT (212u) // 4, R, Sector Count.
#define EXT_CSD_S_A_TIMEOUT (217u) // 1, R, Sleep/awake timeout.
#define EXT_CSD_S_C_VCCQ (219u) // 1, R, Sleep current (VCCQ).
#define EXT_CSD_S_C_VCC (220u) // 1, R, Sleep current (VCC).
#define EXT_CSD_HC_WP_GRP_SIZE (221u) // 1, R, High-capacity write protect group size.
#define EXT_CSD_REL_WR_SEC_C (222u) // 1, R, Reliable write sector count.
#define EXT_CSD_ERASE_TIMEOUT_MULT (223u) // 1, R, High-capacity erase timeout.
#define EXT_CSD_HC_ERASE_GRP_SIZE (224u) // 1, R, High-capacity erase unit size.
#define EXT_CSD_ACC_SIZE (225u) // 1, R, Access size.
#define EXT_CSD_BOOT_SIZE_MULTI (226u) // 1, R, Boot partition size.
#define EXT_CSD_BOOT_INFO (228u) // 1, R, Boot information.
#define EXT_CSD_SEC_TRIM_MULT (229u) // 1, R, Secure TRIM Multiplier.
#define EXT_CSD_SEC_ERASE_MULT (230u) // 1, R, Secure Erase Multiplier.
#define EXT_CSD_SEC_FEATURE_SUPPORT (231u) // 1, R, Secure Feature support.
#define EXT_CSD_TRIM_MULT (232u) // 1, R, TRIM Multiplier.
#define EXT_CSD_MIN_PERF_DDR_R_8_52 (234u) // 1, R, Minimum Read Performance for 8bit at 52MHz in DDR mode.
#define EXT_CSD_MIN_PERF_DDR_W_8_52 (235u) // 1, R, Minimum Write Performance for 8bit at 52MHz in DDR mode.
#define EXT_CSD_PWR_CL_DDR_52_195 (238u) // 1, R, Power class for 52MHz, DDR at 1.95V.
#define EXT_CSD_PWR_CL_DDR_52_360 (239u) // 1, R, Power class for 52MHz, DDR at 3.6V.
#define EXT_CSD_INI_TIMEOUT_AP (241u) // 1, R, 1st initialization time after partitioning.
#define EXT_CSD_CORRECTLY_PRG_SECTORS_NUM (242u) // 4, R, Number of correctly programmed sectors.
#define EXT_CSD_BKOPS_STATUS (246u) // 1, R, Background operations status.
#define EXT_CSD_BKOPS_SUPPORT (502u) // 1, R, Background operations support.
#define EXT_CSD_HPI_FEATURES (503u) // 1, R, HPI features.
#define EXT_CSD_S_CMD_SET (504u) // 1, R, Supported Command Sets.