From nobody Thu Feb 02 06:46:57 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4P6q8K3DClz3c3FY; Thu, 2 Feb 2023 06:46:57 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4P6q8K2Tqcz4Kbq; Thu, 2 Feb 2023 06:46:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675320417; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HEqw/JHfJII2TQRv9nXnPK1RYnUP8FO6kiLY9vqm/5g=; b=jNBXvJgGQG6518BlD1dTQoVZTW4PvxdriHftCRs4gHfYJfaYGPU+uAulSBNLugeKuPmtgK m3BE05umK4dE73p7ngCmrMGkfKMqNWa8M44MKw4smcLAJTrzqNvPZprkgbL0Ou0PSDxe7X 9HQlhkAhokQAGh3fqeNr+/kNd+4+RWaYf3LMFzRUaN/bNNKE2joBr2hArRJS6CZk4mWijP /3TMI2mbvVusTnsUpS1Sy4lE3rkcsgHQs42H9YdMGALbgYE5uznbPRe2O3OWdeJCyDlbDi fnPK9ufV4LYCi2MSPEP55QkirCqcXhfsZhbfa1sVsdEfLycxfeZOS2kCtfccGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675320417; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HEqw/JHfJII2TQRv9nXnPK1RYnUP8FO6kiLY9vqm/5g=; b=VWnavkB3ZVQVvVpO4Uz6J0sONhbPGk68KCfaAMwJlnONkX+bu0lPku0fZuwvTzmcHsuGW0 LD1QYAbLGMPXN3HBThsnncchlvMiKMrkLvV/PTiP7mEZtbIlK75MsNfei0L4pq0/GPY78l 1/W5WWaA/u8lNz8QhPUDHL2gGWkxWFVi1vJIEWiNLxB5iFeXk770uhj+TcVhZHPozKN0my Pce3RqkqFW08b85S9ZxSsTURL/gK92o5H9LZCn8dKjR7vcmIsNqgf9uoJ/oun9vdpnAGh4 eMdNrrEBRBpmvA5hCJ8lijWy1GdV3i13OMNDsM1ocuPwC7ztvCg7XVQlbppRdw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1675320417; a=rsa-sha256; cv=none; b=PcQoHNUn98vXMmB4uisskUpq4wyXrePV0gfVMXLdV1KaU9vztun0OlnTnc9e0rQ8zawex9 vO7DR4mLmSKr8Zq/JEb4p0yGdPpPVx6KfmmmUXtEw5HiTgMB20B9GYx2ywhx8pjALpiVPZ sC/AgRi57yghr4/rsLMMkEZdEOEGsXYEwosPOaqVqMSC2jjdR5SD9FRzHk+Tx97ODGXsVm /eQu4H0HyDI8OwPFM6iBNvH5dYcWGxESP6PL03Jd6X6CeDGrNJwdJFK4lIrPpp4v2b3DQW YB7aURzyK2Xp/i2WM1ctequnYTQFveubsIV92R01I1HkN9O0vNKioAS/pJTvfQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4P6q8K1YvtzlBh; Thu, 2 Feb 2023 06:46:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 3126kvGJ089643; Thu, 2 Feb 2023 06:46:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 3126kv27089642; Thu, 2 Feb 2023 06:46:57 GMT (envelope-from git) Date: Thu, 2 Feb 2023 06:46:57 GMT Message-Id: <202302020646.3126kv27089642@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Emmanuel Vadot Subject: git: a540d9f2d4c8 - stable/13 - arm64: rockchip: rk_gpio: Improve mode switching List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: manu X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: a540d9f2d4c8bee3074f4f35c679d564a44ecc11 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by manu: URL: https://cgit.FreeBSD.org/src/commit/?id=a540d9f2d4c8bee3074f4f35c679d564a44ecc11 commit a540d9f2d4c8bee3074f4f35c679d564a44ecc11 Author: Emmanuel Vadot AuthorDate: 2021-09-22 14:55:54 +0000 Commit: Emmanuel Vadot CommitDate: 2023-02-02 06:38:07 +0000 arm64: rockchip: rk_gpio: Improve mode switching Changing mode on a pin (input/output/pullup/pulldown) is a bit slow. Improve this by caching what we can. We need to check if the pin is in gpio mode, do that the first time that we have a request for this pin and cache the result. We can't do that at attach as we are a child of rk_pinctrl and it didn't finished its attach then. Cache also the flags specific to the pinctrl (pullup or pulldown) if the pin is in input mode. Cache the registers that deals with input/output mode and output value. Also remove some register reads when we change the direction of a pin or when we change the output value since the bit changed in the registers only affect output pins. (cherry picked from commit 87f642ac03e3cefea7048cb46b17810d01e97dd5) --- sys/arm64/rockchip/rk_gpio.c | 94 ++++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 39 deletions(-) diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c index d3623b2302ec..564059fe5d23 100644 --- a/sys/arm64/rockchip/rk_gpio.c +++ b/sys/arm64/rockchip/rk_gpio.c @@ -73,6 +73,14 @@ __FBSDID("$FreeBSD$"); #define RK_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) +#define GPIO_FLAGS_PINCTRL GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN +#define RK_GPIO_MAX_PINS 32 + +struct pin_cached { + uint8_t is_gpio; + uint32_t flags; +}; + struct rk_gpio_softc { device_t sc_dev; device_t sc_busdev; @@ -82,6 +90,9 @@ struct rk_gpio_softc { bus_space_handle_t sc_bsh; clk_t clk; device_t pinctrl; + uint32_t swporta; + uint32_t swporta_ddr; + struct pin_cached pin_cached[RK_GPIO_MAX_PINS]; }; static struct ofw_compat_data compat_data[] = { @@ -125,7 +136,7 @@ rk_gpio_attach(device_t dev) { struct rk_gpio_softc *sc; phandle_t node; - int err; + int err, i; sc = device_get_softc(dev); sc->sc_dev = dev; @@ -166,6 +177,15 @@ rk_gpio_attach(device_t dev) return (ENXIO); } + /* Set the cached value to unknown */ + for (i = 0; i < RK_GPIO_MAX_PINS; i++) + sc->pin_cached[i].is_gpio = 2; + + RK_GPIO_LOCK(sc); + sc->swporta = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR); + sc->swporta_ddr = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); + RK_GPIO_UNLOCK(sc); + return (0); } @@ -229,28 +249,25 @@ static int rk_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) { struct rk_gpio_softc *sc; - uint32_t reg; int rv; - bool is_gpio; sc = device_get_softc(dev); - rv = FDT_PINCTRL_IS_GPIO(sc->pinctrl, dev, pin, &is_gpio); - if (rv != 0) - return (rv); - if (!is_gpio) - return (EINVAL); + if (__predict_false(sc->pin_cached[pin].is_gpio != 1)) { + rv = FDT_PINCTRL_IS_GPIO(sc->pinctrl, dev, pin, (bool *)&sc->pin_cached[pin].is_gpio); + if (rv != 0) + return (rv); + if (sc->pin_cached[pin].is_gpio == 0) + return (EINVAL); + } *flags = 0; rv = FDT_PINCTRL_GET_FLAGS(sc->pinctrl, dev, pin, flags); if (rv != 0) return (rv); + sc->pin_cached[pin].flags = *flags; - RK_GPIO_LOCK(sc); - reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); - RK_GPIO_UNLOCK(sc); - - if (reg & (1 << pin)) + if (sc->swporta_ddr & (1 << pin)) *flags |= GPIO_PIN_OUTPUT; else *flags |= GPIO_PIN_INPUT; @@ -270,31 +287,32 @@ static int rk_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) { struct rk_gpio_softc *sc; - uint32_t reg; int rv; - bool is_gpio; sc = device_get_softc(dev); - rv = FDT_PINCTRL_IS_GPIO(sc->pinctrl, dev, pin, &is_gpio); - if (rv != 0) - return (rv); - if (!is_gpio) - return (EINVAL); + if (__predict_false(sc->pin_cached[pin].is_gpio != 1)) { + rv = FDT_PINCTRL_IS_GPIO(sc->pinctrl, dev, pin, (bool *)&sc->pin_cached[pin].is_gpio); + if (rv != 0) + return (rv); + if (sc->pin_cached[pin].is_gpio == 0) + return (EINVAL); + } - rv = FDT_PINCTRL_SET_FLAGS(sc->pinctrl, dev, pin, flags); - if (rv != 0) - return (rv); + if (__predict_false((flags & GPIO_PIN_INPUT) && ((flags & GPIO_FLAGS_PINCTRL) != sc->pin_cached[pin].flags))) { + rv = FDT_PINCTRL_SET_FLAGS(sc->pinctrl, dev, pin, flags); + sc->pin_cached[pin].flags = flags & GPIO_FLAGS_PINCTRL; + if (rv != 0) + return (rv); + } RK_GPIO_LOCK(sc); - - reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); if (flags & GPIO_PIN_INPUT) - reg &= ~(1 << pin); + sc->swporta_ddr &= ~(1 << pin); else if (flags & GPIO_PIN_OUTPUT) - reg |= (1 << pin); + sc->swporta_ddr |= (1 << pin); - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, reg); + RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, sc->swporta_ddr); RK_GPIO_UNLOCK(sc); return (0); @@ -321,17 +339,15 @@ static int rk_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) { struct rk_gpio_softc *sc; - uint32_t reg; sc = device_get_softc(dev); RK_GPIO_LOCK(sc); - reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR); if (value) - reg |= (1 << pin); + sc->swporta |= (1 << pin); else - reg &= ~(1 << pin); - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, reg); + sc->swporta &= ~(1 << pin); + RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, sc->swporta); RK_GPIO_UNLOCK(sc); return (0); @@ -341,17 +357,15 @@ static int rk_gpio_pin_toggle(device_t dev, uint32_t pin) { struct rk_gpio_softc *sc; - uint32_t reg; sc = device_get_softc(dev); RK_GPIO_LOCK(sc); - reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR); - if (reg & (1 << pin)) - reg &= ~(1 << pin); + if (sc->swporta & (1 << pin)) + sc->swporta &= ~(1 << pin); else - reg |= (1 << pin); - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, reg); + sc->swporta |= (1 << pin); + RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, sc->swporta); RK_GPIO_UNLOCK(sc); return (0); @@ -370,6 +384,7 @@ rk_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR); if (orig_pins) *orig_pins = reg; + sc->swporta = reg; if ((clear_pins | change_pins) != 0) { reg = (reg & ~clear_pins) ^ change_pins; @@ -410,6 +425,7 @@ rk_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, reg &= ~mask; reg |= set; RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, reg); + sc->swporta_ddr = reg; RK_GPIO_UNLOCK(sc); return (0);