Index: sys/arch/arm/samsung/exynos5410_clock.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/samsung/exynos5410_clock.c,v retrieving revision 1.5 diff -u -p -r1.5 exynos5410_clock.c --- sys/arch/arm/samsung/exynos5410_clock.c 18 Oct 2019 06:13:38 -0000 1.5 +++ sys/arch/arm/samsung/exynos5410_clock.c 17 Mar 2020 21:19:59 -0000 @@ -448,7 +448,7 @@ exynos5410_clock_attach(device_t parent, sc->sc_dev = self; sc->sc_bst = faa->faa_bst; - + error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); if (error) { aprint_error(": couldn't map %#" PRIxBUSADDR ": %d", Index: sys/arch/arm/samsung/exynos_gpio.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/samsung/exynos_gpio.c,v retrieving revision 1.25 diff -u -p -r1.25 exynos_gpio.c --- sys/arch/arm/samsung/exynos_gpio.c 4 Jul 2018 22:16:42 -0000 1.25 +++ sys/arch/arm/samsung/exynos_gpio.c 17 Mar 2020 21:19:59 -0000 @@ -1,11 +1,11 @@ /* $NetBSD: exynos_gpio.c,v 1.25 2018/07/04 22:16:42 jmcneill Exp $ */ /*- -* Copyright (c) 2014 The NetBSD Foundation, Inc. +* Copyright (c) 2014, 2020 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation -* by Reinoud Zandijk +* by Reinoud Zandijk, and by Nick Hudson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -63,11 +63,7 @@ struct exynos_gpio_bank { const bus_addr_t bank_core_offset; const uint8_t bank_bits; - uint8_t bank_pin_mask; - uint8_t bank_pin_inuse_mask; - bus_space_handle_t bank_bsh; struct exynos_gpio_pin_cfg bank_cfg; - struct exynos_gpio_bank * bank_next; }; struct exynos_gpio_pin { @@ -88,7 +84,30 @@ struct exynos_gpio_pin { .bank_bits = b, \ } -static struct exynos_gpio_bank exynos5_banks[] = { +#define GPIO_GRP_INTR(o, n, b, i) \ + { \ + .bank_name = #n, \ + .bank_core_offset = GPIO_REG(v,s,o), \ + .bank_bits = b, \ + } + +#define GPIO_GRP_NONE(o, n, b) \ + { \ + .bank_name = #n, \ + .bank_core_offset = GPIO_REG(v,s,o), \ + .bank_bits = b, \ + } + +#define GPIO_GRP_WAKEUP(o, n, b, i) \ + { \ + .bank_name = #n, \ + .bank_core_offset = GPIO_REG(v,s,o), \ + .bank_bits = b, \ + } + + + +static struct exynos_gpio_bank exynos5420_banks[] = { GPIO_GRP(5, MUXA, 0x0000, gpy7, 8), GPIO_GRP(5, MUXA, 0x0C00, gpx0, 8), GPIO_GRP(5, MUXA, 0x0C20, gpx1, 8), @@ -129,10 +148,78 @@ static struct exynos_gpio_bank exynos5_b GPIO_GRP(5, MUXD, 0x0100, gph0, 4), GPIO_GRP(5, MUXE, 0x0000, gpz, 7), +}; + +struct exynos_pinctrl_banks exynos5420_pinctrl_banks = { + .epb_banks = exynos5420_banks, + .epb_nbanks = __arraycount(exynos5420_banks) +}; + +static struct exynos_gpio_bank exynos5410_banks[] = { + /* pin-controller 0 */ + GPIO_GRP_INTR(0x000, gpa0, 8, 0x00), + GPIO_GRP_INTR(0x020, gpa1, 6, 0x04), + GPIO_GRP_INTR(0x040, gpa2, 8, 0x08), + GPIO_GRP_INTR(0x060, gpb0, 5, 0x0c), + GPIO_GRP_INTR(0x080, gpb1, 5, 0x10), + GPIO_GRP_INTR(0x0A0, gpb2, 4, 0x14), + GPIO_GRP_INTR(0x0C0, gpb3, 4, 0x18), + GPIO_GRP_INTR(0x0E0, gpc0, 7, 0x1c), + GPIO_GRP_INTR(0x100, gpc3, 4, 0x20), + GPIO_GRP_INTR(0x120, gpc1, 7, 0x24), + GPIO_GRP_INTR(0x140, gpc2, 7, 0x28), + GPIO_GRP_INTR(0x180, gpd1, 8, 0x2c), + GPIO_GRP_INTR(0x1A0, gpe0, 8, 0x30), + GPIO_GRP_INTR(0x1C0, gpe1, 2, 0x34), + GPIO_GRP_INTR(0x1E0, gpf0, 6, 0x38), + GPIO_GRP_INTR(0x200, gpf1, 8, 0x3c), + GPIO_GRP_INTR(0x220, gpg0, 8, 0x40), + GPIO_GRP_INTR(0x240, gpg1, 8, 0x44), + GPIO_GRP_INTR(0x260, gpg2, 2, 0x48), + GPIO_GRP_INTR(0x280, gph0, 4, 0x4c), + GPIO_GRP_INTR(0x2A0, gph1, 8, 0x50), + GPIO_GRP_NONE(0x160, gpm5, 2), + GPIO_GRP_NONE(0x2C0, gpm7, 8), + GPIO_GRP_NONE(0x2E0, gpy0, 6), + GPIO_GRP_NONE(0x300, gpy1, 4), + GPIO_GRP_NONE(0x320, gpy2, 6), + GPIO_GRP_NONE(0x340, gpy3, 8), + GPIO_GRP_NONE(0x360, gpy4, 8), + GPIO_GRP_NONE(0x380, gpy5, 8), + GPIO_GRP_NONE(0x3A0, gpy6, 8), + GPIO_GRP_NONE(0x3C0, gpy7, 8), + GPIO_GRP_WAKEUP(0xC00, gpx0, 8, 0x00), + GPIO_GRP_WAKEUP(0xC20, gpx1, 8, 0x04), + GPIO_GRP_WAKEUP(0xC40, gpx2, 8, 0x08), + GPIO_GRP_WAKEUP(0xC60, gpx3, 8, 0x0c), + + /* pin-controller 1 */ + GPIO_GRP_INTR(0x000, gpj0, 5, 0x00), + GPIO_GRP_INTR(0x020, gpj1, 8, 0x04), + GPIO_GRP_INTR(0x040, gpj2, 8, 0x08), + GPIO_GRP_INTR(0x060, gpj3, 8, 0x0c), + GPIO_GRP_INTR(0x080, gpj4, 2, 0x10), + GPIO_GRP_INTR(0x0A0, gpk0, 8, 0x14), + GPIO_GRP_INTR(0x0C0, gpk1, 8, 0x18), + GPIO_GRP_INTR(0x0E0, gpk2, 8, 0x1c), + GPIO_GRP_INTR(0x100, gpk3, 7, 0x20), + + /* pin-controller 2 */ + GPIO_GRP_INTR(0x000, gpv0, 8, 0x00), + GPIO_GRP_INTR(0x020, gpv1, 8, 0x04), + GPIO_GRP_INTR(0x060, gpv2, 8, 0x08), + GPIO_GRP_INTR(0x080, gpv3, 8, 0x0c), + GPIO_GRP_INTR(0x0C0, gpv4, 2, 0x10), + + /* pin-controller 2 */ + GPIO_GRP_INTR(0x000, gpz, 7, 0x00), +}; +struct exynos_pinctrl_banks exynos5410_pinctrl_banks = { + .epb_banks = exynos5410_banks, + .epb_nbanks = __arraycount(exynos5410_banks) }; -struct exynos_gpio_bank *exynos_gpio_banks = exynos5_banks; static int exynos_gpio_pin_read(void *, int); static void exynos_gpio_pin_write(void *, int, int); @@ -179,11 +266,13 @@ static int exynos_gpio_pin_read(void *cookie, int pin) { struct exynos_gpio_bank * const bank = cookie; + uint8_t val; KASSERT(pin < bank->bank_bits); - return (bus_space_read_1(bank->bank_sc->sc_bst, - bank->bank_sc->sc_bsh, - EXYNOS_GPIO_DAT) >> pin) & 1; + val = bus_space_read_1(bank->bank_sc->sc_bst, bank->bank_sc->sc_bsh, + EXYNOS_GPIO_DAT); + + return __SHIFTOUT(val, __BIT(pin)); } static void @@ -193,15 +282,13 @@ exynos_gpio_pin_write(void *cookie, int int val; KASSERT(pin < bank->bank_bits); - val = bus_space_read_1(bank->bank_sc->sc_bst, - bank->bank_sc->sc_bsh, - EXYNOS_GPIO_DAT); + val = bus_space_read_1(bank->bank_sc->sc_bst, bank->bank_sc->sc_bsh, + EXYNOS_GPIO_DAT); val &= ~__BIT(pin); if (value) val |= __BIT(pin); - bus_space_write_1(bank->bank_sc->sc_bst, - bank->bank_sc->sc_bsh, - EXYNOS_GPIO_DAT, val); + bus_space_write_1(bank->bank_sc->sc_bst, bank->bank_sc->sc_bsh, + EXYNOS_GPIO_DAT, val); } static void @@ -279,20 +366,20 @@ struct exynos_gpio_softc * exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent, const struct fdt_attach_args *faa, int node) { - struct exynos_gpio_bank *bank = kmem_zalloc(sizeof(*bank), KM_SLEEP); struct exynos_gpio_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); struct gpiobus_attach_args gba; struct gpio_chipset_tag *gc_tag; char result[64]; OF_getprop(node, "name", result, sizeof(result)); - bank = exynos_gpio_bank_lookup(result); + struct exynos_gpio_bank *bank = + exynos_gpio_bank_lookup(parent->sc_epb, result); if (bank == NULL) { aprint_error_dev(parent->sc_dev, "no bank found for %s\n", result); return NULL; } - + sc->sc_dev = parent->sc_dev; sc->sc_bst = &armv7_generic_bs_tag; sc->sc_bsh = parent->sc_bsh; @@ -307,13 +394,12 @@ exynos_gpio_bank_config(struct exynos_pi gba.gba_gc = &bank->bank_gc; gba.gba_pins = bank->bank_pins; gba.gba_npins = bank->bank_bits; + bank->bank_sc = sc; bank->bank_dev = config_found_ia(parent->sc_dev, "gpiobus", &gba, exynos_gpio_cfprint); - bank->bank_pin_mask = __BIT(bank->bank_bits) - 1; - bank->bank_pin_inuse_mask = 0; - + bank->bank_dev->dv_private = sc; /* read in our initial settings */ bank->bank_cfg.cfg = GPIO_READ(bank, EXYNOS_GPIO_CON); @@ -333,12 +419,12 @@ exynos_gpio_bank_config(struct exynos_pi * the '-', or the four character string if the dash is not present. */ struct exynos_gpio_bank * -exynos_gpio_bank_lookup(const char *name) +exynos_gpio_bank_lookup(struct exynos_pinctrl_banks *epb, const char *name) { struct exynos_gpio_bank *bank; - for (u_int n = 0; n < __arraycount(exynos5_banks); n++) { - bank = &exynos_gpio_banks[n]; + for (u_int n = 0; n < epb->epb_nbanks; n++) { + bank = &epb->epb_banks[n]; if (!strncmp(bank->bank_name, name, strlen(bank->bank_name))) { return bank; @@ -365,25 +451,17 @@ exynos_gpio_pin_lookup(const char *name) static void * exynos_gpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags) { - const u_int *cells = data; - struct exynos_gpio_bank *bank = NULL; struct exynos_gpio_pin *gpin; - int n; if (len != 12) return NULL; + const u_int *cells = data; const int pin = be32toh(cells[1]) & 0x0f; const int actlo = be32toh(cells[2]) & 0x01; - for (n = 0; n < __arraycount(exynos5_banks); n++) { - if (exynos_gpio_banks[n].bank_dev == dev) { - bank = &exynos_gpio_banks[n]; - break; - } - } - if (bank == NULL) - return NULL; + struct exynos_gpio_softc *bank_sc = device_private(dev); + struct exynos_gpio_bank * const bank = bank_sc->sc_bank; gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP); gpin->pin_sc = bank->bank_sc; Index: sys/arch/arm/samsung/exynos_pinctrl.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/samsung/exynos_pinctrl.c,v retrieving revision 1.15 diff -u -p -r1.15 exynos_pinctrl.c --- sys/arch/arm/samsung/exynos_pinctrl.c 18 Oct 2019 06:13:38 -0000 1.15 +++ sys/arch/arm/samsung/exynos_pinctrl.c 17 Mar 2020 21:20:00 -0000 @@ -1,11 +1,11 @@ /* $NetBSD: exynos_pinctrl.c,v 1.15 2019/10/18 06:13:38 skrll Exp $ */ /*- -* Copyright (c) 2015 The NetBSD Foundation, Inc. +* Copyright (c) 2015, 2020 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation -* by Marty Fouts +* by Marty Fouts, and by Nick Hudson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -72,15 +72,19 @@ static struct fdtbus_pinctrl_controller_ CFATTACH_DECL_NEW(exynos_pinctrl, sizeof(struct exynos_pinctrl_softc), exynos_pinctrl_match, exynos_pinctrl_attach, NULL, NULL); + +static const struct of_compat_data compat_data[] = { + { "samsung,exynos5410-pinctrl", (uintptr_t)&exynos5410_pinctrl_banks }, + { "samsung,exynos5420-pinctrl", (uintptr_t)&exynos5420_pinctrl_banks }, + { NULL } +}; + static int exynos_pinctrl_match(device_t parent, cfdata_t cf, void *aux) { - const char * const compatible[] = { - "samsung,exynos5410-pinctrl", - "samsung,exynos5420-pinctrl", - NULL }; struct fdt_attach_args * const faa = aux; - return of_match_compatible(faa->faa_phandle, compatible); + + return of_match_compat_data(faa->faa_phandle, compat_data); } static void @@ -99,9 +103,12 @@ exynos_pinctrl_attach(device_t parent, d return; } - aprint_normal(" pinctl @ 0x%08x ", (uint)addr); + aprint_normal(" pinctrl @ 0x%08x ", (uint)addr); + self->dv_private = sc; sc->sc_dev = self; sc->sc_bst = faa->faa_bst; + sc->sc_epb = (struct exynos_pinctrl_banks *)of_search_compatible(faa->faa_phandle, compat_data)->data; + error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); if (error) { aprint_error(": couldn't map %#" PRIxBUSADDR ": %d", @@ -121,7 +128,7 @@ exynos_pinctrl_attach(device_t parent, d if (of_hasprop(child, "samsung,pins")) { fdtbus_register_pinctrl_config(self, child, - &exynos_pinctrl_controller_func); + &exynos_pinctrl_controller_func); } } } @@ -155,6 +162,7 @@ static int exynos_do_config(struct exynos_pinctrl_config *pc) { struct exynos_gpio_pin_cfg *gc = &pc->pc_pincfg; + struct exynos_pinctrl_banks *epb = pc->pc_sc->sc_epb; struct exynos_gpio_bank *bank; const char *pins; int pin; @@ -166,7 +174,7 @@ exynos_do_config(struct exynos_pinctrl_c for (pins = fdtbus_get_string(pc->pc_phandle, "samsung,pins"); pins_len > 0; pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) { - bank = exynos_gpio_bank_lookup(pins); + bank = exynos_gpio_bank_lookup(epb, pins); pin = exynos_parse_pin(pins); if (bank == NULL) { aprint_error_dev(pc->pc_sc->sc_dev, @@ -178,7 +186,7 @@ exynos_do_config(struct exynos_pinctrl_c return 0; } - + static int exynos_pinctrl_set_cfg(device_t dev, const void *data, size_t len) { Index: sys/arch/arm/samsung/exynos_pinctrl.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/samsung/exynos_pinctrl.h,v retrieving revision 1.2 diff -u -p -r1.2 exynos_pinctrl.h --- sys/arch/arm/samsung/exynos_pinctrl.h 22 Dec 2015 03:36:01 -0000 1.2 +++ sys/arch/arm/samsung/exynos_pinctrl.h 17 Mar 2020 21:20:00 -0000 @@ -1,3 +1,34 @@ +/* $NetBSD$ */ + +/*- +* Copyright (c) 2015, 2020 The NetBSD Foundation, Inc. +* All rights reserved. +* +* This code is derived from software contributed to The NetBSD Foundation +* by Marty Fouts, and by Nick Hudson +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + extern struct fdtbus_gpio_controller_func exynos_gpio_funcs; struct exynos_pinctrl_softc { @@ -5,4 +36,5 @@ struct exynos_pinctrl_softc { bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; + struct exynos_pinctrl_banks *sc_epb; }; Index: sys/arch/arm/samsung/exynos_var.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/samsung/exynos_var.h,v retrieving revision 1.27 diff -u -p -r1.27 exynos_var.h --- sys/arch/arm/samsung/exynos_var.h 8 Oct 2018 08:17:00 -0000 1.27 +++ sys/arch/arm/samsung/exynos_var.h 17 Mar 2020 21:20:00 -0000 @@ -93,6 +93,11 @@ struct exyo_attach_args { bus_dma_tag_t exyo_coherent_dmat; }; +struct exynos_pinctrl_banks { + struct exynos_gpio_bank *epb_banks; + size_t epb_nbanks; +}; + struct exynos_gpio_pinset { char pinset_bank[10]; uint8_t pinset_func; @@ -168,7 +173,10 @@ extern void exynos_usb_soc_powerup(void) extern void exyo_device_register(device_t self, void *aux); extern void exyo_device_register_post_config(device_t self, void *aux); -extern struct exynos_gpio_bank *exynos_gpio_bank_lookup(const char *name); +extern struct exynos_pinctrl_banks exynos5410_pinctrl_banks; +extern struct exynos_pinctrl_banks exynos5420_pinctrl_banks; + +extern struct exynos_gpio_bank *exynos_gpio_bank_lookup(struct exynos_pinctrl_banks *, const char *name); extern bool exynos_gpio_pinset_available(const struct exynos_gpio_pinset *); extern void exynos_gpio_pinset_acquire(const struct exynos_gpio_pinset *); extern void exynos_gpio_pinset_release(const struct exynos_gpio_pinset *);