SD/MMC/SDIO Registers

From DSiBrew
Jump to navigation Jump to search

SD_xxx is used to access onboard eMMC and external SD card slot (as selected via SD_CARD_PORT_SELECT).
SDIO_xxx is used to access the Atheros Wifi unit.

DSi SD/MMC I/O Map

 ARM7 DSi SD/MMC Registers for Memory Card access (SD Card and onboard eMMC)
 4004800h 2    SD_CMD              Command and Response/Data Type
 4004802h 2    SD_CARD_PORT_SELECT   (SD/MMC:020Fh, SDIO:010Fh)
 4004804h 4    SD_CMD_PARAM0-1     Argument (32bit, 2 halfwords)
 4004808h 2    SD_STOP_INTERNAL_ACTION
 400480Ah 2    SD_DATA16_BLK_COUNT        "Transfer Block Count"
 400480Ch 16   SD_RESPONSE0-7 (128bit, 8 halfwords)
 400481Ch 4    SD_IRQ_STATUS0-1  ;IRQ Status  (0=ack, 1=req)
 4004820h 4    SD_IRQ_MASK0-1    ;IRQ Disable (0=enable, 1=disable)
 4004824h 2    SD_CARD_CLK_CTL Card Clock Control
 4004826h 2    SD_DATA16_BLK_LEN  Memory Card Transfer Data Length
 4004828h 2    SD_CARD_OPTION Memory Card Option Setup (can be C0FFh)
 400482Ah 2    Fixed always zero?
 400482Ch 4    SD_ERROR_DETAIL_STATUS0-1   Error Detail Status
 4004830h 2    SD_DATA16_FIFO        Data Port  (SD_FIFO?)
 4004832h 2    Fixed always zero?   ;(TC6371AF:BUF1 Data MSBs?)
 4004834h 2    ? SD_TRANSACTION_CTL  Transaction Control
 4004836h 2    ? SD_CARD_INTERRUPT_CONTROL ;4004A36h used in SDIO IRQ handler
 4004838h 2    ? SD_CLK_AND_WAIT_CTL       ;4004A38h used in SDIO IRQ handler
 400483Ah 2    Fixed always zero?   ;(SDCTL_SDIO_HOST_INFORMATION)
 400483Ch 2    Fixed always zero?   ;(SDCTL_ERROR_CONTROL)
 400483Eh 2    Fixed always zero?   ;(TC6387XB: LED_CONTROL)
 4004840h 2    Fixed always 003Fh?
 4004842h 2    Fixed always 002Ah?
 4004844h 6Eh  Fixed always zerofilled?
 40048B2h 2    Fixed always FFFFh?
 40048B4h 6    Fixed always zerofilled?
 40048BAh 2    Fixed always 0200h?
 40048BCh 1Ch  Fixed always zerofilled?
 40048D8h 2    SD_DATA_CTL
 40048DAh 6    Fixed always zerofilled?
 40048E0h 2    SD_SOFT_RESET  Software Reset (bit0=SRST=0=reset)
 40048E2h 2    Fixed always 0009h?  ;(RESERVED2/9, TC6371AF:CORE_REV)
 40048E4h 2    Fixed always zero?
 40048E6h 2    Fixed always zero?   ;(RESERVED3, TC6371AF:BUF_ADR)
 40048E8h 2    Fixed always zero?   ;(TC6371AF:Resp_Header)
 40048EAh 6    Fixed always zerofilled?
 40048F0h 2    Fixed always zero?   ;(RESERVED10)
 40048F2h 2    ? Can be 0003h
 40048F4h 2    ? Can be 0770h
 40048F6h 2    ? Firmware tests bit0 (but, always 0?)       (RESERVED4)
 40048F8h 2    Fixed always 0004h?   (nonzero, unlike SDIO) (RESERVED5)
 40048FAh 2    ? Can be 0004h..0007h (nonzero, unlike SDIO) (RESERVED6)
 40048FCh 2    ? Can be 0024h..00FFh?                       (RESERVED7)
 40048FEh 2    ? Can be 0024h..00FFh?   (RESERVED8 / TC6371AF:Revision)
 4004900h 2    SD_DATA32_IRQ
 4004902h 2    Fixed always zero?
 4004904h 2    SD_DATA32_BLK_LEN
 4004906h 2    Fixed always zero?
 4004908h 2    SD_DATA32_BLK_COUNT
 400490Ah 2    Fixed always zero?
 400490Ch 4    SD_DATA32_FIFO
 4004910h F0h  Fixed always zerofilled?
 ARM7 DSi SD/MMC Registers for SDIO access (for Atheros Wifi)
 4004A00h 200h SDIO_xxx (same as SD_xxx at 4004800h..40049FFh, see there)
 4004A02h 2    SDIO_CARD_PORT_SELECT (slightly different than 4004802h)
 4004AF8h 2    Fixed always zero? (unlike SD_xxx at 40048F8h) (RESERVED5)
 4004AFAh 2    Fixed always zero? (unlike SD_xxx at 40048FAh) (RESERVED6)

