blob: 297705bbb2987a06b492fc0acfa89c301e825fd8 [file] [log] [blame]
// 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 uint8 SDMMC_MAX_CLIENT_ID = 7;
enum SdmmcVoltage : uint8 {
V330 = 0;
V180 = 1;
MAX = 2;
};
enum SdmmcBusWidth : uint8 {
ONE = 0;
FOUR = 1;
EIGHT = 2;
MAX = 3;
};
enum SdmmcTiming : uint8 {
LEGACY = 0;
HS = 1;
HSDDR = 2;
HS200 = 3;
HS400 = 4;
SDR12 = 5;
SDR25 = 6;
SDR50 = 7;
SDR104 = 8;
DDR50 = 9;
MAX = 10;
};
resource union SdmmcBuffer {
/// The ID of a VMO that was previously registered.
1: uint32 vmo_id;
/// 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: zx.handle:VMO vmo;
};
enum SdmmcBufferType : uint32 {
VMO_ID = 1;
VMO_HANDLE = 2;
};
resource struct SdmmcBufferRegion {
SdmmcBuffer buffer;
SdmmcBufferType type;
/// Offset into the VMO to start reading or writing. This is relative to the offset passed to
/// RegisterVmo if type is VMO_ID.
uint64 offset;
/// Number of bytes to read from or write to this buffer region.
uint64 size;
};
resource struct SdmmcReqNew {
uint32 cmd_idx;
uint32 cmd_flags;
uint32 arg;
uint32 blocksize;
/// If true, the SDMMC driver should not print any error messages for this request. This is used
/// for initialization and tuning, when some requests are expected to fail.
bool probe_tuning_cmd;
/// The client ID for this request. Only VMOs registered with this client may be present in
/// buffers below.
uint8 client_id;
vector<SdmmcBufferRegion> buffers;
};
/// number of pages per request - 2M per request
/// matches DMA_DESC_COUNT in dev/block/sdhci
/// (PAGE_SIZE / sizeof(zx_paddr_t))
const uint64 SDMMC_PAGES_COUNT = 512;
/// sdmmc requests. one per command
resource struct SdmmcReq {
uint32 cmd_idx;
uint32 cmd_flags;
uint32 arg;
/// data command parameters
uint16 blockcount;
uint16 blocksize;
bool use_dma;
/// Used if use_dma is true
zx.handle:VMO dma_vmo;
/// Used if use_dma is false
[Mutable, Buffer] vector<uint8> virt;
/// offset into dma_vmo or virt
uint64 buf_offset;
zx.handle pmt;
bool probe_tuning_cmd;
/// response data
array<uint32>:4 response;
/// status
zx.status status;
};
enum SdmmcHostCap : 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;
};
enum SdmmcHostPrefs : uint64 {
DISABLE_HS400 = 0x1;
DISABLE_HS200 = 0x2;
DISABLE_HSDDR = 0x4;
};
struct SdmmcHostInfo {
/// Controller capabilities
uint64 caps;
/// Maximum data request size
uint64 max_transfer_size;
uint64 max_transfer_size_non_dma;
/// The number of buffer regions that may be used in a single request.
uint64 max_buffer_regions;
/// Host specific preferences
uint64 prefs;
};
enum SdmmcVmoRight : 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", BanjoLayout = "ddk-interface"]
protocol InBandInterrupt {
Callback() -> ();
};
[Transport = "Banjo", BanjoLayout = "ddk-protocol"]
protocol Sdmmc {
/// Get host info.
HostInfo() -> (zx.status s, SdmmcHostInfo info);
/// Set signal voltage.
SetSignalVoltage(SdmmcVoltage voltage) -> (zx.status s);
/// Set bus width.
SetBusWidth(SdmmcBusWidth bus_width) -> (zx.status s);
/// Set bus frequency, zero means disable the clock to the card.
SetBusFreq(uint32 bus_freq) -> (zx.status s);
/// Set mmc timing.
SetTiming(SdmmcTiming timing) -> (zx.status s);
/// Issue a hw reset.
HwReset() -> ();
/// Perform tuning.
PerformTuning(uint32 cmd_idx) -> (zx.status s);
/// Issue a request.
Request([InOut] SdmmcReq req) -> (zx.status s);
RegisterInBandInterrupt([InOut] InBandInterrupt interrupt_cb) -> (zx.status s);
/// 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(uint32 vmo_id, uint8 client_id, zx.handle:VMO vmo, uint64 offset,
uint64 size, uint32 vmo_rights) -> (zx.status status);
/// The callee unmaps/unpins the VMO and returns ownership to the caller.
UnregisterVmo(uint32 vmo_id, uint8 client_id) -> (zx.status status, zx.handle:VMO 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(SdmmcReqNew req) -> (zx.status status, array<uint32>:4 response);
};