[vim3][sdio] Enable SDIO on vim3
Bug: None
Test: Saw SDIO probe message with manufacturer/product IDs
Test: device-enumeration-test
Change-Id: Icc832acbc4121c52c5d07751e89bd2b17afb70ae
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/402564
Testability-Review: Braden Kell <bradenkell@google.com>
Commit-Queue: Braden Kell <bradenkell@google.com>
Reviewed-by: Eric Holland <hollande@google.com>
Reviewed-by: Carl Norum <cjn@google.com>
diff --git a/src/devices/board/drivers/vim3/BUILD.gn b/src/devices/board/drivers/vim3/BUILD.gn
index 4929d94..4a36d02 100644
--- a/src/devices/board/drivers/vim3/BUILD.gn
+++ b/src/devices/board/drivers/vim3/BUILD.gn
@@ -19,6 +19,7 @@
"vim3-gpio.cc",
"vim3-i2c.cc",
"vim3-sd.cc",
+ "vim3-sdio.cc",
"vim3-sysmem.cc",
"vim3.cc",
]
diff --git a/src/devices/board/drivers/vim3/vim3-gpio.cc b/src/devices/board/drivers/vim3/vim3-gpio.cc
index c0fb519..8ce61ac 100644
--- a/src/devices/board/drivers/vim3/vim3-gpio.cc
+++ b/src/devices/board/drivers/vim3/vim3-gpio.cc
@@ -68,9 +68,10 @@
// GPIOs to expose from generic GPIO driver.
static const gpio_pin_t gpio_pins[] = {
- {VIM3_J4_PIN_39},
- {VIM3_ETH_MAC_INTR},
- {A311D_GPIOBOOT(12)},
+ {VIM3_J4_PIN_39},
+ {VIM3_ETH_MAC_INTR},
+ {A311D_GPIOBOOT(12)},
+ {A311D_GPIOX(6)},
};
static const pbus_metadata_t gpio_metadata[] = {
diff --git a/src/devices/board/drivers/vim3/vim3-sdio.cc b/src/devices/board/drivers/vim3/vim3-sdio.cc
new file mode 100644
index 0000000..8fea1ac
--- /dev/null
+++ b/src/devices/board/drivers/vim3/vim3-sdio.cc
@@ -0,0 +1,103 @@
+// Copyright 2020 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.
+
+#include <ddk/binding.h>
+#include <ddk/debug.h>
+#include <ddk/metadata.h>
+#include <ddk/platform-defs.h>
+#include <ddk/protocol/sdmmc.h>
+#include <soc/aml-a311d/a311d-gpio.h>
+#include <soc/aml-a311d/a311d-hw.h>
+#include <soc/aml-common/aml-sd-emmc.h>
+
+#include "vim3.h"
+
+namespace vim3 {
+
+static const pbus_mmio_t sdio_mmios[] = {
+ {
+ .base = A311D_EMMC_A_BASE,
+ .length = A311D_EMMC_A_LENGTH,
+ },
+};
+
+static const pbus_irq_t sdio_irqs[] = {
+ {
+ .irq = A311D_SD_EMMC_A_IRQ,
+ .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+ },
+};
+
+static const pbus_bti_t sdio_btis[] = {
+ {
+ .iommu_index = 0,
+ .bti_id = BTI_SDIO,
+ },
+};
+
+static aml_sd_emmc_config_t config = {
+ .supports_dma = true,
+ .min_freq = 400'000,
+ .max_freq = 200'000'000,
+ .version_3 = true,
+ .prefs = 0,
+};
+
+static const pbus_metadata_t sdio_metadata[] = {
+ {
+ .type = DEVICE_METADATA_EMMC_CONFIG,
+ .data_buffer = &config,
+ .data_size = sizeof(config),
+ },
+};
+
+static const zx_bind_inst_t root_match[] = {
+ BI_MATCH(),
+};
+static const zx_bind_inst_t wifi_pwren_gpio_match[] = {
+ BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_GPIO),
+ BI_MATCH_IF(EQ, BIND_GPIO_PIN, A311D_GPIOX(6)),
+};
+static const device_fragment_part_t wifi_pwren_gpio_fragment[] = {
+ {std::size(root_match), root_match},
+ {std::size(wifi_pwren_gpio_match), wifi_pwren_gpio_match},
+};
+static const device_fragment_t sdio_fragments[] = {
+ {std::size(wifi_pwren_gpio_fragment), wifi_pwren_gpio_fragment},
+};
+
+zx_status_t Vim3::SdioInit() {
+ zx_status_t status;
+
+ pbus_dev_t sdio_dev = {};
+ sdio_dev.name = "aml_sdio";
+ sdio_dev.vid = PDEV_VID_AMLOGIC;
+ sdio_dev.pid = PDEV_PID_GENERIC;
+ sdio_dev.did = PDEV_DID_AMLOGIC_SD_EMMC_A;
+ sdio_dev.mmio_list = sdio_mmios;
+ sdio_dev.mmio_count = countof(sdio_mmios);
+ sdio_dev.irq_list = sdio_irqs;
+ sdio_dev.irq_count = countof(sdio_irqs);
+ sdio_dev.bti_list = sdio_btis;
+ sdio_dev.bti_count = countof(sdio_btis);
+ sdio_dev.metadata_list = sdio_metadata;
+ sdio_dev.metadata_count = countof(sdio_metadata);
+
+ gpio_impl_.SetAltFunction(A311D_GPIOX(0), A311D_GPIOX_0_SDIO_D0_FN);
+ gpio_impl_.SetAltFunction(A311D_GPIOX(1), A311D_GPIOX_1_SDIO_D1_FN);
+ gpio_impl_.SetAltFunction(A311D_GPIOX(2), A311D_GPIOX_2_SDIO_D2_FN);
+ gpio_impl_.SetAltFunction(A311D_GPIOX(3), A311D_GPIOX_3_SDIO_D3_FN);
+ gpio_impl_.SetAltFunction(A311D_GPIOX(4), A311D_GPIOX_4_SDIO_CLK_FN);
+ gpio_impl_.SetAltFunction(A311D_GPIOX(5), A311D_GPIOX_5_SDIO_CMD_FN);
+
+ if ((status = pbus_.CompositeDeviceAdd(&sdio_dev, sdio_fragments, countof(sdio_fragments),
+ UINT32_MAX)) != ZX_OK) {
+ zxlogf(ERROR, "SdInit could not add sdio_dev: %d", status);
+ return status;
+ }
+
+ return ZX_OK;
+}
+
+} // namespace vim3
diff --git a/src/devices/board/drivers/vim3/vim3.cc b/src/devices/board/drivers/vim3/vim3.cc
index 0d5c05b..afc122c 100644
--- a/src/devices/board/drivers/vim3/vim3.cc
+++ b/src/devices/board/drivers/vim3/vim3.cc
@@ -94,6 +94,11 @@
init_txn_->Reply(ZX_ERR_INTERNAL);
return status;
}
+ if ((status = SdioInit()) != ZX_OK) {
+ zxlogf(ERROR, "SdioInit() failed: %d\n", status);
+ init_txn_->Reply(ZX_ERR_INTERNAL);
+ return status;
+ }
init_txn_->Reply(status);
return ZX_OK;
}
diff --git a/src/devices/board/drivers/vim3/vim3.h b/src/devices/board/drivers/vim3/vim3.h
index 74b5aca..c0bb528 100644
--- a/src/devices/board/drivers/vim3/vim3.h
+++ b/src/devices/board/drivers/vim3/vim3.h
@@ -25,6 +25,7 @@
BTI_EMMC,
BTI_ETHERNET,
BTI_SD,
+ BTI_SDIO,
BTI_SYSMEM,
};
@@ -52,6 +53,7 @@
zx_status_t GpioInit();
zx_status_t I2cInit();
zx_status_t SdInit();
+ zx_status_t SdioInit();
zx_status_t Start();
zx_status_t SysmemInit();
diff --git a/src/devices/lib/amlogic/include/soc/aml-a311d/a311d-gpio.h b/src/devices/lib/amlogic/include/soc/aml-a311d/a311d-gpio.h
index 0e50a65..2e47121 100644
--- a/src/devices/lib/amlogic/include/soc/aml-a311d/a311d-gpio.h
+++ b/src/devices/lib/amlogic/include/soc/aml-a311d/a311d-gpio.h
@@ -75,6 +75,14 @@
#define A311D_GPIOC_4_SDCARD_CLK_FN 1
#define A311D_GPIOC_5_SDCARD_CMD_FN 1
+// GPIOC pin alternate functions
+#define A311D_GPIOX_0_SDIO_D0_FN 1
+#define A311D_GPIOX_1_SDIO_D1_FN 1
+#define A311D_GPIOX_2_SDIO_D2_FN 1
+#define A311D_GPIOX_3_SDIO_D3_FN 1
+#define A311D_GPIOX_4_SDIO_CLK_FN 1
+#define A311D_GPIOX_5_SDIO_CMD_FN 1
+
// GPIOZ pin alternate functions
#define A311D_GPIOZ_0_ETH_MDIO_FN 1
#define A311D_GPIOZ_1_ETH_MDC_FN 1
diff --git a/zircon/system/utest/device-enumeration/main.cc b/zircon/system/utest/device-enumeration/main.cc
index 307a0c1..79a401e 100644
--- a/zircon/system/utest/device-enumeration/main.cc
+++ b/zircon/system/utest/device-enumeration/main.cc
@@ -204,6 +204,8 @@
"dwmac/eth_phy/phy_null_device",
"dwmac/Designware MAC/ethernet",
"aml_sd/aml-sd-emmc",
+ "aml_sdio/aml-sd-emmc/sdmmc/sdmmc-sdio/sdmmc-sdio-1",
+ "aml_sdio/aml-sd-emmc/sdmmc/sdmmc-sdio/sdmmc-sdio-2",
};
ASSERT_NO_FATAL_FAILURES(TestRunner(kDevicePaths, std::size(kDevicePaths)));