Showing changes from revision #3 to #4:
Added | Removed | Changed
SD host controllers may be attached via a PCI bus as was anticipated by the SD standard. In this case, the SDIODriver would scan the PCI bus for devices of the appropriate class. It should be noted however that at the present time there are no RISC OS platforms with such an architecture, so this is considered a future enhancement.
Host controllers with alternate attachments are discovered via the HAL Device API. This potentially includes hot-pluggable host controllers, as is true of all HAL Devices. The HAL Device looks like this:
Offset | Bits | Value | Meaning |
---|---|---|---|
0 | Type: | ||
15 – 8 | 5 | Controller of peripheral buses | |
7 – 0 | 1 | For SDIO controller | |
2 | ID: | ||
15 – 0 | 1 | Generic SDHCI controller | |
4 | Location: | ||
31 – 28 | 5 | (interconnect) for OMAP3 | |
27 – 24 | 1 | (L4 interconnect) for OMAP3 | |
23 – 16 | 0 | 0 for OMAP3 | |
15 – 8 | 0 | 0 for OMAP3 | |
7 – 0 | 0 | 0 for OMAP3 | |
8 | Version: Only major version 0 has currently been defined. Within major version 0, minor version 1 indicates the presence of the TriggerCommand function pointer (which may still be NULL) | ||
12 | Description: | ||
16 | Address: | ||
20 | Reserved1: | ||
32 | Activate: | ||
36 | Deactivate: | ||
40 | Reset: | ||
44 | Sleep: | ||
48 | DeviceNumber: | ||
52 | TestIRQ: | ||
56 | ClearIRQ: | ||
60 | Reserved2: | ||
64 | Flags: | ||
31 – 3 | Reserved, must be zero | ||
2 | 1 | the controller doesn’t set the error interrupt bit in the normal interrupt status register | |
1 | 1 | The controller doesn’t strip the byte containing the CRC and end bit from R2 responses before placing in the response registers | |
0 | 0 | All register reads and writes must use 32-bit accesses | |
68 | 31 – 0 | Number of slots supported by this host controller – or technically, the number of standard register sets it provides, which corresponds to the number of CMD lines it drives. Each slot is normally used to drive a single MMC or SD device, but it is possible that multiple devices can be driven by a single slot – for MMC buses this is achieved by the use of an identifying field, the RCA, in the command argument; for SD buses, a Shared Bus configuration can be implemented in hardware, with a separate CLK line for multiple devices that share the same CMD line | |
72 | 31 – 0 | Pointer to array of structures giving further information about each slot |
Type | Function Pointer | Meaning |
---|---|---|
void | WriteRegister(device *controller, uint32_t slot, void *address, uint32_t value, uint32_t width) | function pointer to a custom routine to write a register in the SDHCI controller. If flags bit 0 is set, then writes have already been amalgamated into 32-bit words and the address will be word aligned. Otherwise the fourth parameter represents the value to be written, zero-extended to a 32-bit value, and the fifth contains the width of the register in bytes. This entry is intended for controllers that have special requirements (such as the BCM2835 where the rate of register pokes must be strictly limited). In other cases, a null pointer can be given, and the register will be written using a simple data write operation |
uint64_t | GetCapabilities(device *controller, uint32_t slot) | function pointer to a custom routine to read the controller’s capabilities register. This is intended for controllers that do not implement this standard SDHCI register; if the register is implemented, you can use a null pointer instead. The value returned from this function should follow the bit layout as defined in the SDHCI standard |
uint32_t | GetVddCapabilities(device *controller, uint32_t slot) | bit 0 set => 3.3 V supported bit 1 set => 3.0 V supported bit 2 set => 1.8 V supported other bits reserved, should be 0 If you report more than one bit set, then you must also support 0 V (this is because cards must be powered down in order to change their operating voltage) |
void | SetVdd(device *controller, uint32_t slot, uint32_t voltage) | |
void | SetBusMode(device *controller, uint32_t slot, bool od_not_pp) | |
void | PostPowerOn(device *controller, uint32_t slot) | |
void | SetBusWidth(device_t *controller, uint32_t slot, uint32_t lines) | |
uint32_t | GetMaxCurrent(device *controller, uint32_t slot) | |
uint32_t | SetSDCLK(device *controller, uint32_t slot, uint32_t freq_khz) | |
uint32_t | GetTMCLK(device *controller, uint32_t slot) | |
void | SetActivity(device *controller, uint32_t slot, uint32_t level) | |
bool | GetCardDetect(device *controller, uint32_t slot) | |
bool | GetWriteProtect(device * controller, uint32_t slot) | |
void | TriggerCommand(device *controller, uint32_t slot, uint16_t transfer_mode, uint16_t command) |
Further information on HAL Device Descriptor fields can be found here.
The structures pointed at by slotinfo have the following layout:
Offset | Bits | Meaning |
---|---|---|
0 | ||
31 – 8 | ||
7 | ||
6 | ||
5 – 3 | ||
2 – 1 | ||
0 | ||
4 | ||
31 – 0 |
The OMAP3530 has 3 host controllers with one slot on each, but since the beagleboard only tracks out one of them to an SD connector, only this one will be reported by the HAL. For boards like the IGEPv2 which use 2 of the controllers, the HAL will instead report two devices. A driver for a beagleboard expansion card would announce the additional controller(s) once the expansion card had been detected – this is necessary since the HAL can’t be expected to have knowledge of how to detect every possible expansion card and how they route their SD buses.
(Actually, to simplify initial development, this device will be implemented in a module, so that complete ROM rebuilds are not required to test each incremental change, but when the code becomes stable it will be moved into the HAL proper.)
First, a note on controller and card addressing. There are a number of fields common to multiple parts of the API:
The SDIODriver is responsible for probing cards, to identify which are memory cards, which are IO cards and which are combo cards, and for IO cards, discovering the set of functions available and the Function Interface Code for each. However, it is not appropriate for it to create further HAL devices to describe functions because to do so would mean hard-coding knowledge of the meaning of each Function Interface Code into the SDIODriver, and additional codes could be allocated at any time; it is better that this knowledge is encapsulated within the driver module for that specific function.