420 lines
16 KiB
Plaintext
420 lines
16 KiB
Plaintext
/*
|
|
* Copyright (c) 2012, ETH Zurich. All rights reserved.
|
|
*
|
|
* This file is distributed under the terms in the attached LICENSE file.
|
|
* If you do not find this file, copies can be found by writing to:
|
|
* ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
|
|
*/
|
|
|
|
/*
|
|
* sdhc.dev
|
|
*
|
|
* DESCRIPTION: SD Host Controller
|
|
*
|
|
* See:
|
|
* SD Specifications Part A2: SD Host Controller Simplified Specification
|
|
* Version 3.00, February 25, 2011.
|
|
* Technical Committee, SD Association
|
|
*
|
|
* Note that the specification specifies 16-bit registers. Here we
|
|
* merge adjacent registers into 32-bit ones, so they are accessed
|
|
* two-at-a-time as 32-bit words. This is how they are implemented on
|
|
* the TI OMAP SoCs, for example.
|
|
*/
|
|
|
|
device sdhc msbfirst (addr base) "SD Host Controller" {
|
|
|
|
//
|
|
// Command formats (the non-trival ones)
|
|
//
|
|
// The following section numbers refer to:
|
|
// SD Specifications Part 1: Physical Layer Simplified Specification
|
|
// Version 3.01, May 18, 2010.
|
|
// Technical Committee, SD Card Association
|
|
//
|
|
|
|
// 4.7.4
|
|
datatype cmd4 msbfirst(32) "SET_DSR command" {
|
|
dsr 16 "DSR value";
|
|
_ 16;
|
|
};
|
|
|
|
datatype rcacmd msbfirst(32) "Commands 7,9,10,13,15,55" {
|
|
rca 16 "RCA value";
|
|
_ 16;
|
|
};
|
|
|
|
datatype cmd8 msbfirst(32) "SEND_IF_COND command" {
|
|
_ 20 mbz;
|
|
vhs 4 "Voltage supplied (VHS)";
|
|
pattern 8 "Check pattern";
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// Host controller registers
|
|
//
|
|
// The following section numbers refer to:
|
|
// SD Specifications Part A2: SD Host Controller Simplified Specification
|
|
// Version 3.00, February 25, 2011.
|
|
// Technical Committee, SD Association
|
|
//
|
|
|
|
// 2.2.1
|
|
register sdmasa rw addr(base, 0x00) "SDMA system address"
|
|
type(uint32);
|
|
|
|
register arg2 rw also addr(base, 0x00) "Argument 2"
|
|
type(uint32);
|
|
|
|
// 2.2.2/3
|
|
register blckcnt rw addr(base, 0x04) "Block count" {
|
|
nblk 16 "Block count";
|
|
_ 1 mbz;
|
|
hsbb 3 "Host SDMA buffer boundary (4k . 2^x)";
|
|
blen 12 "Transfer block size (bytes)";
|
|
};
|
|
|
|
// 2.2.4
|
|
register arg1 rw addr(base, 0x08) "Argument 1"
|
|
type(uint32);
|
|
|
|
// 2.2.5/6
|
|
constants auto_en "Auto command enable values" {
|
|
auto_en_dis = 0b00 "Auto Command Disabled";
|
|
auto_en_12 = 0b01 "Auto CMD12 Enable";
|
|
auto_en_23 = 0b10 "Auto CMD23 Enable";
|
|
};
|
|
constants cmd_tp "Command type" {
|
|
cmd_tp_abrt = 0b11 "Abort CMD12, CMD52 for writing I/O Abort";
|
|
cmd_tp_rsme = 0b10 "Resume CMD52 for writing Function Select";
|
|
cmd_tp_susp = 0b01 "Suspend CMD52 for writing Bus Suspend";
|
|
cmd_tp_norm = 0b00 "Normal; other commands";
|
|
};
|
|
constants rsp_tp "Response type" {
|
|
rsp_tp_none = 0b00 "No response";
|
|
rsp_tp_136 = 0b01 "Response length 136";
|
|
rsp_tp_48 = 0b10 "Response length 48";
|
|
rsp_tp_48cb = 0b11 "Response length 48 check busy after response";
|
|
};
|
|
register ctm rw addr(base, 0x0C) "Command and transfer mode" {
|
|
_ 2 mbz;
|
|
index 6 "Command index";
|
|
cmd_type 2 type(cmd_tp) "Command type";
|
|
dp 1 "Data present select";
|
|
cice 1 "Command index check enable";
|
|
ccce 1 "Command CRC check enable";
|
|
_ 1 mbz;
|
|
rsp_type 2 "Response type select";
|
|
_ 10 mbz;
|
|
msbs 1 "Multi/single block select (1=multi)";
|
|
ddir 1 "Data transfer direction select (1=read)";
|
|
acen 2 type(auto_en) "Auto command enable";
|
|
bce 1 "Block count enable";
|
|
de 1 "DMA enable";
|
|
};
|
|
|
|
// 2.2.7
|
|
regarray resp rw addr(base, 0x10)[4] "Response"
|
|
type(uint32);
|
|
|
|
// 2.2.8
|
|
register bdp rw addr(base, 0x20) "Buffer data port"
|
|
type(uint32);
|
|
|
|
// 2.2.9
|
|
register ps ro addr(base, 0x24) "Present state" {
|
|
_ 7 mbz;
|
|
clsl 1 "CMD line signal level";
|
|
dlsl 4 "DAT[3:0] line signal level";
|
|
wp 1 "Write protect switch pin level (0=ro)";
|
|
cdpl 1 "Card detect pin level (1=present)";
|
|
css 1 "Card state stable";
|
|
cins 1 "Card inserted";
|
|
_ 4 mbz;
|
|
bre 1 "Buffer read enable";
|
|
bwe 1 "Buffer write enable";
|
|
rta 1 "Read transfer active";
|
|
wta 1 "Write transfer active";
|
|
_ 4 mbz;
|
|
rtr 1 "Re-tuning request";
|
|
dla 1 "DAT line active";
|
|
dati 1 "Command inhibit (DAT)";
|
|
cmdi 1 "Command inhibit (CMD)";
|
|
};
|
|
|
|
// 2.2.10-13
|
|
constants voltage "Bus voltage select" {
|
|
voltage_33 = 0b111 "3.3V (typ.)";
|
|
voltage_30 = 0b110 "3.0V (typ.)";
|
|
voltage_18 = 0b101 "1.8V (typ.)";
|
|
};
|
|
register hctl rw addr(base, 0x28) "Host control" {
|
|
_ 5 mbz;
|
|
rem 1 "Wakeup event enable on SD card removal";
|
|
ins 1 "Wakeup event enable on SD card insertion";
|
|
iwe 1 "Wakeup event enable on card interrupt";
|
|
_ 4 mbz;
|
|
ibg 1 "Interrupt at block gap";
|
|
rwc 1 "Read wait control";
|
|
cr 1 "Continue request";
|
|
sbgr 1 "Stop at block gap request";
|
|
_ 4 mbz;
|
|
sdvs 3 type(voltage) "SD bus voltage select";
|
|
sdbp 1 "SD bus power";
|
|
cdss 1 "Card detect signal selection";
|
|
cdtl 1 "Card detect test level";
|
|
edtw 1 "Extended data transfer width";
|
|
dmas 2 "DMA select";
|
|
hspe 1 "High speed enable";
|
|
dtw 1 "Data transfer width";
|
|
lc 1 "LED control";
|
|
};
|
|
|
|
// 2.2.14-16
|
|
register sysctl rw addr(base, 0x2C) "System control" {
|
|
_ 5 mbz;
|
|
srd 1 "Software reset for DAT line";
|
|
src 1 "Software reset for CMD line";
|
|
sra 1 "Software reset for all";
|
|
_ 4 mbz;
|
|
dto 4 "Data timeout counter value";
|
|
clkd 10 "SDCLK frequency select";
|
|
cgs 1 "Clock generator select";
|
|
_ 2 mbz;
|
|
cen 1 "SD clock enable";
|
|
ics 1 ro "Internal clock stable";
|
|
ice 1 "Internal clock enable";
|
|
};
|
|
|
|
// 2.2.17/18
|
|
register stat addr(base, 0x30) "Interrupt status" {
|
|
// 4 bits in the spec, but we have two bits in the OMAP 44xx
|
|
// adaptor which we also specify here. Might need to change
|
|
// this if we encounter another SDHC reader with different
|
|
// use of these bits.
|
|
vses 2 rw "Vendor specific error status";
|
|
bada 1 rw1c "Bad access to data space";
|
|
cerr 1 rw1c "Card error";
|
|
_ 1 mbz;
|
|
te 1 rw1c "Tuning error";
|
|
admae 1 rw1c "ADMA error";
|
|
ace 1 rw1c "Auto CMD error";
|
|
cle 1 rw1c "Current limit error";
|
|
deb 1 rw1c "Data end bit error";
|
|
dcrc 1 rw1c "Data CRC error";
|
|
dto 1 rw1c "Data timeout error";
|
|
cie 1 rw1c "Command index error";
|
|
ceb 1 rw1c "Command end bit error";
|
|
ccrc 1 rw1c "Command CRC error";
|
|
cto 1 rw1c "Command timeout error";
|
|
erri 1 ro "Error interrupt";
|
|
_ 2 mbz;
|
|
rte 1 ro "Re-tuning event";
|
|
intc 1 ro "INT_C";
|
|
intb 1 ro "INT_B";
|
|
inta 1 ro "INT_A";
|
|
cirq 1 ro "Card interrupt";
|
|
crem 1 rw1c "Card removal";
|
|
cins 1 rw1c "Card insertion";
|
|
brr 1 rw1c "Buffer read ready";
|
|
bwr 1 rw1c "Buffer write ready";
|
|
dma 1 rw1c "DMA interrupt";
|
|
bge 1 rw1c "Block gap event";
|
|
tc 1 rw1c "Transfer complete";
|
|
cc 1 rw1c "Command complete";
|
|
};
|
|
|
|
|
|
|
|
// 2.2.19-22
|
|
regtype ir "Interrupt register" {
|
|
// 4 bits in the spec, but we have two bits in the OMAP 44xx
|
|
// adaptor which we also specify here. Might need to change
|
|
// this if we encounter another SDHC reader with different
|
|
// use of these bits.
|
|
vses 2 rw "Vendor specific error status";
|
|
bada 1 rw "Bad access to data space";
|
|
cerr 1 rw "Card error";
|
|
_ 1 mbz;
|
|
te 1 rw "Tuning error";
|
|
admae 1 rw "ADMA error";
|
|
ace 1 rw "Auto CMD error";
|
|
cle 1 rw "Current limit error";
|
|
deb 1 rw "Data end bit error";
|
|
dcrc 1 rw "Data CRC error";
|
|
dto 1 rw "Data timeout error";
|
|
cie 1 rw "Command index error";
|
|
ceb 1 rw "Command end bit error";
|
|
ccrc 1 rw "Command CRC error";
|
|
cto 1 rw "Command timeout error";
|
|
_ 3 mbz;
|
|
rte 1 rw "Re-tuning event";
|
|
intc 1 rw "INT_C";
|
|
intb 1 rw "INT_B";
|
|
inta 1 rw "INT_A";
|
|
cirq 1 rw "Card interrupt";
|
|
crem 1 rw "Card removal";
|
|
cins 1 rw "Card insertion";
|
|
brr 1 rw "Buffer read ready";
|
|
bwr 1 rw "Buffer write ready";
|
|
dma 1 rw "DMA interrupt";
|
|
bge 1 rw "Block gap event";
|
|
tc 1 rw "Transfer complete";
|
|
cc 1 rw "Command complete";
|
|
};
|
|
|
|
register ie addr(base, 0x34) "Interrupt enable"
|
|
type(ir);
|
|
register ise addr(base, 0x38) "Interrupt signal enable"
|
|
type(ir);
|
|
|
|
// 2.2.23-24
|
|
constants uhs_mode "UHS mode" {
|
|
uhs_sdr12 = 0b000 "SDR12";
|
|
uhs_sdr25 = 0b001 "SDR25";
|
|
uhs_sdr50 = 0b010 "SDR50";
|
|
uhs_sdr104 = 0b011 "SDR104";
|
|
uhs_ddr50 = 0b100 "DDR50";
|
|
};
|
|
register aces addr(base, 0x3c) "Auto CMD error status / Host control 2" {
|
|
pve 1 rw "Preset value enable";
|
|
aie 1 rw "Asynchronous interrupt enable";
|
|
_ 6 mbz;
|
|
scs 1 rw "Sampling clock select";
|
|
et 1 rw "Execute tuning";
|
|
dss 2 rw "Driver strength select";
|
|
lvse 1 rw "1.8V signaling enable";
|
|
ums 3 rw type(uhs_mode) "UHS mode select";
|
|
_ 8 mbz;
|
|
cni 1 ro "Command not issued by Auto CMD12 error";
|
|
_ 2 mbz;
|
|
acie 1 ro "Auto CMD index error";
|
|
acebe 1 ro "Auto CMD end bit error";
|
|
acce 1 ro "Auto CMD CRC error";
|
|
acte 1 ro "Auto CMD timeout error";
|
|
acne 1 ro "Auto CMD12 not executed";
|
|
};
|
|
|
|
// 2.2.25
|
|
// This register is, bizarrely, writeable on the OMAP44xx, and
|
|
// needs to be written to configure the controller.
|
|
constants slot_tp "Slot type" {
|
|
slot_rem = 0b00 "Removable card slot";
|
|
slot_emb = 0b01 "Embedded slot for one device";
|
|
slot_shr = 0b10 "Shared bus slot";
|
|
};
|
|
register capa rw addr(base, 0x40) "Capability register A" {
|
|
slottp 2 type(slot_tp) "Slot type";
|
|
ais 1 "Asynchronous interrupt support";
|
|
bit64 1 "64-bit system bus support";
|
|
_ 1 mbz;
|
|
vs18 1 "Voltage support 1.8V";
|
|
vs30 1 "Voltage support 3.0V";
|
|
vs33 1 "Voltage support 3.3V";
|
|
srs 1 "Suspend/resume support";
|
|
ds 1 "SDMA support";
|
|
hss 1 "High speed support";
|
|
_ 1 mbz;
|
|
ad2s 1 "ADMA2 support";
|
|
bit8 1 "8-bit support for embedded device";
|
|
mbl 2 "Max block length";
|
|
bcf 8 "Base clock frequency for SD clock";
|
|
tcu 1 "Timeout clock unit";
|
|
_ 1 mbz;
|
|
tcf 6 "Tileout clock frequency";
|
|
};
|
|
|
|
register capb ro addr(base, 0x44) "Capability register B" {
|
|
_ 8 mbz;
|
|
cm 8 "Clock multiplier";
|
|
rtm 2 "Re-tuning modes";
|
|
utsdr50 1 "Use tuning for SDR50";
|
|
_ 1 mbz;
|
|
tcrt 4 "Timer count for re-tuning";
|
|
_ 1 mbz;
|
|
dtd 1 "Driver type D support";
|
|
dtc 1 "Driver type C support";
|
|
dta 1 "Driver type A support";
|
|
_ 1 mbz;
|
|
ddr50 1 "DDR50 support";
|
|
sdr104 1 "SDR104 support";
|
|
sdr50 1 "SDR50 support";
|
|
};
|
|
|
|
// 2.2.26
|
|
register mcc ro addr(base, 0x48) "Maximum current capabilities" {
|
|
_ 8 mbz;
|
|
mc18 8 "Maximum current for 1.8V";
|
|
mc30 8 "Maximum current for 3.0V";
|
|
mc33 8 "Maximum current for 3.3V";
|
|
};
|
|
|
|
// 2.2.27
|
|
register fer wo addr(base, 0x50) "Force event register" {
|
|
vses 4 wo "Vendor specific error status";
|
|
_ 2 mbz;
|
|
ae 1 wo "ADMA error";
|
|
ace 1 wo "Auto CMD error";
|
|
cle 1 wo "Current limit error";
|
|
debe 1 wo "Data end bit error";
|
|
dce 1 wo "Data CRC error";
|
|
dte 1 wo "Data timeout error";
|
|
cie 1 wo "Command index error";
|
|
cebe 1 wo "Command end bit error";
|
|
cce 1 wo "Command CRC error";
|
|
cte 1 wo "Command timeout error";
|
|
_ 8 mbz;
|
|
cni 1 wo "Command not issued by Auto CMD12 error";
|
|
_ 2 mbz;
|
|
acie 1 wo "Auto CMD index error";
|
|
acebe 1 wo "Auto CMD end bit error";
|
|
acce 1 wo "Auto CMD CRC error";
|
|
acte 1 wo "Auto CMD timeout error";
|
|
acne 1 wo "Auto CMD12 not executed";
|
|
};
|
|
|
|
// 2.2.29
|
|
register admaes ro addr(base, 0x54) "ADMA error status" {
|
|
_ 29 mbz;
|
|
lme 1 "ADMA length mismatch error";
|
|
aes 2 "ADMA error state";
|
|
};
|
|
|
|
// 2.2.30
|
|
register admasl rw addr(base, 0x58) "ADMA system address low"
|
|
type(uint32);
|
|
register admash rw addr(base, 0x5C) "ADMA system address high"
|
|
type(uint32);
|
|
|
|
//
|
|
// We do not, at present, implement the Preset Value registers.
|
|
//
|
|
|
|
// 2.2.32
|
|
register sbc rw addr(base, 0xE0) "Shared bus control" {
|
|
_ 1 mbz;
|
|
bepc 7 rw "Back-end power control";
|
|
_ 1 mbz;
|
|
ips 3 rw "Interrupt pin select";
|
|
_ 1 mbz;
|
|
cps 3 rw "Clock pin select";
|
|
_ 1 mbz;
|
|
bwp 7 ro "Bus width preset";
|
|
_ 2 mbz;
|
|
niip 2 ro "Number of interrupt input pins";
|
|
_ 1 mbz;
|
|
ncp 3 ro "Number of clock pins";
|
|
};
|
|
|
|
// 2.2.33/34
|
|
register rev rw addr(base, 0xFC) "Version / Slot int. status" {
|
|
vrev 8 ro "Vendor version number";
|
|
srev 8 ro "Specification version number";
|
|
_ 8 mbz;
|
|
slots 8 "Interrupt status per slot";
|
|
};
|
|
|
|
};
|