From 735c7fe55ead40fb9b6d75294d2ae840a00cb149 Mon Sep 17 00:00:00 2001 From: "Wojciech A. Koszek" Date: Sat, 27 Apr 2013 23:07:49 +0000 Subject: [PATCH] Add Xilinx Zynq ARM/FPGA SoC support to FreeBSD/arm port. Submitted by: Thomas Skibo Tested by: wkoszek (ZedBoard) Reviewed by: wkoszek, freebsd-arm@ (no objections raised) --- share/man/man4/man4.arm/Makefile | 2 +- share/man/man4/man4.arm/devcfg.4 | 84 ++++++++++++++++++++++++++++++++ sys/arm/arm/cpufunc.c | 3 +- sys/arm/arm/identcpu.c | 2 + sys/arm/include/armreg.h | 1 + sys/dev/mmc/mmc.c | 1 + sys/dev/uart/uart.h | 1 + sys/dev/uart/uart_bus_fdt.c | 4 ++ 8 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 share/man/man4/man4.arm/devcfg.4 diff --git a/share/man/man4/man4.arm/Makefile b/share/man/man4/man4.arm/Makefile index 8d3e2e1c362c..3bf4db0ed914 100644 --- a/share/man/man4/man4.arm/Makefile +++ b/share/man/man4/man4.arm/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -MAN= mge.4 npe.4 +MAN= mge.4 npe.4 devcfg.4 MLINKS= mge.4 if_mge.4 MLINKS+=npe.4 if_npe.4 diff --git a/share/man/man4/man4.arm/devcfg.4 b/share/man/man4/man4.arm/devcfg.4 new file mode 100644 index 000000000000..5068fa4f7b45 --- /dev/null +++ b/share/man/man4/man4.arm/devcfg.4 @@ -0,0 +1,84 @@ +.\" +.\" Copyright (c) 2013 Thomas Skibo +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" 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$ +.\" +.Dd February 28, 2013 +.Dt DEVCFG 4 +.Os +.Sh NAME +.Nm devcfg +.Nd Zynq PL device config interface +.Sh SYNOPSIS +.Cd device devcfg +.Sh DESCRIPTION +The special file +.Pa /dev/devcfg +can be used to configure the PL (FPGA) section of the Xilinx Zynq-7000. +.Pp +On the first write to the character device at file offset 0, the devcfg driver +asserts the top-level PL reset signals, disables the PS-PL level shifters, +and clears the PL configuration. Write data is sent to +the PCAP (processor configuration access port). When the PL asserts the +DONE signal, the devcfg driver will enable the level shifters and release +the top-level PL reset signals. +.Pp +The PL (FPGA) can be configured by writing the bitstream to the +character device like this: +.Bd -literal -offset indent +cat design.bit.bin > /dev/devcfg +.Ed +.Pp +The file should not be confused with the .bit file output by the FPGA +design tools. It is the binary form of the configuration bitstream. +The Xilinx +.Pa promgen +tool can do the conversion: +.Bd -literal -offset indent +promgen -b -w -p bin -data_width 32 -u 0 design.bit -o design.bit.bin +.Ed +.Sh SYSCTL VARIABLES +The devcfg driver provides the following +.Xr sysctl 8 +variables: +.Bl -tag -width 12 +.It Va hw.fpga.pl_done +.Pp +This variable always reflects the status of the PL's DONE signal. A 1 +means the PL section has been properly programmed. +.It Va hw.fpga.en_level_shifters +.Pp +This variable controls if the PS-PL level shifters are enabled after the +PL section has been reconfigured. This variable is 1 by default but setting +it to 0 allows the PL section to be programmed with configurations that +don't interface to the PS section of the part. Changing this value has no +effect on the level shifters until the next device reconfiguration. +.Sh FILES +/dev/devcfg Character device for +.Nm +driver. +.Sh AUTHORS +Thomas Skibo +.Sh SEE ALSO +Zynq-7000 SoC Technical Reference Manual (Xilinx doc UG585) diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 1d15e27dd500..f2359518850c 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -1480,7 +1480,8 @@ set_cpufuncs() cputype == CPU_ID_CORTEXA8R2 || cputype == CPU_ID_CORTEXA8R3 || cputype == CPU_ID_CORTEXA9R1 || - cputype == CPU_ID_CORTEXA9R2) { + cputype == CPU_ID_CORTEXA9R2 || + cputype == CPU_ID_CORTEXA9R3) { cpufuncs = cortexa_cpufuncs; cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ get_cachetype_cp15(); diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu.c index 56f6e067237f..414396a9e468 100644 --- a/sys/arm/arm/identcpu.c +++ b/sys/arm/arm/identcpu.c @@ -246,6 +246,8 @@ const struct cpuidtab cpuids[] = { generic_steppings }, { CPU_ID_CORTEXA9R2, CPU_CLASS_CORTEXA, "Cortex A9-r2", generic_steppings }, + { CPU_ID_CORTEXA9R3, CPU_CLASS_CORTEXA, "Cortex A9-r3", + generic_steppings }, { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110", sa110_steppings }, diff --git a/sys/arm/include/armreg.h b/sys/arm/include/armreg.h index 35fe6d743626..238dfe261d99 100644 --- a/sys/arm/include/armreg.h +++ b/sys/arm/include/armreg.h @@ -152,6 +152,7 @@ #define CPU_ID_CORTEXA8R3 0x413fc080 #define CPU_ID_CORTEXA9R1 0x411fc090 #define CPU_ID_CORTEXA9R2 0x412fc090 +#define CPU_ID_CORTEXA9R3 0x413fc090 #define CPU_ID_SA110 0x4401a100 #define CPU_ID_SA1100 0x4401a110 #define CPU_ID_TI925T 0x54029250 diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c index dd4c5ef9d1c9..f101e6599650 100644 --- a/sys/dev/mmc/mmc.c +++ b/sys/dev/mmc/mmc.c @@ -1734,3 +1734,4 @@ DRIVER_MODULE(mmc, ti_mmchs, mmc_driver, mmc_devclass, NULL, NULL); DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL); DRIVER_MODULE(mmc, sdhci_pci, mmc_driver, mmc_devclass, NULL, NULL); DRIVER_MODULE(mmc, sdhci_bcm, mmc_driver, mmc_devclass, NULL, NULL); +DRIVER_MODULE(mmc, sdhci_fdt, mmc_driver, mmc_devclass, NULL, NULL); diff --git a/sys/dev/uart/uart.h b/sys/dev/uart/uart.h index 52297477d007..772793f88284 100644 --- a/sys/dev/uart/uart.h +++ b/sys/dev/uart/uart.h @@ -72,6 +72,7 @@ extern struct uart_class uart_sbbc_class __attribute__((weak)); extern struct uart_class uart_z8530_class __attribute__((weak)); extern struct uart_class uart_lpc_class __attribute__((weak)); extern struct uart_class uart_pl011_class __attribute__((weak)); +extern struct uart_class uart_cdnc_class __attribute__((weak)); #ifdef PC98 struct uart_class *uart_pc98_getdev(u_long port); diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c index cd4f71ca60b3..f45a1c6aeac7 100644 --- a/sys/dev/uart/uart_bus_fdt.c +++ b/sys/dev/uart/uart_bus_fdt.c @@ -109,6 +109,8 @@ uart_fdt_probe(device_t dev) sc->sc_class = &uart_imx_class; else if (ofw_bus_is_compatible(dev, "arm,pl011")) sc->sc_class = &uart_pl011_class; + else if (ofw_bus_is_compatible(dev, "cadence,uart")) + sc->sc_class = &uart_cdnc_class; else return (ENXIO); @@ -196,6 +198,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) class = &uart_ns8250_class; if (fdt_is_compatible(node, "arm,pl011")) class = &uart_pl011_class; + if (fdt_is_compatible(node, "cadence,uart")) + class = &uart_cdnc_class; di->bas.chan = 0; di->bas.regshft = (u_int)shift;