diff --git a/sys/arm/annapurna/alpine/alpine_ccu.c b/sys/arm/annapurna/alpine/alpine_ccu.c new file mode 100644 index 000000000000..19dc57a6dc53 --- /dev/null +++ b/sys/arm/annapurna/alpine/alpine_ccu.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 2015,2016 Annapurna Labs Ltd. and affiliates + * All rights reserved. + * + * Developed by Semihalf. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define AL_CCU_SNOOP_CONTROL_IOFAB_0_OFFSET 0x4000 +#define AL_CCU_SNOOP_CONTROL_IOFAB_1_OFFSET 0x5000 +#define AL_CCU_SPECULATION_CONTROL_OFFSET 0x4 + +static struct resource_spec al_ccu_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +struct al_ccu_softc { + struct resource *res; +}; + +static int al_ccu_probe(device_t dev); +static int al_ccu_attach(device_t dev); +static int al_ccu_detach(device_t dev); + +static device_method_t al_ccu_methods[] = { + DEVMETHOD(device_probe, al_ccu_probe), + DEVMETHOD(device_attach, al_ccu_attach), + DEVMETHOD(device_detach, al_ccu_detach), + + { 0, 0 } +}; + +static driver_t al_ccu_driver = { + "ccu", + al_ccu_methods, + sizeof(struct al_ccu_softc) +}; + +static devclass_t al_ccu_devclass; + +EARLY_DRIVER_MODULE(al_ccu, simplebus, al_ccu_driver, + al_ccu_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE); +EARLY_DRIVER_MODULE(al_ccu, ofwbus, al_ccu_driver, + al_ccu_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE); + +static int +al_ccu_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "annapurna-labs,al-ccu")) + return (ENXIO); + + device_set_desc(dev, "Alpine CCU"); + + return (BUS_PROBE_DEFAULT); +} + +static int +al_ccu_attach(device_t dev) +{ + struct al_ccu_softc *sc; + int err; + + sc = device_get_softc(dev); + + err = bus_alloc_resources(dev, al_ccu_spec, &sc->res); + if (err != 0) { + device_printf(dev, "could not allocate resources\n"); + return (err); + } + + /* Enable cache snoop */ + bus_write_4(sc->res, AL_CCU_SNOOP_CONTROL_IOFAB_0_OFFSET, 1); + bus_write_4(sc->res, AL_CCU_SNOOP_CONTROL_IOFAB_1_OFFSET, 1); + + /* Disable speculative fetches from masters */ + bus_write_4(sc->res, AL_CCU_SPECULATION_CONTROL_OFFSET, 7); + + return (0); +} + +static int +al_ccu_detach(device_t dev) +{ + struct al_ccu_softc *sc; + + sc = device_get_softc(dev); + + bus_release_resources(dev, al_ccu_spec, &sc->res); + + return (0); +} diff --git a/sys/arm/annapurna/alpine/alpine_nb_service.c b/sys/arm/annapurna/alpine/alpine_nb_service.c new file mode 100644 index 000000000000..3725cd340f33 --- /dev/null +++ b/sys/arm/annapurna/alpine/alpine_nb_service.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 2015,2016 Annapurna Labs Ltd. and affiliates + * All rights reserved. + * + * Developed by Semihalf. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define AL_NB_ACF_MISC_OFFSET 0xD0 +#define AL_NB_ACF_MISC_READ_BYPASS (1 << 30) + +static struct resource_spec nb_service_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +struct nb_service_softc { + struct resource *res; +}; + +static int nb_service_probe(device_t dev); +static int nb_service_attach(device_t dev); +static int nb_service_detach(device_t dev); + +static device_method_t nb_service_methods[] = { + DEVMETHOD(device_probe, nb_service_probe), + DEVMETHOD(device_attach, nb_service_attach), + DEVMETHOD(device_detach, nb_service_detach), + + { 0, 0 } +}; + +static driver_t nb_service_driver = { + "nb_service", + nb_service_methods, + sizeof(struct nb_service_softc) +}; + +static devclass_t nb_service_devclass; + +EARLY_DRIVER_MODULE(nb_service, simplebus, nb_service_driver, + nb_service_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE); +EARLY_DRIVER_MODULE(nb_service, ofwbus, nb_service_driver, + nb_service_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE); + +static int +nb_service_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "annapurna-labs,al-nb-service")) + return (ENXIO); + + device_set_desc(dev, "Alpine North Bridge Service"); + + return (BUS_PROBE_DEFAULT); +} + +static int +nb_service_attach(device_t dev) +{ + struct nb_service_softc *sc; + uint32_t val; + int err; + + sc = device_get_softc(dev); + + err = bus_alloc_resources(dev, nb_service_spec, &sc->res); + if (err != 0) { + device_printf(dev, "could not allocate resources\n"); + return (err); + } + + /* Do not allow reads to bypass writes to different addresses */ + val = bus_read_4(sc->res, AL_NB_ACF_MISC_OFFSET); + val &= ~AL_NB_ACF_MISC_READ_BYPASS; + bus_write_4(sc->res, AL_NB_ACF_MISC_OFFSET, val); + + return (0); +} + +static int +nb_service_detach(device_t dev) +{ + struct nb_service_softc *sc; + + sc = device_get_softc(dev); + + bus_release_resources(dev, nb_service_spec, &sc->res); + + return (0); +} diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index 40c3fc65e503..35633ec5c055 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -90,6 +90,10 @@ options SOC_ALLWINNER_A64 options SOC_CAVM_THUNDERX options SOC_HISI_HI6220 +# Annapurna Alpine drivers +device al_ccu # Alpine Cache Coherency Unit +device al_nb_service # Alpine North Bridge Service + # VirtIO support device virtio device virtio_mmio diff --git a/sys/boot/fdt/dts/arm/annapurna-alpine.dts b/sys/boot/fdt/dts/arm/annapurna-alpine.dts index 100d2d046feb..f6768db7882e 100644 --- a/sys/boot/fdt/dts/arm/annapurna-alpine.dts +++ b/sys/boot/fdt/dts/arm/annapurna-alpine.dts @@ -137,6 +137,12 @@ reg = <0x00ff5ec0 0x30>; }; + ccu { + compatible = "annapurna-labs,al-ccu"; + reg = <0x00090000 0x10000>; + io_coherency = <1>; + }; + nb_service { compatible = "annapurna-labs,al-nb-service"; reg = <0x00070000 0x10000>; diff --git a/sys/conf/files.arm b/sys/conf/files.arm index c2eaf4af6099..86ae79e96dd1 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -1,4 +1,6 @@ # $FreeBSD$ +arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt +arm/annapurna/alpine/alpine_nb_service.c optional al_nb_service fdt arm/arm/autoconf.c standard arm/arm/bcopy_page.S standard arm/arm/bcopyinout.S standard diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 46b28909e50d..c3d795734f18 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -38,6 +38,8 @@ arm/allwinner/clk/aw_pll.c optional aw_ccu \ arm/allwinner/clk/aw_thsclk.c optional aw_ccu arm/allwinner/clk/aw_usbclk.c optional aw_ccu arm/allwinner/if_awg.c optional awg +arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt +arm/annapurna/alpine/alpine_nb_service.c optional al_nb_service fdt arm/arm/generic_timer.c standard arm/arm/gic.c standard arm/arm/gic_fdt.c optional fdt