Module Name: src Committed By: hkenken Date: Wed Jul 24 12:33:19 UTC 2019
Modified Files: src/sys/arch/arm/imx: files.imx51 files.imx6 files.imx7 imx51_gpio.c imx51var.h imx6_gpio.c imx6_pcie.c imx6_usdhc.c imx7_gpio.c imx7_usdhc.c imxgpio.c imxgpiovar.h src/sys/arch/evbarm/conf: ARMADILLO-IOT-G3 CUBOX-I HUMMINGBOARD IMX6UL-STARTER KOBO NETWALKER NITROGEN6X mk.nitrogen6 std.nitrogen6 src/sys/arch/evbarm/imx7: imx7_ioconfig.c src/sys/arch/evbarm/kobo: kobo_machdep.c src/sys/arch/evbarm/netwalker: netwalker_lcd.c netwalker_machdep.c netwalker_spi.c netwalker_usb.c src/sys/arch/evbarm/nitrogen6: nitrogen6_iomux.c Added Files: src/sys/arch/arm/imx: imxpcie.c imxpciereg.h imxpcievar.h Log Message: Modified i.MX GPIO control module and PCIe module. + Add imxpcie.c imx PCIe common driver To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/arch/arm/imx/files.imx51 cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/imx/files.imx6 cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/imx/files.imx7 \ src/sys/arch/arm/imx/imx51var.h cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/imx/imx51_gpio.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/imx6_gpio.c \ src/sys/arch/arm/imx/imx7_usdhc.c cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/imx/imx6_pcie.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/imx/imx6_usdhc.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/imx7_gpio.c \ src/sys/arch/arm/imx/imxgpiovar.h cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/imx/imxgpio.c cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/imxpcie.c \ src/sys/arch/arm/imx/imxpciereg.h src/sys/arch/arm/imx/imxpcievar.h cvs rdiff -u -r1.18 -r1.19 src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3 cvs rdiff -u -r1.20 -r1.21 src/sys/arch/evbarm/conf/CUBOX-I cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/conf/HUMMINGBOARD cvs rdiff -u -r1.12 -r1.13 src/sys/arch/evbarm/conf/IMX6UL-STARTER cvs rdiff -u -r1.9 -r1.10 src/sys/arch/evbarm/conf/KOBO cvs rdiff -u -r1.37 -r1.38 src/sys/arch/evbarm/conf/NETWALKER cvs rdiff -u -r1.22 -r1.23 src/sys/arch/evbarm/conf/NITROGEN6X cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/conf/mk.nitrogen6 cvs rdiff -u -r1.10 -r1.11 src/sys/arch/evbarm/conf/std.nitrogen6 cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbarm/imx7/imx7_ioconfig.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/kobo/kobo_machdep.c cvs rdiff -u -r1.5 -r1.6 src/sys/arch/evbarm/netwalker/netwalker_lcd.c \ src/sys/arch/evbarm/netwalker/netwalker_usb.c cvs rdiff -u -r1.25 -r1.26 src/sys/arch/evbarm/netwalker/netwalker_machdep.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/netwalker/netwalker_spi.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/imx/files.imx51 diff -u src/sys/arch/arm/imx/files.imx51:1.18 src/sys/arch/arm/imx/files.imx51:1.19 --- src/sys/arch/arm/imx/files.imx51:1.18 Sat Mar 17 18:34:09 2018 +++ src/sys/arch/arm/imx/files.imx51 Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: files.imx51,v 1.18 2018/03/17 18:34:09 ryo Exp $ +# $NetBSD: files.imx51,v 1.19 2019/07/24 12:33:18 hkenken Exp $ # # Configuration info for the Freescale i.MX5x # @@ -62,9 +62,8 @@ file arch/arm/imx/imxwdog.c imxwdog # iMX GPIO device imxgpio: gpiobus attach imxgpio at axi -file arch/arm/imx/imxgpio.c imxgpio needs-flag +file arch/arm/imx/imxgpio.c imxgpio file arch/arm/imx/imx51_gpio.c imxgpio -defflag opt_imxgpio.h IMX_GPIO_INTR_SPLIT # iMX IOMUX device imxiomux : bus_space_generic Index: src/sys/arch/arm/imx/files.imx6 diff -u src/sys/arch/arm/imx/files.imx6:1.16 src/sys/arch/arm/imx/files.imx6:1.17 --- src/sys/arch/arm/imx/files.imx6:1.16 Wed Jul 24 11:58:00 2019 +++ src/sys/arch/arm/imx/files.imx6 Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: files.imx6,v 1.16 2019/07/24 11:58:00 hkenken Exp $ +# $NetBSD: files.imx6,v 1.17 2019/07/24 12:33:18 hkenken Exp $ # # Configuration info for the Freescale i.MX6 # @@ -28,8 +28,9 @@ file arch/arm/imx/imx6_axi.c axi # iMX6 PCIe device imxpcie: pcibus -attach imxpcie at axi -file arch/arm/imx/imx6_pcie.c imxpcie +attach imxpcie at axi with imx6_pcie +file arch/arm/imx/imxpcie.c imxpcie +file arch/arm/imx/imx6_pcie.c imx6_pcie # iMX6 Clock Control Module device imxccm : clk @@ -62,9 +63,8 @@ file arch/arm/imx/imxwdog.c imxwdog # iMX GPIO device imxgpio: gpiobus attach imxgpio at axi -file arch/arm/imx/imxgpio.c imxgpio needs-flag +file arch/arm/imx/imxgpio.c imxgpio file arch/arm/imx/imx6_gpio.c imxgpio -defflag opt_imxgpio.h IMX_GPIO_INTR_SPLIT # iMX6 IOMUX device imxiomux Index: src/sys/arch/arm/imx/files.imx7 diff -u src/sys/arch/arm/imx/files.imx7:1.6 src/sys/arch/arm/imx/files.imx7:1.7 --- src/sys/arch/arm/imx/files.imx7:1.6 Sat Mar 17 18:34:09 2018 +++ src/sys/arch/arm/imx/files.imx7 Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: files.imx7,v 1.6 2018/03/17 18:34:09 ryo Exp $ +# $NetBSD: files.imx7,v 1.7 2019/07/24 12:33:18 hkenken Exp $ # # Configuration info for the Freescale i.MX7 # @@ -52,9 +52,8 @@ file arch/arm/imx/imxwdog.c imxwdog # iMX GPIO device imxgpio: gpiobus attach imxgpio at axi -file arch/arm/imx/imxgpio.c imxgpio needs-flag +file arch/arm/imx/imxgpio.c imxgpio file arch/arm/imx/imx7_gpio.c imxgpio -defflag opt_imxgpio.h IMX_GPIO_INTR_SPLIT # iMX7 IOMUX device imxiomux Index: src/sys/arch/arm/imx/imx51var.h diff -u src/sys/arch/arm/imx/imx51var.h:1.6 src/sys/arch/arm/imx/imx51var.h:1.7 --- src/sys/arch/arm/imx/imx51var.h:1.6 Sat Mar 17 18:34:09 2018 +++ src/sys/arch/arm/imx/imx51var.h Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx51var.h,v 1.6 2018/03/17 18:34:09 ryo Exp $ */ +/* $NetBSD: imx51var.h,v 1.7 2019/07/24 12:33:18 hkenken Exp $ */ /* * Copyright (c) 2015 Genetec Corporation. All rights reserved. @@ -49,10 +49,6 @@ extern struct bus_space armv7_generic_a4 extern struct arm32_bus_dma_tag arm_generic_dma_tag; extern struct arm32_bus_dma_tag imx_bus_dma_tag; -void gpio_set_direction(uint32_t, uint32_t); -void gpio_data_write(uint32_t, uint32_t); -bool gpio_data_read(uint32_t); - struct axi_attach_args { const char *aa_name; bus_space_tag_t aa_iot; @@ -63,7 +59,6 @@ struct axi_attach_args { int aa_irqbase; }; - /* iomux utility functions */ struct iomux_conf { u_int pin; Index: src/sys/arch/arm/imx/imx51_gpio.c diff -u src/sys/arch/arm/imx/imx51_gpio.c:1.3 src/sys/arch/arm/imx/imx51_gpio.c:1.4 --- src/sys/arch/arm/imx/imx51_gpio.c:1.3 Fri Jul 25 07:49:56 2014 +++ src/sys/arch/arm/imx/imx51_gpio.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx51_gpio.c,v 1.3 2014/07/25 07:49:56 hkenken Exp $ */ +/* $NetBSD: imx51_gpio.c,v 1.4 2019/07/24 12:33:18 hkenken Exp $ */ /* derived from imx31_gpio.c */ /*- @@ -30,13 +30,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx51_gpio.c,v 1.3 2014/07/25 07:49:56 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx51_gpio.c,v 1.4 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_imx.h" #include "locators.h" #include "gpio.h" +#define _INTR_PRIVATE + #include <sys/param.h> #include <sys/evcnt.h> #include <sys/atomic.h> @@ -86,6 +88,7 @@ imxgpio_match(device_t parent, cfdata_t void imxgpio_attach(device_t parent, device_t self, void *aux) { + struct imxgpio_softc * const gpio = device_private(self); struct axi_attach_args * const aa = aux; bus_space_handle_t ioh; int error; @@ -100,21 +103,30 @@ imxgpio_attach(device_t parent, device_t aprint_error_dev(self, "missing irqbase in config\n"); return; } - + if (aa->aa_size == AXICF_SIZE_DEFAULT) aa->aa_size = GPIO_SIZE; error = bus_space_map(aa->aa_iot, aa->aa_addr, aa->aa_size, 0, &ioh); - if (error) { aprint_error(": failed to map register %#lx@%#lx: %d\n", aa->aa_size, aa->aa_addr, error); return; } - imxgpio_attach_common(self, aa->aa_iot, ioh, - (aa->aa_addr - GPIO1_BASE) / 0x4000, - aa->aa_irq, aa->aa_irqbase); + gpio->gpio_is = intr_establish(aa->aa_irq, + IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); + KASSERT(gpio->gpio_is != NULL ); + gpio->gpio_is_high = intr_establish(aa->aa_irq + 1, + IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); + KASSERT(gpio->gpio_is_high != NULL); + + gpio->gpio_memt = aa->aa_iot; + gpio->gpio_memh = ioh; + gpio->gpio_unit = (aa->aa_addr - GPIO1_BASE) / 0x4000; + gpio->gpio_irqbase = aa->aa_irqbase; + + imxgpio_attach_common(self); } Index: src/sys/arch/arm/imx/imx6_gpio.c diff -u src/sys/arch/arm/imx/imx6_gpio.c:1.2 src/sys/arch/arm/imx/imx6_gpio.c:1.3 --- src/sys/arch/arm/imx/imx6_gpio.c:1.2 Fri Jun 9 18:14:59 2017 +++ src/sys/arch/arm/imx/imx6_gpio.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx6_gpio.c,v 1.2 2017/06/09 18:14:59 ryo Exp $ */ +/* $NetBSD: imx6_gpio.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -29,7 +29,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx6_gpio.c,v 1.2 2017/06/09 18:14:59 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx6_gpio.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $"); + +#define _INTR_PRIVATE #include "opt_imx.h" @@ -45,12 +47,12 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_gpio.c, #include <arm/cpu.h> #include <arm/armreg.h> #include <arm/cpufunc.h> +#include <arm/pic/picvar.h> #include <sys/bus.h> #include <arm/imx/imx6_reg.h> #include <arm/imx/imx6var.h> -#include <arm/pic/picvar.h> #include <arm/imx/imxgpioreg.h> #include <arm/imx/imxgpiovar.h> @@ -88,9 +90,10 @@ imxgpio_match(device_t parent, cfdata_t void imxgpio_attach(device_t parent, device_t self, void *aux) { + struct imxgpio_softc * const gpio = device_private(self); struct axi_attach_args * const aa = aux; bus_space_handle_t ioh; - int error, group; + int error; if (aa->aa_irq == AXICF_IRQ_DEFAULT && aa->aa_irqbase != AXICF_IRQBASE_DEFAULT) { @@ -114,8 +117,21 @@ imxgpio_attach(device_t parent, device_t return; } - group = (aa->aa_addr - IMX6_AIPS1_BASE - AIPS1_GPIO1_BASE) / 0x4000; - imxgpio_attach_common(self, aa->aa_iot, ioh, group, - aa->aa_irq, aa->aa_irqbase); + aprint_naive("\n"); + aprint_normal(": GPIO\n"); + + gpio->gpio_memt = aa->aa_iot; + gpio->gpio_memh = ioh; + gpio->gpio_unit = (aa->aa_addr - IMX6_AIPS1_BASE - AIPS1_GPIO1_BASE) / 0x4000; + gpio->gpio_irqbase = aa->aa_irqbase; + + gpio->gpio_is = intr_establish(aa->aa_irq, + IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); + KASSERT(gpio->gpio_is != NULL ); + gpio->gpio_is_high = intr_establish(aa->aa_irq + 1, + IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); + KASSERT(gpio->gpio_is_high != NULL); + + imxgpio_attach_common(self); } Index: src/sys/arch/arm/imx/imx7_usdhc.c diff -u src/sys/arch/arm/imx/imx7_usdhc.c:1.2 src/sys/arch/arm/imx/imx7_usdhc.c:1.3 --- src/sys/arch/arm/imx/imx7_usdhc.c:1.2 Thu Oct 26 05:08:30 2017 +++ src/sys/arch/arm/imx/imx7_usdhc.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx7_usdhc.c,v 1.2 2017/10/26 05:08:30 ryo Exp $ */ +/* $NetBSD: imx7_usdhc.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2012 Genetec Corporation. All rights reserved. @@ -29,10 +29,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx7_usdhc.c,v 1.2 2017/10/26 05:08:30 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx7_usdhc.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $"); #include "imxgpio.h" +#define _INTR_PRIVATE + #include <sys/param.h> #include <sys/device.h> #include <sys/systm.h> @@ -141,7 +143,7 @@ sdhc_set_gpio_cd(struct sdhc_axi_softc * sc->sc_gpio_cd = GPIO_NO(grp, pin); #if NIMXGPIO > 0 - gpio_set_direction(sc->sc_gpio_cd, GPIO_DIR_IN); + gpio_set_direction(sc->sc_gpio_cd, GPIO_PIN_INPUT); #endif } Index: src/sys/arch/arm/imx/imx6_pcie.c diff -u src/sys/arch/arm/imx/imx6_pcie.c:1.9 src/sys/arch/arm/imx/imx6_pcie.c:1.10 --- src/sys/arch/arm/imx/imx6_pcie.c:1.9 Thu Jun 20 08:16:19 2019 +++ src/sys/arch/arm/imx/imx6_pcie.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx6_pcie.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $ */ +/* $NetBSD: imx6_pcie.c,v 1.10 2019/07/24 12:33:18 hkenken Exp $ */ /* * Copyright (c) 2016 Genetec Corporation. All rights reserved. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.10 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_pci.h" @@ -39,6 +39,8 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c, #include "imxgpio.h" #include "locators.h" +#define _INTR_PRIVATE + #include <sys/bus.h> #include <sys/device.h> #include <sys/intr.h> @@ -58,467 +60,42 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c, #include <dev/pci/pcivar.h> #include <dev/pci/pciconf.h> +#include <arm/imx/imxpcievar.h> #include <arm/imx/imxgpioreg.h> #include <arm/imx/imxgpiovar.h> #include <arm/imx/imx6var.h> #include <arm/imx/imx6_reg.h> -#include <arm/imx/imx6_pciereg.h> #include <arm/imx/imx6_iomuxreg.h> #include <arm/imx/imx6_ccmreg.h> #include <arm/imx/imx6_ccmvar.h> -static int imx6pcie_match(device_t, cfdata_t, void *); -static void imx6pcie_attach(device_t, device_t, void *); - -#define IMX6_PCIE_MEM_BASE 0x01000000 -#define IMX6_PCIE_MEM_SIZE 0x00f00000 /* 15MB */ -#define IMX6_PCIE_ROOT_BASE 0x01f00000 -#define IMX6_PCIE_ROOT_SIZE 0x00080000 /* 512KB */ -#define IMX6_PCIE_IO_BASE 0x01f80000 -#define IMX6_PCIE_IO_SIZE 0x00010000 /* 64KB */ - -struct imx6pcie_ih { - int (*ih_handler)(void *); - void *ih_arg; - int ih_ipl; - TAILQ_ENTRY(imx6pcie_ih) ih_entry; -}; - -struct imx6pcie_softc { - device_t sc_dev; - - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - bus_space_handle_t sc_root_ioh; - bus_dma_tag_t sc_dmat; - - struct arm32_pci_chipset sc_pc; - - TAILQ_HEAD(, imx6pcie_ih) sc_intrs; - - void *sc_ih; - kmutex_t sc_lock; - u_int sc_intrgen; +struct imx6_pcie_softc { + struct imxpcie_softc sc_imxpcie; int32_t sc_gpio_reset; int32_t sc_gpio_reset_active; - int32_t sc_gpio_pwren; - int32_t sc_gpio_pwren_active; - - struct clk *sc_clk_pcie_axi; - struct clk *sc_clk_lvds1_gate; - struct clk *sc_clk_pcie_ref; }; -#define PCIE_CONF_LOCK(s) (s) = disable_interrupts(I32_bit) -#define PCIE_CONF_UNLOCK(s) restore_interrupts((s)) - -#define PCIE_READ(sc, reg) \ - bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, reg) -#define PCIE_WRITE(sc, reg, val) \ - bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, reg, val) - -static int imx6pcie_intr(void *); -static void imx6pcie_init(pci_chipset_tag_t, void *); -static void imx6pcie_setup(struct imx6pcie_softc * const); - -static void imx6pcie_attach_hook(device_t, device_t, - struct pcibus_attach_args *); -static int imx6pcie_bus_maxdevs(void *, int); -static pcitag_t imx6pcie_make_tag(void *, int, int, int); -static void imx6pcie_decompose_tag(void *, pcitag_t, int *, int *, int *); -static pcireg_t imx6pcie_conf_read(void *, pcitag_t, int); -static void imx6pcie_conf_write(void *, pcitag_t, int, pcireg_t); -#ifdef __HAVE_PCI_CONF_HOOK -static int imx6pcie_conf_hook(void *, int, int, int, pcireg_t); -#endif -static void imx6pcie_conf_interrupt(void *, int, int, int, int, int *); - -static int imx6pcie_intr_map(const struct pci_attach_args *, - pci_intr_handle_t *); -static const char *imx6pcie_intr_string(void *, pci_intr_handle_t, - char *, size_t); -const struct evcnt *imx6pcie_intr_evcnt(void *, pci_intr_handle_t); -static void * imx6pcie_intr_establish(void *, pci_intr_handle_t, - int, int (*)(void *), void *, - const char *); -static void imx6pcie_intr_disestablish(void *, void *); - -CFATTACH_DECL_NEW(imxpcie, sizeof(struct imx6pcie_softc), - imx6pcie_match, imx6pcie_attach, NULL, NULL); - -static int -imx6pcie_linkup_status(struct imx6pcie_softc *sc) -{ - return PCIE_READ(sc, PCIE_PL_DEBUG1) & PCIE_PL_DEBUG1_XMLH_LINK_UP; -} - -static int -imx6pcie_valid_device(struct imx6pcie_softc *sc, int bus, int dev) -{ - if (bus != 0 && !imx6pcie_linkup_status(sc)) - return 0; - if (bus <= 1 && dev > 0) - return 0; - - return 1; -} - -static int -imx6pcie_init_clocks(struct imx6pcie_softc *sc) -{ - int error; - - error = clk_enable(sc->sc_clk_pcie_axi); - if (error) { - aprint_error_dev(sc->sc_dev, "couldn't enable pcie_axi: %d\n", error); - return error; - } - error = clk_enable(sc->sc_clk_lvds1_gate); - if (error) { - aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n", error); - return error; - } - error = clk_enable(sc->sc_clk_pcie_ref); - if (error) { - aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error); - return error; - } - - return 0; -} - -static int -imx6pcie_init_phy(struct imx6pcie_softc *sc) -{ - uint32_t v; - - /* initialize IOMUX */ - v = iomux_read(IOMUX_GPR12); - v &= ~IOMUX_GPR12_APP_LTSSM_ENABLE; - iomux_write(IOMUX_GPR12, v); - - v &= ~IOMUX_GPR12_DEVICE_TYPE; - v |= IOMUX_GPR12_DEVICE_TYPE_PCIE_RC; - iomux_write(IOMUX_GPR12, v); - - v &= ~IOMUX_GPR12_LOS_LEVEL; - v |= __SHIFTIN(9, IOMUX_GPR12_LOS_LEVEL); - iomux_write(IOMUX_GPR12, v); - - v = 0; - v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_LOW); - v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_FULL); - v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_6DB); - v |= __SHIFTIN(0, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB); - v |= __SHIFTIN(0, IOMUX_GPR8_PCS_TX_DEEMPH_GEN1); - iomux_write(IOMUX_GPR8, v); - - return 0; -} - -static int -imx6pcie_phy_wait_ack(struct imx6pcie_softc *sc, int ack) -{ - uint32_t v; - int timeout; - - for (timeout = 10; timeout > 0; --timeout) { - v = PCIE_READ(sc, PCIE_PL_PHY_STATUS); - if (!!(v & PCIE_PL_PHY_STATUS_ACK) == !!ack) - return 0; - delay(1); - } - - return -1; -} - -static int -imx6pcie_phy_addr(struct imx6pcie_softc *sc, uint32_t addr) -{ - uint32_t v; - - v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA); - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); - - v |= PCIE_PL_PHY_CTRL_CAP_ADR; - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); - - if (imx6pcie_phy_wait_ack(sc, 1)) - return -1; - - v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA); - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); - - if (imx6pcie_phy_wait_ack(sc, 0)) - return -1; - - return 0; -} - -static int -imx6pcie_phy_write(struct imx6pcie_softc *sc, uint32_t addr, uint16_t data) -{ - /* write address */ - if (imx6pcie_phy_addr(sc, addr) != 0) - return -1; - - /* store data */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); - - /* assert CAP_DAT and wait ack */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA) | PCIE_PL_PHY_CTRL_CAP_DAT); - if (imx6pcie_phy_wait_ack(sc, 1)) - return -1; - - /* deassert CAP_DAT and wait ack */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); - if (imx6pcie_phy_wait_ack(sc, 0)) - return -1; - - /* assert WR and wait ack */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_WR); - if (imx6pcie_phy_wait_ack(sc, 1)) - return -1; - - /* deassert WR and wait ack */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); - if (imx6pcie_phy_wait_ack(sc, 0)) - return -1; - - /* done */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0); - - return 0; -} - -static int -imx6pcie_phy_read(struct imx6pcie_softc *sc, uint32_t addr) -{ - uint32_t v; - - /* write address */ - if (imx6pcie_phy_addr(sc, addr) != 0) - return -1; - - /* assert RD */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_RD); - if (imx6pcie_phy_wait_ack(sc, 1)) - return -1; - - /* read data */ - v = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_PHY_STATUS), - PCIE_PL_PHY_STATUS_DATA); - - /* deassert RD */ - PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0); - if (imx6pcie_phy_wait_ack(sc, 0)) - return -1; - - return v; -} - -static int -imx6pcie_assert_core_reset(struct imx6pcie_softc *sc) -{ - uint32_t gpr1; - uint32_t gpr12; - - gpr1 = iomux_read(IOMUX_GPR1); - gpr12 = iomux_read(IOMUX_GPR12); - - /* already enabled by bootloader */ - if ((gpr1 & IOMUX_GPR1_REF_SSP_EN) && - (gpr12 & IOMUX_GPR12_APP_LTSSM_ENABLE)) { - uint32_t v = PCIE_READ(sc, PCIE_PL_PFLR); - v &= ~PCIE_PL_PFLR_LINK_STATE; - v |= PCIE_PL_PFLR_FORCE_LINK; - PCIE_WRITE(sc, PCIE_PL_PFLR, v); - - gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE; - iomux_write(IOMUX_GPR12, gpr12); - } - -#if defined(IMX6DQP) - gpr1 |= IOMUX_GPR1_PCIE_SW_RST; - iomux_write(IOMUX_GPR1, gpr1); -#endif - - gpr1 |= IOMUX_GPR1_TEST_POWERDOWN; - iomux_write(IOMUX_GPR1, gpr1); - gpr1 &= ~IOMUX_GPR1_REF_SSP_EN; - iomux_write(IOMUX_GPR1, gpr1); - - return 0; -} - -static int -imx6pcie_deassert_core_reset(struct imx6pcie_softc *sc) -{ - uint32_t v; - - /* Power ON */ -#if NIMXGPIO > 0 - if (sc->sc_gpio_pwren >= 0) { - gpio_data_write(sc->sc_gpio_pwren, sc->sc_gpio_pwren_active); - delay(100 * 1000); - gpio_data_write(sc->sc_gpio_pwren, !sc->sc_gpio_pwren_active); - } -#endif - - v = iomux_read(IOMUX_GPR1); - -#if defined(IMX6DQP) - v &= ~IOMUX_GPR1_PCIE_SW_RST; - iomux_write(IOMUX_GPR1, v); -#endif - - delay(50 * 1000); - - v &= ~IOMUX_GPR1_TEST_POWERDOWN; - iomux_write(IOMUX_GPR1, v); - delay(10); - v |= IOMUX_GPR1_REF_SSP_EN; - iomux_write(IOMUX_GPR1, v); - - delay(50 * 1000); - - /* Reset */ -#if NIMXGPIO > 0 - if (sc->sc_gpio_reset >= 0) { - gpio_data_write(sc->sc_gpio_reset, sc->sc_gpio_reset_active); - delay(100 * 1000); - gpio_data_write(sc->sc_gpio_reset, !sc->sc_gpio_reset_active); - } -#endif - - return 0; -} - -static int -imx6pcie_wait_for_link(struct imx6pcie_softc *sc) -{ - uint32_t ltssm, valid, v; - int retry; - -#define LINKUP_RETRY 200 - for (retry = LINKUP_RETRY; retry > 0; --retry) { - if (!imx6pcie_linkup_status(sc)) { - delay(100); - continue; - } - - valid = imx6pcie_phy_read(sc, PCIE_PHY_RX_ASIC_OUT) & - PCIE_PHY_RX_ASIC_OUT_VALID; - ltssm = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_DEBUG0), - PCIE_PL_DEBUG0_XMLH_LTSSM_STATE); - - if ((ltssm == 0x0d) && !valid) { - aprint_normal_dev(sc->sc_dev, "resetting PCIe phy\n"); - - v = imx6pcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO); - v |= PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD; - v |= PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD; - imx6pcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v); - - delay(3000); - - v = imx6pcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO); - v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD; - v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD; - imx6pcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v); - } - - return 0; - } - - aprint_error_dev(sc->sc_dev, "Link Up failed.\n"); +static int imx6_pcie_match(device_t, cfdata_t, void *); +static void imx6_pcie_attach(device_t, device_t, void *); - return -1; -} - -static int -imx6pcie_wait_for_changespeed(struct imx6pcie_softc *sc) -{ - uint32_t v; - int retry; - -#define CHANGESPEED_RETRY 200 - for (retry = CHANGESPEED_RETRY; retry > 0; --retry) { - v = PCIE_READ(sc, PCIE_PL_G2CR); - if (!(v & PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE)) - return 0; - delay(100); - } - - aprint_error_dev(sc->sc_dev, "Speed change timeout.\n"); - - return -1; -} - -static void -imx6pcie_linkup(struct imx6pcie_softc *sc) -{ - uint32_t v; - int ret; +static void imx6_pcie_configure(void *); +static uint32_t imx6_pcie_gpr_read(void *, uint32_t); +static void imx6_pcie_gpr_write(void *, uint32_t, uint32_t); +static void imx6_pcie_reset(void *); - imx6pcie_assert_core_reset(sc); - imx6pcie_init_phy(sc); - imx6pcie_deassert_core_reset(sc); - - imx6pcie_setup(sc); - - /* GEN1 Operation */ - v = PCIE_READ(sc, PCIE_RC_LCR); - v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS; - v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; - PCIE_WRITE(sc, PCIE_RC_LCR, v); - - /* Link Up */ - v = iomux_read(IOMUX_GPR12); - v |= IOMUX_GPR12_APP_LTSSM_ENABLE; - iomux_write(IOMUX_GPR12, v); - - ret = imx6pcie_wait_for_link(sc); - if (ret) - goto error; - - /* Change speed */ - v = PCIE_READ(sc, PCIE_PL_G2CR); - v |= PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE; - PCIE_WRITE(sc, PCIE_PL_G2CR, v); - - ret = imx6pcie_wait_for_changespeed(sc); - if (ret) - goto error; - - /* Allow Gen2 mode */ - v = PCIE_READ(sc, PCIE_RC_LCR); - v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS; - v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2; - PCIE_WRITE(sc, PCIE_RC_LCR, v); - - ret = imx6pcie_wait_for_link(sc); - if (ret) - goto error; - - v = PCIE_READ(sc, PCIE_RC_LCSR); - aprint_normal_dev(sc->sc_dev, "LinkUp, Gen %d\n", - (int)__SHIFTOUT(v, PCIE_RC_LCSR_LINK_SPEED)); - - return; - -error: - aprint_error_dev(sc->sc_dev, - "PCIE_PL_DEBUG0,1 = %08x, %08x\n", - PCIE_READ(sc, PCIE_PL_DEBUG0), - PCIE_READ(sc, PCIE_PL_DEBUG1)); +#define IMX6_PCIE_MEM_BASE 0x01000000 +#define IMX6_PCIE_MEM_SIZE 0x00f00000 /* 15MB */ +#define IMX6_PCIE_ROOT_BASE 0x01f00000 +#define IMX6_PCIE_ROOT_SIZE 0x00080000 /* 512KB */ +#define IMX6_PCIE_IO_BASE 0x01f80000 +#define IMX6_PCIE_IO_SIZE 0x00010000 /* 64KB */ - return; -} +CFATTACH_DECL_NEW(imx6_pcie, sizeof(struct imx6_pcie_softc), + imx6_pcie_match, imx6_pcie_attach, NULL, NULL); static int -imx6pcie_match(device_t parent, cfdata_t cf, void *aux) +imx6_pcie_match(device_t parent, cfdata_t cf, void *aux) { struct axi_attach_args * const aa = aux; @@ -542,37 +119,37 @@ imx6pcie_match(device_t parent, cfdata_t } static void -imx6pcie_attach(device_t parent, device_t self, void *aux) +imx6_pcie_attach(device_t parent, device_t self, void *aux) { - struct imx6pcie_softc * const sc = device_private(self); + struct imx6_pcie_softc * const ipsc = device_private(self); + struct imxpcie_softc * const sc = &ipsc->sc_imxpcie; struct axi_attach_args * const aa = aux; - struct pcibus_attach_args pba; + + aprint_naive("\n"); + aprint_normal(": PCI Express Controller\n"); sc->sc_dev = self; sc->sc_iot = aa->aa_iot; sc->sc_dmat = aa->aa_dmat; + sc->sc_root_addr = IMX6_PCIE_ROOT_BASE; + sc->sc_root_size = IMX6_PCIE_ROOT_SIZE; + sc->sc_cookie = ipsc; + sc->sc_pci_netbsd_configure = imx6_pcie_configure; + sc->sc_gpr_read = imx6_pcie_gpr_read; + sc->sc_gpr_write = imx6_pcie_gpr_write; + sc->sc_reset = imx6_pcie_reset; if (aa->aa_size == AXICF_SIZE_DEFAULT) aa->aa_size = IMX6_PCIE_SIZE; - aprint_naive("\n"); - aprint_normal(": PCI Express Controller\n"); - if (bus_space_map(sc->sc_iot, aa->aa_addr, aa->aa_size, 0, &sc->sc_ioh)) { aprint_error_dev(self, "Cannot map registers\n"); return; } - if (bus_space_map(sc->sc_iot, IMX6_PCIE_ROOT_BASE, - IMX6_PCIE_ROOT_SIZE, 0, &sc->sc_root_ioh)) { - aprint_error_dev(self, "Cannot map registers\n"); - return; - } - imx6_set_gpio(self, "imx6pcie-reset-gpio", &sc->sc_gpio_reset, - &sc->sc_gpio_reset_active, GPIO_DIR_OUT); - imx6_set_gpio(self, "imx6pcie-pwren-gpio", &sc->sc_gpio_pwren, - &sc->sc_gpio_pwren_active, GPIO_DIR_OUT); + imx6_set_gpio(self, "imxpcie-reset-gpio", &ipsc->sc_gpio_reset, + &ipsc->sc_gpio_reset_active, GPIO_PIN_OUTPUT); sc->sc_clk_pcie_axi = imx6_get_clock("pcie_axi"); if (sc->sc_clk_pcie_axi == NULL) { @@ -590,15 +167,11 @@ imx6pcie_attach(device_t parent, device_ return; } - imx6pcie_init_clocks(sc); - - imx6pcie_linkup(sc); - TAILQ_INIT(&sc->sc_intrs); mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); sc->sc_ih = intr_establish(aa->aa_irq, IPL_VM, IST_LEVEL, - imx6pcie_intr, sc); + imxpcie_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "failed to establish interrupt on %d\n", aa->aa_irq); @@ -606,7 +179,14 @@ imx6pcie_attach(device_t parent, device_ } aprint_normal_dev(self, "interrupting on %d\n", aa->aa_irq); - imx6pcie_init(&sc->sc_pc, sc); + imxpcie_attach_common(sc); +} + +static void +imx6_pcie_configure(void *cookie) +{ + struct imx6_pcie_softc *ipsc = cookie; + struct imxpcie_softc *sc = &ipsc->sc_imxpcie; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; @@ -626,341 +206,34 @@ imx6pcie_attach(device_t parent, device_ extent_destroy(memext); if (error) { - aprint_error_dev(self, "configuration failed (%d)\n", + aprint_error_dev(sc->sc_dev, "configuration failed (%d)\n", error); - return; } #endif - - memset(&pba, 0, sizeof(pba)); - pba.pba_flags = PCI_FLAGS_MEM_OKAY | - PCI_FLAGS_IO_OKAY; - pba.pba_iot = sc->sc_iot; - pba.pba_memt = sc->sc_iot; - pba.pba_dmat = sc->sc_dmat; - pba.pba_pc = &sc->sc_pc; - pba.pba_bus = 0; - - config_found_ia(self, "pcibus", &pba, pcibusprint); -} - -static int -imx6pcie_intr(void *priv) -{ - struct imx6pcie_softc *sc = priv; - struct imx6pcie_ih *pcie_ih; - int rv = 0; - uint32_t v; - - for (int i = 0; i < 8; i++) { - v = PCIE_READ(sc, PCIE_PL_MSICIN_STATUS + i * 0xC); - int bit; - while ((bit = ffs(v) - 1) >= 0) { - PCIE_WRITE(sc, PCIE_PL_MSICIN_STATUS + i * 0xC, - __BIT(bit)); - v &= ~__BIT(bit); - } - } - - mutex_enter(&sc->sc_lock); - const u_int lastgen = sc->sc_intrgen; - TAILQ_FOREACH(pcie_ih, &sc->sc_intrs, ih_entry) { - int (*callback)(void *) = pcie_ih->ih_handler; - void *arg = pcie_ih->ih_arg; - mutex_exit(&sc->sc_lock); - rv += callback(arg); - mutex_enter(&sc->sc_lock); - if (lastgen != sc->sc_intrgen) - break; - } - mutex_exit(&sc->sc_lock); - - return rv; -} - -static void -imx6pcie_setup(struct imx6pcie_softc * const sc) -{ - uint32_t v; - - /* Setup RC */ - - /* BARs */ - PCIE_WRITE(sc, PCI_BAR0, 0x00000004); - PCIE_WRITE(sc, PCI_BAR1, 0x00000000); - - /* Interurupt pins */ - v = PCIE_READ(sc, PCI_INTERRUPT_REG); - v &= ~(PCI_INTERRUPT_PIN_MASK << PCI_INTERRUPT_PIN_SHIFT); - v |= PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT; - PCIE_WRITE(sc, PCI_INTERRUPT_REG, v); - - /* Bus number */ - v = PCIE_READ(sc, PCI_BRIDGE_BUS_REG); - v &= ~(PCI_BRIDGE_BUS_SUBORDINATE | PCI_BRIDGE_BUS_SECONDARY | - PCI_BRIDGE_BUS_PRIMARY); - v |= PCI_BRIDGE_BUS_NUM_SUBORDINATE(1); - v |= PCI_BRIDGE_BUS_NUM_SECONDARY(1); - v |= PCI_BRIDGE_BUS_NUM_PRIMARY(0); - PCIE_WRITE(sc, PCI_BRIDGE_BUS_REG, v); - - /* Command register */ - v = PCIE_READ(sc, PCI_COMMAND_STATUS_REG); - v |= PCI_COMMAND_IO_ENABLE | - PCI_COMMAND_MEM_ENABLE | - PCI_COMMAND_MASTER_ENABLE | - PCI_COMMAND_SERR_ENABLE; - PCIE_WRITE(sc, PCI_COMMAND_STATUS_REG, v); - - PCIE_WRITE(sc, PCI_CLASS_REG, - PCI_CLASS_CODE(PCI_CLASS_BRIDGE, - PCI_SUBCLASS_BRIDGE_PCI, PCI_INTERFACE_BRIDGE_PCI_PCI)); - - PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); - - PCIE_WRITE(sc, PCIE_PL_IATURLBA, IMX6_PCIE_ROOT_BASE); - PCIE_WRITE(sc, PCIE_PL_IATURUBA, 0); - PCIE_WRITE(sc, PCIE_PL_IATURLA, IMX6_PCIE_ROOT_BASE + IMX6_PCIE_ROOT_SIZE); - - PCIE_WRITE(sc, PCIE_PL_IATURLTA, 0); - PCIE_WRITE(sc, PCIE_PL_IATURUTA, 0); - PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); - PCIE_WRITE(sc, PCIE_PL_IATURC2, PCIE_PL_IATURC2_REGION_ENABLE); -} - -void -imx6pcie_init(pci_chipset_tag_t pc, void *priv) -{ - pc->pc_conf_v = priv; - pc->pc_attach_hook = imx6pcie_attach_hook; - pc->pc_bus_maxdevs = imx6pcie_bus_maxdevs; - pc->pc_make_tag = imx6pcie_make_tag; - pc->pc_decompose_tag = imx6pcie_decompose_tag; - pc->pc_conf_read = imx6pcie_conf_read; - pc->pc_conf_write = imx6pcie_conf_write; -#ifdef __HAVE_PCI_CONF_HOOK - pc->pc_conf_hook = imx6pcie_conf_hook; -#endif - pc->pc_conf_interrupt = imx6pcie_conf_interrupt; - - pc->pc_intr_v = priv; - pc->pc_intr_map = imx6pcie_intr_map; - pc->pc_intr_string = imx6pcie_intr_string; - pc->pc_intr_evcnt = imx6pcie_intr_evcnt; - pc->pc_intr_establish = imx6pcie_intr_establish; - pc->pc_intr_disestablish = imx6pcie_intr_disestablish; -} - -static void -imx6pcie_attach_hook(device_t parent, device_t self, - struct pcibus_attach_args *pba) -{ - /* nothing to do */ -} - -static int -imx6pcie_bus_maxdevs(void *v, int busno) -{ - return 32; -} - -static pcitag_t -imx6pcie_make_tag(void *v, int b, int d, int f) -{ - return (b << 16) | (d << 11) | (f << 8); } -static void -imx6pcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) +static uint32_t +imx6_pcie_gpr_read(void *cookie, uint32_t reg) { - if (bp) - *bp = (tag >> 16) & 0xff; - if (dp) - *dp = (tag >> 11) & 0x1f; - if (fp) - *fp = (tag >> 8) & 0x7; + return iomux_read(reg); } -/* - * work around. - * If there is no PCIe devices, DABT will be generated by read/write access to - * config area, so replace original DABT handler with simple jump-back one. - */ -extern u_int data_abort_handler_address; -static bool data_abort_flag; static void -imx6pcie_data_abort_handler(trapframe_t *tf) -{ - data_abort_flag = true; - tf->tf_pc += 0x4; - return; -} - -static pcireg_t -imx6pcie_conf_read(void *v, pcitag_t tag, int offset) +imx6_pcie_gpr_write(void *cookie, uint32_t reg, uint32_t val) { - struct imx6pcie_softc *sc = v; - bus_space_handle_t bsh; - int b, d, f; - pcireg_t ret = -1; - int s; - - imx6pcie_decompose_tag(v, tag, &b, &d, &f); - - if ((unsigned int)offset >= PCI_EXTCONF_SIZE) - return ret; - if (!imx6pcie_valid_device(sc, b, d)) - return ret; - - PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); - if (b < 2) - PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); - else - PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1); - - if (b == 0) { - bsh = sc->sc_ioh; - } else { - PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8); - bsh = sc->sc_root_ioh; - } - PCIE_READ(sc, PCIE_PL_IATURC2); - - PCIE_CONF_LOCK(s); - - u_int saved = data_abort_handler_address; - data_abort_handler_address = (u_int)imx6pcie_data_abort_handler; - data_abort_flag = false; - - ret = bus_space_read_4(sc->sc_iot, bsh, offset & ~0x3); - - data_abort_handler_address = saved; - - PCIE_CONF_UNLOCK(s); - - if (data_abort_flag) - ret = -1; - - return ret; + iomux_write(reg, val); } static void -imx6pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val) +imx6_pcie_reset(void *cookie) { - struct imx6pcie_softc *sc = v; - bus_space_handle_t bsh; - int b, d, f; - int s; - - imx6pcie_decompose_tag(v, tag, &b, &d, &f); - - if ((unsigned int)offset >= PCI_EXTCONF_SIZE) - return; - if (!imx6pcie_valid_device(sc, b, d)) - return; + struct imx6_pcie_softc *ipsc = cookie; - PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); - if (b < 2) - PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); - else - PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1); - - if (b == 0) { - bsh = sc->sc_ioh; - } else { - PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8); - bsh = sc->sc_root_ioh; +#if NIMXGPIO > 0 + if (ipsc->sc_gpio_reset >= 0) { + gpio_data_write(ipsc->sc_gpio_reset, ipsc->sc_gpio_reset_active); + delay(100 * 1000); + gpio_data_write(ipsc->sc_gpio_reset, !ipsc->sc_gpio_reset_active); } - PCIE_READ(sc, PCIE_PL_IATURC2); - - PCIE_CONF_LOCK(s); - - u_int saved = data_abort_handler_address; - data_abort_handler_address = (u_int)imx6pcie_data_abort_handler; - - bus_space_write_4(sc->sc_iot, bsh, offset & ~0x3, val); - - data_abort_handler_address = saved; - - PCIE_CONF_UNLOCK(s); - - return; -} - -#ifdef __HAVE_PCI_CONF_HOOK -static int -imx6pcie_conf_hook(void *v, int b, int d, int f, pcireg_t id) -{ - return PCI_CONF_DEFAULT; -} #endif - -static void -imx6pcie_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz, - int *ilinep) -{ - /* nothing to do */ -} - -static int -imx6pcie_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih) -{ - if (pa->pa_intrpin == 0) - return EINVAL; - *ih = pa->pa_intrpin; - return 0; -} - -static const char * -imx6pcie_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len) -{ - if (ih == PCI_INTERRUPT_PIN_NONE) - return NULL; - - strlcpy(buf, "pci", len); - - return buf; -} - -const struct evcnt * -imx6pcie_intr_evcnt(void *v, pci_intr_handle_t ih) -{ - return NULL; -} - -static void * -imx6pcie_intr_establish(void *v, pci_intr_handle_t ih, int ipl, - int (*callback)(void *), void *arg, const char *xname) -{ - struct imx6pcie_softc *sc = v; - struct imx6pcie_ih *pcie_ih; - - if (ih == 0) - return NULL; - - pcie_ih = kmem_alloc(sizeof(*pcie_ih), KM_SLEEP); - pcie_ih->ih_handler = callback; - pcie_ih->ih_arg = arg; - pcie_ih->ih_ipl = ipl; - - mutex_enter(&sc->sc_lock); - TAILQ_INSERT_TAIL(&sc->sc_intrs, pcie_ih, ih_entry); - sc->sc_intrgen++; - mutex_exit(&sc->sc_lock); - - return pcie_ih; -} - -static void -imx6pcie_intr_disestablish(void *v, void *vih) -{ - struct imx6pcie_softc *sc = v; - struct imx6pcie_ih *pcie_ih = vih; - - mutex_enter(&sc->sc_lock); - TAILQ_REMOVE(&sc->sc_intrs, pcie_ih, ih_entry); - sc->sc_intrgen++; - mutex_exit(&sc->sc_lock); - - kmem_free(pcie_ih, sizeof(*pcie_ih)); } Index: src/sys/arch/arm/imx/imx6_usdhc.c diff -u src/sys/arch/arm/imx/imx6_usdhc.c:1.7 src/sys/arch/arm/imx/imx6_usdhc.c:1.8 --- src/sys/arch/arm/imx/imx6_usdhc.c:1.7 Thu Jun 20 08:16:19 2019 +++ src/sys/arch/arm/imx/imx6_usdhc.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx6_usdhc.c,v 1.7 2019/06/20 08:16:19 hkenken Exp $ */ +/* $NetBSD: imx6_usdhc.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2012 Genetec Corporation. All rights reserved. * Written by Hiroyuki Bessho for Genetec Corporation. @@ -28,10 +28,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx6_usdhc.c,v 1.7 2019/06/20 08:16:19 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx6_usdhc.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $"); #include "imxgpio.h" +#define _INTR_PRIVATE + #include <sys/param.h> #include <sys/device.h> #include <sys/systm.h> @@ -115,22 +117,22 @@ sdhc_attach(device_t parent, device_t se case IMX6_AIPS2_BASE + AIPS2_USDHC1_BASE: sc->sc_clk = imx6_get_clock("usdhc1"); imx6_set_gpio(self, "usdhc1-cd-gpio", &sc->sc_gpio_cd, - &sc->sc_gpio_cd_active, GPIO_DIR_IN); + &sc->sc_gpio_cd_active, GPIO_PIN_INPUT); break; case IMX6_AIPS2_BASE + AIPS2_USDHC2_BASE: sc->sc_clk = imx6_get_clock("usdhc2"); imx6_set_gpio(self, "usdhc2-cd-gpio", &sc->sc_gpio_cd, - &sc->sc_gpio_cd_active, GPIO_DIR_IN); + &sc->sc_gpio_cd_active, GPIO_PIN_INPUT); break; case IMX6_AIPS2_BASE + AIPS2_USDHC3_BASE: sc->sc_clk = imx6_get_clock("usdhc3"); imx6_set_gpio(self, "usdhc3-cd-gpio", &sc->sc_gpio_cd, - &sc->sc_gpio_cd_active, GPIO_DIR_IN); + &sc->sc_gpio_cd_active, GPIO_PIN_INPUT); break; case IMX6_AIPS2_BASE + AIPS2_USDHC4_BASE: sc->sc_clk = imx6_get_clock("usdhc4"); imx6_set_gpio(self, "usdhc4-cd-gpio", &sc->sc_gpio_cd, - &sc->sc_gpio_cd_active, GPIO_DIR_IN); + &sc->sc_gpio_cd_active, GPIO_PIN_INPUT); break; } Index: src/sys/arch/arm/imx/imx7_gpio.c diff -u src/sys/arch/arm/imx/imx7_gpio.c:1.1 src/sys/arch/arm/imx/imx7_gpio.c:1.2 --- src/sys/arch/arm/imx/imx7_gpio.c:1.1 Tue May 17 06:44:45 2016 +++ src/sys/arch/arm/imx/imx7_gpio.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx7_gpio.c,v 1.1 2016/05/17 06:44:45 ryo Exp $ */ +/* $NetBSD: imx7_gpio.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,11 +30,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx7_gpio.c,v 1.1 2016/05/17 06:44:45 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx7_gpio.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $"); #include "locators.h" #include "gpio.h" +#define _INTR_PRIVATE + #include <sys/param.h> #include <sys/evcnt.h> #include <sys/atomic.h> @@ -81,9 +83,10 @@ imxgpio_match(device_t parent __unused, void imxgpio_attach(device_t parent __unused, device_t self, void *aux) { + struct imxgpio_softc * const gpio = device_private(self); struct axi_attach_args * const aa = aux; bus_space_handle_t ioh; - int error, group; + int error; if (aa->aa_irq == AXICF_IRQ_DEFAULT && aa->aa_irqbase != AXICF_IRQBASE_DEFAULT) { @@ -100,14 +103,23 @@ imxgpio_attach(device_t parent __unused, error = bus_space_map(aa->aa_iot, aa->aa_addr, aa->aa_size, 0, &ioh); - if (error) { aprint_error(": failed to map register %#lx@%#lx: %d\n", aa->aa_size, aa->aa_addr, error); return; } - group = (aa->aa_addr - IMX7_AIPS_BASE - AIPS1_GPIO1_BASE) / 0x10000; - imxgpio_attach_common(self, aa->aa_iot, ioh, group, - aa->aa_irq, aa->aa_irqbase); + gpio->gpio_is = intr_establish(aa->aa_irq, + IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); + KASSERT(gpio->gpio_is != NULL ); + gpio->gpio_is_high = intr_establish(aa->aa_irq + 1, + IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); + KASSERT(gpio->gpio_is_high != NULL); + + gpio->gpio_memt = aa->aa_iot; + gpio->gpio_memh = ioh; + gpio->gpio_unit = (aa->aa_addr - IMX7_AIPS_BASE - AIPS1_GPIO1_BASE) / 0x10000; + gpio->gpio_irqbase = aa->aa_irqbase; + + imxgpio_attach_common(self); } Index: src/sys/arch/arm/imx/imxgpiovar.h diff -u src/sys/arch/arm/imx/imxgpiovar.h:1.1 src/sys/arch/arm/imx/imxgpiovar.h:1.2 --- src/sys/arch/arm/imx/imxgpiovar.h:1.1 Tue Nov 30 13:05:27 2010 +++ src/sys/arch/arm/imx/imxgpiovar.h Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imxgpiovar.h,v 1.1 2010/11/30 13:05:27 bsh Exp $ */ +/* $NetBSD: imxgpiovar.h,v 1.2 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. * All rights reserved. @@ -27,27 +27,59 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _ARM_IMX_IMXGRPIOVAR_H -#define _ARM_IMX_IMXGRPIOVAR_H +#ifndef _ARM_IMX_IMXGPIOVAR_H +#define _ARM_IMX_IMXGPIOVAR_H + +#include <sys/gpio.h> +#include <dev/gpio/gpiovar.h> -#include <sys/bus.h> -#include <sys/device.h> #include <arm/imx/imxgpioreg.h> /* for GPIO_NPINS */ -void imxgpio_attach_common(device_t, bus_space_tag_t, bus_space_handle_t, - int, int, int); +struct imxgpio_softc { + struct pic_softc gpio_pic; + + device_t gpio_dev; + bus_space_tag_t gpio_memt; + bus_space_handle_t gpio_memh; + + void *gpio_is; + void *gpio_is_high; + + uint gpio_unit; + uint gpio_irqbase; + uint32_t gpio_enable_mask; + uint32_t gpio_edge_mask; + uint32_t gpio_level_mask; +#if NGPIO > 0 + struct gpio_chipset_tag gpio_chipset; + gpio_pin_t gpio_pins[32]; +#endif + + kmutex_t gpio_lock; +}; + +struct imxgpio_pin { + int pin_no; + u_int pin_flags; + bool pin_actlo; +}; + +void imxgpio_attach_common(device_t); /* defined imx[35]1_gpio.c */ extern const int imxgpio_ngroups; int imxgpio_match(device_t, cfdata_t, void *); void imxgpio_attach(device_t, device_t, void *); - -#define GPIO_NO(group, pin) (((group) - 1) * GPIO_NPINS + (pin)) -#define GPIO_MODULE(pin) ((pin) / GPIO_NPINS) +int imxgpio_pin_read(void *, int); +void imxgpio_pin_write(void *, int, int); +void imxgpio_pin_ctl(void *, int, int); /* in-kernel GPIO access utility functions */ -enum GPIO_DIRECTION {GPIO_DIR_IN, GPIO_DIR_OUT}; -void gpio_set_direction(u_int, enum GPIO_DIRECTION); +void gpio_set_direction(u_int, int); void gpio_data_write(u_int, u_int); bool gpio_data_read(u_int); -#endif /* _ARM_IMX_IMXGRPIOVAR_H */ + +#define GPIO_NO(group, pin) (((group) - 1) * GPIO_NPINS + (pin)) +#define GPIO_MODULE(pin) ((pin) / GPIO_NPINS) + +#endif /* _ARM_IMX_IMXGPIOVAR_H */ Index: src/sys/arch/arm/imx/imxgpio.c diff -u src/sys/arch/arm/imx/imxgpio.c:1.5 src/sys/arch/arm/imx/imxgpio.c:1.6 --- src/sys/arch/arm/imx/imxgpio.c:1.5 Thu Sep 25 05:05:28 2014 +++ src/sys/arch/arm/imx/imxgpio.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imxgpio.c,v 1.5 2014/09/25 05:05:28 ryo Exp $ */ +/* $NetBSD: imxgpio.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -29,19 +29,17 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 1.5 2014/09/25 05:05:28 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $"); #define _INTR_PRIVATE #include "locators.h" #include "gpio.h" -#include "opt_imxgpio.h" #include <sys/param.h> #include <sys/evcnt.h> #include <sys/atomic.h> - -#include <uvm/uvm_extern.h> +#include <sys/bus.h> #include <machine/intr.h> @@ -49,13 +47,6 @@ __KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v #include <arm/armreg.h> #include <arm/cpufunc.h> -#include <sys/bus.h> - -#include <arm/imx/imx31reg.h> -#include <arm/imx/imx31var.h> -#include <arm/imx/imxgpioreg.h> -#include <arm/pic/picvar.h> - #include <arm/imx/imxgpioreg.h> #include <arm/imx/imxgpiovar.h> @@ -67,68 +58,37 @@ __KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v #define MAX_NGROUP 8 -static void gpio_pic_block_irqs(struct pic_softc *, size_t, uint32_t); -static void gpio_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); -static int gpio_pic_find_pending_irqs(struct pic_softc *); -static void gpio_pic_establish_irq(struct pic_softc *, struct intrsource *); - -const struct pic_ops gpio_pic_ops = { - .pic_unblock_irqs = gpio_pic_unblock_irqs, - .pic_block_irqs = gpio_pic_block_irqs, - .pic_find_pending_irqs = gpio_pic_find_pending_irqs, - .pic_establish_irq = gpio_pic_establish_irq, +static void imxgpio_pic_block_irqs(struct pic_softc *, size_t, uint32_t); +static void imxgpio_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); +static int imxgpio_pic_find_pending_irqs(struct pic_softc *); +static void imxgpio_pic_establish_irq(struct pic_softc *, struct intrsource *); + +const struct pic_ops imxgpio_pic_ops = { + .pic_unblock_irqs = imxgpio_pic_unblock_irqs, + .pic_block_irqs = imxgpio_pic_block_irqs, + .pic_find_pending_irqs = imxgpio_pic_find_pending_irqs, + .pic_establish_irq = imxgpio_pic_establish_irq, .pic_source_name = NULL }; -struct gpio_softc { - device_t gpio_dev; - struct pic_softc gpio_pic; -#if defined(IMX_GPIO_INTR_SPLIT) - struct intrsource *gpio_is_0_15; - struct intrsource *gpio_is_16_31; -#else - struct intrsource *gpio_is; -#endif - bus_space_tag_t gpio_memt; - bus_space_handle_t gpio_memh; - uint32_t gpio_enable_mask; - uint32_t gpio_edge_mask; - uint32_t gpio_level_mask; -#if NGPIO > 0 - struct gpio_chipset_tag gpio_chipset; - gpio_pin_t gpio_pins[32]; -#endif -}; +static struct imxgpio_softc *imxgpio_handles[MAX_NGROUP]; -static struct { - bus_space_tag_t iot; - struct { - bus_space_handle_t ioh; - struct gpio_softc *softc; - } unit[MAX_NGROUP]; -} gpio_handles; - -extern struct cfdriver imxgpio_cd; - -CFATTACH_DECL_NEW(imxgpio, - sizeof(struct gpio_softc), - imxgpio_match, imxgpio_attach, - NULL, NULL); - - -#define PIC_TO_SOFTC(pic) \ - ((struct gpio_softc *)((char *)(pic) - \ - offsetof(struct gpio_softc, gpio_pic))) +CFATTACH_DECL_NEW(imxgpio, sizeof(struct imxgpio_softc), + imxgpio_match, imxgpio_attach, NULL, NULL); -#define GPIO_READ(gpio, reg) \ +#define PIC_TO_SOFTC(pic) \ + ((struct imxgpio_softc *)((char *)(pic) - \ + offsetof(struct imxgpio_softc, gpio_pic))) + +#define GPIO_READ(gpio, reg) \ bus_space_read_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg)) -#define GPIO_WRITE(gpio, reg, val) \ +#define GPIO_WRITE(gpio, reg, val) \ bus_space_write_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg), (val)) void -gpio_pic_unblock_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) +imxgpio_pic_unblock_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) { - struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); + struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic); KASSERT(irq_base == 0); gpio->gpio_enable_mask |= irq_mask; @@ -138,9 +98,9 @@ gpio_pic_unblock_irqs(struct pic_softc * } void -gpio_pic_block_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) +imxgpio_pic_block_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask) { - struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); + struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic); KASSERT(irq_base == 0); gpio->gpio_enable_mask &= ~irq_mask; @@ -148,9 +108,9 @@ gpio_pic_block_irqs(struct pic_softc *pi } int -gpio_pic_find_pending_irqs(struct pic_softc *pic) +imxgpio_pic_find_pending_irqs(struct pic_softc *pic) { - struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); + struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic); uint32_t v; uint32_t pending; @@ -213,9 +173,9 @@ gpio_pic_find_pending_irqs(struct pic_so (GPIO_ICR_EDGE_RISING << (2*IST_EDGE_BOTH))) void -gpio_pic_establish_irq(struct pic_softc *pic, struct intrsource *is) +imxgpio_pic_establish_irq(struct pic_softc *pic, struct intrsource *is) { - struct gpio_softc * const gpio = PIC_TO_SOFTC(pic); + struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic); KASSERT(is->is_irq < 32); uint32_t irq_mask = __BIT(is->is_irq); uint32_t v; @@ -265,20 +225,26 @@ gpio_pic_establish_irq(struct pic_softc #if NGPIO > 0 -static int +int imxgpio_pin_read(void *arg, int pin) { - struct gpio_softc * const gpio = arg; + struct imxgpio_softc * const gpio = arg; + int val; + + val = __SHIFTOUT(GPIO_READ(gpio, GPIO_DR), __BIT(pin)); - return (GPIO_READ(gpio, GPIO_DR) >> pin) & 1; + return val; } -static void +void imxgpio_pin_write(void *arg, int pin, int value) { - struct gpio_softc * const gpio = arg; - uint32_t mask = 1 << pin; - uint32_t old, new; + struct imxgpio_softc * const gpio = arg; + uint32_t mask = __BIT(pin); + uint32_t old; + uint32_t new; + + mutex_enter(&gpio->gpio_lock); old = GPIO_READ(gpio, GPIO_DR); if (value) @@ -288,30 +254,43 @@ imxgpio_pin_write(void *arg, int pin, in if (old != new) GPIO_WRITE(gpio, GPIO_DR, new); + + mutex_exit(&gpio->gpio_lock); } -static void +void imxgpio_pin_ctl(void *arg, int pin, int flags) { - struct gpio_softc * const gpio = arg; - uint32_t mask = 1 << pin; - uint32_t old, new; + struct imxgpio_softc * const gpio = arg; + uint32_t mask = __BIT(pin); + uint32_t old; + uint32_t new; + + mutex_enter(&gpio->gpio_lock); old = GPIO_READ(gpio, GPIO_DIR); new = old; - switch (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { - case GPIO_PIN_INPUT: new &= ~mask; break; - case GPIO_PIN_OUTPUT: new |= mask; break; - default: return; + switch (flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) { + case GPIO_PIN_INPUT: + new &= ~mask; + break; + case GPIO_PIN_OUTPUT: + new |= mask; + break; + default: + break; } + if (old != new) GPIO_WRITE(gpio, GPIO_DIR, new); + + mutex_exit(&gpio->gpio_lock); } static void gpio_defer(device_t self) { - struct gpio_softc * const gpio = device_private(self); + struct imxgpio_softc * const gpio = device_private(self); struct gpio_chipset_tag * const gp = &gpio->gpio_chipset; struct gpiobus_attach_args gba; gpio_pin_t *pins; @@ -332,7 +311,7 @@ gpio_defer(device_t self) for (pin = 0, mask = 1, pins = gpio->gpio_pins; pin < 32; pin++, mask <<= 1, pins++) { pins->pin_num = pin; - if ((gpio->gpio_edge_mask|gpio->gpio_level_mask) & mask) + if ((gpio->gpio_edge_mask | gpio->gpio_level_mask) & mask) pins->pin_caps = GPIO_PIN_INPUT; else pins->pin_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT; @@ -347,112 +326,69 @@ gpio_defer(device_t self) #endif /* NGPIO > 0 */ void -imxgpio_attach_common(device_t self, bus_space_tag_t iot, - bus_space_handle_t ioh, int index, int intr, int irqbase) +imxgpio_attach_common(device_t self) { - struct gpio_softc * const gpio = device_private(self); + struct imxgpio_softc * const gpio = device_private(self); - KASSERT(index < MAX_NGROUP); + KASSERT(gpio->gpio_unit < MAX_NGROUP); gpio->gpio_dev = self; - gpio->gpio_memt = iot; - gpio->gpio_memh = ioh; - if (irqbase > 0) { - gpio->gpio_pic.pic_ops = &gpio_pic_ops; + if (gpio->gpio_irqbase > 0) { + aprint_normal_dev(gpio->gpio_dev, "interrupts %d..%d\n", + gpio->gpio_irqbase, gpio->gpio_irqbase + GPIO_NPINS - 1); + + gpio->gpio_pic.pic_ops = &imxgpio_pic_ops; strlcpy(gpio->gpio_pic.pic_name, device_xname(self), sizeof(gpio->gpio_pic.pic_name)); gpio->gpio_pic.pic_maxsources = 32; - pic_add(&gpio->gpio_pic, irqbase); - - aprint_normal(": interrupts %d..%d", - irqbase, irqbase + GPIO_NPINS - 1); - -#if defined(IMX_GPIO_INTR_SPLIT) - gpio->gpio_is_0_15 = intr_establish(intr, - IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); - KASSERT( gpio->gpio_is_0_15 != NULL ); - gpio->gpio_is_16_31 = intr_establish(intr + 1, - IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); - KASSERT( gpio->gpio_is_16_31 != NULL ); -#else - gpio->gpio_is = intr_establish(intr, - IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic); - KASSERT( gpio->gpio_is != NULL ); -#endif + pic_add(&gpio->gpio_pic, gpio->gpio_irqbase); } - aprint_normal("\n"); - gpio_handles.iot = iot; - gpio_handles.unit[index].softc = gpio; - gpio_handles.unit[index].ioh = ioh; + mutex_init(&gpio->gpio_lock, MUTEX_DEFAULT, IPL_VM); + + imxgpio_handles[gpio->gpio_unit] = gpio; #if NGPIO > 0 config_interrupts(self, gpio_defer); #endif } -#define GPIO_GROUP_READ(index,offset) \ - bus_space_read_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \ - (offset)) -#define GPIO_GROUP_WRITE(index,offset,value) \ - bus_space_write_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \ - (offset), (value)) - +/* in-kernel GPIO access utility functions */ void -gpio_set_direction(u_int gpio, u_int dir) +gpio_set_direction(u_int gpio, int dir) { int index = gpio / GPIO_NPINS; - int bit = gpio % GPIO_NPINS; - uint32_t reg; + int pin = gpio % GPIO_NPINS; KDASSERT(index < imxgpio_ngroups); + KASSERT(imxgpio_handles[index] != NULL); - /* XXX lock */ - - - reg = GPIO_GROUP_READ(index, GPIO_DIR); - if (dir == GPIO_DIR_OUT) - reg |= __BIT(bit); - else - reg &= ~__BIT(bit); - GPIO_GROUP_WRITE(index, GPIO_DIR, reg); - - /* XXX unlock */ + imxgpio_pin_ctl(imxgpio_handles[index], pin, dir); } - void gpio_data_write(u_int gpio, u_int value) { int index = gpio / GPIO_NPINS; - int bit = gpio % GPIO_NPINS; - uint32_t reg; + int pin = gpio % GPIO_NPINS; KDASSERT(index < imxgpio_ngroups); + KASSERT(imxgpio_handles[index] != NULL); - /* XXX lock */ - reg = GPIO_GROUP_READ(index, GPIO_DR); - if (value) - reg |= __BIT(bit); - else - reg &= ~__BIT(bit); - GPIO_GROUP_WRITE(index, GPIO_DR, reg); - - /* XXX unlock */ + imxgpio_pin_write(imxgpio_handles[index], pin, value); } bool gpio_data_read(u_int gpio) { int index = gpio / GPIO_NPINS; - int bit = gpio % GPIO_NPINS; - uint32_t reg; + int pin = gpio % GPIO_NPINS; KDASSERT(index < imxgpio_ngroups); + KASSERT(imxgpio_handles[index] != NULL); - reg = GPIO_GROUP_READ(index, GPIO_DR); - - return reg & __BIT(bit) ? true : false; + return imxgpio_pin_read(imxgpio_handles[index], pin) ? true : false; } + Index: src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3 diff -u src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3:1.18 src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3:1.19 --- src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3:1.18 Sat May 18 08:49:23 2019 +++ src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3 Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: ARMADILLO-IOT-G3,v 1.18 2019/05/18 08:49:23 skrll Exp $ +# $NetBSD: ARMADILLO-IOT-G3,v 1.19 2019/07/24 12:33:18 hkenken Exp $ # # ARMADILLO-IOT-G3 -- Atmark Techno, Armadillo-IoT G3 # @@ -201,7 +201,6 @@ imxgpio4 at axi? addr 0x30220000 irqbase imxgpio5 at axi? addr 0x30210000 irqbase 416 irq 106 imxgpio6 at axi? addr 0x30200000 irqbase 448 irq 108 gpio* at imxgpio? -options IMX_GPIO_INTR_SPLIT # Clock Control imxccm0 at axi? addr 0x30380000 Index: src/sys/arch/evbarm/conf/CUBOX-I diff -u src/sys/arch/evbarm/conf/CUBOX-I:1.20 src/sys/arch/evbarm/conf/CUBOX-I:1.21 --- src/sys/arch/evbarm/conf/CUBOX-I:1.20 Fri Apr 26 22:46:03 2019 +++ src/sys/arch/evbarm/conf/CUBOX-I Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: CUBOX-I,v 1.20 2019/04/26 22:46:03 sevan Exp $ +# $NetBSD: CUBOX-I,v 1.21 2019/07/24 12:33:18 hkenken Exp $ # # CuBox-i # - http://www.solid-run.com/products/cubox-i-mini-computer/ @@ -208,7 +208,6 @@ imxgpio4 at axi? addr 0x020ac000 irqbase imxgpio5 at axi? addr 0x020b0000 irqbase 416 irq 108 imxgpio6 at axi? addr 0x020b4000 irqbase 448 irq 110 gpio* at imxgpio? -options IMX_GPIO_INTR_SPLIT # Clock Control imxccm0 at axi? addr 0x020c4000 Index: src/sys/arch/evbarm/conf/HUMMINGBOARD diff -u src/sys/arch/evbarm/conf/HUMMINGBOARD:1.7 src/sys/arch/evbarm/conf/HUMMINGBOARD:1.8 --- src/sys/arch/evbarm/conf/HUMMINGBOARD:1.7 Wed Feb 6 11:58:30 2019 +++ src/sys/arch/evbarm/conf/HUMMINGBOARD Wed Jul 24 12:33:18 2019 @@ -1,5 +1,5 @@ # -# $NetBSD: HUMMINGBOARD,v 1.7 2019/02/06 11:58:30 rin Exp $ +# $NetBSD: HUMMINGBOARD,v 1.8 2019/07/24 12:33:18 hkenken Exp $ # # Hummingboard -- Freescale i.MX6 Eval Board Kernel # @@ -71,7 +71,6 @@ imxgpio4 at axi? addr 0x020ac000 irqbase imxgpio5 at axi? addr 0x020b0000 irqbase 416 irq 108 imxgpio6 at axi? addr 0x020b4000 irqbase 448 irq 110 gpio* at imxgpio? -options IMX_GPIO_INTR_SPLIT # Clock Control imxccm0 at axi? addr 0x020c4000 Index: src/sys/arch/evbarm/conf/IMX6UL-STARTER diff -u src/sys/arch/evbarm/conf/IMX6UL-STARTER:1.12 src/sys/arch/evbarm/conf/IMX6UL-STARTER:1.13 --- src/sys/arch/evbarm/conf/IMX6UL-STARTER:1.12 Fri Apr 26 22:46:03 2019 +++ src/sys/arch/evbarm/conf/IMX6UL-STARTER Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: IMX6UL-STARTER,v 1.12 2019/04/26 22:46:03 sevan Exp $ +# $NetBSD: IMX6UL-STARTER,v 1.13 2019/07/24 12:33:18 hkenken Exp $ # # IMX6UL-STARTER - Freescale i.MX6UL Evaluation Board # @@ -210,7 +210,6 @@ imxgpio2 at axi? addr 0x020a4000 irqbase imxgpio3 at axi? addr 0x020a8000 irqbase 352 irq 104 imxgpio4 at axi? addr 0x020ac000 irqbase 384 irq 106 gpio* at imxgpio? -options IMX_GPIO_INTR_SPLIT # Clock Control imxccm0 at axi? addr 0x020c4000 Index: src/sys/arch/evbarm/conf/KOBO diff -u src/sys/arch/evbarm/conf/KOBO:1.9 src/sys/arch/evbarm/conf/KOBO:1.10 --- src/sys/arch/evbarm/conf/KOBO:1.9 Wed Feb 6 11:58:30 2019 +++ src/sys/arch/evbarm/conf/KOBO Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: KOBO,v 1.9 2019/02/06 11:58:30 rin Exp $ +# $NetBSD: KOBO,v 1.10 2019/07/24 12:33:18 hkenken Exp $ # # KOBO -- http://kobo.com # @@ -84,6 +84,7 @@ imxgpio2 at axi? addr 0x53f8c000 irqbase imxgpio3 at axi? addr 0x53f90000 irqbase 224 irq 56 imxgpio4 at axi? addr 0x53fdc000 irqbase 256 irq 103 imxgpio5 at axi? addr 0x53fe0000 irqbase 288 irq 105 +gpio* at imxgpio? # EPDC E-Ink Controller #epdc0 at axi? addr 0x41010000 size 0x2000 irq 27 Index: src/sys/arch/evbarm/conf/NETWALKER diff -u src/sys/arch/evbarm/conf/NETWALKER:1.37 src/sys/arch/evbarm/conf/NETWALKER:1.38 --- src/sys/arch/evbarm/conf/NETWALKER:1.37 Wed Feb 6 11:58:30 2019 +++ src/sys/arch/evbarm/conf/NETWALKER Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: NETWALKER,v 1.37 2019/02/06 11:58:30 rin Exp $ +# $NetBSD: NETWALKER,v 1.38 2019/07/24 12:33:18 hkenken Exp $ # # NETWALKER -- http://www.sharp.co.jp/netwalker/ # @@ -17,7 +17,7 @@ options CONSDEVNAME="\"imxuart\"",CONAD options CONSPEED=115200 # Console speed # Development and Debugging options -#options DEBUG +#options DEBUG #options KGDB makeoptions DEBUG="-g" # compile full symbol table makeoptions COPY_SYMTAB=1 @@ -35,7 +35,7 @@ options BOOT_ARGS="\"verbose console=fb #options BOOT_ARGS="\"verbose\"" # Kernel root file system and dump configuration. -config netbsd root on ? type ? +#config netbsd root on ? type ? config netbsd-ld0 root on ld0 type ffs # The main bus device @@ -79,7 +79,6 @@ imxgpio1 at axi? addr 0x73f88000 irqbase imxgpio2 at axi? addr 0x73f8c000 irqbase 192 irq 54 imxgpio3 at axi? addr 0x73f90000 irqbase 224 irq 56 gpio* at imxgpio? -options IMX_GPIO_INTR_SPLIT # I2C imxi2c0 at axi? addr 0x83fc8000 irq 62 Index: src/sys/arch/evbarm/conf/NITROGEN6X diff -u src/sys/arch/evbarm/conf/NITROGEN6X:1.22 src/sys/arch/evbarm/conf/NITROGEN6X:1.23 --- src/sys/arch/evbarm/conf/NITROGEN6X:1.22 Fri Apr 26 22:46:03 2019 +++ src/sys/arch/evbarm/conf/NITROGEN6X Wed Jul 24 12:33:18 2019 @@ -1,16 +1,11 @@ -# $NetBSD: NITROGEN6X,v 1.22 2019/04/26 22:46:03 sevan Exp $ +# $NetBSD: NITROGEN6X,v 1.23 2019/07/24 12:33:18 hkenken Exp $ # # Nitrogen6X # - http://boundarydevices.com/products/nitrogen6x-board-imx6-arm-cortex-a9-sbc/ # include "arch/evbarm/conf/std.nitrogen6" - -#options INCLUDE_CONFIG_FILE # embed config file in kernel binary - -# estimated number of users - -maxusers 32 +include "arch/evbarm/conf/GENERIC.common" # Board Type options EVBARM_BOARDTYPE=nitrogen6x @@ -20,150 +15,20 @@ options CPU_CORTEX options CPU_CORTEXA9 options IMX6 options MULTIPROCESSOR -options PMAPCOUNTERS # Standard system options -options INSECURE # disable kernel security levels - X needs this - -options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT -#options NTP # NTP phase/frequency locked loop -options KTRACE # system call tracing via ktrace(1) - -# Note: SysV IPC parameters can be changed dynamically; see sysctl(8). -options SYSVMSG # System V-like message queues -options SYSVSEM # System V-like semaphores -options SYSVSHM # System V-like memory sharing - -#options USERCONF # userconf(4) support -#options PIPE_SOCKETPAIR # smaller, but slower pipe(2) -options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel - -# Alternate buffer queue strategies for better responsiveness under high -# disk I/O load. -#options BUFQ_READPRIO -options BUFQ_PRIOCSCAN - -# Diagnostic/debugging support options -options VERBOSE_INIT_ARM # verbose bootstraping messages -options DIAGNOSTIC # internally consistency checks - +#options DIAGNOSTIC # internal consistency checks #options DEBUG -#options PMAP_DEBUG # Enable pmap_debug_level code -options LOCKDEBUG # expensive locking checks/support -options IRQSTATS # manage IRQ statistics -#options NO_POWERSAVE # uncomment this to run under ICE - -#makeoptions COPTS="-O2" -options DDB # in-kernel debugger -#options DDB_KEYCODE=0x1d # ^] -#options DDB_COMMANDONENTER="bt" # execute command when ddb is entered -options DDB_ONPANIC=1 # see also sysctl(7): `ddb.onpanic' -options DDB_HISTORY_SIZE=100 # Enable history editing in DDB -options DDB_VERBOSE_HELP -#options KGDB -#options KGDB_DEVNAME="\"imxuart\"" -#options KGDB_DEVADDR=0x021e8000 -#options KGDB_DEVRATE=115200 +#options KGDB makeoptions DEBUG="-g" # compile full symbol table makeoptions COPY_SYMTAB=1 -#options SYSCALL_STATS # per syscall counts -#options SYSCALL_TIMES # per syscall times -#options SYSCALL_TIMES_HASCOUNTER # use 'broken' rdtsc (soekris) - - -# Compatibility options - -include "conf/compat_netbsd60.config" -options COMPAT_NETBSD32 # allow running arm (e.g. non-earm) binaries - -options COMPAT_OSSAUDIO # OSS (Voxware) audio driver compatibility - -# Wedge support -options DKWEDGE_AUTODISCOVER # Automatically add dk(4) instances -options DKWEDGE_METHOD_GPT # Supports GPT partitions as wedges - -# File systems -file-system FFS # UFS -file-system MFS # memory file system -file-system NFS # Network File System client -file-system TMPFS # Efficient memory file-system -file-system EXT2FS # second extended file system (linux) -file-system LFS # log-structured file system -file-system NTFS # Windows/NT file system (experimental) -file-system CD9660 # ISO 9660 + Rock Ridge file system -file-system MSDOSFS # MS-DOS file system -file-system FDESC # /dev/fd -file-system KERNFS # /kern -file-system NULLFS # loopback file system -file-system OVERLAY # overlay file system -file-system PROCFS # /proc -file-system PUFFS # Userspace file systems (e.g. ntfs-3g & sshfs) -file-system SMBFS # experimental - CIFS; also needs nsmb (below) -file-system UMAPFS # NULLFS + uid and gid remapping -file-system UNION # union file system -file-system CODA # Coda File System; also needs vcoda (below) -file-system PTYFS # /dev/ptm support -#file-system UDF # experimental - OSTA UDF CD/DVD file-system -#file-system HFS # experimental - Apple HFS+ (read-only) -#file-system NILFS # experimental - NTT's NiLFS(2) - -# File system options -options QUOTA # legacy UFS quotas -options QUOTA2 # new, in-filesystem UFS quotas -#options DISKLABEL_EI # disklabel Endian Independent support -options FFS_EI # FFS Endian Independent support -options WAPBL # File system journaling support -# Note that UFS_DIRHASH is suspected of causing kernel memory corruption. -# It is not recommended for general use. -#options UFS_DIRHASH # UFS Large Directory Hashing - Experimental -options NFSSERVER # Network File System server -#options EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and - # immutable) behave as system flags. -#options FFS_NO_SNAPSHOT # No FFS snapshot support - -# Networking options -#options GATEWAY # packet forwarding -options INET # IP + ICMP + TCP + UDP -options INET6 # IPv6 -options IPSEC # IP security -#options IPSEC_DEBUG # debug for IP security -#options MPLS # MultiProtocol Label Switching (needs mpls) -#options MROUTING # IP multicast routing -#options PIM # Protocol Independent Multicast -options NETATALK # AppleTalk networking protocols -options PPP_BSDCOMP # BSD-Compress compression support for PPP -options PPP_DEFLATE # Deflate compression support for PPP -options PPP_FILTER # Active filter support for PPP (requires bpf) -#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG - -#options ALTQ # Manipulate network interfaces' output queues -#options ALTQ_BLUE # Stochastic Fair Blue -#options ALTQ_CBQ # Class-Based Queueing -#options ALTQ_CDNR # Diffserv Traffic Conditioner -#options ALTQ_FIFOQ # First-In First-Out Queue -#options ALTQ_FLOWVALVE # RED/flow-valve (red-penalty-box) -#options ALTQ_HFSC # Hierarchical Fair Service Curve -#options ALTQ_LOCALQ # Local queueing discipline -#options ALTQ_PRIQ # Priority Queueing -#options ALTQ_RED # Random Early Detection -#options ALTQ_RIO # RED with IN/OUT -#options ALTQ_WFQ # Weighted Fair Queueing # Device options # Console options. also need IMXUARTCONSOLE options CONSDEVNAME="\"imxuart\"",CONADDR=0x021e8000,CONSPEED=115200 -# These options enable verbose messages for several subsystems. -# Warning, these may compile large string tables into the kernel! -options MIIVERBOSE # verbose PHY autoconfig messages -#options PCIVERBOSE # verbose PCI device autoconfig messages -#options PCI_CONFIG_DUMP # verbosely dump PCI config space -#options PCMCIAVERBOSE # verbose PCMCIA configuration messages -#options SCSIVERBOSE # Verbose SCSI errors -options USBVERBOSE # verbose USB device autoconfig messages - # Kernel root file system and dump configuration. config netbsd root on ? type ? @@ -197,7 +62,6 @@ imxgpio4 at axi? addr 0x020ac000 irqbase imxgpio5 at axi? addr 0x020b0000 irqbase 416 irq 108 imxgpio6 at axi? addr 0x020b4000 irqbase 448 irq 110 gpio* at imxgpio? -options IMX_GPIO_INTR_SPLIT # Clock Control imxccm0 at axi? addr 0x020c4000 @@ -302,89 +166,3 @@ sdmmc* at sdhc? #options SDMMC_DEBUG ld* at sdmmc? # MMC/SD card - - -# Pseudo-Devices - -pseudo-device crypto # /dev/crypto device -pseudo-device swcrypto # software crypto implementation - -# disk/mass storage pseudo-devices -pseudo-device bio # RAID control device driver -pseudo-device ccd # concatenated/striped disk devices -pseudo-device cgd # cryptographic disk devices -pseudo-device raid # RAIDframe disk driver -#options RAID_AUTOCONFIG # auto-configuration of RAID components -#Options to enable various other RAIDframe RAID types. -#options RF_INCLUDE_EVENODD=1 -#options RF_INCLUDE_RAID5_RS=1 -#options RF_INCLUDE_PARITYLOGGING=1 -#options RF_INCLUDE_CHAINDECLUSTER=1 -#options RF_INCLUDE_INTERDECLUSTER=1 -#options RF_INCLUDE_PARITY_DECLUSTERING=1 -#options RF_INCLUDE_PARITY_DECLUSTERING_DS=1 -pseudo-device fss # file system snapshot device -pseudo-device putter # for puffs and pud - -pseudo-device vnd # disk-like interface to files -options VND_COMPRESSION # compressed vnd(4) - - -# network pseudo-devices -pseudo-device bpfilter # Berkeley packet filter -#pseudo-device carp # Common Address Redundancy Protocol -pseudo-device loop # network loopback -#pseudo-device mpls # MPLS pseudo-interface -pseudo-device ppp # Point-to-Point Protocol -pseudo-device pppoe # PPP over Ethernet (RFC 2516) -pseudo-device sl # Serial Line IP -pseudo-device strip # Starmode Radio IP (Metricom) -pseudo-device irframetty # IrDA frame line discipline -pseudo-device tun # network tunneling over tty -pseudo-device tap # virtual Ethernet -pseudo-device gre # generic L3 over IP tunnel -pseudo-device gif # IPv[46] over IPv[46] tunnel (RFC1933) -#pseudo-device faith # IPv[46] tcp relay translation i/f -pseudo-device stf # 6to4 IPv6 over IPv4 encapsulation -pseudo-device vlan # IEEE 802.1q encapsulation -pseudo-device bridge # simple inter-network bridging -#options BRIDGE_IPF # bridge uses IP/IPv6 pfil hooks too -pseudo-device agr # IEEE 802.3ad link aggregation -#pseudo-device npf # NPF packet filter - -# -# accept filters -pseudo-device accf_data # "dataready" accept filter -pseudo-device accf_http # "httpready" accept filter - -# miscellaneous pseudo-devices -pseudo-device pty # pseudo-terminals -pseudo-device sequencer # MIDI sequencer -#options RND_COM # use "com" randomness as well (BROKEN) -pseudo-device clockctl # user control of clock subsystem -pseudo-device ksyms # /dev/ksyms -pseudo-device lockstat # lock profiling -pseudo-device bcsp # BlueCore Serial Protocol -pseudo-device btuart # Bluetooth HCI UART (H4) - -# a pseudo device needed for Coda # also needs CODA (above) -pseudo-device vcoda # coda minicache <-> venus comm. - -# a pseudo device needed for SMBFS -pseudo-device nsmb # experimental - SMB requester - -# wscons pseudo-devices -pseudo-device wsmux # mouse & keyboard multiplexor -pseudo-device wsfont - -# pseudo audio device driver -#pseudo-device pad - -# userland interface to drivers, including autoconf and properties retrieval -pseudo-device drvctl - -# Veriexec -include "dev/veriexec.config" - -options PAX_MPROTECT=0 # PaX mprotect(2) restrictions -options PAX_ASLR=0 # PaX Address Space Layout Randomization Index: src/sys/arch/evbarm/conf/mk.nitrogen6 diff -u src/sys/arch/evbarm/conf/mk.nitrogen6:1.4 src/sys/arch/evbarm/conf/mk.nitrogen6:1.5 --- src/sys/arch/evbarm/conf/mk.nitrogen6:1.4 Sat May 18 08:49:23 2019 +++ src/sys/arch/evbarm/conf/mk.nitrogen6 Wed Jul 24 12:33:18 2019 @@ -1,25 +1,30 @@ -# $NetBSD: mk.nitrogen6,v 1.4 2019/05/18 08:49:23 skrll Exp $ +# $NetBSD: mk.nitrogen6,v 1.5 2019/07/24 12:33:18 hkenken Exp $ + +ENTRYPOINT= generic_start SYSTEM_FIRST_OBJ= armv6_start.o SYSTEM_FIRST_SFILE= ${ARM}/arm/armv6_start.S _OSRELEASE!= ${HOST_SH} $S/conf/osrelease.sh -#KERNEL_BASE_PHYS?=$(LOADADDRESS) -#KERNEL_BASE_VIRT?=$(LOADADDRESS) - -MKUBOOTIMAGEARGS= -A arm -T kernel_noload -O linux -C none +MKUBOOTIMAGEARGS= -A arm -T kernel -O linux MKUBOOTIMAGEARGS+= -e 0 -MKUBOOTIMAGEARGS+= -n "NetBSD/$(BOARDTYPE) ${_OSRELEASE}" +MKUBOOTIMAGEARGS+= -n "NetBSD/${BOARDTYPE:U${MACHINE_ARCH}} ${_OSRELEASE}" +MKUBOOTIMAGEARGS+= -a $(KERNEL_BASE_PHYS) -e $(KERNEL_BASE_PHYS) +MKUBOOTIMAGEARGS_NONE= ${MKUBOOTIMAGEARGS} -C none +MKUBOOTIMAGEARGS_GZ= ${MKUBOOTIMAGEARGS} -C gz SYSTEM_LD_TAIL_EXTRA+=; \ echo ${OBJCOPY} -S -O binary $@ $@.bin; \ ${OBJCOPY} -S -O binary $@ $@.bin; \ - echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub; \ - ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub; \ - echo + echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \ + ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \ + echo ${TOOL_GZIP} -c $@.bin > $@.bin.gz; \ + ${TOOL_GZIP} -c $@.bin > $@.bin.gz; \ + echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub; \ + ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@} EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.ub@} EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin.gz@} - +EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.gz.ub@} Index: src/sys/arch/evbarm/conf/std.nitrogen6 diff -u src/sys/arch/evbarm/conf/std.nitrogen6:1.10 src/sys/arch/evbarm/conf/std.nitrogen6:1.11 --- src/sys/arch/evbarm/conf/std.nitrogen6:1.10 Sat May 18 08:49:23 2019 +++ src/sys/arch/evbarm/conf/std.nitrogen6 Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -# $NetBSD: std.nitrogen6,v 1.10 2019/05/18 08:49:23 skrll Exp $ +# $NetBSD: std.nitrogen6,v 1.11 2019/07/24 12:33:18 hkenken Exp $ # # standard NetBSD/evbarm options for Nitrogen6X @@ -25,10 +25,6 @@ options __HAVE_FAST_SOFTINTS # should options __HAVE_GENERIC_START makeoptions BOARDMKFRAG="${THISARM}/conf/mk.nitrogen6" -makeoptions CPPFLAGS+="-I$S/../../../include" -makeoptions CPUFLAGS="-mcpu=cortex-a9" -# The physical address is chosen by u-boot and determined by armv6_start.S. -# The 64 byte offset is due to u-boot header. -makeoptions KERNEL_BASE_PHYS="0x00000040" -makeoptions KERNEL_BASE_VIRT="0x80000040" +makeoptions KERNEL_BASE_PHYS="0x18000040" +makeoptions KERNEL_BASE_VIRT="0x80000040" Index: src/sys/arch/evbarm/imx7/imx7_ioconfig.c diff -u src/sys/arch/evbarm/imx7/imx7_ioconfig.c:1.2 src/sys/arch/evbarm/imx7/imx7_ioconfig.c:1.3 --- src/sys/arch/evbarm/imx7/imx7_ioconfig.c:1.2 Thu Mar 28 12:07:30 2019 +++ src/sys/arch/evbarm/imx7/imx7_ioconfig.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx7_ioconfig.c,v 1.2 2019/03/28 12:07:30 christos Exp $ */ +/* $NetBSD: imx7_ioconfig.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $ */ /* * Copyright (c) 2015 Ryo Shimizu <r...@nerv.org> @@ -26,9 +26,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx7_ioconfig.c,v 1.2 2019/03/28 12:07:30 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx7_ioconfig.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_evbarm_boardtype.h" + +#define _INTR_PRIVATE + #include <sys/bus.h> #include <sys/device.h> #include <sys/param.h> @@ -190,7 +193,7 @@ static const struct iomux_conf iomux_dat #define GPIO_SETDIR(unit, pin, dir) \ AIPS_WRITE(GPIO_ADDR(unit) + GPIO_DIR, \ (AIPS_READ(GPIO_ADDR(unit) + GPIO_DIR) & ~(1 << (pin))) | \ - ((dir) << (pin))) + ((dir == GPIO_PIN_OUTPUT) ? __BIT(pin) : 0)) #define GPIO_WRITE(unit, pin, data) \ AIPS_WRITE(GPIO_ADDR(unit) + GPIO_DR, \ (AIPS_READ(GPIO_ADDR(unit) + GPIO_DR) & ~(1 << (pin))) | \ @@ -198,7 +201,7 @@ static const struct iomux_conf iomux_dat /* GPIO set dir & write data */ #define GPIO_DIROUT_WRITE(unit, pin, data) \ do { \ - GPIO_SETDIR(unit, pin, GPIO_DIR_OUT); \ + GPIO_SETDIR(unit, pin, GPIO_PIN_OUTPUT); \ GPIO_WRITE(unit, pin, data); \ } while (0 /* CONSTCOND */) Index: src/sys/arch/evbarm/kobo/kobo_machdep.c diff -u src/sys/arch/evbarm/kobo/kobo_machdep.c:1.7 src/sys/arch/evbarm/kobo/kobo_machdep.c:1.8 --- src/sys/arch/evbarm/kobo/kobo_machdep.c:1.7 Tue Jul 16 14:41:47 2019 +++ src/sys/arch/evbarm/kobo/kobo_machdep.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kobo_machdep.c,v 1.7 2019/07/16 14:41:47 skrll Exp $ */ +/* $NetBSD: kobo_machdep.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $ */ /* * Copyright (c) 2002, 2003, 2005, 2010 Genetec Corporation. @@ -102,7 +102,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kobo_machdep.c,v 1.7 2019/07/16 14:41:47 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kobo_machdep.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_evbarm_boardtype.h" #include "opt_arm_debug.h" @@ -137,7 +137,6 @@ __KERNEL_RCSID(0, "$NetBSD: kobo_machdep #include <arm/imx/imxuartreg.h> #include <arm/imx/imxuartvar.h> #include <arm/imx/imx50_iomuxreg.h> -#include <arm/imx/imxgpiovar.h> #include <evbarm/kobo/kobo.h> #include <evbarm/kobo/kobo_reg.h> Index: src/sys/arch/evbarm/netwalker/netwalker_lcd.c diff -u src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.5 src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.6 --- src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.5 Mon Dec 21 04:26:29 2015 +++ src/sys/arch/evbarm/netwalker/netwalker_lcd.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: netwalker_lcd.c,v 1.5 2015/12/21 04:26:29 hkenken Exp $ */ +/* $NetBSD: netwalker_lcd.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2011, 2012 Genetec corp. All rights reserved. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netwalker_lcd.c,v 1.5 2015/12/21 04:26:29 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netwalker_lcd.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_imx51_ipuv3.h" #include "opt_netwalker_lcd.h" @@ -36,8 +36,11 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_lc #include "ioconf.h" #include "netwalker_backlight.h" +#define _INTR_PRIVATE + #include <sys/param.h> #include <sys/device.h> +#include <sys/gpio.h> #include <sys/bus.h> #include <arm/imx/imx51var.h> @@ -140,17 +143,17 @@ void lcd_attach( device_t parent, device } /* LCD power on */ - gpio_set_direction(GPIO_NO(4, 9), GPIO_DIR_OUT); - gpio_set_direction(GPIO_NO(4, 10), GPIO_DIR_OUT); - gpio_set_direction(GPIO_NO(3, 3), GPIO_DIR_OUT); + gpio_set_direction(GPIO_NO(4, 9), GPIO_PIN_OUTPUT); + gpio_set_direction(GPIO_NO(4, 10), GPIO_PIN_OUTPUT); + gpio_set_direction(GPIO_NO(3, 3), GPIO_PIN_OUTPUT); - gpio_data_write(GPIO_NO(3, 3), 1); - gpio_data_write(GPIO_NO(4, 9), 1); + gpio_data_write(GPIO_NO(3, 3), GPIO_PIN_HIGH); + gpio_data_write(GPIO_NO(4, 9), GPIO_PIN_HIGH); delay(180 * 1000); - gpio_data_write(GPIO_NO(4, 10), 1); + gpio_data_write(GPIO_NO(4, 10), GPIO_PIN_HIGH); - gpio_set_direction(GPIO_NO(2, 13), GPIO_DIR_OUT); - gpio_data_write(GPIO_NO(2, 13), 1); + gpio_set_direction(GPIO_NO(2, 13), GPIO_PIN_OUTPUT); + gpio_data_write(GPIO_NO(2, 13), GPIO_PIN_HIGH); imx51_ipuv3_attach_sub(sc, aux, &sharp_panel); Index: src/sys/arch/evbarm/netwalker/netwalker_usb.c diff -u src/sys/arch/evbarm/netwalker/netwalker_usb.c:1.5 src/sys/arch/evbarm/netwalker/netwalker_usb.c:1.6 --- src/sys/arch/evbarm/netwalker/netwalker_usb.c:1.5 Wed Jul 24 11:20:55 2019 +++ src/sys/arch/evbarm/netwalker/netwalker_usb.c Wed Jul 24 12:33:18 2019 @@ -25,7 +25,11 @@ * */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netwalker_usb.c,v 1.5 2019/07/24 11:20:55 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netwalker_usb.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $"); + +#include "locators.h" + +#define _INTR_PRIVATE #include <sys/param.h> #include <sys/systm.h> @@ -34,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_us #include <sys/device.h> #include <sys/intr.h> #include <sys/bus.h> +#include <sys/gpio.h> #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> @@ -49,7 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_us #include <arm/imx/imxusbvar.h> #include <arm/imx/imx51_iomuxreg.h> #include <arm/imx/imxgpiovar.h> -#include "locators.h" struct netwalker_usbc_softc { struct imxusbc_softc sc_imxusbc; /* Must be first */ @@ -145,8 +149,8 @@ init_h1(struct imxehci_softc *sc) uint32_t reg; /* output HIGH to USBH1_STP */ - gpio_data_write(GPIO_NO(1, 27), 1); - gpio_set_direction(GPIO_NO(1, 27), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(1, 27), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(1, 27), GPIO_PIN_OUTPUT); iomux_mux_config(iomux_usb1_config); @@ -178,21 +182,21 @@ init_h1(struct imxehci_softc *sc) /* HUB RESET release */ - gpio_data_write(GPIO_NO(1, 7), 1); - gpio_set_direction(GPIO_NO(1, 7), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(1, 7), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(1, 7), GPIO_PIN_OUTPUT); /* Drive 26M_OSC_EN line high 3_1 */ - gpio_data_write(GPIO_NO(3, 1), 1); - gpio_set_direction(GPIO_NO(3, 1), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(3, 1), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(3, 1), GPIO_PIN_OUTPUT); /* Drive USB_CLK_EN_B line low 2_1 */ - gpio_data_write(GPIO_NO(2, 1), 0); - gpio_set_direction(GPIO_NO(2, 1), GPIO_DIR_IN); + gpio_data_write(GPIO_NO(2, 1), GPIO_PIN_LOW); + gpio_set_direction(GPIO_NO(2, 1), GPIO_PIN_INPUT); /* MX51_PIN_EIM_D21 - De-assert USB PHY RESETB */ delay(10 * 1000); - gpio_data_write(GPIO_NO(2, 5), 1); - gpio_set_direction(GPIO_NO(2, 5), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(2, 5), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(2, 5), GPIO_PIN_OUTPUT); iomux_set_function(MUX_PIN(EIM_D21), IOMUX_CONFIG_ALT1); delay(5 * 1000); } Index: src/sys/arch/evbarm/netwalker/netwalker_machdep.c diff -u src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.25 src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.26 --- src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.25 Tue Jul 16 14:41:47 2019 +++ src/sys/arch/evbarm/netwalker/netwalker_machdep.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: netwalker_machdep.c,v 1.25 2019/07/16 14:41:47 skrll Exp $ */ +/* $NetBSD: netwalker_machdep.c,v 1.26 2019/07/24 12:33:18 hkenken Exp $ */ /* * Copyright (c) 2002, 2003, 2005, 2010 Genetec Corporation. @@ -102,7 +102,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.25 2019/07/16 14:41:47 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.26 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_evbarm_boardtype.h" #include "opt_arm_debug.h" @@ -145,7 +145,6 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ma #include <arm/imx/imxuartreg.h> #include <arm/imx/imxuartvar.h> #include <arm/imx/imx51_iomuxreg.h> -#include <arm/imx/imxgpiovar.h> #include <evbarm/netwalker/netwalker_reg.h> #include <evbarm/netwalker/netwalker.h> Index: src/sys/arch/evbarm/netwalker/netwalker_spi.c diff -u src/sys/arch/evbarm/netwalker/netwalker_spi.c:1.1 src/sys/arch/evbarm/netwalker/netwalker_spi.c:1.2 --- src/sys/arch/evbarm/netwalker/netwalker_spi.c:1.1 Sat Mar 29 12:00:27 2014 +++ src/sys/arch/evbarm/netwalker/netwalker_spi.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: netwalker_spi.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $ */ +/* $NetBSD: netwalker_spi.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $ */ /*- * Copyright (c) 2009 Genetec Corporation. All rights reserved. @@ -27,13 +27,16 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netwalker_spi.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netwalker_spi.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_imxspi.h" +#define _INTR_PRIVATE + #include <sys/param.h> #include <sys/bus.h> #include <sys/device.h> +#include <sys/gpio.h> #include <arm/imx/imx51reg.h> #include <arm/imx/imx51var.h> @@ -56,16 +59,16 @@ imxspi_cs_enable(void *arg, int slave) { switch (slave) { case 0: - gpio_data_write(GPIO_NO(4, 24), 0); - gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(4, 24), GPIO_PIN_LOW); + gpio_set_direction(GPIO_NO(4, 24), GPIO_PIN_OUTPUT); break; case 1: - gpio_data_write(GPIO_NO(4, 25), 0); - gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(4, 25), GPIO_PIN_LOW); + gpio_set_direction(GPIO_NO(4, 25), GPIO_PIN_OUTPUT); break; case 2: - gpio_data_write(GPIO_NO(3, 0), 0); - gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(3, 0), GPIO_PIN_LOW); + gpio_set_direction(GPIO_NO(3, 0), GPIO_PIN_OUTPUT); break; } @@ -77,16 +80,16 @@ imxspi_cs_disable(void *arg, int slave) { switch (slave) { case 0: - gpio_data_write(GPIO_NO(4, 24), 1); - gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_IN); + gpio_data_write(GPIO_NO(4, 24), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(4, 24), GPIO_PIN_INPUT); break; case 1: - gpio_data_write(GPIO_NO(4, 25), 1); - gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_IN); + gpio_data_write(GPIO_NO(4, 25), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(4, 25), GPIO_PIN_INPUT); break; case 2: - gpio_data_write(GPIO_NO(3, 0), 1); - gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_IN); + gpio_data_write(GPIO_NO(3, 0), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(3, 0), GPIO_PIN_INPUT); break; } @@ -116,21 +119,21 @@ imxspi_attach(device_t parent, device_t if (device_cfdata(self)->cf_unit == 0) { /* CS 0 GPIO setting */ - gpio_data_write(GPIO_NO(4, 24), 1); - gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_IN); + gpio_data_write(GPIO_NO(4, 24), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(4, 24), GPIO_PIN_INPUT); /* CS 1 GPIO setting */ - gpio_data_write(GPIO_NO(4, 25), 1); - gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_IN); + gpio_data_write(GPIO_NO(4, 25), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(4, 25), GPIO_PIN_INPUT); /* CS 2 */ /* OJ6SH-T25 Shutdown */ - gpio_data_write(GPIO_NO(3, 14), 0); - gpio_set_direction(GPIO_NO(3, 14), GPIO_DIR_OUT); + gpio_data_write(GPIO_NO(3, 14), GPIO_PIN_LOW); + gpio_set_direction(GPIO_NO(3, 14), GPIO_PIN_OUTPUT); /* CS 2 GPIO setting */ - gpio_data_write(GPIO_NO(3, 0), 1); - gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_IN); + gpio_data_write(GPIO_NO(3, 0), GPIO_PIN_HIGH); + gpio_set_direction(GPIO_NO(3, 0), GPIO_PIN_INPUT); sc->sc_tag.spi_cs_enable = imxspi_cs_enable; sc->sc_tag.spi_cs_disable = imxspi_cs_disable; Index: src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c diff -u src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c:1.4 src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c:1.5 --- src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c:1.4 Fri Jun 9 18:14:59 2017 +++ src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c Wed Jul 24 12:33:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nitrogen6_iomux.c,v 1.4 2017/06/09 18:14:59 ryo Exp $ */ +/* $NetBSD: nitrogen6_iomux.c,v 1.5 2019/07/24 12:33:18 hkenken Exp $ */ /* * Copyright (c) 2015 Ryo Shimizu <r...@nerv.org> @@ -26,17 +26,23 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nitrogen6_iomux.c,v 1.4 2017/06/09 18:14:59 ryo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nitrogen6_iomux.c,v 1.5 2019/07/24 12:33:18 hkenken Exp $"); #include "opt_evbarm_boardtype.h" + +#define _INTR_PRIVATE + #include <sys/bus.h> #include <sys/device.h> #include <sys/param.h> +#include <sys/gpio.h> + #include <arm/imx/imx6_reg.h> #include <arm/imx/imx6var.h> #include <arm/imx/imx6_iomuxreg.h> #include <arm/imx/imxgpioreg.h> #include <arm/imx/imxgpiovar.h> + #include <evbarm/nitrogen6/platform.h> struct gpio_conf { @@ -537,41 +543,41 @@ static const struct iomux_conf iomux_dat static const struct gpio_conf gpio_data[] = { /* GPIOn, PIN, dir, value */ #if (EVBARM_BOARDTYPE == nitrogen6x) - { 3, 22, GPIO_DIR_OUT, 1 }, /* USB OTG */ - { 7, 0, GPIO_DIR_IN, 0 }, /* SD3 CD */ - { 2, 6, GPIO_DIR_IN, 0 }, /* SD4 CD */ + { 3, 22, GPIO_PIN_OUTPUT, 1 }, /* USB OTG */ + { 7, 0, GPIO_PIN_INPUT, 0 }, /* SD3 CD */ + { 2, 6, GPIO_PIN_INPUT, 0 }, /* SD4 CD */ #endif #if (EVBARM_BOARDTYPE == nitrogen6max) - { 3, 22, GPIO_DIR_OUT, 1 }, /* USB OTG */ - { 7, 12, GPIO_DIR_OUT, 1 }, /* USB HUB RESET */ - { 6, 14, GPIO_DIR_OUT, 1 }, /* SD3 VSELECT */ - { 7, 0, GPIO_DIR_IN, 0 }, /* SD3 CD */ - { 2, 6, GPIO_DIR_IN, 0 }, /* SD4 CD */ + { 3, 22, GPIO_PIN_OUTPUT, 1 }, /* USB OTG */ + { 7, 12, GPIO_PIN_OUTPUT, 1 }, /* USB HUB RESET */ + { 6, 14, GPIO_PIN_OUTPUT, 1 }, /* SD3 VSELECT */ + { 7, 0, GPIO_PIN_INPUT, 0 }, /* SD3 CD */ + { 2, 6, GPIO_PIN_INPUT, 0 }, /* SD4 CD */ #endif #if (EVBARM_BOARDTYPE == cubox_i) - { 4, 29, GPIO_DIR_OUT, 1 }, /* FRONT LED? */ - { 3, 22, GPIO_DIR_OUT, 1 }, /* USB OTG */ - { 1, 0, GPIO_DIR_OUT, 1 }, /* USB H1 */ - { 1, 4, GPIO_DIR_IN, 0 }, /* USDHC2 */ + { 4, 29, GPIO_PIN_OUTPUT, 1 }, /* FRONT LED? */ + { 3, 22, GPIO_PIN_OUTPUT, 1 }, /* USB OTG */ + { 1, 0, GPIO_PIN_OUTPUT, 1 }, /* USB H1 */ + { 1, 4, GPIO_PIN_INPUT, 0 }, /* USDHC2 */ #endif #if (EVBARM_BOARDTYPE == hummingboard) - { 3, 22, GPIO_DIR_OUT, 1 }, /* USB OTG */ - { 1, 0, GPIO_DIR_OUT, 1 }, /* USB H1 */ - { 1, 4, GPIO_DIR_IN, 0 }, /* USDHC2 */ - { 3, 4, GPIO_DIR_OUT, 0 }, /* PCIe */ + { 3, 22, GPIO_PIN_OUTPUT, 1 }, /* USB OTG */ + { 1, 0, GPIO_PIN_OUTPUT, 1 }, /* USB H1 */ + { 1, 4, GPIO_PIN_INPUT, 0 }, /* USDHC2 */ + { 3, 4, GPIO_PIN_OUTPUT, 0 }, /* PCIe */ #endif #if (EVBARM_BOARDTYPE == hummingboard_edge) - { 3, 22, GPIO_DIR_OUT, 1 }, /* USB OTG */ - { 1, 0, GPIO_DIR_OUT, 1 }, /* USB H1 */ - { 1, 4, GPIO_DIR_IN, 0 }, /* USDHC2 */ - { 2, 11, GPIO_DIR_OUT, 0 }, /* PCIe */ + { 3, 22, GPIO_PIN_OUTPUT, 1 }, /* USB OTG */ + { 1, 0, GPIO_PIN_OUTPUT, 1 }, /* USB H1 */ + { 1, 4, GPIO_PIN_INPUT, 0 }, /* USDHC2 */ + { 2, 11, GPIO_PIN_OUTPUT, 0 }, /* PCIe */ #endif #if (EVBARM_BOARDTYPE == ccimx6ulstarter) - { 3, 2, GPIO_DIR_OUT, 1 }, /* ENET1 phy */ + { 3, 2, GPIO_PIN_OUTPUT, 1 }, /* ENET1 phy */ #endif /* end of table */ - { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, }; @@ -615,10 +621,10 @@ nitrogen6_gpio_config(const struct gpio_ const struct gpio_conf *c; for (c = conflist; c->group != 0; c++) { - if (c->dir == GPIO_DIR_IN) { + if (c->dir == GPIO_PIN_INPUT) { *AIPS1_ADDR(GPIO_ADDR(c->group, GPIO_DIR)) &= ~(1 << c->pin); - } else if (c->dir == GPIO_DIR_OUT) { + } else if (c->dir == GPIO_PIN_OUTPUT) { *AIPS1_ADDR(GPIO_ADDR(c->group, GPIO_DIR)) |= (1 << c->pin); Added files: Index: src/sys/arch/arm/imx/imxpcie.c diff -u /dev/null src/sys/arch/arm/imx/imxpcie.c:1.1 --- /dev/null Wed Jul 24 12:33:19 2019 +++ src/sys/arch/arm/imx/imxpcie.c Wed Jul 24 12:33:18 2019 @@ -0,0 +1,798 @@ +/* $NetBSD: imxpcie.c,v 1.1 2019/07/24 12:33:18 hkenken Exp $ */ + +/* + * Copyright (c) 2019 Genetec Corporation. All rights reserved. + * Written by Hashimoto Kenichi for Genetec Corporation. + * + * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION + * 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. + */ + +/* + * i.MX6 On-Chip PCI Express Controller + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imxpcie.c,v 1.1 2019/07/24 12:33:18 hkenken Exp $"); + +#include "opt_pci.h" +#include "opt_fdt.h" + +#include "pci.h" +#include "locators.h" + +#define _INTR_PRIVATE + +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/extent.h> +#include <sys/queue.h> +#include <sys/mutex.h> +#include <sys/kmem.h> + +#include <machine/frame.h> +#include <arm/cpufunc.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pciconf.h> +#include <dev/clk/clk_backend.h> + +#include <arm/imx/imxpciereg.h> +#include <arm/imx/imxpcievar.h> +#include <arm/imx/imx6var.h> +#include <arm/imx/imx6_iomuxreg.h> + +#define PCIE_CONF_LOCK(s) (s) = disable_interrupts(I32_bit) +#define PCIE_CONF_UNLOCK(s) restore_interrupts((s)) + +#define PCIE_READ(sc, reg) \ + bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, reg) +#define PCIE_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, reg, val) + +static void imxpcie_init(pci_chipset_tag_t, void *); +static void imxpcie_setup(struct imxpcie_softc * const); + +static void imxpcie_attach_hook(device_t, device_t, struct pcibus_attach_args *); +static int imxpcie_bus_maxdevs(void *, int); +static pcitag_t imxpcie_make_tag(void *, int, int, int); +static void imxpcie_decompose_tag(void *, pcitag_t, int *, int *, int *); +static pcireg_t imxpcie_conf_read(void *, pcitag_t, int); +static void imxpcie_conf_write(void *, pcitag_t, int, pcireg_t); +#ifdef __HAVE_PCI_CONF_HOOK +static int imxpcie_conf_hook(void *, int, int, int, pcireg_t); +#endif +static void imxpcie_conf_interrupt(void *, int, int, int, int, int *); + +static int imxpcie_intr_map(const struct pci_attach_args *, pci_intr_handle_t *); +static const char *imxpcie_intr_string(void *, pci_intr_handle_t, char *, size_t); +const struct evcnt *imxpcie_intr_evcnt(void *, pci_intr_handle_t); +static void * imxpcie_intr_establish(void *, pci_intr_handle_t, int, + int (*)(void *), void *, const char *); +static void imxpcie_intr_disestablish(void *, void *); + +static int +imxpcie_linkup_status(struct imxpcie_softc *sc) +{ + return PCIE_READ(sc, PCIE_PL_DEBUG1) & PCIE_PL_DEBUG1_XMLH_LINK_UP; +} + +static int +imxpcie_valid_device(struct imxpcie_softc *sc, int bus, int dev) +{ + if (bus != 0 && !imxpcie_linkup_status(sc)) + return 0; + if (bus <= 1 && dev > 0) + return 0; + + return 1; +} + +static int +imxpcie_init_phy(struct imxpcie_softc *sc) +{ + uint32_t v; + + /* initialize IOMUX */ + v = sc->sc_gpr_read(sc, IOMUX_GPR12); + v &= ~IOMUX_GPR12_APP_LTSSM_ENABLE; + sc->sc_gpr_write(sc, IOMUX_GPR12, v); + + v &= ~IOMUX_GPR12_LOS_LEVEL; + v |= __SHIFTIN(9, IOMUX_GPR12_LOS_LEVEL); + sc->sc_gpr_write(sc, IOMUX_GPR12, v); + + v = 0; + v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_LOW); + v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_FULL); + v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_6DB); + v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB); + v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN1); + sc->sc_gpr_write(sc, IOMUX_GPR8, v); + + v &= ~IOMUX_GPR12_DEVICE_TYPE; + v |= IOMUX_GPR12_DEVICE_TYPE_PCIE_RC; + sc->sc_gpr_write(sc, IOMUX_GPR12, v); + + return 0; +} + +static int +imxpcie_phy_wait_ack(struct imxpcie_softc *sc, int ack) +{ + uint32_t v; + int timeout; + + for (timeout = 10; timeout > 0; --timeout) { + v = PCIE_READ(sc, PCIE_PL_PHY_STATUS); + if (!!(v & PCIE_PL_PHY_STATUS_ACK) == !!ack) + return 0; + delay(1); + } + + return -1; +} + +static int +imxpcie_phy_addr(struct imxpcie_softc *sc, uint32_t addr) +{ + uint32_t v; + + v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA); + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); + + v |= PCIE_PL_PHY_CTRL_CAP_ADR; + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); + + if (imxpcie_phy_wait_ack(sc, 1)) + return -1; + + v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA); + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v); + + if (imxpcie_phy_wait_ack(sc, 0)) + return -1; + + return 0; +} + +static int +imxpcie_phy_write(struct imxpcie_softc *sc, uint32_t addr, uint16_t data) +{ + /* write address */ + if (imxpcie_phy_addr(sc, addr) != 0) + return -1; + + /* store data */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); + + /* assert CAP_DAT and wait ack */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA) | PCIE_PL_PHY_CTRL_CAP_DAT); + if (imxpcie_phy_wait_ack(sc, 1)) + return -1; + + /* deassert CAP_DAT and wait ack */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); + if (imxpcie_phy_wait_ack(sc, 0)) + return -1; + + /* assert WR and wait ack */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_WR); + if (imxpcie_phy_wait_ack(sc, 1)) + return -1; + + /* deassert WR and wait ack */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA)); + if (imxpcie_phy_wait_ack(sc, 0)) + return -1; + + /* done */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0); + + return 0; +} + +static int +imxpcie_phy_read(struct imxpcie_softc *sc, uint32_t addr) +{ + uint32_t v; + + /* write address */ + if (imxpcie_phy_addr(sc, addr) != 0) + return -1; + + /* assert RD */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_RD); + if (imxpcie_phy_wait_ack(sc, 1)) + return -1; + + /* read data */ + v = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_PHY_STATUS), + PCIE_PL_PHY_STATUS_DATA); + + /* deassert RD */ + PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0); + if (imxpcie_phy_wait_ack(sc, 0)) + return -1; + + return v; +} + +static int +imxpcie_assert_core_reset(struct imxpcie_softc *sc) +{ + uint32_t gpr1; + uint32_t gpr12; + + gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1); + gpr12 = sc->sc_gpr_read(sc, IOMUX_GPR12); + + /* already enabled by bootloader */ + if ((gpr1 & IOMUX_GPR1_REF_SSP_EN) && + (gpr12 & IOMUX_GPR12_APP_LTSSM_ENABLE)) { + uint32_t v = PCIE_READ(sc, PCIE_PL_PFLR); + v &= ~PCIE_PL_PFLR_LINK_STATE; + v |= PCIE_PL_PFLR_FORCE_LINK; + PCIE_WRITE(sc, PCIE_PL_PFLR, v); + + gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE; + sc->sc_gpr_write(sc, IOMUX_GPR12, gpr12); + } + +#if defined(IMX6DQP) + gpr1 |= IOMUX_GPR1_PCIE_SW_RST; + sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); +#endif + + gpr1 |= IOMUX_GPR1_TEST_POWERDOWN; + sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); + gpr1 &= ~IOMUX_GPR1_REF_SSP_EN; + sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); + + return 0; +} + +static int +imxpcie_deassert_core_reset(struct imxpcie_softc *sc) +{ + int error; + + error = clk_enable(sc->sc_clk_pcie_axi); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable pcie_axi: %d\n", error); + return error; + } + error = clk_enable(sc->sc_clk_lvds1_gate); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n", error); + return error; + } + error = clk_enable(sc->sc_clk_pcie_ref); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error); + return error; + } + + uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1); + +#if defined(IMX6DQP) + gpr1 &= ~IOMUX_GPR1_PCIE_SW_RST; + sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); +#endif + + delay(50 * 1000); + + gpr1 &= ~IOMUX_GPR1_TEST_POWERDOWN; + sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); + delay(10); + gpr1 |= IOMUX_GPR1_REF_SSP_EN; + sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1); + + delay(50 * 1000); + + /* Reset */ + if (sc->sc_reset != NULL) + sc->sc_reset(sc); + + return 0; +} + +static int +imxpcie_wait_for_link(struct imxpcie_softc *sc) +{ +#define LINKUP_RETRY 20000 + for (int retry = LINKUP_RETRY; retry > 0; --retry) { + if (!imxpcie_linkup_status(sc)) { + delay(10); + continue; + } + + uint32_t valid = imxpcie_phy_read(sc, PCIE_PHY_RX_ASIC_OUT) & + PCIE_PHY_RX_ASIC_OUT_VALID; + uint32_t ltssm = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_DEBUG0), + PCIE_PL_DEBUG0_XMLH_LTSSM_STATE); + + if ((ltssm == 0x0d) && !valid) { + aprint_normal_dev(sc->sc_dev, "resetting PCIe phy\n"); + + uint32_t v = imxpcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO); + v |= PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD; + v |= PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD; + imxpcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v); + + delay(3000); + + v = imxpcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO); + v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD; + v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD; + imxpcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v); + } + + return 0; + } + + aprint_error_dev(sc->sc_dev, "Link Up failed.\n"); + + return -1; +} + +static int +imxpcie_wait_for_changespeed(struct imxpcie_softc *sc) +{ +#define CHANGESPEED_RETRY 200 + for (int retry = CHANGESPEED_RETRY; retry > 0; --retry) { + uint32_t v = PCIE_READ(sc, PCIE_PL_G2CR); + if (!(v & PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE)) + return 0; + delay(100); + } + + aprint_error_dev(sc->sc_dev, "Speed change timeout.\n"); + + return -1; +} + +static void +imxpcie_linkup(struct imxpcie_softc *sc) +{ + uint32_t v; + int ret; + + imxpcie_assert_core_reset(sc); + imxpcie_init_phy(sc); + imxpcie_deassert_core_reset(sc); + + imxpcie_setup(sc); + + /* GEN1 Operation */ + v = PCIE_READ(sc, PCIE_RC_LCR); + v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS; + v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; + PCIE_WRITE(sc, PCIE_RC_LCR, v); + + /* Link Up */ + v = sc->sc_gpr_read(sc, IOMUX_GPR12); + v |= IOMUX_GPR12_APP_LTSSM_ENABLE; + sc->sc_gpr_write(sc, IOMUX_GPR12, v); + + ret = imxpcie_wait_for_link(sc); + if (ret) + goto error; + + /* Allow Gen2 mode */ + v = PCIE_READ(sc, PCIE_RC_LCR); + v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS; + v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2; + PCIE_WRITE(sc, PCIE_RC_LCR, v); + + /* Change speed */ + v = PCIE_READ(sc, PCIE_PL_G2CR); + v |= PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE; + PCIE_WRITE(sc, PCIE_PL_G2CR, v); + + ret = imxpcie_wait_for_changespeed(sc); + if (ret) + goto error; + + ret = imxpcie_wait_for_link(sc); + if (ret) + goto error; + + v = PCIE_READ(sc, PCIE_RC_LCSR); + aprint_normal_dev(sc->sc_dev, "LinkUp, Gen %d\n", + (int)__SHIFTOUT(v, PCIE_RC_LCSR_LINK_SPEED)); + + return; + +error: + aprint_error_dev(sc->sc_dev, "PCIE_PL_DEBUG0,1 = %08x, %08x\n", + PCIE_READ(sc, PCIE_PL_DEBUG0), PCIE_READ(sc, PCIE_PL_DEBUG1)); + + return; +} + +void +imxpcie_attach_common(struct imxpcie_softc * const sc) +{ + struct pcibus_attach_args pba; + + if (bus_space_map(sc->sc_iot, sc->sc_root_addr, sc->sc_root_size, 0, + &sc->sc_root_ioh)) { + aprint_error_dev(sc->sc_dev, "Cannot map root config\n"); + return; + } + + imxpcie_linkup(sc); + + TAILQ_INIT(&sc->sc_intrs); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); + + imxpcie_init(&sc->sc_pc, sc); + + if (sc->sc_pci_netbsd_configure != NULL) + sc->sc_pci_netbsd_configure(sc); + + memset(&pba, 0, sizeof(pba)); + pba.pba_flags = PCI_FLAGS_MEM_OKAY | + PCI_FLAGS_IO_OKAY; + pba.pba_iot = sc->sc_iot; + pba.pba_memt = sc->sc_iot; + pba.pba_dmat = sc->sc_dmat; + pba.pba_pc = &sc->sc_pc; + pba.pba_bus = 0; + + config_found_ia(sc->sc_dev, "pcibus", &pba, pcibusprint); +} + +int +imxpcie_intr(void *priv) +{ + struct imxpcie_softc *sc = priv; + struct imxpcie_ih *pcie_ih; + + for (int i = 0; i < 8; i++) { + uint32_t v = PCIE_READ(sc, PCIE_PL_MSICIN_STATUS + i * 0xC); + int bit; + while ((bit = ffs(v) - 1) >= 0) { + PCIE_WRITE(sc, PCIE_PL_MSICIN_STATUS + i * 0xC, + __BIT(bit)); + v &= ~__BIT(bit); + } + } + + mutex_enter(&sc->sc_lock); + int rv = 0; + const u_int lastgen = sc->sc_intrgen; + TAILQ_FOREACH(pcie_ih, &sc->sc_intrs, ih_entry) { + int (*callback)(void *) = pcie_ih->ih_handler; + void *arg = pcie_ih->ih_arg; + mutex_exit(&sc->sc_lock); + rv += callback(arg); + mutex_enter(&sc->sc_lock); + if (lastgen != sc->sc_intrgen) + break; + } + mutex_exit(&sc->sc_lock); + + return rv; +} + +static void +imxpcie_setup(struct imxpcie_softc * const sc) +{ + uint32_t v; + + /* Setup RC */ + v = PCIE_READ(sc, PCIE_PL_PLCR); + v &= ~PCIE_PL_PLCR_LINK_MODE_ENABLE; + v |= __SHIFTIN(1, PCIE_PL_PLCR_LINK_MODE_ENABLE); + PCIE_WRITE(sc, PCIE_PL_PLCR, v); + + v = PCIE_READ(sc, PCIE_PL_G2CR); + v &= ~PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES; + v |= __SHIFTIN(1, PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES); + PCIE_WRITE(sc, PCIE_PL_G2CR, v); + + /* BARs */ + PCIE_WRITE(sc, PCI_BAR0, 0x00000004); + PCIE_WRITE(sc, PCI_BAR1, 0x00000000); + + /* Interurupt pins */ + v = PCIE_READ(sc, PCI_INTERRUPT_REG); + v &= ~(PCI_INTERRUPT_PIN_MASK << PCI_INTERRUPT_PIN_SHIFT); + v |= PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT; + PCIE_WRITE(sc, PCI_INTERRUPT_REG, v); + + /* Bus number */ + v = PCIE_READ(sc, PCI_BRIDGE_BUS_REG); + v &= ~(PCI_BRIDGE_BUS_SUBORDINATE | PCI_BRIDGE_BUS_SECONDARY | + PCI_BRIDGE_BUS_PRIMARY); + v |= PCI_BRIDGE_BUS_NUM_SUBORDINATE(1); + v |= PCI_BRIDGE_BUS_NUM_SECONDARY(1); + v |= PCI_BRIDGE_BUS_NUM_PRIMARY(0); + PCIE_WRITE(sc, PCI_BRIDGE_BUS_REG, v); + + /* Command register */ + v = PCIE_READ(sc, PCI_COMMAND_STATUS_REG); + v |= PCI_COMMAND_IO_ENABLE | + PCI_COMMAND_MEM_ENABLE | + PCI_COMMAND_MASTER_ENABLE | + PCI_COMMAND_SERR_ENABLE; + PCIE_WRITE(sc, PCI_COMMAND_STATUS_REG, v); + + PCIE_WRITE(sc, PCI_CLASS_REG, + PCI_CLASS_CODE(PCI_CLASS_BRIDGE, + PCI_SUBCLASS_BRIDGE_PCI, + PCI_INTERFACE_BRIDGE_PCI_PCI)); + + PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); + + PCIE_WRITE(sc, PCIE_PL_IATURLBA, sc->sc_root_addr); + PCIE_WRITE(sc, PCIE_PL_IATURUBA, 0); + PCIE_WRITE(sc, PCIE_PL_IATURLA, sc->sc_root_addr + sc->sc_root_size); + + PCIE_WRITE(sc, PCIE_PL_IATURLTA, 0); + PCIE_WRITE(sc, PCIE_PL_IATURUTA, 0); + PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); + PCIE_WRITE(sc, PCIE_PL_IATURC2, PCIE_PL_IATURC2_REGION_ENABLE); +} + +void +imxpcie_init(pci_chipset_tag_t pc, void *priv) +{ + pc->pc_conf_v = priv; + pc->pc_attach_hook = imxpcie_attach_hook; + pc->pc_bus_maxdevs = imxpcie_bus_maxdevs; + pc->pc_make_tag = imxpcie_make_tag; + pc->pc_decompose_tag = imxpcie_decompose_tag; + pc->pc_conf_read = imxpcie_conf_read; + pc->pc_conf_write = imxpcie_conf_write; +#ifdef __HAVE_PCI_CONF_HOOK + pc->pc_conf_hook = imxpcie_conf_hook; +#endif + pc->pc_conf_interrupt = imxpcie_conf_interrupt; + + pc->pc_intr_v = priv; + pc->pc_intr_map = imxpcie_intr_map; + pc->pc_intr_string = imxpcie_intr_string; + pc->pc_intr_evcnt = imxpcie_intr_evcnt; + pc->pc_intr_establish = imxpcie_intr_establish; + pc->pc_intr_disestablish = imxpcie_intr_disestablish; +} + +static void +imxpcie_attach_hook(device_t parent, device_t self, + struct pcibus_attach_args *pba) +{ + /* nothing to do */ +} + +static int +imxpcie_bus_maxdevs(void *v, int busno) +{ + return 32; +} + +static pcitag_t +imxpcie_make_tag(void *v, int b, int d, int f) +{ + return (b << 16) | (d << 11) | (f << 8); +} + +static void +imxpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) +{ + if (bp) + *bp = (tag >> 16) & 0xff; + if (dp) + *dp = (tag >> 11) & 0x1f; + if (fp) + *fp = (tag >> 8) & 0x7; +} + +/* + * work around. + * If there is no PCIe devices, DABT will be generated by read/write access to + * config area, so replace original DABT handler with simple jump-back one. + */ +extern u_int data_abort_handler_address; +static bool data_abort_flag; +static void +imxpcie_data_abort_handler(trapframe_t *tf) +{ + data_abort_flag = true; + tf->tf_pc += 0x4; + return; +} + +static pcireg_t +imxpcie_conf_read(void *v, pcitag_t tag, int offset) +{ + struct imxpcie_softc *sc = v; + bus_space_handle_t bsh; + int b, d, f; + pcireg_t ret = -1; + int s; + + imxpcie_decompose_tag(v, tag, &b, &d, &f); + + if ((unsigned int)offset >= PCI_EXTCONF_SIZE) + return ret; + if (!imxpcie_valid_device(sc, b, d)) + return ret; + + PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); + if (b < 2) + PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); + else + PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1); + + if (b == 0) { + bsh = sc->sc_ioh; + } else { + PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8); + bsh = sc->sc_root_ioh; + } + PCIE_READ(sc, PCIE_PL_IATURC2); + + PCIE_CONF_LOCK(s); + + u_int saved = data_abort_handler_address; + data_abort_handler_address = (u_int)imxpcie_data_abort_handler; + data_abort_flag = false; + + ret = bus_space_read_4(sc->sc_iot, bsh, offset & ~0x3); + + data_abort_handler_address = saved; + + PCIE_CONF_UNLOCK(s); + + if (data_abort_flag) + ret = -1; + + return ret; +} + +static void +imxpcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val) +{ + struct imxpcie_softc *sc = v; + bus_space_handle_t bsh; + int b, d, f; + int s; + + imxpcie_decompose_tag(v, tag, &b, &d, &f); + + if ((unsigned int)offset >= PCI_EXTCONF_SIZE) + return; + if (!imxpcie_valid_device(sc, b, d)) + return; + + PCIE_WRITE(sc, PCIE_PL_IATUVR, 0); + if (b < 2) + PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0); + else + PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1); + + if (b == 0) { + bsh = sc->sc_ioh; + } else { + PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8); + bsh = sc->sc_root_ioh; + } + PCIE_READ(sc, PCIE_PL_IATURC2); + + PCIE_CONF_LOCK(s); + + u_int saved = data_abort_handler_address; + data_abort_handler_address = (u_int)imxpcie_data_abort_handler; + + bus_space_write_4(sc->sc_iot, bsh, offset & ~0x3, val); + + data_abort_handler_address = saved; + + PCIE_CONF_UNLOCK(s); + + return; +} + +#ifdef __HAVE_PCI_CONF_HOOK +static int +imxpcie_conf_hook(void *v, int b, int d, int f, pcireg_t id) +{ + return PCI_CONF_DEFAULT; +} +#endif + +static void +imxpcie_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz, + int *ilinep) +{ + /* nothing to do */ +} + +static int +imxpcie_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih) +{ + if (pa->pa_intrpin == 0) + return EINVAL; + *ih = pa->pa_intrpin; + return 0; +} + +static const char * +imxpcie_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len) +{ + if (ih == PCI_INTERRUPT_PIN_NONE) + return NULL; + + snprintf(buf, len, "pci"); + + return buf; +} + +const struct evcnt * +imxpcie_intr_evcnt(void *v, pci_intr_handle_t ih) +{ + return NULL; +} + +static void * +imxpcie_intr_establish(void *v, pci_intr_handle_t ih, int ipl, + int (*callback)(void *), void *arg, const char *xname) +{ + struct imxpcie_softc *sc = v; + struct imxpcie_ih *pcie_ih; + + if (ih == 0) + return NULL; + + pcie_ih = kmem_alloc(sizeof(*pcie_ih), KM_SLEEP); + pcie_ih->ih_handler = callback; + pcie_ih->ih_arg = arg; + pcie_ih->ih_ipl = ipl; + + mutex_enter(&sc->sc_lock); + TAILQ_INSERT_TAIL(&sc->sc_intrs, pcie_ih, ih_entry); + sc->sc_intrgen++; + mutex_exit(&sc->sc_lock); + + return pcie_ih; +} + +static void +imxpcie_intr_disestablish(void *v, void *vih) +{ + struct imxpcie_softc *sc = v; + struct imxpcie_ih *pcie_ih = vih; + + mutex_enter(&sc->sc_lock); + TAILQ_REMOVE(&sc->sc_intrs, pcie_ih, ih_entry); + sc->sc_intrgen++; + mutex_exit(&sc->sc_lock); + + kmem_free(pcie_ih, sizeof(*pcie_ih)); +} Index: src/sys/arch/arm/imx/imxpciereg.h diff -u /dev/null src/sys/arch/arm/imx/imxpciereg.h:1.1 --- /dev/null Wed Jul 24 12:33:19 2019 +++ src/sys/arch/arm/imx/imxpciereg.h Wed Jul 24 12:33:18 2019 @@ -0,0 +1,297 @@ +/* $NetBSD: imxpciereg.h,v 1.1 2019/07/24 12:33:18 hkenken Exp $ */ + +/* + * Copyright (c) 2015 Ryo Shimizu <r...@nerv.org> + * All rights reserved. + * + * 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 AUTHOR ``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 AUTHOR 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. + */ + +#ifndef _ARM_IMX_IMX6_PCIEREG_H_ +#define _ARM_IMX_IMX6_PCIEREG_H_ + +/* PCIe EP Mode Registers */ +#define PCIE_EP_DEVICEID 0x00000000 +#define PCIE_EP_COMMAND 0x00000004 +#define PCIE_EP_BIST 0x0000000c +#define PCIE_EP_BAR0 0x00000010 +#define PCIE_EP_MASK0 0x00000010 +#define PCIE_EP_MASK1 0x00000014 +#define PCIE_EP_MASK2 0x00000018 +#define PCIE_EP_MASK3 0x0000001c +#define PCIE_EP_CISP 0x00000028 +#define PCIE_EP_SSID 0x0000002c +#define PCIE_EP_EROMBAR 0x00000030 +#define PCIE_EP_EROMMASK 0x00000030 +#define PCIE_EP_CAPPR 0x00000034 +#define PCIE_EP_ILR 0x0000003c +#define PCIE_EP_AER 0x00000100 +#define PCIE_EP_UESR 0x00000104 +#define PCIE_EP_UEMR 0x00000108 +#define PCIE_EP_UESEVR 0x0000010c +#define PCIE_EP_CESR 0x00000110 +#define PCIE_EP_CEMR 0x00000114 +#define PCIE_EP_ACCR 0x00000118 +#define PCIE_EP_HLR 0x0000011c +#define PCIE_EP_VCECHR 0x00000140 +#define PCIE_EP_PVCCR1 0x00000144 +#define PCIE_EP_PVCCR2 0x00000148 +#define PCIE_EP_PVCCSR 0x0000014c +#define PCIE_EP_VCRCR 0x00000150 +#define PCIE_EP_VCRCONR 0x00000154 +#define PCIE_EP_VCRSR 0x00000158 + +/* PCIe RC Mode Registers */ +#define PCIE_RC_DEVICEID 0x00000000 +#define PCIE_RC_COMMAND 0x00000004 +#define PCIE_RC_REVID 0x00000008 +#define PCIE_RC_BIST 0x0000000c +#define PCIE_RC_BAR0 0x00000010 +#define PCIE_RC_BAR1 0x00000014 +#define PCIE_RC_BNR 0x00000018 +#define PCIE_RC_IOBLSSR 0x0000001c +#define PCIE_RC_MEM_BLR 0x00000020 +#define PCIE_RC_PREF_MEM_BLR 0x00000024 +#define PCIE_RC_PREF_BASE_U32 0x00000028 +#define PCIE_RC_PREF_LIM_U32 0x0000002c +#define PCIE_RC_IO_BASE_LIM_U16 0x00000030 +#define PCIE_RC_CAPPR 0x00000034 +#define PCIE_RC_EROMBAR 0x00000038 +#define PCIE_RC_EROMMASK 0x00000038 +#define PCIE_RC_PMCR 0x00000040 +#define PCIE_RC_PMCSR 0x00000044 +#define PCIE_RC_CIDR 0x00000070 +#define PCIE_RC_DCR 0x00000074 +#define PCIE_RC_DCONR 0x00000078 +#define PCIE_RC_LCR 0x0000007c +#define PCIE_RC_LCR_MAX_LINK_SPEEDS __BITS(3, 0) +#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1 __SHIFTIN(0x1, PCIE_RC_LCR_MAX_LINK_SPEEDS) +#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2 __SHIFTIN(0x2, PCIE_RC_LCR_MAX_LINK_SPEEDS) +#define PCIE_RC_LCSR 0x00000080 +#define PCIE_RC_LCSR_LINK_SPEED __BITS(19, 16) +#define PCIE_RC_SCR 0x00000084 +#define PCIE_RC_SCSR 0x00000088 +#define PCIE_RC_RCCR 0x0000008c +#define PCIE_RC_RSR 0x00000090 +#define PCIE_RC_DCR2 0x00000094 +#define PCIE_RC_DCSR2 0x00000098 +#define PCIE_RC_LCR2 0x0000009c +#define PCIE_RC_LCSR2 0x000000a0 +#define PCIE_RC_AER 0x00000100 +#define PCIE_RC_UESR 0x00000104 +#define PCIE_RC_UEMR 0x00000108 +#define PCIE_RC_UESEVR 0x0000010c +#define PCIE_RC_CESR 0x00000110 +#define PCIE_RC_CEMR 0x00000114 +#define PCIE_RC_ACCR 0x00000118 +#define PCIE_RC_HLR 0x0000011c +#define PCIE_RC_RECR 0x0000012c +#define PCIE_RC_RESR 0x00000130 +#define PCIE_RC_ESIR 0x00000134 +#define PCIE_RC_VCECHR 0x00000140 +#define PCIE_RC_PVCCR1 0x00000144 +#define PCIE_RC_PVCCR2 0x00000148 +#define PCIE_RC_PVCCSR 0x0000014c +#define PCIE_RC_VCRCR 0x00000150 +#define PCIE_RC_VCRCONR 0x00000154 +#define PCIE_RC_VCRSR 0x00000158 + +/* PCIe Port Logic Registers */ +#define PCIE_PL_ALTRTR 0x00000700 +#define PCIE_PL_VSDR 0x00000704 +#define PCIE_PL_PFLR 0x00000708 +#define PCIE_PL_PFLR_LOW_POWER_ENTRANCE_COUNT __BITS(31, 24) +#define PCIE_PL_PFLR_LINK_STATE __BITS(21, 16) +#define PCIE_PL_PFLR_FORCE_LINK __BIT(15) +#define PCIE_PL_PFLR_LINK_NUMBER __BITS(7, 0) +#define PCIE_PL_AFLACR 0x0000070c +#define PCIE_PL_PLCR 0x00000710 +#define PCIE_PL_PLCR_LINK_MODE_ENABLE __BITS(21, 16) +#define PCIE_PL_LSR 0x00000714 +#define PCIE_PL_SNR 0x00000718 +#define PCIE_PL_STRFM1 0x0000071c +#define PCIE_PL_STRFM2 0x00000720 +#define PCIE_PL_AMODNPSR 0x00000724 +#define PCIE_PL_DEBUG0 0x00000728 +#define PCIE_PL_DEBUG0_XMLH_LTSSM_STATE __BITS(0, 5) +#define PCIE_PL_DEBUG1 0x0000072c +#define PCIE_PL_DEBUG1_XMLH_LINK_UP __BIT(4) +#define PCIE_PL_DEBUG1_XMLH_LINK_IN_TRAINING __BIT(29) +#define PCIE_PL_TPFCSR 0x00000730 +#define PCIE_PL_TNFCSR 0x00000734 +#define PCIE_PL_TCFCSR 0x00000738 +#define PCIE_PL_QSR 0x0000073c +#define PCIE_PL_VCTAR1 0x00000740 +#define PCIE_PL_VCTAR2 0x00000744 +#define PCIE_PL_VC0PRQC 0x00000748 +#define PCIE_PL_VC0NRQC 0x0000074c +#define PCIE_PL_VC0CRQC 0x00000750 +#define PCIE_PL_VCNPRQC 0x00000754 +#define PCIE_PL_VCNNRQC 0x00000758 +#define PCIE_PL_VCNCRQC 0x0000075c +#define PCIE_PL_VC0PBD 0x000007a8 +#define PCIE_PL_VC0NPBD 0x000007ac +#define PCIE_PL_VC0CBD 0x000007b0 +#define PCIE_PL_VC1PBD 0x000007b4 +#define PCIE_PL_VC1NPBD 0x000007b8 +#define PCIE_PL_VC1CBD 0x000007bc +#define PCIE_PL_G2CR 0x0000080c +#define PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE __BIT(17) +#define PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES __BITS(16, 8) +#define PCIE_PL_PHY_STATUS 0x00000810 +#define PCIE_PL_PHY_STATUS_ACK __BIT(16) +#define PCIE_PL_PHY_STATUS_DATA __BITS(0, 15) +#define PCIE_PL_PHY_CTRL 0x00000814 +#define PCIE_PL_PHY_CTRL_RD __BIT(19) +#define PCIE_PL_PHY_CTRL_WR __BIT(18) +#define PCIE_PL_PHY_CTRL_CAP_DAT __BIT(17) +#define PCIE_PL_PHY_CTRL_CAP_ADR __BIT(16) +#define PCIE_PL_PHY_CTRL_DATA __BITS(0, 15) +#define PCIE_PL_MRCCR0 0x00000818 +#define PCIE_PL_MRCCR1 0x0000081c +#define PCIE_PL_MSICA 0x00000820 +#define PCIE_PL_MSICUA 0x00000824 +#define PCIE_PL_MSICIN_ENB 0x00000828 +#define PCIE_PL_MSICIN_MASK 0x0000082c +#define PCIE_PL_MSICIN_STATUS 0x00000830 +#define PCIE_PL_MSICGPIO 0x00000888 + +// ATU_R_BaseAddress 0x900 +#define PCIE_PL_IATUVR 0x00000900 +// ATU_VIEWPORT_R (ATU_R_BaseAddress + 0x0) + +#define PCIE_PL_IATURC1 0x00000904 +// ATU_REGION_CTRL1_R (ATU_R_BaseAddress + 0x4) +#define PCIE_PL_IATURC1_FUNC __BITS(22, 20) +#define PCIE_PL_IATURC1_AT __BITS(17, 16) +#define PCIE_PL_IATURC1_ATTR __BITS(10, 9) +#define PCIE_PL_IATURC1_TD __BIT(8) +#define PCIE_PL_IATURC1_TC __BITS(7, 5) +#define PCIE_PL_IATURC1_TYPE __BITS(4, 0) +#define PCIE_PL_IATURC1_TYPE_IO __SHIFTIN(0, PCIE_PL_IATURC1_TYPE) +#define PCIE_PL_IATURC1_TYPE_MEM __SHIFTIN(2, PCIE_PL_IATURC1_TYPE) +#define PCIE_PL_IATURC1_TYPE_CFG0 __SHIFTIN(4, PCIE_PL_IATURC1_TYPE) +#define PCIE_PL_IATURC1_TYPE_CFG1 __SHIFTIN(5, PCIE_PL_IATURC1_TYPE) + +#define PCIE_PL_IATURC2 0x00000908 +// ATU_REGION_CTRL2_R (ATU_R_BaseAddress + 0x8) +#define PCIE_PL_IATURC2_REGION_ENABLE __BIT(31) + +#define PCIE_PL_IATURLBA 0x0000090c +// ATU_REGION_LOWBASE_R (ATU_R_BaseAddress + 0xC) + +#define PCIE_PL_IATURUBA 0x00000910 +// ATU_REGION_UPBASE_R (ATU_R_BaseAddress + 0x10) + +#define PCIE_PL_IATURLA 0x00000914 +// ATU_REGION_LIMIT_ADDR_R (ATU_R_BaseAddress + 0x14) + +#define PCIE_PL_IATURLTA 0x00000918 +// ATU_REGION_LOW_TRGT_ADDR_R (ATU_R_BaseAddress + 0x18) + +#define PCIE_PL_IATURUTA 0x0000091c +// ATU_REGION_UP_TRGT_ADDR_R (ATU_R_BaseAddress + 0x1C) + +/* PCIe PHY registers */ +#define PCIE_PHY_IDCODE_LO 0x0000 +#define PCIE_PHY_IDCODE_HI 0x0001 +#define PCIE_PHY_DEBUG 0x0002 +#define PCIE_PHY_RTUNE_DEBUG 0x0003 +#define PCIE_PHY_RTUNE_STAT 0x0004 +#define PCIE_PHY_SS_PHASE 0x0005 +#define PCIE_PHY_SS_FREQ 0x0006 +#define PCIE_PHY_ATEOVRD 0x0010 +#define PCIE_PHY_MPLL_OVRD_IN_LO 0x0011 +#define PCIE_PHY_MPLL_OVRD_IN_HI 0x0011 +#define PCIE_PHY_SSC_OVRD_IN 0x0013 +#define PCIE_PHY_BS_OVRD_IN 0x0014 +#define PCIE_PHY_LEVEL_OVRD_IN 0x0015 +#define PCIE_PHY_SUP_OVRD_OUT 0x0016 +#define PCIE_PHY_MPLL_ASIC_IN 0x0017 +#define PCIE_PHY_BS_ASIC_IN 0x0018 +#define PCIE_PHY_LEVEL_ASIC_IN 0x0019 +#define PCIE_PHY_SSC_ASIC_IN 0x001a +#define PCIE_PHY_SUP_ASIC_OUT 0x001b +#define PCIE_PHY_ATEOVRD_STATUS 0x001c +#define PCIE_PHY_SCOPE_ENABLES 0x0020 +#define PCIE_PHY_SCOPE_SAMPLES 0x0021 +#define PCIE_PHY_SCOPE_COUNT 0x0022 +#define PCIE_PHY_SCOPE_CTL 0x0023 +#define PCIE_PHY_SCOPE_MASK_000 0x0024 +#define PCIE_PHY_SCOPE_MASK_001 0x0025 +#define PCIE_PHY_SCOPE_MASK_010 0x0026 +#define PCIE_PHY_SCOPE_MASK_011 0x0027 +#define PCIE_PHY_SCOPE_MASK_100 0x0028 +#define PCIE_PHY_SCOPE_MASK_101 0x0029 +#define PCIE_PHY_SCOPE_MASK_110 0x002a +#define PCIE_PHY_SCOPE_MASK_111 0x002b +#define PCIE_PHY_MPLL_LOOP_CTL 0x0030 +#define PCIE_PHY_MPLL_ATB_MEAS2 0x0032 +#define PCIE_PHY_MPLL_OVR 0x0033 +#define PCIE_PHY_RTUNE_RTUNE_CTRL 0x0034 +#define PCIE_PHY_TX_OVRD_IN_LO 0x1000 +#define PCIE_PHY_TX_OVRD_IN_HI 0x1001 +#define PCIE_PHY_TX_OVRD_DRV_LO 0x1003 +#define PCIE_PHY_TX_OVRD_OUT 0x1004 +#define PCIE_PHY_RX_OVRD_IN_LO 0x1005 +#define PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD __BIT(3) +#define PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD __BIT(5) +#define PCIE_PHY_RX_OVRD_IN_HI 0x1006 +#define PCIE_PHY_RX_OVRD_OUT 0x1007 +#define PCIE_PHY_TX_ASIC_IN 0x1008 +#define PCIE_PHY_TX_ASIC_DRV_LO 0x1009 +#define PCIE_PHY_TX_ASIC_DRV_HI 0x100a +#define PCIE_PHY_TX_ASIC_OUT 0x100b +#define PCIE_PHY_RX_ASIC_IN 0x100c +#define PCIE_PHY_RX_ASIC_OUT 0x100d +#define PCIE_PHY_RX_ASIC_OUT_LOS __BIT(2) +#define PCIE_PHY_RX_ASIC_OUT_PLL_STATE __BIT(1) +#define PCIE_PHY_RX_ASIC_OUT_VALID __BIT(0) +#define PCIE_PHY_TX_VMD_FSM_TX_VCM_0 0x1011 +#define PCIE_PHY_TX_VMD_FSM_TX_VCM_1 0x1012 +#define PCIE_PHY_TX_VMD_FSM_TX_VCM_DEBUG_IN 0x1013 +#define PCIE_PHY_TX_VMD_FSM_TX_VCM_DEBUG_OUT 0x1014 +#define PCIE_PHY_TX_LBERT_CTL 0x1015 +#define PCIE_PHY_RX_LBERT_CTL 0x1016 +#define PCIE_PHY_RX_LBERT_ERR 0x1017 +#define PCIE_PHY_RX_SCOPE_CTL 0x1018 +#define PCIE_PHY_RX_SCOPE_PHASE 0x1019 +#define PCIE_PHY_RX_DPLL_FREQ 0x101a +#define PCIE_PHY_RX_CDR_CTL 0x101b +#define PCIE_PHY_RX_CDR_CDR_FSM_DEBUG 0x101c +#define PCIE_PHY_RX_CDR_LOCK_VEC_OVRD 0x101d +#define PCIE_PHY_RX_CDR_LOCK_VEC 0x101e +#define PCIE_PHY_RX_CDR_ADAP_FSM 0x101f +#define PCIE_PHY_RX_ATB0 0x1020 +#define PCIE_PHY_RX_ATB1 0x1021 +#define PCIE_PHY_RX_ENPWR0 0x1022 +#define PCIE_PHY_RX_PMIX_PHASE 0x1023 +#define PCIE_PHY_RX_ENPWR1 0x1024 +#define PCIE_PHY_RX_ENPWR2 0x1025 +#define PCIE_PHY_RX_SCOPE 0x1026 +#define PCIE_PHY_TX_TXDRV_CNTRL 0x102b +#define PCIE_PHY_TX_POWER_CTL 0x102c +#define PCIE_PHY_TX_ALT_BLOCK 0x102d +#define PCIE_PHY_TX_ALT_AND_LOOPBACK 0x102e +#define PCIE_PHY_TX_TX_ATB_REG 0x102f + +#endif /* _ARM_IMX_IMX6_PCIEREG_H_ */ Index: src/sys/arch/arm/imx/imxpcievar.h diff -u /dev/null src/sys/arch/arm/imx/imxpcievar.h:1.1 --- /dev/null Wed Jul 24 12:33:19 2019 +++ src/sys/arch/arm/imx/imxpcievar.h Wed Jul 24 12:33:18 2019 @@ -0,0 +1,75 @@ +/* $NetBSD: imxpcievar.h,v 1.1 2019/07/24 12:33:18 hkenken Exp $ */ + +/* + * Copyright (c) 2019 Genetec Corporation. All rights reserved. + * Written by Hashimoto Kenichi for Genetec Corporation. + * + * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION + * 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. + */ + +#ifndef _ARM_IMX_IMXPCIEVAR_H_ +#define _ARM_IMX_IMXPCIEVAR_H_ + +struct imxpcie_ih; + +struct imxpcie_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + bus_space_handle_t sc_root_ioh; + bus_space_handle_t sc_gpr_ioh; + bus_dma_tag_t sc_dmat; + + paddr_t sc_root_addr; + size_t sc_root_size; + + struct arm32_pci_chipset sc_pc; + + TAILQ_HEAD(, imxpcie_ih) sc_intrs; + + void *sc_ih; + kmutex_t sc_lock; + u_int sc_intrgen; + + struct clk *sc_clk_pcie_axi; + struct clk *sc_clk_lvds1_gate; + struct clk *sc_clk_pcie_ref; + + void *sc_cookie; + void (* sc_pci_netbsd_configure)(void *); + uint32_t (* sc_gpr_read)(void *, uint32_t); + void (* sc_gpr_write)(void *, uint32_t, uint32_t); + void (* sc_reset)(void *); +}; + +struct imxpcie_ih { + int (*ih_handler)(void *); + void *ih_arg; + int ih_ipl; + TAILQ_ENTRY(imxpcie_ih) ih_entry; +}; + +int imxpcie_intr(void *); +void imxpcie_attach_common(struct imxpcie_softc *); + +#endif /* _ARM_IMX_IMXPCIEVAR_H_ */