Module Name: src Committed By: hkenken Date: Wed Jul 24 13:12:34 UTC 2019
Added Files: src/sys/arch/arm/imx: imx6_gpcreg.h src/sys/arch/arm/imx/fdt: files.imx6 if_enet_imx.c imx6_ahcisata.c imx6_clk.c imx6_com.c imx6_gpc.c imx6_gpio.c imx6_iomux.c imx6_pcie.c imx6_platform.c imx6_platform.h imx6_sdhc.c imx6_usb.c imx6_usbphy.c src/sys/arch/evbarm/conf: IMX files.imx mk.imx std.imx Log Message: Add support for device tree. + CCM (clk) + COM (uart) + GPIO + IOMUX (pin control) + PCIe + SDHC + USB Host + USB phy To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/imx6_gpcreg.h cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/fdt/files.imx6 \ src/sys/arch/arm/imx/fdt/if_enet_imx.c \ src/sys/arch/arm/imx/fdt/imx6_ahcisata.c \ src/sys/arch/arm/imx/fdt/imx6_clk.c src/sys/arch/arm/imx/fdt/imx6_com.c \ src/sys/arch/arm/imx/fdt/imx6_gpc.c src/sys/arch/arm/imx/fdt/imx6_gpio.c \ src/sys/arch/arm/imx/fdt/imx6_iomux.c \ src/sys/arch/arm/imx/fdt/imx6_pcie.c \ src/sys/arch/arm/imx/fdt/imx6_platform.c \ src/sys/arch/arm/imx/fdt/imx6_platform.h \ src/sys/arch/arm/imx/fdt/imx6_sdhc.c src/sys/arch/arm/imx/fdt/imx6_usb.c \ src/sys/arch/arm/imx/fdt/imx6_usbphy.c cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/conf/IMX \ src/sys/arch/evbarm/conf/files.imx src/sys/arch/evbarm/conf/mk.imx \ src/sys/arch/evbarm/conf/std.imx Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: src/sys/arch/arm/imx/imx6_gpcreg.h diff -u /dev/null src/sys/arch/arm/imx/imx6_gpcreg.h:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/imx6_gpcreg.h Wed Jul 24 13:12:33 2019 @@ -0,0 +1,41 @@ +/* $NetBSD: imx6_gpcreg.h,v 1.1 2019/07/24 13:12:33 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 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_GPCREG_H_ +#define _ARM_IMX_IMX6_GPCREG_H_ + +#define GPC_CNTR 0x00000000 +#define GPC_PGR 0x00000004 +#define GPC_IMR1 0x00000008 +#define GPC_IMR2 0x0000000C +#define GPC_IMR3 0x00000010 +#define GPC_IMR4 0x00000014 +#define GPC_ISR1 0x00000018 +#define GPC_ISR2 0x0000001C +#define GPC_ISR3 0x00000020 +#define GPC_ISR4 0x00000024 + +#endif /* _ARM_IMX_IMX6_GPCREG_H_ */ Index: src/sys/arch/arm/imx/fdt/files.imx6 diff -u /dev/null src/sys/arch/arm/imx/fdt/files.imx6:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/files.imx6 Wed Jul 24 13:12:33 2019 @@ -0,0 +1,80 @@ +# $NetBSD: files.imx6,v 1.1 2019/07/24 13:12:33 hkenken Exp $ +# +# Configuration info for the Freescale i.MX6 +# + +file arch/arm/arm32/arm32_boot.c +file arch/arm/arm32/arm32_kvminit.c +file arch/arm/arm32/arm32_reboot.c +file arch/arm/arm32/irq_dispatch.S +file arch/arm/arm32/armv7_generic_space.c +file arch/arm/arm/arm_generic_dma.c +file arch/arm/arm/bus_space_a4x.S + +file arch/arm/imx/fdt/imx6_platform.c soc_imx + +# SOC parameters +defflag opt_soc.h SOC_IMX +defflag opt_soc.h SOC_IMX6QDL: SOC_IMX + +# Clock +device imxccm : clk +attach imxccm at fdt +file arch/arm/imx/imx6_ccm.c imxccm +file arch/arm/imx/fdt/imx6_clk.c imxccm + +# GPC +device imxgpc +attach imxgpc at fdt +file arch/arm/imx/fdt/imx6_gpc.c imxgpc + +# IOMUX +device imxiomux +attach imxiomux at fdt +file arch/arm/imx/fdt/imx6_iomux.c imxiomux + +# GPIO controller +device imxgpio: gpiobus +attach imxgpio at fdt +file arch/arm/imx/imxgpio.c imxgpio +file arch/arm/imx/fdt/imx6_gpio.c imxgpio + +# UART +device imxuart { } : bus_space_generic +attach imxuart at fdt with imx6_com +file arch/arm/imx/imxuart.c imxuart needs-flag +file arch/arm/imx/fdt/imx6_com.c imx6_com needs-flag +defflag opt_imxuart.h IMXUARTCONSOLE + +# FEC +device enet: ether, ifnet, arp, mii, bus_dma_generic +attach enet at fdt +file arch/arm/imx/if_enet.c enet +file arch/arm/imx/fdt/if_enet_imx.c enet + +# SATA +attach ahcisata at fdt with imx6_ahcisata +file arch/arm/imx/fdt/imx6_ahcisata.c imx6_ahcisata + +# USB Controller +device imxusbc { [unit=-1], [irq=-1] } : bus_dma_generic +attach imxusbc at fdt with imxusbc_fdt +file arch/arm/imx/fdt/imx6_usb.c imxusbc_fdt + +attach ehci at imxusbc with imxehci +file arch/arm/imx/imxusb.c imxehci + +# USB PHY +device imxusbphy +attach imxusbphy at fdt +file arch/arm/imx/fdt/imx6_usbphy.c imxusbphy + +# SDMMC +attach sdhc at fdt with imx6_sdhc +file arch/arm/imx/fdt/imx6_sdhc.c imx6_sdhc + +# PCIe +device imxpcie: pcibus +attach imxpcie at fdt with imxpcie_fdt +file arch/arm/imx/imxpcie.c imxpcie +file arch/arm/imx/fdt/imx6_pcie.c imxpcie_fdt Index: src/sys/arch/arm/imx/fdt/if_enet_imx.c diff -u /dev/null src/sys/arch/arm/imx/fdt/if_enet_imx.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/if_enet_imx.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,173 @@ +/* $NetBSD: if_enet_imx.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: if_enet_imx.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> + +#include <arm/imx/imx6var.h> +#include <arm/imx/imx6_reg.h> +#include <arm/imx/if_enetreg.h> +#include <arm/imx/if_enetvar.h> + +#include <dev/fdt/fdtvar.h> + +static const char * const compatible[] = { + "fsl,imx6q-fec", + NULL +}; + +static int enet_init_clocks(struct enet_softc *); +static void enet_phy_reset(const int); + +int +enet_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +void +enet_attach(device_t parent, device_t self, void *aux) +{ + struct enet_softc *sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_space_tag_t bst = faa->faa_bst; + bus_space_handle_t bsh; + bus_addr_t addr; + bus_size_t size; + int error; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get enet registers\n"); + return; + } + + error = bus_space_map(bst, addr, size, 0, &bsh); + if (error) { + aprint_error(": couldn't map enet registers: %d\n", error); + return; + } + + sc->sc_clk_enet = fdtbus_clock_get(phandle, "ahb"); + if (sc->sc_clk_enet == NULL) { + aprint_error(": couldn't get clock ahb\n"); + goto failure; + } + sc->sc_clk_enet_ref= fdtbus_clock_get(phandle, "ptp"); + if (sc->sc_clk_enet_ref == NULL) { + aprint_error(": couldn't get clock ptp\n"); + goto failure; + } + + aprint_naive("\n"); + aprint_normal(": Gigabit Ethernet Controller\n"); + + enet_phy_reset(phandle); + + sc->sc_dev = self; + sc->sc_iot = bst; + sc->sc_ioh = bsh; + sc->sc_dmat = faa->faa_dmat; + + sc->sc_imxtype = 6; /* i.MX6 */ + sc->sc_rgmii = 1; + + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + goto failure; + } + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_NET, 0, + enet_intr, sc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt on %s\n", + intrstr); + goto failure; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + enet_init_clocks(sc); + sc->sc_pllclock = clk_get_rate(sc->sc_clk_enet); + + if (enet_attach_common(self) != 0) + goto failure; + + return; + +failure: + bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); + return; +} + +static int +enet_init_clocks(struct enet_softc *sc) +{ + int error; + + error = clk_enable(sc->sc_clk_enet); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable enet: %d\n", error); + return error; + } + error = clk_enable(sc->sc_clk_enet_ref); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable enet_ref: %d\n", error); + return error; + } + + return 0; +} + +static void +enet_phy_reset(const int phandle) +{ + struct fdtbus_gpio_pin *reset; + int error; + + reset = fdtbus_gpio_acquire(phandle, "phy-reset-gpios", GPIO_PIN_OUTPUT); + if (reset == NULL) + return; + + u_int msec; + error = of_getprop_uint32(phandle, "phy-reset-duration", &msec); + if (error) + msec = 1; + + /* Reset */ + fdtbus_gpio_write(reset, 1); + delay(msec * 1000); + fdtbus_gpio_write(reset, 0); + + fdtbus_gpio_release(reset); +} Index: src/sys/arch/arm/imx/fdt/imx6_ahcisata.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_ahcisata.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_ahcisata.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,480 @@ +/* $NetBSD: imx6_ahcisata.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_ahcisata.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/kernel.h> + +#include <dev/ata/atavar.h> +#include <dev/ic/ahcisatavar.h> + +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6var.h> +#include <arm/imx/imx6_ahcisatareg.h> +#include <arm/imx/imx6_iomuxreg.h> +#include <arm/imx/imx6_ccmreg.h> +#include <arm/imx/imx6_ccmvar.h> + +#include <dev/fdt/fdtvar.h> + +static int imx6_ahcisata_match(device_t, cfdata_t, void *); +static void imx6_ahcisata_attach(device_t, device_t, void *); + +struct imx6_ahcisata_softc { + struct ahci_softc sc; + + device_t sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + bus_space_handle_t sc_gpr_ioh; + void *sc_ih; + + u_int sc_tx_level; + u_int sc_tx_boost; + u_int sc_tx_atten; + u_int sc_rx_eq; + u_int sc_ss; + + struct clk *sc_clk_sata; + struct clk *sc_clk_sata_ref; + struct clk *sc_clk_ahb; +}; + +static int imx6_ahcisata_init(struct imx6_ahcisata_softc *); +static int imx6_ahcisata_phy_ctrl(struct imx6_ahcisata_softc *, uint32_t, int); +static int imx6_ahcisata_phy_addr(struct imx6_ahcisata_softc *, uint32_t); +static int imx6_ahcisata_phy_write(struct imx6_ahcisata_softc *, uint32_t, uint16_t); +static int imx6_ahcisata_phy_read(struct imx6_ahcisata_softc *, uint32_t); +static int imx6_ahcisata_init_clocks(struct imx6_ahcisata_softc *); + +CFATTACH_DECL_NEW(imx6_ahcisata, sizeof(struct imx6_ahcisata_softc), + imx6_ahcisata_match, imx6_ahcisata_attach, NULL, NULL); + +static int +imx6_ahcisata_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "fsl,imx6q-ahci", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imx6_ahcisata_attach(device_t parent, device_t self, void *aux) +{ + struct imx6_ahcisata_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t ahci_addr; + bus_size_t ahci_size; + bus_addr_t addr; + bus_size_t size; + char intrstr[128]; + int error; + + if (fdtbus_get_reg(phandle, 0, &ahci_addr, &ahci_size) != 0) { + aprint_error(": couldn't get ahci registers\n"); + return; + } + + if (of_getprop_uint32(phandle, "fsl,transmit-level-mV", &sc->sc_tx_level) != 0) + sc->sc_tx_level = 1104; + if (of_getprop_uint32(phandle, "fsl,transmit-boost-mdB", &sc->sc_tx_boost) != 0) + sc->sc_tx_boost = 3330; + if (of_getprop_uint32(phandle, "fsl,transmit-atten-16ths", &sc->sc_tx_atten) != 0) + sc->sc_tx_atten = 9; + if (of_getprop_uint32(phandle, "fsl,receive-eq-mdB", &sc->sc_rx_eq) != 0) + sc->sc_rx_eq = 3000; + if (of_getprop_bool(phandle, "fsl,no-spread-spectrum") == false) + sc->sc_ss = 1; + + sc->sc_clk_sata = fdtbus_clock_get(phandle, "sata"); + if (sc->sc_clk_sata == NULL) { + aprint_error(": couldn't get clock sata\n"); + return; + } + sc->sc_clk_sata_ref = fdtbus_clock_get(phandle, "sata_ref"); + if (sc->sc_clk_sata_ref == NULL) { + aprint_error(": couldn't get clock sata_ref\n"); + return; + } + sc->sc_clk_ahb = fdtbus_clock_get(phandle, "ahb"); + if (sc->sc_clk_ahb == NULL) { + aprint_error(": couldn't get clock ahb\n"); + return; + } + + aprint_naive("\n"); + aprint_normal(": AHCI Controller\n"); + + aprint_debug_dev(self, "tx level %d [mV]\n", sc->sc_tx_level); + aprint_debug_dev(self, "tx boost %d [mdB]\n", sc->sc_tx_boost); + aprint_debug_dev(self, "tx atten %d [16ths]\n", sc->sc_tx_atten); + aprint_debug_dev(self, "rx eq %d [mdB]\n", sc->sc_rx_eq); + aprint_debug_dev(self, "ss %d\n", sc->sc_ss); + + sc->sc_dev = self; + + sc->sc.sc_atac.atac_dev = self; + sc->sc.sc_ahci_ports = 1; + sc->sc.sc_dmat = faa->faa_dmat; + sc->sc.sc_ahcit = faa->faa_bst; + sc->sc.sc_ahcis = ahci_size; + error = bus_space_map(sc->sc.sc_ahcit, ahci_addr, ahci_size, 0, + &sc->sc.sc_ahcih); + if (error) { + aprint_error(": couldn't map ahci registers: %d\n", error); + return; + } + + sc->sc_iot = sc->sc.sc_ahcit; + sc->sc_ioh = sc->sc.sc_ahcih; + + const int gpr_phandle = OF_finddevice("/soc/aips-bus/iomuxc-gpr"); + fdtbus_get_reg(gpr_phandle, 0, &addr, &size); + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_gpr_ioh)) { + aprint_error_dev(self, "Cannot map registers\n"); + return; + } + + if (imx6_ahcisata_init_clocks(sc) != 0) { + aprint_error_dev(self, "couldn't init clocks\n"); + return; + } + + if (imx6_ahcisata_init(sc) != 0) { + aprint_error_dev(self, "couldn't init ahci\n"); + return; + } + + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_BIO, 0, + ahci_intr, &sc->sc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt on %s\n", + intrstr); + return; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + ahci_attach(&sc->sc); +} + +static int +imx6_ahcisata_phy_ctrl(struct imx6_ahcisata_softc *sc, uint32_t bitmask, int on) +{ + uint32_t v; + int timeout; + + v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR); + if (on) + v |= bitmask; + else + v &= ~bitmask; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, v); + + for (timeout = 5000; timeout > 0; --timeout) { + v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYSR); + if (!!(v & SATA_P0PHYSR_CR_ACK) == !!on) + break; + delay(100); + } + + if (timeout > 0) + return 0; + + return -1; +} + +static int +imx6_ahcisata_phy_addr(struct imx6_ahcisata_softc *sc, uint32_t addr) +{ + delay(100); + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, addr); + + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 1) != 0) + return -1; + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_ADDR, 0) != 0) + return -1; + + return 0; +} + +static int +imx6_ahcisata_phy_write(struct imx6_ahcisata_softc *sc, uint32_t addr, + uint16_t data) +{ + if (imx6_ahcisata_phy_addr(sc, addr) != 0) + return -1; + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, data); + + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 1) != 0) + return -1; + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_CAP_DATA, 0) != 0) + return -1; + + if ((addr == SATA_PHY_CLOCK_RESET) && data) { + /* we can't check ACK after RESET */ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, + data | SATA_P0PHYCR_CR_WRITE); + return 0; + } + + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 1) != 0) + return -1; + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_WRITE, 0) != 0) + return -1; + + return 0; +} + +static int +imx6_ahcisata_phy_read(struct imx6_ahcisata_softc *sc, uint32_t addr) +{ + uint32_t v; + + if (imx6_ahcisata_phy_addr(sc, addr) != 0) + return -1; + + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 1) != 0) + return -1; + + v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYSR); + + if (imx6_ahcisata_phy_ctrl(sc, SATA_P0PHYCR_CR_READ, 0) != 0) + return -1; + + return SATA_P0PHYSR_CR_DATA_OUT(v); +} + +const static int tx_level[] = { + 937, + 947, + 957, + 966, + 976, + 986, + 996, + 1005, + 1015, + 1025, + 1035, + 1045, + 1054, + 1064, + 1074, + 1084, + 1094, + 1104, + 1113, + 1123, + 1133, + 1143, + 1152, + 1162, + 1172, + 1182, + 1191, + 1201, + 1211, + 1221, + 1230, + 1240, +}; + +const static int tx_boots[] = { + 0, + 370, + 740, + 1110, + 1480, + 1850, + 2220, + 2590, + 2960, + 3330, + 3700, + 4070, + 4440, + 4810, + 5280, + 5750, +}; + +const static int tx_atten[] = { + 16, + 14, + 12, + 10, + 9, + 8, +}; + +const static int rx_eq[] = { + 500, + 1000, + 1500, + 2000, + 2500, + 3000, + 3500, + 4000, +}; + +static int +imx6_ahcisata_search_regval(const int *values, int count, int val) +{ + for (int i = 0; i < count; i++) + if (values[i] == val) + return i; + + return -1; +} + +static int +imx6_ahcisata_init(struct imx6_ahcisata_softc *sc) +{ + uint32_t v; + int timeout; + int pllstat; + + v = bus_space_read_4(sc->sc_iot, sc->sc_gpr_ioh, IOMUX_GPR13); + /* clear */ + v &= ~(IOMUX_GPR13_SATA_PHY_8 | + IOMUX_GPR13_SATA_PHY_7 | + IOMUX_GPR13_SATA_PHY_6 | + IOMUX_GPR13_SATA_SPEED | + IOMUX_GPR13_SATA_PHY_5 | + IOMUX_GPR13_SATA_PHY_4 | + IOMUX_GPR13_SATA_PHY_3 | + IOMUX_GPR13_SATA_PHY_2 | + IOMUX_GPR13_SATA_PHY_1 | + IOMUX_GPR13_SATA_PHY_0); + /* setting */ + struct { + const int *array; + int count; + int val; + int def_val; + int mask; + } gpr13_sata_phy_settings[] = { + { tx_level, __arraycount(tx_level), sc->sc_tx_level, + 0x11, IOMUX_GPR13_SATA_PHY_2 }, + { tx_boots, __arraycount(tx_boots), sc->sc_tx_boost, + 0x09, IOMUX_GPR13_SATA_PHY_3 }, + { tx_atten, __arraycount(tx_atten), sc->sc_tx_atten, + 0x04, IOMUX_GPR13_SATA_PHY_4 }, + { rx_eq, __arraycount(rx_eq), sc->sc_rx_eq, + 0x05, IOMUX_GPR13_SATA_PHY_8 } + }; + for (int i = 0; i < __arraycount(gpr13_sata_phy_settings); i++) { + int val; + val = imx6_ahcisata_search_regval( + gpr13_sata_phy_settings[i].array, + gpr13_sata_phy_settings[i].count, + gpr13_sata_phy_settings[i].val); + if (val == -1) + val = gpr13_sata_phy_settings[i].def_val; + v |= __SHIFTIN(val, gpr13_sata_phy_settings[i].mask); + } + v |= __SHIFTIN(sc->sc_ss, IOMUX_GPR13_SATA_PHY_5); + v |= __SHIFTIN(0x12, IOMUX_GPR13_SATA_PHY_7); /* Rx SATA2m */ + v |= __SHIFTIN(3, IOMUX_GPR13_SATA_PHY_6); /* Rx DPLL mode */ + v |= __SHIFTIN(1, IOMUX_GPR13_SATA_SPEED); /* 3.0GHz */ + v |= __SHIFTIN(1, IOMUX_GPR13_SATA_PHY_1); /* PLL clock enable */ + bus_space_write_4(sc->sc_iot, sc->sc_gpr_ioh, IOMUX_GPR13, v); + + /* phy reset */ + if (imx6_ahcisata_phy_write(sc, SATA_PHY_CLOCK_RESET, + SATA_PHY_CLOCK_RESET_RST) < 0) { + aprint_error_dev(sc->sc_dev, "cannot reset PHY\n"); + return -1; + } + + for (timeout = 50; timeout > 0; --timeout) { + delay(100); + pllstat = imx6_ahcisata_phy_read(sc, SATA_PHY_LANE0_OUT_STAT); + if (pllstat < 0) { + aprint_error_dev(sc->sc_dev, + "cannot read LANE0 status\n"); + break; + } + if (pllstat & SATA_PHY_LANE0_OUT_STAT_RX_PLL_STATE) + break; + } + if (timeout <= 0) + return -1; + + /* Support Staggered Spin-up */ + v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_CAP); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_CAP, v | SATA_CAP_SSS); + + /* Ports Implmented. must set 1 */ + v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_PI); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_PI, v | SATA_PI_PI); + + /* set 1ms-timer = AHB clock / 1000 */ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_TIMER1MS, + clk_get_rate(sc->sc_clk_ahb) / 1000); + + return 0; +} + +static int +imx6_ahcisata_init_clocks(struct imx6_ahcisata_softc *sc) +{ + int error; + + error = clk_enable(sc->sc_clk_sata); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable sata: %d\n", error); + return error; + } + error = clk_enable(sc->sc_clk_sata_ref); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable sata-ref: %d\n", error); + return error; + } + error = clk_enable(sc->sc_clk_ahb); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable anb: %d\n", error); + return error; + } + + return 0; +} Index: src/sys/arch/arm/imx/fdt/imx6_clk.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_clk.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_clk.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,141 @@ +/* $NetBSD: imx6_clk.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_clk.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/sysctl.h> +#include <sys/cpufreq.h> +#include <sys/malloc.h> +#include <sys/kmem.h> +#include <sys/param.h> + +#include <arm/imx/imx6_ccmvar.h> + +#include <dev/clk/clk_backend.h> +#include <dev/fdt/fdtvar.h> + +static struct clk *imx6_clk_decode(device_t, int, const void *, size_t); + +static const struct fdtbus_clock_controller_func imx6_ccm_fdtclock_funcs = { + .decode = imx6_clk_decode +}; + +static struct clk * +imx6_clk_decode(device_t dev, int cc_phandle, const void *data, size_t len) +{ + struct clk *clk; + + /* #clock-cells should be 1 */ + if (len != 4) + return NULL; + + const u_int clock_id = be32dec(data); + + clk = imx6_get_clock_by_id(clock_id); + if (clk) + return clk; + + return NULL; +} + +static void +imx6_clk_fixed_from_fdt(const char *name) +{ + struct imx6_clk *iclk = (struct imx6_clk *)imx6_get_clock(name); + + KASSERT(iclk != NULL); + + char *path = kmem_asprintf("/clocks/%s", name); + int phandle = OF_finddevice(path); + kmem_free(path, strlen(path) + 1); + + if (of_getprop_uint32(phandle, "clock-frequency", &iclk->clk.fixed.rate) != 0) + iclk->clk.fixed.rate = 0; +} + +static int imxccm_match(device_t, cfdata_t, void *); +static void imxccm_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(imxccm, sizeof(struct imxccm_softc), + imxccm_match, imxccm_attach, NULL, NULL); + +static int +imxccm_match(device_t parent, cfdata_t cfdata, void *aux) +{ + const char * const compatible[] = { "fsl,imx6q-ccm", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imxccm_attach(device_t parent, device_t self, void *aux) +{ + struct imxccm_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; + + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) { + aprint_error(": can't map ccm registers\n"); + return; + } + + int phandle = OF_finddevice("/soc/aips-bus/anatop"); + fdtbus_get_reg(phandle, 0, &addr, &size); + + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh_analog)) { + aprint_error(": can't map anatop registers\n"); + return; + } + + imxccm_attach_common(self); + + imx6_clk_fixed_from_fdt("ckil"); + imx6_clk_fixed_from_fdt("ckih"); + imx6_clk_fixed_from_fdt("osc"); + imx6_clk_fixed_from_fdt("anaclk1"); + imx6_clk_fixed_from_fdt("anaclk2"); + + fdtbus_register_clock_controller(self, faa->faa_phandle, + &imx6_ccm_fdtclock_funcs); +} + Index: src/sys/arch/arm/imx/fdt/imx6_com.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_com.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_com.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,148 @@ +/* $NetBSD: imx6_com.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_com.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" +#include "opt_imxuart.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> + +#include <dev/fdt/fdtvar.h> + +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6var.h> +#include <arm/imx/imxuartreg.h> +#include <arm/imx/imxuartvar.h> + +static int imx6_com_match(device_t, struct cfdata *, void *); +static void imx6_com_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(imx6_com, sizeof(struct imxuart_softc), + imx6_com_match, imx6_com_attach, NULL, NULL); + +static const char * const compatible[] = { + "fsl,imx6q-uart", + NULL +}; + +static int +imx6_com_match(device_t parent, struct cfdata *cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imx6_com_attach(device_t parent, device_t self, void *aux) +{ + struct imxuart_softc *sc = device_private(self); + struct imxuart_regs *regsp = &sc->sc_regs; + struct fdt_attach_args *faa = aux; + const int phandle = faa->faa_phandle; + bus_space_tag_t bst = faa->faa_bst; + bus_space_handle_t bsh; + char intrstr[128]; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + if (bus_space_map(bst, addr, size, 0, &bsh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + + sc->sc_dev = self; + regsp->ur_iot = bst; + regsp->ur_iobase = addr; + regsp->ur_ioh = bsh; + + if (imxuart_is_console(regsp->ur_iot, regsp->ur_iobase, ®sp->ur_ioh)) + aprint_normal(" (console)"); + + aprint_normal("\n"); + + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_SERIAL, + FDT_INTR_MPSAFE, imxuintr, sc); + if (sc->sc_ih == NULL) + aprint_error_dev(self, "failed to establish interrupt\n"); + + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + imxuart_attach_subr(sc); + +} + +/* + * Console support + */ + +static int +imx6_com_console_match(int phandle) +{ + return of_match_compatible(phandle, compatible); +} + +static void +imx6_com_console_consinit(struct fdt_attach_args *faa, u_int uart_freq) +{ + const int phandle = faa->faa_phandle; + bus_space_tag_t bst = faa->faa_bst; + bus_addr_t addr; + bus_size_t size; + tcflag_t flags; + int speed; + + fdtbus_get_reg(phandle, 0, &addr, &size); + speed = fdtbus_get_stdout_speed(); + if (speed < 0) + speed = 115200; /* default */ + flags = fdtbus_get_stdout_flags(); + + imxuart_set_frequency(uart_freq, 2); + if (imxuart_cnattach(bst, addr, speed, flags) != 0) + panic("cannot attach console UART"); +} + +static const struct fdt_console imx6_com_console = { + .match = imx6_com_console_match, + .consinit = imx6_com_console_consinit, +}; + +FDT_CONSOLE(imx6_com, &imx6_com_console); Index: src/sys/arch/arm/imx/fdt/imx6_gpc.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_gpc.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_gpc.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,158 @@ +/* $NetBSD: imx6_gpc.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_gpc.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> + +#include <arm/imx/imx6var.h> +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6_gpcreg.h> + +#include <arm/cortex/gic_intr.h> + +#include <dev/fdt/fdtvar.h> + +struct imxgpc_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; +}; + +static int imxgpc_match(device_t, struct cfdata *, void *); +static void imxgpc_attach(device_t, device_t, void *); + +static void *imxgpc_establish(device_t, u_int *, int, int, + int (*)(void *), void *); +static void imxgpc_disestablish(device_t, void *); +static bool imxgpc_intrstr(device_t, u_int *, char *, size_t); + +struct fdtbus_interrupt_controller_func imxgpc_funcs = { + .establish = imxgpc_establish, + .disestablish = imxgpc_disestablish, + .intrstr = imxgpc_intrstr +}; + +CFATTACH_DECL_NEW(imxgpc, sizeof(struct imxgpc_softc), + imxgpc_match, imxgpc_attach, NULL, NULL); + +static int +imxgpc_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "fsl,imx6q-gpc", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imxgpc_attach(device_t parent, device_t self, void *aux) +{ + struct imxgpc_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t gpc_addr; + bus_size_t gpc_size; + int error; + + if (fdtbus_get_reg(phandle, 0, &gpc_addr, &gpc_size) != 0) { + aprint_error(": couldn't get gpc registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; + + error = bus_space_map(sc->sc_iot, gpc_addr, gpc_size, 0, + &sc->sc_ioh); + if (error) { + aprint_error(": couldn't map gpc registers: %d\n", error); + return; + } + + error = fdtbus_register_interrupt_controller(self, faa->faa_phandle, + &imxgpc_funcs); + if (error) { + aprint_error(": couldn't register with fdtbus: %d\n", error); + return; + } + + aprint_naive("\n"); + aprint_normal(": General Power Controller\n"); + + return; +} + +static void * +imxgpc_establish(device_t dev, u_int *specifier, int ipl, int flags, + int (*func)(void *), void *arg) +{ + /* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */ + /* 2nd cell is the interrupt number */ + /* 3rd cell is flags */ + + const u_int type = be32toh(specifier[0]); + const u_int intr = be32toh(specifier[1]); + const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr); + const u_int trig = be32toh(specifier[2]) & 0xf; + const u_int level = (trig & 0x3) ? IST_EDGE : IST_LEVEL; + + const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0; + + aprint_debug_dev(dev, "intr establish irq %d, level %d\n", irq, level); + return intr_establish(irq, ipl, level | mpsafe, func, arg); +} + +static void +imxgpc_disestablish(device_t dev, void *ih) +{ + intr_disestablish(ih); +} + +static bool +imxgpc_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) +{ + /* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */ + /* 2nd cell is the interrupt number */ + /* 3rd cell is flags */ + + if (!specifier) + return false; + + const u_int type = be32toh(specifier[0]); + const u_int intr = be32toh(specifier[1]); + const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr); + + snprintf(buf, buflen, "irq %d", irq); + + return true; +} Index: src/sys/arch/arm/imx/fdt/imx6_gpio.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_gpio.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_gpio.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,274 @@ +/* $NetBSD: imx6_gpio.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_gpio.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" +#include "gpio.h" + +#define _INTR_PRIVATE + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/kmem.h> +#include <sys/gpio.h> + +#include <dev/gpio/gpiovar.h> + +#include <arm/pic/picvar.h> +#include <arm/imx/imx6_reg.h> + +#include <arm/imx/imxgpioreg.h> +#include <arm/imx/imxgpiovar.h> + +#include <dev/fdt/fdtvar.h> + +static void *imx6_gpio_fdt_acquire(device_t, const void *, size_t, int); +static void imx6_gpio_fdt_release(device_t, void *); +static int imx6_gpio_fdt_read(device_t, void *, bool); +static void imx6_gpio_fdt_write(device_t, void *, int, bool); + +static void *imxgpio_establish(device_t, u_int *, int, int, + int (*)(void *), void *); +static void imxgpio_disestablish(device_t, void *); +static bool imxgpio_intrstr(device_t, u_int *, char *, size_t); + +static struct fdtbus_interrupt_controller_func imxgpio_funcs = { + .establish = imxgpio_establish, + .disestablish = imxgpio_disestablish, + .intrstr = imxgpio_intrstr +}; + +static struct fdtbus_gpio_controller_func imx6_gpio_funcs = { + .acquire = imx6_gpio_fdt_acquire, + .release = imx6_gpio_fdt_release, + .read = imx6_gpio_fdt_read, + .write = imx6_gpio_fdt_write +}; + +const int imxgpio_ngroups = GPIO_NGROUPS; + +int +imxgpio_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { + "fsl,imx6q-gpio", + NULL + }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +void +imxgpio_attach(device_t parent, device_t self, void *aux) +{ + struct imxgpio_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + char intrstr[128]; + const int phandle = faa->faa_phandle; + bus_space_handle_t ioh; + bus_addr_t addr; + bus_size_t size; + int error; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + error = bus_space_map(faa->faa_bst, addr, size, 0, &ioh); + if (error) { + aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); + return; + } + + aprint_naive("\n"); + aprint_normal(": GPIO (%s)\n", fdtbus_get_string(phandle, "name")); + + sc->gpio_memt = faa->faa_bst; + sc->gpio_memh = ioh; + sc->gpio_unit = (addr - IMX6_AIPS1_BASE - AIPS1_GPIO1_BASE) / 0x4000; + sc->gpio_irqbase = PIC_MAXSOURCES + sc->gpio_unit * GPIO_NPINS; + + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + return; + } + sc->gpio_is = fdtbus_intr_establish(phandle, 0, IPL_HIGH, 0, + pic_handle_intr, &sc->gpio_pic); + if (sc->gpio_is == NULL) { + aprint_error_dev(self, "couldn't establish interrupt on %s\n", + intrstr); + return; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + if (!fdtbus_intr_str(phandle, 1, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + return; + } + sc->gpio_is_high = fdtbus_intr_establish(phandle, 1, IPL_HIGH, 0, + pic_handle_intr, &sc->gpio_pic); + if (sc->gpio_is_high == NULL) { + aprint_error_dev(self, "couldn't establish interrupt on %s\n", + intrstr); + return; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + fdtbus_register_gpio_controller(self, phandle, &imx6_gpio_funcs); + + error = fdtbus_register_interrupt_controller(self, phandle, + &imxgpio_funcs); + if (error) { + aprint_error(": couldn't register with fdtbus: %d\n", error); + return; + } + + imxgpio_attach_common(self); +} + +static void * +imx6_gpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags) +{ + struct imxgpio_softc * const sc = device_private(dev); + struct imxgpio_pin *gpin; + const u_int *gpio = data; + + if (len != 12) + return NULL; + + const u_int pin = be32toh(gpio[1]); + const bool actlo = be32toh(gpio[2]) & 1; + + gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP); + gpin->pin_no = pin; + gpin->pin_flags = flags; + gpin->pin_actlo = actlo; + + imxgpio_pin_ctl(sc, gpin->pin_no, gpin->pin_flags); + + return gpin; +} + +static void +imx6_gpio_fdt_release(device_t dev, void *priv) +{ + struct imxgpio_softc * const sc = device_private(dev); + struct imxgpio_pin *gpin = priv; + + imxgpio_pin_ctl(sc, gpin->pin_no, GPIO_PIN_INPUT); + kmem_free(gpin, sizeof(*gpin)); +} + +static int +imx6_gpio_fdt_read(device_t dev, void *priv, bool raw) +{ + struct imxgpio_softc * const sc = device_private(dev); + struct imxgpio_pin *gpin = priv; + int val; + + val = imxgpio_pin_read(sc, gpin->pin_no); + + if (!raw && gpin->pin_actlo) + val = !val; + + return val; +} + +static void +imx6_gpio_fdt_write(device_t dev, void *priv, int val, bool raw) +{ + struct imxgpio_softc * const sc = device_private(dev); + struct imxgpio_pin *gpin = priv; + + if (!raw && gpin->pin_actlo) + val = !val; + + imxgpio_pin_write(sc, gpin->pin_no, val); +} + +static void * +imxgpio_establish(device_t dev, u_int *specifier, int ipl, int flags, + int (*func)(void *), void *arg) +{ + struct imxgpio_softc * const sc = device_private(dev); + + /* 1st cell is the interrupt number */ + /* 2nd cell is flags */ + + const u_int intr = be32toh(specifier[0]); + const u_int trig = be32toh(specifier[1]) & 0xf; + u_int level; + + if ((trig & 0x1) && (trig & 0x2)) + level = IST_EDGE_BOTH; + else if (trig & 0x1) + level = IST_EDGE_RISING; + else if (trig & 0x2) + level = IST_EDGE_FALLING; + else if (trig & 0x4) + level = IST_LEVEL_HIGH; + else + level = IST_LEVEL_LOW; + + const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0; + + aprint_debug_dev(dev, "intr establish irq %d, level %d\n", + sc->gpio_irqbase + intr, level); + return intr_establish(sc->gpio_irqbase + intr, ipl, level | mpsafe, func, arg); +} + +static void +imxgpio_disestablish(device_t dev, void *ih) +{ + intr_disestablish(ih); +} + +static bool +imxgpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) +{ + struct imxgpio_softc * const sc = device_private(dev); + + /* 1st cell is the interrupt number */ + /* 2nd cell is flags */ + + if (!specifier) + return false; + + const u_int intr = be32toh(specifier[0]); + + snprintf(buf, buflen, "irq %d (gpio%d %d)", + sc->gpio_irqbase + intr, sc->gpio_unit, intr); + + return true; +} Index: src/sys/arch/arm/imx/fdt/imx6_iomux.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_iomux.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_iomux.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,178 @@ +/* $NetBSD: imx6_iomux.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_iomux.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> + +#include <arm/imx/imx6var.h> +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6_iomuxreg.h> + +#include <dev/fdt/fdtvar.h> + +struct imxiomux_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + int sc_phandle; +}; + +#define CONFIG_NO_PAD_CTL __BIT(31) +#define CONFIG_SION __BIT(30) + +static int +imx6_pinctrl_set_config(device_t dev, const void *data, size_t len) +{ + struct imxiomux_softc * const sc = device_private(dev); + int pins_len; + uint32_t reg; + + if (len != 4) + return -1; + + const int phandle = fdtbus_get_phandle_from_native(be32dec(data)); + const u_int *pins = fdtbus_get_prop(phandle, "fsl,pins", &pins_len); + + aprint_debug_dev(sc->sc_dev, "name %s\n", fdtbus_get_string(phandle, "name")); + while (pins_len >= 24) { + u_int mux_reg = be32toh(pins[0]); + u_int conf_reg = be32toh(pins[1]); + u_int input_reg = be32toh(pins[2]); + u_int mux_mode = be32toh(pins[3]); + u_int input_val = be32toh(pins[4]); + u_int config = be32toh(pins[5]); + + if (config & CONFIG_SION) + mux_mode |= IOMUX_CONFIG_SION; + config &= ~CONFIG_SION; + + reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, mux_reg); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, mux_reg, mux_mode); + aprint_debug_dev(sc->sc_dev, + "mux offset 0x%08x, val 0x%08x -> 0x%08x\n", + mux_reg, reg, mux_mode); + + if (!(config & CONFIG_NO_PAD_CTL)) { + reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, conf_reg); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, conf_reg, config); + aprint_debug_dev(sc->sc_dev, + "config offset 0x%08x, val 0x%08x -> 0x%08x\n", + conf_reg, reg, config); + } + + if (__SHIFTOUT(input_val, __BITS(31, 24)) == 0xff) { + uint8_t sel = __SHIFTOUT(input_val, __BITS(7, 0)); + uint8_t width = __SHIFTOUT(input_val, __BITS(15, 8)); + uint8_t shift = __SHIFTOUT(input_val, __BITS(23, 16)); + uint32_t mask = __BITS(shift + (width - 1), shift); + + reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, input_reg); + reg &= ~mask; + reg |= __SHIFTIN(sel, mask); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, input_reg, reg); + aprint_debug_dev(sc->sc_dev, + "+input offset 0x%08x, val 0x%08x\n", + input_reg, reg); + } else if (input_reg != 0) { + reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, input_reg); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, input_reg, input_val); + aprint_debug_dev(sc->sc_dev, + "input offset 0x%08x, val 0x%08x -> 0x%08x\n", + input_reg, reg, input_val); + } + + pins_len -= 24; + pins += 6; + } + + return 0; +} + +static struct fdtbus_pinctrl_controller_func imx6_pinctrl_funcs = { + .set_config = imx6_pinctrl_set_config, +}; + +static int imxiomux_match(device_t, struct cfdata *, void *); +static void imxiomux_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(imxiomux, sizeof(struct imxiomux_softc), + imxiomux_match, imxiomux_attach, NULL, NULL); + +static int +imxiomux_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "fsl,imx6q-iomuxc", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imxiomux_attach(device_t parent, device_t self, void *aux) +{ + struct imxiomux_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + int error; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get iomux registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; + + error = bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh); + if (error) { + aprint_error(": couldn't map iomux registers: %d\n", error); + return; + } + + aprint_naive("\n"); + aprint_normal(": IOMUX Controller\n"); + + for (int child = OF_child(phandle); child; child = OF_peer(child)) { + for (int sub = OF_child(child); sub; sub = OF_peer(sub)) { + if (!of_hasprop(sub, "fsl,pins")) + continue; + fdtbus_register_pinctrl_config(self, sub, &imx6_pinctrl_funcs); + } + } + + fdtbus_pinctrl_configure(); +} + Index: src/sys/arch/arm/imx/fdt/imx6_pcie.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_pcie.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_pcie.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,248 @@ +/* $NetBSD: imx6_pcie.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_pci.h" +#include "opt_fdt.h" + +#include "pci.h" +#include "imxgpio.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 <sys/gpio.h> + +#include <machine/frame.h> +#include <arm/cpufunc.h> + +#include <dev/fdt/fdtvar.h> + +#include <dev/pci/pcireg.h> +#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_iomuxreg.h> +#include <arm/imx/imx6_ccmreg.h> +#include <arm/imx/imx6_ccmvar.h> + +struct imxpcie_fdt_softc { + struct imxpcie_softc sc_imxpcie; + + struct fdtbus_gpio_pin *sc_pin_reset; +}; + +static int imx6_pcie_match(device_t, cfdata_t, void *); +static void imx6_pcie_attach(device_t, device_t, void *); + +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 *); + +#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 */ + +CFATTACH_DECL_NEW(imxpcie_fdt, sizeof(struct imxpcie_fdt_softc), + imx6_pcie_match, imx6_pcie_attach, NULL, NULL); + +static const char * const compatible[] = { + "fsl,imx6q-pcie", + NULL +}; + +static int +imx6_pcie_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imx6_pcie_attach(device_t parent, device_t self, void *aux) +{ + struct imxpcie_fdt_softc * const ifsc = device_private(self); + struct imxpcie_softc * const sc = &ifsc->sc_imxpcie; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_space_tag_t bst = faa->faa_bst; + char intrstr[128]; + bus_addr_t addr; + bus_size_t size; + + aprint_naive("\n"); + aprint_normal(": PCI Express Controller\n"); + + sc->sc_dev = self; + sc->sc_iot = bst; + sc->sc_dmat = faa->faa_dmat; + sc->sc_cookie = ifsc; + 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 (fdtbus_get_reg_byname(phandle, "dbi", &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) { + aprint_error_dev(self, "Cannot map registers\n"); + return; + } + if (fdtbus_get_reg_byname(phandle, "config", &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + sc->sc_root_addr = addr; + sc->sc_root_size = size; + + const int gpr_phandle = OF_finddevice("/soc/aips-bus/iomuxc-gpr"); + fdtbus_get_reg(gpr_phandle, 0, &addr, &size); + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_gpr_ioh)) { + aprint_error_dev(self, "Cannot map registers\n"); + return; + } + + ifsc->sc_pin_reset = fdtbus_gpio_acquire(phandle, "reset-gpio", + GPIO_PIN_OUTPUT); + if (!ifsc->sc_pin_reset) { + aprint_error(": couldn't acquire reset gpio\n"); + return; + } + + sc->sc_clk_pcie_axi = fdtbus_clock_get(phandle, "pcie"); + if (sc->sc_clk_pcie_axi == NULL) { + aprint_error(": couldn't get clock pcie_axi\n"); + return; + } + sc->sc_clk_lvds1_gate = fdtbus_clock_get(phandle, "pcie_bus"); + if (sc->sc_clk_lvds1_gate == NULL) { + aprint_error(": couldn't get clock lvds1_gate\n"); + return; + } + sc->sc_clk_pcie_ref = fdtbus_clock_get(phandle, "pcie_phy"); + if (sc->sc_clk_pcie_ref == NULL) { + aprint_error(": couldn't get clock pcie_ref\n"); + return; + } + + TAILQ_INIT(&sc->sc_intrs); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); + + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, 0, imxpcie_intr, sc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt on %s\n", + intrstr); + return; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + imxpcie_attach_common(sc); +} + +static void +imx6_pcie_configure(void *cookie) +{ + struct imxpcie_fdt_softc * const ifsc = cookie; + struct imxpcie_softc * const sc = &ifsc->sc_imxpcie; + +#ifdef PCI_NETBSD_CONFIGURE + struct extent *ioext, *memext; + int error; + + ioext = extent_create("pciio", IMX6_PCIE_IO_BASE, + IMX6_PCIE_IO_BASE + IMX6_PCIE_IO_SIZE - 1, + NULL, 0, EX_NOWAIT); + memext = extent_create("pcimem", IMX6_PCIE_MEM_BASE, + IMX6_PCIE_MEM_BASE + IMX6_PCIE_MEM_SIZE - 1, + NULL, 0, EX_NOWAIT); + + error = pci_configure_bus(&sc->sc_pc, ioext, memext, NULL, 0, + arm_dcache_align); + + extent_destroy(ioext); + extent_destroy(memext); + + if (error) { + aprint_error_dev(sc->sc_dev, "configuration failed (%d)\n", + error); + } +#endif +} + +static uint32_t +imx6_pcie_gpr_read(void *cookie, uint32_t reg) +{ + struct imxpcie_fdt_softc * const ifsc = cookie; + struct imxpcie_softc * const sc = &ifsc->sc_imxpcie; + return bus_space_read_4(sc->sc_iot, sc->sc_gpr_ioh, reg); +} + +static void +imx6_pcie_gpr_write(void *cookie, uint32_t reg, uint32_t val) +{ + struct imxpcie_fdt_softc * const ifsc = cookie; + struct imxpcie_softc * const sc = &ifsc->sc_imxpcie; + bus_space_write_4(sc->sc_iot, sc->sc_gpr_ioh, reg, val); +} + +static void +imx6_pcie_reset(void *cookie) +{ + struct imxpcie_fdt_softc * const ifsc = cookie; + + fdtbus_gpio_write(ifsc->sc_pin_reset, 1); + delay(20 * 1000); + fdtbus_gpio_write(ifsc->sc_pin_reset, 0); +} Index: src/sys/arch/arm/imx/fdt/imx6_platform.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_platform.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_platform.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,200 @@ +/* $NetBSD: imx6_platform.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_soc.h" +#include "arml2cc.h" +#include "opt_multiprocessor.h" +#include "opt_fdt.h" +#include "opt_fdt_arm.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/cpu.h> +#include <sys/device.h> +#include <sys/termios.h> + +#include <dev/fdt/fdtvar.h> +#include <arm/fdt/arm_fdtvar.h> + +#include <uvm/uvm_extern.h> + +#include <arm/arm32/machdep.h> + +#include <machine/bootconfig.h> +#include <arm/cpufunc.h> + +#include <arm/cortex/a9tmr_var.h> +#include <arm/cortex/scu_reg.h> +#include <arm/cortex/gic_reg.h> +#include <arm/cortex/pl310_var.h> + +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6_srcreg.h> +#include <arm/imx/imxuartreg.h> + +#include <arm/imx/fdt/imx6_platform.h> + +#include <libfdt.h> + +#define IMX_REF_FREQ 80000000 + +#ifdef VERBOSE_INIT_ARM +#define VPRINTF(...) printf(__VA_ARGS__) +#else +#define VPRINTF(...) __nothing +#endif + +extern struct bus_space armv7_generic_bs_tag; +extern struct bus_space armv7_generic_a4x_bs_tag; +extern struct arm32_bus_dma_tag arm_generic_dma_tag; + +static const struct pmap_devmap * +imx_platform_devmap(void) +{ + static const struct pmap_devmap devmap[] = { + DEVMAP_ENTRY(KERNEL_IO_IOREG_VBASE, IMX6_IOREG_PBASE, IMX6_IOREG_SIZE), + DEVMAP_ENTRY(KERNEL_IO_ARMCORE_VBASE, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE), + DEVMAP_ENTRY_END +}; + + return devmap; +} + +static void +imx_platform_init_attach_args(struct fdt_attach_args *faa) +{ + faa->faa_bst = &armv7_generic_bs_tag; + faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag; + faa->faa_dmat = &arm_generic_dma_tag; +} + +void imx_platform_early_putchar(char); + +void +imx_platform_early_putchar(char c) +{ +#ifdef CONSADDR +#define CONSADDR_VA ((CONSADDR - IMX6_IOREG_PBASE) + KERNEL_IO_IOREG_VBASE) + + volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ? + (volatile uint32_t *)CONSADDR_VA : + (volatile uint32_t *)CONSADDR; + + while ((le32toh(uartaddr[(IMX_USR2/4)]) & IMX_USR2_TXDC) == 0) + ; + + uartaddr[(IMX_UTXD/4)] = htole32(c); +#endif +} + +static void +imx_platform_device_register(device_t self, void *aux) +{ +} + +static u_int +imx_platform_uart_freq(void) +{ + return IMX_REF_FREQ; +} + +static void +imx_platform_bootstrap(void) +{ +#if NARML2CC > 0 + bus_space_tag_t bst = &armv7_generic_bs_tag; + bus_space_handle_t bsh; + if (bus_space_map(bst, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE, 0, &bsh)) + panic("couldn't map armcore registers"); + arml2cc_init(bst, bsh, ARMCORE_L2C_BASE); + bus_space_unmap(bst, bsh, IMX6_ARMCORE_SIZE); +#endif + + arm_fdt_cpu_bootstrap(); +} + +static int +imx_platform_mpstart(void) +{ +#if defined(MULTIPROCESSOR) + bus_space_tag_t bst = &armv7_generic_bs_tag; + bus_space_handle_t bsh; + + if (bus_space_map(bst, IMX6_ARMCORE_PBASE, IMX6_ARMCORE_SIZE, 0, &bsh) != 0) + panic("couldn't map armcore registers"); + + /* Enable Snoop Control Unit */ + bus_space_write_4(bst, bsh, SCU_INV_ALL_REG, 0xff); + bus_space_write_4(bst, bsh, SCU_CTL, + bus_space_read_4(bst, bsh, SCU_CTL) | SCU_CTL_SCU_ENA); + + bus_space_unmap(bst, bsh, AIPS1_SRC_SIZE); + + if (bus_space_map(bst, IMX6_AIPS1_BASE + AIPS1_SRC_BASE, AIPS1_SRC_SIZE, 0, &bsh) != 0) + panic("couldn't map SRC"); + + + uint32_t srcctl = bus_space_read_4(bst, bsh, SRC_SCR); + const paddr_t mpstart = KERN_VTOPHYS((vaddr_t)cpu_mpstart); + + srcctl &= ~(SRC_SCR_CORE1_ENABLE | SRC_SCR_CORE2_ENABLE | + SRC_SCR_CORE3_ENABLE); + bus_space_write_4(bst, bsh, SRC_SCR, srcctl); + + for (int i = 1; i < arm_cpu_max; i++) { + bus_space_write_4(bst, bsh, SRC_GPRN_ENTRY(i), mpstart); + srcctl |= SRC_SCR_COREN_RST(i); + srcctl |= SRC_SCR_COREN_ENABLE(i); + } + bus_space_write_4(bst, bsh, SRC_SCR, srcctl); + + bus_space_unmap(bst, bsh, AIPS1_SRC_SIZE); + + return arm_fdt_cpu_mpstart(); +#endif +} + +static void +imx6_platform_reset(void) +{ +} + +const struct arm_platform imx6_platform = { + .ap_devmap = imx_platform_devmap, + .ap_bootstrap = imx_platform_bootstrap, + .ap_init_attach_args = imx_platform_init_attach_args, + .ap_device_register = imx_platform_device_register, + .ap_reset = imx6_platform_reset, + .ap_delay = a9tmr_delay, + .ap_uart_freq = imx_platform_uart_freq, + .ap_mpstart = imx_platform_mpstart, +}; + +ARM_PLATFORM(imx6, "fsl,imx6q", &imx6_platform); + Index: src/sys/arch/arm/imx/fdt/imx6_platform.h diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_platform.h:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_platform.h Wed Jul 24 13:12:33 2019 @@ -0,0 +1,35 @@ +/* $NetBSD: imx6_platform.h,v 1.1 2019/07/24 13:12:33 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 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_FDT_IMX6_PLATFORM_H +#define _ARM_IMX_FDT_IMX6_PLATFORM_H + +#include <arch/evbarm/fdt/platform.h> + +#define KERNEL_IO_IOREG_VBASE KERNEL_IO_VBASE +#define KERNEL_IO_ARMCORE_VBASE (KERNEL_IO_IOREG_VBASE + IMX6_IOREG_SIZE) + +#endif /* _ARM_IMX_FDT_IMX6_PLATFORM_H */ Index: src/sys/arch/arm/imx/fdt/imx6_sdhc.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_sdhc.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_sdhc.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,191 @@ +/* $NetBSD: imx6_sdhc.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_sdhc.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/gpio.h> + +#include <dev/sdmmc/sdhcreg.h> +#include <dev/sdmmc/sdhcvar.h> +#include <dev/sdmmc/sdmmcvar.h> + +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6var.h> + +#include <dev/fdt/fdtvar.h> + +static int imx6_sdhc_match(device_t, cfdata_t, void *); +static void imx6_sdhc_attach(device_t, device_t, void *); + +static int imx6_sdhc_card_detect(struct sdhc_softc *); + +struct imx6_sdhc_softc { + struct sdhc_softc sc_sdhc; + + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + bus_size_t sc_bsz; + + struct sdhc_host *sc_host; + void *sc_ih; + + struct clk *sc_clk_per; + + struct fdtbus_gpio_pin *sc_pin_cd; +}; + +CFATTACH_DECL_NEW(imx6_sdhc, sizeof(struct imx6_sdhc_softc), + imx6_sdhc_match, imx6_sdhc_attach, NULL, NULL); + +static const char * const compatible[] = { + "fsl,imx6q-usdhc", + NULL +}; + +static int +imx6_sdhc_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imx6_sdhc_attach(device_t parent, device_t self, void *aux) +{ + struct imx6_sdhc_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + char intrstr[128]; + bus_addr_t addr; + bus_size_t size; + u_int bus_width; + int error; + + if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + if (of_getprop_uint32(faa->faa_phandle, "bus-width", &bus_width)) + bus_width = 4; + + sc->sc_clk_per = fdtbus_clock_get(faa->faa_phandle, "per"); + if (sc->sc_clk_per == NULL) { + aprint_error(": couldn't get clock\n"); + return; + } + + sc->sc_sdhc.sc_dev = self; + sc->sc_sdhc.sc_dmat = faa->faa_dmat; + + sc->sc_sdhc.sc_clkbase = clk_get_rate(sc->sc_clk_per) / 1000; + sc->sc_sdhc.sc_flags = + SDHC_FLAG_USE_DMA | + SDHC_FLAG_NO_PWR0 | + SDHC_FLAG_HAVE_DVS | + SDHC_FLAG_32BIT_ACCESS | + SDHC_FLAG_8BIT_MODE | + SDHC_FLAG_USE_ADMA2 | + SDHC_FLAG_USDHC; + + if (bus_width == 8) { + sc->sc_sdhc.sc_flags |= SDHC_FLAG_8BIT_MODE; + } + sc->sc_sdhc.sc_host = &sc->sc_host; + + sc->sc_bst = faa->faa_bst; + error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); + if (error) { + aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); + return; + } + sc->sc_bsz = size; + + sc->sc_pin_cd = fdtbus_gpio_acquire(faa->faa_phandle, + "cd-gpios", GPIO_PIN_INPUT); + + if (sc->sc_pin_cd) { + sc->sc_sdhc.sc_vendor_card_detect = imx6_sdhc_card_detect; + sc->sc_sdhc.sc_flags |= SDHC_FLAG_POLL_CARD_DET; + } + + error = clk_enable(sc->sc_clk_per); + if (error) { + aprint_error(": couldn't enable clock: %d\n", error); + return; + } + + aprint_naive("\n"); + aprint_normal(": SDMMC (%u kHz)\n", sc->sc_sdhc.sc_clkbase); + + if (sc->sc_sdhc.sc_clkbase == 0) { + aprint_error_dev(self, "couldn't determine frequency\n"); + return; + } + + if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SDMMC, 0, + sdhc_intr, &sc->sc_sdhc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "couldn't establish interrupt on %s\n", + intrstr); + return; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + error = sdhc_host_found(&sc->sc_sdhc, sc->sc_bst, sc->sc_bsh, sc->sc_bsz); + if (error) { + aprint_error_dev(self, "couldn't initialize host, error = %d\n", + error); + fdtbus_intr_disestablish(faa->faa_phandle, sc->sc_ih); + sc->sc_ih = NULL; + return; + } +} + +static int +imx6_sdhc_card_detect(struct sdhc_softc *ssc) +{ + struct imx6_sdhc_softc *sc = device_private(ssc->sc_dev); + + KASSERT(sc->sc_pin_cd != NULL); + + return fdtbus_gpio_read(sc->sc_pin_cd); +} + Index: src/sys/arch/arm/imx/fdt/imx6_usb.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_usb.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_usb.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,277 @@ +/* $NetBSD: imx6_usb.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_usb.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" + +#include <locators.h> + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/bus.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usbdivar.h> +#include <dev/usb/usb_mem.h> + +#include <dev/usb/ehcireg.h> +#include <dev/usb/ehcivar.h> + +#include <arm/imx/imx6var.h> +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6_usbreg.h> +#include <arm/imx/imxusbvar.h> + +#include <dev/fdt/fdtvar.h> + +struct imxusbc_fdt_softc { + struct imxusbc_softc sc_imxusbc; /* Must be first */ + + int sc_phandle; +}; + +static int imx6_usb_match(device_t, struct cfdata *, void *); +static void imx6_usb_attach(device_t, device_t, void *); +static int imx6_usb_init_clocks(struct imxusbc_softc *); +static void imx6_usb_init(struct imxehci_softc *); +static void init_otg(struct imxehci_softc *); +static void init_h1(struct imxehci_softc *); +static int imxusbc_print(void *, const char *); +static void *imx6_usb_intr_establish(struct imxehci_softc *); + +/* attach structures */ +CFATTACH_DECL_NEW(imxusbc_fdt, sizeof(struct imxusbc_fdt_softc), + imx6_usb_match, imx6_usb_attach, NULL, NULL); + +static const char * const compatible[] = { + "fsl,imx6q-usb", + NULL +}; + +static int +imx6_usb_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imx6_usb_attach(device_t parent, device_t self, void *aux) +{ + struct imxusbc_fdt_softc *ifsc = device_private(self); + struct imxusbc_softc *sc = &ifsc->sc_imxusbc; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_space_tag_t bst = faa->faa_bst; + bus_space_handle_t bsh; + bus_addr_t addr; + bus_size_t size; + int error; + + aprint_naive("\n"); + aprint_normal("\n"); + + ifsc->sc_phandle = phandle; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get imxusbc registers\n"); + return; + } + + error = bus_space_map(bst, addr, size, 0, &bsh); + if (error) { + aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); + return; + } + + sc->sc_clk = fdtbus_clock_get_index(phandle, 0); + if (sc->sc_clk == NULL) { + aprint_error(": couldn't get clock\n"); + return; + } + + sc->sc_init_md_hook = imx6_usb_init; + sc->sc_intr_establish_md_hook = imx6_usb_intr_establish; + sc->sc_setup_md_hook = NULL; + + sc->sc_dev = self; + sc->sc_iot = bst; + sc->sc_ioh = bsh; + sc->sc_ehci_size = size; + sc->sc_ehci_offset = 0; + + struct fdt_phandle_data data; + error = fdtbus_get_phandle_with_data(phandle, "fsl,usbmisc", + "#index-cells", 0, &data); + if (error) { + aprint_error(": couldn't get usbmisc property\n"); + return; + } + int unit = be32toh(data.values[0]); + + if (fdtbus_get_reg(data.phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get usbmisc registers\n"); + return; + } + error = bus_space_map(bst, addr, size, 0, &bsh); + if (error) { + aprint_error(": couldn't map usbmisc registers: %d\n", error); + return; + } + sc->sc_ioh_usbnc = bsh; + + if (imx6_usb_init_clocks(sc) != 0) { + aprint_error_dev(self, "couldn't init clocks\n"); + return; + } + + /* attach OTG/EHCI host controllers */ + struct imxusbc_attach_args iaa; + iaa.aa_iot = sc->sc_iot; + iaa.aa_ioh = sc->sc_ioh; + iaa.aa_dmat = faa->faa_dmat; + iaa.aa_unit = unit; + iaa.aa_irq = IMXUSBCCF_IRQ_DEFAULT; + config_found_sm_loc(self, "imxusbc", NULL, &iaa, imxusbc_print, NULL); + + return; +} + +static int +imxusbc_print(void *aux, const char *name __unused) +{ + struct imxusbc_attach_args *iaa; + + iaa = (struct imxusbc_attach_args *)aux; + + aprint_normal(" unit %d intr %d", iaa->aa_unit, iaa->aa_irq); + return UNCONF; +} + + +static int +imx6_usb_init_clocks(struct imxusbc_softc *sc) +{ + int error; + + error = clk_enable(sc->sc_clk); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable: %d\n", error); + return error; + } + + return 0; +} + +static void +imx6_usb_init(struct imxehci_softc *sc) +{ + switch (sc->sc_unit) { + case 0: /* OTG controller */ + init_otg(sc); + break; + case 1: /* EHCI Host 1 */ + init_h1(sc); + break; + case 2: /* EHCI Host 2 */ + case 3: /* EHCI Host 3 */ + default: + aprint_error_dev(sc->sc_dev, "unit %d not supported\n", + sc->sc_unit); + } +} + +static void +init_otg(struct imxehci_softc *sc) +{ + struct imxusbc_softc *usbc = sc->sc_usbc; + uint32_t v; + + sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE; + + imxehci_reset(sc); + + v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_OTG_CTRL); + v |= USBNC_USB_OTG_CTRL_WKUP_VBUS_EN; + v |= USBNC_USB_OTG_CTRL_OVER_CUR_DIS; + v |= USBNC_USB_OTG_CTRL_PWR_POL; + v &= ~USBNC_USB_OTG_CTRL_UTMI_ON_CLOCK; + bus_space_write_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_OTG_CTRL, v); +} + +static void +init_h1(struct imxehci_softc *sc) +{ + struct imxusbc_softc *usbc = sc->sc_usbc; + uint32_t v; + + sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE; + + v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_UH1_CTRL); + v |= USBNC_USB_UH1_CTRL_OVER_CUR_POL; + v |= USBNC_USB_UH1_CTRL_OVER_CUR_DIS; + bus_space_write_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_UH1_CTRL, v); + + /* do reset */ + imxehci_reset(sc); + + /* set mode */ + v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh, USBC_UH1_USBMODE); + v &= ~USBC_UH_USBMODE_CM; + v |= __SHIFTIN(USBC_UH_USBMODE_CM, USBC_UH_USBMODE_CM_HOST_CONTROLLER); + bus_space_write_4(usbc->sc_iot, usbc->sc_ioh, USBC_UH1_USBMODE, v); +} + +static void * +imx6_usb_intr_establish(struct imxehci_softc *sc) +{ + struct imxusbc_fdt_softc *ifsc = (struct imxusbc_fdt_softc *)sc->sc_usbc; + ehci_softc_t *hsc = &sc->sc_hsc; + void *ih; + + char intrstr[128]; + if (!fdtbus_intr_str(ifsc->sc_phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(sc->sc_dev, "failed to decode interrupt\n"); + return NULL; + } + ih = fdtbus_intr_establish(ifsc->sc_phandle, 0, IPL_USB, 0, ehci_intr, hsc); + if (ih == NULL) { + aprint_error_dev(sc->sc_dev, "failed to establish interrupt on %s\n", + intrstr); + return NULL; + } + aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr); + + return ih; +} Index: src/sys/arch/arm/imx/fdt/imx6_usbphy.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_usbphy.c:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/arm/imx/fdt/imx6_usbphy.c Wed Jul 24 13:12:33 2019 @@ -0,0 +1,163 @@ +/* $NetBSD: imx6_usbphy.c,v 1.1 2019/07/24 13:12:33 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 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. + */ +#include <sys/cdefs.h> +__KERNEL_RCSID(1, "$NetBSD: imx6_usbphy.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $"); + +#include "opt_fdt.h" + +#include "locators.h" +#include "ohci.h" +#include "ehci.h" + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> + +#include <arm/imx/imx6var.h> +#include <arm/imx/imx6_reg.h> +#include <arm/imx/imx6_usbphyreg.h> + +#include <dev/fdt/fdtvar.h> + +struct imx6_usbphy_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + struct clk *sc_clk; +}; + +static int imx6_usbphy_match(device_t, cfdata_t, void *); +static void imx6_usbphy_attach(device_t, device_t, void *); + +static int imx6_usbphy_init_clocks(device_t); +static int imx6_usbphy_enable(device_t, void *, bool); + +CFATTACH_DECL_NEW(imxusbphy, sizeof(struct imx6_usbphy_softc), + imx6_usbphy_match, imx6_usbphy_attach, NULL, NULL); + +static const char * const compatible[] = { + "fsl,imx6q-usbphy", + NULL +}; + +static int +imx6_usbphy_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imx6_usbphy_attach(device_t parent, device_t self, void *aux) +{ + struct imx6_usbphy_softc *sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_space_tag_t bst = faa->faa_bst; + bus_space_handle_t bsh; + bus_addr_t addr; + bus_size_t size; + int error; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get iomux registers\n"); + return; + } + + error = bus_space_map(bst, addr, size, 0, &bsh); + if (error) { + aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error); + return; + } + + sc->sc_clk = fdtbus_clock_get_index(phandle, 0); + if (sc->sc_clk == NULL) { + aprint_error(": couldn't get clock\n"); + return; + } + + sc->sc_dev = self; + sc->sc_iot = bst; + sc->sc_ioh = bsh; + + aprint_naive("\n"); + aprint_normal(": USB PHY\n"); + + imx6_usbphy_init_clocks(self); + imx6_usbphy_enable(self, NULL, true); +} + +static int +imx6_usbphy_init_clocks(device_t dev) +{ + struct imx6_usbphy_softc * const sc = device_private(dev); + int error; + + error = clk_enable(sc->sc_clk); + if (error) { + aprint_error_dev(sc->sc_dev, "couldn't enable: %d\n", error); + return error; + } + + return 0; +} + +#define USBPHY_READ(sc, reg) \ + bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)) +#define USBPHY_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) + +static int +imx6_usbphy_enable(device_t dev, void *priv, bool enable) +{ + struct imx6_usbphy_softc * const sc = device_private(dev); + + /* USBPHY enable */ + USBPHY_WRITE(sc, USBPHY_CTRL, USBPHY_CTRL_CLKGATE); + + /* do reset */ + USBPHY_WRITE(sc, USBPHY_CTRL_SET, USBPHY_CTRL_SFTRST); + delay(100); + + /* clear reset, and run clocks */ + USBPHY_WRITE(sc, USBPHY_CTRL_CLR, + USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE); + delay(100); + + /* power on */ + USBPHY_WRITE(sc, USBPHY_PWD, 0); + + /* UTMI+Level2, Level3 */ + USBPHY_WRITE(sc, USBPHY_CTRL_SET, + USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3); + + return 0; +} + Index: src/sys/arch/evbarm/conf/IMX diff -u /dev/null src/sys/arch/evbarm/conf/IMX:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/evbarm/conf/IMX Wed Jul 24 13:12:34 2019 @@ -0,0 +1,134 @@ +# +# $NetBSD: IMX,v 1.1 2019/07/24 13:12:34 hkenken Exp $ +# +# NXP(Freescale) I.MX family SoCs +# + +include "arch/evbarm/conf/std.imx" +include "arch/evbarm/conf/files.imx" +include "arch/evbarm/conf/GENERIC.common" + +makeoptions DTSGNUARCH="arm" +makeoptions DTSSUBDIR="fsl" +makeoptions DTS=" + imx6q-hummingboard.dts + imx6dl-hummingboard.dts + imx6q-hummingboard2.dts + imx6dl-hummingboard2.dts +" + +options MULTIPROCESSOR + +options CPU_CORTEXA9 + +options SOC_IMX6Q +options SOC_IMX6DL +options SOC_IMX6QDL + +pseudo-device openfirm # /dev/openfirm + +#options DIAGNOSTIC # internal consistency checks +#options DEBUG +#options LOCKDEBUG +#options PMAP_DEBUG # Enable pmap_debug_level code +#options IPKDB # remote kernel debugging +#options VERBOSE_INIT_ARM # verbose bootstrapping messages +# CONSADDR is required for early init messages from VERBOSE_INIT_ARM. +options CONSADDR=0x02020000 +options EARLYCONS=imx +options BOOT_ARGS="\"verbose debug\"" + +makeoptions DEBUG="-g" # compile full symbol table +makeoptions COPY_SYMTAB=1 + +config netbsd root on ? type ? + +# Device tree support +armfdt0 at root +simplebus* at fdt? pass 0 + +# CPUs +cpus* at fdt? pass 0 +cpu* at fdt? pass 0 + +# Timer +a9tmr* at fdt? pass 2 # A9 Global Timer +arma9tmr0 at a9tmr? + +# Interrupt controller +gic* at fdt? pass 1 # ARM Generic Interrupt Controller +armgic0 at gic? + +l2cc* at fdt? pass 1 # ARM Cortex A9 L2 Cache Controller +arml2cc* at l2cc? + +# Clock +fclock* at fdt? pass 1 +ffclock* at fdt? pass 1 +fregulator* at fdt? pass 5 +gregulator* at fdt? pass 4 +imxccm* at fdt? pass 1 # i.MX6 ccm + +# IOMUX +imxiomux* at fdt? pass 2 + +# GPC +imxgpc* at fdt? pass 2 + +# GPIO +imxgpio* at fdt? pass 3 +gpio* at gpiobus? + +# UART +imxuart* at fdt? +options IMXUARTCONSOLE + +# Network Interfaces +enet* at fdt? # FEC + +# MII/PHY support +atphy* at mii? phy ? # Attansic/Atheros PHYs +ukphy* at mii? phy ? # generic unknown PHYs + +# SATA +ahcisata* at fdt? # SATA +atabus* at ahcisata? channel ? +wd* at atabus? drive ? + +# ATAPI bus support +atapibus* at atapi? + +# ATAPI devices +# flags have the same meaning as for IDE drives. +cd* at atapibus? drive ? flags 0x0000 # ATAPI CD-ROM drives +sd* at atapibus? drive ? flags 0x0000 # ATAPI disk drives +st* at atapibus? drive ? flags 0x0000 # ATAPI tape drives +uk* at atapibus? drive ? flags 0x0000 # ATAPI unknown + +# SDMMC +sdhc* at fdt? # SDMMC +sdmmc* at sdhc? +ld* at sdmmc? + +# USB +imxusbphy* at fdt? +imxusbc* at fdt? +ehci* at imxusbc? +usb* at ehci? + +# USB device drivers +include "dev/usb/usbdevices.config" + +midi* at midibus? + +# PCIe +imxpcie* at fdt? +#options PCIVERBOSE +#options PCI_CONFIG_DUMP + +pci* at imxpcie? +ppb* at pci? dev ? function ? +pci* at ppb? + +cinclude "arch/evbarm/conf/IMX.local" + Index: src/sys/arch/evbarm/conf/files.imx diff -u /dev/null src/sys/arch/evbarm/conf/files.imx:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/evbarm/conf/files.imx Wed Jul 24 13:12:34 2019 @@ -0,0 +1,12 @@ +# $NetBSD: files.imx,v 1.1 2019/07/24 13:12:34 hkenken Exp $ +# +# NXP(Freescale) i.MX configuration info +# + +include "arch/arm/pic/files.pic" +include "arch/arm/cortex/files.cortex" + +include "arch/evbarm/conf/files.fdt" + +include "arch/arm/imx/fdt/files.imx6" + Index: src/sys/arch/evbarm/conf/mk.imx diff -u /dev/null src/sys/arch/evbarm/conf/mk.imx:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/evbarm/conf/mk.imx Wed Jul 24 13:12:34 2019 @@ -0,0 +1,34 @@ +# $NetBSD: mk.imx,v 1.1 2019/07/24 13:12:34 hkenken Exp $ + +.if !empty(MACHINE_ARCH:M*eb) +EXTRA_LINKFLAGS+= --be8 +.endif + +ENTRYPOINT= generic_start + +SYSTEM_FIRST_OBJ= armv6_start.o +SYSTEM_FIRST_SFILE= ${ARM}/arm/armv6_start.S + +_OSRELEASE!= ${HOST_SH} $S/conf/osrelease.sh + +MKUBOOTIMAGEARGS= -A arm -T kernel -O linux +MKUBOOTIMAGEARGS+= -e 0 +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_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.imx diff -u /dev/null src/sys/arch/evbarm/conf/std.imx:1.1 --- /dev/null Wed Jul 24 13:12:34 2019 +++ src/sys/arch/evbarm/conf/std.imx Wed Jul 24 13:12:34 2019 @@ -0,0 +1,32 @@ +# $NetBSD: std.imx,v 1.1 2019/07/24 13:12:34 hkenken Exp $ +# + +machine evbarm arm +include "arch/arm/conf/std.arm" # arch standard options +include "arch/evbarm/conf/std.evbarm" + +# Architecture opions +options ARM_GENERIC_TODR +options ARM_HAS_VBAR +options ARM_INTR_IMPL="<arch/arm/fdt/fdt_intr.h>" +options DRAM_BLOCKS=256 +options EVBARM_BOARDTYPE="evbarm" +options FDT # Flattened Device Tree support +options FPU_VFP +options MODULAR +options MODULAR_DEFAULT_AUTOLOAD +options PCI_NETBSD_CONFIGURE +options TPIDRPRW_IS_CURCPU +options __BUS_SPACE_HAS_STREAM_METHODS +options __HAVE_CPU_COUNTER +options __HAVE_CPU_UAREA_ALLOC_IDLELWP +options __HAVE_GENERIC_START +options __HAVE_GENERIC_CPU_INITCLOCKS +options __HAVE_FAST_SOFTINTS # should be in types.h +options __HAVE_PCI_CONF_HOOK +#options __HAVE_PCI_MSI_MSIX + +makeoptions BOARDMKFRAG="${THISARM}/conf/mk.imx" + +makeoptions KERNEL_BASE_PHYS="0x18000000" +makeoptions KERNEL_BASE_VIRT="0x80000000"