blob: 2bbeef1f5282b112a52f006f25baad7a30f4657a [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 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>;
});
};