summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-14 20:11:20 +0000
committerian <ian@FreeBSD.org>2014-05-14 20:11:20 +0000
commitf6194d9105a20998792570a5c3733a06ebe6f906 (patch)
tree5b6fd5c8a0ce1d17498d3870c53104c8d7f0c61f
parent057c7452877929463827f58db062e6c8a7e70e1e (diff)
downloadFreeBSD-src-f6194d9105a20998792570a5c3733a06ebe6f906.zip
FreeBSD-src-f6194d9105a20998792570a5c3733a06ebe6f906.tar.gz
MFC r256839, r256948, r256950, r257299, r257414, r258057, r259090
Add configuration for the Freescale i.MX53 Quick Start Board. Add the Raspberry Pi BSC (I2C compliant) controller driver. Add Radxa Rock board (by radxa.com) support. Digi-CCWMX53: enable ffec and uart, USB. Add support for Freescale Vybrid Family VF600 Move and rename dwc otg driver to more generic one as it appears to work for rk3188 SoC based board too.
-rw-r--r--sys/arm/broadcom/bcm2835/files.bcm28352
-rw-r--r--sys/arm/conf/COSMIC139
-rw-r--r--sys/arm/conf/DIGI-CCWMX5320
-rw-r--r--sys/arm/conf/RADXA119
-rw-r--r--sys/arm/freescale/vybrid/files.vybrid28
-rw-r--r--sys/arm/freescale/vybrid/std.vybrid20
-rw-r--r--sys/arm/freescale/vybrid/vf_anadig.c214
-rw-r--r--sys/arm/freescale/vybrid/vf_ccm.c188
-rw-r--r--sys/arm/freescale/vybrid/vf_common.c86
-rw-r--r--sys/arm/freescale/vybrid/vf_common.h40
-rw-r--r--sys/arm/freescale/vybrid/vf_ehci.c416
-rw-r--r--sys/arm/freescale/vybrid/vf_gpio.c403
-rw-r--r--sys/arm/freescale/vybrid/vf_iomuxc.c171
-rw-r--r--sys/arm/freescale/vybrid/vf_iomuxc.h165
-rw-r--r--sys/arm/freescale/vybrid/vf_machdep.c93
-rw-r--r--sys/arm/freescale/vybrid/vf_mscm.c123
-rw-r--r--sys/arm/freescale/vybrid/vf_nfc.c524
-rw-r--r--sys/arm/freescale/vybrid/vf_src.c147
-rw-r--r--sys/arm/freescale/vybrid/vf_src.h30
-rw-r--r--sys/arm/freescale/vybrid/vf_uart.c509
-rw-r--r--sys/boot/fdt/dts/digi-ccwmx53.dts4
-rw-r--r--sys/boot/fdt/dts/rk3188-radxa.dts59
-rw-r--r--sys/boot/fdt/dts/rk3188.dtsi251
-rw-r--r--sys/boot/fdt/dts/vybrid-cosmic.dts56
-rw-r--r--sys/boot/fdt/dts/vybrid.dtsi223
-rw-r--r--sys/dev/uart/uart.h1
-rw-r--r--sys/dev/uart/uart_bus_fdt.c1
-rw-r--r--sys/dev/usb/controller/dwc_otg_fdt.c (renamed from sys/arm/broadcom/bcm2835/dwc_otg_brcm.c)0
28 files changed, 4023 insertions, 9 deletions
diff --git a/sys/arm/broadcom/bcm2835/files.bcm2835 b/sys/arm/broadcom/bcm2835/files.bcm2835
index ca13964..e7356ae 100644
--- a/sys/arm/broadcom/bcm2835/files.bcm2835
+++ b/sys/arm/broadcom/bcm2835/files.bcm2835
@@ -14,7 +14,7 @@ arm/broadcom/bcm2835/bcm2835_systimer.c standard
arm/broadcom/bcm2835/bcm2835_wdog.c standard
arm/broadcom/bcm2835/bus_space.c optional fdt
arm/broadcom/bcm2835/common.c optional fdt
-arm/broadcom/bcm2835/dwc_otg_brcm.c optional dwcotg
+dev/usb/controller/dwc_otg_fdt.c optional dwcotg
arm/arm/bus_space_generic.c standard
arm/arm/bus_space_asm_generic.S standard
diff --git a/sys/arm/conf/COSMIC b/sys/arm/conf/COSMIC
new file mode 100644
index 0000000..409895c
--- /dev/null
+++ b/sys/arm/conf/COSMIC
@@ -0,0 +1,139 @@
+# Kernel configuration for Cosmic Board (Freescale Vybrid Family development board).
+#
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
+
+ident COSMIC
+
+include "../freescale/vybrid/std.vybrid"
+
+makeoptions MODULES_OVERRIDE=""
+makeoptions WITHOUT_MODULES="ahc"
+
+makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+makeoptions WERROR="-Werror"
+
+options HZ=100 ##
+options SCHED_4BSD #4BSD scheduler
+options INET #InterNETworking
+options INET6 #IPv6 communications protocols
+options FFS #Berkeley Fast Filesystem
+options SOFTUPDATES
+options UFS_ACL #Support for access control lists
+options UFS_DIRHASH #Improve performance on big directories
+options MSDOSFS #MSDOS Filesystem
+options CD9660 #ISO 9660 Filesystem
+options PROCFS #Process filesystem (requires PSEUDOFS)
+options PSEUDOFS #Pseudo-filesystem framework
+#options NANDFS #NAND Filesystem
+options TMPFS
+options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI
+options KTRACE
+options SYSVSHM #SYSV-style shared memory
+options SYSVMSG #SYSV-style message queues
+options SYSVSEM #SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+options KBD_INSTALL_CDEV
+options PREEMPTION
+options FREEBSD_BOOT_LOADER
+options VFP # vfp/neon
+
+# Debugging
+makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+options BREAK_TO_DEBUGGER
+#options VERBOSE_SYSINIT #Enable verbose sysinit messages
+options KDB
+options DDB #Enable the kernel debugger
+options INVARIANTS #Enable calls of extra sanity checking
+options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS #Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed
+options DIAGNOSTIC
+
+# NFS support
+options NFSCL #Network Filesystem Client
+options NFSLOCKD #Network Lock Manager
+options NFS_ROOT #NFS usable as /, requires NFSCLIENT
+
+# Uncomment this for NFS root
+#options NFS_ROOT #NFS usable as /, requires NFSCL
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ffec0
+
+device mmc # mmc/sd bus
+device mmcsd # mmc/sd flash cards
+device sdhci # generic sdhci
+
+#options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/cosmic\"
+#options ROOTDEVNAME=\"nandfs:/dev/gnand0s.root\"
+options ROOTDEVNAME=\"ufs:/dev/da0\"
+
+#options SMP
+
+# Pseudo devices
+
+device loop
+device random
+device pty
+device md
+device gpio
+
+# USB support
+device usb
+options USB_DEBUG
+#options USB_REQ_DEBUG
+#options USB_VERBOSE
+#device musb
+device ehci
+#device ohci
+
+device umass
+device scbus # SCSI bus (required for SCSI)
+device da # Direct Access (disks)
+device pass
+
+# SATA
+#device ata
+#device atadisk
+#device mvs
+
+device nand
+
+# Serial ports
+device uart
+
+# I2C (TWSI)
+#device iic
+#device iicbus
+
+# Ethernet
+device ether
+device ffec
+
+# USB ethernet support, requires miibus
+device miibus
+device axe # ASIX Electronics USB Ethernet
+device bpf # Berkeley packet filter
+
+#FDT
+options FDT
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=vybrid-cosmic.dts
diff --git a/sys/arm/conf/DIGI-CCWMX53 b/sys/arm/conf/DIGI-CCWMX53
index 5aec9fe..8a44844 100644
--- a/sys/arm/conf/DIGI-CCWMX53
+++ b/sys/arm/conf/DIGI-CCWMX53
@@ -65,7 +65,7 @@ options VFP # vfp/neon
#options BOOTP_COMPAT
#options BOOTP_NFSROOT
#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=ue0
+#options BOOTP_WIRED_TO=ffec0
#options ROOTDEVNAME=\"ufs:ada0s2a\"
@@ -105,8 +105,12 @@ device ether # Ethernet support
#device faith # IPv6-to-IPv4 relaying (translation)
#device firmware # firmware assist module
+# Ethernet
+device ffec # Freescale Fast Ethernet Controller
+device miibus # Standard mii bus
+
# Serial (COM) ports
-#device uart # Multi-uart driver
+device uart # Multi-uart driver
options ALT_BREAK_TO_DEBUGGER
device ata
@@ -130,13 +134,13 @@ device cd # CD
device pass # Passthrough device (direct SCSI access)
# USB support
-#options USB_DEBUG # enable debug msgs
-#device ehci # OHCI USB interface
-#device usb # USB Bus (required)
-#device umass # Disks/Mass storage - Requires scbus and da
-#device uhid # "Human Interface Devices"
+options USB_DEBUG # enable debug msgs
+device ehci # OHCI USB interface
+device usb # USB Bus (required)
+device umass # Disks/Mass storage - Requires scbus and da
+device uhid # "Human Interface Devices"
#device ukbd # Allow keyboard like HIDs to control console
-#device ums
+device ums
# USB Ethernet, requires miibus
#device miibus
diff --git a/sys/arm/conf/RADXA b/sys/arm/conf/RADXA
new file mode 100644
index 0000000..d62f155
--- /dev/null
+++ b/sys/arm/conf/RADXA
@@ -0,0 +1,119 @@
+# RADXA -- Custom configuration for the RADXA ARM development
+# platform, check out http://www.radxa.com
+#
+# For more information on this file, please read the handbook section on
+# Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
+
+ident RADXA
+
+include "../rockchip/std.rk30xx"
+
+makeoptions MODULES_OVERRIDE=""
+makeoptions WITHOUT_MODULES="ahc"
+
+options HZ=100
+options SCHED_4BSD #4BSD scheduler
+options INET #InterNETworking
+options INET6 #IPv6 communications protocols
+options FFS #Berkeley Fast Filesystem
+options SOFTUPDATES #Enable FFS soft updates support
+options UFS_ACL #Support for access control lists
+options UFS_DIRHASH #Improve performance on big directories
+options MSDOSFS #MSDOS Filesystem
+options CD9660 #ISO 9660 Filesystem
+options PROCFS #Process filesystem (requires PSEUDOFS)
+options PSEUDOFS #Pseudo-filesystem framework
+options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI
+options KTRACE #ktrace(1) support
+options SYSVSHM #SYSV-style shared memory
+options SYSVMSG #SYSV-style message queues
+options SYSVSEM #SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options PREEMPTION
+options FREEBSD_BOOT_LOADER
+options VFP # vfp/neon
+
+# Debugging
+makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+options BREAK_TO_DEBUGGER
+#options VERBOSE_SYSINIT #Enable verbose sysinit messages
+options KDB
+options DDB #Enable the kernel debugger
+#options INVARIANTS #Enable calls of extra sanity checking
+#options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS
+options WITNESS #Enable checks to detect deadlocks and cycles
+options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed
+options DIAGNOSTIC
+
+# NFS support
+#options NFSCL
+#options NFSSERVER #Network Filesystem Server
+#options NFSCLIENT #Network Filesystem Client
+
+# MMC/SD/SDIO card slot support
+#device mmc # mmc/sd bus
+#device mmcsd # mmc/sd flash cards
+
+# Boot device is 2nd slice on MMC/SD card
+options ROOTDEVNAME=\"ufs:/dev/da0s2\"
+
+# Console and misc
+device uart
+device uart_ns8250
+device pty
+device snp
+device md
+device random # Entropy device
+
+# I2C support
+#device iicbus
+#device iic
+
+# GPIO
+device gpio
+
+device scbus # SCSI bus (required for SCSI)
+device da # Direct Access (disks)
+device pass
+
+# USB support
+device usb
+options USB_DEBUG
+#options USB_REQ_DEBUG
+#options USB_VERBOSE
+device dwcotg #DWC OTG controller
+
+device umass
+
+# Ethernet
+device loop
+device ether
+device mii
+device smscphy
+device bpf
+
+# USB ethernet support, requires miibus
+device miibus
+device udav
+
+# Flattened Device Tree
+options FDT
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=rk3188-radxa.dts
+
diff --git a/sys/arm/freescale/vybrid/files.vybrid b/sys/arm/freescale/vybrid/files.vybrid
new file mode 100644
index 0000000..4f700d0
--- /dev/null
+++ b/sys/arm/freescale/vybrid/files.vybrid
@@ -0,0 +1,28 @@
+# $FreeBSD$
+
+kern/kern_clocksource.c standard
+
+arm/arm/bus_space_generic.c standard
+arm/arm/bus_space_asm_generic.S standard
+arm/arm/cpufunc_asm_armv5.S standard
+arm/arm/cpufunc_asm_arm10.S standard
+arm/arm/cpufunc_asm_arm11.S standard
+arm/arm/cpufunc_asm_armv7.S standard
+arm/arm/irq_dispatch.S standard
+
+arm/arm/bus_space-v6.c standard
+arm/arm/gic.c standard
+arm/arm/mpcore_timer.c standard
+
+arm/freescale/vybrid/vf_machdep.c standard
+arm/freescale/vybrid/vf_common.c standard
+arm/freescale/vybrid/vf_ccm.c standard
+arm/freescale/vybrid/vf_anadig.c standard
+arm/freescale/vybrid/vf_iomuxc.c standard
+arm/freescale/vybrid/vf_mscm.c standard
+arm/freescale/vybrid/vf_src.c standard
+arm/freescale/vybrid/vf_nfc.c optional nand
+arm/freescale/vybrid/vf_ehci.c optional ehci
+arm/freescale/vybrid/vf_gpio.c optional gpio
+arm/freescale/vybrid/vf_uart.c optional uart
+dev/ffec/if_ffec.c optional ffec
diff --git a/sys/arm/freescale/vybrid/std.vybrid b/sys/arm/freescale/vybrid/std.vybrid
new file mode 100644
index 0000000..92d5a46
--- /dev/null
+++ b/sys/arm/freescale/vybrid/std.vybrid
@@ -0,0 +1,20 @@
+# $FreeBSD$
+
+makeoption ARM_LITTLE_ENDIAN
+
+cpu CPU_CORTEXA
+machine arm armv6
+
+options PHYSADDR=0x80000000
+
+makeoptions KERNPHYSADDR=0x80100000
+options KERNPHYSADDR=0x80100000
+
+makeoptions KERNVIRTADDR=0xc0100000
+options KERNVIRTADDR=0xc0100000
+
+options STARTUP_PAGETABLE_ADDR=0x81000000
+
+options ARM_L2_PIPT
+
+files "../freescale/vybrid/files.vybrid"
diff --git a/sys/arm/freescale/vybrid/vf_anadig.c b/sys/arm/freescale/vybrid/vf_anadig.c
new file mode 100644
index 0000000..afa860d
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_anadig.c
@@ -0,0 +1,214 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family Analog components control digital interface (ANADIG)
+ * Chapter 11, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define ANADIG_PLL3_CTRL 0x010 /* PLL3 Control */
+#define ANADIG_PLL7_CTRL 0x020 /* PLL7 Control */
+#define ANADIG_PLL2_CTRL 0x030 /* PLL2 Control */
+#define ANADIG_PLL2_SS 0x040 /* PLL2 Spread Spectrum */
+#define ANADIG_PLL2_NUM 0x050 /* PLL2 Numerator */
+#define ANADIG_PLL2_DENOM 0x060 /* PLL2 Denominator */
+#define ANADIG_PLL4_CTRL 0x070 /* PLL4 Control */
+#define ANADIG_PLL4_NUM 0x080 /* PLL4 Numerator */
+#define ANADIG_PLL4_DENOM 0x090 /* PLL4 Denominator */
+#define ANADIG_PLL6_CTRL 0x0A0 /* PLL6 Control */
+#define ANADIG_PLL6_NUM 0x0B0 /* PLL6 Numerator */
+#define ANADIG_PLL6_DENOM 0x0C0 /* PLL6 Denominator */
+#define ANADIG_PLL5_CTRL 0x0E0 /* PLL5 Control */
+#define ANADIG_PLL3_PFD 0x0F0 /* PLL3 PFD */
+#define ANADIG_PLL2_PFD 0x100 /* PLL2 PFD */
+#define ANADIG_REG_1P1 0x110 /* Regulator 1P1 */
+#define ANADIG_REG_3P0 0x120 /* Regulator 3P0 */
+#define ANADIG_REG_2P5 0x130 /* Regulator 2P5 */
+#define ANADIG_ANA_MISC0 0x150 /* Analog Miscellaneous */
+#define ANADIG_ANA_MISC1 0x160 /* Analog Miscellaneous */
+#define ANADIG_ANADIG_DIGPROG 0x260 /* Digital Program */
+#define ANADIG_PLL1_CTRL 0x270 /* PLL1 Control */
+#define ANADIG_PLL1_SS 0x280 /* PLL1 Spread Spectrum */
+#define ANADIG_PLL1_NUM 0x290 /* PLL1 Numerator */
+#define ANADIG_PLL1_DENOM 0x2A0 /* PLL1 Denominator */
+#define ANADIG_PLL1_PFD 0x2B0 /* PLL1_PFD */
+#define ANADIG_PLL_LOCK 0x2C0 /* PLL Lock */
+
+#define USB_VBUS_DETECT(n) (0x1A0 + 0x60 * n)
+#define USB_CHRG_DETECT(n) (0x1B0 + 0x60 * n)
+#define USB_VBUS_DETECT_STATUS(n) (0x1C0 + 0x60 * n)
+#define USB_CHRG_DETECT_STATUS(n) (0x1D0 + 0x60 * n)
+#define USB_LOOPBACK(n) (0x1E0 + 0x60 * n)
+#define USB_MISC(n) (0x1F0 + 0x60 * n)
+
+#define ANADIG_PLL_LOCKED (1 << 31)
+#define ENABLE_LINREG (1 << 0)
+#define EN_CLK_TO_UTMI (1 << 30)
+
+#define CTRL_BYPASS (1 << 16)
+#define CTRL_PWR (1 << 12)
+#define CTRL_PLL_EN (1 << 13)
+#define EN_USB_CLKS (1 << 6)
+
+struct anadig_softc {
+ struct resource *res[1];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+};
+
+static struct resource_spec anadig_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+anadig_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,mvf600-anadig"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family ANADIG Unit");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+enable_pll(struct anadig_softc *sc, int pll_ctrl)
+{
+ int reg;
+
+ reg = READ4(sc, pll_ctrl);
+ reg &= ~(CTRL_BYPASS | CTRL_PWR);
+ if (pll_ctrl == ANADIG_PLL3_CTRL || pll_ctrl == ANADIG_PLL7_CTRL) {
+ /* It is USB PLL. Power bit logic is reversed */
+ reg |= (CTRL_PWR | EN_USB_CLKS);
+ }
+ WRITE4(sc, pll_ctrl, reg);
+
+ /* Wait for PLL lock */
+ while (!(READ4(sc, pll_ctrl) & ANADIG_PLL_LOCKED))
+ ;
+
+ reg = READ4(sc, pll_ctrl);
+ reg |= (CTRL_PLL_EN);
+ WRITE4(sc, pll_ctrl, reg);
+
+ return (0);
+}
+
+static int
+anadig_attach(device_t dev)
+{
+ struct anadig_softc *sc;
+ int reg;
+
+ sc = device_get_softc(dev);
+
+ if (bus_alloc_resources(dev, anadig_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]);
+
+ /* Enable USB PLLs */
+ enable_pll(sc, ANADIG_PLL3_CTRL);
+ enable_pll(sc, ANADIG_PLL7_CTRL);
+
+ /* Enable other */
+ enable_pll(sc, ANADIG_PLL1_CTRL);
+ enable_pll(sc, ANADIG_PLL2_CTRL);
+ enable_pll(sc, ANADIG_PLL4_CTRL);
+ enable_pll(sc, ANADIG_PLL5_CTRL);
+ enable_pll(sc, ANADIG_PLL6_CTRL);
+
+ /* Enable USB voltage regulator */
+ reg = READ4(sc, ANADIG_REG_3P0);
+ reg |= (ENABLE_LINREG);
+ WRITE4(sc, ANADIG_REG_3P0, reg);
+
+ /* Give clocks to USB */
+ reg = READ4(sc, USB_MISC(0));
+ reg |= (EN_CLK_TO_UTMI);
+ WRITE4(sc, USB_MISC(0), reg);
+
+ reg = READ4(sc, USB_MISC(1));
+ reg |= (EN_CLK_TO_UTMI);
+ WRITE4(sc, USB_MISC(1), reg);
+
+#if 0
+ printf("USB_ANALOG_USB_MISC(0) == 0x%08x\n",
+ READ4(sc, USB_ANALOG_USB_MISC(0)));
+ printf("USB_ANALOG_USB_MISC(1) == 0x%08x\n",
+ READ4(sc, USB_ANALOG_USB_MISC(1)));
+#endif
+
+ return (0);
+}
+
+static device_method_t anadig_methods[] = {
+ DEVMETHOD(device_probe, anadig_probe),
+ DEVMETHOD(device_attach, anadig_attach),
+ { 0, 0 }
+};
+
+static driver_t anadig_driver = {
+ "anadig",
+ anadig_methods,
+ sizeof(struct anadig_softc),
+};
+
+static devclass_t anadig_devclass;
+
+DRIVER_MODULE(anadig, simplebus, anadig_driver, anadig_devclass, 0, 0);
diff --git a/sys/arm/freescale/vybrid/vf_ccm.c b/sys/arm/freescale/vybrid/vf_ccm.c
new file mode 100644
index 0000000..1410faa
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_ccm.c
@@ -0,0 +1,188 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family Clock Controller Module (CCM)
+ * Chapter 10, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define CCM_CCR 0x00 /* Control Register */
+#define CCM_CSR 0x04 /* Status Register */
+#define CCM_CCSR 0x08 /* Clock Switcher Register */
+#define CCM_CACRR 0x0C /* ARM Clock Root Register */
+#define CCM_CSCMR1 0x10 /* Serial Clock Multiplexer Register 1 */
+#define CCM_CSCDR1 0x14 /* Serial Clock Divider Register 1 */
+#define CCM_CSCDR2 0x18 /* Serial Clock Divider Register 2 */
+#define CCM_CSCDR3 0x1C /* Serial Clock Divider Register 3 */
+#define CCM_CSCMR2 0x20 /* Serial Clock Multiplexer Register 2 */
+#define CCM_CTOR 0x28 /* Testing Observability Register */
+#define CCM_CLPCR 0x2C /* Low Power Control Register */
+#define CCM_CISR 0x30 /* Interrupt Status Register */
+#define CCM_CIMR 0x34 /* Interrupt Mask Register */
+#define CCM_CCOSR 0x38 /* Clock Output Source Register */
+#define CCM_CGPR 0x3C /* General Purpose Register */
+
+#define CCM_CCGRN 12
+#define CCM_CCGR(n) (0x40 + (n * 0x04)) /* Clock Gating Register */
+#define CCM_CMEOR(n) (0x70 + (n * 0x70)) /* Module Enable Override Reg */
+#define CCM_CCPGR(n) (0x90 + (n * 0x04)) /* Platform Clock Gating Reg */
+
+#define CCM_CPPDSR 0x88 /* PLL PFD Disable Status Register */
+#define CCM_CCOWR 0x8C /* CORE Wakeup Register */
+
+#define PLL3_PFD4_EN (1 << 31)
+#define PLL3_PFD3_EN (1 << 30)
+#define PLL3_PFD2_EN (1 << 29)
+#define PLL3_PFD1_EN (1 << 28)
+#define PLL2_PFD4_EN (1 << 15)
+#define PLL2_PFD3_EN (1 << 14)
+#define PLL2_PFD2_EN (1 << 13)
+#define PLL2_PFD1_EN (1 << 12)
+#define PLL1_PFD4_EN (1 << 11)
+#define PLL1_PFD3_EN (1 << 10)
+#define PLL1_PFD2_EN (1 << 9)
+#define PLL1_PFD1_EN (1 << 8)
+
+/* CCM_CCR */
+#define FIRC_EN (1 << 16)
+#define FXOSC_EN (1 << 12)
+#define FXOSC_RDY (1 << 5)
+
+/* CCM_CSCDR1 */
+#define ENET_TS_EN (1 << 23)
+#define RMII_CLK_EN (1 << 24)
+
+struct ccm_softc {
+ struct resource *res[1];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ device_t dev;
+};
+
+static struct resource_spec ccm_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+ccm_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,mvf600-ccm"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family CCM Unit");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ccm_attach(device_t dev)
+{
+ struct ccm_softc *sc;
+ int reg;
+ int i;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, ccm_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]);
+
+ /* Enable oscillator */
+ reg = READ4(sc, CCM_CCR);
+ reg |= (FIRC_EN | FXOSC_EN);
+ WRITE4(sc, CCM_CCR, reg);
+
+ /* Wait 10 times */
+ for (i = 0; i < 10; i++) {
+ if (READ4(sc, CCM_CSR) & FXOSC_RDY) {
+ device_printf(sc->dev, "On board oscillator is ready.\n");
+ break;
+ }
+
+ cpufunc_nullop();
+ }
+
+ /* Clock is on during all modes, except stop mode. */
+ for (i = 0; i < CCM_CCGRN; i++) {
+ WRITE4(sc, CCM_CCGR(i), 0xffffffff);
+ }
+
+ /* Enable ENET clocks */
+ reg = READ4(sc, CCM_CSCDR1);
+ reg |= (ENET_TS_EN | RMII_CLK_EN);
+ WRITE4(sc, CCM_CSCDR1, reg);
+
+ return (0);
+}
+
+static device_method_t ccm_methods[] = {
+ DEVMETHOD(device_probe, ccm_probe),
+ DEVMETHOD(device_attach, ccm_attach),
+ { 0, 0 }
+};
+
+static driver_t ccm_driver = {
+ "ccm",
+ ccm_methods,
+ sizeof(struct ccm_softc),
+};
+
+static devclass_t ccm_devclass;
+
+DRIVER_MODULE(ccm, simplebus, ccm_driver, ccm_devclass, 0, 0);
diff --git a/sys/arm/freescale/vybrid/vf_common.c b/sys/arm/freescale/vybrid/vf_common.c
new file mode 100644
index 0000000..ffec9a3
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_common.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/freescale/vybrid/vf_src.h>
+
+void
+cpu_reset(void)
+{
+ phandle_t src;
+ uint32_t addr, paddr;
+ bus_addr_t vaddr;
+
+ if (src_swreset() == 0)
+ goto end;
+
+ src = OF_finddevice("src");
+ if ((src != 0) && (OF_getprop(src, "reg", &paddr, sizeof(paddr))) > 0) {
+ addr = fdt32_to_cpu(paddr);
+ if (bus_space_map(fdtbus_bs_tag, addr, 0x10, 0, &vaddr) == 0) {
+ bus_space_write_4(fdtbus_bs_tag, vaddr, 0x00, SW_RST);
+ }
+ }
+
+end:
+ while (1);
+}
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+ { NULL, NULL }
+};
+
+static int
+fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+ int *pol)
+{
+
+ if (!fdt_is_compatible(node, "arm,gic"))
+ return (ENXIO);
+
+ *interrupt = fdt32_to_cpu(intr[0]);
+ *trig = INTR_TRIGGER_CONFORM;
+ *pol = INTR_POLARITY_CONFORM;
+ return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+ &fdt_pic_decode_ic,
+ NULL
+};
diff --git a/sys/arm/freescale/vybrid/vf_common.h b/sys/arm/freescale/vybrid/vf_common.h
new file mode 100644
index 0000000..d11f000
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_common.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 READ4(_sc, _reg) \
+ bus_space_read_4(_sc->bst, _sc->bsh, _reg)
+#define WRITE4(_sc, _reg, _val) \
+ bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
+#define READ2(_sc, _reg) \
+ bus_space_read_2(_sc->bst, _sc->bsh, _reg)
+#define WRITE2(_sc, _reg, _val) \
+ bus_space_write_2(_sc->bst, _sc->bsh, _reg, _val)
+#define READ1(_sc, _reg) \
+ bus_space_read_1(_sc->bst, _sc->bsh, _reg)
+#define WRITE1(_sc, _reg, _val) \
+ bus_space_write_1(_sc->bst, _sc->bsh, _reg, _val)
diff --git a/sys/arm/freescale/vybrid/vf_ehci.c b/sys/arm/freescale/vybrid/vf_ehci.c
new file mode 100644
index 0000000..76edb85
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_ehci.c
@@ -0,0 +1,416 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family Universal Serial Bus (USB) Controller
+ * Chapter 44-45, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/condvar.h>
+#include <sys/rman.h>
+#include <sys/gpio.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include "gpio_if.h"
+#include "opt_platform.h"
+
+#define ENUTMILEVEL3 (1 << 15)
+#define ENUTMILEVEL2 (1 << 14)
+
+#define GPIO_USB_PWR 134
+
+#define USB_ID 0x000 /* Identification register */
+#define USB_HWGENERAL 0x004 /* Hardware General */
+#define USB_HWHOST 0x008 /* Host Hardware Parameters */
+#define USB_HWDEVICE 0x00C /* Device Hardware Parameters */
+#define USB_HWTXBUF 0x010 /* TX Buffer Hardware Parameters */
+#define USB_HWRXBUF 0x014 /* RX Buffer Hardware Parameters */
+#define USB_HCSPARAMS 0x104 /* Host Controller Structural Parameters */
+
+#define USBPHY_PWD 0x00 /* PHY Power-Down Register */
+#define USBPHY_PWD_SET 0x04 /* PHY Power-Down Register */
+#define USBPHY_PWD_CLR 0x08 /* PHY Power-Down Register */
+#define USBPHY_PWD_TOG 0x0C /* PHY Power-Down Register */
+#define USBPHY_TX 0x10 /* PHY Transmitter Control Register */
+#define USBPHY_RX 0x20 /* PHY Receiver Control Register */
+#define USBPHY_RX_SET 0x24 /* PHY Receiver Control Register */
+#define USBPHY_RX_CLR 0x28 /* PHY Receiver Control Register */
+#define USBPHY_RX_TOG 0x2C /* PHY Receiver Control Register */
+#define USBPHY_CTRL 0x30 /* PHY General Control Register */
+#define USBPHY_CTRL_SET 0x34 /* PHY General Control Register */
+#define USBPHY_CTRL_CLR 0x38 /* PHY General Control Register */
+#define USBPHY_CTRL_TOG 0x3C /* PHY General Control Register */
+#define USBPHY_STATUS 0x40 /* PHY Status Register */
+#define USBPHY_DEBUG 0x50 /* PHY Debug Register */
+#define USBPHY_DEBUG_SET 0x54 /* PHY Debug Register */
+#define USBPHY_DEBUG_CLR 0x58 /* PHY Debug Register */
+#define USBPHY_DEBUG_TOG 0x5C /* PHY Debug Register */
+#define USBPHY_DEBUG0_STATUS 0x60 /* UTMI Debug Status Register 0 */
+#define USBPHY_DEBUG1 0x70 /* UTMI Debug Status Register 1 */
+#define USBPHY_DEBUG1_SET 0x74 /* UTMI Debug Status Register 1 */
+#define USBPHY_DEBUG1_CLR 0x78 /* UTMI Debug Status Register 1 */
+#define USBPHY_DEBUG1_TOG 0x7C /* UTMI Debug Status Register 1 */
+#define USBPHY_VERSION 0x80 /* UTMI RTL Version */
+#define USBPHY_IP 0x90 /* PHY IP Block Register */
+#define USBPHY_IP_SET 0x94 /* PHY IP Block Register */
+#define USBPHY_IP_CLR 0x98 /* PHY IP Block Register */
+#define USBPHY_IP_TOG 0x9C /* PHY IP Block Register */
+
+#define USBPHY_CTRL_SFTRST (1 << 31)
+#define USBPHY_CTRL_CLKGATE (1 << 30)
+#define USBPHY_DEBUG_CLKGATE (1 << 30)
+
+#define PHY_READ4(_sc, _reg) \
+ bus_space_read_4(_sc->bst_phy, _sc->bsh_phy, _reg)
+#define PHY_WRITE4(_sc, _reg, _val) \
+ bus_space_write_4(_sc->bst_phy, _sc->bsh_phy, _reg, _val)
+
+#define USBC_READ4(_sc, _reg) \
+ bus_space_read_4(_sc->bst_usbc, _sc->bsh_usbc, _reg)
+#define USBC_WRITE4(_sc, _reg, _val) \
+ bus_space_write_4(_sc->bst_usbc, _sc->bsh_usbc, _reg, _val)
+
+/* Forward declarations */
+static int vybrid_ehci_attach(device_t dev);
+static int vybrid_ehci_detach(device_t dev);
+static int vybrid_ehci_probe(device_t dev);
+
+struct vybrid_ehci_softc {
+ ehci_softc_t base;
+ device_t dev;
+ struct resource *res[6];
+ bus_space_tag_t bst_phy;
+ bus_space_handle_t bsh_phy;
+ bus_space_tag_t bst_usbc;
+ bus_space_handle_t bsh_usbc;
+};
+
+static struct resource_spec vybrid_ehci_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_MEMORY, 1, RF_ACTIVE },
+ { SYS_RES_MEMORY, 2, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static device_method_t ehci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, vybrid_ehci_probe),
+ DEVMETHOD(device_attach, vybrid_ehci_attach),
+ DEVMETHOD(device_detach, vybrid_ehci_detach),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+ { 0, 0 }
+};
+
+/* kobj_class definition */
+static driver_t ehci_driver = {
+ "ehci",
+ ehci_methods,
+ sizeof(ehci_softc_t)
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
+MODULE_DEPEND(ehci, usb, 1, 1, 1);
+
+/*
+ * Public methods
+ */
+static int
+vybrid_ehci_probe(device_t dev)
+{
+
+ if (ofw_bus_is_compatible(dev, "fsl,mvf600-usb-ehci") == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family integrated USB controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+phy_init(struct vybrid_ehci_softc *esc)
+{
+ device_t sc_gpio_dev;
+ int reg;
+
+ /* Reset phy */
+ reg = PHY_READ4(esc, USBPHY_CTRL);
+ reg |= (USBPHY_CTRL_SFTRST);
+ PHY_WRITE4(esc, USBPHY_CTRL, reg);
+
+ /* Minimum reset time */
+ DELAY(10000);
+
+ reg &= ~(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE);
+ PHY_WRITE4(esc, USBPHY_CTRL, reg);
+
+ reg = (ENUTMILEVEL2 | ENUTMILEVEL3);
+ PHY_WRITE4(esc, USBPHY_CTRL_SET, reg);
+
+ /* Get the GPIO device, we need this to give power to USB */
+ sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+ if (sc_gpio_dev == NULL) {
+ device_printf(esc->dev, "Error: failed to get the GPIO dev\n");
+ return (1);
+ }
+
+ /* Give power to USB */
+ GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB_PWR, GPIO_PIN_OUTPUT);
+ GPIO_PIN_SET(sc_gpio_dev, GPIO_USB_PWR, GPIO_PIN_HIGH);
+
+ /* Power up PHY */
+ PHY_WRITE4(esc, USBPHY_PWD, 0x00);
+
+ /* Ungate clocks */
+ reg = PHY_READ4(esc, USBPHY_DEBUG);
+ reg &= ~(USBPHY_DEBUG_CLKGATE);
+ PHY_WRITE4(esc, USBPHY_DEBUG, reg);
+
+#if 0
+ printf("USBPHY_CTRL == 0x%08x\n",
+ PHY_READ4(esc, USBPHY_CTRL));
+ printf("USBPHY_IP == 0x%08x\n",
+ PHY_READ4(esc, USBPHY_IP));
+ printf("USBPHY_STATUS == 0x%08x\n",
+ PHY_READ4(esc, USBPHY_STATUS));
+ printf("USBPHY_DEBUG == 0x%08x\n",
+ PHY_READ4(esc, USBPHY_DEBUG));
+ printf("USBPHY_DEBUG0_STATUS == 0x%08x\n",
+ PHY_READ4(esc, USBPHY_DEBUG0_STATUS));
+ printf("USBPHY_DEBUG1 == 0x%08x\n",
+ PHY_READ4(esc, USBPHY_DEBUG1));
+#endif
+
+ return (0);
+}
+
+static int
+vybrid_ehci_attach(device_t dev)
+{
+ struct vybrid_ehci_softc *esc;
+ ehci_softc_t *sc;
+ bus_space_handle_t bsh;
+ int err;
+ int reg;
+
+ esc = device_get_softc(dev);
+ esc->dev = dev;
+
+ sc = &esc->base;
+ sc->sc_bus.parent = dev;
+ sc->sc_bus.devices = sc->sc_devices;
+ sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+
+ if (bus_alloc_resources(dev, vybrid_ehci_spec, esc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ /* EHCI registers */
+ sc->sc_io_tag = rman_get_bustag(esc->res[0]);
+ bsh = rman_get_bushandle(esc->res[0]);
+ sc->sc_io_size = rman_get_size(esc->res[0]);
+
+ esc->bst_usbc = rman_get_bustag(esc->res[1]);
+ esc->bsh_usbc = rman_get_bushandle(esc->res[1]);
+
+ esc->bst_phy = rman_get_bustag(esc->res[2]);
+ esc->bsh_phy = rman_get_bushandle(esc->res[2]);
+
+ /* get all DMA memory */
+ if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
+ &ehci_iterate_hw_softc))
+ return (ENXIO);
+
+#if 0
+ printf("USBx_HCSPARAMS is 0x%08x\n",
+ bus_space_read_4(sc->sc_io_tag, bsh, USB_HCSPARAMS));
+ printf("USB_ID == 0x%08x\n",
+ bus_space_read_4(sc->sc_io_tag, bsh, USB_ID));
+ printf("USB_HWGENERAL == 0x%08x\n",
+ bus_space_read_4(sc->sc_io_tag, bsh, USB_HWGENERAL));
+ printf("USB_HWHOST == 0x%08x\n",
+ bus_space_read_4(sc->sc_io_tag, bsh, USB_HWHOST));
+ printf("USB_HWDEVICE == 0x%08x\n",
+ bus_space_read_4(sc->sc_io_tag, bsh, USB_HWDEVICE));
+ printf("USB_HWTXBUF == 0x%08x\n",
+ bus_space_read_4(sc->sc_io_tag, bsh, USB_HWTXBUF));
+ printf("USB_HWRXBUF == 0x%08x\n",
+ bus_space_read_4(sc->sc_io_tag, bsh, USB_HWRXBUF));
+#endif
+
+ if (phy_init(esc)) {
+ device_printf(dev, "Could not setup PHY\n");
+ return (1);
+ }
+
+ /*
+ * Set handle to USB related registers subregion used by
+ * generic EHCI driver.
+ */
+ err = bus_space_subregion(sc->sc_io_tag, bsh, 0x100,
+ sc->sc_io_size, &sc->sc_io_hdl);
+ if (err != 0)
+ return (ENXIO);
+
+ /* Setup interrupt handler */
+ err = bus_setup_intr(dev, esc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
+ NULL, (driver_intr_t *)ehci_interrupt, sc,
+ &sc->sc_intr_hdl);
+ if (err) {
+ device_printf(dev, "Could not setup irq, "
+ "%d\n", err);
+ return (1);
+ }
+
+ /* Add USB device */
+ sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+ if (!sc->sc_bus.bdev) {
+ device_printf(dev, "Could not add USB device\n");
+ err = bus_teardown_intr(dev, esc->res[5],
+ sc->sc_intr_hdl);
+ if (err)
+ device_printf(dev, "Could not tear down irq,"
+ " %d\n", err);
+ return (1);
+ }
+ device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+ strlcpy(sc->sc_vendor, "Freescale", sizeof(sc->sc_vendor));
+
+ /* Set host mode */
+ reg = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8);
+ reg |= 0x3;
+ bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8, reg);
+
+ /* Set flags */
+ sc->sc_flags |= EHCI_SCFLG_SETMODE | EHCI_SCFLG_NORESTERM;
+
+ err = ehci_init(sc);
+ if (!err) {
+ sc->sc_flags |= EHCI_SCFLG_DONEINIT;
+ err = device_probe_and_attach(sc->sc_bus.bdev);
+ } else {
+ device_printf(dev, "USB init failed err=%d\n", err);
+
+ device_delete_child(dev, sc->sc_bus.bdev);
+ sc->sc_bus.bdev = NULL;
+
+ err = bus_teardown_intr(dev, esc->res[5],
+ sc->sc_intr_hdl);
+ if (err)
+ device_printf(dev, "Could not tear down irq,"
+ " %d\n", err);
+ return (1);
+ }
+ return (0);
+}
+
+static int
+vybrid_ehci_detach(device_t dev)
+{
+ struct vybrid_ehci_softc *esc;
+ ehci_softc_t *sc;
+ int err;
+
+ esc = device_get_softc(dev);
+ sc = &esc->base;
+
+ if (sc->sc_flags & EHCI_SCFLG_DONEINIT)
+ return (0);
+
+ /*
+ * only call ehci_detach() after ehci_init()
+ */
+ if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
+ ehci_detach(sc);
+ sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+ }
+
+ /*
+ * Disable interrupts that might have been switched on in
+ * ehci_init.
+ */
+ if (sc->sc_io_tag && sc->sc_io_hdl)
+ bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl,
+ EHCI_USBINTR, 0);
+
+ if (esc->res[5] && sc->sc_intr_hdl) {
+ err = bus_teardown_intr(dev, esc->res[5],
+ sc->sc_intr_hdl);
+ if (err) {
+ device_printf(dev, "Could not tear down irq,"
+ " %d\n", err);
+ return (err);
+ }
+ sc->sc_intr_hdl = NULL;
+ }
+
+ if (sc->sc_bus.bdev) {
+ device_delete_child(dev, sc->sc_bus.bdev);
+ sc->sc_bus.bdev = NULL;
+ }
+
+ /* During module unload there are lots of children leftover */
+ device_delete_children(dev);
+
+ bus_release_resources(dev, vybrid_ehci_spec, esc->res);
+
+ return (0);
+}
diff --git a/sys/arm/freescale/vybrid/vf_gpio.c b/sys/arm/freescale/vybrid/vf_gpio.c
new file mode 100644
index 0000000..8a7b9b1
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_gpio.c
@@ -0,0 +1,403 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family General-Purpose Input/Output (GPIO)
+ * Chapter 7, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include "gpio_if.h"
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define GPIO_PDOR(n) (0x00 + 0x40 * (n >> 5))
+#define GPIO_PSOR(n) (0x04 + 0x40 * (n >> 5))
+#define GPIO_PCOR(n) (0x08 + 0x40 * (n >> 5))
+#define GPIO_PTOR(n) (0x0C + 0x40 * (n >> 5))
+#define GPIO_PDIR(n) (0x10 + 0x40 * (n >> 5))
+
+#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
+#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
+
+#define NPORTS 5
+#define NGPIO (NPORTS * 32)
+#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
+
+/*
+ * GPIO interface
+ */
+static int vf_gpio_pin_max(device_t, int *);
+static int vf_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
+static int vf_gpio_pin_getname(device_t, uint32_t, char *);
+static int vf_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
+static int vf_gpio_pin_setflags(device_t, uint32_t, uint32_t);
+static int vf_gpio_pin_set(device_t, uint32_t, unsigned int);
+static int vf_gpio_pin_get(device_t, uint32_t, unsigned int *);
+static int vf_gpio_pin_toggle(device_t, uint32_t pin);
+
+struct vf_gpio_softc {
+ struct resource *res[6];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
+ struct mtx sc_mtx;
+ int gpio_npins;
+ struct gpio_pin gpio_pins[NGPIO];
+ void *gpio_ih[NPORTS];
+};
+
+struct vf_gpio_softc *gpio_sc;
+
+static struct resource_spec vf_gpio_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 1, RF_ACTIVE },
+ { SYS_RES_IRQ, 2, RF_ACTIVE },
+ { SYS_RES_IRQ, 3, RF_ACTIVE },
+ { SYS_RES_IRQ, 4, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+vf_gpio_intr(void *arg)
+{
+ struct vf_gpio_softc *sc;
+ sc = arg;
+
+ /* TODO: interrupt handling */
+
+ return (FILTER_HANDLED);
+}
+
+
+static int
+vf_gpio_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,mvf600-gpio"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family GPIO Unit");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+vf_gpio_attach(device_t dev)
+{
+ struct vf_gpio_softc *sc;
+ int irq, i;
+
+ sc = device_get_softc(dev);
+ mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+ if (bus_alloc_resources(dev, vf_gpio_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ gpio_sc = sc;
+
+ /* Memory interface */
+ sc->bst = rman_get_bustag(sc->res[0]);
+ sc->bsh = rman_get_bushandle(sc->res[0]);
+
+ sc->gpio_npins = NGPIO;
+
+ for (irq = 0; irq < NPORTS; irq ++) {
+ if ((bus_setup_intr(dev, sc->res[1 + irq], INTR_TYPE_MISC,
+ vf_gpio_intr, NULL, sc, &sc->gpio_ih[irq]))) {
+ device_printf(dev,
+ "WARNING: unable to register interrupt handler\n");
+ return (ENXIO);
+ }
+ }
+
+ for (i = 0; i < sc->gpio_npins; i++) {
+ sc->gpio_pins[i].gp_pin = i;
+ sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
+ sc->gpio_pins[i].gp_flags =
+ (READ4(sc, GPIO_PDOR(i)) & (1 << (i % 32))) ?
+ GPIO_PIN_OUTPUT: GPIO_PIN_INPUT;
+ snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
+ "vf_gpio%d.%d", device_get_unit(dev), i);
+ }
+
+ device_add_child(dev, "gpioc", device_get_unit(dev));
+ device_add_child(dev, "gpiobus", device_get_unit(dev));
+
+ return (bus_generic_attach(dev));
+}
+
+static int
+vf_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+ *maxpin = NGPIO - 1;
+ return (0);
+}
+
+static int
+vf_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+ struct vf_gpio_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < sc->gpio_npins; i++) {
+ if (sc->gpio_pins[i].gp_pin == pin)
+ break;
+ }
+
+ if (i >= sc->gpio_npins)
+ return (EINVAL);
+
+ GPIO_LOCK(sc);
+ memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME);
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+vf_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+ struct vf_gpio_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < sc->gpio_npins; i++) {
+ if (sc->gpio_pins[i].gp_pin == pin)
+ break;
+ }
+
+ if (i >= sc->gpio_npins)
+ return (EINVAL);
+
+ GPIO_LOCK(sc);
+ *caps = sc->gpio_pins[i].gp_caps;
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+vf_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+ struct vf_gpio_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < sc->gpio_npins; i++) {
+ if (sc->gpio_pins[i].gp_pin == pin)
+ break;
+ }
+
+ if (i >= sc->gpio_npins)
+ return (EINVAL);
+
+ GPIO_LOCK(sc);
+ *flags = sc->gpio_pins[i].gp_flags;
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+vf_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+ struct vf_gpio_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < sc->gpio_npins; i++) {
+ if (sc->gpio_pins[i].gp_pin == pin)
+ break;
+ }
+
+ if (i >= sc->gpio_npins)
+ return (EINVAL);
+
+ GPIO_LOCK(sc);
+ *val = (READ4(sc, GPIO_PDOR(i)) & (1 << (i % 32)));
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+vf_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+ struct vf_gpio_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < sc->gpio_npins; i++) {
+ if (sc->gpio_pins[i].gp_pin == pin)
+ break;
+ }
+
+ if (i >= sc->gpio_npins)
+ return (EINVAL);
+
+ GPIO_LOCK(sc);
+ WRITE4(sc, GPIO_PTOR(i), (1 << (i % 32)));
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+
+static void
+vf_gpio_pin_configure(struct vf_gpio_softc *sc, struct gpio_pin *pin,
+ unsigned int flags)
+{
+
+ GPIO_LOCK(sc);
+
+ /*
+ * Manage input/output
+ */
+ if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+ pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+ if (flags & GPIO_PIN_OUTPUT) {
+ pin->gp_flags |= GPIO_PIN_OUTPUT;
+
+ } else {
+ pin->gp_flags |= GPIO_PIN_INPUT;
+ WRITE4(sc, GPIO_PCOR(pin->gp_pin),
+ (1 << (pin->gp_pin % 32)));
+ }
+ }
+
+ GPIO_UNLOCK(sc);
+}
+
+
+static int
+vf_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+ struct vf_gpio_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < sc->gpio_npins; i++) {
+ if (sc->gpio_pins[i].gp_pin == pin)
+ break;
+ }
+
+ if (i >= sc->gpio_npins)
+ return (EINVAL);
+
+ /* Check for unwanted flags. */
+ if ((flags & sc->gpio_pins[i].gp_caps) != flags)
+ return (EINVAL);
+
+ /* Can't mix input/output together */
+ if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) ==
+ (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT))
+ return (EINVAL);
+
+ vf_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
+
+ return (0);
+}
+
+static int
+vf_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+ struct vf_gpio_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < sc->gpio_npins; i++) {
+ if (sc->gpio_pins[i].gp_pin == pin)
+ break;
+ }
+
+ if (i >= sc->gpio_npins)
+ return (EINVAL);
+
+ GPIO_LOCK(sc);
+ if (value)
+ WRITE4(sc, GPIO_PSOR(i), (1 << (i % 32)));
+ else
+ WRITE4(sc, GPIO_PCOR(i), (1 << (i % 32)));
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static device_method_t vf_gpio_methods[] = {
+ DEVMETHOD(device_probe, vf_gpio_probe),
+ DEVMETHOD(device_attach, vf_gpio_attach),
+
+ /* GPIO protocol */
+ DEVMETHOD(gpio_pin_max, vf_gpio_pin_max),
+ DEVMETHOD(gpio_pin_getname, vf_gpio_pin_getname),
+ DEVMETHOD(gpio_pin_getcaps, vf_gpio_pin_getcaps),
+ DEVMETHOD(gpio_pin_getflags, vf_gpio_pin_getflags),
+ DEVMETHOD(gpio_pin_get, vf_gpio_pin_get),
+ DEVMETHOD(gpio_pin_toggle, vf_gpio_pin_toggle),
+ DEVMETHOD(gpio_pin_setflags, vf_gpio_pin_setflags),
+ DEVMETHOD(gpio_pin_set, vf_gpio_pin_set),
+ { 0, 0 }
+};
+
+static driver_t vf_gpio_driver = {
+ "gpio",
+ vf_gpio_methods,
+ sizeof(struct vf_gpio_softc),
+};
+
+static devclass_t vf_gpio_devclass;
+
+DRIVER_MODULE(vf_gpio, simplebus, vf_gpio_driver, vf_gpio_devclass, 0, 0);
diff --git a/sys/arm/freescale/vybrid/vf_iomuxc.c b/sys/arm/freescale/vybrid/vf_iomuxc.c
new file mode 100644
index 0000000..08daf5e
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_iomuxc.c
@@ -0,0 +1,171 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family Input/Output Multiplexer Controller (IOMUXC)
+ * Chapter 5, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_iomuxc.h>
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define IBE (1 << 0) /* Input Buffer Enable Field */
+#define OBE (1 << 1) /* Output Buffer Enable Field. */
+#define PUE (1 << 2) /* Pull / Keep Select Field. */
+#define PKE (1 << 3) /* Pull / Keep Enable Field. */
+#define PUS_MASK (3 << 4) /* Pull Up / Down Config Field. */
+#define DSE_MASK (7 << 6) /* Drive Strength Field. */
+#define HYS (1 << 9) /* Hysteresis Enable Field */
+
+#define MUX_MODE_MASK 7
+#define MUX_MODE_SHIFT 20
+#define MUX_MODE_GPIO 0
+#define MUX_MODE_RMII 1
+#define MUX_MODE_RMII_CLKIN 2
+#define MUX_MODE_VBUS_EN_OTG 2
+
+#define PUS_22_KOHM_PULL_UP (3 << 4)
+#define DSE_25_OHM (6 << 6)
+
+#define NET0_PAD_START 45
+#define NET1_PAD_START 54
+#define NET_PAD_N 9
+
+struct iomuxc_softc {
+ struct resource *tmr_res[1];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ device_t dev;
+};
+
+static struct resource_spec iomuxc_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+iomuxc_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,mvf600-iomuxc"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family IOMUXC Unit");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+configure_pad(struct iomuxc_softc *sc, int pad, int mux_mode)
+{
+ int reg;
+
+ reg = READ4(sc, pad);
+ reg &= ~(MUX_MODE_MASK << MUX_MODE_SHIFT);
+ reg |= (mux_mode << MUX_MODE_SHIFT);
+ WRITE4(sc, pad, reg);
+
+ return (0);
+}
+
+static int
+iomuxc_attach(device_t dev)
+{
+ struct iomuxc_softc *sc;
+ int reg;
+ int i;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, iomuxc_spec, sc->tmr_res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ /* Memory interface */
+ sc->bst = rman_get_bustag(sc->tmr_res[0]);
+ sc->bsh = rman_get_bushandle(sc->tmr_res[0]);
+
+ /* USB */
+ configure_pad(sc, IOMUXC_PTA17, MUX_MODE_VBUS_EN_OTG);
+ reg = (PKE | PUE | PUS_22_KOHM_PULL_UP | DSE_25_OHM | OBE);
+ WRITE4(sc, IOMUXC_PTA7, reg);
+
+ /* NET */
+ configure_pad(sc, IOMUXC_PTA6, MUX_MODE_RMII_CLKIN);
+
+ /* NET0 */
+ for (i = NET0_PAD_START; i <= (NET0_PAD_START + NET_PAD_N); i++) {
+ configure_pad(sc, IOMUXC(i), MUX_MODE_RMII);
+ }
+
+ /* NET1 */
+ for (i = NET1_PAD_START; i <= (NET1_PAD_START + NET_PAD_N); i++) {
+ configure_pad(sc, IOMUXC(i), MUX_MODE_RMII);
+ }
+
+ return (0);
+}
+
+static device_method_t iomuxc_methods[] = {
+ DEVMETHOD(device_probe, iomuxc_probe),
+ DEVMETHOD(device_attach, iomuxc_attach),
+ { 0, 0 }
+};
+
+static driver_t iomuxc_driver = {
+ "iomuxc",
+ iomuxc_methods,
+ sizeof(struct iomuxc_softc),
+};
+
+static devclass_t iomuxc_devclass;
+
+DRIVER_MODULE(iomuxc, simplebus, iomuxc_driver, iomuxc_devclass, 0, 0);
diff --git a/sys/arm/freescale/vybrid/vf_iomuxc.h b/sys/arm/freescale/vybrid/vf_iomuxc.h
new file mode 100644
index 0000000..98b98b3
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_iomuxc.h
@@ -0,0 +1,165 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 IOMUXC(n) (n * 0x04)
+#define IOMUXCN 135
+#define IOMUXC_PTA6 0x000 /* Software MUX Pad Control Register 0 */
+#define IOMUXC_PTA8 0x004 /* Software MUX Pad Control Register 1 */
+#define IOMUXC_PTA9 0x008 /* Software MUX Pad Control Register 2 */
+#define IOMUXC_PTA10 0x00C /* Software MUX Pad Control Register 3 */
+#define IOMUXC_PTA11 0x010 /* Software MUX Pad Control Register 4 */
+#define IOMUXC_PTA12 0x014 /* Software MUX Pad Control Register 5 */
+#define IOMUXC_PTA16 0x018 /* Software MUX Pad Control Register 6 */
+#define IOMUXC_PTA17 0x01C /* Software MUX Pad Control Register 7 */
+#define IOMUXC_PTA18 0x020 /* Software MUX Pad Control Register 8 */
+#define IOMUXC_PTA19 0x024 /* Software MUX Pad Control Register 9 */
+#define IOMUXC_PTA20 0x028 /* Software MUX Pad Control Register 10 */
+#define IOMUXC_PTA21 0x02C /* Software MUX Pad Control Register 11 */
+#define IOMUXC_PTA22 0x030 /* Software MUX Pad Control Register 12 */
+#define IOMUXC_PTA23 0x034 /* Software MUX Pad Control Register 13 */
+#define IOMUXC_PTA24 0x038 /* Software MUX Pad Control Register 14 */
+#define IOMUXC_PTA25 0x03C /* Software MUX Pad Control Register 15 */
+#define IOMUXC_PTA26 0x040 /* Software MUX Pad Control Register 16 */
+#define IOMUXC_PTA27 0x044 /* Software MUX Pad Control Register 17 */
+#define IOMUXC_PTA28 0x048 /* Software MUX Pad Control Register 18 */
+#define IOMUXC_PTA29 0x04C /* Software MUX Pad Control Register 19 */
+#define IOMUXC_PTA30 0x050 /* Software MUX Pad Control Register 20 */
+#define IOMUXC_PTA31 0x054 /* Software MUX Pad Control Register 21 */
+#define IOMUXC_PTB0 0x058 /* Software MUX Pad Control Register 22 */
+#define IOMUXC_PTB1 0x05C /* Software MUX Pad Control Register 23 */
+#define IOMUXC_PTB2 0x060 /* Software MUX Pad Control Register 24 */
+#define IOMUXC_PTB3 0x064 /* Software MUX Pad Control Register 25 */
+#define IOMUXC_PTB4 0x068 /* Software MUX Pad Control Register 26 */
+#define IOMUXC_PTB5 0x06C /* Software MUX Pad Control Register 27 */
+#define IOMUXC_PTB6 0x070 /* Software MUX Pad Control Register 28 */
+#define IOMUXC_PTB7 0x074 /* Software MUX Pad Control Register 29 */
+#define IOMUXC_PTB8 0x078 /* Software MUX Pad Control Register 30 */
+#define IOMUXC_PTB9 0x07C /* Software MUX Pad Control Register 31 */
+#define IOMUXC_PTB10 0x080 /* Software MUX Pad Control Register 32 */
+#define IOMUXC_PTB11 0x084 /* Software MUX Pad Control Register 33 */
+#define IOMUXC_PTB12 0x088 /* Software MUX Pad Control Register 34 */
+#define IOMUXC_PTB13 0x08C /* Software MUX Pad Control Register 35 */
+#define IOMUXC_PTB14 0x090 /* Software MUX Pad Control Register 36 */
+#define IOMUXC_PTB15 0x094 /* Software MUX Pad Control Register 37 */
+#define IOMUXC_PTB16 0x098 /* Software MUX Pad Control Register 38 */
+#define IOMUXC_PTB17 0x09C /* Software MUX Pad Control Register 39 */
+#define IOMUXC_PTB18 0x0A0 /* Software MUX Pad Control Register 40 */
+#define IOMUXC_PTB19 0x0A4 /* Software MUX Pad Control Register 41 */
+#define IOMUXC_PTB20 0x0A8 /* Software MUX Pad Control Register 42 */
+#define IOMUXC_PTB21 0x0AC /* Software MUX Pad Control Register 43 */
+#define IOMUXC_PTB22 0x0B0 /* Software MUX Pad Control Register 44 */
+#define IOMUXC_PTC0 0x0B4 /* Software MUX Pad Control Register 45 */
+#define IOMUXC_PTC1 0x0B8 /* Software MUX Pad Control Register 46 */
+#define IOMUXC_PTC2 0x0BC /* Software MUX Pad Control Register 47 */
+#define IOMUXC_PTC3 0x0C0 /* Software MUX Pad Control Register 48 */
+#define IOMUXC_PTC4 0x0C4 /* Software MUX Pad Control Register 49 */
+#define IOMUXC_PTC5 0x0C8 /* Software MUX Pad Control Register 50 */
+#define IOMUXC_PTC6 0x0CC /* Software MUX Pad Control Register 51 */
+#define IOMUXC_PTC7 0x0D0 /* Software MUX Pad Control Register 52 */
+#define IOMUXC_PTC8 0x0D4 /* Software MUX Pad Control Register 53 */
+#define IOMUXC_PTC9 0x0D8 /* Software MUX Pad Control Register 54 */
+#define IOMUXC_PTC10 0x0DC /* Software MUX Pad Control Register 55 */
+#define IOMUXC_PTC11 0x0E0 /* Software MUX Pad Control Register 56 */
+#define IOMUXC_PTC12 0x0E4 /* Software MUX Pad Control Register 57 */
+#define IOMUXC_PTC13 0x0E8 /* Software MUX Pad Control Register 58 */
+#define IOMUXC_PTC14 0x0EC /* Software MUX Pad Control Register 59 */
+#define IOMUXC_PTC15 0x0F0 /* Software MUX Pad Control Register 60 */
+#define IOMUXC_PTC16 0x0F4 /* Software MUX Pad Control Register 61 */
+#define IOMUXC_PTC17 0x0F8 /* Software MUX Pad Control Register 62 */
+#define IOMUXC_PTD31 0x0FC /* Software MUX Pad Control Register 63 */
+#define IOMUXC_PTD30 0x100 /* Software MUX Pad Control Register 64 */
+#define IOMUXC_PTD29 0x104 /* Software MUX Pad Control Register 65 */
+#define IOMUXC_PTD28 0x108 /* Software MUX Pad Control Register 66 */
+#define IOMUXC_PTD27 0x10C /* Software MUX Pad Control Register 67 */
+#define IOMUXC_PTD26 0x110 /* Software MUX Pad Control Register 68 */
+#define IOMUXC_PTD25 0x114 /* Software MUX Pad Control Register 69 */
+#define IOMUXC_PTD24 0x118 /* Software MUX Pad Control Register 70 */
+#define IOMUXC_PTD23 0x11C /* Software MUX Pad Control Register 71 */
+#define IOMUXC_PTD22 0x120 /* Software MUX Pad Control Register 72 */
+#define IOMUXC_PTD21 0x124 /* Software MUX Pad Control Register 73 */
+#define IOMUXC_PTD20 0x128 /* Software MUX Pad Control Register 74 */
+#define IOMUXC_PTD19 0x12C /* Software MUX Pad Control Register 75 */
+#define IOMUXC_PTD18 0x130 /* Software MUX Pad Control Register 76 */
+#define IOMUXC_PTD17 0x134 /* Software MUX Pad Control Register 77 */
+#define IOMUXC_PTD16 0x138 /* Software MUX Pad Control Register 78 */
+#define IOMUXC_PTD0 0x13C /* Software MUX Pad Control Register 79 */
+#define IOMUXC_PTD1 0x140 /* Software MUX Pad Control Register 80 */
+#define IOMUXC_PTD2 0x144 /* Software MUX Pad Control Register 81 */
+#define IOMUXC_PTD3 0x148 /* Software MUX Pad Control Register 82 */
+#define IOMUXC_PTD4 0x14C /* Software MUX Pad Control Register 83 */
+#define IOMUXC_PTD5 0x150 /* Software MUX Pad Control Register 84 */
+#define IOMUXC_PTD6 0x154 /* Software MUX Pad Control Register 85 */
+#define IOMUXC_PTD7 0x158 /* Software MUX Pad Control Register 86 */
+#define IOMUXC_PTD8 0x15C /* Software MUX Pad Control Register 87 */
+#define IOMUXC_PTD9 0x160 /* Software MUX Pad Control Register 88 */
+#define IOMUXC_PTD10 0x164 /* Software MUX Pad Control Register 89 */
+#define IOMUXC_PTD11 0x168 /* Software MUX Pad Control Register 90 */
+#define IOMUXC_PTD12 0x16C /* Software MUX Pad Control Register 91 */
+#define IOMUXC_PTD13 0x170 /* Software MUX Pad Control Register 92 */
+#define IOMUXC_PTB23 0x174 /* Software MUX Pad Control Register 93 */
+#define IOMUXC_PTB24 0x178 /* Software MUX Pad Control Register 94 */
+#define IOMUXC_PTB25 0x17C /* Software MUX Pad Control Register 95 */
+#define IOMUXC_PTB26 0x180 /* Software MUX Pad Control Register 96 */
+#define IOMUXC_PTB27 0x184 /* Software MUX Pad Control Register 97 */
+#define IOMUXC_PTB28 0x188 /* Software MUX Pad Control Register 98 */
+#define IOMUXC_PTC26 0x18C /* Software MUX Pad Control Register 99 */
+#define IOMUXC_PTC27 0x190 /* Software MUX Pad Control Register 100 */
+#define IOMUXC_PTC28 0x194 /* Software MUX Pad Control Register 101 */
+#define IOMUXC_PTC29 0x198 /* Software MUX Pad Control Register 102 */
+#define IOMUXC_PTC30 0x19C /* Software MUX Pad Control Register 103 */
+#define IOMUXC_PTC31 0x1A0 /* Software MUX Pad Control Register 104 */
+#define IOMUXC_PTE0 0x1A4 /* Software MUX Pad Control Register 105 */
+#define IOMUXC_PTE1 0x1A8 /* Software MUX Pad Control Register 106 */
+#define IOMUXC_PTE2 0x1AC /* Software MUX Pad Control Register 107 */
+#define IOMUXC_PTE3 0x1B0 /* Software MUX Pad Control Register 108 */
+#define IOMUXC_PTE4 0x1B4 /* Software MUX Pad Control Register 109 */
+#define IOMUXC_PTE5 0x1B8 /* Software MUX Pad Control Register 110 */
+#define IOMUXC_PTE6 0x1BC /* Software MUX Pad Control Register 111 */
+#define IOMUXC_PTE7 0x1C0 /* Software MUX Pad Control Register 112 */
+#define IOMUXC_PTE8 0x1C4 /* Software MUX Pad Control Register 113 */
+#define IOMUXC_PTE9 0x1C8 /* Software MUX Pad Control Register 114 */
+#define IOMUXC_PTE10 0x1CC /* Software MUX Pad Control Register 115 */
+#define IOMUXC_PTE11 0x1D0 /* Software MUX Pad Control Register 116 */
+#define IOMUXC_PTE12 0x1D4 /* Software MUX Pad Control Register 117 */
+#define IOMUXC_PTE13 0x1D8 /* Software MUX Pad Control Register 118 */
+#define IOMUXC_PTE14 0x1DC /* Software MUX Pad Control Register 119 */
+#define IOMUXC_PTE15 0x1E0 /* Software MUX Pad Control Register 120 */
+#define IOMUXC_PTE16 0x1E4 /* Software MUX Pad Control Register 121 */
+#define IOMUXC_PTE17 0x1E8 /* Software MUX Pad Control Register 122 */
+#define IOMUXC_PTE18 0x1EC /* Software MUX Pad Control Register 123 */
+#define IOMUXC_PTE19 0x1F0 /* Software MUX Pad Control Register 124 */
+#define IOMUXC_PTE20 0x1F4 /* Software MUX Pad Control Register 125 */
+#define IOMUXC_PTE21 0x1F8 /* Software MUX Pad Control Register 126 */
+#define IOMUXC_PTE22 0x1FC /* Software MUX Pad Control Register 127 */
+#define IOMUXC_PTE23 0x200 /* Software MUX Pad Control Register 128 */
+#define IOMUXC_PTE24 0x204 /* Software MUX Pad Control Register 129 */
+#define IOMUXC_PTE25 0x208 /* Software MUX Pad Control Register 130 */
+#define IOMUXC_PTE26 0x20C /* Software MUX Pad Control Register 131 */
+#define IOMUXC_PTE27 0x210 /* Software MUX Pad Control Register 132 */
+#define IOMUXC_PTE28 0x214 /* Software MUX Pad Control Register 133 */
+#define IOMUXC_PTA7 0x218 /* Software MUX Pad Control Register 134 */
diff --git a/sys/arm/freescale/vybrid/vf_machdep.c b/sys/arm/freescale/vybrid/vf_machdep.c
new file mode 100644
index 0000000..29e7355
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_machdep.c
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 "opt_ddb.h"
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+ return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+}
+
+void
+initarm_gpio_init(void)
+{
+
+}
+
+void
+initarm_late_init(void)
+{
+
+}
+
+int
+initarm_devmap_init(void)
+{
+
+ arm_devmap_add_entry(0x40000000, 0x100000);
+
+ return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+ return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+ return (0);
+}
diff --git a/sys/arm/freescale/vybrid/vf_mscm.c b/sys/arm/freescale/vybrid/vf_mscm.c
new file mode 100644
index 0000000..5741627
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_mscm.c
@@ -0,0 +1,123 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family Miscellaneous System Control Module (MSCM)
+ * Chapter 66, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define VF_NINT 112 /* Total number of interrupts */
+
+/* Int Router Shared Peripheral Routing Control */
+#define MSCM_IRSPRC(n) (0x880 + 2 * n)
+
+struct mscm_softc {
+ struct resource *res[1];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+};
+
+static struct resource_spec mscm_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+mscm_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,mvf600-mscm"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family Miscellaneous System Control Module");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+mscm_attach(device_t dev)
+{
+ struct mscm_softc *sc;
+ int i;
+
+ sc = device_get_softc(dev);
+
+ if (bus_alloc_resources(dev, mscm_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]);
+
+ /* Route all the interrupts to CP0 */
+ for (i = 0; i < VF_NINT; i++)
+ WRITE2(sc, MSCM_IRSPRC(i), 1);
+
+ return (0);
+}
+
+static device_method_t mscm_methods[] = {
+ DEVMETHOD(device_probe, mscm_probe),
+ DEVMETHOD(device_attach, mscm_attach),
+ { 0, 0 }
+};
+
+static driver_t mscm_driver = {
+ "mscm",
+ mscm_methods,
+ sizeof(struct mscm_softc),
+};
+
+static devclass_t mscm_devclass;
+
+DRIVER_MODULE(mscm, simplebus, mscm_driver, mscm_devclass, 0, 0);
diff --git a/sys/arm/freescale/vybrid/vf_nfc.c b/sys/arm/freescale/vybrid/vf_nfc.c
new file mode 100644
index 0000000..8132200
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_nfc.c
@@ -0,0 +1,524 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family NAND Flash Controller (NFC)
+ * Chapter 31, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/time.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/nand/nand.h>
+#include <dev/nand/nandbus.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include "nfc_if.h"
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+enum addr_type {
+ ADDR_NONE,
+ ADDR_ID,
+ ADDR_ROW,
+ ADDR_ROWCOL
+};
+
+struct fsl_nfc_fcm {
+ uint32_t addr_bits;
+ enum addr_type addr_type;
+ uint32_t col_addr_bits;
+ uint32_t row_addr_bits;
+ u_int read_ptr;
+ u_int addr_ptr;
+ u_int command;
+ u_int code;
+};
+
+struct vf_nand_softc {
+ struct nand_softc nand_dev;
+ bus_space_handle_t bsh;
+ bus_space_tag_t bst;
+ struct resource *res[2];
+ struct fsl_nfc_fcm fcm;
+};
+
+static struct resource_spec nfc_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int vf_nand_attach(device_t);
+static int vf_nand_probe(device_t);
+static int vf_nand_send_command(device_t, uint8_t);
+static int vf_nand_send_address(device_t, uint8_t);
+static int vf_nand_start_command(device_t);
+static uint8_t vf_nand_read_byte(device_t);
+static void vf_nand_read_buf(device_t, void *, uint32_t);
+static void vf_nand_write_buf(device_t, void *, uint32_t);
+static int vf_nand_select_cs(device_t, uint8_t);
+static int vf_nand_read_rnb(device_t);
+
+#define CMD_READ_PAGE 0x7EE0
+#define CMD_PROG_PAGE 0x7FC0
+#define CMD_PROG_PAGE_DMA 0xFFC8
+#define CMD_ERASE 0x4EC0
+#define CMD_READ_ID 0x4804
+#define CMD_READ_STATUS 0x4068
+#define CMD_RESET 0x4040
+#define CMD_RANDOM_IN 0x7140
+#define CMD_RANDOM_OUT 0x70E0
+
+#define CMD_BYTE2_PROG_PAGE 0x10
+#define CMD_BYTE2_PAGE_READ 0x30
+#define CMD_BYTE2_ERASE 0xD0
+
+#define NFC_CMD1 0x3F00 /* Flash command 1 */
+#define NFC_CMD2 0x3F04 /* Flash command 2 */
+#define NFC_CAR 0x3F08 /* Column address */
+#define NFC_RAR 0x3F0C /* Row address */
+#define NFC_RPT 0x3F10 /* Flash command repeat */
+#define NFC_RAI 0x3F14 /* Row address increment */
+#define NFC_SR1 0x3F18 /* Flash status 1 */
+#define NFC_SR2 0x3F1C /* Flash status 2 */
+#define NFC_DMA_CH1 0x3F20 /* DMA channel 1 address */
+#define NFC_DMACFG 0x3F24 /* DMA configuration */
+#define NFC_SWAP 0x3F28 /* Cach swap */
+#define NFC_SECSZ 0x3F2C /* Sector size */
+#define NFC_CFG 0x3F30 /* Flash configuration */
+#define NFC_DMA_CH2 0x3F34 /* DMA channel 2 address */
+#define NFC_ISR 0x3F38 /* Interrupt status */
+
+#define ECCMODE_SHIFT 17
+#define AIAD_SHIFT 5
+#define AIBN_SHIFT 4
+#define PAGECOUNT_SHIFT 0
+#define BITWIDTH_SHIFT 7
+#define BITWIDTH8 0
+#define BITWIDTH16 1
+#define PAGECOUNT_MASK 0xf
+
+#define CMD2_BYTE1_SHIFT 24
+#define CMD2_CODE_SHIFT 8
+#define CMD2_BUFNO_SHIFT 1
+#define CMD2_START_SHIFT 0
+
+static device_method_t vf_nand_methods[] = {
+ DEVMETHOD(device_probe, vf_nand_probe),
+ DEVMETHOD(device_attach, vf_nand_attach),
+ DEVMETHOD(nfc_start_command, vf_nand_start_command),
+ DEVMETHOD(nfc_send_command, vf_nand_send_command),
+ DEVMETHOD(nfc_send_address, vf_nand_send_address),
+ DEVMETHOD(nfc_read_byte, vf_nand_read_byte),
+ DEVMETHOD(nfc_read_buf, vf_nand_read_buf),
+ DEVMETHOD(nfc_write_buf, vf_nand_write_buf),
+ DEVMETHOD(nfc_select_cs, vf_nand_select_cs),
+ DEVMETHOD(nfc_read_rnb, vf_nand_read_rnb),
+ { 0, 0 },
+};
+
+static driver_t vf_nand_driver = {
+ "nand",
+ vf_nand_methods,
+ sizeof(struct vf_nand_softc),
+};
+
+static devclass_t vf_nand_devclass;
+DRIVER_MODULE(vf_nand, simplebus, vf_nand_driver, vf_nand_devclass, 0, 0);
+
+static int
+vf_nand_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,mvf600-nand"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family NAND controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+vf_nand_attach(device_t dev)
+{
+ struct vf_nand_softc *sc;
+ int err;
+ int reg;
+
+ sc = device_get_softc(dev);
+ if (bus_alloc_resources(dev, nfc_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources!\n");
+ return (ENXIO);
+ }
+
+ sc->bst = rman_get_bustag(sc->res[0]);
+ sc->bsh = rman_get_bushandle(sc->res[0]);
+
+ /* Size in bytes of one elementary transfer unit */
+ WRITE4(sc, NFC_SECSZ, 2048);
+
+ /* Flash mode width */
+ reg = READ4(sc, NFC_CFG);
+ reg |= (BITWIDTH16 << BITWIDTH_SHIFT);
+
+ /* No correction, ECC bypass */
+ reg &= ~(0x7 << ECCMODE_SHIFT);
+
+ /* Disable Auto-incrementing of flash row address */
+ reg &= ~(0x1 << AIAD_SHIFT);
+
+ /* Disable Auto-incrementing of buffer numbers */
+ reg &= ~(0x1 << AIBN_SHIFT);
+
+ /*
+ * Number of virtual pages (in one physical flash page)
+ * to be programmed or read, etc.
+ */
+ reg &= ~(PAGECOUNT_MASK);
+ reg |= (1 << PAGECOUNT_SHIFT);
+ WRITE4(sc, NFC_CFG, reg);
+
+ nand_init(&sc->nand_dev, dev, NAND_ECC_NONE, 0, 0, NULL, NULL);
+ err = nandbus_create(dev);
+ return (err);
+}
+
+static int
+vf_nand_start_command(device_t dev)
+{
+ struct vf_nand_softc *sc;
+ struct fsl_nfc_fcm *fcm;
+ int reg;
+
+ sc = device_get_softc(dev);
+ fcm = &sc->fcm;
+
+ nand_debug(NDBG_DRV,"vf_nand: start command %x", fcm->command);
+
+ /* CMD2 */
+ reg = READ4(sc, NFC_CMD2);
+ reg &= ~(0xff << CMD2_BYTE1_SHIFT);
+ reg |= (fcm->command << CMD2_BYTE1_SHIFT);
+ WRITE4(sc, NFC_CMD2, reg);
+
+ /* CMD1 */
+ if ((fcm->command == NAND_CMD_READ) ||
+ (fcm->command == NAND_CMD_PROG) ||
+ (fcm->command == NAND_CMD_ERASE)) {
+ reg = READ4(sc, NFC_CMD1);
+ reg &= ~(0xff << 24);
+
+ if (fcm->command == NAND_CMD_READ)
+ reg |= (CMD_BYTE2_PAGE_READ << 24);
+ else if (fcm->command == NAND_CMD_PROG)
+ reg |= (CMD_BYTE2_PROG_PAGE << 24);
+ else if (fcm->command == NAND_CMD_ERASE)
+ reg |= (CMD_BYTE2_ERASE << 24);
+
+ WRITE4(sc, NFC_CMD1, reg);
+ }
+
+ /* We work with 1st buffer */
+ reg = READ4(sc, NFC_CMD2);
+ reg &= ~(0xf << CMD2_BUFNO_SHIFT);
+ reg |= (0 << CMD2_BUFNO_SHIFT);
+ WRITE4(sc, NFC_CMD2, reg);
+
+ /* Cmd CODE */
+ reg = READ4(sc, NFC_CMD2);
+ reg &= ~(0xffff << CMD2_CODE_SHIFT);
+ reg |= (fcm->code << CMD2_CODE_SHIFT);
+ WRITE4(sc, NFC_CMD2, reg);
+
+ /* Col */
+ if (fcm->addr_type == ADDR_ROWCOL) {
+ reg = READ4(sc, NFC_CAR);
+ reg &= ~(0xffff);
+ reg |= fcm->col_addr_bits;
+ nand_debug(NDBG_DRV,"setting CAR to 0x%08x\n", reg);
+ WRITE4(sc, NFC_CAR, reg);
+ }
+
+ /* Row */
+ reg = READ4(sc, NFC_RAR);
+ reg &= ~(0xffffff);
+ if (fcm->addr_type == ADDR_ID)
+ reg |= fcm->addr_bits;
+ else
+ reg |= fcm->row_addr_bits;
+ WRITE4(sc, NFC_RAR, reg);
+
+ /* Start */
+ reg = READ4(sc, NFC_CMD2);
+ reg |= (1 << CMD2_START_SHIFT);
+ WRITE4(sc, NFC_CMD2, reg);
+
+ /* Wait command completion */
+ while (READ4(sc, NFC_CMD2) & (1 << CMD2_START_SHIFT))
+ ;
+
+ return (0);
+}
+
+static int
+vf_nand_send_command(device_t dev, uint8_t command)
+{
+ struct vf_nand_softc *sc;
+ struct fsl_nfc_fcm *fcm;
+
+ nand_debug(NDBG_DRV,"vf_nand: send command %x", command);
+
+ sc = device_get_softc(dev);
+ fcm = &sc->fcm;
+
+ if ((command == NAND_CMD_READ_END) ||
+ (command == NAND_CMD_PROG_END) ||
+ (command == NAND_CMD_ERASE_END)) {
+ return (0);
+ }
+
+ fcm->command = command;
+
+ fcm->code = 0;
+ fcm->read_ptr = 0;
+ fcm->addr_type = 0;
+ fcm->addr_bits = 0;
+
+ fcm->addr_ptr = 0;
+ fcm->col_addr_bits = 0;
+ fcm->row_addr_bits = 0;
+
+ switch (command) {
+ case NAND_CMD_READ:
+ fcm->code = CMD_READ_PAGE;
+ fcm->addr_type = ADDR_ROWCOL;
+ break;
+ case NAND_CMD_PROG:
+ fcm->code = CMD_PROG_PAGE;
+ fcm->addr_type = ADDR_ROWCOL;
+ break;
+ case NAND_CMD_PROG_END:
+ break;
+ case NAND_CMD_ERASE_END:
+ break;
+ case NAND_CMD_RESET:
+ fcm->code = CMD_RESET;
+ break;
+ case NAND_CMD_READ_ID:
+ fcm->code = CMD_READ_ID;
+ fcm->addr_type = ADDR_ID;
+ break;
+ case NAND_CMD_READ_PARAMETER:
+ fcm->code = CMD_READ_PAGE;
+ fcm->addr_type = ADDR_ID;
+ break;
+ case NAND_CMD_STATUS:
+ fcm->code = CMD_READ_STATUS;
+ break;
+ case NAND_CMD_ERASE:
+ fcm->code = CMD_ERASE;
+ fcm->addr_type = ADDR_ROW;
+ break;
+ default:
+ nand_debug(NDBG_DRV, "unknown command %d\n", command);
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+vf_nand_send_address(device_t dev, uint8_t addr)
+{
+ struct vf_nand_softc *sc;
+ struct fsl_nfc_fcm *fcm;
+
+ nand_debug(NDBG_DRV,"vf_nand: send address %x", addr);
+ sc = device_get_softc(dev);
+ fcm = &sc->fcm;
+
+ nand_debug(NDBG_DRV, "setting addr #%d to 0x%02x\n", fcm->addr_ptr, addr);
+
+ if (fcm->addr_type == ADDR_ID) {
+ fcm->addr_bits = addr;
+ } else if (fcm->addr_type == ADDR_ROWCOL) {
+
+ if (fcm->addr_ptr < 2)
+ fcm->col_addr_bits |= (addr << (fcm->addr_ptr * 8));
+ else
+ fcm->row_addr_bits |= (addr << ((fcm->addr_ptr - 2) * 8));
+
+ } else if (fcm->addr_type == ADDR_ROW)
+ fcm->row_addr_bits |= (addr << (fcm->addr_ptr * 8));
+
+ fcm->addr_ptr += 1;
+
+ return (0);
+}
+
+static uint8_t
+vf_nand_read_byte(device_t dev)
+{
+ struct vf_nand_softc *sc;
+ struct fsl_nfc_fcm *fcm;
+ uint8_t data;
+ int sr1, sr2;
+ int b;
+
+ sc = device_get_softc(dev);
+ fcm = &sc->fcm;
+
+ sr1 = READ4(sc, NFC_SR1);
+ sr2 = READ4(sc, NFC_SR2);
+
+ data = 0;
+ if (fcm->addr_type == ADDR_ID) {
+ b = 32 - ((fcm->read_ptr + 1) * 8);
+ data = (sr1 >> b) & 0xff;
+ fcm->read_ptr++;
+ } else if (fcm->command == NAND_CMD_STATUS) {
+ data = sr2 & 0xff;
+ }
+
+ nand_debug(NDBG_DRV,"vf_nand: read %x", data);
+ return (data);
+}
+
+static void
+vf_nand_read_buf(device_t dev, void* buf, uint32_t len)
+{
+ struct vf_nand_softc *sc;
+ struct fsl_nfc_fcm *fcm;
+ uint16_t *tmp;
+ uint8_t *b;
+ int i;
+
+ b = (uint8_t*)buf;
+ sc = device_get_softc(dev);
+ fcm = &sc->fcm;
+
+ nand_debug(NDBG_DRV, "vf_nand: read_buf len %d", len);
+
+ if (fcm->command == NAND_CMD_READ_PARAMETER) {
+ tmp = malloc(len, M_DEVBUF, M_NOWAIT);
+ bus_read_region_2(sc->res[0], 0x0, tmp, len);
+
+ for (i = 0; i < len; i += 2) {
+ b[i] = tmp[i+1];
+ b[i+1] = tmp[i];
+ }
+
+ free(tmp, M_DEVBUF);
+
+#ifdef NAND_DEBUG
+ for (i = 0; i < len; i++) {
+ if (!(i % 16))
+ printf("%s", i == 0 ? "vf_nand:\n" : "\n");
+ printf(" %x", b[i]);
+ if (i == len - 1)
+ printf("\n");
+ }
+#endif
+
+ } else {
+
+ for (i = 0; i < len; i++) {
+ b[i] = READ1(sc, i);
+
+#ifdef NAND_DEBUG
+ if (!(i % 16))
+ printf("%s", i == 0 ? "vf_nand:\n" : "\n");
+ printf(" %x", b[i]);
+ if (i == len - 1)
+ printf("\n");
+#endif
+ }
+
+ }
+}
+
+static void
+vf_nand_write_buf(device_t dev, void* buf, uint32_t len)
+{
+ struct vf_nand_softc *sc;
+ struct fsl_nfc_fcm *fcm;
+ uint8_t *b;
+ int i;
+
+ b = (uint8_t*)buf;
+ sc = device_get_softc(dev);
+ fcm = &sc->fcm;
+
+ nand_debug(NDBG_DRV,"vf_nand: write_buf len %d", len);
+
+ for (i = 0; i < len; i++) {
+ WRITE1(sc, i, b[i]);
+
+#ifdef NAND_DEBUG
+ if (!(i % 16))
+ printf("%s", i == 0 ? "vf_nand:\n" : "\n");
+ printf(" %x", b[i]);
+ if (i == len - 1)
+ printf("\n");
+#endif
+
+ }
+}
+
+static int
+vf_nand_select_cs(device_t dev, uint8_t cs)
+{
+
+ if (cs > 0)
+ return (ENODEV);
+
+ return (0);
+}
+
+static int
+vf_nand_read_rnb(device_t dev)
+{
+
+ /* no-op */
+ return (0); /* ready */
+}
diff --git a/sys/arm/freescale/vybrid/vf_src.c b/sys/arm/freescale/vybrid/vf_src.c
new file mode 100644
index 0000000..0fe6f3b
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_src.c
@@ -0,0 +1,147 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family System Reset Controller (SRC)
+ * Chapter 18, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_src.h>
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define SRC_SCR 0x00 /* SRC Control Register */
+#define SRC_SBMR1 0x04 /* SRC Boot Mode Register 1 */
+#define SRC_SRSR 0x08 /* SRC Status Register */
+#define SRC_SECR 0x0C /* SRC_SECR */
+#define SRC_SICR 0x14 /* SRC Reset Interrupt Configuration Register */
+#define SRC_SIMR 0x18 /* SRC Interrupt Masking Register */
+#define SRC_SBMR2 0x1C /* SRC Boot Mode Register 2 */
+#define SRC_GPR0 0x20 /* General Purpose Register */
+#define SRC_GPR1 0x24 /* General Purpose Register */
+#define SRC_GPR2 0x28 /* General Purpose Register */
+#define SRC_GPR3 0x2C /* General Purpose Register */
+#define SRC_GPR4 0x30 /* General Purpose Register */
+#define SRC_MISC0 0x4C /* MISC0 */
+#define SRC_MISC1 0x50 /* MISC1 */
+#define SRC_MISC2 0x54 /* MISC2 */
+#define SRC_MISC3 0x58 /* MISC3 */
+
+struct src_softc {
+ struct resource *res[1];
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+};
+
+struct src_softc *src_sc;
+
+static struct resource_spec src_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+int
+src_swreset(void)
+{
+
+ if (src_sc == NULL)
+ return (1);
+
+ WRITE4(src_sc, SRC_SCR, SW_RST);
+
+ return (0);
+}
+
+static int
+src_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,mvf600-src"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Vybrid Family System Reset Controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+src_attach(device_t dev)
+{
+ struct src_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (bus_alloc_resources(dev, src_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]);
+
+ src_sc = sc;
+
+ return (0);
+}
+
+static device_method_t src_methods[] = {
+ DEVMETHOD(device_probe, src_probe),
+ DEVMETHOD(device_attach, src_attach),
+ { 0, 0 }
+};
+
+static driver_t src_driver = {
+ "src",
+ src_methods,
+ sizeof(struct src_softc),
+};
+
+static devclass_t src_devclass;
+
+DRIVER_MODULE(src, simplebus, src_driver, src_devclass, 0, 0);
diff --git a/sys/arm/freescale/vybrid/vf_src.h b/sys/arm/freescale/vybrid/vf_src.h
new file mode 100644
index 0000000..8e50b05
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_src.h
@@ -0,0 +1,30 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 SW_RST (1 << 12) /* Software reset */
+int src_swreset(void);
diff --git a/sys/arm/freescale/vybrid/vf_uart.c b/sys/arm/freescale/vybrid/vf_uart.c
new file mode 100644
index 0000000..d181432
--- /dev/null
+++ b/sys/arm/freescale/vybrid/vf_uart.c
@@ -0,0 +1,509 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
+ */
+
+/*
+ * Vybrid Family Universal Asynchronous Receiver/Transmitter
+ * Chapter 49, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kdb.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_bus.h>
+
+#include "uart_if.h"
+
+#define UART_BDH 0x00 /* Baud Rate Registers: High */
+#define UART_BDL 0x01 /* Baud Rate Registers: Low */
+#define UART_C1 0x02 /* Control Register 1 */
+#define UART_C2 0x03 /* Control Register 2 */
+#define UART_S1 0x04 /* Status Register 1 */
+#define UART_S2 0x05 /* Status Register 2 */
+#define UART_C3 0x06 /* Control Register 3 */
+#define UART_D 0x07 /* Data Register */
+#define UART_MA1 0x08 /* Match Address Registers 1 */
+#define UART_MA2 0x09 /* Match Address Registers 2 */
+#define UART_C4 0x0A /* Control Register 4 */
+#define UART_C5 0x0B /* Control Register 5 */
+#define UART_ED 0x0C /* Extended Data Register */
+#define UART_MODEM 0x0D /* Modem Register */
+#define UART_IR 0x0E /* Infrared Register */
+#define UART_PFIFO 0x10 /* FIFO Parameters */
+#define UART_CFIFO 0x11 /* FIFO Control Register */
+#define UART_SFIFO 0x12 /* FIFO Status Register */
+#define UART_TWFIFO 0x13 /* FIFO Transmit Watermark */
+#define UART_TCFIFO 0x14 /* FIFO Transmit Count */
+#define UART_RWFIFO 0x15 /* FIFO Receive Watermark */
+#define UART_RCFIFO 0x16 /* FIFO Receive Count */
+#define UART_C7816 0x18 /* 7816 Control Register */
+#define UART_IE7816 0x19 /* 7816 Interrupt Enable Register */
+#define UART_IS7816 0x1A /* 7816 Interrupt Status Register */
+#define UART_WP7816T0 0x1B /* 7816 Wait Parameter Register */
+#define UART_WP7816T1 0x1B /* 7816 Wait Parameter Register */
+#define UART_WN7816 0x1C /* 7816 Wait N Register */
+#define UART_WF7816 0x1D /* 7816 Wait FD Register */
+#define UART_ET7816 0x1E /* 7816 Error Threshold Register */
+#define UART_TL7816 0x1F /* 7816 Transmit Length Register */
+#define UART_C6 0x21 /* CEA709.1-B Control Register 6 */
+#define UART_PCTH 0x22 /* CEA709.1-B Packet Cycle Time Counter High */
+#define UART_PCTL 0x23 /* CEA709.1-B Packet Cycle Time Counter Low */
+#define UART_B1T 0x24 /* CEA709.1-B Beta1 Timer */
+#define UART_SDTH 0x25 /* CEA709.1-B Secondary Delay Timer High */
+#define UART_SDTL 0x26 /* CEA709.1-B Secondary Delay Timer Low */
+#define UART_PRE 0x27 /* CEA709.1-B Preamble */
+#define UART_TPL 0x28 /* CEA709.1-B Transmit Packet Length */
+#define UART_IE 0x29 /* CEA709.1-B Interrupt Enable Register */
+#define UART_WB 0x2A /* CEA709.1-B WBASE */
+#define UART_S3 0x2B /* CEA709.1-B Status Register */
+#define UART_S4 0x2C /* CEA709.1-B Status Register */
+#define UART_RPL 0x2D /* CEA709.1-B Received Packet Length */
+#define UART_RPREL 0x2E /* CEA709.1-B Received Preamble Length */
+#define UART_CPW 0x2F /* CEA709.1-B Collision Pulse Width */
+#define UART_RIDT 0x30 /* CEA709.1-B Receive Indeterminate Time */
+#define UART_TIDT 0x31 /* CEA709.1-B Transmit Indeterminate Time */
+
+#define UART_C2_TE (1 << 3) /* Transmitter Enable */
+#define UART_C2_TIE (1 << 7) /* Transmitter Interrupt Enable */
+#define UART_C2_RE (1 << 2) /* Receiver Enable */
+#define UART_C2_RIE (1 << 5) /* Receiver Interrupt Enable */
+#define UART_S1_TDRE (1 << 7) /* Transmit Data Register Empty Flag */
+#define UART_S1_RDRF (1 << 5) /* Receive Data Register Full Flag */
+#define UART_S2_LBKDIF (1 << 7) /* LIN Break Detect Interrupt Flag */
+
+#define UART_C4_BRFA 0x1f /* Baud Rate Fine Adjust */
+#define UART_BDH_SBR 0x1f /* UART Baud Rate Bits */
+
+/*
+ * Low-level UART interface.
+ */
+static int vf_uart_probe(struct uart_bas *bas);
+static void vf_uart_init(struct uart_bas *bas, int, int, int, int);
+static void vf_uart_term(struct uart_bas *bas);
+static void vf_uart_putc(struct uart_bas *bas, int);
+static int vf_uart_rxready(struct uart_bas *bas);
+static int vf_uart_getc(struct uart_bas *bas, struct mtx *);
+
+void uart_reinit(struct uart_softc *,int,int);
+
+static struct uart_ops uart_vybrid_ops = {
+ .probe = vf_uart_probe,
+ .init = vf_uart_init,
+ .term = vf_uart_term,
+ .putc = vf_uart_putc,
+ .rxready = vf_uart_rxready,
+ .getc = vf_uart_getc,
+};
+
+static int
+vf_uart_probe(struct uart_bas *bas)
+{
+
+ return (0);
+}
+
+static void
+vf_uart_init(struct uart_bas *bas, int baudrate, int databits,
+ int stopbits, int parity)
+{
+
+}
+
+static void
+vf_uart_term(struct uart_bas *bas)
+{
+
+}
+
+static void
+vf_uart_putc(struct uart_bas *bas, int c)
+{
+
+ while (!(uart_getreg(bas, UART_S1) & UART_S1_TDRE))
+ ;
+
+ uart_setreg(bas, UART_D, c);
+}
+
+static int
+vf_uart_rxready(struct uart_bas *bas)
+{
+ int usr1;
+
+ usr1 = uart_getreg(bas, UART_S1);
+ if (usr1 & UART_S1_RDRF) {
+ return (1);
+ }
+
+ return (0);
+}
+
+static int
+vf_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+ int c;
+
+ uart_lock(hwmtx);
+
+ while (!(uart_getreg(bas, UART_S1) & UART_S1_RDRF))
+ ;
+
+ c = uart_getreg(bas, UART_D);
+ uart_unlock(hwmtx);
+
+ return (c & 0xff);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct vf_uart_softc {
+ struct uart_softc base;
+};
+
+void
+uart_reinit(struct uart_softc *sc, int clkspeed, int baud)
+{
+ struct uart_bas *bas;
+ int sbr;
+ int brfa;
+ int reg;
+
+ bas = &sc->sc_bas;
+ if (!bas) {
+ printf("Error: cant reconfigure bas\n");
+ return;
+ }
+
+ uart_setreg(bas, UART_MODEM, 0x00);
+
+ /*
+ * Disable transmitter and receiver
+ * for a while.
+ */
+ reg = uart_getreg(bas, UART_C2);
+ reg &= ~(UART_C2_RE | UART_C2_TE);
+ uart_setreg(bas, UART_C2, 0x00);
+
+ uart_setreg(bas, UART_C1, 0x00);
+
+ sbr = (uint16_t) (clkspeed / (baud * 16));
+ brfa = (clkspeed / baud) - (sbr * 16);
+
+ reg = uart_getreg(bas, UART_BDH);
+ reg &= ~UART_BDH_SBR;
+ reg |= ((sbr & 0x1f00) >> 8);
+ uart_setreg(bas, UART_BDH, reg);
+
+ reg = sbr & 0x00ff;
+ uart_setreg(bas, UART_BDL, reg);
+
+ reg = uart_getreg(bas, UART_C4);
+ reg &= ~UART_C4_BRFA;
+ reg |= (brfa & UART_C4_BRFA);
+ uart_setreg(bas, UART_C4, reg);
+
+ reg = uart_getreg(bas, UART_C2);
+ reg |= (UART_C2_RE | UART_C2_TE);
+ uart_setreg(bas, UART_C2, reg);
+
+}
+
+static int vf_uart_bus_attach(struct uart_softc *);
+static int vf_uart_bus_detach(struct uart_softc *);
+static int vf_uart_bus_flush(struct uart_softc *, int);
+static int vf_uart_bus_getsig(struct uart_softc *);
+static int vf_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int vf_uart_bus_ipend(struct uart_softc *);
+static int vf_uart_bus_param(struct uart_softc *, int, int, int, int);
+static int vf_uart_bus_probe(struct uart_softc *);
+static int vf_uart_bus_receive(struct uart_softc *);
+static int vf_uart_bus_setsig(struct uart_softc *, int);
+static int vf_uart_bus_transmit(struct uart_softc *);
+
+static kobj_method_t vf_uart_methods[] = {
+ KOBJMETHOD(uart_attach, vf_uart_bus_attach),
+ KOBJMETHOD(uart_detach, vf_uart_bus_detach),
+ KOBJMETHOD(uart_flush, vf_uart_bus_flush),
+ KOBJMETHOD(uart_getsig, vf_uart_bus_getsig),
+ KOBJMETHOD(uart_ioctl, vf_uart_bus_ioctl),
+ KOBJMETHOD(uart_ipend, vf_uart_bus_ipend),
+ KOBJMETHOD(uart_param, vf_uart_bus_param),
+ KOBJMETHOD(uart_probe, vf_uart_bus_probe),
+ KOBJMETHOD(uart_receive, vf_uart_bus_receive),
+ KOBJMETHOD(uart_setsig, vf_uart_bus_setsig),
+ KOBJMETHOD(uart_transmit, vf_uart_bus_transmit),
+ { 0, 0 }
+};
+
+struct uart_class uart_vybrid_class = {
+ "vybrid",
+ vf_uart_methods,
+ sizeof(struct vf_uart_softc),
+ .uc_ops = &uart_vybrid_ops,
+ .uc_range = 0x100,
+ .uc_rclk = 24000000 /* TODO: get value from CCM */
+};
+
+static int
+vf_uart_bus_attach(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ int reg;
+
+ bas = &sc->sc_bas;
+
+ sc->sc_hwiflow = 0;
+ sc->sc_hwoflow = 0;
+
+ uart_reinit(sc, 66000000, 115200);
+
+ reg = uart_getreg(bas, UART_C2);
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+ reg &= ~UART_C2_RIE;
+ } else {
+ reg |= UART_C2_RIE;
+ }
+ uart_setreg(bas, UART_C2, reg);
+
+ return (0);
+}
+
+static int
+vf_uart_bus_detach(struct uart_softc *sc)
+{
+
+ /* TODO */
+ return (0);
+}
+
+static int
+vf_uart_bus_flush(struct uart_softc *sc, int what)
+{
+
+ /* TODO */
+ return (0);
+}
+
+static int
+vf_uart_bus_getsig(struct uart_softc *sc)
+{
+
+ /* TODO */
+ return (0);
+}
+
+static int
+vf_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+ struct uart_bas *bas;
+ int error;
+
+ bas = &sc->sc_bas;
+ error = 0;
+ uart_lock(sc->sc_hwmtx);
+ switch (request) {
+ case UART_IOCTL_BREAK:
+ /* TODO */
+ break;
+ case UART_IOCTL_BAUD:
+ /* TODO */
+ *(int*)data = 115200;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ uart_unlock(sc->sc_hwmtx);
+
+ return (error);
+}
+
+static int
+vf_uart_bus_ipend(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ int ipend;
+ uint32_t usr1, usr2;
+ int reg;
+ int sfifo;
+
+ bas = &sc->sc_bas;
+ ipend = 0;
+
+ uart_lock(sc->sc_hwmtx);
+
+ usr1 = uart_getreg(bas, UART_S1);
+ usr2 = uart_getreg(bas, UART_S2);
+ sfifo = uart_getreg(bas, UART_SFIFO);
+
+ /* ack usr2 */
+ uart_setreg(bas, UART_S2, usr2);
+
+ if (usr1 & UART_S1_TDRE) {
+ reg = uart_getreg(bas, UART_C2);
+ reg &= ~(UART_C2_TIE);
+ uart_setreg(bas, UART_C2, reg);
+
+ if (sc->sc_txbusy != 0) {
+ ipend |= SER_INT_TXIDLE;
+ }
+ }
+
+ if (usr1 & UART_S1_RDRF) {
+ reg = uart_getreg(bas, UART_C2);
+ reg &= ~(UART_C2_RIE);
+ uart_setreg(bas, UART_C2, reg);
+
+ ipend |= SER_INT_RXREADY;
+ }
+
+ if (usr2 & UART_S2_LBKDIF) {
+ ipend |= SER_INT_BREAK;
+ }
+
+ uart_unlock(sc->sc_hwmtx);
+
+ return (ipend);
+}
+
+static int
+vf_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
+ int stopbits, int parity)
+{
+
+ uart_lock(sc->sc_hwmtx);
+ vf_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity);
+ uart_unlock(sc->sc_hwmtx);
+
+ return (0);
+}
+
+static int
+vf_uart_bus_probe(struct uart_softc *sc)
+{
+ int error;
+
+ error = vf_uart_probe(&sc->sc_bas);
+ if (error)
+ return (error);
+
+ sc->sc_rxfifosz = 1;
+ sc->sc_txfifosz = 1;
+
+ device_set_desc(sc->sc_dev, "Vybrid Family UART");
+ return (0);
+}
+
+static int
+vf_uart_bus_receive(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ int reg;
+ int c;
+
+ bas = &sc->sc_bas;
+ uart_lock(sc->sc_hwmtx);
+
+ /* Read FIFO */
+ while (uart_getreg(bas, UART_S1) & UART_S1_RDRF) {
+ if (uart_rx_full(sc)) {
+ /* No space left in input buffer */
+ sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+ break;
+ }
+
+ c = uart_getreg(bas, UART_D);
+ uart_rx_put(sc, c);
+ }
+
+ /* Reenable Data Ready interrupt */
+ reg = uart_getreg(bas, UART_C2);
+ reg |= (UART_C2_RIE);
+ uart_setreg(bas, UART_C2, reg);
+
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+}
+
+static int
+vf_uart_bus_setsig(struct uart_softc *sc, int sig)
+{
+ struct uart_bas *bas;
+ int reg;
+
+ /* TODO: implement (?) */
+
+ /* XXX workaround to have working console on mount prompt */
+ /* Enable RX interrupt */
+ bas = &sc->sc_bas;
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+ reg = uart_getreg(bas, UART_C2);
+ reg |= (UART_C2_RIE);
+ uart_setreg(bas, UART_C2, reg);
+ }
+
+ return (0);
+}
+
+static int
+vf_uart_bus_transmit(struct uart_softc *sc)
+{
+ struct uart_bas *bas = &sc->sc_bas;
+ int i;
+ int reg;
+
+ bas = &sc->sc_bas;
+ uart_lock(sc->sc_hwmtx);
+
+ /* Fill TX FIFO */
+ for (i = 0; i < sc->sc_txdatasz; i++) {
+ uart_setreg(bas, UART_D, sc->sc_txbuf[i] & 0xff);
+ uart_barrier(&sc->sc_bas);
+ }
+
+ sc->sc_txbusy = 1;
+
+ /* Call me when ready */
+ reg = uart_getreg(bas, UART_C2);
+ reg |= (UART_C2_TIE);
+ uart_setreg(bas, UART_C2, reg);
+
+ uart_unlock(sc->sc_hwmtx);
+
+ return (0);
+}
diff --git a/sys/boot/fdt/dts/digi-ccwmx53.dts b/sys/boot/fdt/dts/digi-ccwmx53.dts
index f89c0d0..898ffbb 100644
--- a/sys/boot/fdt/dts/digi-ccwmx53.dts
+++ b/sys/boot/fdt/dts/digi-ccwmx53.dts
@@ -101,6 +101,10 @@
};
};
aips@60000000 {
+ ethernet@63fec000 {
+ status = "okay";
+ phy-mode = "rmii";
+ };
i2c@63fc4000 {
status = "okay";
};
diff --git a/sys/boot/fdt/dts/rk3188-radxa.dts b/sys/boot/fdt/dts/rk3188-radxa.dts
new file mode 100644
index 0000000..7fc8ec5
--- /dev/null
+++ b/sys/boot/fdt/dts/rk3188-radxa.dts
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$
+ */
+
+/dts-v1/;
+
+/include/ "rk3188.dtsi"
+
+/ {
+ model = "Radxa RadxaRock";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x60000000 0x80000000 >; /* 2GB RAM */
+ };
+
+ aliases {
+ soc = &SOC;
+ };
+
+ SOC: rk3188 {
+
+ uart2: serial@20064000 {
+ status = "okay";
+ };
+
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = &uart2;
+ stdout = &uart2;
+ };
+};
+
diff --git a/sys/boot/fdt/dts/rk3188.dtsi b/sys/boot/fdt/dts/rk3188.dtsi
new file mode 100644
index 0000000..2efa678
--- /dev/null
+++ b/sys/boot/fdt/dts/rk3188.dtsi
@@ -0,0 +1,251 @@
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$
+ */
+
+/ {
+ compatible = "rockchip,rk3188";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &SOC;
+ };
+
+ SOC: rk3188 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ GIC: interrupt-controller@1013d000 {
+ compatible = "arm,gic";
+ reg = <0x1013d000 0x1000>, /* Distributor Registers */
+ <0x1013c100 0x0100>; /* CPU Interface Registers */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ pmu@20004000 {
+ compatible = "rockchip,rk30xx-pmu";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x20004000 0x100>;
+ };
+
+ grf@20008000 {
+ compatible = "rockchip,rk30xx-grf";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = < 0x20008000 0x2000 >;
+ };
+
+ mp_tmr@1013c600 {
+ compatible = "arm,mpcore-timers";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = < 148500000 >;
+ reg = <0x1013c200 0x100>, /* Global Timer Regs */
+ <0x1013c600 0x20>; /* Private Timer Regs */
+ interrupts = < 27 29 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ timer@20038000 {
+ compatible = "rockchip,rk30xx-timer";
+ compatible = "rockchip,rk3188-dw-apb-timer-osc";
+ reg = <0x20038000 0x20>;
+ interrupts = <76>;
+ clocks = <24000000>;
+ status = "disabled";
+ };
+
+ timer@20038020 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x20038020 0x20>;
+ interrupts = <77>;
+ clocks = <24000000>;
+ status = "disabled";
+ };
+
+ timer@20038060 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x20038060 0x20>;
+ interrupts = <91>;
+ clocks = <24000000>;
+ status = "disabled";
+ };
+
+ timer@20038080 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x20038080 0x20>;
+ interrupts = <92>;
+ clocks = <24000000>;
+ status = "disabled";
+ };
+
+ timer@200380a0 {
+ compatible = "rockchip,rk30xx-timer";
+ reg = <0x200380a0 0x20>;
+ interrupts = <96>;
+ clocks = <24000000>;
+ status = "disabled";
+ };
+
+ watchdog@2004c000 {
+ compatible = "rockchip,rk30xx-wdt";
+ reg = <0x2004c000 0x100>;
+ };
+
+ gpio0: gpio@2000a000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2000a000 0x100>;
+ interrupts = <86>;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio1: gpio@2003c000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2003c000 0x100>;
+ interrupts = <87>;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio2: gpio@2003e000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x2003e000 0x100>;
+ interrupts = <88>;
+ interrupt-parent = <&GIC>;
+ };
+
+ gpio3: gpio@20080000 {
+ compatible = "rockchip,rk30xx-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x20080000 0x100>;
+ interrupts = <89>;
+ interrupt-parent = <&GIC>;
+ };
+
+ usb0: usb@10180000 {
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <48>;
+ interrupt-parent = <&GIC>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usb1: usb@101c0000 {
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0x101c0000 0x40000>;
+ interrupts = < 49 >;
+ interrupt-parent = <&GIC>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ uart0: serial@10124000 {
+ compatible = "ns16550";
+ reg = <0x10124000 0x400>;
+ reg-shift = <2>;
+ interrupts = <66>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ busy-detect = <1>;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ uart1: serial@10126000 {
+ compatible = "ns16550";
+ reg = <0x10126000 0x400>;
+ reg-shift = <2>;
+ interrupts = <67>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ busy-detect = <1>;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ uart2: serial@20064000 {
+ compatible = "ns16550";
+ reg = <0x20064000 0x400>;
+ reg-shift = <2>;
+ interrupts = <68>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ busy-detect = <1>;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ uart3: serial@20068000 {
+ compatible = "ns16550";
+ reg = <0x20068000 0x400>;
+ reg-shift = <2>;
+ interrupts = <69>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ busy-detect = <1>;
+ broken-txfifo = <1>;
+ status = "disabled";
+ };
+
+ mmc@10214000 {
+ compatible = "rockchip,rk30xx-mmc";
+ reg = <0x10214000 0x1000>;
+ interrupts = <55>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <24000000>; /* TODO: verify freq */
+ status = "disabled";
+ };
+
+ mmc@10218000 {
+ compatible = "rockchip,rk30xx-mmc";
+ reg = <0x10218000 0x1000>;
+ interrupts = <56>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <24000000>; /* TODO: verify freq */
+ status = "disabled";
+ };
+ };
+};
+
diff --git a/sys/boot/fdt/dts/vybrid-cosmic.dts b/sys/boot/fdt/dts/vybrid-cosmic.dts
new file mode 100644
index 0000000..79b49f7
--- /dev/null
+++ b/sys/boot/fdt/dts/vybrid-cosmic.dts
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$
+ */
+
+/dts-v1/;
+
+/include/ "vybrid.dtsi"
+
+/ {
+ model = "Cosmic Board";
+
+ memory {
+ device_type = "memory";
+ reg = < 0x80000000 0x10000000 >; /* 256MB RAM */
+ };
+
+ SOC: vybrid {
+ serial0: serial@40027000 {
+ status = "disabled";
+ };
+
+ fec0: ethernet@400D0000 {
+ status = "disabled";
+ };
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "serial1";
+ stdout = "serial1";
+ };
+};
diff --git a/sys/boot/fdt/dts/vybrid.dtsi b/sys/boot/fdt/dts/vybrid.dtsi
new file mode 100644
index 0000000..004b1a1
--- /dev/null
+++ b/sys/boot/fdt/dts/vybrid.dtsi
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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$
+ */
+
+/ {
+ model = "Freescale Vybrid Family";
+ compatible = "freescale,vybrid", "fsl,vf";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ interrupt-parent = <&GIC>;
+
+ aliases {
+ soc = &SOC;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ src = &SRC;
+ };
+
+ SOC: vybrid {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+ bus-frequency = <0>;
+
+ SRC: src@4006E000 {
+ compatible = "fsl,mvf600-src";
+ reg = <0x4006E000 0x100>;
+ };
+
+ mscm@40001000 {
+ compatible = "fsl,mvf600-mscm";
+ reg = <0x40001000 0x1000>;
+ };
+
+ GIC: interrupt-controller@01c81000 {
+ compatible = "arm,gic";
+ reg = <0x40003000 0x1000>, /* Distributor Registers */
+ <0x40002100 0x100>; /* CPU Interface Registers */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ anadig@40050000 {
+ compatible = "fsl,mvf600-anadig";
+ reg = <0x40050000 0x300>;
+ };
+
+ ccm@4006b000 {
+ compatible = "fsl,mvf600-ccm";
+ reg = <0x4006b000 0x1000>;
+ };
+
+ mp_tmr@40002100 {
+ compatible = "arm,mpcore-timers";
+ clock-frequency = <133000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = < 0x40002200 0x100 >, /* Global Timer Registers */
+ < 0x40002600 0x100 >; /* Private Timer Registers */
+ interrupts = < 27 29 >;
+ interrupt-parent = < &GIC >;
+ };
+
+ pit@40037000 {
+ compatible = "fsl,mvf600-pit";
+ reg = <0x40037000 0x1000>;
+ interrupts = < 71 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 24000000 >;
+ };
+
+ lptmr@40040000 {
+ compatible = "fsl,mvf600-lptmr";
+ reg = <0x40040000 0x1000>;
+ interrupts = < 72 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = < 24000000 >;
+ };
+
+ iomuxc@40048000 {
+ compatible = "fsl,mvf600-iomuxc";
+ reg = <0x40048000 0x1000>;
+ };
+
+ gpio@400FF000 {
+ compatible = "fsl,mvf600-gpio";
+ reg = <0x400FF000 0x200>;
+ #gpio-cells = <3>;
+ gpio-controller;
+ interrupts = < 139 140 141 142 143 >;
+ interrupt-parent = <&GIC>;
+
+ };
+
+ nand@400E0000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mvf600-nand";
+ reg = <0x400E0000 0x10000>;
+ interrupts = < 115 >;
+ interrupt-parent = <&GIC>;
+
+ partition@40000 {
+ reg = <0x40000 0x200000>; /* 2MB */
+ label = "u-boot";
+ read-only;
+ };
+
+ partition@240000 {
+ reg = <0x240000 0x200000>; /* 2MB */
+ label = "test";
+ };
+
+ partition@440000 {
+ reg = <0x440000 0xa00000>; /* 10MB */
+ label = "kernel";
+ };
+
+ partition@e40000 {
+ reg = <0xe40000 0x1e000000>; /* 480MB */
+ label = "root";
+ };
+
+ };
+
+ sdhci0: sdhci@400B1000 {
+ compatible = "fsl,mvf600-sdhci";
+ reg = <0x400B1000 0x1000>;
+ interrupts = < 59 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = <50000000>;
+ };
+
+ sdhci1: sdhci@400B2000 {
+ compatible = "fsl,mvf600-sdhci";
+ reg = <0x400B2000 0x1000>;
+ interrupts = < 60 >;
+ interrupt-parent = <&GIC>;
+ clock-frequency = <50000000>;
+ };
+
+ serial0: serial@40027000 {
+ compatible = "fsl,mvf600-uart";
+ reg = <0x40027000 0x1000>;
+ interrupts = <93>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ };
+
+ serial1: serial@40028000 {
+ compatible = "fsl,mvf600-uart";
+ reg = <0x40028000 0x1000>;
+ interrupts = <94>;
+ interrupt-parent = <&GIC>;
+ current-speed = <115200>;
+ clock-frequency = < 24000000 >;
+ };
+
+ usb@40034000 {
+ compatible = "fsl,mvf600-usb-ehci", "usb-ehci";
+ reg = < 0x40034000 0x1000 >, /* ehci */
+ < 0x40035000 0x1000 >, /* usbc */
+ < 0x40050800 0x100 >; /* phy */
+ interrupts = < 107 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ usb@400b4000 {
+ compatible = "fsl,mvf600-usb-ehci", "usb-ehci";
+ reg = < 0x400b4000 0x1000 >, /* ehci */
+ < 0x400b5000 0x1000 >, /* usbc */
+ < 0x40050C00 0x100 >; /* phy */
+ interrupts = < 108 >;
+ interrupt-parent = <&GIC>;
+ };
+
+ fec0: ethernet@400D0000 {
+ compatible = "fsl,mvf600-fec";
+ reg = <0x400D0000 0x1000>;
+ interrupts = < 110 >;
+ interrupt-parent = <&GIC>;
+ phy-mode = "rmii";
+ phy-disable-preamble;
+ };
+
+ fec1: ethernet@400D1000 {
+ compatible = "fsl,mvf600-fec";
+ reg = <0x400D1000 0x1000>;
+ interrupts = < 111 >;
+ interrupt-parent = <&GIC>;
+ phy-mode = "rmii";
+ phy-disable-preamble;
+ };
+
+ };
+};
diff --git a/sys/dev/uart/uart.h b/sys/dev/uart/uart.h
index 095d368..4874488 100644
--- a/sys/dev/uart/uart.h
+++ b/sys/dev/uart/uart.h
@@ -75,6 +75,7 @@ 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));
extern struct uart_class uart_ti8250_class __attribute__((weak));
+extern struct uart_class uart_vybrid_class __attribute__((weak));
#ifdef FDT
struct ofw_compat_data;
diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c
index 5a0ebd7..a98c50a 100644
--- a/sys/dev/uart/uart_bus_fdt.c
+++ b/sys/dev/uart/uart_bus_fdt.c
@@ -80,6 +80,7 @@ static struct ofw_compat_data compat_data[] = {
{"fsl,imx27-uart", (uintptr_t)&uart_imx_class},
{"fsl,imx25-uart", (uintptr_t)&uart_imx_class},
{"fsl,imx21-uart", (uintptr_t)&uart_imx_class},
+ {"fsl,mvf600-uart", (uintptr_t)&uart_vybrid_class},
{"lpc,uart", (uintptr_t)&uart_lpc_class},
{"ti,ns16550", (uintptr_t)&uart_ti8250_class},
{"ns16550", (uintptr_t)&uart_ns8250_class},
diff --git a/sys/arm/broadcom/bcm2835/dwc_otg_brcm.c b/sys/dev/usb/controller/dwc_otg_fdt.c
index ac7a18d..ac7a18d 100644
--- a/sys/arm/broadcom/bcm2835/dwc_otg_brcm.c
+++ b/sys/dev/usb/controller/dwc_otg_fdt.c
OpenPOWER on IntegriCloud