From: patrick Date: Tue, 18 Jan 2022 11:36:21 +0000 (+0000) Subject: Improve how quirks are handled on sdhc(4)-compatible drivers. So far X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=bfa5fdb5f0a76cb47f36d53ec1ef502ba9eb90ce;p=openbsd Improve how quirks are handled on sdhc(4)-compatible drivers. So far we have passed a modified version of the contents in the capabilities register if we wanted to override what sdhc(4) would otherwise read. Unfortunately there's a second capabilities register that we did not yet take into consideration, which is why to disable DDR50 support we created a quirk flag in the softc. The sdhc(4) ACPI nodes have a way to mask and set bits in both of the capabilities register, which is a flexible approach to solving that issue and using that for our sdhc(4) drivers even improves readability. ok kettenis@ --- diff --git a/sys/arch/armv7/marvell/mvpxa.c b/sys/arch/armv7/marvell/mvpxa.c index 27aaef3a4cb..aaa2b939a06 100644 --- a/sys/arch/armv7/marvell/mvpxa.c +++ b/sys/arch/armv7/marvell/mvpxa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mvpxa.c,v 1.3 2021/10/24 17:52:27 mpi Exp $ */ +/* $OpenBSD: mvpxa.c,v 1.4 2022/01/18 11:36:21 patrick Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * Copyright (c) 2017 Patrick Wildt @@ -111,7 +111,7 @@ mvpxa_attach(struct device *parent, struct device *self, void *aux) { struct mvpxa_softc *sc = (struct mvpxa_softc *)self; struct fdt_attach_args *faa = aux; - uint32_t caps; + uint64_t capmask = 0, capset = 0; if (faa->fa_nreg < 3) { printf(": not enough registers\n"); @@ -162,11 +162,11 @@ mvpxa_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_host = &sc->sc_host; sc->sc.sc_dmat = faa->fa_dmat; - caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SDHC_CAPABILITIES); if (OF_getproplen(faa->fa_node, "no-1-8-v") >= 0) - caps &= ~SDHC_VOLTAGE_SUPP_1_8V; + capmask |= SDHC_VOLTAGE_SUPP_1_8V; - sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh, sc->sc_size, 1, caps); + sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh, sc->sc_size, 1, + capmask, capset); return; unmap: diff --git a/sys/dev/acpi/sdhc_acpi.c b/sys/dev/acpi/sdhc_acpi.c index 0e3a633fa2b..17931f04ee7 100644 --- a/sys/dev/acpi/sdhc_acpi.c +++ b/sys/dev/acpi/sdhc_acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sdhc_acpi.c,v 1.19 2021/12/21 20:53:46 kettenis Exp $ */ +/* $OpenBSD: sdhc_acpi.c,v 1.20 2022/01/18 11:36:21 patrick Exp $ */ /* * Copyright (c) 2016 Mark Kettenis * @@ -88,7 +88,7 @@ sdhc_acpi_attach(struct device *parent, struct device *self, void *aux) struct sdhc_acpi_softc *sc = (struct sdhc_acpi_softc *)self; struct acpi_attach_args *aaa = aux; struct aml_value res; - uint32_t cap, capmask; + uint64_t capmask, capset; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_node = aaa->aaa_node; @@ -135,13 +135,8 @@ sdhc_acpi_attach(struct device *parent, struct device *self, void *aux) sdhc_acpi_power_on(sc, sc->sc_node); sdhc_acpi_explore(sc); - cap = acpi_getpropint(sc->sc_node, "sdhci-caps", 0); capmask = acpi_getpropint(sc->sc_node, "sdhci-caps-mask", 0); - if (capmask != 0) { - cap = bus_space_read_4(sc->sc_memt, sc->sc_memh, - SDHC_CAPABILITIES); - cap &= ~capmask; - } + capset = acpi_getpropint(sc->sc_node, "sdhci-caps", 0); /* Raspberry Pi4 "emmc2" controller. */ if (strcmp(aaa->aaa_dev, "BRCME88C") == 0) @@ -152,7 +147,7 @@ sdhc_acpi_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_clkbase = acpi_getpropint(sc->sc_node, "clock-frequency", 0) / 1000; sdhc_host_found(&sc->sc, sc->sc_memt, sc->sc_memh, - aaa->aaa_size[0], 1, cap); + aaa->aaa_size[0], 1, capmask, capset); } int diff --git a/sys/dev/fdt/cdsdhc.c b/sys/dev/fdt/cdsdhc.c index df3b760b43b..6c31225a935 100644 --- a/sys/dev/fdt/cdsdhc.c +++ b/sys/dev/fdt/cdsdhc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cdsdhc.c,v 1.1 2022/01/18 07:53:39 visa Exp $ */ +/* $OpenBSD: cdsdhc.c,v 1.2 2022/01/18 11:36:21 patrick Exp $ */ /* * Copyright (c) 2022 Visa Hankala @@ -97,7 +97,7 @@ cdsdhc_attach(struct device *parent, struct device *self, void *aux) { struct fdt_attach_args *faa = aux; struct cdsdhc_softc *sc = (struct cdsdhc_softc *)self; - uint32_t caps = 0; + uint64_t capmask = 0, capset = 0; uint32_t ver; sc->sc_iot = faa->fa_iot; @@ -131,7 +131,7 @@ cdsdhc_attach(struct device *parent, struct device *self, void *aux) sc->sc_sdhc.sc_dmat = faa->fa_dmat; sc->sc_sdhc.sc_bus_clock_pre = cdsdhc_bus_clock_pre; sdhc_host_found(&sc->sc_sdhc, sc->sc_iot, sc->sc_srs_ioh, SRS_SIZE, - 1, caps); + 1, capmask, capset); return; disable: diff --git a/sys/dev/fdt/sdhc_fdt.c b/sys/dev/fdt/sdhc_fdt.c index 2ca87570633..67b4015b0e1 100644 --- a/sys/dev/fdt/sdhc_fdt.c +++ b/sys/dev/fdt/sdhc_fdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sdhc_fdt.c,v 1.18 2021/10/24 17:52:27 mpi Exp $ */ +/* $OpenBSD: sdhc_fdt.c,v 1.19 2022/01/18 11:36:21 patrick Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -140,7 +140,8 @@ 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; struct regmap *rm = NULL; - uint32_t reg, phandle, freq, cap = 0; + uint64_t capmask = 0, capset = 0; + uint32_t reg, phandle, freq; char pad_type[16] = { 0 }; if (faa->fa_nreg < 1) { @@ -230,7 +231,7 @@ sdhc_fdt_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_flags |= SDHC_F_NOPWR0; /* XXX Doesn't work on Rockchip RK3399. */ - sc->sc.sc_flags |= SDHC_F_NODDR50; + capmask |= (uint64_t)SDHC_DDR50_SUPP << 32; } if (OF_is_compatible(faa->fa_node, "arasan,sdhci-8.9a")) { @@ -242,8 +243,9 @@ sdhc_fdt_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_flags |= SDHC_F_NOPWR0; if (OF_is_compatible(faa->fa_node, "brcm,bcm2835-sdhci")) { - cap = SDHC_VOLTAGE_SUPP_3_3V | SDHC_HIGH_SPEED_SUPP; - cap |= SDHC_MAX_BLK_LEN_1024 << SDHC_MAX_BLK_LEN_SHIFT; + capmask = 0xffffffff; + capset = SDHC_VOLTAGE_SUPP_3_3V | SDHC_HIGH_SPEED_SUPP; + capset |= SDHC_MAX_BLK_LEN_1024 << SDHC_MAX_BLK_LEN_SHIFT; freq = clock_get_frequency(faa->fa_node, NULL); sc->sc.sc_clkbase = freq / 1000; @@ -278,13 +280,11 @@ sdhc_fdt_attach(struct device *parent, struct device *self, void *aux) } } - cap = bus_space_read_4(sc->sc_iot, sc->sc_ioh, - SDHC_CAPABILITIES); if (OF_getpropint(faa->fa_node, "bus-width", 1) != 8) - cap &= ~SDHC_8BIT_MODE_SUPP; + capmask |= SDHC_8BIT_MODE_SUPP; if (OF_getproplen(faa->fa_node, "no-1-8-v") == 0) { - cap &= ~SDHC_VOLTAGE_SUPP_1_8V; - sc->sc.sc_flags |= SDHC_F_NODDR50; + capmask |= SDHC_VOLTAGE_SUPP_1_8V; + capmask |= (uint64_t)SDHC_DDR50_SUPP << 32; } if (OF_getproplen(faa->fa_node, "marvell,xenon-phy-slow-mode") == 0) @@ -318,7 +318,8 @@ sdhc_fdt_attach(struct device *parent, struct device *self, void *aux) sc->sc.sc_bus_clock_post = sdhc_fdt_xenon_bus_clock_post; } - sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh, sc->sc_size, 1, cap); + sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh, sc->sc_size, 1, + capmask, capset); return; unmap: diff --git a/sys/dev/pci/sdhc_pci.c b/sys/dev/pci/sdhc_pci.c index 7d838362762..de582ccd79a 100644 --- a/sys/dev/pci/sdhc_pci.c +++ b/sys/dev/pci/sdhc_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sdhc_pci.c,v 1.22 2022/01/11 21:41:15 jsg Exp $ */ +/* $OpenBSD: sdhc_pci.c,v 1.23 2022/01/18 11:36:21 patrick Exp $ */ /* * Copyright (c) 2006 Uwe Stuehler @@ -110,7 +110,6 @@ sdhc_pci_attach(struct device *parent, struct device *self, void *aux) bus_space_tag_t iot; bus_space_handle_t ioh; bus_size_t size; - u_int32_t caps = 0; sc->sc_pc = pa->pa_pc; sc->sc_tag = pa->pa_tag; @@ -183,7 +182,7 @@ sdhc_pci_attach(struct device *parent, struct device *self, void *aux) break; } - if (sdhc_host_found(&sc->sc, iot, ioh, size, usedma, caps) != 0) + if (sdhc_host_found(&sc->sc, iot, ioh, size, usedma, 0, 0) != 0) printf("%s at 0x%x: can't initialize host\n", sc->sc.sc_dev.dv_xname, reg); diff --git a/sys/dev/sdmmc/sdhc.c b/sys/dev/sdmmc/sdhc.c index 6e6847b07ac..46c2ab4153f 100644 --- a/sys/dev/sdmmc/sdhc.c +++ b/sys/dev/sdmmc/sdhc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sdhc.c,v 1.71 2021/09/11 22:42:12 mglocker Exp $ */ +/* $OpenBSD: sdhc.c,v 1.72 2022/01/18 11:36:21 patrick Exp $ */ /* * Copyright (c) 2006 Uwe Stuehler @@ -238,10 +238,12 @@ sdhc_write_2(struct sdhc_host *hp, bus_size_t offset, uint16_t value) */ int sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, - bus_space_handle_t ioh, bus_size_t iosize, int usedma, u_int32_t caps) + bus_space_handle_t ioh, bus_size_t iosize, int usedma, uint64_t capmask, + uint64_t capset) { struct sdmmcbus_attach_args saa; struct sdhc_host *hp; + uint32_t caps; int error = 1; int max_clock; @@ -267,8 +269,9 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, (void)sdhc_host_reset(hp); /* Determine host capabilities. */ - if (caps == 0) - caps = HREAD4(hp, SDHC_CAPABILITIES); + caps = HREAD4(hp, SDHC_CAPABILITIES); + caps &= ~capmask; + caps |= capset; /* Use DMA if the host system and the controller support it. */ if (usedma && ISSET(caps, SDHC_ADMA2_SUPP)) { @@ -404,6 +407,8 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3) { uint32_t caps2 = HREAD4(hp, SDHC_CAPABILITIES2); + caps2 &= ~(capmask >> 32); + caps2 |= capset >> 32; if (ISSET(caps, SDHC_8BIT_MODE_SUPP)) saa.caps |= SMC_CAPS_8BIT_MODE; @@ -412,9 +417,6 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, saa.caps |= SMC_CAPS_MMC_DDR52; } - if (ISSET(sc->sc_flags, SDHC_F_NODDR50)) - saa.caps &= ~SMC_CAPS_MMC_DDR52; - if (ISSET(sc->sc_flags, SDHC_F_NONREMOVABLE)) saa.caps |= SMC_CAPS_NONREMOVABLE; diff --git a/sys/dev/sdmmc/sdhcvar.h b/sys/dev/sdmmc/sdhcvar.h index 831ac2e9111..fd964167f11 100644 --- a/sys/dev/sdmmc/sdhcvar.h +++ b/sys/dev/sdmmc/sdhcvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sdhcvar.h,v 1.15 2021/09/11 22:42:12 mglocker Exp $ */ +/* $OpenBSD: sdhcvar.h,v 1.16 2022/01/18 11:36:21 patrick Exp $ */ /* * Copyright (c) 2006 Uwe Stuehler @@ -40,7 +40,7 @@ struct sdhc_softc { /* Host controller functions called by the attachment driver. */ int sdhc_host_found(struct sdhc_softc *, bus_space_tag_t, - bus_space_handle_t, bus_size_t, int, u_int32_t); + bus_space_handle_t, bus_size_t, int, uint64_t, uint64_t); int sdhc_activate(struct device *, int); void sdhc_shutdown(void *); int sdhc_intr(void *); @@ -49,9 +49,8 @@ void sdhc_needs_discover(struct sdhc_softc *); /* flag values */ #define SDHC_F_NOPWR0 (1 << 0) -#define SDHC_F_NODDR50 (1 << 1) -#define SDHC_F_NONREMOVABLE (1 << 2) -#define SDHC_F_32BIT_ACCESS (1 << 3) -#define SDHC_F_NO_HS_BIT (1 << 4) +#define SDHC_F_NONREMOVABLE (1 << 1) +#define SDHC_F_32BIT_ACCESS (1 << 2) +#define SDHC_F_NO_HS_BIT (1 << 3) #endif