Notes based on reading linux/drivers/mmc/host/sdhci.c and associated files:
HC = Host Controller
0 Resets not honoured until we provide a clock SDHCI_QUIRK_CLOCK_BEFORE_RESET
1 Really supports DMA but caps bits lie SDHCI_QUIRK_FORCE_DMA
2 Doesn't like being reset when there's no card SDHCI_QUIRK_NO_CARD_NO_RESET
3 Doesn't like clearing the power register before being changed SDHCI_QUIRK_SINGLE_POWER_WRITE
4 Needs command data reset on each ios change due to flaky internal state SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS
5 Broken DMA engine SDHCI_QUIRK_BROKEN_DMA
6 Broken ADMA engine SDHCI_QUIRK_BROKEN_ADMA
7 Needs DMA addresses to be 32 bit aligned SDHCI_QUIRK_32BIT_DMA_ADDR
8 Needs DMA chunks to be a multiple of 32 bits SDHCI_QUIRK_32BIT_DMA_SIZE
9 Needs ADMA chunks to be a multiple of 32 bits SDHCI_QUIRK_32BIT_ADMA_SIZE
10 Have to reset after every request to stay stable SDHCI_QUIRK_RESET_AFTER_REQUEST
11 Can't cope with simulataneous voltage and power writes SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER
12 Provides broken timeout value for transfers SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
13 Has problem with buffer bits in PIO transfers < 4 bytes (eg JMicron JMB38x) SDHCI_QUIRK_BROKEN_SMALL_PIO
14 Doesn't provide a transfer-complete IRQ if not busy SDHCI_QUIRK_NO_BUSY_IRQ
15 Can't reliably detect cards SDHCI_QUIRK_BROKEN_CARD_DETECTION
16 Write protect state inverted SDHCI_QUIRK_INVERTED_WRITE_PROTECT
17 Clock management non-standard SDHCI_QUIRK_NONSTANDARD_CLOCK
18 Needs delay for PIO transfers (doesn't like them fast) SDHCI_QUIRK_PIO_NEEDS_DELAY
19 Loses signal/IRQ enable states over reset - have to restore afterwards SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET
20 Needs forcing of block size to be 2048 bytes SDHCI_QUIRK_FORCE_BLK_SZ_2048
21 Can't do multi-block transfers SDHCI_QUIRK_NO_MULTIBLOCK
22 Can only do 1 bit data transfers SDHCI_QUIRK_FORCE_1_BIT_DATA
23 Needs 10ms delay between power and clock SDHCI_QUIRK_DELAY_AFTER_POWER
24 SDCLK used instead of TMCLK for data timeouts SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
25 Capability reports wrong base clock SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN
26 Can't support End Attribute in NOP ADMA descriptor SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
27 No device capabilities register. Need to be faked up by host SDHCI_QUIRK_MISSING_CAPS
28 Multiblock transfers stopped with ACMD12 SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12
29 No HISPD bit field for HI-SPEED SD cards SDHCI_QUIRK_NO_HISPD_BIT
30 ADMA descriptors with length 0 are treated incorrectly SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC
31 Read-only detection using the SDHCI_PRESENT_STATE register is not reliable SDHCI_QUIRK_UNSTABLE_RO_DETECT
Platform drivers (ie specific ARM boards with SDHCI ports) only set SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, SDHCI_QUIRK_FORCE_1_BIT_DATA, SDHCI_QUIRK_INVERTED_WRITE_PROTECT. Some SoCs have extra drivers for their own weirdnesses (Tegra does, OMAP doesn’t AFAICS) which may set more quirk bits.
0 Driver does its own card detection SDHCI_QUIRK2_OWN_CARD_DETECTION
0 SDIO FN0 outside the VS CCCR range are permitted MMC_QUIRK_LENIENT_FN0
1 Use current block size for byte mode MMC_QUIRK_BLKSZ_FOR_BYTE_MODE
2 SDIO attached is missing CIA registers MMC_QUIRK_NONSTD_SDIO
3 Card will fail if SDIO bus clock gated MMC_QUIRK_BROKEN_CLK_GATING
4 Non-standard function interfaces on SDIO card MMC_QUIRK_NONSTD_FUNC_IF
5 Resistor for CD/DAT[3] should be disconnected MMC_QUIRK_DISABLE_CD
6 CMD38 broken for iNAND devices MMC_QUIRK_INAND_CMD38
7 Don't use CMD23 for regular multiblock MMC_QUIRK_BLK_NO_CMD23
8 Don't send 512 bytes in byte mode MMC_QUIRK_BROKEN_BYTE_MODE_512
0x0,SDHCI_DMA_ADDRESS/SDHCI_ARGUMENT2
0x4,SDHCI_BLOCK_SIZE
0x06,SDHCI_BLOCK_COUNT
0x08,SDHCI_ARGUMENT
0x0C,SDHCI_TRANSFER_MODE
0x0E,SDHCI_COMMAND
0x10,SDHCI_RESPONSE
0x20,SDHCI_BUFFER
0x24,SDHCI_PRESENT_STATE
0x28,SDHCI_HOST_CONTROL
0x29,SDHCI_POWER_CONTROL
0x2A,SDHCI_BLOCK_GAP_CONTROL
0x2B,SDHCI_WAKE_UP_CONTROL
0x2C,SDHCI_CLOCK_CONTROL
0x2E,SDHCI_TIMEOUT_CONTROL
0x2F,SDHCI_SOFTWARE_RESET
0x30,SDHCI_INT_STATUS
0x34,SDHCI_INT_ENABLE
0x38,SDHCI_SIGNAL_ENABLE
0x3C,SDHCI_ACMD12_ERR
0x3E,SDHCI_HOST_CONTROL2
0x40,SDHCI_CAPABILITIES
0x44,SDHCI_CAPABILITIES_1
0x48,SDHCI_MAX_CURRENT (4C-4F reserved for further max current)
0x50,SDHCI_SET_ACMD12_ERROR
0x52,SDHCI_SET_INT_ERROR
0x54,SDHCI_ADMA_ERROR
0x55-0x57,reserved
0x58,SDHCI_ADMA_ADDRESS
0x60-0xFB,reserved
0xFC,SDHCI_SLOT_INT_STATUS
0xFE,SDHCI_HOST_VERSION
To reset the controller:
To clear and set IRQs:
Read a block into a scatter/gather list. Perform read32s of SDHCI_BUFFER, but watch that the scatter/gather blocks may not be multiples of 4 bytes.
Save the local Linux interrupt state before and restore after the PIO loop
The same as above, but for writes. Uses write32 to SDHCI_BUFFER
Controller quirks flags:
If Host Controller 2.00 or later, will use ADMA if device can use it (capability bit SDHCI_CAN_DO_AMA2) and not disabled by quirk.
If no SDMA or ADMA, will fallback to PIO
If can do ADMA, allocate descriptors for scatter/gather entries – if can’t allocate fallback to SDMA.
Max clock freq (in MHz) is bits 15-8 in capability register in version >= 3.00, bits 13-8 before. (Check ‘CLOCK_BASE_BROKEN’ capability flag). Call host→ops→get_max_clock(host)
If HC >= 3.00, read out clock multiplier from caps 1. If not supported or zero, clock multipler = 1
Calculate f_min and f_max:
f_max = max_clk
If spec 3.00 and clock multipler non-zero:
f_min = max_clk * clk_mul / 1024
f_max = max_clk * clk_mul
If spec 3.00 and clk_mul=0
f_min = max_clk / max clock divider from spec 3.00
If spec < 3.00
f_min = max_clk / max clock divider from spec 2.00
Read timeout clock from cap0. If zero, get from host→ops→get_timeout_clock if available. If caps0 SDHCI_TIMEOUT_CLK_UNIT bit set, time in ms else in seconds.
If spec 3.00 and can do ADMA or SDMA, then support command ACMD23, otherwise don’t.
Bus width:
Platform code (not sdhci.c) sets MMC_CAP_8_BIT_DATA if available on our board: controller may support it but have pins wired
If SDHCI_QUIRK_FORCE_1_BIT_DATA then we can use MMC_CAP_4_BIT_DATA
Speeds:
If spec >= 3.00 can use UHS-I mode (UHS_SDR12 and UHS_SDR25)
caps1 says can support SDR104+SDR50 mode, or SDR50 mode
caps1 says can support DDR50 mode
caps1 says if need tuning for SDR50
caps1 says if supports driver type A, type C, type D
Set power off notify timeout values (short or none)
Initialise re-tuning timer count from caps1 (2^(caps_bits-1))
Tuning mode from caps1
Read 32 bit SDHCI_MAX_CURRENT register
If can do VDD=3.3V (caps0), pick out max_current_330 from MAX_CURRENT register (in mA). If >150mA set XPC bit for 3.3V.
Same again for VDD=3.0V, 1.8V. Max current at 1.8V can be in steps of 800mA, 600mA, 400mA, 200mA.
ocr_avail section (something to do with available voltage ranges)