summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-05-05 15:23:47 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-05-05 15:23:47 +0000
commit121b8fdd65770dd510178c7a6fad088e7e7b71de (patch)
tree3e4b5354ddf93cf1d5471426286a8dac9d95d388 /sys
parent6cd94f10b75222b100778c63c74f4e65cdae907d (diff)
Add glue to attach SDHC compliant controllers using the FDT. This makes
the eMMC controller on the Rockchip RK3399 work.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm64/conf/GENERIC4
-rw-r--r--sys/arch/arm64/conf/RAMDISK4
-rw-r--r--sys/dev/fdt/files.fdt5
-rw-r--r--sys/dev/fdt/sdhc_fdt.c129
4 files changed, 139 insertions, 3 deletions
diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC
index cd410e6fda2..5fac925e354 100644
--- a/sys/arch/arm64/conf/GENERIC
+++ b/sys/arch/arm64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.27 2017/04/30 17:42:32 kettenis Exp $
+# $OpenBSD: GENERIC,v 1.28 2017/05/05 15:23:46 kettenis Exp $
#
# GENERIC machine description file
#
@@ -53,6 +53,8 @@ ahci* at fdt?
ehci* at fdt?
pciecam* at fdt?
pci* at pciecam?
+sdhc* at fdt?
+sdmmc* at sdhc?
xhci* at fdt?
# NS16550 compatible serial ports
diff --git a/sys/arch/arm64/conf/RAMDISK b/sys/arch/arm64/conf/RAMDISK
index ffd35eeae7a..e4a0115604e 100644
--- a/sys/arch/arm64/conf/RAMDISK
+++ b/sys/arch/arm64/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.24 2017/04/30 17:42:32 kettenis Exp $
+# $OpenBSD: RAMDISK,v 1.25 2017/05/05 15:23:46 kettenis Exp $
#
# GENERIC machine description file
#
@@ -63,6 +63,8 @@ ahci* at fdt?
ehci* at fdt?
pciecam* at fdt?
pci* at pciecam?
+sdhc* at fdt?
+sdmmc* at sdhc?
xhci* at fdt?
# NS16550 compatible serial ports
diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt
index 67e60350d6c..41960672874 100644
--- a/sys/dev/fdt/files.fdt
+++ b/sys/dev/fdt/files.fdt
@@ -1,4 +1,4 @@
-# $OpenBSD: files.fdt,v 1.12 2017/04/30 17:42:32 kettenis Exp $
+# $OpenBSD: files.fdt,v 1.13 2017/05/05 15:23:46 kettenis Exp $
#
# Config file and device description for machine-independent FDT code.
# Included by ports that need it.
@@ -51,6 +51,9 @@ file dev/fdt/ahci_fdt.c ahci_fdt
attach ehci at fdt with ehci_fdt
file dev/fdt/ehci_fdt.c ehci_fdt
+attach sdhc at fdt with sdhc_fdt
+file dev/fdt/sdhc_fdt.c sdhc_fdt
+
attach xhci at fdt with xhci_fdt
file dev/fdt/xhci_fdt.c xhci_fdt
diff --git a/sys/dev/fdt/sdhc_fdt.c b/sys/dev/fdt/sdhc_fdt.c
new file mode 100644
index 00000000000..ca018475056
--- /dev/null
+++ b/sys/dev/fdt/sdhc_fdt.c
@@ -0,0 +1,129 @@
+/* $OpenBSD: sdhc_fdt.c,v 1.1 2017/05/05 15:23:46 kettenis Exp $ */
+/*
+ * Copyright (c) 2017 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_clock.h>
+#include <dev/ofw/fdt.h>
+
+#include <dev/sdmmc/sdhcreg.h>
+#include <dev/sdmmc/sdhcvar.h>
+#include <dev/sdmmc/sdmmcvar.h>
+
+struct sdhc_fdt_softc {
+ struct sdhc_softc sc;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ bus_size_t sc_size;
+ void *sc_ih;
+
+ struct sdhc_host *sc_host;
+};
+
+int sdhc_fdt_match(struct device *, void *, void *);
+void sdhc_fdt_attach(struct device *, struct device *, void *);
+
+struct cfattach sdhc_fdt_ca = {
+ sizeof(struct sdhc_fdt_softc), sdhc_fdt_match, sdhc_fdt_attach
+};
+
+int sdhc_fdt_signal_voltage(struct sdhc_softc *, int);
+
+int
+sdhc_fdt_match(struct device *parent, void *match, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+
+ return OF_is_compatible(faa->fa_node, "arasan,sdhci-5.1");
+}
+
+void
+sdhc_fdt_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct sdhc_fdt_softc *sc = (struct sdhc_fdt_softc *)self;
+ struct fdt_attach_args *faa = aux;
+
+ if (faa->fa_nreg < 1) {
+ printf(": no registers\n");
+ return;
+ }
+
+ sc->sc_iot = faa->fa_iot;
+ sc->sc_size = faa->fa_reg[0].size;
+
+ if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
+ faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
+ printf(": can't map registers\n");
+ return;
+ }
+
+ clock_enable_all(faa->fa_node);
+
+ sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_BIO,
+ sdhc_intr, sc, sc->sc.sc_dev.dv_xname);
+ if (sc->sc_ih == NULL) {
+ printf(": can't establish interrupt\n");
+ goto unmap;
+ }
+
+ printf("\n");
+
+ sc->sc.sc_host = &sc->sc_host;
+ sc->sc.sc_dmat = faa->fa_dmat;
+
+ /*
+ * Arasan controller always uses 1.8V and doesn't like an
+ * explicit switch.
+ *
+ */
+ if (OF_is_compatible(faa->fa_node, "arasan,shdc-5,1"))
+ sc->sc.sc_signal_voltage = sdhc_fdt_signal_voltage;
+
+ /*
+ * Rockchip RK3399 PHY doesn't like being powered down at low
+ * clock speeds.
+ */
+ if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-sdhci-5.1"))
+ sc->sc.sc_flags |= SDHC_F_NOPWR0;
+
+ /* XXX Doesn't work on Rockchip RK3399. */
+ sc->sc.sc_flags |= SDHC_F_NODDR50;
+
+ sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh, sc->sc_size, 1, 0);
+ return;
+
+unmap:
+ bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
+}
+
+int
+sdhc_fdt_signal_voltage(struct sdhc_softc *sc, int signal_voltage)
+{
+ switch (signal_voltage) {
+ case SDMMC_SIGNAL_VOLTAGE_180:
+ return 0;
+ default:
+ return EINVAL;
+ }
+}