| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| library fuchsia.hardware.sdmmc; |
| |
| using zx; |
| |
| /// The max value of client_id fields below. There is no known need for more than eight clients at |
| /// the moment, however if that changes later this value will be increased. |
| const SDMMC_MAX_CLIENT_ID uint8 = 7; |
| |
| type SdmmcVoltage = strict enum : uint8 { |
| V330 = 0; |
| V180 = 1; |
| MAX = 2; |
| }; |
| |
| type SdmmcBusWidth = strict enum : uint8 { |
| ONE = 0; |
| FOUR = 1; |
| EIGHT = 2; |
| MAX = 3; |
| }; |
| |
| type SdmmcTiming = strict enum : uint8 { |
| LEGACY = 0; |
| HS = 1; |
| HSDDR = 2; |
| HS200 = 3; |
| HS400 = 4; |
| SDR12 = 5; |
| SDR25 = 6; |
| SDR50 = 7; |
| SDR104 = 8; |
| DDR50 = 9; |
| MAX = 10; |
| }; |
| |
| type SdmmcBuffer = strict resource union { |
| /// The ID of a VMO that was previously registered. |
| 1: vmo_id uint32; |
| /// An unregistered VMO of which the protocol implementation does not take ownership. The VMO is |
| /// pinned upon entering Request and is unpinned before returning. |
| 2: vmo zx.handle:VMO; |
| }; |
| |
| type SdmmcBufferType = strict enum : uint32 { |
| VMO_ID = 1; |
| VMO_HANDLE = 2; |
| }; |
| |
| type SdmmcBufferRegion = resource struct { |
| buffer SdmmcBuffer; |
| type SdmmcBufferType; |
| /// Offset into the VMO to start reading or writing. This is relative to the offset passed to |
| /// RegisterVmo if type is VMO_ID. |
| offset uint64; |
| /// Number of bytes to read from or write to this buffer region. |
| size uint64; |
| }; |
| |
| type SdmmcReqNew = resource struct { |
| cmd_idx uint32; |
| cmd_flags uint32; |
| arg uint32; |
| |
| blocksize uint32; |
| |
| /// If true, the SDMMC driver should reduce the log level of any error |
| /// messages that this request produces. This will be set on requests for |
| /// which errors are expected or not fatal. |
| suppress_error_messages bool; |
| |
| /// The client ID for this request. Only VMOs registered with this client may be present in |
| /// buffers below. |
| client_id uint8; |
| buffers vector<SdmmcBufferRegion>:MAX; |
| }; |
| |
| /// number of pages per request - 2M per request |
| /// matches DMA_DESC_COUNT in dev/block/sdhci |
| /// (PAGE_SIZE / sizeof(zx_paddr_t)) |
| const SDMMC_PAGES_COUNT uint64 = 512; |
| |
| /// sdmmc requests. one per command |
| type SdmmcReq = resource struct { |
| cmd_idx uint32; |
| cmd_flags uint32; |
| arg uint32; |
| |
| /// data command parameters |
| blockcount uint16; |
| blocksize uint16; |
| use_dma bool; |
| /// Used if use_dma is true |
| dma_vmo zx.handle:VMO; |
| /// Used if use_dma is false |
| @mutable |
| @buffer |
| virt vector<uint8>:MAX; |
| /// offset into dma_vmo or virt |
| buf_offset uint64; |
| pmt zx.handle; |
| |
| /// If true, the SDMMC driver should reduce the log level of any error |
| /// messages that this request produces. This will be set on requests for |
| /// which errors are expected or not fatal. |
| suppress_error_messages bool; |
| |
| /// response data |
| response array<uint32, 4>; |
| |
| /// status |
| status zx.status; |
| }; |
| |
| type SdmmcHostCap = strict enum : uint64 { |
| BUS_WIDTH_8 = 0x1; |
| DMA = 0x2; |
| VOLTAGE_330 = 0x4; |
| AUTO_CMD12 = 0x8; |
| SDR104 = 0x10; |
| SDR50 = 0x20; |
| DDR50 = 0x40; |
| /// The host does not require tuning for SDR50. |
| NO_TUNING_SDR50 = 0x80; |
| }; |
| |
| type SdmmcHostPrefs = strict enum : uint64 { |
| DISABLE_HS400 = 0x1; |
| DISABLE_HS200 = 0x2; |
| DISABLE_HSDDR = 0x4; |
| }; |
| |
| type SdmmcHostInfo = struct { |
| /// Controller capabilities |
| caps uint64; |
| /// Maximum data request size |
| max_transfer_size uint64; |
| max_transfer_size_non_dma uint64; |
| /// The number of buffer regions that may be used in a single request. |
| max_buffer_regions uint64; |
| /// Host specific preferences |
| prefs uint64; |
| }; |
| |
| type SdmmcVmoRight = strict enum : uint32 { |
| READ = 0x1; // The protocol implementation can read from this VMO (used for write requests). |
| WRITE = 0x2; // The protocol implementation can write to this VMO (used for read requests). |
| }; |
| |
| @transport("Banjo") |
| @banjo_layout("ddk-interface") |
| protocol InBandInterrupt { |
| Callback() -> (); |
| }; |
| |
| @transport("Banjo") |
| @banjo_layout("ddk-protocol") |
| protocol Sdmmc { |
| /// Get host info. |
| HostInfo() -> (struct { |
| s zx.status; |
| info SdmmcHostInfo; |
| }); |
| /// Set signal voltage. |
| SetSignalVoltage(struct { |
| voltage SdmmcVoltage; |
| }) -> (struct { |
| s zx.status; |
| }); |
| /// Set bus width. |
| SetBusWidth(struct { |
| bus_width SdmmcBusWidth; |
| }) -> (struct { |
| s zx.status; |
| }); |
| /// Set bus frequency, zero means disable the clock to the card. |
| SetBusFreq(struct { |
| bus_freq uint32; |
| }) -> (struct { |
| s zx.status; |
| }); |
| /// Set mmc timing. |
| SetTiming(struct { |
| timing SdmmcTiming; |
| }) -> (struct { |
| s zx.status; |
| }); |
| /// Issue a hw reset. |
| HwReset() -> (); |
| /// Perform tuning. |
| PerformTuning(struct { |
| cmd_idx uint32; |
| }) -> (struct { |
| s zx.status; |
| }); |
| /// Issue a request. |
| Request(resource struct { |
| @in_out |
| req SdmmcReq; |
| }) -> (struct { |
| s zx.status; |
| }); |
| RegisterInBandInterrupt(resource struct { |
| @in_out |
| interrupt_cb client_end:InBandInterrupt; |
| }) -> (struct { |
| s zx.status; |
| }); |
| |
| /// In the methods below, vmo_id is used to uniquely identify a VMO that will be passed to |
| /// Request in an SdmmcBufferRegion. VMO IDs are chosen by the caller, and may be any uint32 |
| /// value. |
| /// Registers a VMO and transfers ownership to the protocol implementation. vmo_rights is a bit |
| /// field containing SdmmcVmoRight values, and determines the read/write permissions used by |
| /// the implementation when pinning or mapping the VMO. The implementation may pin vmo during |
| /// this call or any time it is used in a request, and may keep it pinned until the VMO is |
| /// unregistered. client_id may be in [0, SDMMC_MAX_CLIENT_ID] and identifies the ID space for |
| /// this VMO to be registered in (that is, two different VMOs may use the same ID if they are |
| /// registered for different clients). |
| RegisterVmo(resource struct { |
| vmo_id uint32; |
| client_id uint8; |
| vmo zx.handle:VMO; |
| offset uint64; |
| size uint64; |
| vmo_rights uint32; |
| }) -> (struct { |
| status zx.status; |
| }); |
| /// The callee unmaps/unpins the VMO and returns ownership to the caller. |
| UnregisterVmo(struct { |
| vmo_id uint32; |
| client_id uint8; |
| }) -> (resource struct { |
| status zx.status; |
| vmo zx.handle:VMO; |
| }); |
| |
| /// Perform the request. The protocol implementation chooses whether or not to use DMA depending |
| /// on the properties of the request and the capabilities of the controller. |
| /// |
| /// Clients are responsible for performing the following cache operations: |
| /// |
| /// After read requests: |
| /// - Call zx_cache_flush with ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE on buffers that |
| /// have been mapped by the client. |
| /// - Call zx_vmo_op_range with ZX_VMO_OP_CACHE_CLEAN_INVALIDATE on all other buffers. |
| /// |
| /// Note that writing to any portion of a buffer before DoRwTxnNew has returned can corrupt the |
| /// received data. |
| /// |
| /// Before write requests: |
| /// - Call zx_cache_flush with ZX_CACHE_FLUSH_DATA on buffers that have been mapped by the |
| /// client. |
| /// - Call zx_vmo_op_range with ZX_VMO_OP_CACHE_CLEAN on all other buffers. |
| RequestNew(resource struct { |
| req SdmmcReqNew; |
| }) -> (struct { |
| status zx.status; |
| response array<uint32, 4>; |
| }); |
| }; |