diff --git a/sys/arm/altera/socfpga/files.socfpga b/sys/arm/altera/socfpga/files.socfpga index bb228d8fe0db..441e38842bf0 100644 --- a/sys/arm/altera/socfpga/files.socfpga +++ b/sys/arm/altera/socfpga/files.socfpga @@ -16,3 +16,4 @@ arm/arm/mpcore_timer.c standard arm/altera/socfpga/socfpga_common.c standard arm/altera/socfpga/socfpga_machdep.c standard arm/altera/socfpga/socfpga_manager.c standard +arm/altera/socfpga/socfpga_rstmgr.c standard diff --git a/sys/arm/altera/socfpga/socfpga_common.c b/sys/arm/altera/socfpga/socfpga_common.c index 86d46e3f2dff..6531a416c1a9 100644 --- a/sys/arm/altera/socfpga/socfpga_common.c +++ b/sys/arm/altera/socfpga/socfpga_common.c @@ -42,20 +42,31 @@ __FBSDID("$FreeBSD$"); #include #include -#define RESMAN_BASE 0xFFD05000 -#define RESMAN_CTRL 0x4 -#define SWWARMRSTREQ (1 << 1) +#include void cpu_reset(void) { + uint32_t addr, paddr; bus_addr_t vaddr; + phandle_t node; - if (bus_space_map(fdtbus_bs_tag, RESMAN_BASE, 0x10, 0, &vaddr) == 0) { - bus_space_write_4(fdtbus_bs_tag, vaddr, - RESMAN_CTRL, SWWARMRSTREQ); + if (rstmgr_warmreset() == 0) + goto end; + + node = OF_finddevice("rstmgr"); + if (node == -1) + goto end; + + if ((OF_getprop(node, "reg", &paddr, sizeof(paddr))) > 0) { + addr = fdt32_to_cpu(paddr); + if (bus_space_map(fdtbus_bs_tag, addr, 0x8, 0, &vaddr) == 0) { + bus_space_write_4(fdtbus_bs_tag, vaddr, + RSTMGR_CTRL, CTRL_SWWARMRSTREQ); + } } +end: while (1); } diff --git a/sys/arm/altera/socfpga/socfpga_l3regs.h b/sys/arm/altera/socfpga/socfpga_l3regs.h new file mode 100644 index 000000000000..b4ef6f6d980d --- /dev/null +++ b/sys/arm/altera/socfpga/socfpga_l3regs.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2014 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define L3REGS_REMAP 0x0 /* Remap */ +#define REMAP_LWHPS2FPGA (1 << 4) +#define REMAP_HPS2FPGA (1 << 3) +#define REMAP_MPUZERO (1 << 0) +#define L3REGS_L4MAIN 0x8 /* L4 main peripherals security */ +#define L3REGS_L4SP 0xC /* L4 SP Peripherals Security */ +#define L3REGS_L4MP 0x10 /* L4 MP Peripherals Security */ +#define L3REGS_L4OSC1 0x14 /* L4 OSC1 Peripherals Security */ +#define L3REGS_L4SPIM 0x18 /* L4 SPIM Peripherals Security */ +#define L3REGS_STM 0x1C /* STM Peripheral Security */ +#define L3REGS_LWHPS2FPGAREGS 0x20 /* LWHPS2FPGA AXI Bridge Security */ +#define L3REGS_USB1 0x28 /* USB1 Peripheral Security */ +#define L3REGS_NANDDATA 0x2C /* NAND Flash Controller Data Sec */ +#define L3REGS_USB0 0x80 /* USB0 Peripheral Security */ +#define L3REGS_NANDREGS 0x84 /* NAND Flash Controller Security */ +#define L3REGS_QSPIDATA 0x88 /* QSPI Flash Controller Data Sec */ +#define L3REGS_FPGAMGRDATA 0x8C /* FPGA Manager Data Peripheral Sec */ +#define L3REGS_HPS2FPGAREGS 0x90 /* HPS2FPGA AXI Bridge Perip. Sec */ +#define L3REGS_ACP 0x94 /* MPU ACP Peripheral Security */ +#define L3REGS_ROM 0x98 /* ROM Peripheral Security */ +#define L3REGS_OCRAM 0x9C /* On-chip RAM Peripheral Security */ +#define L3REGS_SDRDATA 0xA0 /* SDRAM Data Peripheral Security */ diff --git a/sys/arm/altera/socfpga/socfpga_rstmgr.c b/sys/arm/altera/socfpga/socfpga_rstmgr.c new file mode 100644 index 000000000000..36a1d7558210 --- /dev/null +++ b/sys/arm/altera/socfpga/socfpga_rstmgr.c @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2014 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * SOCFPGA Reset Manager. + * Chapter 3, Cyclone V Device Handbook (CV-5V2 2014.07.22) + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +struct rstmgr_softc { + struct resource *res[1]; + bus_space_tag_t bst; + bus_space_handle_t bsh; + device_t dev; +}; + +struct rstmgr_softc *rstmgr_sc; + +static struct resource_spec rstmgr_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +enum { + RSTMGR_SYSCTL_FPGA2HPS, + RSTMGR_SYSCTL_LWHPS2FPGA, + RSTMGR_SYSCTL_HPS2FPGA +}; + +static int +l3remap(struct rstmgr_softc *sc, int remap, int enable) +{ + uint32_t addr, paddr; + bus_addr_t vaddr; + phandle_t node; + int reg; + + /* + * Control whether bridge is visible to L3 masters or not. + * Register is write-only. + */ + + reg = REMAP_MPUZERO; + if (enable) + reg |= (remap); + else + reg &= ~(remap); + + node = OF_finddevice("l3regs"); + if (node == -1) { + device_printf(sc->dev, "Can't find l3regs node\n"); + return (1); + } + + if ((OF_getprop(node, "reg", &paddr, sizeof(paddr))) > 0) { + addr = fdt32_to_cpu(paddr); + if (bus_space_map(fdtbus_bs_tag, addr, 0x4, 0, &vaddr) == 0) { + bus_space_write_4(fdtbus_bs_tag, vaddr, + L3REGS_REMAP, reg); + return (0); + } + } + + return (1); +} + +static int +rstmgr_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct rstmgr_softc *sc; + int enable; + int remap; + int err; + int reg; + int bit; + + sc = arg1; + + switch (arg2) { + case RSTMGR_SYSCTL_FPGA2HPS: + bit = BRGMODRST_FPGA2HPS; + remap = 0; + break; + case RSTMGR_SYSCTL_LWHPS2FPGA: + bit = BRGMODRST_LWHPS2FPGA; + remap = REMAP_LWHPS2FPGA; + break; + case RSTMGR_SYSCTL_HPS2FPGA: + bit = BRGMODRST_HPS2FPGA; + remap = REMAP_HPS2FPGA; + break; + default: + return (1); + }; + + reg = READ4(sc, RSTMGR_BRGMODRST); + enable = reg & bit ? 0 : 1; + + err = sysctl_handle_int(oidp, &enable, 0, req); + if (err || !req->newptr) + return (err); + + if (enable == 1) + reg &= ~(bit); + else if (enable == 0) + reg |= (bit); + else + return (EINVAL); + + WRITE4(sc, RSTMGR_BRGMODRST, reg); + l3remap(sc, remap, enable); + + return (0); +} + +int +rstmgr_warmreset(void) +{ + struct rstmgr_softc *sc; + + sc = rstmgr_sc; + if (sc == NULL) + return (1); + + /* Request warm reset */ + WRITE4(sc, RSTMGR_CTRL, + CTRL_SWWARMRSTREQ); + + return (0); +} + +static int +rstmgr_add_sysctl(struct rstmgr_softc *sc) +{ + struct sysctl_oid_list *children; + struct sysctl_ctx_list *ctx; + + ctx = device_get_sysctl_ctx(sc->dev); + children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)); + + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fpga2hps", + CTLTYPE_UINT | CTLFLAG_RW, sc, RSTMGR_SYSCTL_FPGA2HPS, + rstmgr_sysctl, "I", "Enable fpga2hps bridge"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "lwhps2fpga", + CTLTYPE_UINT | CTLFLAG_RW, sc, RSTMGR_SYSCTL_LWHPS2FPGA, + rstmgr_sysctl, "I", "Enable lwhps2fpga bridge"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "hps2fpga", + CTLTYPE_UINT | CTLFLAG_RW, sc, RSTMGR_SYSCTL_HPS2FPGA, + rstmgr_sysctl, "I", "Enable hps2fpga bridge"); + + return (0); +} + +static int +rstmgr_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "altr,rst-mgr")) + return (ENXIO); + + device_set_desc(dev, "Reset Manager"); + return (BUS_PROBE_DEFAULT); +} + +static int +rstmgr_attach(device_t dev) +{ + struct rstmgr_softc *sc; + + sc = device_get_softc(dev); + sc->dev = dev; + + if (bus_alloc_resources(dev, rstmgr_spec, sc->res)) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + + /* Memory interface */ + sc->bst = rman_get_bustag(sc->res[0]); + sc->bsh = rman_get_bushandle(sc->res[0]); + + rstmgr_sc = sc; + rstmgr_add_sysctl(sc); + + return (0); +} + +static device_method_t rstmgr_methods[] = { + DEVMETHOD(device_probe, rstmgr_probe), + DEVMETHOD(device_attach, rstmgr_attach), + { 0, 0 } +}; + +static driver_t rstmgr_driver = { + "rstmgr", + rstmgr_methods, + sizeof(struct rstmgr_softc), +}; + +static devclass_t rstmgr_devclass; + +DRIVER_MODULE(rstmgr, simplebus, rstmgr_driver, rstmgr_devclass, 0, 0); diff --git a/sys/arm/altera/socfpga/socfpga_rstmgr.h b/sys/arm/altera/socfpga/socfpga_rstmgr.h new file mode 100644 index 000000000000..db7d2a088b40 --- /dev/null +++ b/sys/arm/altera/socfpga/socfpga_rstmgr.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2014 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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 AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define RSTMGR_STAT 0x0 /* Status */ +#define RSTMGR_CTRL 0x4 /* Control */ +#define CTRL_SWWARMRSTREQ (1 << 1) /* Trigger warm reset */ +#define RSTMGR_COUNTS 0x8 /* Reset Cycles Count */ +#define RSTMGR_MPUMODRST 0x10 /* MPU Module Reset */ +#define RSTMGR_PERMODRST 0x14 /* Peripheral Module Reset */ +#define RSTMGR_PER2MODRST 0x18 /* Peripheral 2 Module Reset */ +#define RSTMGR_BRGMODRST 0x1C /* Bridge Module Reset */ +#define BRGMODRST_FPGA2HPS (1 << 2) +#define BRGMODRST_LWHPS2FPGA (1 << 1) +#define BRGMODRST_HPS2FPGA (1 << 0) +#define RSTMGR_MISCMODRST 0x20 /* Miscellaneous Module Reset */ + +int rstmgr_warmreset(void); diff --git a/sys/boot/fdt/dts/arm/socfpga.dtsi b/sys/boot/fdt/dts/arm/socfpga.dtsi index 38adb1ed4c9b..e1b56cc456bf 100644 --- a/sys/boot/fdt/dts/arm/socfpga.dtsi +++ b/sys/boot/fdt/dts/arm/socfpga.dtsi @@ -39,6 +39,8 @@ aliases { soc = &SOC; + rstmgr = &rstmgr; + l3regs = &l3regs; serial0 = &serial0; serial1 = &serial1; }; @@ -69,6 +71,16 @@ interrupt-parent = < &GIC >; }; + rstmgr: rstmgr@ffd05000 { + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>; + }; + + l3regs: l3regs@ff800000 { + compatible = "altr,l3regs"; + reg = <0xff800000 0x1000>; + }; + fpgamgr: fpgamgr@ff706000 { compatible = "altr,fpga-mgr"; reg = <0xff706000 0x1000>, /* FPGAMGRREGS */