From owner-svn-src-head@freebsd.org Tue Apr 14 16:34:14 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 734AA2C465D; Tue, 14 Apr 2020 16:34:14 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491rfZ2XqBz4R8y; Tue, 14 Apr 2020 16:34:14 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4DC108563; Tue, 14 Apr 2020 16:34:14 +0000 (UTC) (envelope-from manu@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03EGYEaJ009596; Tue, 14 Apr 2020 16:34:14 GMT (envelope-from manu@FreeBSD.org) Received: (from manu@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03EGYE0m009595; Tue, 14 Apr 2020 16:34:14 GMT (envelope-from manu@FreeBSD.org) Message-Id: <202004141634.03EGYE0m009595@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: manu set sender to manu@FreeBSD.org using -f From: Emmanuel Vadot Date: Tue, 14 Apr 2020 16:34:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r359925 - head/sys/arm/allwinner X-SVN-Group: head X-SVN-Commit-Author: manu X-SVN-Commit-Paths: head/sys/arm/allwinner X-SVN-Commit-Revision: 359925 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Apr 2020 16:34:14 -0000 Author: manu Date: Tue Apr 14 16:34:13 2020 New Revision: 359925 URL: https://svnweb.freebsd.org/changeset/base/359925 Log: arm: allwinner: aw_mmc: Use the mmc_fdt_helper The fdt properties are now parsed via the help of mmc_fdt_helper functions. This also adds card detection. Note that on some boards (like the Pine64) card detection is broken due to a missing resistor on the cd pin. MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D23268 Modified: head/sys/arm/allwinner/aw_mmc.c Modified: head/sys/arm/allwinner/aw_mmc.c ============================================================================== --- head/sys/arm/allwinner/aw_mmc.c Tue Apr 14 16:30:54 2020 (r359924) +++ head/sys/arm/allwinner/aw_mmc.c Tue Apr 14 16:34:13 2020 (r359925) @@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include @@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -122,6 +125,7 @@ struct aw_mmc_softc { int aw_timeout; struct callout aw_timeoutc; struct mmc_host aw_host; + struct mmc_fdt_helper mmc_helper; #ifdef MMCCAM union ccb * ccb; struct cam_devq * devq; @@ -136,9 +140,8 @@ struct aw_mmc_softc { uint32_t aw_intr; uint32_t aw_intr_wait; void * aw_intrhand; - regulator_t aw_reg_vmmc; - regulator_t aw_reg_vqmmc; unsigned int aw_clock; + device_t child; /* Fields required for DMA access. */ bus_addr_t aw_dma_desc_phys; @@ -164,6 +167,7 @@ static int aw_mmc_reset(struct aw_mmc_softc *); static int aw_mmc_init(struct aw_mmc_softc *); static void aw_mmc_intr(void *); static int aw_mmc_update_clock(struct aw_mmc_softc *, uint32_t); +static void aw_mmc_helper_cd_handler(device_t, bool); static void aw_mmc_print_error(uint32_t); static int aw_mmc_update_ios(device_t, device_t); @@ -360,6 +364,40 @@ aw_mmc_cam_request(struct aw_mmc_softc *sc, union ccb } #endif /* MMCCAM */ +static void +aw_mmc_helper_cd_handler(device_t dev, bool present) +{ + struct aw_mmc_softc *sc; + + sc = device_get_softc(dev); + AW_MMC_LOCK(sc); + if (present) { + if (sc->child == NULL) { + if (bootverbose) + device_printf(sc->aw_dev, "Card inserted\n"); + + sc->child = device_add_child(sc->aw_dev, "mmc", -1); + AW_MMC_UNLOCK(sc); + if (sc->child) { + device_set_ivars(sc->child, sc); + (void)device_probe_and_attach(sc->child); + } + } else + AW_MMC_UNLOCK(sc); + } else { + /* Card isn't present, detach if necessary */ + if (sc->child != NULL) { + if (bootverbose) + device_printf(sc->aw_dev, "Card removed\n"); + + AW_MMC_UNLOCK(sc); + device_delete_child(sc->aw_dev, sc->child); + sc->child = NULL; + } else + AW_MMC_UNLOCK(sc); + } +} + static int aw_mmc_probe(device_t dev) { @@ -377,15 +415,11 @@ aw_mmc_probe(device_t dev) static int aw_mmc_attach(device_t dev) { - device_t child; struct aw_mmc_softc *sc; struct sysctl_ctx_list *ctx; struct sysctl_oid_list *tree; - uint32_t bus_width, max_freq; - phandle_t node; int error; - node = ofw_bus_get_node(dev); sc = device_get_softc(dev); sc->aw_dev = dev; @@ -399,7 +433,7 @@ aw_mmc_attach(device_t dev) return (ENXIO); } if (bus_setup_intr(dev, sc->aw_res[AW_MMC_IRQRES], - INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_mmc_intr, sc, + INTR_TYPE_NET | INTR_MPSAFE, NULL, aw_mmc_intr, sc, &sc->aw_intrhand)) { bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res); device_printf(dev, "cannot setup interrupt handler\n"); @@ -463,47 +497,15 @@ aw_mmc_attach(device_t dev) goto fail; } - if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0) - bus_width = 4; - - if (regulator_get_by_ofw_property(dev, 0, "vmmc-supply", - &sc->aw_reg_vmmc) == 0) { - if (bootverbose) - device_printf(dev, "vmmc-supply regulator found\n"); - } - if (regulator_get_by_ofw_property(dev, 0, "vqmmc-supply", - &sc->aw_reg_vqmmc) == 0 && bootverbose) { - if (bootverbose) - device_printf(dev, "vqmmc-supply regulator found\n"); - } - + /* Set some defaults for freq and supported mode */ sc->aw_host.f_min = 400000; - - if (OF_getencprop(node, "max-frequency", &max_freq, - sizeof(uint32_t)) <= 0) - max_freq = 52000000; - sc->aw_host.f_max = max_freq; - + sc->aw_host.f_max = 52000000; sc->aw_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340; - sc->aw_host.caps = MMC_CAP_HSPEED | MMC_CAP_UHS_SDR12 | - MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | - MMC_CAP_UHS_DDR50 | MMC_CAP_MMC_DDR52; + sc->aw_host.caps |= MMC_CAP_HSPEED | MMC_CAP_SIGNALING_330; + mmc_fdt_parse(dev, 0, &sc->mmc_helper, &sc->aw_host); + mmc_fdt_gpio_setup(dev, 0, &sc->mmc_helper, aw_mmc_helper_cd_handler); - if (sc->aw_reg_vqmmc != NULL) { - if (regulator_check_voltage(sc->aw_reg_vqmmc, 1800000) == 0) - sc->aw_host.caps |= MMC_CAP_SIGNALING_180; - if (regulator_check_voltage(sc->aw_reg_vqmmc, 3300000) == 0) - sc->aw_host.caps |= MMC_CAP_SIGNALING_330; - } else - sc->aw_host.caps |= MMC_CAP_SIGNALING_330; - - if (bus_width >= 4) - sc->aw_host.caps |= MMC_CAP_4_BIT_DATA; - if (bus_width >= 8) - sc->aw_host.caps |= MMC_CAP_8_BIT_DATA; - #ifdef MMCCAM - child = NULL; /* Not used by MMCCAM, need to silence compiler warnings */ sc->ccb = NULL; if ((sc->devq = cam_simq_alloc(1)) == NULL) { goto fail; @@ -530,18 +532,8 @@ aw_mmc_attach(device_t dev) } mtx_unlock(&sc->sim_mtx); -#else /* !MMCCAM */ - child = device_add_child(dev, "mmc", -1); - if (child == NULL) { - device_printf(dev, "attaching MMC bus failed!\n"); - goto fail; - } - if (device_probe_and_attach(child) != 0) { - device_printf(dev, "attaching MMC child failed!\n"); - device_delete_child(dev, child); - goto fail; - } #endif /* MMCCAM */ + return (0); fail: @@ -1301,7 +1293,7 @@ aw_mmc_switch_vccq(device_t bus, device_t child) sc = device_get_softc(bus); - if (sc->aw_reg_vqmmc == NULL) + if (sc->mmc_helper.vqmmc_supply == NULL) return EOPNOTSUPP; switch (sc->aw_host.ios.vccq) { @@ -1315,7 +1307,7 @@ aw_mmc_switch_vccq(device_t bus, device_t child) return EINVAL; } - err = regulator_set_voltage(sc->aw_reg_vqmmc, uvolt, uvolt); + err = regulator_set_voltage(sc->mmc_helper.vqmmc_supply, uvolt, uvolt); if (err != 0) { device_printf(sc->aw_dev, "Cannot set vqmmc to %d<->%d\n", @@ -1360,10 +1352,10 @@ aw_mmc_update_ios(device_t bus, device_t child) if (bootverbose) device_printf(sc->aw_dev, "Powering down sd/mmc\n"); - if (sc->aw_reg_vmmc) - regulator_disable(sc->aw_reg_vmmc); - if (sc->aw_reg_vqmmc) - regulator_disable(sc->aw_reg_vqmmc); + if (sc->mmc_helper.vmmc_supply) + regulator_disable(sc->mmc_helper.vmmc_supply); + if (sc->mmc_helper.vqmmc_supply) + regulator_disable(sc->mmc_helper.vqmmc_supply); aw_mmc_reset(sc); break; @@ -1371,10 +1363,10 @@ aw_mmc_update_ios(device_t bus, device_t child) if (bootverbose) device_printf(sc->aw_dev, "Powering up sd/mmc\n"); - if (sc->aw_reg_vmmc) - regulator_enable(sc->aw_reg_vmmc); - if (sc->aw_reg_vqmmc) - regulator_enable(sc->aw_reg_vqmmc); + if (sc->mmc_helper.vmmc_supply) + regulator_enable(sc->mmc_helper.vmmc_supply); + if (sc->mmc_helper.vqmmc_supply) + regulator_enable(sc->mmc_helper.vqmmc_supply); aw_mmc_init(sc); break; }; @@ -1450,8 +1442,11 @@ aw_mmc_update_ios(device_t bus, device_t child) static int aw_mmc_get_ro(device_t bus, device_t child) { + struct aw_mmc_softc *sc; - return (0); + sc = device_get_softc(bus); + + return (mmc_fdt_gpio_get_readonly(&sc->mmc_helper)); } static int