[dev][sdhci] switch to BTI
Re-landed version of I8a4bc3a508db17458ddd6324841d1d78306ab320 (git
26c25eb8505e136576ac4a319a77540834b380bd), modified only to build clean.
I believe this was reverted in the bulk revert
335c3a414e169804eb9050d784af6cebd0f5c77f because it did not build
cleanly. Testing on Acer and Paradise showed no issue.
Change-Id: I10b96fa1a6e3f95aac71c501339abf89174be811
diff --git a/system/dev/block/pci-sdhci/pci-sdhci.c b/system/dev/block/pci-sdhci/pci-sdhci.c
index eb12f3d..be43a3e 100644
--- a/system/dev/block/pci-sdhci/pci-sdhci.c
+++ b/system/dev/block/pci-sdhci/pci-sdhci.c
@@ -25,6 +25,7 @@
volatile sdhci_regs_t* regs;
uint64_t regs_size;
zx_handle_t regs_handle;
+ zx_handle_t bti_handle;
} pci_sdhci_device_t;
static zx_status_t pci_sdhci_get_interrupt(void* ctx, zx_handle_t* handle_out) {
@@ -63,6 +64,17 @@
return ZX_OK;
}
+static zx_status_t pci_sdhci_get_bti(void* ctx, uint32_t index, zx_handle_t* out_handle) {
+ pci_sdhci_device_t* dev = ctx;
+ if (dev->bti_handle == ZX_HANDLE_INVALID) {
+ zx_status_t st = pci_get_bti(&dev->pci, index, &dev->bti_handle);
+ if (st != ZX_OK) {
+ return st;
+ }
+ }
+ return zx_handle_duplicate(dev->bti_handle, ZX_RIGHT_SAME_RIGHTS, out_handle);
+}
+
static uint32_t pci_sdhci_get_base_clock(void* ctx) {
return 0;
}
@@ -90,6 +102,7 @@
static sdhci_protocol_ops_t pci_sdhci_sdhci_proto = {
.get_interrupt = pci_sdhci_get_interrupt,
.get_mmio = pci_sdhci_get_mmio,
+ .get_bti = pci_sdhci_get_bti,
.get_base_clock = pci_sdhci_get_base_clock,
.get_quirks = pci_sdhci_get_quirks,
.hw_reset = pci_sdhci_hw_reset,
@@ -105,6 +118,7 @@
if (dev->regs != NULL) {
zx_handle_close(dev->regs_handle);
}
+ zx_handle_close(dev->bti_handle);
free(dev);
}
diff --git a/system/dev/block/sdhci/sdhci.c b/system/dev/block/sdhci/sdhci.c
index 4facdb2..f5ad649 100644
--- a/system/dev/block/sdhci/sdhci.c
+++ b/system/dev/block/sdhci/sdhci.c
@@ -78,6 +78,8 @@
sdhci_protocol_t sdhci;
+ zx_handle_t bti_handle;
+
// DMA descriptors
io_buffer_t iobuf;
sdhci_adma64_desc_t* descs;
@@ -798,6 +800,8 @@
static void sdhci_release(void* ctx) {
sdhci_device_t* dev = ctx;
+ zx_handle_close(dev->irq_handle);
+ zx_handle_close(dev->bti_handle);
free(dev);
}
@@ -832,8 +836,9 @@
// allocate and setup DMA descriptor
if (sdhci_supports_adma2_64bit(dev)) {
- status = io_buffer_init(&dev->iobuf, DMA_DESC_COUNT * sizeof(sdhci_adma64_desc_t),
- IO_BUFFER_RW | IO_BUFFER_CONTIG);
+ status = io_buffer_init_with_bti(&dev->iobuf, dev->bti_handle,
+ DMA_DESC_COUNT * sizeof(sdhci_adma64_desc_t),
+ IO_BUFFER_RW | IO_BUFFER_CONTIG);
if (status != ZX_OK) {
zxlogf(ERROR, "sdhci: error allocating DMA descriptors\n");
goto fail;
@@ -933,6 +938,12 @@
goto fail;
}
+ status = dev->sdhci.ops->get_bti(dev->sdhci.ctx, 0, &dev->bti_handle);
+ if (status != ZX_OK) {
+ zxlogf(ERROR, "sdhci: error %d in get_bti\n", status);
+ goto fail;
+ }
+
status = dev->sdhci.ops->get_interrupt(dev->sdhci.ctx, &dev->irq_handle);
if (status < 0) {
zxlogf(ERROR, "sdhci: error %d in get_interrupt\n", status);
@@ -1010,6 +1021,9 @@
if (dev->irq_handle != ZX_HANDLE_INVALID) {
zx_handle_close(dev->irq_handle);
}
+ if (dev->bti_handle != ZX_HANDLE_INVALID) {
+ zx_handle_close(dev->bti_handle);
+ }
if (dev->iobuf.vmo_handle != ZX_HANDLE_INVALID) {
zx_handle_close(dev->iobuf.vmo_handle);
}
diff --git a/system/ulib/ddk/include/ddk/protocol/sdhci.h b/system/ulib/ddk/include/ddk/protocol/sdhci.h
index e508985..72271e2 100644
--- a/system/ulib/ddk/include/ddk/protocol/sdhci.h
+++ b/system/ulib/ddk/include/ddk/protocol/sdhci.h
@@ -14,6 +14,10 @@
// TODO: should be replaced with a generic busdev mechanism
zx_status_t (*get_interrupt)(void* ctx, zx_handle_t* handle_out);
zx_status_t (*get_mmio)(void* ctx, volatile sdhci_regs_t** out);
+ // Gets a handle to the bus transaction initiator for the device. The caller
+ // receives ownership of the handle.
+ zx_status_t (*get_bti)(void* ctx, uint32_t index, zx_handle_t* out_handle);
+
uint32_t (*get_base_clock)(void* ctx);
// returns device quirks