From nobody Fri Aug 19 13:22:57 2022 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 4M8MrK5Nkgz4Z7P7; Fri, 19 Aug 2022 13:22: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 4M8MrK4knVz46QB; Fri, 19 Aug 2022 13:22:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660915377; 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=Aq1sttdo4j0BX49Px4t41q/58GnQdsRmK+qV1MNbZu4=; b=n/y28AokFy7LIa29BUhsGNXfWyg4+SnP69vJCiozLRzRerQdRO3DRog/SLoKNedwnw2zi3 s2PqAFmzr7SMTV2wFWSZ1zB3wYByFrChL1TCXz6DuZQdrk+6ERG1yjDDC3LgFBb2quwkup 6FmHgfZN3GVV0N5kqzDyExrt3Q2+c9VPKvsBMAFD+wbfegxQdY34t6zZzmTghEuLN3vo55 Ni2JWqN4KkbTIXd6TCebUOoMrP+nSzUpZ3GY+Bs64RL50OkXJbF6Xacpf0w12z3iPzGqwe f2wV131yI0GJ8RjJPxKpx1Ie13iTrpHlMu4m1NECOOQS9VaHgk1MEybf3LMUzA== 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 4M8MrK3nS2ztdB; Fri, 19 Aug 2022 13:22: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 27JDMv7h007433; Fri, 19 Aug 2022 13:22:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 27JDMv0b007432; Fri, 19 Aug 2022 13:22:57 GMT (envelope-from git) Date: Fri, 19 Aug 2022 13:22:57 GMT Message-Id: <202208191322.27JDMv0b007432@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Ganbold Tsagaankhuu Subject: git: 901df07a4768 - main - Code refactoring for existing rk_gpio driver. It supports gpio type checking. Depending on gpio type some register addresses are different. 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: ganbold X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 901df07a47684dca7b06f60d838a56456d751a23 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1660915377; 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=Aq1sttdo4j0BX49Px4t41q/58GnQdsRmK+qV1MNbZu4=; b=H3r18gXTj8EZA8DjyVXsS8tIDrl6pN/vm4y0CJ9qC2gcwqvXCUs1OIgUwEHg0iED9vzbk6 6oXEO11daYyM/dOvGIsPgtOs66ECktOxPdDQVKmz6afnAq61NqvW8ESCV5vfT0pf/5c4QI U1lnF8VrXjBVafbxuKXCqMnmMyxJ5pn1OxRE70Sq/fJa3iiBrdMp56M35s4P1qY6EDOGg3 8CIwBG6cvh9k1EStW607/1jd8WRMv/pyLR5qyguRAwMg/UVrQdyUDdYVFdNr8OX3sfI1FS KDv4YIlpllKmTLIY6RTbzqIT8nNe3Ls6VdefCkF9KJdqmOmD+vr1uiOYKdBQEQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1660915377; a=rsa-sha256; cv=none; b=exH70/opm1WaDAvxYsXFQHexd4VfacD3WdaU32kGuTSkRQ78twv1w70O1N0DgPrerjqLY3 FLtQgGRi23OK+cvxKtcvMk1h73KZesqGdbWthSjMWftf0CLkf+8eHcELMdIHKCY6KDPMQi gwPPNxu6M3r7Pit6OzHW1tsl/dlN9ztk1SL8ICSegrRiDSdvij0mdTQSGaa9by+2wP65Kv pnALjlS36p1s5y5RfC2FsGQ+47d0gd0JwpblSxZG5lY4k1C7greaLjAgxXkaspWNgq7QGM VnUzklNs8KEu2GNkkbJlIItumCMkGAzpHlRS8LvHCFGWBsenR17kRDM6mn9GyQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by ganbold: URL: https://cgit.FreeBSD.org/src/commit/?id=901df07a47684dca7b06f60d838a56456d751a23 commit 901df07a47684dca7b06f60d838a56456d751a23 Author: Søren Schmidt AuthorDate: 2022-08-19 13:22:01 +0000 Commit: Ganbold Tsagaankhuu CommitDate: 2022-08-19 13:22:01 +0000 Code refactoring for existing rk_gpio driver. It supports gpio type checking. Depending on gpio type some register addresses are different. Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D36262 --- sys/arm64/rockchip/rk_gpio.c | 155 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 127 insertions(+), 28 deletions(-) diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c index 46df1faee419..c9ad1c9ea1df 100644 --- a/sys/arm64/rockchip/rk_gpio.c +++ b/sys/arm64/rockchip/rk_gpio.c @@ -2,6 +2,7 @@ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2018 Emmanuel Vadot + * Copyright (c) 2021 Soren Schmidt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,20 +54,21 @@ __FBSDID("$FreeBSD$"); #include "fdt_pinctrl_if.h" -#define RK_GPIO_SWPORTA_DR 0x00 /* Data register */ -#define RK_GPIO_SWPORTA_DDR 0x04 /* Data direction register */ - -#define RK_GPIO_INTEN 0x30 /* Interrupt enable register */ -#define RK_GPIO_INTMASK 0x34 /* Interrupt mask register */ -#define RK_GPIO_INTTYPE_LEVEL 0x38 /* Interrupt level register */ -#define RK_GPIO_INT_POLARITY 0x3C /* Interrupt polarity register */ -#define RK_GPIO_INT_STATUS 0x40 /* Interrupt status register */ -#define RK_GPIO_INT_RAWSTATUS 0x44 /* Raw Interrupt status register */ - -#define RK_GPIO_DEBOUNCE 0x48 /* Debounce enable register */ - -#define RK_GPIO_PORTA_EOI 0x4C /* Clear interrupt register */ -#define RK_GPIO_EXT_PORTA 0x50 /* External port register */ +enum gpio_regs { + RK_GPIO_SWPORTA_DR = 1, /* Data register */ + RK_GPIO_SWPORTA_DDR, /* Data direction register */ + RK_GPIO_INTEN, /* Interrupt enable register */ + RK_GPIO_INTMASK, /* Interrupt mask register */ + RK_GPIO_INTTYPE_LEVEL, /* Interrupt level register */ + RK_GPIO_INTTYPE_BOTH, /* Both rise and falling edge */ + RK_GPIO_INT_POLARITY, /* Interrupt polarity register */ + RK_GPIO_INT_STATUS, /* Interrupt status register */ + RK_GPIO_INT_RAWSTATUS, /* Raw Interrupt status register */ + RK_GPIO_DEBOUNCE, /* Debounce enable register */ + RK_GPIO_PORTA_EOI, /* Clear interrupt register */ + RK_GPIO_EXT_PORTA, /* External port register */ + RK_GPIO_REGNUM +}; #define RK_GPIO_LS_SYNC 0x60 /* Level sensitive syncronization enable register */ @@ -92,7 +94,9 @@ struct rk_gpio_softc { device_t pinctrl; uint32_t swporta; uint32_t swporta_ddr; + uint32_t version; struct pin_cached pin_cached[RK_GPIO_MAX_PINS]; + uint8_t regs[RK_GPIO_REGNUM]; }; static struct ofw_compat_data compat_data[] = { @@ -106,6 +110,10 @@ static struct resource_spec rk_gpio_spec[] = { { -1, 0 } }; +#define RK_GPIO_VERSION 0x78 +#define RK_GPIO_TYPE_V1 0x00000000 +#define RK_GPIO_TYPE_V2 0x01000c2b + static int rk_gpio_detach(device_t dev); #define RK_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx) @@ -117,6 +125,49 @@ static int rk_gpio_detach(device_t dev); #define RK_GPIO_READ(_sc, _off) \ bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off) +static int +rk_gpio_read_bit(struct rk_gpio_softc *sc, int reg, int bit) +{ + int offset = sc->regs[reg]; + uint32_t value; + + if (sc->version == RK_GPIO_TYPE_V1) { + value = RK_GPIO_READ(sc, offset); + value >>= bit; + } else { + value = RK_GPIO_READ(sc, bit > 15 ? offset + 4 : offset); + value >>= (bit % 16); + } + return (value & 1); +} + +static uint32_t +rk_gpio_read_4(struct rk_gpio_softc *sc, int reg) +{ + int offset = sc->regs[reg]; + uint32_t value; + + if (sc->version == RK_GPIO_TYPE_V1) + value = RK_GPIO_READ(sc, offset); + else + value = (RK_GPIO_READ(sc, offset) & 0xffff) | + (RK_GPIO_READ(sc, offset + 4) << 16); + return (value); +} + +static void +rk_gpio_write_4(struct rk_gpio_softc *sc, int reg, uint32_t value) +{ + int offset = sc->regs[reg]; + + if (sc->version == RK_GPIO_TYPE_V1) + RK_GPIO_WRITE(sc, offset, value); + else { + RK_GPIO_WRITE(sc, offset, (value & 0xffff) | 0xffff0000); + RK_GPIO_WRITE(sc, offset + 4, (value >> 16) | 0xffff0000); + } +} + static int rk_gpio_probe(device_t dev) { @@ -170,6 +221,43 @@ rk_gpio_attach(device_t dev) rk_gpio_detach(dev); return (ENXIO); } + RK_GPIO_LOCK(sc); + sc->version = rk_gpio_read_4(sc, RK_GPIO_VERSION); + RK_GPIO_UNLOCK(sc); + + switch (sc->version) { + case RK_GPIO_TYPE_V1: + sc->regs[RK_GPIO_SWPORTA_DR] = 0x00; + sc->regs[RK_GPIO_SWPORTA_DDR] = 0x04; + sc->regs[RK_GPIO_INTEN] = 0x30; + sc->regs[RK_GPIO_INTMASK] = 0x34; + sc->regs[RK_GPIO_INTTYPE_LEVEL] = 0x38; + sc->regs[RK_GPIO_INT_POLARITY] = 0x3c; + sc->regs[RK_GPIO_INT_STATUS] = 0x40; + sc->regs[RK_GPIO_INT_RAWSTATUS] = 0x44; + sc->regs[RK_GPIO_DEBOUNCE] = 0x48; + sc->regs[RK_GPIO_PORTA_EOI] = 0x4c; + sc->regs[RK_GPIO_EXT_PORTA] = 0x50; + break; + case RK_GPIO_TYPE_V2: + sc->regs[RK_GPIO_SWPORTA_DR] = 0x00; + sc->regs[RK_GPIO_SWPORTA_DDR] = 0x08; + sc->regs[RK_GPIO_INTEN] = 0x10; + sc->regs[RK_GPIO_INTMASK] = 0x18; + sc->regs[RK_GPIO_INTTYPE_LEVEL] = 0x20; + sc->regs[RK_GPIO_INTTYPE_BOTH] = 0x30; + sc->regs[RK_GPIO_INT_POLARITY] = 0x28; + sc->regs[RK_GPIO_INT_STATUS] = 0x50; + sc->regs[RK_GPIO_INT_RAWSTATUS] = 0x58; + sc->regs[RK_GPIO_DEBOUNCE] = 0x38; + sc->regs[RK_GPIO_PORTA_EOI] = 0x60; + sc->regs[RK_GPIO_EXT_PORTA] = 0x70; + break; + default: + device_printf(dev, "Unknown gpio version %08x\n", sc->version); + rk_gpio_detach(dev); + return (ENXIO); + } sc->sc_busdev = gpiobus_attach_bus(dev); if (sc->sc_busdev == NULL) { @@ -182,8 +270,8 @@ rk_gpio_attach(device_t dev) 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); + sc->swporta = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DR); + sc->swporta_ddr = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DDR); RK_GPIO_UNLOCK(sc); return (0); @@ -260,7 +348,6 @@ rk_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 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) @@ -279,6 +366,9 @@ static int rk_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) { + if (pin >= RK_GPIO_MAX_PINS) + return EINVAL; + *caps = RK_GPIO_DEFAULT_CAPS; return (0); } @@ -291,6 +381,9 @@ rk_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) sc = device_get_softc(dev); + if (pin >= RK_GPIO_MAX_PINS) + 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) @@ -312,7 +405,7 @@ rk_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) else if (flags & GPIO_PIN_OUTPUT) sc->swporta_ddr |= (1 << pin); - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, sc->swporta_ddr); + rk_gpio_write_4(sc, RK_GPIO_SWPORTA_DDR, sc->swporta_ddr); RK_GPIO_UNLOCK(sc); return (0); @@ -322,16 +415,16 @@ static int rk_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) { struct rk_gpio_softc *sc; - uint32_t reg; sc = device_get_softc(dev); + if (pin >= RK_GPIO_MAX_PINS) + return (EINVAL); + RK_GPIO_LOCK(sc); - reg = RK_GPIO_READ(sc, RK_GPIO_EXT_PORTA); + *val = rk_gpio_read_bit(sc, RK_GPIO_EXT_PORTA, pin); RK_GPIO_UNLOCK(sc); - *val = reg & (1 << pin) ? 1 : 0; - return (0); } @@ -342,12 +435,15 @@ rk_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) sc = device_get_softc(dev); + if (pin >= RK_GPIO_MAX_PINS) + return (EINVAL); + RK_GPIO_LOCK(sc); if (value) sc->swporta |= (1 << pin); else sc->swporta &= ~(1 << pin); - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, sc->swporta); + rk_gpio_write_4(sc, RK_GPIO_SWPORTA_DR, sc->swporta); RK_GPIO_UNLOCK(sc); return (0); @@ -360,12 +456,15 @@ rk_gpio_pin_toggle(device_t dev, uint32_t pin) sc = device_get_softc(dev); + if (pin >= RK_GPIO_MAX_PINS) + return (EINVAL); + RK_GPIO_LOCK(sc); if (sc->swporta & (1 << pin)) sc->swporta &= ~(1 << pin); else sc->swporta |= (1 << pin); - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, sc->swporta); + rk_gpio_write_4(sc, RK_GPIO_SWPORTA_DR, sc->swporta); RK_GPIO_UNLOCK(sc); return (0); @@ -381,14 +480,14 @@ rk_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, sc = device_get_softc(dev); RK_GPIO_LOCK(sc); - reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DR); + reg = rk_gpio_read_4(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; - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DR, reg); + rk_gpio_write_4(sc, RK_GPIO_SWPORTA_DR, reg); } RK_GPIO_UNLOCK(sc); @@ -421,10 +520,10 @@ rk_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, } RK_GPIO_LOCK(sc); - reg = RK_GPIO_READ(sc, RK_GPIO_SWPORTA_DDR); + reg = rk_gpio_read_4(sc, RK_GPIO_SWPORTA_DDR); reg &= ~mask; reg |= set; - RK_GPIO_WRITE(sc, RK_GPIO_SWPORTA_DDR, reg); + rk_gpio_write_4(sc, RK_GPIO_SWPORTA_DDR, reg); sc->swporta_ddr = reg; RK_GPIO_UNLOCK(sc);