DSi SD/MMC I/O Ports: Command/Param/Response/Data

4004800h/4004A00h - SD_CMD - Command and Response/Data Type (R/W)

 15    undoc   Unknown/undoc  (read/write-able)
 14    undoc   Security Cmd   (0=Normal, 1=Whatever/Security) (sdio?)
 13    undoc   Data Length    (0=Single Block, 1=Multiple Blocks)
 12    undoc   Data Direction (0=Write, 1=Read)
 11    NTDT    Data Transfer  (0=No data, 1=With data)
 10-8  REP2-0  Response Type  (0..2=Unknown/Reserved, 3=None, 4=48bit,
                               5=48bit+Busy, 6=136bit, 7=48bitOcrWithoutCRC7)
 7-6   CMD1-0  Command Type   (0=CMD, 1=ACMD, 2..3=unknown, maybe GEN WR/RD?)
 5-0   CIX     Command Index  (0..3Fh, command index)

Invalid values can cause ILA error (particulary on setting NTDT for CMD12, or for CMD's Response=None). ILA error will also occur if an old CMD is still busy.
DSi software is always writing just ZERO to bit11-6 though? Maybe the hardware does automatically know which SD/MMC CMDs and ACMDs have data? Or maybe data is always automatically transferred when receiving a data-startbit, or when writing to data register - and bits like NTDT would be needed only for things like proper data timeout handling?

4004804h/4004A04h - SD_CMD_PARAM0-1 - Argument (32bit, 2 halfwords) (R/W)

 31-0  Parameter value for CMD

The parameter value should be written <before> sending the command via SD_CMD/SDIO_CMD.

400480Ch/4004A0Ch - SD_RESPONSE0-7 - Response (128bit, 8 halfwords) (R)

After sending a command, wait for the CMDRESPEND bit (IRQ_STATUS.bit0) to get set, then read the RESPONSE (if the command does have any response).

For normal 32bit responses:
 31-0      Response
 127-32    Older Responses
For CID/CSD responses:
 119-0     120bit Response
 127-120   Zero (always?)

Seems to be left-shifted when receiving response bits. So, for 32bit responses, bit0-31 would contain the current response, and bit32-127 would contain older responses.

DATA16 vs DATA32

Data can be transferred in 16bit or 32bit units (as selected in DATA_CTL.bit1 and DATA32_IRQ.bit1). There are separate data, block len, and block count registers for 16bit and 32bit mode (that's probably due to some odd patchwork, where the manufacturer has added 32bit support to the original 16bit chip design).
Naturally, a 32bit transfer is faster than two 16bit transfers. Nethertheless, the DSi firmware does use both 32bit and 16bit mode once and then; 32bit mode is required for NDMA transfers (which don't support 16bit).

40048D8h/4004AD8h - SD_DATA_CTL

 15-13  Unknown (usually 0)
 12     Unknown (usually 1)                                             (R?)
 11-6   Unknown (usually 0)
 5      Unknown (read/write-able) (usually 0)                           (R/W)
 4      Unknown (usually 1)                                             (R?)
 3-2    Unknown (usually 0)
 1      Select 16bit/32bit Data Mode (0=DATA16, 1=DATA32, see 4004900h) (R/W)
 0      Unknown (usually 0)

Known written values are 0000h and 0002h. However, known read values are 1010h and 1012h.
DATA32 mode requires setting both 40048D8h.bit1 and 4004900h.bit1. For DATA16 mode, both bits should be zero (though DATA16 seems to be also working the same way when only either of the bits is zero).

===400480Ah/4004A0Ah - SD_DATA16_BLK_COUNT - "Transfer Block Count" (R/W)
4004908h/4004B08h - SD_DATA32_BLK_COUNT (R/W)===

 15-0   Number of Data Blocks for multiple read/write commands (0..FFFFh)

In Data32 mode, DATA32_BLK_COUNT is decremented after each block (except after the last block, where it stays at 0001h instead of getting zero). In Data16 mode, SD_DATA16_BLK_COUNT doesn't decrease (instead, there must be some hidden internal counter register).
If enabled in STOP_INTERNAL_ACTION.bit8, then the hardware will be automatically sending STOP_TRANSMISSION (CMD12) after the last block (otherwise the decrement occurs as described above, but the hardware keeps transferring blocks infinitely).

4004826h/4004A26h - SD_DATA16_BLK_LEN - Transfer Data Length (R/W)

4004904h/4004B04h - SD_DATA32_BLK_LEN (R/W)

 15-10  Unknown/unused (appears to be always zero)
 9-0    Data Block Length in bytes (for DATA16: clipped to max 0200h by hw)

Should be usually 0200h (for 512-byte SD/MMC memory blocks). Other values may be needed for SDIO functions, or when accessing SSR/SCR/PWD registers via data transfers.
DATA32_BLK_LEN can be max 3FFh (unlike DATA16_BLK_LEN which is clipped to max=200h by hardware).

4004830h/4004A30h - SD_DATA16_FIFO - Data Port (SD_FIFO?)

400490Ch/4004B0Ch - SD_DATA32_FIFO

For Data16:
 15-0   Data (16bit) (...or could it be accessed as 32bit, too?)
For Data32:
 31-0   Data (32bit) (...or could it be accessed as 16bit, too?)

Transfer data here (read after RXRDY gets set, or write after TXRQ gets set). FIFO size is unknown (if there's any FIFO behind it).

DSi SD/MMC I/O Ports: Interrupt/Status

400481Ch - SD_IRQ_STATUS0-1 - Interrupt Status (R/ack)
4004A1Ch - SDIO_IRQ_STATUS0-1 - Interrupt Status (R/ack)
4004820h - SD_IRQ_MASK0-1 - Interrupt Mask (R/W)
4004A20h - SDIO_IRQ_MASK0-1 - Interrupt Mask (R/W)
The IRQ_STATUS registers contain acknowledge-able IRQ Flags (those bits that that are maskable in IRQ_MASK register), as well as static read-only status bits without IRQ function (eg. WRPROTECT).

  • IRQ Flags/Write (0=Acknowledge, 1=No change)
  • IRQ Flags/Read (0=No IRQ, 1=IRQ)
  • IRQ Mask (0=Enable, 1=Disable) (8B7F031Dh when all IRQs disabled)
 Bit Stat  Mask   Function
 0   SREP  MREP   CMDRESPEND    (response end) (or R1b: busy end)
 1   0     0      Unknown/unused (always 0)
 2   SRWA  MRWA   DATAEND       (is NOT set? after data read/write end bit)
 3   SCOT  MCOT   CARD_REMOVE (0=No event, 1=Is/was newly ejected)      ;\DSi
 4   SCIN  MCIN   CARD_INSERT (0=No event, 1=Is/was newly inserted)     ; SD
 5   undoc 0      SIGSTATE    (0=Ejected, 1=Inserted) (SDIO: always 1)  ; Card
 6   0     0      Unknown/unused (always 0)                             ; Slot
 7   undoc 0      WRPROTECT   (0=Locked/Ejected, 1=Unlocked/HalfEjected);/
 8   undoc undoc  CARD_REMOVE_A (always 0)   ;\maybe fixed state for
 9   undoc undoc  CARD_INSERT_A (always 0)   ; DSi's onboard eMMC chip
 10  undoc 0      SIGSTATE_A    (always 1)   ;/(also fixed as so for SDIO)
 11  0     0      Unknown/unused (always 0)
 12  0     0      Unknown/unused (always 0)
 13  0     0      Unknown/unused (always 0)
 14  0     0      Unknown/unused (always 0)
 15  0     0      Unknown/unused (always 0)
 16  SCIX  MCIX   CMD_IDX_ERR   Bad CMD-index in response      (RCMDE,SCMDE)
 17  SCRC  MCRC   CRCFAIL       CRC response error (WCRCE,RCRCE,SCRCE,CCRCE)
 18  SEND  MEND   STOPBIT_ERR   End bit error      (WEBER,REBER,SEBER,CEBER)
 19  SDTO  MDTO   DATATIMEOUT   Data Timeout                (NRCS,NWCS,KBSY)
 20  SFOF  MFOF   RXOVERFLOW    HOST tried write full
 21  SFUF  MFUF   TXUNDERRUN    HOST tried read empty
 22  SCTO  MCTO   CMDTIMEOUT    Response start-bit timeout         (NRS,NSR)
 23  1 ?   0      Unknown/undoc (usually set?)
 24  SBRE  MBRE   RXRDY         (fifo not empty) (request data read)
 25  SBWE  MBWE   TXRQ          (datafifoempty?) (request data write)
 26  0     0      Unknown/unused (always 0)
 27  undoc undoc  Unknown/undoc  (bit27 is mask-able in IRQ_MASK)
 28  0     0      Unknown/unused (always 0)
 29  1 ?   0      Unknown/undoc  (usually set?) (unlike toshiba ILFSL/IFSMSK)
 30  undoc 0      CMD_BUSY
 31  ILA   IMSK   Illegal Command Access (old CMD still busy, or wrong NTDT)

Acknowledge by STAT=0, or by MASK=1 (uh, really?), or by soft reset (SRST=0) or hard reset.


4004900h - SD_DATA32_IRQ
4004B00h - SDIO_DATA32_IRQ

 15-13  Unknown/unused (appears to be always zero)
 12     Unknown (paired with bit9) (can be set)   IRQ enable ?!      (R/W?)
 11     Unknown (paired with bit8) (can be set)   IRQ enable ?!      (R/W?)
 10     Unknown (read=0) write: (0=No change, 1=Clear Bit8,9) ?      (W?)
 9      Unknown (paired with bit12) (automatically cleared after...) (R?)
 8      Unknown (paired with bit11)                                  (R?)
 7-2    Unknown (0)
 1      Unknown (can be set)  (autoclear bit8,9 on xfer end?)        (R/W?)
 0      Unknown (0)

Can be 1A02h, but changes to 1802h after reading from somewhere (maybe from DATA32_FIFO?).
Bit8,9 seem to be whatever extra IRQ flags, the flags get set ONLY in DATA32 mode (not in DATA16 mode).


400482Ch - SD_ERROR_DETAIL_STATUS0-1 - Error Detail Status
4004A2Ch - SDIO_ERROR_DETAIL_STATUS0-1 - Error Detail Status

 31-23 ?      Unknown/unused/undoc
 22    KBSY   Timeout for CRC status busy timeout                  ;\STAT.19
 21    NWCS   Timeout for CRC status timeout                       ; (SDTO)
 20    NRCS   Timeout for Data start-bit, or for Post Data Busy    ;/
 19-18 ?      Unknown/unused/undoc
 17    NRS    Response timeout for auto-issued CMD12               ;\STAT.22
 16    NCR    Response timeout for non-auto-issued CMD's           ;/(SCTO)
 15-14 ?      Unknown/unused/undoc
 13    ??     Unknown/undoc (bit13 can be nonzero on DSi!)
 12    ?      Unknown/unused/undoc
 11    WCRCE  CRC error for Write CRC status for a write command   ;\
 10    RCRCE  CRC error for read data                              ; STAT.17
 9     SCRCE  CRC error for a response for auto-issued CMD12       ; (SCRC)
 8     CCRCE  CRC error for a response for non-auto-issued CMD's   ;/
 5     WEBER  End bit error for Write CRC status                   ;\
 4     REBER  End bit error for read data                          ; STAT.18
 3     SEBER  End bit error for response for auto-issued CMD12     ; (SEND)
 2     CEBER  End bit error for response for non-auto-issued CMD's ;/
 1?    SCMDE  Bad CMD-index in response of auto-issued CMD12       ;\STAT.16
 0     RCMDE  Bad CMD-index in response of non-auto-issued CMD's   ;/(SCIX)

Unknown if/when/how the error bits can be reset/acknowledged.
Note: CMD12 is STOP_TRANSMISSION (maybe sent after BLK_COUNT?).
The four "auto-issued CMD12" bits exist for SD registers only (not SDIO). SCMDE is probably in bit1 (though, official specs say bit0, which would be same as RCMDE).


4004A36h - DSi: 0000 - SDCTL_CARD_INTERRUPT_CONTROL
This does NOT seem to be implemented as described below on DSi. 4004A36h does seem to behave more like 4004836h, see there.

 15-13  ?      Unknown (zero on DSi)
 12     CINT0  SDIO Interrupt Flag (0=none, 1=irq)       (/IRQ aka Data1 pin)
 11-9   ?      Unknown (zero on DSi)
 8      CIMSK0 SDIO Interrupt Mask (0=enable, 1=disable) (/IRQ aka Data1 pin)
 7-0    ?      Unknown (zero on DSi)

Acknowledge by writing CINT0=0, or CIMSK0=1, or hard reset (unlike as for other SD/MMC interrupts, soft reset does not acknowlege this interrupt type?).

DSi SD/MMC I/O Ports: Control

4004802h - SD_CARD_PORT_SELECT (0201h)
4004A02h - SDIO_CARD_PORT_SELECT (0100h)

 15-11 Unknown/unused (appears to be always zero)
 10    Unknown (write: should be 1, read: usually/always 0)   (W?)
 9     Unknown (write: should be 0, read: usually 1 for SD)
 8     Unknown (write: should be 0, read: usually 1 for SDIO)
 7-4   Unknown/unused (appears to be always zero)
 3-1   Unknown (R/W)
 0     Port Select (0=SD Card Slot, 1=Onboard eMMC)  (for SDIO: Unknown)

Known written values are 0400h and 0401h (SD). However known read values are 0201h (SD) and 0100h (SDIO).


4004828h - DSi: 40E0 - SD_CARD_OPTION - Memory Card Option Setup
4004A28h - DSi: 40EE - SDIO_CARD_OPTION - Card Option Setup

 15        Bus Width (0=4bit, 1=1bit)
 14        Unknown (usually set)
 13-8      Unknown/unused (appears to be always zero)
 7-4       Unknown, maybe some 4bit timing/timeout value
 0-3       Unknown, maybe another 4bit timing/timeout value

Settings spotted on DSi are 40E0h,40EEh.
Among others, this register should contain a 4bit timeout setting, "RTO[3:0] for SD (aka TO[3:0] for SDIO) timeout period for data start/busy bits, in the form of a multiple number of the SDCLK period."
Maybe also selects transfer CLK rate, or whatever.


4004834h - DSi: 0000 - SD_TRANSACTION_CTL - Transaction Control
4004A34h - DSi: 0000 - SDIO_TRANSACTION_CTL - Transaction Control

 15-10 Unknown/unused (appears to be always zero)
 9-8   Unknown
 7-3   Unknown/unused (appears to be always zero)
 2     Unknown
 1     Unknown/unused (appears to be always zero)
 0     Unknown

Maybe also selects transfer CLK rate, or whatever.


40048E0h - DSi: 0007 - SD_SOFT_RESET - Software Reset
4004AE0h - DSi: 0006 - SDIO_SOFT_RESET - Software Reset

 15-3 Unknown/unused (appears to be always zero)
 2    ?    Unknown (can be nonzero on DSi)
 1    ?    Unknown (can be nonzero on DSi)
 0    SRST Soft Reset (0=Reset, 1=Release)

Software should apply reset after sensing card insertion/removal, and (thereafter) release reset in case of card insertion. Software reset does acknowledge all IRQs (except that from SDIO /IRQ pin?), and does probably also reinitialize some other registers.


4004808h - DSi: 0100 - SDCTL_STOP_INTERNAL_ACTION

 15-9   Unknown/unused (appears to be always zero)
 8      Unknown (1=Enable automatic sending of CMD12 after BLK_COUNT blocks?)
 7-1    Unknown/unused (appears to be always zero)
 0      Unknown

Stop whatever internal action for whatever purpose in whatever situation?
Existing code does set bit8 (prior to changing SD_DATA16_BLK_COUNT).
Existing code does clear bit0 (alongsides with IRQ enable/acknowlege or so).


4004824h - DSi: 0000 - DSi: Used? - SDCTL_CARD_CLK_CTL Card Clock Control
Can be max 07FFh on DSi... ie. bit15 CANNOT be set?

 15     Disable HCLK divider (0=SDCLK selected via bit7-0, 1=SDCLK=HCLK)
 14-10  Unknown (zero on DSi)
 9      Unknown (set in some cases on DSi)
 8      Unknown (1=Start Clock, or Apply Clock Change, or so?)
 7-0    HCLK Div (0,1,2,4,8,10h,20h,40h,80h = Div2,4,8,16,32,64,128,256,512)

Clock supply to SD Card
The SDCLK signal is used for a provision of SD Memory Card or SDIO Card. Please refer to the following setting for enabling the SDCLK output.

(1) Set Stop Clock Control Register (Config Offset:40h) to 1Fh.
(2) Set D0 of SD Software Reset Register (Offset:0E0h) to 1b.
(3) Set D7-0 of SD Card Clock Control Register (Offset:024h). These bits
    are used for setting the frequency of SDCLK.
      80h : SDCLK=HCLK/512
      40h : SDCLK=HCLK/256
      20h : SDCLK=HCLK/128
      10h : SDCLK=HCLK/64
      08h : SDCLK=HCLK/32
      04h : SDCLK=HCLK/16
      02h : SDCLK=HCLK/8
      01h : SDCLK=HCLK/4
      00h : SDCLK=HCLK/2
    In addition, TC6387XB holds a function that SDCLK can have same
    frequency as HCLK. In this case, D7-0 settings of SD Card Clock Control
    Register (Offset:024h) becomes invalid setting.
    * Set D0 of Clock Mode Register (Config Offset:42h) to 1b.
    * Set D15 of SD Card Clock Control Register (Offset:024h) to 1b.
    Please attend that the specification of SDCLK is max.25MHz at the case
    of SD Card and is max.20MHz at the case of MultiMedia Card.
(4) D8 of SD Card Clock Control Register (Offset:024h) to 1b.
(5) D8 of Clock & Wait Control Register (Offset:138h) to 1b.

On the DSi, HCLK seems to be 33.513982 MHz.


4004x38h - DSi: 0000 - SDCTL_CLK_AND_WAIT_CTL

 15-0   Unknown (zero on DSi)

Maybe transfer CLK rate, or some master clock control for the clock input.


4004x3Ah - DSi: 0000 - SDCTL_SDIO_HOST_INFORMATION
4004x3Ch - DSi: 0000 - SDCTL_ERROR_CONTROL
4004x3Eh - DSi: 0000 - SDCTL_SDLED_CONTROL - LED Control (TC6387XB only)

 15-0   Unknown (zero on DSi)


40048E2h - DSi: 0009 - SDCTL_RESERVED2 (TC6371AF:CORE_REV)
40048E6h - DSi: 0000 - SDCTL_RESERVED3 (TC6371AF:BUF_ADR)
40048E8h - DSi: 0000 - UNDOC/UNUSED (TC6371AF:Resp_Header)
40048F6h - DSi: 0000 - SDCTL_RESERVED4 --- used by DSi !!!
40048F8h - DSi: 0004 - SDCTL_RESERVED5 <-- DSi: SD only (not SDIO)
40048FAh - DSi: 0007 - SDCTL_RESERVED6 <-- DSi: SD only (not SDIO)
40048FCh - DSi: 00FC - SDCTL_RESERVED7
40048FEh - DSi: 00FF - SDCTL_RESERVED8 (TC6371AF:Revision)
4004xE2h - DSi: 0000 - SDCTL_RESERVED9
4004xF0h - DSi: 0000 - SDCTL_RESERVED10
4004836h - DSi: 0002 - UNDOC! (bit1 can be set, other bits always 0)

 15-0   Unknown


4004838h/4004A38h - DSi: C007 - UNDOC!
4004840h/4004A40h - DSi: 003F - UNDOC?
4004842h/4004A42h - DSi: 002A - UNDOC?
40048B2h/4004AB2h - DSi: FFFF - UNDOC?
40048BAh/4004ABAh - DSi: 0200 - UNDOC?
40048F4h/4004AF4h - DSi: 0700 - UNDOC!

 15-0   Unknown