blob: a8ea26038a77b95ebce21a3d9351a108d739d83d [file] [log] [blame] [edit]
// Copyright 2024 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.
@available(added=HEAD)
library fuchsia.hardware.sdhci;
using fuchsia.hardware.sdmmc;
using zx;
type Quirk = strict bits : uint64 {
/// This is a BCM28xx specific quirk. The bottom 8 bits of the 136
/// bit response are normally filled by 7 CRC bits and 1 reserved bit.
/// The BCM controller checks the CRC for us and strips it off in the
/// process.
/// The higher level stack expects 136B responses to be packed in a
/// certain way so we shift all the fields back to their proper offsets.
STRIP_RESPONSE_CRC = 0x1;
/// BCM28xx quirk: The BCM28xx appears to use its internal DMA engine to
/// perform transfers against the SD card. Normally we would use SDMA or
/// ADMA (if the part supported it). Since this part doesn't appear to
/// support either, we just use PIO.
NO_DMA = 0x2;
/// The bottom 8 bits of the 136 bit response are normally filled by 7 CRC bits
/// and 1 reserved bit. Some controllers strip off the CRC.
/// The higher level stack expects 136B responses to be packed in a certain way
/// so we shift all the fields back to their proper offsets.
STRIP_RESPONSE_CRC_PRESERVE_ORDER = 0x4;
/// The controller uses a tuning process that does not follow the SDHCI specification.
NON_STANDARD_TUNING = 0x8;
/// Don't use DDR modes even if the SDHCI capabilities register indicates it is supported.
NO_DDR = 0x10;
/// Prevent DMA buffers from crossing boundaries specified by dma_boundary_alignment. For
/// example, a boundary alignment of 0x10000 will cause buffers crossing 64K boundaries to be
/// split across multiple descriptors.
USE_DMA_BOUNDARY_ALIGNMENT = 0x20;
NO_HS400_ENHANCED_STROBE = 0x40;
/// These bits correspond to the following fuchsia.hardware.sdmmc.Sdmmc methods:
/// - `SetSignalVoltage()`
/// - `SetBusWidth()`
/// - `SetBusFreq()`
/// - `SetTiming()`
/// - `PerformTuning()`
///
/// If the bit for a method is set, it means that the hardware deviates from the SDHCI
/// specification, and the SDHCI driver should call `VendorConfigureBus()` or
/// `VendorPerformTuning()` to let the vendor driver handle the operation. If the bit is not
/// set, the SDHCI will handle the operation as per the specification.
VENDOR_SET_SIGNAL_VOLTAGE = 0x80;
VENDOR_SET_BUS_WIDTH = 0x100;
VENDOR_SET_BUS_FREQ = 0x200;
VENDOR_SET_TIMING = 0x400;
VENDOR_PERFORM_TUNING = 0x800;
};
@discoverable
@transport("Driver")
closed protocol Device {
strict GetInterrupt() -> (resource struct {
irq zx.Handle:INTERRUPT;
}) error zx.Status;
/// Mmio size minus offset must be at least 512 bytes as per the SDHCI specification.
strict GetSdhciMmio() -> (resource struct {
mmio zx.Handle:VMO;
offset zx.Off;
}) error zx.Status;
/// Mmio size minus offset must be at least 260 bytes as per the CQHCI specification.
/// Returns
/// - ZX_ERR_NOT_SUPPORTED if the device does not support CQHCI
strict GetCqhciMmio() -> (resource struct {
mmio zx.Handle:VMO;
offset zx.Off;
}) error zx.Status;
/// Gets a handle to the bus transaction initiator for the device. The caller
/// receives ownership of the handle.
strict GetBti(struct {
index uint32;
}) -> (resource struct {
bti zx.Handle:BTI;
}) error zx.Status;
strict GetBaseClock() -> (struct {
clock uint32;
});
/// Returns device quirks.
strict GetQuirks() -> (struct {
quirks Quirk;
dma_boundary_alignment uint64;
});
/// Platform specific HW reset.
strict HwReset() -> ();
/// This method should be used to handle bus configuration on behalf of the SDHCI driver in
/// cases where the hardware deviates from the SDHCI specification. See the `Quirk` bits above.
strict VendorConfigureBus(flexible union {
1: voltage fuchsia.hardware.sdmmc.SdmmcVoltage;
2: width fuchsia.hardware.sdmmc.SdmmcBusWidth;
/// SDHCI defines two clocks: the clock delivered to the external card ("SD clock") and the
/// internal clock (upstream of the SD clock).
///
/// `VendorConfigureBus()` with `frequency_hz` always enables the internal clock, and if
/// `frequency_hz` is nonzero, enables the SD clock with the given frequency (the SD clock
/// is disabled if `frequency_hz` is zero). The driver must wait for all clocks to be stable
/// before returning.
3: frequency_hz uint32;
4: timing fuchsia.hardware.sdmmc.SdmmcTiming;
}) -> () error zx.Status;
/// Perform a vendor-specific tuning sequence. `cmd_idx` is the command that should used to
/// receive the tuning pattern from the device.
strict VendorPerformTuning(struct {
cmd_idx uint32;
}) -> () error zx.Status;
};
service Service {
device client_end:Device;
};