summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorray <ray@FreeBSD.org>2013-03-20 15:39:27 +0000
committerray <ray@FreeBSD.org>2013-03-20 15:39:27 +0000
commita88f1a3d131b117c073d9babaa2cf03d4b2d232a (patch)
treef1b419d2a4a76881f82969c1ddfa46ffb1e62836
parent1ba62d29d15f003883f84f1d20496240d9eda819 (diff)
downloadFreeBSD-src-a88f1a3d131b117c073d9babaa2cf03d4b2d232a.zip
FreeBSD-src-a88f1a3d131b117c073d9babaa2cf03d4b2d232a.tar.gz
Integrate Efika MX project back to home.
Sponsored by: The FreeBSD Foundation
-rw-r--r--sys/arm/conf/EFIKA_MX177
-rw-r--r--sys/arm/freescale/imx/bus_space.c130
-rw-r--r--sys/arm/freescale/imx/common.c75
-rw-r--r--sys/arm/freescale/imx/console.c164
-rw-r--r--sys/arm/freescale/imx/i2c.c492
-rw-r--r--sys/arm/freescale/imx/imx.files51
-rw-r--r--sys/arm/freescale/imx/imx51_ccm.c474
-rw-r--r--sys/arm/freescale/imx/imx51_ccmreg.h250
-rw-r--r--sys/arm/freescale/imx/imx51_ccmvar.h110
-rw-r--r--sys/arm/freescale/imx/imx51_dpllreg.h105
-rw-r--r--sys/arm/freescale/imx/imx51_gpio.c481
-rw-r--r--sys/arm/freescale/imx/imx51_iomux.c232
-rw-r--r--sys/arm/freescale/imx/imx51_iomuxreg.h761
-rw-r--r--sys/arm/freescale/imx/imx51_iomuxvar.h45
-rw-r--r--sys/arm/freescale/imx/imx51_ipuv3.c876
-rw-r--r--sys/arm/freescale/imx/imx51_ipuv3reg.h919
-rw-r--r--sys/arm/freescale/imx/imx51_sdmareg.h142
-rw-r--r--sys/arm/freescale/imx/imx51_ssireg.h180
-rw-r--r--sys/arm/freescale/imx/imx51_tzicreg.h85
-rw-r--r--sys/arm/freescale/imx/imx_gpt.c370
-rw-r--r--sys/arm/freescale/imx/imx_gptreg.h96
-rw-r--r--sys/arm/freescale/imx/imx_gptvar.h50
-rw-r--r--sys/arm/freescale/imx/imx_machdep.c142
-rw-r--r--sys/arm/freescale/imx/imx_wdog.c163
-rw-r--r--sys/arm/freescale/imx/imx_wdogreg.h65
-rw-r--r--sys/arm/freescale/imx/std.imx15
-rw-r--r--sys/arm/freescale/imx/tzic.c187
-rw-r--r--sys/boot/fdt/dts/efikamx.dts122
-rw-r--r--sys/boot/fdt/dts/imx51x.dtsi590
-rw-r--r--sys/dev/ata/chipsets/ata-fsl.c238
-rw-r--r--sys/dev/uart/uart.h1
-rw-r--r--sys/dev/uart/uart_bus_fdt.c4
-rw-r--r--sys/dev/uart/uart_dev_imx.c436
-rw-r--r--sys/dev/uart/uart_dev_imx5xx.h222
-rw-r--r--sys/dev/usb/controller/ehci_imx.c282
35 files changed, 8732 insertions, 0 deletions
diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX
new file mode 100644
index 0000000..75e2943
--- /dev/null
+++ b/sys/arm/conf/EFIKA_MX
@@ -0,0 +1,177 @@
+# Kernel configuration for Efika MX Smarttop/Smartbook boards
+#
+# 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 EFIKA_MX
+
+include "../freescale/imx/std.imx"
+
+makeoptions WITHOUT_MODULES="ahc"
+
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+#options DEBUG
+
+options SCHED_4BSD # 4BSD scheduler
+#options PREEMPTION # Enable kernel thread preemption
+options INET # InterNETworking
+#options INET6 # IPv6 communications protocols
+#options SCTP # Stream Control Transmission Protocol
+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 UFS_GJOURNAL # Enable gjournal-based UFS journaling
+#options MD_ROOT # MD is a potential root device
+options NFSCL # New Network Filesystem Client
+#options NFSD # New Network Filesystem Server
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+#options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # TMP Memory Filesystem
+options GEOM_PART_GPT # GUID Partition Tables.
+options GEOM_LABEL # Provides labelization
+#options COMPAT_FREEBSD5 # Compatible with FreeBSD5
+#options COMPAT_FREEBSD6 # Compatible with FreeBSD6
+#options COMPAT_FREEBSD7 # Compatible with FreeBSD7
+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 INCLUDE_CONFIG_FILE # Include this file in kernel
+
+# required for netbooting
+#options BOOTP
+#options BOOTP_COMPAT
+#options BOOTP_NFSROOT
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ue0
+#
+options ROOTDEVNAME=\"ufs:ada0s2a\"
+
+
+# kernel/memory size reduction
+#options MUTEX_NOINLINE
+#options NO_FFS_SNAPSHOT
+#options NO_SWAPPING
+#options NO_SYSCTL_DESCR
+#options RWLOCK_NOINLINE
+
+# Debugging support. Always need this:
+options KDB # Enable kernel debugger support.
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic.
+# For full debugger support use this instead:
+options DDB # Support DDB.
+#options GDB # Support remote GDB.
+options DEADLKRES # Enable the deadlock resolver
+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
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device bpf # Berkeley packet filter
+
+# Pseudo devices.
+device loop # Network loopback
+device random # Entropy device
+device ether # Ethernet support
+#device vlan # 802.1Q VLAN support
+#device tun # Packet tunnel.
+#device md # Memory "disks"
+#device gif # IPv6 and IPv4 tunneling
+#device faith # IPv6-to-IPv4 relaying (translation)
+#device firmware # firmware assist module
+
+# Serial (COM) ports
+device uart # Multi-uart driver
+options ALT_BREAK_TO_DEBUGGER
+
+device ata
+device atapci # Only for helper functions
+device imxata
+options ATA_CAM
+options ATA_STATIC_ID # Static device numbering
+
+device iomux # IO Multiplexor
+
+device gpio
+device gpioled
+
+device fsliic
+device iic
+device iicbus
+
+# SCSI peripherals
+device scbus # SCSI bus (required for SCSI)
+device da # Direct Access (disks)
+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"
+device u3g
+
+# USB Ethernet, requires miibus
+device miibus
+device aue # ADMtek USB Ethernet
+device axe # ASIX Electronics USB Ethernet
+device cdce # Generic USB over Ethernet
+device cue # CATC USB Ethernet
+device kue # Kawasaki LSI USB Ethernet
+device rue # RealTek RTL8150 USB Ethernet
+device udav # Davicom DM9601E USB
+
+# USB Wireless
+device rum # Ralink Technology RT2501USB wireless NICs
+
+# Watchdog timer.
+# WARNING: can't be disabled!!!
+device imxwdt # Watchdog
+
+# Wireless NIC cards
+device wlan # 802.11 support
+device wlan_wep # 802.11 WEP support
+device wlan_ccmp # 802.11 CCMP support
+device wlan_tkip # 802.11 TKIP support
+device wlan_amrr # AMRR transmit rate control algorithm
+
+# Flattened Device Tree
+options FDT
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=efikamx.dts
+
+# NOTE: serial console will be disabled if syscons enabled
+# Uncomment following lines for framebuffer/syscons support
+device sc
+device kbdmux
+options SC_DFLT_FONT # compile font in
+makeoptions SC_DFLT_FONT=cp437
+device ukbd # Allow keyboard like HIDs to control console
+
+device ums
diff --git a/sys/arm/freescale/imx/bus_space.c b/sys/arm/freescale/imx/bus_space.c
new file mode 100644
index 0000000..6d92f45
--- /dev/null
+++ b/sys/arm/freescale/imx/bus_space.c
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (C) 2012 FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Tymoshenko under sponsorship
+ * from the FreeBSD Foundation.
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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 <sys/malloc.h>
+
+#include <machine/bus.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(generic);
+bs_protos(generic_armv4);
+
+struct bus_space _base_tag = {
+ /* cookie */
+ .bs_cookie = (void *) 0,
+
+ /* mapping/unmapping */
+ .bs_map = generic_bs_map,
+ .bs_unmap = generic_bs_unmap,
+ .bs_subregion = generic_bs_subregion,
+
+ /* allocation/deallocation */
+ .bs_alloc = generic_bs_alloc,
+ .bs_free = generic_bs_free,
+
+ /* barrier */
+ .bs_barrier = generic_bs_barrier,
+
+ /* read (single) */
+ .bs_r_1 = generic_bs_r_1,
+ .bs_r_2 = generic_armv4_bs_r_2,
+ .bs_r_4 = generic_bs_r_4,
+ .bs_r_8 = NULL,
+
+ /* read multiple */
+ .bs_rm_1 = generic_bs_rm_1,
+ .bs_rm_2 = generic_armv4_bs_rm_2,
+ .bs_rm_4 = generic_bs_rm_4,
+ .bs_rm_8 = NULL,
+
+ /* read region */
+ .bs_rr_1 = generic_bs_rr_1,
+ .bs_rr_2 = generic_armv4_bs_rr_2,
+ .bs_rr_4 = generic_bs_rr_4,
+ .bs_rr_8 = NULL,
+
+ /* write (single) */
+ .bs_w_1 = generic_bs_w_1,
+ .bs_w_2 = generic_armv4_bs_w_2,
+ .bs_w_4 = generic_bs_w_4,
+ .bs_w_8 = NULL,
+
+ /* write multiple */
+ .bs_wm_1 = generic_bs_wm_1,
+ .bs_wm_2 = generic_armv4_bs_wm_2,
+ .bs_wm_4 = generic_bs_wm_4,
+ .bs_wm_8 = NULL,
+
+ /* write region */
+ .bs_wr_1 = generic_bs_wr_1,
+ .bs_wr_2 = generic_armv4_bs_wr_2,
+ .bs_wr_4 = generic_bs_wr_4,
+ .bs_wr_8 = NULL,
+
+ /* read multiple stream */
+ .bs_rm_1_s = generic_bs_rm_1,
+ .bs_rm_2_s = generic_armv4_bs_rm_2,
+ .bs_rm_4_s = generic_bs_rm_4,
+ .bs_rm_8_s = NULL,
+
+ /* write multiple stream */
+ .bs_wm_1_s = generic_bs_wm_1,
+ .bs_wm_2_s = generic_armv4_bs_wm_2,
+ .bs_wm_4_s = generic_bs_wm_4,
+ .bs_wm_8_s = NULL,
+
+ /* set multiple */
+ /* XXX not implemented */
+
+ /* set region */
+ .bs_sr_1 = NULL,
+ .bs_sr_2 = generic_armv4_bs_sr_2,
+ .bs_sr_4 = generic_bs_sr_4,
+ .bs_sr_8 = NULL,
+
+ /* copy */
+ .bs_c_1 = NULL,
+ .bs_c_2 = generic_armv4_bs_c_2,
+ .bs_c_4 = NULL,
+ .bs_c_8 = NULL,
+};
+
+bus_space_tag_t fdtbus_bs_tag = &_base_tag;
diff --git a/sys/arm/freescale/imx/common.c b/sys/arm/freescale/imx/common.c
new file mode 100644
index 0000000..cf0f974
--- /dev/null
+++ b/sys/arm/freescale/imx/common.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+ { NULL, NULL }
+};
+
+static int
+fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+ int *pol)
+{
+
+ *interrupt = fdt32_to_cpu(intr[0]);
+ *trig = INTR_TRIGGER_CONFORM;
+ *pol = INTR_POLARITY_CONFORM;
+
+ return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+ &fdt_intc_decode_ic,
+ NULL
+};
diff --git a/sys/arm/freescale/imx/console.c b/sys/arm/freescale/imx/console.c
new file mode 100644
index 0000000..c1b7dee
--- /dev/null
+++ b/sys/arm/freescale/imx/console.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+/* Simple UART console driver for Freescale i.MX515 */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/cons.h>
+#include <sys/consio.h>
+#include <sys/kernel.h>
+
+/* Allow it to be predefined, to be able to use another UART for console */
+#ifndef IMX_UART_BASE
+#define IMX_UART_BASE 0xe3fbc000 /* UART1 */
+#endif
+
+#define IMX_RXD (u_int32_t *)(IMX_UART_BASE + 0x00)
+#define IMX_TXD (u_int32_t *)(IMX_UART_BASE + 0x40)
+
+#define IMX_UFCR (u_int32_t *)(IMX_UART_BASE + 0x90)
+#define IMX_USR1 (u_int32_t *)(IMX_UART_BASE + 0x94)
+#define IMX_USR1_TRDY (1 << 13)
+
+#define IMX_USR2 (u_int32_t *)(IMX_UART_BASE + 0x98)
+#define IMX_USR2_RDR (1 << 0)
+#define IMX_USR2_TXFE (1 << 14)
+#define IMX_USR2_TXDC (1 << 3)
+
+#define IMX_UTS (u_int32_t *)(IMX_UART_BASE + 0xb4)
+#define IMX_UTS_TXFULL (1 << 4)
+
+/*
+ * uart related funcs
+ */
+static u_int32_t
+uart_getreg(u_int32_t *bas)
+{
+
+ return *((volatile u_int32_t *)(bas)) & 0xff;
+}
+
+static void
+uart_setreg(u_int32_t *bas, u_int32_t val)
+{
+
+ *((volatile u_int32_t *)(bas)) = (u_int32_t)val;
+}
+
+static int
+ub_tstc(void)
+{
+
+ return ((uart_getreg(IMX_USR2) & IMX_USR2_RDR) ? 1 : 0);
+}
+
+static int
+ub_getc(void)
+{
+
+ while (!ub_tstc());
+ __asm __volatile("nop");
+
+ return (uart_getreg(IMX_RXD) & 0xff);
+}
+
+static void
+ub_putc(unsigned char c)
+{
+
+ if (c == '\n')
+ ub_putc('\r');
+
+ while (uart_getreg(IMX_UTS) & IMX_UTS_TXFULL)
+ __asm __volatile("nop");
+
+ uart_setreg(IMX_TXD, c);
+}
+
+static cn_probe_t uart_cnprobe;
+static cn_init_t uart_cninit;
+static cn_term_t uart_cnterm;
+static cn_getc_t uart_cngetc;
+static cn_putc_t uart_cnputc;
+static cn_grab_t uart_cngrab;
+static cn_ungrab_t uart_cnungrab;
+
+static void
+uart_cngrab(struct consdev *cp)
+{
+
+}
+
+static void
+uart_cnungrab(struct consdev *cp)
+{
+
+}
+
+
+static void
+uart_cnprobe(struct consdev *cp)
+{
+
+ sprintf(cp->cn_name, "uart");
+ cp->cn_pri = CN_NORMAL;
+}
+
+static void
+uart_cninit(struct consdev *cp)
+{
+ uart_setreg(IMX_UFCR, 0x00004210);
+}
+
+void
+uart_cnputc(struct consdev *cp, int c)
+{
+
+ ub_putc(c);
+}
+
+int
+uart_cngetc(struct consdev * cp)
+{
+
+ return ub_getc();
+}
+
+static void
+uart_cnterm(struct consdev * cp)
+{
+
+}
+
+CONSOLE_DRIVER(uart);
diff --git a/sys/arm/freescale/imx/i2c.c b/sys/arm/freescale/imx/i2c.c
new file mode 100644
index 0000000..91e2083
--- /dev/null
+++ b/sys/arm/freescale/imx/i2c.c
@@ -0,0 +1,492 @@
+/*-
+ * Copyright (C) 2008-2009 Semihalf, Michal Hajduk
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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 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 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 <sys/module.h>
+#include <sys/resource.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+#include "iicbus_if.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>
+
+#define I2C_ADDR_REG 0x00 /* I2C slave address register */
+#define I2C_FDR_REG 0x04 /* I2C frequency divider register */
+#define I2C_CONTROL_REG 0x08 /* I2C control register */
+#define I2C_STATUS_REG 0x0C /* I2C status register */
+#define I2C_DATA_REG 0x10 /* I2C data register */
+#define I2C_DFSRR_REG 0x14 /* I2C Digital Filter Sampling rate */
+
+#define I2CCR_MEN (1 << 7) /* Module enable */
+#define I2CCR_MSTA (1 << 5) /* Master/slave mode */
+#define I2CCR_MTX (1 << 4) /* Transmit/receive mode */
+#define I2CCR_TXAK (1 << 3) /* Transfer acknowledge */
+#define I2CCR_RSTA (1 << 2) /* Repeated START */
+
+#define I2CSR_MCF (1 << 7) /* Data transfer */
+#define I2CSR_MASS (1 << 6) /* Addressed as a slave */
+#define I2CSR_MBB (1 << 5) /* Bus busy */
+#define I2CSR_MAL (1 << 4) /* Arbitration lost */
+#define I2CSR_SRW (1 << 2) /* Slave read/write */
+#define I2CSR_MIF (1 << 1) /* Module interrupt */
+#define I2CSR_RXAK (1 << 0) /* Received acknowledge */
+
+#define I2C_BAUD_RATE_FAST 0x31
+#define I2C_BAUD_RATE_DEF 0x3F
+#define I2C_DFSSR_DIV 0x10
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
+ printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+struct i2c_softc {
+ device_t dev;
+ device_t iicbus;
+ struct resource *res;
+ struct mtx mutex;
+ int rid;
+ bus_space_handle_t bsh;
+ bus_space_tag_t bst;
+};
+
+static phandle_t i2c_get_node(device_t, device_t);
+static int i2c_probe(device_t);
+static int i2c_attach(device_t);
+
+static int i2c_repeated_start(device_t, u_char, int);
+static int i2c_start(device_t, u_char, int);
+static int i2c_stop(device_t);
+static int i2c_reset(device_t, u_char, u_char, u_char *);
+static int i2c_read(device_t, char *, int, int *, int, int);
+static int i2c_write(device_t, const char *, int, int *, int);
+
+static device_method_t i2c_methods[] = {
+ DEVMETHOD(device_probe, i2c_probe),
+ DEVMETHOD(device_attach, i2c_attach),
+
+ /* OFW methods */
+ DEVMETHOD(ofw_bus_get_node, i2c_get_node),
+
+ DEVMETHOD(iicbus_callback, iicbus_null_callback),
+ DEVMETHOD(iicbus_repeated_start, i2c_repeated_start),
+ DEVMETHOD(iicbus_start, i2c_start),
+ DEVMETHOD(iicbus_stop, i2c_stop),
+ DEVMETHOD(iicbus_reset, i2c_reset),
+ DEVMETHOD(iicbus_read, i2c_read),
+ DEVMETHOD(iicbus_write, i2c_write),
+ DEVMETHOD(iicbus_transfer, iicbus_transfer_gen),
+
+ { 0, 0 }
+};
+
+static driver_t i2c_driver = {
+ "iichb",
+ i2c_methods,
+ sizeof(struct i2c_softc),
+};
+static devclass_t i2c_devclass;
+
+DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
+DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);
+
+static phandle_t
+i2c_get_node(device_t bus, device_t dev)
+{
+ /*
+ * Share controller node with iicbus device
+ */
+ return ofw_bus_get_node(bus);
+}
+
+static __inline void
+i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val)
+{
+
+ bus_space_write_1(sc->bst, sc->bsh, off, val);
+}
+
+static __inline uint8_t
+i2c_read_reg(struct i2c_softc *sc, bus_size_t off)
+{
+
+ return (bus_space_read_1(sc->bst, sc->bsh, off));
+}
+
+static __inline void
+i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask)
+{
+ uint8_t status;
+
+ status = i2c_read_reg(sc, off);
+ status |= mask;
+ i2c_write_reg(sc, off, status);
+}
+
+/* Wait for transfer interrupt flag */
+static int
+wait_for_iif(struct i2c_softc *sc)
+{
+ int retry;
+
+ retry = 1000;
+ while (retry --) {
+ if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MIF)
+ return (IIC_NOERR);
+ DELAY(10);
+ }
+
+ return (IIC_ETIMEOUT);
+}
+
+/* Wait for free bus */
+static int
+wait_for_nibb(struct i2c_softc *sc)
+{
+ int retry;
+
+ retry = 1000;
+ while (retry --) {
+ if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0)
+ return (IIC_NOERR);
+ DELAY(10);
+ }
+
+ return (IIC_ETIMEOUT);
+}
+
+/* Wait for transfer complete+interrupt flag */
+static int
+wait_for_icf(struct i2c_softc *sc)
+{
+ int retry;
+
+ retry = 1000;
+ while (retry --) {
+
+ if ((i2c_read_reg(sc, I2C_STATUS_REG) &
+ (I2CSR_MCF|I2CSR_MIF)) == (I2CSR_MCF|I2CSR_MIF))
+ return (IIC_NOERR);
+ DELAY(10);
+ }
+
+ return (IIC_ETIMEOUT);
+}
+
+static int
+i2c_probe(device_t dev)
+{
+ struct i2c_softc *sc;
+
+ if (!ofw_bus_is_compatible(dev, "fsl,imx-i2c"))
+ return (ENXIO);
+
+ sc = device_get_softc(dev);
+ sc->rid = 0;
+
+ sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
+ RF_ACTIVE);
+ if (sc->res == NULL) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ sc->bst = rman_get_bustag(sc->res);
+ sc->bsh = rman_get_bushandle(sc->res);
+
+ /* Enable I2C */
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN);
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res);
+ device_set_desc(dev, "I2C bus controller");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+i2c_attach(device_t dev)
+{
+ struct i2c_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+ sc->rid = 0;
+
+ mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
+
+ sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
+ RF_ACTIVE);
+ if (sc->res == NULL) {
+ device_printf(dev, "could not allocate resources");
+ mtx_destroy(&sc->mutex);
+ return (ENXIO);
+ }
+
+ sc->bst = rman_get_bustag(sc->res);
+ sc->bsh = rman_get_bushandle(sc->res);
+
+ sc->iicbus = device_add_child(dev, "iicbus", -1);
+ if (sc->iicbus == NULL) {
+ device_printf(dev, "could not add iicbus child");
+ mtx_destroy(&sc->mutex);
+ return (ENXIO);
+ }
+
+ bus_generic_attach(dev);
+ return (IIC_NOERR);
+}
+
+static int
+i2c_repeated_start(device_t dev, u_char slave, int timeout)
+{
+ struct i2c_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ mtx_lock(&sc->mutex);
+
+ i2c_write_reg(sc, I2C_ADDR_REG, slave);
+ if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) {
+ mtx_unlock(&sc->mutex);
+ return (IIC_EBUSBSY);
+ }
+
+ /* Set repeated start condition */
+ DELAY(10);
+ i2c_flag_set(sc, I2C_CONTROL_REG, I2CCR_RSTA);
+ DELAY(10);
+ /* Clear status */
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+ /* Write target address - LSB is R/W bit */
+ i2c_write_reg(sc, I2C_DATA_REG, slave);
+
+ error = wait_for_iif(sc);
+
+ /* Clear status */
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+
+ mtx_unlock(&sc->mutex);
+
+ if (error)
+ return (error);
+
+ return (IIC_NOERR);
+}
+
+static int
+i2c_start(device_t dev, u_char slave, int timeout)
+{
+ struct i2c_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ mtx_lock(&sc->mutex);
+ i2c_write_reg(sc, I2C_ADDR_REG, slave);
+ if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) {
+ mtx_unlock(&sc->mutex);
+ return (IIC_EBUSBSY);
+ }
+
+ /* Set start condition */
+ i2c_write_reg(sc, I2C_CONTROL_REG,
+ I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK);
+ DELAY(100);
+ i2c_write_reg(sc, I2C_CONTROL_REG,
+ I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX | I2CCR_TXAK);
+ /* Clear status */
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+ /* Write target address - LSB is R/W bit */
+ i2c_write_reg(sc, I2C_DATA_REG, slave);
+
+ error = wait_for_iif(sc);
+
+ mtx_unlock(&sc->mutex);
+ if (error)
+ return (error);
+
+ return (IIC_NOERR);
+}
+
+
+static int
+i2c_stop(device_t dev)
+{
+ struct i2c_softc *sc;
+
+ sc = device_get_softc(dev);
+ mtx_lock(&sc->mutex);
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
+ DELAY(100);
+ /* Reset controller if bus still busy after STOP */
+ if (wait_for_nibb(sc) == IIC_ETIMEOUT) {
+ i2c_write_reg(sc, I2C_CONTROL_REG, 0);
+ DELAY(1000);
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
+
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+ }
+ mtx_unlock(&sc->mutex);
+
+ return (IIC_NOERR);
+}
+
+static int
+i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
+{
+ struct i2c_softc *sc;
+ uint8_t baud_rate;
+
+ sc = device_get_softc(dev);
+
+ switch (speed) {
+ case IIC_FAST:
+ baud_rate = I2C_BAUD_RATE_FAST;
+ break;
+ case IIC_SLOW:
+ case IIC_UNKNOWN:
+ case IIC_FASTEST:
+ default:
+ baud_rate = I2C_BAUD_RATE_DEF;
+ break;
+ }
+
+ mtx_lock(&sc->mutex);
+ i2c_write_reg(sc, I2C_CONTROL_REG, 0x0);
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+ DELAY(1000);
+
+ i2c_write_reg(sc, I2C_FDR_REG, 20);
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN);
+ DELAY(1000);
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+ mtx_unlock(&sc->mutex);
+
+ return (IIC_NOERR);
+}
+
+static int
+i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
+{
+ struct i2c_softc *sc;
+ int error, reg;
+
+ sc = device_get_softc(dev);
+ *read = 0;
+
+ mtx_lock(&sc->mutex);
+
+ if (len) {
+ if (len == 1)
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+ I2CCR_MSTA | I2CCR_TXAK);
+
+ else
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+ I2CCR_MSTA);
+
+ /* dummy read */
+ i2c_read_reg(sc, I2C_DATA_REG);
+ DELAY(1000);
+ }
+
+ while (*read < len) {
+ error = wait_for_icf(sc);
+ if (error) {
+ mtx_unlock(&sc->mutex);
+ return (error);
+ }
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+ if ((*read == len - 2) && last) {
+ /* NO ACK on last byte */
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+ I2CCR_MSTA | I2CCR_TXAK);
+ }
+
+ if ((*read == len - 1) && last) {
+ /* Transfer done, remove master bit */
+ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+ I2CCR_TXAK);
+ }
+
+ reg = i2c_read_reg(sc, I2C_DATA_REG);
+ *buf++ = reg;
+ (*read)++;
+ }
+ mtx_unlock(&sc->mutex);
+
+ return (IIC_NOERR);
+}
+
+static int
+i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
+{
+ struct i2c_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ *sent = 0;
+
+ mtx_lock(&sc->mutex);
+ while (*sent < len) {
+ i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+ i2c_write_reg(sc, I2C_DATA_REG, *buf++);
+
+ error = wait_for_iif(sc);
+ if (error) {
+ mtx_unlock(&sc->mutex);
+ return (error);
+ }
+
+ (*sent)++;
+ }
+ mtx_unlock(&sc->mutex);
+
+ return (IIC_NOERR);
+}
diff --git a/sys/arm/freescale/imx/imx.files b/sys/arm/freescale/imx/imx.files
new file mode 100644
index 0000000..dd2a975
--- /dev/null
+++ b/sys/arm/freescale/imx/imx.files
@@ -0,0 +1,51 @@
+# $FreeBSD$
+arm/arm/bus_space_asm_generic.S standard
+arm/arm/bus_space_generic.c standard
+arm/arm/cpufunc_asm_armv5.S standard
+arm/arm/cpufunc_asm_arm11.S standard
+arm/arm/cpufunc_asm_armv7.S standard
+arm/arm/irq_dispatch.S standard
+kern/kern_clocksource.c standard
+
+# Init
+arm/freescale/imx/imx_machdep.c standard
+arm/freescale/imx/common.c standard
+arm/freescale/imx/bus_space.c standard
+
+# Dummy serial console
+#arm/freescale/imx/console.c standard
+
+# TrustZone Interrupt Controller
+arm/freescale/imx/tzic.c standard
+
+# IOMUX - external pins multiplexor
+arm/freescale/imx/imx51_iomux.c optional iomux
+
+# GPIO
+arm/freescale/imx/imx51_gpio.c optional gpio
+
+# Generic Periodic Timer
+arm/freescale/imx/imx_gpt.c standard
+
+# Clock Configuration Manager
+arm/freescale/imx/imx51_ccm.c standard
+
+# i.MX5xx PATA controller
+dev/ata/chipsets/ata-fsl.c optional imxata
+
+# UART driver
+dev/uart/uart_dev_imx.c optional uart
+
+# USB join controller (1 OTG, 3 EHCI)
+dev/usb/controller/ehci_imx.c optional ehci
+
+# Watchdog
+arm/freescale/imx/imx_wdog.c optional imxwdt
+
+# i2c
+arm/freescale/imx/i2c.c optional fsliic
+dev/ofw/ofw_iicbus.c optional fsliic
+
+# IPU - Image Processing Unit (frame buffer also)
+arm/freescale/imx/imx51_ipuv3.c optional sc
+
diff --git a/sys/arm/freescale/imx/imx51_ccm.c b/sys/arm/freescale/imx/imx51_ccm.c
new file mode 100644
index 0000000..6093e2b
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_ccm.c
@@ -0,0 +1,474 @@
+/* $NetBSD: imx51_ccm.c,v 1.1 2012/04/17 09:33:31 bsh Exp $ */
+/*
+ * Copyright (c) 2010, 2011, 2012 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * Clock Controller Module (CCM)
+ */
+
+#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 <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.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 <arm/freescale/imx/imx51_ccmvar.h>
+#include <arm/freescale/imx/imx51_ccmreg.h>
+#include <arm/freescale/imx/imx51_dpllreg.h>
+
+#define IMXCCMDEBUG
+#undef IMXCCMDEBUG
+
+#ifndef IMX51_OSC_FREQ
+#define IMX51_OSC_FREQ (24 * 1000 * 1000) /* 24MHz */
+#endif
+
+#ifndef IMX51_CKIL_FREQ
+#define IMX51_CKIL_FREQ 32768
+#endif
+
+struct imxccm_softc {
+ device_t sc_dev;
+ struct resource *res[7];
+ u_int64_t pll_freq[IMX51_N_DPLLS];
+};
+
+struct imxccm_softc *ccm_softc = NULL;
+
+static uint64_t imx51_get_pll_freq(u_int);
+
+static int imxccm_match(device_t);
+static int imxccm_attach(device_t);
+
+static device_method_t imxccm_methods[] = {
+ DEVMETHOD(device_probe, imxccm_match),
+ DEVMETHOD(device_attach, imxccm_attach),
+
+ DEVMETHOD_END
+};
+
+static driver_t imxccm_driver = {
+ "imxccm",
+ imxccm_methods,
+ sizeof(struct imxccm_softc),
+};
+
+static devclass_t imxccm_devclass;
+
+EARLY_DRIVER_MODULE(imxccm, simplebus, imxccm_driver, imxccm_devclass, 0, 0,
+ BUS_PASS_CPU);
+
+static struct resource_spec imxccm_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Global registers */
+ { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* DPLLIP1 */
+ { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* DPLLIP2 */
+ { SYS_RES_MEMORY, 3, RF_ACTIVE }, /* DPLLIP3 */
+ { SYS_RES_IRQ, 0, RF_ACTIVE }, /* 71 */
+ { SYS_RES_IRQ, 1, RF_ACTIVE }, /* 72 */
+ { -1, 0 }
+};
+
+static int
+imxccm_match(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,imx51-ccm"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale Clock Control Module");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+imxccm_attach(device_t dev)
+{
+ struct imxccm_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+
+ if (bus_alloc_resources(dev, imxccm_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ ccm_softc = sc;
+
+ imx51_get_pll_freq(1);
+ imx51_get_pll_freq(2);
+ imx51_get_pll_freq(3);
+
+ device_printf(dev, "PLL1=%lluMHz, PLL2=%lluMHz, PLL3=%lluMHz\n",
+ sc->pll_freq[0] / 1000000,
+ sc->pll_freq[1] / 1000000,
+ sc->pll_freq[2] / 1000000);
+ device_printf(dev, "CPU clock=%d, UART clock=%d\n",
+ imx51_get_clock(IMX51CLK_ARM_ROOT),
+ imx51_get_clock(IMX51CLK_UART_CLK_ROOT));
+ device_printf(dev,
+ "mainbus clock=%d, ahb clock=%d ipg clock=%d perclk=%d\n",
+ imx51_get_clock(IMX51CLK_MAIN_BUS_CLK),
+ imx51_get_clock(IMX51CLK_AHB_CLK_ROOT),
+ imx51_get_clock(IMX51CLK_IPG_CLK_ROOT),
+ imx51_get_clock(IMX51CLK_PERCLK_ROOT));
+
+
+ return (0);
+}
+
+u_int
+imx51_get_clock(enum imx51_clock clk)
+{
+ u_int freq;
+ u_int sel;
+ uint32_t cacrr; /* ARM clock root register */
+ uint32_t ccsr;
+ uint32_t cscdr1;
+ uint32_t cscmr1;
+ uint32_t cbcdr;
+ uint32_t cbcmr;
+ uint32_t cdcr;
+
+ if (ccm_softc == NULL)
+ return (0);
+
+ switch (clk) {
+ case IMX51CLK_PLL1:
+ case IMX51CLK_PLL2:
+ case IMX51CLK_PLL3:
+ return ccm_softc->pll_freq[clk-IMX51CLK_PLL1];
+ case IMX51CLK_PLL1SW:
+ ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+ if ((ccsr & CCSR_PLL1_SW_CLK_SEL) == 0)
+ return ccm_softc->pll_freq[1-1];
+ /* step clock */
+ /* FALLTHROUGH */
+ case IMX51CLK_PLL1STEP:
+ ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+ switch ((ccsr & CCSR_STEP_SEL_MASK) >> CCSR_STEP_SEL_SHIFT) {
+ case 0:
+ return imx51_get_clock(IMX51CLK_LP_APM);
+ case 1:
+ return 0; /* XXX PLL bypass clock */
+ case 2:
+ return ccm_softc->pll_freq[2-1] /
+ (1 + ((ccsr & CCSR_PLL2_DIV_PODF_MASK) >>
+ CCSR_PLL2_DIV_PODF_SHIFT));
+ case 3:
+ return ccm_softc->pll_freq[3-1] /
+ (1 + ((ccsr & CCSR_PLL3_DIV_PODF_MASK) >>
+ CCSR_PLL3_DIV_PODF_SHIFT));
+ }
+ /*NOTREACHED*/
+ case IMX51CLK_PLL2SW:
+ ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+ if ((ccsr & CCSR_PLL2_SW_CLK_SEL) == 0)
+ return imx51_get_clock(IMX51CLK_PLL2);
+ return 0; /* XXX PLL2 bypass clk */
+ case IMX51CLK_PLL3SW:
+ ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+ if ((ccsr & CCSR_PLL3_SW_CLK_SEL) == 0)
+ return imx51_get_clock(IMX51CLK_PLL3);
+ return 0; /* XXX PLL3 bypass clk */
+
+ case IMX51CLK_LP_APM:
+ ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+ return (ccsr & CCSR_LP_APM) ?
+ imx51_get_clock(IMX51CLK_FPM) : IMX51_OSC_FREQ;
+
+ case IMX51CLK_ARM_ROOT:
+ freq = imx51_get_clock(IMX51CLK_PLL1SW);
+ cacrr = bus_read_4(ccm_softc->res[0], CCMC_CACRR);
+ return freq / (cacrr + 1);
+
+ /* ... */
+ case IMX51CLK_MAIN_BUS_CLK_SRC:
+ cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+ if ((cbcdr & CBCDR_PERIPH_CLK_SEL) == 0)
+ freq = imx51_get_clock(IMX51CLK_PLL2SW);
+ else {
+ freq = 0;
+ cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR);
+ switch ((cbcmr & CBCMR_PERIPH_APM_SEL_MASK) >>
+ CBCMR_PERIPH_APM_SEL_SHIFT) {
+ case 0:
+ freq = imx51_get_clock(IMX51CLK_PLL1SW);
+ break;
+ case 1:
+ freq = imx51_get_clock(IMX51CLK_PLL3SW);
+ break;
+ case 2:
+ freq = imx51_get_clock(IMX51CLK_LP_APM);
+ break;
+ case 3:
+ /* XXX: error */
+ break;
+ }
+ }
+ return freq;
+ case IMX51CLK_MAIN_BUS_CLK:
+ freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC);
+ cdcr = bus_read_4(ccm_softc->res[0], CCMC_CDCR);
+ return freq / (cdcr & CDCR_PERIPH_CLK_DVFS_PODF_MASK) >>
+ CDCR_PERIPH_CLK_DVFS_PODF_SHIFT;
+ case IMX51CLK_AHB_CLK_ROOT:
+ freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK);
+ cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+ return freq / (1 + ((cbcdr & CBCDR_AHB_PODF_MASK) >>
+ CBCDR_AHB_PODF_SHIFT));
+ case IMX51CLK_IPG_CLK_ROOT:
+ freq = imx51_get_clock(IMX51CLK_AHB_CLK_ROOT);
+ cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+ return freq / (1 + ((cbcdr & CBCDR_IPG_PODF_MASK) >>
+ CBCDR_IPG_PODF_SHIFT));
+
+ case IMX51CLK_PERCLK_ROOT:
+ cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR);
+ if (cbcmr & CBCMR_PERCLK_IPG_SEL)
+ return imx51_get_clock(IMX51CLK_IPG_CLK_ROOT);
+ if (cbcmr & CBCMR_PERCLK_LP_APM_SEL)
+ freq = imx51_get_clock(IMX51CLK_LP_APM);
+ else
+ freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC);
+ cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+
+#ifdef IMXCCMDEBUG
+ printf("cbcmr=%x cbcdr=%x\n", cbcmr, cbcdr);
+#endif
+
+ freq /= 1 + ((cbcdr & CBCDR_PERCLK_PRED1_MASK) >>
+ CBCDR_PERCLK_PRED1_SHIFT);
+ freq /= 1 + ((cbcdr & CBCDR_PERCLK_PRED2_MASK) >>
+ CBCDR_PERCLK_PRED2_SHIFT);
+ freq /= 1 + ((cbcdr & CBCDR_PERCLK_PODF_MASK) >>
+ CBCDR_PERCLK_PODF_SHIFT);
+ return freq;
+ case IMX51CLK_UART_CLK_ROOT:
+ cscdr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCDR1);
+ cscmr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1);
+
+#ifdef IMXCCMDEBUG
+ printf("cscdr1=%x cscmr1=%x\n", cscdr1, cscmr1);
+#endif
+
+ sel = (cscmr1 & CSCMR1_UART_CLK_SEL_MASK) >>
+ CSCMR1_UART_CLK_SEL_SHIFT;
+
+ freq = 0; /* shut up GCC */
+ switch (sel) {
+ case 0:
+ case 1:
+ case 2:
+ freq = imx51_get_clock(IMX51CLK_PLL1SW + sel);
+ break;
+ case 3:
+ freq = imx51_get_clock(IMX51CLK_LP_APM);
+ break;
+ }
+
+ return freq / (1 + ((cscdr1 & CSCDR1_UART_CLK_PRED_MASK) >>
+ CSCDR1_UART_CLK_PRED_SHIFT)) /
+ (1 + ((cscdr1 & CSCDR1_UART_CLK_PODF_MASK) >>
+ CSCDR1_UART_CLK_PODF_SHIFT));
+ case IMX51CLK_IPU_HSP_CLK_ROOT:
+ freq = 0;
+ cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR);
+ switch ((cbcmr & CBCMR_IPU_HSP_CLK_SEL_MASK) >>
+ CBCMR_IPU_HSP_CLK_SEL_SHIFT) {
+ case 0:
+ freq = imx51_get_clock(IMX51CLK_ARM_AXI_A_CLK);
+ break;
+ case 1:
+ freq = imx51_get_clock(IMX51CLK_ARM_AXI_B_CLK);
+ break;
+ case 2:
+ freq = imx51_get_clock(
+ IMX51CLK_EMI_SLOW_CLK_ROOT);
+ break;
+ case 3:
+ freq = imx51_get_clock(IMX51CLK_AHB_CLK_ROOT);
+ break;
+ }
+ return freq;
+ default:
+ device_printf(ccm_softc->sc_dev,
+ "clock %d: not supported yet\n", clk);
+ return 0;
+ }
+}
+
+
+static uint64_t
+imx51_get_pll_freq(u_int pll_no)
+{
+ uint32_t dp_ctrl;
+ uint32_t dp_op;
+ uint32_t dp_mfd;
+ uint32_t dp_mfn;
+ uint32_t mfi;
+ int32_t mfn;
+ uint32_t mfd;
+ uint32_t pdf;
+ uint32_t ccr;
+ uint64_t freq = 0;
+ u_int ref = 0;
+
+ KASSERT(1 <= pll_no && pll_no <= IMX51_N_DPLLS, ("Wrong PLL id"));
+
+ dp_ctrl = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_CTL);
+
+ if (dp_ctrl & DP_CTL_HFSM) {
+ dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_OP);
+ dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFD);
+ dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFN);
+ } else {
+ dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_OP);
+ dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFD);
+ dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFN);
+ }
+
+ pdf = dp_op & DP_OP_PDF_MASK;
+ mfi = max(5, (dp_op & DP_OP_MFI_MASK) >> DP_OP_MFI_SHIFT);
+ mfd = dp_mfd;
+ if (dp_mfn & 0x04000000)
+ /* 27bit signed value */
+ mfn = (uint32_t)(0xf8000000 | dp_mfn);
+ else
+ mfn = dp_mfn;
+
+ switch (dp_ctrl & DP_CTL_REF_CLK_SEL_MASK) {
+ case DP_CTL_REF_CLK_SEL_COSC:
+ /* Internal Oscillator */
+ /* TODO: get from FDT "fsl,imx-osc" */
+ ref = 24000000; /* IMX51_OSC_FREQ */
+ break;
+ case DP_CTL_REF_CLK_SEL_FPM:
+ ccr = bus_read_4(ccm_softc->res[0], CCMC_CCR);
+ if (ccr & CCR_FPM_MULT)
+ /* TODO: get from FDT "fsl,imx-ckil" */
+ ref = 32768 * 1024;
+ else
+ /* TODO: get from FDT "fsl,imx-ckil" */
+ ref = 32768 * 512;
+ break;
+ default:
+ ref = 0;
+ }
+
+ if (dp_ctrl & DP_CTL_REF_CLK_DIV)
+ ref /= 2;
+
+ ref *= 4;
+ freq = (int64_t)ref * mfi + (int64_t)ref * mfn / (mfd + 1);
+ freq /= pdf + 1;
+
+ if (!(dp_ctrl & DP_CTL_DPDCK0_2_EN))
+ freq /= 2;
+
+#ifdef IMXCCMDEBUG
+ printf("ref: %dKHz ", ref);
+ printf("dp_ctl: %08x ", dp_ctrl);
+ printf("pdf: %3d ", pdf);
+ printf("mfi: %3d ", mfi);
+ printf("mfd: %3d ", mfd);
+ printf("mfn: %3d ", mfn);
+ printf("pll: %d\n", (uint32_t)freq);
+#endif
+
+ ccm_softc->pll_freq[pll_no-1] = freq;
+
+ return (freq);
+}
+
+void
+imx51_clk_gating(int clk_src, int mode)
+{
+ int field, group;
+ uint32_t reg;
+
+ group = CCMR_CCGR_MODULE(clk_src);
+ field = clk_src % CCMR_CCGR_NSOURCE;
+ reg = bus_read_4(ccm_softc->res[0], CCMC_CCGR(group));
+ reg &= ~(0x03 << field * 2);
+ reg |= (mode << field * 2);
+ bus_write_4(ccm_softc->res[0], CCMC_CCGR(group), reg);
+}
+
+int
+imx51_get_clk_gating(int clk_src)
+{
+ uint32_t reg;
+
+ reg = bus_read_4(ccm_softc->res[0],
+ CCMC_CCGR(CCMR_CCGR_MODULE(clk_src)));
+ return ((reg >> (clk_src % CCMR_CCGR_NSOURCE) * 2) & 0x03);
+}
+
diff --git a/sys/arm/freescale/imx/imx51_ccmreg.h b/sys/arm/freescale/imx/imx51_ccmreg.h
new file mode 100644
index 0000000..d17b98a
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_ccmreg.h
@@ -0,0 +1,250 @@
+/* $NetBSD: imx51_ccmreg.h,v 1.1 2012/04/17 09:33:31 bsh Exp $ */
+/*
+ * Copyright (c) 2011, 2012 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _IMX51_CCMREG_H
+#define _IMX51_CCMREG_H
+
+#include <sys/cdefs.h>
+
+/* register offset address */
+
+#define CCMC_BASE 0x73fd4000
+#define CCMC_CCR 0x0000
+#define CCR_FPM_MULT 0x00001000
+#define CCMC_CCDR 0x0004
+#define CCMC_CSR 0x0008
+#define CCMC_CCSR 0x000c
+#define CCSR_LP_APM 0x00000200
+#define CCSR_STEP_SEL_SHIFT 7
+#define CCSR_STEP_SEL_MASK 0x00000180
+#define CCSR_PLL2_DIV_PODF_SHIFT 5
+#define CCSR_PLL2_DIV_PODF_MASK 0x00000060
+#define CCSR_PLL3_DIV_PODF_SHIFT 3
+#define CCSR_PLL3_DIV_PODF_MASK 0x00000030
+#define CCSR_PLL1_SW_CLK_SEL 0x00000004
+#define CCSR_PLL2_SW_CLK_SEL 0x00000002
+#define CCSR_PLL3_SW_CLK_SEL 0x00000001
+#define CCMC_CACRR 0x0010
+#define CCMC_CBCDR 0x0014
+#define CBCDR_DDR_HIGH_FREQ_CLK_SEL 0x40000000
+#define CBCDR_DDR_CLK_PODF_SHIFT 27
+#define CBCDR_DDR_CLK_PODF_MASK 0x38000000
+#define CBCDR_EMI_CLK_SEL 0x04000000
+#define CBCDR_PERIPH_CLK_SEL 0x02000000
+#define CBCDR_EMI_SLOW_PODF_SHIFT 22
+#define CBCDR_EMI_SLOW_PODF_MASK 0x01c00000
+#define CBCDR_AXI_B_PODF_SHIFT 19
+#define CBCDR_AXI_B_PODF_MASK 0x00380000
+#define CBCDR_AXI_A_PODF_SHIFT 16
+#define CBCDR_AXI_A_PODF_MASK 0x1fff0000
+#define CBCDR_NFC_PODF_SHIFT 13
+#define CBCDR_NFC_PODF_MASK 0x00018000
+#define CBCDR_AHB_PODF_SHIFT 10
+#define CBCDR_AHB_PODF_MASK 0x00001c00
+#define CBCDR_IPG_PODF_SHIFT 8
+#define CBCDR_IPG_PODF_MASK 0x00000300
+#define CBCDR_PERCLK_PRED1_SHIFT 6
+#define CBCDR_PERCLK_PRED1_MASK 0x000000c0
+#define CBCDR_PERCLK_PRED2_SHIFT 3
+#define CBCDR_PERCLK_PRED2_MASK 0x00000038
+#define CBCDR_PERCLK_PODF_SHIFT 0
+#define CBCDR_PERCLK_PODF_MASK 0x00000007
+#define CCMC_CBCMR 0x0018
+#define CBCMR_PERIPH_APM_SEL_SHIFT 12
+#define CBCMR_PERIPH_APM_SEL_MASK 0x00003000
+#define CBCMR_IPU_HSP_CLK_SEL_SHIFT 6
+#define CBCMR_IPU_HSP_CLK_SEL_MASK 0x000000c0
+#define CBCMR_PERCLK_LP_APM_SEL 0x00000002
+#define CBCMR_PERCLK_IPG_SEL 0x00000001
+#define CCMC_CSCMR1 0x001c
+#define CSCMR1_UART_CLK_SEL_SHIFT 24
+#define CSCMR1_UART_CLK_SEL_MASK 0x03000000
+#define CCMC_CSCMR2 0x0020
+#define CCMC_CSCDR1 0x0024
+#define CSCDR1_UART_CLK_PRED_SHIFT 3
+#define CSCDR1_UART_CLK_PRED_MASK 0x00000038
+#define CSCDR1_UART_CLK_PODF_SHIFT 0
+#define CSCDR1_UART_CLK_PODF_MASK 0x00000007
+#define CCMC_CS1CDR 0x0028
+#define CCMC_CS2CDR 0x002c
+#define CCMC_CDCDR 0x0030
+#define CCMC_CSCDR2 0x0038
+#define CCMC_CSCDR3 0x003c
+#define CCMC_CSCDR4 0x0040
+#define CCMC_CWDR 0x0044
+#define CCMC_CDHIPR 0x0048
+#define CCMC_CDCR 0x004c
+#define CDCR_PERIPH_CLK_DVFS_PODF_SHIFT 0
+#define CDCR_PERIPH_CLK_DVFS_PODF_MASK 0x00000003
+#define CCMC_CTOR 0x0050
+#define CCMC_CLPCR 0x0054
+#define CCMC_CISR 0x0058
+#define CCMC_CIMR 0x005c
+#define CCMC_CCOSR 0x0060
+#define CCMC_CGPR 0x0064
+#define CCMC_CCGR(n) (0x0068 + (n) * 4)
+#define CCMC_CMEOR 0x0084
+
+#define CCMC_SIZE 0x88
+
+/* CCGR Clock Gate Register */
+
+#define CCMR_CCGR_NSOURCE 16
+#define CCMR_CCGR_NGROUPS 7
+#define CCMR_CCGR_MODULE(clk) ((clk) / CCMR_CCGR_NSOURCE)
+#define __CCGR_NUM(a, b) ((a) * 16 + (b))
+
+#define CCGR_ARM_BUS_CLK __CCGR_NUM(0, 0)
+#define CCGR_ARM_AXI_CLK __CCGR_NUM(0, 1)
+#define CCGR_ARM_DEBUG_CLK __CCGR_NUM(0, 2)
+#define CCGR_TZIC_CLK __CCGR_NUM(0, 3)
+#define CCGR_DAP_CLK __CCGR_NUM(0, 4)
+#define CCGR_TPIU_CLK __CCGR_NUM(0, 5)
+#define CCGR_CTI2_CLK __CCGR_NUM(0, 6)
+#define CCGR_CTI3_CLK __CCGR_NUM(0, 7)
+#define CCGR_AHBMUX1_CLK __CCGR_NUM(0, 8)
+#define CCGR_AHBMUX2_CLK __CCGR_NUM(0, 9)
+#define CCGR_ROMCP_CLK __CCGR_NUM(0, 10)
+#define CCGR_ROM_CLK __CCGR_NUM(0, 11)
+#define CCGR_AIPS_TZ1_CLK __CCGR_NUM(0, 12)
+#define CCGR_AIPS_TZ2_CLK __CCGR_NUM(0, 13)
+#define CCGR_AHB_MAX_CLK __CCGR_NUM(0, 14)
+#define CCGR_IIM_CLK __CCGR_NUM(0, 15)
+#define CCGR_TMAX1_CLK __CCGR_NUM(1, 0)
+#define CCGR_TMAX2_CLK __CCGR_NUM(1, 1)
+#define CCGR_TMAX3_CLK __CCGR_NUM(1, 2)
+#define CCGR_UART1_CLK __CCGR_NUM(1, 3)
+#define CCGR_UART1_SERIAL_CLK __CCGR_NUM(1, 4)
+#define CCGR_UART2_CLK __CCGR_NUM(1, 5)
+#define CCGR_UART2_SERIAL_CLK __CCGR_NUM(1, 6)
+#define CCGR_UART3_CLK __CCGR_NUM(1, 7)
+#define CCGR_UART3_SERIAL_CLK __CCGR_NUM(1, 8)
+#define CCGR_I2C1_SERIAL_CLK __CCGR_NUM(1, 9)
+#define CCGR_I2C2_SERIAL_CLK __CCGR_NUM(1, 10)
+#define CCGR_HSI2C_CLK __CCGR_NUM(1, 11)
+#define CCGR_HSI2C_SERIAL_CLK __CCGR_NUM(1, 12)
+#define CCGR_FIRI_CLK __CCGR_NUM(1, 13)
+#define CCGR_FIRI_SERIAL_CLK __CCGR_NUM(1, 14)
+#define CCGR_SCC_CLK __CCGR_NUM(1, 15)
+
+#define CCGR_USB_PHY_CLK __CCGR_NUM(2, 0)
+#define CCGR_EPIT1_CLK __CCGR_NUM(2, 1)
+#define CCGR_EPIT1_SERIAL_CLK __CCGR_NUM(2, 2)
+#define CCGR_EPIT2_CLK __CCGR_NUM(2, 3)
+#define CCGR_EPIT2_SERIAL_CLK __CCGR_NUM(2, 4)
+#define CCGR_PWM1_CLK __CCGR_NUM(2, 5)
+#define CCGR_PWM1_SERIAL_CLK __CCGR_NUM(2, 6)
+#define CCGR_PWM2_CLK __CCGR_NUM(2, 7)
+#define CCGR_PWM2_SERIAL_CLK __CCGR_NUM(2, 8)
+#define CCGR_GPT_CLK __CCGR_NUM(2, 9)
+#define CCGR_GPT_SERIAL_CLK __CCGR_NUM(2, 10)
+#define CCGR_OWIRE_CLK __CCGR_NUM(2, 11)
+#define CCGR_FEC_CLK __CCGR_NUM(2, 12)
+#define CCGR_USBOH3_IPG_AHB_CLK __CCGR_NUM(2, 13)
+#define CCGR_USBOH3_60M_CLK __CCGR_NUM(2, 14)
+#define CCGR_TVE_CLK __CCGR_NUM(2, 15)
+
+#define CCGR_ESDHC1_CLK __CCGR_NUM(3, 0)
+#define CCGR_ESDHC1_SERIAL_CLK __CCGR_NUM(3, 1)
+#define CCGR_ESDHC2_CLK __CCGR_NUM(3, 2)
+#define CCGR_ESDHC2_SERIAL_CLK __CCGR_NUM(3, 3)
+#define CCGR_ESDHC3_CLK __CCGR_NUM(3, 4)
+#define CCGR_ESDHC3_SERIAL_CLK __CCGR_NUM(3, 5)
+#define CCGR_ESDHC4_CLK __CCGR_NUM(3, 6)
+#define CCGR_ESDHC4_SERIAL_CLK __CCGR_NUM(3, 7)
+#define CCGR_SSI1_CLK __CCGR_NUM(3, 8)
+#define CCGR_SSI1_SERIAL_CLK __CCGR_NUM(3, 9)
+#define CCGR_SSI2_CLK __CCGR_NUM(3, 10)
+#define CCGR_SSI2_SERIAL_CLK __CCGR_NUM(3, 11)
+#define CCGR_SSI3_CLK __CCGR_NUM(3, 12)
+#define CCGR_SSI3_SERIAL_CLK __CCGR_NUM(3, 13)
+#define CCGR_SSI_EXT1_CLK __CCGR_NUM(3, 14)
+#define CCGR_SSI_EXT2_CLK __CCGR_NUM(3, 15)
+
+#define CCGR_PATA_CLK __CCGR_NUM(4, 0)
+#define CCGR_SIM_CLK __CCGR_NUM(4, 1)
+#define CCGR_SIM_SERIAL_CLK __CCGR_NUM(4, 2)
+#define CCGR_SAHARA_CLK __CCGR_NUM(4, 3)
+#define CCGR_RTIC_CLK __CCGR_NUM(4, 4)
+#define CCGR_ECSPI1_CLK __CCGR_NUM(4, 5)
+#define CCGR_ECSPI1_SERIAL_CLK __CCGR_NUM(4, 6)
+#define CCGR_ECSPI2_CLK __CCGR_NUM(4, 7)
+#define CCGR_ECSPI2_SERIAL_CLK __CCGR_NUM(4, 8)
+#define CCGR_CSPI_CLK __CCGR_NUM(4, 9)
+#define CCGR_SRTC_CLK __CCGR_NUM(4, 10)
+#define CCGR_SDMA_CLK __CCGR_NUM(4, 11)
+
+#define CCGR_SPBA_CLK __CCGR_NUM(5, 0)
+#define CCGR_GPU_CLK __CCGR_NUM(5, 1)
+#define CCGR_GARB_CLK __CCGR_NUM(5, 2)
+#define CCGR_VPU_CLK __CCGR_NUM(5, 3)
+#define CCGR_VPU_SERIAL_CLK __CCGR_NUM(5, 4)
+#define CCGR_IPU_CLK __CCGR_NUM(5, 5)
+#define CCGR_EMI_GARB_CLK __CCGR_NUM(6, 0)
+#define CCGR_IPU_DI0_CLK __CCGR_NUM(6, 1)
+#define CCGR_IPU_DI1_CLK __CCGR_NUM(6, 2)
+#define CCGR_GPU2D_CLK __CCGR_NUM(6, 3)
+#define CCGR_SLIMBUS_CLK __CCGR_NUM(6, 4)
+#define CCGR_SLIMBUS_SERIAL_CLK __CCGR_NUM(6, 5)
+
+#define CCGR_CLK_MODE_OFF 0
+#define CCGR_CLK_MODE_RUNMODE 1
+#define CCGR_CLK_MODE_ALWAYS 3
+
+#endif /* _IMX51_CCMREG_H */
+
diff --git a/sys/arm/freescale/imx/imx51_ccmvar.h b/sys/arm/freescale/imx/imx51_ccmvar.h
new file mode 100644
index 0000000..9b798f1
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_ccmvar.h
@@ -0,0 +1,110 @@
+/* $NetBSD: imx51_ccmvar.h,v 1.1 2012/04/17 09:33:31 bsh Exp $ */
+/*
+ * Copyright (c) 2012 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _ARM_IMX_IMX51_CCMVAR_H_
+#define _ARM_IMX_IMX51_CCMVAR_H_
+
+enum imx51_clock {
+ IMX51CLK_FPM,
+ IMX51CLK_PLL1,
+ IMX51CLK_PLL2,
+ IMX51CLK_PLL3,
+ IMX51CLK_PLL1SW,
+ IMX51CLK_PLL2SW,
+ IMX51CLK_PLL3SW,
+ IMX51CLK_PLL1STEP,
+ IMX51CLK_LP_APM,
+ IMX51CLK_ARM_ROOT,
+ IMX51CLK_MAIN_BUS_CLK_SRC, /* XXX */
+ IMX51CLK_MAIN_BUS_CLK,
+ IMX51CLK_EMI_SLOW_CLK_ROOT,
+ IMX51CLK_ENFC_CLK_ROOT,
+ IMX51CLK_AHB_CLK_ROOT,
+ IMX51CLK_IPG_CLK_ROOT,
+ IMX51CLK_PERCLK_ROOT,
+ IMX51CLK_DDR_CLK_ROOT,
+ IMX51CLK_ARM_AXI_CLK_ROOT,
+ IMX51CLK_ARM_AXI_A_CLK,
+ IMX51CLK_ARM_AXI_B_CLK,
+ IMX51CLK_IPU_HSP_CLK_ROOT,
+ IMX51CLK_CKIL_SYNC_CLK_ROOT,
+ IMX51CLK_USBOH3_CLK_ROOT,
+ IMX51CLK_ESDHC1_CLK_ROOT,
+ IMX51CLK_ESDHC2_CLK_ROOT,
+ IMX51CLK_ESDHC3_CLK_ROOT,
+ IMX51CLK_UART_CLK_ROOT,
+ IMX51CLK_SSI1_CLK_ROOT,
+ IMX51CLK_SSI2_CLK_ROOT,
+ IMX51CLK_SSI_EXT1_CLK_ROOT,
+ IMX51CLK_SSI_EXT2_CLK_ROOT,
+ IMX51CLK_USB_PHY_CLK_ROOT,
+ IMX51CLK_TVE_216_54_CLK_ROOT,
+ IMX51CLK_DI_CLK_ROOT,
+ IMX51CLK_SPDIF0_CLK_ROOT,
+ IMX51CLK_SPDIF1_CLK_ROOT,
+ IMX51CLK_CSPI_CLK_ROOT,
+ IMX51CLK_WRCK_CLK_ROOT,
+ IMX51CLK_LPSR_CLK_ROOT,
+ IMX51CLK_PGC_CLK_ROOT
+};
+
+u_int imx51_get_clock(enum imx51_clock);
+void imx51_clk_gating(int, int);
+int imx51_get_clk_gating(int);
+
+#endif /* _ARM_IMX_IMX51_CCMVAR_H_ */
diff --git a/sys/arm/freescale/imx/imx51_dpllreg.h b/sys/arm/freescale/imx/imx51_dpllreg.h
new file mode 100644
index 0000000..06393da
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_dpllreg.h
@@ -0,0 +1,105 @@
+/* $NetBSD: imx51_dpllreg.h,v 1.1 2012/04/17 09:33:31 bsh Exp $ */
+/*
+ * Copyright (c) 2012 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _IMX51_DPLLREG_H
+#define _IMX51_DPLLREG_H
+
+#include <sys/cdefs.h>
+
+/* register offset address */
+
+#define IMX51_N_DPLLS 3 /* 1..3 */
+
+#define DPLL_BASE(n) (0x83F80000 + (0x4000 * ((n)-1)))
+#define DPLL_SIZE 0x100
+
+#define DPLL_DP_CTL 0x0000 /* 0x1223 */
+#define DP_CTL_LRF 0x00000001
+#define DP_CTL_BRM 0x00000002
+#define DP_CTL_PLM 0x00000004
+#define DP_CTL_RCP 0x00000008
+#define DP_CTL_RST 0x00000010
+#define DP_CTL_UPEN 0x00000020
+#define DP_CTL_PRE 0x00000040
+#define DP_CTL_HFSM 0x00000080
+#define DP_CTL_REF_CLK_SEL_MASK 0x00000300
+#define DP_CTL_REF_CLK_SEL_COSC 0x00000200
+#define DP_CTL_REF_CLK_SEL_FPM 0x00000300
+#define DP_CTL_REF_CLK_DIV 0x00000400
+#define DP_CTL_DPDCK0_2_EN 0x00001000
+#define DP_CTL_HIGHCLK_EN DP_CTL_DPDCK0_2_EN
+#define DP_CTL_MULCTRL 0x00002000
+#define DPLL_DP_CONFIG 0x0004 /* 2 */
+#define DPLL_DP_CONFIG_APEN 0x00000002
+#define DPLL_DP_CONFIG_LDREQ 0x00000001
+#define DPLL_DP_OP 0x0008 /* 0x80 */
+#define DP_OP_PDF_SHIFT 0
+#define DP_OP_PDF_MASK (0xf << DP_OP_PDF_SHIFT)
+#define DP_OP_MFI_SHIFT 4
+#define DP_OP_MFI_MASK (0xf << DP_OP_MFI_SHIFT)
+#define DPLL_DP_MFD 0x000C /* 2 */
+#define DPLL_DP_MFN 0x0010 /* 1 */
+#define DPLL_DP_MFNMINUS 0x0014 /* 0 */
+#define DPLL_DP_MFNPLUS 0x0018 /* 0 */
+#define DPLL_DP_HFS_OP 0x001C /* 0x80 */
+#define DPLL_DP_HFS_MFD 0x0020 /* 2 */
+#define DPLL_DP_HFS_MFN 0x0024 /* 1 */
+#define DPLL_DP_TOGC 0x0028 /* 0x20000 */
+#define DPLL_DP_DESTAT 0x002C /* 1 */
+
+#endif /* _IMX51_DPLLREG_H */
diff --git a/sys/arm/freescale/imx/imx51_gpio.c b/sys/arm/freescale/imx/imx51_gpio.c
new file mode 100644
index 0000000..d42a313
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_gpio.c
@@ -0,0 +1,481 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * Freescale i.MX515 GPIO driver.
+ */
+
+#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/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.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 "gpio_if.h"
+
+#define GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
+#define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
+#define GPIO_LOCK_INIT(_sc) mtx_init(&_sc->sc_mtx, \
+ device_get_nameunit(_sc->sc_dev), "imx_gpio", MTX_DEF)
+#define GPIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
+#define GPIO_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+#define WRITE4(_sc, _r, _v) \
+ bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r), (_v))
+#define READ4(_sc, _r) \
+ bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r))
+#define SET4(_sc, _r, _m) \
+ WRITE4((_sc), (_r), READ4((_sc), (_r)) | (_m))
+#define CLEAR4(_sc, _r, _m) \
+ WRITE4((_sc), (_r), READ4((_sc), (_r)) & ~(_m))
+
+/* Registers definition for Freescale i.MX515 GPIO controller */
+
+#define IMX_GPIO_DR_REG 0x000 /* Pin Data */
+#define IMX_GPIO_OE_REG 0x004 /* Set Pin Output */
+#define IMX_GPIO_PSR_REG 0x008 /* Pad Status */
+#define IMX_GPIO_ICR1_REG 0x00C /* Interrupt Configuration */
+#define IMX_GPIO_ICR2_REG 0x010 /* Interrupt Configuration */
+#define GPIO_ICR_COND_LOW 0
+#define GPIO_ICR_COND_HIGH 1
+#define GPIO_ICR_COND_RISE 2
+#define GPIO_ICR_COND_FALL 3
+#define IMX_GPIO_IMR_REG 0x014 /* Interrupt Mask Register */
+#define IMX_GPIO_ISR_REG 0x018 /* Interrupt Status Register */
+#define IMX_GPIO_EDGE_REG 0x01C /* Edge Detect Register */
+
+#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
+#define NGPIO 32
+
+struct imx51_gpio_softc {
+ device_t dev;
+ struct mtx sc_mtx;
+ struct resource *sc_res[11]; /* 1 x mem, 2 x IRQ, 8 x IRQ */
+ void *gpio_ih[11]; /* 1 ptr is not a big waste */
+ int sc_l_irq; /* Last irq resource */
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ int gpio_npins;
+ struct gpio_pin gpio_pins[NGPIO];
+};
+
+static struct resource_spec imx_gpio_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 1, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static struct resource_spec imx_gpio0irq_spec[] = {
+ { SYS_RES_IRQ, 2, RF_ACTIVE },
+ { SYS_RES_IRQ, 3, RF_ACTIVE },
+ { SYS_RES_IRQ, 4, RF_ACTIVE },
+ { SYS_RES_IRQ, 5, RF_ACTIVE },
+ { SYS_RES_IRQ, 6, RF_ACTIVE },
+ { SYS_RES_IRQ, 7, RF_ACTIVE },
+ { SYS_RES_IRQ, 8, RF_ACTIVE },
+ { SYS_RES_IRQ, 9, RF_ACTIVE },
+ { -1, 0 }
+};
+
+/*
+ * Helpers
+ */
+static void imx51_gpio_pin_configure(struct imx51_gpio_softc *,
+ struct gpio_pin *, uint32_t);
+
+/*
+ * Driver stuff
+ */
+static int imx51_gpio_probe(device_t);
+static int imx51_gpio_attach(device_t);
+static int imx51_gpio_detach(device_t);
+static int imx51_gpio_intr(void *);
+
+/*
+ * GPIO interface
+ */
+static int imx51_gpio_pin_max(device_t, int *);
+static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
+static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
+static int imx51_gpio_pin_getname(device_t, uint32_t, char *);
+static int imx51_gpio_pin_setflags(device_t, uint32_t, uint32_t);
+static int imx51_gpio_pin_set(device_t, uint32_t, unsigned int);
+static int imx51_gpio_pin_get(device_t, uint32_t, unsigned int *);
+static int imx51_gpio_pin_toggle(device_t, uint32_t pin);
+
+static void
+imx51_gpio_pin_configure(struct imx51_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;
+ SET4(sc, IMX_GPIO_OE_REG, (1 << pin->gp_pin));
+ }
+ else {
+ pin->gp_flags |= GPIO_PIN_INPUT;
+ CLEAR4(sc, IMX_GPIO_OE_REG, (1 << pin->gp_pin));
+ }
+ }
+
+ GPIO_UNLOCK(sc);
+}
+
+static int
+imx51_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+ *maxpin = NGPIO - 1;
+ return (0);
+}
+
+static int
+imx51_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+ struct imx51_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
+imx51_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+ struct imx51_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
+imx51_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+ struct imx51_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
+imx51_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+ struct imx51_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);
+
+ /* Filter out 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);
+
+ imx51_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
+
+
+ return (0);
+}
+
+static int
+imx51_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+ struct imx51_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)
+ SET4(sc, IMX_GPIO_DR_REG, (1 << i));
+ else
+ CLEAR4(sc, IMX_GPIO_DR_REG, (1 << i));
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+imx51_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+ struct imx51_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, IMX_GPIO_DR_REG) >> i) & 1;
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+imx51_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+ struct imx51_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, IMX_GPIO_DR_REG,
+ (READ4(sc, IMX_GPIO_DR_REG) ^ (1 << i)));
+ GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+imx51_gpio_intr(void *arg)
+{
+ struct imx51_gpio_softc *sc;
+ uint32_t input, value;
+
+ sc = arg;
+ input = READ4(sc, IMX_GPIO_ISR_REG);
+ value = input & READ4(sc, IMX_GPIO_IMR_REG);
+ WRITE4(sc, IMX_GPIO_DR_REG, input);
+
+ if (!value)
+ goto intr_done;
+
+ /* TODO: interrupt handling */
+
+intr_done:
+ return (FILTER_HANDLED);
+}
+
+static int
+imx51_gpio_probe(device_t dev)
+{
+
+ if (ofw_bus_is_compatible(dev, "fsl,imx51-gpio")) {
+ device_set_desc(dev, "i.MX515 GPIO Controller");
+ return (BUS_PROBE_DEFAULT);
+ }
+
+ return (ENXIO);
+}
+
+static int
+imx51_gpio_attach(device_t dev)
+{
+ struct imx51_gpio_softc *sc;
+ int i, irq;
+
+ sc = device_get_softc(dev);
+ mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+ if (bus_alloc_resources(dev, imx_gpio_spec, sc->sc_res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ sc->dev = dev;
+ sc->gpio_npins = NGPIO;
+ sc->sc_l_irq = 2;
+ sc->sc_iot = rman_get_bustag(sc->sc_res[0]);
+ sc->sc_ioh = rman_get_bushandle(sc->sc_res[0]);
+
+ if (bus_alloc_resources(dev, imx_gpio0irq_spec, &sc->sc_res[3]) == 0) {
+ /*
+ * First GPIO unit able to serve +8 interrupts for 8 first
+ * pins.
+ */
+ sc->sc_l_irq = 10;
+ }
+
+ for (irq = 1; irq <= sc->sc_l_irq; irq ++) {
+ if ((bus_setup_intr(dev, sc->sc_res[irq], INTR_TYPE_MISC,
+ imx51_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, IMX_GPIO_OE_REG) & (1 << i)) ? GPIO_PIN_OUTPUT:
+ GPIO_PIN_INPUT;
+ snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
+ "imx_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
+imx51_gpio_detach(device_t dev)
+{
+ struct imx51_gpio_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
+
+ bus_generic_detach(dev);
+
+ if (sc->sc_res[3])
+ bus_release_resources(dev, imx_gpio0irq_spec, &sc->sc_res[3]);
+
+ if (sc->sc_res[0])
+ bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
+
+ mtx_destroy(&sc->sc_mtx);
+
+ return(0);
+}
+
+static device_method_t imx51_gpio_methods[] = {
+ DEVMETHOD(device_probe, imx51_gpio_probe),
+ DEVMETHOD(device_attach, imx51_gpio_attach),
+ DEVMETHOD(device_detach, imx51_gpio_detach),
+
+ /* GPIO protocol */
+ DEVMETHOD(gpio_pin_max, imx51_gpio_pin_max),
+ DEVMETHOD(gpio_pin_getname, imx51_gpio_pin_getname),
+ DEVMETHOD(gpio_pin_getflags, imx51_gpio_pin_getflags),
+ DEVMETHOD(gpio_pin_getcaps, imx51_gpio_pin_getcaps),
+ DEVMETHOD(gpio_pin_setflags, imx51_gpio_pin_setflags),
+ DEVMETHOD(gpio_pin_get, imx51_gpio_pin_get),
+ DEVMETHOD(gpio_pin_set, imx51_gpio_pin_set),
+ DEVMETHOD(gpio_pin_toggle, imx51_gpio_pin_toggle),
+ {0, 0},
+};
+
+static driver_t imx51_gpio_driver = {
+ "gpio",
+ imx51_gpio_methods,
+ sizeof(struct imx51_gpio_softc),
+};
+static devclass_t imx51_gpio_devclass;
+
+DRIVER_MODULE(imx51_gpio, simplebus, imx51_gpio_driver, imx51_gpio_devclass,
+ 0, 0);
diff --git a/sys/arm/freescale/imx/imx51_iomux.c b/sys/arm/freescale/imx/imx51_iomux.c
new file mode 100644
index 0000000..62f3509
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_iomux.c
@@ -0,0 +1,232 @@
+/* $NetBSD: imx51_iomux.c,v 1.3 2012/04/15 09:51:31 bsh Exp $ */
+
+/*
+ * Copyright (c) 2009, 2010 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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 <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.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 <arm/freescale/imx/imx51_iomuxvar.h>
+#include <arm/freescale/imx/imx51_iomuxreg.h>
+
+
+#define IOMUX_WRITE(_sc, _r, _v) \
+ bus_write_4((_sc)->sc_res, (_r), (_v))
+#define IOMUX_READ(_sc, _r) \
+ bus_read_4((_sc)->sc_res, (_r))
+#define IOMUX_SET(_sc, _r, _m) \
+ IOMUX_WRITE((_sc), (_r), IOMUX_READ((_sc), (_r)) | (_m))
+#define IOMUX_CLEAR(_sc, _r, _m) \
+ IOMUX_WRITE((_sc), (_r), IOMUX_READ((_sc), (_r)) & ~(_m))
+
+struct iomux_softc {
+ struct resource *sc_res;
+ device_t sc_dev;
+};
+
+static int iomux_probe(device_t);
+static int iomux_attach(device_t);
+
+static struct iomux_softc *iomuxsc = NULL;
+
+static struct resource_spec imx_iomux_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Global registers */
+ { -1, 0 }
+};
+
+static int
+iomux_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,imx51-iomux"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale i.MX51 IO pins multiplexor");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+iomux_attach(device_t dev)
+{
+ struct iomux_softc * sc;
+
+ sc = device_get_softc(dev);
+
+ if (bus_alloc_resources(dev, imx_iomux_spec, &sc->sc_res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ iomuxsc = sc;
+
+ /*
+ * XXX: place to fetch all info about pinmuxing from loader data
+ * (FDT blob) and apply. Loader (1st one) must care about
+ * device-to-device difference.
+ */
+
+ return (0);
+}
+
+static void
+iomux_set_function_sub(struct iomux_softc *sc, uint32_t pin, uint32_t fn)
+{
+ bus_size_t mux_ctl_reg = IOMUX_PIN_TO_MUX_ADDRESS(pin);
+
+ if (mux_ctl_reg != IOMUX_MUX_NONE)
+ IOMUX_WRITE(sc, mux_ctl_reg, fn);
+}
+
+void
+iomux_set_function(unsigned int pin, unsigned int fn)
+{
+
+ if (iomuxsc == NULL)
+ return;
+ iomux_set_function_sub(iomuxsc, pin, fn);
+}
+
+static void
+iomux_set_pad_sub(struct iomux_softc *sc, uint32_t pin, uint32_t config)
+{
+ bus_size_t pad_ctl_reg = IOMUX_PIN_TO_PAD_ADDRESS(pin);
+
+ if (pad_ctl_reg != IOMUX_PAD_NONE)
+ IOMUX_WRITE(sc, pad_ctl_reg, config);
+}
+
+void
+iomux_set_pad(unsigned int pin, unsigned int config)
+{
+
+ if (iomuxsc == NULL)
+ return;
+ iomux_set_pad_sub(iomuxsc, pin, config);
+}
+
+#ifdef notyet
+void
+iomux_set_input(unsigned int input, unsigned int config)
+{
+ bus_size_t input_ctl_reg = input;
+
+ bus_space_write_4(iomuxsc->iomux_memt, iomuxsc->iomux_memh,
+ input_ctl_reg, config);
+}
+#endif
+
+void
+iomux_mux_config(const struct iomux_conf *conflist)
+{
+ int i;
+
+ if (iomuxsc == NULL)
+ return;
+ for (i = 0; conflist[i].pin != IOMUX_CONF_EOT; i++) {
+ iomux_set_pad_sub(iomuxsc, conflist[i].pin, conflist[i].pad);
+ iomux_set_function_sub(iomuxsc, conflist[i].pin,
+ conflist[i].mux);
+ }
+}
+
+#ifdef notyet
+void
+iomux_input_config(const struct iomux_input_conf *conflist)
+{
+ int i;
+
+ if (iomuxsc == NULL)
+ return;
+ for (i = 0; conflist[i].inout != -1; i++) {
+ iomux_set_inout(iomuxsc, conflist[i].inout,
+ conflist[i].inout_mode);
+ }
+}
+#endif
+
+static device_method_t imx_iomux_methods[] = {
+ DEVMETHOD(device_probe, iomux_probe),
+ DEVMETHOD(device_attach, iomux_attach),
+
+ DEVMETHOD_END
+};
+
+static driver_t imx_iomux_driver = {
+ "imx_iomux",
+ imx_iomux_methods,
+ sizeof(struct iomux_softc),
+};
+
+static devclass_t imx_iomux_devclass;
+
+EARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver,
+ imx_iomux_devclass, 0, 0, BUS_PASS_BUS - 1);
+
diff --git a/sys/arm/freescale/imx/imx51_iomuxreg.h b/sys/arm/freescale/imx/imx51_iomuxreg.h
new file mode 100644
index 0000000..f965b32
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_iomuxreg.h
@@ -0,0 +1,761 @@
+/*
+ * This file was generated automatically from PDF file by mkiomuxreg_imx51.rb
+ *
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _IMX51_IOMUXREG_H
+#define _IMX51_IOMUXREG_H
+
+#define IOMUXC_MUX_CTL 0x001c /* multiplex control */
+#define IOMUX_CONFIG_SION (1 << 4)
+#define IOMUX_CONFIG_ALT0 (0)
+#define IOMUX_CONFIG_ALT1 (1)
+#define IOMUX_CONFIG_ALT2 (2)
+#define IOMUX_CONFIG_ALT3 (3)
+#define IOMUX_CONFIG_ALT4 (4)
+#define IOMUX_CONFIG_ALT5 (5)
+#define IOMUX_CONFIG_ALT6 (6)
+#define IOMUX_CONFIG_ALT7 (7)
+#define IOMUXC_PAD_CTL 0x03f0 /* pad control */
+#define PAD_CTL_HVE (1 << 13)
+#define PAD_CTL_DDR_INPUT (1 << 9)
+#define PAD_CTL_HYS (1 << 8)
+#define PAD_CTL_PKE (1 << 7)
+#define PAD_CTL_PUE (1 << 6)
+#define PAD_CTL_PULL (PAD_CTL_PKE|PAD_CTL_PUE)
+#define PAD_CTL_KEEPER (PAD_CTL_PKE|0)
+#define PAD_CTL_PUS_100K_PD (0x0 << 4)
+#define PAD_CTL_PUS_47K_PU (0x1 << 4)
+#define PAD_CTL_PUS_100K_PU (0x2 << 4)
+#define PAD_CTL_PUS_22K_PU (0x3 << 4)
+#define PAD_CTL_ODE (1 << 3) /* opendrain */
+#define PAD_CTL_DSE_LOW (0x0 << 1)
+#define PAD_CTL_DSE_MID (0x1 << 1)
+#define PAD_CTL_DSE_HIGH (0x2 << 1)
+#define PAD_CTL_DSE_MAX (0x3 << 1)
+#define PAD_CTL_SRE (1 << 0)
+#define IOMUXC_INPUT_CTL 0x08c4 /* input control */
+#define INPUT_DAISY_0 0
+#define INPUT_DAISY_1 1
+#define INPUT_DAISY_2 2
+#define INPUT_DAISY_3 3
+#define INPUT_DAISY_4 4
+#define INPUT_DAISY_5 5
+#define INPUT_DAISY_6 6
+#define INPUT_DAISY_7 7
+
+/*
+ * IOMUX index
+ */
+#define IOMUX_PIN_TO_MUX_ADDRESS(pin) (((pin) >> 16) & 0xffff)
+#define IOMUX_PIN_TO_PAD_ADDRESS(pin) (((pin) >> 0) & 0xffff)
+
+#define IOMUX_PIN(mux_adr, pad_adr) \
+ (((mux_adr) << 16) | (((pad_adr) << 0)))
+#define IOMUX_MUX_NONE 0xffff
+#define IOMUX_PAD_NONE 0xffff
+
+/* register offset address */
+#define IOMUXC_GPR0 0x0000
+#define IOMUXC_GPR1 0x0004
+#define IOMUXC_OBSERVE_MUX_0 0x0008
+#define IOMUXC_OBSERVE_MUX_1 0x000c
+#define IOMUXC_OBSERVE_MUX_2 0x0010
+#define IOMUXC_OBSERVE_MUX_3 0x0014
+#define IOMUXC_OBSERVE_MUX_4 0x0018
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA0 0x001c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA1 0x0020
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA2 0x0024
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA3 0x0028
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA4 0x002c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA5 0x0030
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA6 0x0034
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA7 0x0038
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA8 0x003c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA9 0x0040
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA10 0x0044
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA11 0x0048
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA12 0x004c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA13 0x0050
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA14 0x0054
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DA15 0x0058
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D16 0x005c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D17 0x0060
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D18 0x0064
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D19 0x0068
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D20 0x006c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D21 0x0070
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D22 0x0074
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D23 0x0078
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D24 0x007c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D25 0x0080
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D26 0x0084
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D27 0x0088
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D28 0x008c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D29 0x0090
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D30 0x0094
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_D31 0x0098
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A16 0x009c
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A17 0x00a0
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A18 0x00a4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A19 0x00a8
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A20 0x00ac
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A21 0x00b0
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A22 0x00b4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A23 0x00b8
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A24 0x00bc
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A25 0x00c0
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A26 0x00c4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_A27 0x00c8
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_EB0 0x00cc
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_EB1 0x00d0
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_EB2 0x00d4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_EB3 0x00d8
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_OE 0x00dc
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_CS0 0x00e0
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_CS1 0x00e4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_CS2 0x00e8
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_CS3 0x00ec
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_CS4 0x00f0
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_CS5 0x00f4
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_DTACK 0x00f8
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_LBA 0x00fc
+#define IOMUXC_SW_MUX_CTL_PAD_EIM_CRE 0x0100
+#define IOMUXC_SW_MUX_CTL_PAD_DRAM_CS1 0x0104
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_WE_B 0x0108
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_RE_B 0x010c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_ALE 0x0110
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CLE 0x0114
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_WP_B 0x0118
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_RB0 0x011c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_RB1 0x0120
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_RB2 0x0124
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_RB3 0x0128
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO_NAND 0x012c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS0 0x0130
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS1 0x0134
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS2 0x0138
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS3 0x013c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS4 0x0140
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS5 0x0144
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS6 0x0148
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS7 0x014c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_RDY_INT 0x0150
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D15 0x0154
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D14 0x0158
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D13 0x015c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D12 0x0160
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D11 0x0164
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D10 0x0168
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D9 0x016c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D8 0x0170
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D7 0x0174
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D6 0x0178
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D5 0x017c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D4 0x0180
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D3 0x0184
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D2 0x0188
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D1 0x018c
+#define IOMUXC_SW_MUX_CTL_PAD_NANDF_D0 0x0190
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D8 0x0194
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D9 0x0198
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D10 0x019c
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D11 0x01a0
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D12 0x01a4
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D13 0x01a8
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D14 0x01ac
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D15 0x01b0
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D16 0x01b4
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D17 0x01b8
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D18 0x01bc
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_D19 0x01c0
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_VSYNC 0x01c4
+#define IOMUXC_SW_MUX_CTL_PAD_CSI1_HSYNC 0x01c8
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D12 0x01cc
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D13 0x01d0
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D14 0x01d4
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D15 0x01d8
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D16 0x01dc
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D17 0x01e0
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D18 0x01e4
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_D19 0x01e8
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_VSYNC 0x01ec
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_HSYNC 0x01f0
+#define IOMUXC_SW_MUX_CTL_PAD_CSI2_PIXCLK 0x01f4
+#define IOMUXC_SW_MUX_CTL_PAD_I2C1_CLK 0x01f8
+#define IOMUXC_SW_MUX_CTL_PAD_I2C1_DAT 0x01fc
+#define IOMUXC_SW_MUX_CTL_PAD_AUD3_BB_TXD 0x0200
+#define IOMUXC_SW_MUX_CTL_PAD_AUD3_BB_RXD 0x0204
+#define IOMUXC_SW_MUX_CTL_PAD_AUD3_BB_CK 0x0208
+#define IOMUXC_SW_MUX_CTL_PAD_AUD3_BB_FS 0x020c
+#define IOMUXC_SW_MUX_CTL_PAD_CSPI1_MOSI 0x0210
+#define IOMUXC_SW_MUX_CTL_PAD_CSPI1_MISO 0x0214
+#define IOMUXC_SW_MUX_CTL_PAD_CSPI1_SS0 0x0218
+#define IOMUXC_SW_MUX_CTL_PAD_CSPI1_SS1 0x021c
+#define IOMUXC_SW_MUX_CTL_PAD_CSPI1_RDY 0x0220
+#define IOMUXC_SW_MUX_CTL_PAD_CSPI1_SCLK 0x0224
+#define IOMUXC_SW_MUX_CTL_PAD_UART1_RXD 0x0228
+#define IOMUXC_SW_MUX_CTL_PAD_UART1_TXD 0x022c
+#define IOMUXC_SW_MUX_CTL_PAD_UART1_RTS 0x0230
+#define IOMUXC_SW_MUX_CTL_PAD_UART1_CTS 0x0234
+#define IOMUXC_SW_MUX_CTL_PAD_UART2_RXD 0x0238
+#define IOMUXC_SW_MUX_CTL_PAD_UART2_TXD 0x023c
+#define IOMUXC_SW_MUX_CTL_PAD_UART3_RXD 0x0240
+#define IOMUXC_SW_MUX_CTL_PAD_UART3_TXD 0x0244
+#define IOMUXC_SW_MUX_CTL_PAD_OWIRE_LINE 0x0248
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0 0x024c
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1 0x0250
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2 0x0254
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3 0x0258
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL0 0x025c
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL1 0x0260
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL2 0x0264
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL3 0x0268
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL4 0x026c
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL5 0x0270
+#define IOMUXC_SW_MUX_CTL_PAD_JTAG_DE_B 0x0274
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_CLK 0x0278
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DIR 0x027c
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_STP 0x0280
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_NXT 0x0284
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA0 0x0288
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA1 0x028c
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA2 0x0290
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA3 0x0294
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA4 0x0298
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA5 0x029c
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA6 0x02a0
+#define IOMUXC_SW_MUX_CTL_PAD_USBH1_DATA7 0x02a4
+#define IOMUXC_SW_MUX_CTL_PAD_DI1_PIN11 0x02a8
+#define IOMUXC_SW_MUX_CTL_PAD_DI1_PIN12 0x02ac
+#define IOMUXC_SW_MUX_CTL_PAD_DI1_PIN13 0x02b0
+#define IOMUXC_SW_MUX_CTL_PAD_DI1_D0_CS 0x02b4
+#define IOMUXC_SW_MUX_CTL_PAD_DI1_D1_CS 0x02b8
+#define IOMUXC_SW_MUX_CTL_PAD_DISPB2_SER_DIN 0x02bc
+#define IOMUXC_SW_MUX_CTL_PAD_DISPB2_SER_DIO 0x02c0
+#define IOMUXC_SW_MUX_CTL_PAD_DISPB2_SER_CLK 0x02c4
+#define IOMUXC_SW_MUX_CTL_PAD_DISPB2_SER_RS 0x02c8
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT0 0x02cc
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT1 0x02d0
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT2 0x02d4
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT3 0x02d8
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT4 0x02dc
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT5 0x02e0
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT6 0x02e4
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT7 0x02e8
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT8 0x02ec
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT9 0x02f0
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT10 0x02f4
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT11 0x02f8
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT12 0x02fc
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT13 0x0300
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT14 0x0304
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT15 0x0308
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT16 0x030c
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT17 0x0310
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT18 0x0314
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT19 0x0318
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT20 0x031c
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT21 0x0320
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT22 0x0324
+#define IOMUXC_SW_MUX_CTL_PAD_DISP1_DAT23 0x0328
+#define IOMUXC_SW_MUX_CTL_PAD_DI1_PIN3 0x032c
+#define IOMUXC_SW_MUX_CTL_PAD_DI1_PIN2 0x0330
+#define IOMUXC_SW_MUX_CTL_PAD_DI_GP1 0x0334
+#define IOMUXC_SW_MUX_CTL_PAD_DI_GP2 0x0338
+#define IOMUXC_SW_MUX_CTL_PAD_DI_GP3 0x033c
+#define IOMUXC_SW_MUX_CTL_PAD_DI2_PIN4 0x0340
+#define IOMUXC_SW_MUX_CTL_PAD_DI2_PIN2 0x0344
+#define IOMUXC_SW_MUX_CTL_PAD_DI2_PIN3 0x0348
+#define IOMUXC_SW_MUX_CTL_PAD_DI2_DISP_CLK 0x034c
+#define IOMUXC_SW_MUX_CTL_PAD_DI_GP4 0x0350
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT0 0x0354
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT1 0x0358
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT2 0x035c
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT3 0x0360
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT4 0x0364
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT5 0x0368
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT6 0x036c
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT7 0x0370
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT8 0x0374
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT9 0x0378
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT10 0x037c
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT11 0x0380
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT12 0x0384
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT13 0x0388
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT14 0x038c
+#define IOMUXC_SW_MUX_CTL_PAD_DISP2_DAT15 0x0390
+#define IOMUXC_SW_MUX_CTL_PAD_SD1_CMD 0x0394
+#define IOMUXC_SW_MUX_CTL_PAD_SD1_CLK 0x0398
+#define IOMUXC_SW_MUX_CTL_PAD_SD1_DATA0 0x039c
+#define IOMUXC_SW_MUX_CTL_PAD_SD1_DATA1 0x03a0
+#define IOMUXC_SW_MUX_CTL_PAD_SD1_DATA2 0x03a4
+#define IOMUXC_SW_MUX_CTL_PAD_SD1_DATA3 0x03a8
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_0 0x03ac
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_1 0x03b0
+#define IOMUXC_SW_MUX_CTL_PAD_SD2_CMD 0x03b4
+#define IOMUXC_SW_MUX_CTL_PAD_SD2_CLK 0x03b8
+#define IOMUXC_SW_MUX_CTL_PAD_SD2_DATA0 0x03bc
+#define IOMUXC_SW_MUX_CTL_PAD_SD2_DATA1 0x03c0
+#define IOMUXC_SW_MUX_CTL_PAD_SD2_DATA2 0x03c4
+#define IOMUXC_SW_MUX_CTL_PAD_SD2_DATA3 0x03c8
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_2 0x03cc
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_3 0x03d0
+#define IOMUXC_SW_MUX_CTL_PAD_PMIC_INT_REQ 0x03d4
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_4 0x03d8
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_5 0x03dc
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_6 0x03e0
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_7 0x03e4
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_8 0x03e8
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_9 0x03ec
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D16 0x03f0
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D17 0x03f4
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D18 0x03f8
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D19 0x03fc
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D20 0x0400
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D21 0x0404
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D22 0x0408
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D23 0x040c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D24 0x0410
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D25 0x0414
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D26 0x0418
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D27 0x041c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D28 0x0420
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D29 0x0424
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D30 0x0428
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_D31 0x042c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A16 0x0430
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A17 0x0434
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A18 0x0438
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A19 0x043c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A20 0x0440
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A21 0x0444
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A22 0x0448
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A23 0x044c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A24 0x0450
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A25 0x0454
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A26 0x0458
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_A27 0x045c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_EB0 0x0460
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_EB1 0x0464
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_EB2 0x0468
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_EB3 0x046c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_OE 0x0470
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_CS0 0x0474
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_CS1 0x0478
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_CS2 0x047c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_CS3 0x0480
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_CS4 0x0484
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_CS5 0x0488
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_DTACK 0x048c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT 0x0490
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_LBA 0x0494
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK 0x0498
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_RW 0x049c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_CRE 0x04a0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS 0x04a4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS 0x04a8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDWE 0x04ac
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE0 0x04b0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE1 0x04b4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK 0x04b8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 0x04bc
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 0x04c0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 0x04c4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 0x04c8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CS0 0x04cc
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CS1 0x04d0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 0x04d4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 0x04d8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2 0x04dc
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3 0x04e0
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_WE_B 0x04e4
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_RE_B 0x04e8
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_ALE 0x04ec
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CLE 0x04f0
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_WP_B 0x04f4
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_RB0 0x04f8
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_RB1 0x04fc
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_RB2 0x0500
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_RB3 0x0504
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_SDBA2 0x0508
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_SDODT1 0x050c
+#define IOMUXC_SW_PAD_CTL_PAD_EIM_SDODT0 0x0510
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO_NAND 0x0514
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS0 0x0518
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS1 0x051c
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS2 0x0520
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS3 0x0524
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS4 0x0528
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS5 0x052c
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS6 0x0530
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS7 0x0534
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_RDY_INT 0x0538
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D15 0x053c
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D14 0x0540
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D13 0x0544
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D12 0x0548
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D11 0x054c
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D10 0x0550
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D9 0x0554
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D8 0x0558
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D7 0x055c
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D6 0x0560
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D5 0x0564
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D4 0x0568
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D3 0x056c
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D2 0x0570
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D1 0x0574
+#define IOMUXC_SW_PAD_CTL_PAD_NANDF_D0 0x0578
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D8 0x057c
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D9 0x0580
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D10 0x0584
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D11 0x0588
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D12 0x058c
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D13 0x0590
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D14 0x0594
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D15 0x0598
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D16 0x059c
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D17 0x05a0
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D18 0x05a4
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_D19 0x05a8
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_VSYNC 0x05ac
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_HSYNC 0x05b0
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_PIXCLK 0x05b4
+#define IOMUXC_SW_PAD_CTL_PAD_CSI1_MCLK 0x05b8
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D12 0x05bc
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D13 0x05c0
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D14 0x05c4
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D15 0x05c8
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D16 0x05cc
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D17 0x05d0
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D18 0x05d4
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_D19 0x05d8
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_VSYNC 0x05dc
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_HSYNC 0x05e0
+#define IOMUXC_SW_PAD_CTL_PAD_CSI2_PIXCLK 0x05e4
+#define IOMUXC_SW_PAD_CTL_PAD_I2C1_CLK 0x05e8
+#define IOMUXC_SW_PAD_CTL_PAD_I2C1_DAT 0x05ec
+#define IOMUXC_SW_PAD_CTL_PAD_AUD3_BB_TXD 0x05f0
+#define IOMUXC_SW_PAD_CTL_PAD_AUD3_BB_RXD 0x05f4
+#define IOMUXC_SW_PAD_CTL_PAD_AUD3_BB_CK 0x05f8
+#define IOMUXC_SW_PAD_CTL_PAD_AUD3_BB_FS 0x05fc
+#define IOMUXC_SW_PAD_CTL_PAD_CSPI1_MOSI 0x0600
+#define IOMUXC_SW_PAD_CTL_PAD_CSPI1_MISO 0x0604
+#define IOMUXC_SW_PAD_CTL_PAD_CSPI1_SS0 0x0608
+#define IOMUXC_SW_PAD_CTL_PAD_CSPI1_SS1 0x060c
+#define IOMUXC_SW_PAD_CTL_PAD_CSPI1_RDY 0x0610
+#define IOMUXC_SW_PAD_CTL_PAD_CSPI1_SCLK 0x0614
+#define IOMUXC_SW_PAD_CTL_PAD_UART1_RXD 0x0618
+#define IOMUXC_SW_PAD_CTL_PAD_UART1_TXD 0x061c
+#define IOMUXC_SW_PAD_CTL_PAD_UART1_RTS 0x0620
+#define IOMUXC_SW_PAD_CTL_PAD_UART1_CTS 0x0624
+#define IOMUXC_SW_PAD_CTL_PAD_UART2_RXD 0x0628
+#define IOMUXC_SW_PAD_CTL_PAD_UART2_TXD 0x062c
+#define IOMUXC_SW_PAD_CTL_PAD_UART3_RXD 0x0630
+#define IOMUXC_SW_PAD_CTL_PAD_UART3_TXD 0x0634
+#define IOMUXC_SW_PAD_CTL_PAD_OWIRE_LINE 0x0638
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW0 0x063c
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW1 0x0640
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW2 0x0644
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW3 0x0648
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL0 0x064c
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL1 0x0650
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL2 0x0654
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL3 0x0658
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL4 0x065c
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL5 0x0660
+#define IOMUXC_SW_PAD_CTL_PAD_JTAG_TCK 0x0664
+#define IOMUXC_SW_PAD_CTL_PAD_JTAG_TMS 0x0668
+#define IOMUXC_SW_PAD_CTL_PAD_JTAG_TDI 0x066c
+#define IOMUXC_SW_PAD_CTL_PAD_JTAG_TRSTB 0x0670
+#define IOMUXC_SW_PAD_CTL_PAD_JTAG_MOD 0x0674
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_CLK 0x0678
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DIR 0x067c
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_STP 0x0680
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_NXT 0x0684
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA0 0x0688
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA1 0x068c
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA2 0x0690
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA3 0x0694
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA4 0x0698
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA5 0x069c
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA6 0x06a0
+#define IOMUXC_SW_PAD_CTL_PAD_USBH1_DATA7 0x06a4
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_PIN11 0x06a8
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_PIN12 0x06ac
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_PIN13 0x06b0
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_D0_CS 0x06b4
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_D1_CS 0x06b8
+#define IOMUXC_SW_PAD_CTL_PAD_DISPB2_SER_DIN 0x06bc
+#define IOMUXC_SW_PAD_CTL_PAD_DISPB2_SER_DIO 0x06c0
+#define IOMUXC_SW_PAD_CTL_PAD_DISPB2_SER_CLK 0x06c4
+#define IOMUXC_SW_PAD_CTL_PAD_DISPB2_SER_RS 0x06c8
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT0 0x06cc
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT1 0x06d0
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT2 0x06d4
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT3 0x06d8
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT4 0x06dc
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT5 0x06e0
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT6 0x06e4
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT7 0x06e8
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT8 0x06ec
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT9 0x06f0
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT10 0x06f4
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT11 0x06f8
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT12 0x06fc
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT13 0x0700
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT14 0x0704
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT15 0x0708
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT16 0x070c
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT17 0x0710
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT18 0x0714
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT19 0x0718
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT20 0x071c
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT21 0x0720
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT22 0x0724
+#define IOMUXC_SW_PAD_CTL_PAD_DISP1_DAT23 0x0728
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_PIN3 0x072c
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_DISP_CLK 0x0730
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_PIN2 0x0734
+#define IOMUXC_SW_PAD_CTL_PAD_DI1_PIN15 0x0738
+#define IOMUXC_SW_PAD_CTL_PAD_DI_GP1 0x073c
+#define IOMUXC_SW_PAD_CTL_PAD_DI_GP2 0x0740
+#define IOMUXC_SW_PAD_CTL_PAD_DI_GP3 0x0744
+#define IOMUXC_SW_PAD_CTL_PAD_DI2_PIN4 0x0748
+#define IOMUXC_SW_PAD_CTL_PAD_DI2_PIN2 0x074c
+#define IOMUXC_SW_PAD_CTL_PAD_DI2_PIN3 0x0750
+#define IOMUXC_SW_PAD_CTL_PAD_DI2_DISP_CLK 0x0754
+#define IOMUXC_SW_PAD_CTL_PAD_DI_GP4 0x0758
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT0 0x075c
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT1 0x0760
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT2 0x0764
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT3 0x0768
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT4 0x076c
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT5 0x0770
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT6 0x0774
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT7 0x0778
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT8 0x077c
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT9 0x0780
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT10 0x0784
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT11 0x0788
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT12 0x078c
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT13 0x0790
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT14 0x0794
+#define IOMUXC_SW_PAD_CTL_PAD_DISP2_DAT15 0x0798
+#define IOMUXC_SW_PAD_CTL_PAD_SD1_CMD 0x079c
+#define IOMUXC_SW_PAD_CTL_PAD_SD1_CLK 0x07a0
+#define IOMUXC_SW_PAD_CTL_PAD_SD1_DATA0 0x07a4
+#define IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1 0x07a8
+#define IOMUXC_SW_PAD_CTL_PAD_SD1_DATA2 0x07ac
+#define IOMUXC_SW_PAD_CTL_PAD_SD1_DATA3 0x07b0
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_0 0x07b4
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_1 0x07b8
+#define IOMUXC_SW_PAD_CTL_PAD_SD2_CMD 0x07bc
+#define IOMUXC_SW_PAD_CTL_PAD_SD2_CLK 0x07c0
+#define IOMUXC_SW_PAD_CTL_PAD_SD2_DATA0 0x07c4
+#define IOMUXC_SW_PAD_CTL_PAD_SD2_DATA1 0x07c8
+#define IOMUXC_SW_PAD_CTL_PAD_SD2_DATA2 0x07cc
+#define IOMUXC_SW_PAD_CTL_PAD_SD2_DATA3 0x07d0
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_2 0x07d4
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_3 0x07d8
+#define IOMUXC_SW_PAD_CTL_PAD_RESET_IN_B 0x07dc
+#define IOMUXC_SW_PAD_CTL_PAD_POR_B 0x07e0
+#define IOMUXC_SW_PAD_CTL_PAD_BOOT_MODE1 0x07e4
+#define IOMUXC_SW_PAD_CTL_PAD_BOOT_MODE0 0x07e8
+#define IOMUXC_SW_PAD_CTL_PAD_PMIC_RDY 0x07ec
+#define IOMUXC_SW_PAD_CTL_PAD_CKIL 0x07f0
+#define IOMUXC_SW_PAD_CTL_PAD_PMIC_STBY_REQ 0x07f4
+#define IOMUXC_SW_PAD_CTL_PAD_PMIC_ON_REQ 0x07f8
+#define IOMUXC_SW_PAD_CTL_PAD_PMIC_INT_REQ 0x07fc
+#define IOMUXC_SW_PAD_CTL_PAD_CLK_SS 0x0800
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_4 0x0804
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_5 0x0808
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_6 0x080c
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_7 0x0810
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_8 0x0814
+#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_9 0x0818
+#define IOMUXC_SW_PAD_CTL_GRP_CSI2_PKE0 0x081c
+#define IOMUXC_SW_PAD_CTL_GRP_DDRPKS 0x0820
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_SR1 0x0824
+#define IOMUXC_SW_PAD_CTL_GRP_DISP2_PKE0 0x0828
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_B4 0x082c
+#define IOMUXC_SW_PAD_CTL_GRP_INDDR 0x0830
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_SR2 0x0834
+#define IOMUXC_SW_PAD_CTL_GRP_PKEDDR 0x0838
+#define IOMUXC_SW_PAD_CTL_GRP_DDR_A0 0x083c
+#define IOMUXC_SW_PAD_CTL_GRP_EMI_PKE0 0x0840
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_SR3 0x0844
+#define IOMUXC_SW_PAD_CTL_GRP_DDR_A1 0x0848
+#define IOMUXC_SW_PAD_CTL_GRP_DDRAPUS 0x084c
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_SR4 0x0850
+#define IOMUXC_SW_PAD_CTL_GRP_EMI_SR5 0x0854
+#define IOMUXC_SW_PAD_CTL_GRP_EMI_SR6 0x0858
+#define IOMUXC_SW_PAD_CTL_GRP_HYSDDR0 0x085c
+#define IOMUXC_SW_PAD_CTL_GRP_CSI1_PKE0 0x0860
+#define IOMUXC_SW_PAD_CTL_GRP_HYSDDR1 0x0864
+#define IOMUXC_SW_PAD_CTL_GRP_DISP1_PKE0 0x0868
+#define IOMUXC_SW_PAD_CTL_GRP_HYSDDR2 0x086c
+#define IOMUXC_SW_PAD_CTL_GRP_HVDDR 0x0870
+#define IOMUXC_SW_PAD_CTL_GRP_HYSDDR3 0x0874
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_SR_B0 0x0878
+#define IOMUXC_SW_PAD_CTL_GRP_DDRAPKS 0x087c
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_SR_B1 0x0880
+#define IOMUXC_SW_PAD_CTL_GRP_DDRPUS 0x0884
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_DS1 0x0888
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_SR_B2 0x088c
+#define IOMUXC_SW_PAD_CTL_GRP_PKEADDR 0x0890
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_DS2 0x0894
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_DS3 0x0898
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_SR_B4 0x089c
+#define IOMUXC_SW_PAD_CTL_GRP_INMODE1 0x08a0
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_B0 0x08a4
+#define IOMUXC_SW_PAD_CTL_GRP_EIM_DS4 0x08a8
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_B1 0x08ac
+#define IOMUXC_SW_PAD_CTL_GRP_DDR_SR_A0 0x08b0
+#define IOMUXC_SW_PAD_CTL_GRP_EMI_DS5 0x08b4
+#define IOMUXC_SW_PAD_CTL_GRP_DRAM_B2 0x08b8
+#define IOMUXC_SW_PAD_CTL_GRP_DDR_SR_A1 0x08bc
+#define IOMUXC_SW_PAD_CTL_GRP_EMI_DS6 0x08c0
+#define IOMUXC_AUDMUX_P4_INPUT_DA_AMX_SELECT_INPUT 0x08c4
+#define IOMUXC_AUDMUX_P4_INPUT_DB_AMX_SELECT_INPUT 0x08c8
+#define IOMUXC_AUDMUX_P4_INPUT_TXCLK_AMX_SELECT_INPUT 0x08cc
+#define IOMUXC_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT 0x08d0
+#define IOMUXC_AUDMUX_P5_INPUT_DA_AMX_SELECT_INPUT 0x08d4
+#define IOMUXC_AUDMUX_P5_INPUT_DB_AMX_SELECT_INPUT 0x08d8
+#define IOMUXC_AUDMUX_P5_INPUT_RXCLK_AMX_SELECT_INPUT 0x08dc
+#define IOMUXC_AUDMUX_P5_INPUT_RXFS_AMX_SELECT_INPUT 0x08e0
+#define IOMUXC_AUDMUX_P5_INPUT_TXCLK_AMX_SELECT_INPUT 0x08e4
+#define IOMUXC_AUDMUX_P5_INPUT_TXFS_AMX_SELECT_INPUT 0x08e8
+#define IOMUXC_AUDMUX_P6_INPUT_DA_AMX_SELECT_INPUT 0x08ec
+#define IOMUXC_AUDMUX_P6_INPUT_DB_AMX_SELECT_INPUT 0x08f0
+#define IOMUXC_AUDMUX_P6_INPUT_RXCLK_AMX_SELECT_INPUT 0x08f4
+#define IOMUXC_AUDMUX_P6_INPUT_RXFS_AMX_SELECT_INPUT 0x08f8
+#define IOMUXC_AUDMUX_P6_INPUT_TXCLK_AMX_SELECT_INPUT 0x08fc
+#define IOMUXC_AUDMUX_P6_INPUT_TXFS_AMX_SELECT_INPUT 0x0900
+#define IOMUXC_CCM_IPP_DI0_CLK_SELECT_INPUT 0x0904
+#define IOMUXC_CCM_IPP_DI1_CLK_SELECT_INPUT 0x0908
+#define IOMUXC_CCM_PLL1_BYPASS_CLK_SELECT_INPUT 0x090c
+#define IOMUXC_CCM_PLL2_BYPASS_CLK_SELECT_INPUT 0x0910
+#define IOMUXC_CSPI_IPP_CSPI_CLK_IN_SELECT_INPUT 0x0914
+#define IOMUXC_CSPI_IPP_IND_MISO_SELECT_INPUT 0x0918
+#define IOMUXC_CSPI_IPP_IND_MOSI_SELECT_INPUT 0x091c
+#define IOMUXC_CSPI_IPP_IND_SS1_B_SELECT_INPUT 0x0920
+#define IOMUXC_CSPI_IPP_IND_SS2_B_SELECT_INPUT 0x0924
+#define IOMUXC_CSPI_IPP_IND_SS3_B_SELECT_INPUT 0x0928
+#define IOMUXC_DPLLIP1_L1T_TOG_EN_SELECT_INPUT 0x092c
+#define IOMUXC_ECSPI2_IPP_IND_SS_B_1_SELECT_INPUT 0x0930
+#define IOMUXC_ECSPI2_IPP_IND_SS_B_3_SELECT_INPUT 0x0934
+#define IOMUXC_EMI_IPP_IND_RDY_INT_SELECT_INPUT 0x0938
+#define IOMUXC_ESDHC3_IPP_DAT0_IN_SELECT_INPUT 0x093c
+#define IOMUXC_ESDHC3_IPP_DAT1_IN_SELECT_INPUT 0x0940
+#define IOMUXC_ESDHC3_IPP_DAT2_IN_SELECT_INPUT 0x0944
+#define IOMUXC_ESDHC3_IPP_DAT3_IN_SELECT_INPUT 0x0948
+#define IOMUXC_FEC_FEC_COL_SELECT_INPUT 0x094c
+#define IOMUXC_FEC_FEC_CRS_SELECT_INPUT 0x0950
+#define IOMUXC_FEC_FEC_MDI_SELECT_INPUT 0x0954
+#define IOMUXC_FEC_FEC_RDATA_0_SELECT_INPUT 0x0958
+#define IOMUXC_FEC_FEC_RDATA_1_SELECT_INPUT 0x095c
+#define IOMUXC_FEC_FEC_RDATA_2_SELECT_INPUT 0x0960
+#define IOMUXC_FEC_FEC_RDATA_3_SELECT_INPUT 0x0964
+#define IOMUXC_FEC_FEC_RX_CLK_SELECT_INPUT 0x0968
+#define IOMUXC_FEC_FEC_RX_DV_SELECT_INPUT 0x096c
+#define IOMUXC_FEC_FEC_RX_ER_SELECT_INPUT 0x0970
+#define IOMUXC_FEC_FEC_TX_CLK_SELECT_INPUT 0x0974
+#define IOMUXC_GPIO3_IPP_IND_G_IN_1_SELECT_INPUT 0x0978
+#define IOMUXC_GPIO3_IPP_IND_G_IN_2_SELECT_INPUT 0x097c
+#define IOMUXC_GPIO3_IPP_IND_G_IN_3_SELECT_INPUT 0x0980
+#define IOMUXC_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT 0x0984
+#define IOMUXC_GPIO3_IPP_IND_G_IN_5_SELECT_INPUT 0x0988
+#define IOMUXC_GPIO3_IPP_IND_G_IN_6_SELECT_INPUT 0x098c
+#define IOMUXC_GPIO3_IPP_IND_G_IN_7_SELECT_INPUT 0x0990
+#define IOMUXC_GPIO3_IPP_IND_G_IN_8_SELECT_INPUT 0x0994
+#define IOMUXC_GPIO3_IPP_IND_G_IN_12_SELECT_INPUT 0x0998
+#define IOMUXC_HSC_MIPI_MIX_PAR0_VSYNC_SELECT_INPUT 0x09a4
+#define IOMUXC_HSC_MIPI_MIX_PAR1_DI_WAIT_SELECT_INPUT 0x09a8
+#define IOMUXC_HSC_MIPI_MIX_PAR_SISG_TRIG_SELECT_INPUT 0x09ac
+#define IOMUXC_I2C1_IPP_SCL_IN_SELECT_INPUT 0x09b0
+#define IOMUXC_I2C1_IPP_SDA_IN_SELECT_INPUT 0x09b4
+#define IOMUXC_I2C2_IPP_SCL_IN_SELECT_INPUT 0x09b8
+#define IOMUXC_I2C2_IPP_SDA_IN_SELECT_INPUT 0x09bc
+#define IOMUXC_IPU_IPP_DI_0_IND_DISPB_SD_D_SELECT_INPUT 0x09c0
+#define IOMUXC_IPU_IPP_DI_1_IND_DISPB_SD_D_SELECT_INPUT 0x09c4
+#define IOMUXC_KPP_IPP_IND_COL_6_SELECT_INPUT 0x09c8
+#define IOMUXC_KPP_IPP_IND_COL_7_SELECT_INPUT 0x09cc
+#define IOMUXC_KPP_IPP_IND_ROW_4_SELECT_INPUT 0x09d0
+#define IOMUXC_KPP_IPP_IND_ROW_5_SELECT_INPUT 0x09d4
+#define IOMUXC_KPP_IPP_IND_ROW_6_SELECT_INPUT 0x09d8
+#define IOMUXC_KPP_IPP_IND_ROW_7_SELECT_INPUT 0x09dc
+#define IOMUXC_UART1_IPP_UART_RTS_B_SELECT_INPUT 0x09e0
+#define IOMUXC_UART1_IPP_UART_RXD_MUX_SELECT_INPUT 0x09e4
+#define IOMUXC_UART2_IPP_UART_RTS_B_SELECT_INPUT 0x09e8
+#define IOMUXC_UART2_IPP_UART_RXD_MUX_SELECT_INPUT 0x09ec
+#define IOMUXC_UART3_IPP_UART_RTS_B_SELECT_INPUT 0x09f0
+#define IOMUXC_UART3_IPP_UART_RXD_MUX_SELECT_INPUT 0x09f4
+#define IOMUXC_USBOH3_IPP_IND_UH3_CLK_SELECT_INPUT 0x09f8
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_0_SELECT_INPUT 0x09fc
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_1_SELECT_INPUT 0x0a00
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_2_SELECT_INPUT 0x0a04
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_3_SELECT_INPUT 0x0a08
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_4_SELECT_INPUT 0x0a0c
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_5_SELECT_INPUT 0x0a10
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_6_SELECT_INPUT 0x0a14
+#define IOMUXC_USBOH3_IPP_IND_UH3_DATA_7_SELECT_INPUT 0x0a18
+#define IOMUXC_USBOH3_IPP_IND_UH3_DIR_SELECT_INPUT 0x0a1c
+#define IOMUXC_USBOH3_IPP_IND_UH3_NXT_SELECT_INPUT 0x0a20
+#define IOMUXC_USBOH3_IPP_IND_UH3_STP_SELECT_INPUT 0x0a24
+
+/* MUX & PAD Control */
+
+#define MUX_PIN(name) \
+ IOMUX_PIN(IOMUXC_SW_MUX_CTL_PAD_##name, \
+ IOMUXC_SW_PAD_CTL_PAD_##name)
+
+#define MUX_PIN_MUX(name) \
+ IOMUX_PIN(IOMUXC_SW_MUX_CTL_PAD_##name, IOMUX_PAD_NONE)
+
+#define MUX_PIN_PAD(name) \
+ IOMUX_PIN(IOMUX_MUX_NONE, IOMUXC_SW_PAD_CTL_PAD_##name)
+
+#define MUX_PIN_GRP(name) \
+ IOMUX_PIN(IOMUX_MUX_NONE, IOMUXC_SW_PAD_CTL_GRP_##name)
+
+#define MUX_PIN_PATH(name) \
+ IOMUX_PIN(IOMUXC_##name##_SELECT_INPUT, IOMUX_MUX_NONE)
+
+/* INPUT Control */
+
+#define MUX_SELECT(name) (name##_SELECT_INPUT)
+
+#endif /* _IMX51_IOMUXREG_H */
diff --git a/sys/arm/freescale/imx/imx51_iomuxvar.h b/sys/arm/freescale/imx/imx51_iomuxvar.h
new file mode 100644
index 0000000..908b705
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_iomuxvar.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+/* iomux utility functions */
+struct iomux_conf {
+ u_int pin;
+#define IOMUX_CONF_EOT ((u_int)(-1))
+ u_short mux;
+ u_short pad;
+};
+
+void iomux_set_function(u_int, u_int);
+void iomux_set_pad(u_int, u_int);
+#ifdef notyet
+void iomux_set_input(u_int, u_int);
+#endif
+void iomux_mux_config(const struct iomux_conf *);
diff --git a/sys/arm/freescale/imx/imx51_ipuv3.c b/sys/arm/freescale/imx/imx51_ipuv3.c
new file mode 100644
index 0000000..0f2e6d4
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_ipuv3.c
@@ -0,0 +1,876 @@
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#include <arm/freescale/imx/imx51_ccmvar.h>
+
+#include <arm/freescale/imx/imx51_ipuv3reg.h>
+
+#define IMX51_IPU_HSP_CLOCK 665000000
+#define IPU3FB_FONT_HEIGHT 16
+
+struct ipu3sc_softc {
+ device_t dev;
+ bus_addr_t pbase;
+ bus_addr_t vbase;
+
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ bus_space_handle_t cm_ioh;
+ bus_space_handle_t dp_ioh;
+ bus_space_handle_t di0_ioh;
+ bus_space_handle_t di1_ioh;
+ bus_space_handle_t dctmpl_ioh;
+ bus_space_handle_t dc_ioh;
+ bus_space_handle_t dmfc_ioh;
+ bus_space_handle_t idmac_ioh;
+ bus_space_handle_t cpmem_ioh;
+};
+
+struct video_adapter_softc {
+ /* Videoadpater part */
+ video_adapter_t va;
+
+ intptr_t fb_addr;
+ intptr_t fb_paddr;
+ unsigned int fb_size;
+
+ int bpp;
+ int depth;
+ unsigned int height;
+ unsigned int width;
+ unsigned int stride;
+
+ unsigned int xmargin;
+ unsigned int ymargin;
+
+ unsigned char *font;
+ int initialized;
+};
+
+static struct ipu3sc_softc *ipu3sc_softc;
+static struct video_adapter_softc va_softc;
+
+/* FIXME: not only 2 bytes color supported */
+static uint16_t colors[16] = {
+ 0x0000, /* black */
+ 0x001f, /* blue */
+ 0x07e0, /* green */
+ 0x07ff, /* cyan */
+ 0xf800, /* red */
+ 0xf81f, /* magenta */
+ 0x3800, /* brown */
+ 0xc618, /* light grey */
+ 0xc618, /* XXX: dark grey */
+ 0x001f, /* XXX: light blue */
+ 0x07e0, /* XXX: light green */
+ 0x07ff, /* XXX: light cyan */
+ 0xf800, /* XXX: light red */
+ 0xf81f, /* XXX: light magenta */
+ 0xffe0, /* yellow */
+ 0xffff, /* white */
+};
+static uint32_t colors_24[16] = {
+ 0x000000,/* Black */
+ 0x000080,/* Blue */
+ 0x008000,/* Green */
+ 0x008080,/* Cyan */
+ 0x800000,/* Red */
+ 0x800080,/* Magenta */
+ 0xcc6600,/* brown */
+ 0xC0C0C0,/* Silver */
+ 0x808080,/* Gray */
+ 0x0000FF,/* Light Blue */
+ 0x00FF00,/* Light Green */
+ 0x00FFFF,/* Light Cyan */
+ 0xFF0000,/* Light Red */
+ 0xFF00FF,/* Light Magenta */
+ 0xFFFF00,/* Yellow */
+ 0xFFFFFF,/* White */
+
+
+};
+
+#define IPUV3_READ(ipuv3, module, reg) \
+ bus_space_read_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg))
+#define IPUV3_WRITE(ipuv3, module, reg, val) \
+ bus_space_write_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg), (val))
+
+#define CPMEM_CHANNEL_OFFSET(_c) ((_c) * 0x40)
+#define CPMEM_WORD_OFFSET(_w) ((_w) * 0x20)
+#define CPMEM_DP_OFFSET(_d) ((_d) * 0x10000)
+#define IMX_IPU_DP0 0
+#define IMX_IPU_DP1 1
+#define CPMEM_CHANNEL(_dp, _ch, _w) \
+ (CPMEM_DP_OFFSET(_dp) + CPMEM_CHANNEL_OFFSET(_ch) + \
+ CPMEM_WORD_OFFSET(_w))
+#define CPMEM_OFFSET(_dp, _ch, _w, _o) \
+ (CPMEM_CHANNEL((_dp), (_ch), (_w)) + (_o))
+
+#define IPUV3_DEBUG 100
+
+#ifdef IPUV3_DEBUG
+#define SUBMOD_DUMP_REG(_sc, _m, _l) \
+ { \
+ int i; \
+ printf("*** " #_m " ***\n"); \
+ for (i = 0; i <= (_l); i += 4) { \
+ if ((i % 32) == 0) \
+ printf("%04x: ", i & 0xffff); \
+ printf("0x%08x%c", IPUV3_READ((_sc), _m, i), \
+ ((i + 4) % 32)?' ':'\n'); \
+ } \
+ printf("\n"); \
+ }
+#endif
+
+#ifdef IPUV3_DEBUG
+int ipuv3_debug = IPUV3_DEBUG;
+#define DPRINTFN(n,x) if (ipuv3_debug>(n)) printf x; else
+#else
+#define DPRINTFN(n,x)
+#endif
+
+static int ipu3_fb_probe(device_t);
+static int ipu3_fb_attach(device_t);
+
+static int
+ipu3_fb_malloc(struct ipu3sc_softc *sc, size_t size)
+{
+
+ sc->vbase = (uint32_t)contigmalloc(size, M_DEVBUF, M_ZERO, 0, ~0,
+ PAGE_SIZE, 0);
+ sc->pbase = vtophys(sc->vbase);
+
+ return (0);
+}
+
+static void
+ipu3_fb_init(void *arg)
+{
+ struct ipu3sc_softc *sc = arg;
+ struct video_adapter_softc *va_sc = &va_softc;
+ uint64_t w0sh96;
+ uint32_t w1sh96;
+
+ /* FW W0[137:125] - 96 = [41:29] */
+ /* FH W0[149:138] - 96 = [53:42] */
+ w0sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 16));
+ w0sh96 <<= 32;
+ w0sh96 |= IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 12));
+
+ va_sc->width = ((w0sh96 >> 29) & 0x1fff) + 1;
+ va_sc->height = ((w0sh96 >> 42) & 0x0fff) + 1;
+
+ /* SLY W1[115:102] - 96 = [19:6] */
+ w1sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 12));
+ va_sc->stride = ((w1sh96 >> 6) & 0x3fff) + 1;
+
+ printf("%dx%d [%d]\n", va_sc->width, va_sc->height, va_sc->stride);
+ va_sc->fb_size = va_sc->height * va_sc->stride;
+
+ ipu3_fb_malloc(sc, va_sc->fb_size);
+
+ /* DP1 + config_ch_23 + word_2 */
+ IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 0),
+ ((sc->pbase >> 3) | ((sc->pbase >> 3) << 29)) & 0xffffffff);
+
+ IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 4),
+ ((sc->pbase >> 3) >> 3) & 0xffffffff);
+
+ va_sc->fb_addr = (intptr_t)sc->vbase;
+ va_sc->fb_paddr = (intptr_t)sc->pbase;
+ va_sc->bpp = va_sc->stride / va_sc->width;
+ va_sc->depth = va_sc->bpp * 8;
+}
+
+static int
+ipu3_fb_probe(device_t dev)
+{
+ int error;
+
+ if (!ofw_bus_is_compatible(dev, "fsl,ipu3"))
+ return (ENXIO);
+
+ device_set_desc(dev, "i.MX515 Image Processing Unit (FB)");
+
+ error = sc_probe_unit(device_get_unit(dev),
+ device_get_flags(dev) | SC_AUTODETECT_KBD);
+
+ if (error != 0)
+ return (error);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ipu3_fb_attach(device_t dev)
+{
+ struct ipu3sc_softc *sc = device_get_softc(dev);
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ int err;
+
+ if (ipu3sc_softc)
+ return (ENXIO);
+
+ ipu3sc_softc = sc;
+
+ device_printf(dev, "\tclock gate status is %d\n",
+ imx51_get_clk_gating(IMX51CLK_IPU_HSP_CLK_ROOT));
+
+ sc->dev = dev;
+
+ err = (sc_attach_unit(device_get_unit(dev),
+ device_get_flags(dev) | SC_AUTODETECT_KBD));
+
+ if (err) {
+ device_printf(dev, "failed to attach syscons\n");
+ goto fail;
+ }
+
+ sc = device_get_softc(dev);
+ sc->iot = iot = fdtbus_bs_tag;
+
+ device_printf(sc->dev, ": i.MX51 IPUV3 controller\n");
+
+ /* map controller registers */
+ err = bus_space_map(iot, IPU_CM_BASE, IPU_CM_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_cm;
+ sc->cm_ioh = ioh;
+
+ /* map Display Multi FIFO Controller registers */
+ err = bus_space_map(iot, IPU_DMFC_BASE, IPU_DMFC_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_dmfc;
+ sc->dmfc_ioh = ioh;
+
+ /* map Display Interface 0 registers */
+ err = bus_space_map(iot, IPU_DI0_BASE, IPU_DI0_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_di0;
+ sc->di0_ioh = ioh;
+
+ /* map Display Interface 1 registers */
+ err = bus_space_map(iot, IPU_DI1_BASE, IPU_DI0_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_di1;
+ sc->di1_ioh = ioh;
+
+ /* map Display Processor registers */
+ err = bus_space_map(iot, IPU_DP_BASE, IPU_DP_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_dp;
+ sc->dp_ioh = ioh;
+
+ /* map Display Controller registers */
+ err = bus_space_map(iot, IPU_DC_BASE, IPU_DC_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_dc;
+ sc->dc_ioh = ioh;
+
+ /* map Image DMA Controller registers */
+ err = bus_space_map(iot, IPU_IDMAC_BASE, IPU_IDMAC_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_idmac;
+ sc->idmac_ioh = ioh;
+
+ /* map CPMEM registers */
+ err = bus_space_map(iot, IPU_CPMEM_BASE, IPU_CPMEM_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_cpmem;
+ sc->cpmem_ioh = ioh;
+
+ /* map DCTEMPL registers */
+ err = bus_space_map(iot, IPU_DCTMPL_BASE, IPU_DCTMPL_SIZE, 0, &ioh);
+ if (err)
+ goto fail_retarn_dctmpl;
+ sc->dctmpl_ioh = ioh;
+
+#ifdef notyet
+ sc->ih = imx51_ipuv3_intr_establish(IMX51_INT_IPUV3, IPL_BIO,
+ ipuv3intr, sc);
+ if (sc->ih == NULL) {
+ device_printf(sc->dev,
+ "unable to establish interrupt at irq %d\n",
+ IMX51_INT_IPUV3);
+ return (ENXIO);
+ }
+#endif
+
+ /*
+ * We have to wait until interrupts are enabled.
+ * Mailbox relies on it to get data from VideoCore
+ */
+ ipu3_fb_init(sc);
+
+ return (0);
+
+fail:
+ return (ENXIO);
+fail_retarn_dctmpl:
+ bus_space_unmap(sc->iot, sc->cpmem_ioh, IPU_CPMEM_SIZE);
+fail_retarn_cpmem:
+ bus_space_unmap(sc->iot, sc->idmac_ioh, IPU_IDMAC_SIZE);
+fail_retarn_idmac:
+ bus_space_unmap(sc->iot, sc->dc_ioh, IPU_DC_SIZE);
+fail_retarn_dp:
+ bus_space_unmap(sc->iot, sc->dp_ioh, IPU_DP_SIZE);
+fail_retarn_dc:
+ bus_space_unmap(sc->iot, sc->di1_ioh, IPU_DI1_SIZE);
+fail_retarn_di1:
+ bus_space_unmap(sc->iot, sc->di0_ioh, IPU_DI0_SIZE);
+fail_retarn_di0:
+ bus_space_unmap(sc->iot, sc->dmfc_ioh, IPU_DMFC_SIZE);
+fail_retarn_dmfc:
+ bus_space_unmap(sc->iot, sc->dc_ioh, IPU_CM_SIZE);
+fail_retarn_cm:
+ device_printf(sc->dev,
+ "failed to map registers (errno=%d)\n", err);
+ return (err);
+}
+
+static device_method_t ipu3_fb_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ipu3_fb_probe),
+ DEVMETHOD(device_attach, ipu3_fb_attach),
+
+ { 0, 0 }
+};
+
+static devclass_t ipu3_fb_devclass;
+
+static driver_t ipu3_fb_driver = {
+ "fb",
+ ipu3_fb_methods,
+ sizeof(struct ipu3sc_softc),
+};
+
+DRIVER_MODULE(ipu3fb, simplebus, ipu3_fb_driver, ipu3_fb_devclass, 0, 0);
+
+/*
+ * Video driver routines and glue.
+ */
+static int ipu3fb_configure(int);
+static vi_probe_t ipu3fb_probe;
+static vi_init_t ipu3fb_init;
+static vi_get_info_t ipu3fb_get_info;
+static vi_query_mode_t ipu3fb_query_mode;
+static vi_set_mode_t ipu3fb_set_mode;
+static vi_save_font_t ipu3fb_save_font;
+static vi_load_font_t ipu3fb_load_font;
+static vi_show_font_t ipu3fb_show_font;
+static vi_save_palette_t ipu3fb_save_palette;
+static vi_load_palette_t ipu3fb_load_palette;
+static vi_set_border_t ipu3fb_set_border;
+static vi_save_state_t ipu3fb_save_state;
+static vi_load_state_t ipu3fb_load_state;
+static vi_set_win_org_t ipu3fb_set_win_org;
+static vi_read_hw_cursor_t ipu3fb_read_hw_cursor;
+static vi_set_hw_cursor_t ipu3fb_set_hw_cursor;
+static vi_set_hw_cursor_shape_t ipu3fb_set_hw_cursor_shape;
+static vi_blank_display_t ipu3fb_blank_display;
+static vi_mmap_t ipu3fb_mmap;
+static vi_ioctl_t ipu3fb_ioctl;
+static vi_clear_t ipu3fb_clear;
+static vi_fill_rect_t ipu3fb_fill_rect;
+static vi_bitblt_t ipu3fb_bitblt;
+static vi_diag_t ipu3fb_diag;
+static vi_save_cursor_palette_t ipu3fb_save_cursor_palette;
+static vi_load_cursor_palette_t ipu3fb_load_cursor_palette;
+static vi_copy_t ipu3fb_copy;
+static vi_putp_t ipu3fb_putp;
+static vi_putc_t ipu3fb_putc;
+static vi_puts_t ipu3fb_puts;
+static vi_putm_t ipu3fb_putm;
+
+static video_switch_t ipu3fbvidsw = {
+ .probe = ipu3fb_probe,
+ .init = ipu3fb_init,
+ .get_info = ipu3fb_get_info,
+ .query_mode = ipu3fb_query_mode,
+ .set_mode = ipu3fb_set_mode,
+ .save_font = ipu3fb_save_font,
+ .load_font = ipu3fb_load_font,
+ .show_font = ipu3fb_show_font,
+ .save_palette = ipu3fb_save_palette,
+ .load_palette = ipu3fb_load_palette,
+ .set_border = ipu3fb_set_border,
+ .save_state = ipu3fb_save_state,
+ .load_state = ipu3fb_load_state,
+ .set_win_org = ipu3fb_set_win_org,
+ .read_hw_cursor = ipu3fb_read_hw_cursor,
+ .set_hw_cursor = ipu3fb_set_hw_cursor,
+ .set_hw_cursor_shape = ipu3fb_set_hw_cursor_shape,
+ .blank_display = ipu3fb_blank_display,
+ .mmap = ipu3fb_mmap,
+ .ioctl = ipu3fb_ioctl,
+ .clear = ipu3fb_clear,
+ .fill_rect = ipu3fb_fill_rect,
+ .bitblt = ipu3fb_bitblt,
+ .diag = ipu3fb_diag,
+ .save_cursor_palette = ipu3fb_save_cursor_palette,
+ .load_cursor_palette = ipu3fb_load_cursor_palette,
+ .copy = ipu3fb_copy,
+ .putp = ipu3fb_putp,
+ .putc = ipu3fb_putc,
+ .puts = ipu3fb_puts,
+ .putm = ipu3fb_putm,
+};
+
+VIDEO_DRIVER(ipu3fb, ipu3fbvidsw, ipu3fb_configure);
+
+extern sc_rndr_sw_t txtrndrsw;
+RENDERER(ipu3fb, 0, txtrndrsw, gfb_set);
+RENDERER_MODULE(ipu3fb, gfb_set);
+
+static uint16_t ipu3fb_static_window[ROW*COL];
+extern u_char dflt_font_16[];
+
+static int
+ipu3fb_configure(int flags)
+{
+ struct video_adapter_softc *sc;
+
+ sc = &va_softc;
+
+ if (sc->initialized)
+ return 0;
+
+ sc->width = 640;
+ sc->height = 480;
+ sc->bpp = 2;
+ sc->stride = sc->width * sc->bpp;
+
+ ipu3fb_init(0, &sc->va, 0);
+
+ sc->initialized = 1;
+
+ return (0);
+}
+
+static int
+ipu3fb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_init(int unit, video_adapter_t *adp, int flags)
+{
+ struct video_adapter_softc *sc;
+ video_info_t *vi;
+
+ sc = (struct video_adapter_softc *)adp;
+ vi = &adp->va_info;
+
+ vid_init_struct(adp, "ipu3fb", -1, unit);
+
+ sc->font = dflt_font_16;
+ vi->vi_cheight = IPU3FB_FONT_HEIGHT;
+ vi->vi_cwidth = 8;
+ vi->vi_width = sc->width/8;
+ vi->vi_height = sc->height/vi->vi_cheight;
+
+ /*
+ * Clamp width/height to syscons maximums
+ */
+ if (vi->vi_width > COL)
+ vi->vi_width = COL;
+ if (vi->vi_height > ROW)
+ vi->vi_height = ROW;
+
+ sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+ sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
+
+ adp->va_window = (vm_offset_t) ipu3fb_static_window;
+ adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
+ adp->va_line_width = sc->stride;
+ adp->va_buffer_size = sc->fb_size;
+
+ vid_register(&sc->va);
+
+ return (0);
+}
+
+static int
+ipu3fb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+
+ bcopy(&adp->va_info, info, sizeof(*info));
+ return (0);
+}
+
+static int
+ipu3fb_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_set_mode(video_adapter_t *adp, int mode)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_save_font(video_adapter_t *adp, int page, int size, int width,
+ u_char *data, int c, int count)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_load_font(video_adapter_t *adp, int page, int size, int width,
+ u_char *data, int c, int count)
+{
+ struct video_adapter_softc *sc;
+
+ sc = (struct video_adapter_softc *)adp;
+ sc->font = data;
+
+ return (0);
+}
+
+static int
+ipu3fb_show_font(video_adapter_t *adp, int page)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_save_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_load_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_set_border(video_adapter_t *adp, int border)
+{
+
+ return (ipu3fb_blank_display(adp, border));
+}
+
+static int
+ipu3fb_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_load_state(video_adapter_t *adp, void *p)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_set_win_org(video_adapter_t *adp, off_t offset)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+
+ *col = *row = 0;
+ return (0);
+}
+
+static int
+ipu3fb_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+ int celsize, int blink)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_blank_display(video_adapter_t *adp, int mode)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
+ int prot, vm_memattr_t *memattr)
+{
+ struct video_adapter_softc *sc;
+
+ sc = (struct video_adapter_softc *)adp;
+
+ /*
+ * This might be a legacy VGA mem request: if so, just point it at the
+ * framebuffer, since it shouldn't be touched
+ */
+ if (offset < sc->stride * sc->height) {
+ *paddr = sc->fb_paddr + offset;
+ return (0);
+ }
+
+ return (EINVAL);
+}
+
+static int
+ipu3fb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
+{
+ struct video_adapter_softc *sc;
+ struct fbtype *fb;
+
+ sc = (struct video_adapter_softc *)adp;
+
+ switch (cmd) {
+ case FBIOGTYPE:
+ fb = (struct fbtype *)data;
+ fb->fb_type = FBTYPE_PCIMISC;
+ fb->fb_height = sc->height;
+ fb->fb_width = sc->width;
+ fb->fb_depth = sc->depth;
+ if (sc->depth <= 1 || sc->depth > 8)
+ fb->fb_cmsize = 0;
+ else
+ fb->fb_cmsize = 1 << sc->depth;
+ fb->fb_size = sc->fb_size;
+ break;
+ case FBIOSCURSOR:
+ return (ENODEV);
+ default:
+ return (fb_commonioctl(adp, cmd, data));
+ }
+
+ return (0);
+}
+
+static int
+ipu3fb_clear(video_adapter_t *adp)
+{
+
+ return (ipu3fb_blank_display(adp, 0));
+}
+
+static int
+ipu3fb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_bitblt(video_adapter_t *adp, ...)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_diag(video_adapter_t *adp, int level)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
+ int size, int bpp, int bit_ltor, int byte_ltor)
+{
+
+ return (0);
+}
+
+static int
+ipu3fb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+{
+ struct video_adapter_softc *sc;
+ int col, row, bpp;
+ int b, i, j, k;
+ uint8_t *addr;
+ u_char *p;
+ uint32_t fg, bg, color;
+
+ sc = (struct video_adapter_softc *)adp;
+ bpp = sc->bpp;
+
+ if (sc->fb_addr == 0)
+ return (0);
+ row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+ col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+ p = sc->font + c * IPU3FB_FONT_HEIGHT;
+ addr = (uint8_t *)sc->fb_addr
+ + (row + sc->ymargin) * (sc->stride)
+ + bpp * (col + sc->xmargin);
+
+ if (bpp == 2) {
+ bg = colors[(a >> 4) & 0x0f];
+ fg = colors[a & 0x0f];
+ } else if (bpp == 3) {
+ bg = colors_24[(a >> 4) & 0x0f];
+ fg = colors_24[a & 0x0f];
+ } else {
+ return (ENXIO);
+ }
+
+ for (i = 0; i < IPU3FB_FONT_HEIGHT; i++) {
+ for (j = 0, k = 7; j < 8; j++, k--) {
+ if ((p[i] & (1 << k)) == 0)
+ color = bg;
+ else
+ color = fg;
+ /* FIXME: BPP maybe different */
+ for (b = 0; b < bpp; b ++)
+ addr[bpp * j + b] =
+ (color >> (b << 3)) & 0xff;
+ }
+
+ addr += (sc->stride);
+ }
+
+ return (0);
+}
+
+static int
+ipu3fb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ ipu3fb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
+
+ return (0);
+}
+
+static int
+ipu3fb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
+ uint32_t pixel_mask, int size, int width)
+{
+
+ return (0);
+}
+
+/*
+ * Define a stub keyboard driver in case one hasn't been
+ * compiled into the kernel
+ */
+#include <sys/kbio.h>
+#include <dev/kbd/kbdreg.h>
+
+static int dummy_kbd_configure(int flags);
+
+keyboard_switch_t ipu3dummysw;
+
+static int
+dummy_kbd_configure(int flags)
+{
+
+ return (0);
+}
+KEYBOARD_DRIVER(ipu3dummy, ipu3dummysw, dummy_kbd_configure);
diff --git a/sys/arm/freescale/imx/imx51_ipuv3reg.h b/sys/arm/freescale/imx/imx51_ipuv3reg.h
new file mode 100644
index 0000000..bdfb4dd
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_ipuv3reg.h
@@ -0,0 +1,919 @@
+/* $NetBSD: imx51_ipuv3reg.h,v 1.1 2012/04/17 10:19:57 bsh Exp $ */
+/*
+ * Copyright (c) 2011, 2012 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _ARM_IMX_IMX51_IPUV3REG_H
+#define _ARM_IMX_IMX51_IPUV3REG_H
+
+/* register offset address */
+
+/*
+ * CM
+ * Control Module
+ */
+#define IPU_CM_CONF 0x00000000
+#define CM_CONF_CSI_SEL 0x80000000
+#define CM_CONF_IC_INPUT 0x40000000
+#define CM_CONF_CSI1_DATA_SOURCE 0x20000000
+#define CM_CONF_CSI0_DATA_SOURCE 0x10000000
+#define CM_CONF_VDI_DMFC_SYNC 0x08000000
+#define CM_CONF_IC_DMFC_SYNC 0x04000000
+#define CM_CONF_IC_DMFC_SEL 0x02000000
+#define CM_CONF_ISP_DOUBLE_FLOW 0x01000000
+#define CM_CONF_IDMAC_DISABLE 0x00400000
+#define CM_CONF_IPU_DIAGBUS_ON 0x00200000
+#define CM_CONF_IPU_DIAGBUS_MODE 0x001f0000
+#define CM_CONF_VDI_EN 0x00001000
+#define CM_CONF_SISG_EN 0x00000800
+#define CM_CONF_DMFC_EN 0x00000400
+#define CM_CONF_DC_EN 0x00000200
+#define CM_CONF_SMFC_EN 0x00000100
+#define CM_CONF_DI1_EN 0x00000080
+#define CM_CONF_DI0_EN 0x00000040
+#define CM_CONF_DP_EN 0x00000020
+#define CM_CONF_ISP_EN 0x00000010
+#define CM_CONF_IRT_EN 0x00000008
+#define CM_CONF_IC_EN 0x00000004
+#define CM_CONF_CSI1_EN 0x00000002
+#define CM_CONF_CSI0_EN 0x00000001
+#define IPU_SISG_CTRL0 0x00000004
+#define IPU_SISG_CTRL1 0x00000008
+#define IPU_CM_INT_CTRL_1 0x0000003c
+#define IPU_CM_INT_CTRL_2 0x00000040
+#define IPU_CM_INT_CTRL_3 0x00000044
+#define IPU_CM_INT_CTRL_4 0x00000048
+#define IPU_CM_INT_CTRL_5 0x0000004c
+#define IPU_CM_INT_CTRL_6 0x00000050
+#define IPU_CM_INT_CTRL_7 0x00000054
+#define IPU_CM_INT_CTRL_8 0x00000058
+#define IPU_CM_INT_CTRL_9 0x0000005c
+#define IPU_CM_INT_CTRL_10 0x00000060
+#define IPU_CM_INT_CTRL_11 0x00000064
+#define IPU_CM_INT_CTRL_12 0x00000068
+#define IPU_CM_INT_CTRL_13 0x0000006c
+#define IPU_CM_INT_CTRL_14 0x00000070
+#define IPU_CM_INT_CTRL_15 0x00000074
+#define IPU_CM_SDMA_EVENT_1 0x00000078
+#define IPU_CM_SDMA_EVENT_2 0x0000007c
+#define IPU_CM_SDMA_EVENT_3 0x00000080
+#define IPU_CM_SDMA_EVENT_4 0x00000084
+#define IPU_CM_SDMA_EVENT_7 0x00000088
+#define IPU_CM_SDMA_EVENT_8 0x0000008c
+#define IPU_CM_SDMA_EVENT_11 0x00000090
+#define IPU_CM_SDMA_EVENT_12 0x00000094
+#define IPU_CM_SDMA_EVENT_13 0x00000098
+#define IPU_CM_SDMA_EVENT_14 0x0000009c
+#define IPU_CM_SRM_PRI1 0x000000a0
+#define IPU_CM_SRM_PRI2 0x000000a4
+#define IPU_CM_FS_PROC_FLOW1 0x000000a8
+#define IPU_CM_FS_PROC_FLOW2 0x000000ac
+#define IPU_CM_FS_PROC_FLOW3 0x000000b0
+#define IPU_CM_FS_DISP_FLOW1 0x000000b4
+#define IPU_CM_FS_DISP_FLOW2 0x000000b8
+#define IPU_CM_SKIP 0x000000bc
+#define IPU_CM_DISP_ALT_CONF 0x000000c0
+#define IPU_CM_DISP_GEN 0x000000c4
+#define CM_DISP_GEN_DI0_COUNTER_RELEASE 0x01000000
+#define CM_DISP_GEN_DI1_COUNTER_RELEASE 0x00800000
+#define CM_DISP_GEN_MCU_MAX_BURST_STOP 0x00400000
+#define CM_DISP_GEN_MCU_T_SHIFT 18
+#define CM_DISP_GEN_MCU_T(n) ((n) << CM_DISP_GEN_MCU_T_SHIFT)
+#define IPU_CM_DISP_ALT1 0x000000c8
+#define IPU_CM_DISP_ALT2 0x000000cc
+#define IPU_CM_DISP_ALT3 0x000000d0
+#define IPU_CM_DISP_ALT4 0x000000d4
+#define IPU_CM_SNOOP 0x000000d8
+#define IPU_CM_MEM_RST 0x000000dc
+#define CM_MEM_START 0x80000000
+#define CM_MEM_EN 0x007fffff
+#define IPU_CM_PM 0x000000e0
+#define IPU_CM_GPR 0x000000e4
+#define CM_GPR_IPU_CH_BUF1_RDY1_CLR 0x80000000
+#define CM_GPR_IPU_CH_BUF1_RDY0_CLR 0x40000000
+#define CM_GPR_IPU_CH_BUF0_RDY1_CLR 0x20000000
+#define CM_GPR_IPU_CH_BUF0_RDY0_CLR 0x10000000
+#define CM_GPR_IPU_ALT_CH_BUF1_RDY1_CLR 0x08000000
+#define CM_GPR_IPU_ALT_CH_BUF1_RDY0_CLR 0x04000000
+#define CM_GPR_IPU_ALT_CH_BUF0_RDY1_CLR 0x02000000
+#define CM_GPR_IPU_ALT_CH_BUF0_RDY0_CLR 0x01000000
+#define CM_GPR_IPU_DI1_CLK_CHANGE_ACK_DIS 0x00800000
+#define CM_GPR_IPU_DI0_CLK_CHANGE_ACK_DIS 0x00400000
+#define CM_GPR_IPU_CH_BUF2_RDY1_CLR 0x00200000
+#define CM_GPR_IPU_CH_BUF2_RDY0_CLR 0x00100000
+#define CM_GPR_IPU_GP(n) __BIT((n))
+#define IPU_CM_CH_DB_MODE_SEL_0 0x00000150
+#define IPU_CM_CH_DB_MODE_SEL_1 0x00000154
+#define IPU_CM_ALT_CH_DB_MODE_SEL_0 0x00000168
+#define IPU_CM_ALT_CH_DB_MODE_SEL_1 0x0000016c
+#define IPU_CM_CH_TRB_MODE_SEL_0 0x00000178
+#define IPU_CM_CH_TRB_MODE_SEL_1 0x0000017c
+#define IPU_CM_INT_STAT_1 0x00000200
+#define IPU_CM_INT_STAT_2 0x00000204
+#define IPU_CM_INT_STAT_3 0x00000208
+#define IPU_CM_INT_STAT_4 0x0000020c
+#define IPU_CM_INT_STAT_5 0x00000210
+#define IPU_CM_INT_STAT_6 0x00000214
+#define IPU_CM_INT_STAT_7 0x00000218
+#define IPU_CM_INT_STAT_8 0x0000021c
+#define IPU_CM_INT_STAT_9 0x00000220
+#define IPU_CM_INT_STAT_10 0x00000224
+#define IPU_CM_INT_STAT_11 0x00000228
+#define IPU_CM_INT_STAT_12 0x0000022c
+#define IPU_CM_INT_STAT_13 0x00000230
+#define IPU_CM_INT_STAT_14 0x00000234
+#define IPU_CM_INT_STAT_15 0x00000238
+#define IPU_CM_CUR_BUF_0 0x0000023c
+#define IPU_CM_CUR_BUF_1 0x00000240
+#define IPU_CM_ALT_CUR_BUF_0 0x00000244
+#define IPU_CM_ALT_CUR_BUF_1 0x00000248
+#define IPU_CM_SRM_STAT 0x0000024c
+#define IPU_CM_PROC_TASKS_STAT 0x00000250
+#define IPU_CM_DISP_TASKS_STAT 0x00000254
+#define IPU_CM_TRIPLE_CUR_BUF_0 0x00000258
+#define IPU_CM_TRIPLE_CUR_BUF_1 0x0000025c
+#define IPU_CM_TRIPLE_CUR_BUF_2 0x00000260
+#define IPU_CM_TRIPLE_CUR_BUF_3 0x00000264
+#define IPU_CM_CH_BUF0_RDY0 0x00000268
+#define IPU_CM_CH_BUF0_RDY1 0x0000026c
+#define IPU_CM_CH_BUF1_RDY0 0x00000270
+#define IPU_CM_CH_BUF1_RDY1 0x00000274
+#define IPU_CM_ALT_CH_BUF0_RDY0 0x00000278
+#define IPU_CM_ALT_CH_BUF0_RDY1 0x0000027c
+#define IPU_CM_ALT_CH_BUF1_RDY0 0x00000280
+#define IPU_CM_ALT_CH_BUF1_RDY1 0x00000284
+#define IPU_CM_CH_BUF2_RDY0 0x00000288
+#define IPU_CM_CH_BUF2_RDY1 0x0000028c
+
+/*
+ * IDMAC
+ * Image DMA Controller
+ */
+#define IPU_IDMAC_CONF 0x00000000
+#define IPU_IDMAC_CH_EN_1 0x00000004
+#define IPU_IDMAC_CH_EN_2 0x00000008
+#define IPU_IDMAC_SEP_ALPHA 0x0000000c
+#define IPU_IDMAC_ALT_SEP_ALPHA 0x00000010
+#define IPU_IDMAC_CH_PRI_1 0x00000014
+#define IPU_IDMAC_CH_PRI_2 0x00000018
+#define IPU_IDMAC_WM_EN_1 0x0000001c
+#define IPU_IDMAC_WM_EN_2 0x00000020
+#define IPU_IDMAC_LOCK_EN_1 0x00000024
+#define IPU_IDMAC_LOCK_EN_2 0x00000028
+#define IPU_IDMAC_SUB_ADDR_0 0x0000002c
+#define IPU_IDMAC_SUB_ADDR_1 0x00000030
+#define IPU_IDMAC_SUB_ADDR_2 0x00000034
+#define IPU_IDMAC_SUB_ADDR_3 0x00000038
+#define IPU_IDMAC_SUB_ADDR_4 0x0000003c
+#define IPU_IDMAC_BNDM_EN_1 0x00000040
+#define IPU_IDMAC_BNDM_EN_2 0x00000044
+#define IPU_IDMAC_SC_CORD 0x00000048
+#define IPU_IDMAC_SC_CORD1 0x0000004c
+#define IPU_IDMAC_CH_BUSY_1 0x00000100
+#define IPU_IDMAC_CH_BUSY_2 0x00000104
+
+#define CH_PANNEL_BG 23
+#define CH_PANNEL_FG 27
+
+/*
+ * DP
+ * Display Port
+ */
+#define IPU_DP_DEBUG_CNT 0x000000bc
+#define IPU_DP_DEBUG_STAT 0x000000c0
+
+/*
+ * IC
+ * Image Converter
+ */
+#define IPU_IC_CONF 0x00000000
+#define IPU_IC_PRP_ENC_RSC 0x00000004
+#define IPU_IC_PRP_VF_RSC 0x00000008
+#define IPU_IC_PP_RSC 0x0000000c
+#define IPU_IC_CMBP_1 0x00000010
+#define IPU_IC_CMBP_2 0x00000014
+#define IPU_IC_IDMAC_1 0x00000018
+#define IPU_IC_IDMAC_2 0x0000001c
+#define IPU_IC_IDMAC_3 0x00000020
+#define IPU_IC_IDMAC_4 0x00000024
+
+/*
+ * CSI
+ * Camera Sensor Interface
+ */
+#define IPU_CSI0_SENS_CONF 0x00000000
+#define IPU_CSI0_SENS_FRM_SIZE 0x00000004
+#define IPU_CSI0_ACT_FRM_SIZE 0x00000008
+#define IPU_CSI0_OUT_FRM_CTRL 0x0000000c
+#define IPU_CSI0_TST_CTRL 0x00000010
+#define IPU_CSI0_CCIR_CODE_1 0x00000014
+#define IPU_CSI0_CCIR_CODE_2 0x00000018
+#define IPU_CSI0_CCIR_CODE_3 0x0000001c
+#define IPU_CSI0_DI 0x00000020
+#define IPU_CSI0_SKIP 0x00000024
+#define IPU_CSI0_CPD_CTRL 0x00000028
+#define IPU_CSI0_CPD_OFFSET1 0x000000ec
+#define IPU_CSI0_CPD_OFFSET2 0x000000f0
+
+#define IPU_CSI1_SENS_CONF 0x00000000
+#define IPU_CSI1_SENS_FRM_SIZE 0x00000004
+#define IPU_CSI1_ACT_FRM_SIZE 0x00000008
+#define IPU_CSI1_OUT_FRM_CTRL 0x0000000c
+#define IPU_CSI1_TST_CTRL 0x00000010
+#define IPU_CSI1_CCIR_CODE_1 0x00000014
+#define IPU_CSI1_CCIR_CODE_2 0x00000018
+#define IPU_CSI1_CCIR_CODE_3 0x0000001c
+#define IPU_CSI1_DI 0x00000020
+#define IPU_CSI1_SKIP 0x00000024
+#define IPU_CSI1_CPD_CTRL 0x00000028
+#define IPU_CSI1_CPD_OFFSET1 0x000000ec
+#define IPU_CSI1_CPD_OFFSET2 0x000000f0
+
+/*
+ * DI
+ * Display Interface
+ */
+#define IPU_DI_GENERAL 0x00000000
+#define DI_GENERAL_DISP_Y_SEL 0x70000000
+#define DI_GENERAL_CLOCK_STOP_MODE 0x0f000000
+#define DI_GENERAL_DISP_CLOCK_INIT 0x00800000
+#define DI_GENERAL_MASK_SEL 0x00400000
+#define DI_GENERAL_VSYNC_EXT 0x00200000
+#define DI_GENERAL_CLK_EXT 0x00100000
+#define DI_GENERAL_WATCHDOG_MODE 0x000c0000
+#define DI_GENERAL_POLARITY_DISP_CLK 0x00020000
+#define DI_GENERAL_SYNC_COUNT_SEL 0x0000f000
+#define DI_GENERAL_ERR_TREATMENT 0x00000800
+#define DI_GENERAL_ERM_VSYNC_SEL 0x00000400
+#define DI_GENERAL_POLARITY_CS(n) (1 << ((n) + 8))
+#define DI_GENERAL_POLARITY(n) (1 << ((n) - 1))
+
+#define IPU_DI_BS_CLKGEN0 0x00000004
+#define DI_BS_CLKGEN0_OFFSET_SHIFT 16
+#define IPU_DI_BS_CLKGEN1 0x00000008
+#define DI_BS_CLKGEN1_DOWN_SHIFT 16
+#define DI_BS_CLKGEN1_UP_SHIFT 0
+#define IPU_DI_SW_GEN0(n) (0x0000000c + ((n) - 1) * 4)
+#define DI_SW_GEN0_RUN_VAL 0x7ff80000
+#define DI_SW_GEN0_RUN_RESOL 0x00070000
+#define DI_SW_GEN0_OFFSET_VAL 0x00007ff8
+#define DI_SW_GEN0_OFFSET_RESOL 0x00000007
+#define __DI_SW_GEN0(run_val, run_resol, offset_val, offset_resol) \
+ (((run_val) << 19) | ((run_resol) << 16) | \
+ ((offset_val) << 3) | (offset_resol))
+#define IPU_DI_SW_GEN1(n) (0x00000030 + ((n) - 1) * 4)
+#define DI_SW_GEN1_CNT_POL_GEN_EN 0x60000000
+#define DI_SW_GEN1_CNT_AUTO_RELOAD 0x10000000
+#define DI_SW_GEN1_CNT_CLR_SEL 0x0e000000
+#define DI_SW_GEN1_CNT_DOWN 0x01ff0000
+#define DI_SW_GEN1_CNT_POL_TRIG_SEL 0x00007000
+#define DI_SW_GEN1_CNT_POL_CLR_SEL 0x00000e00
+#define DI_SW_GEN1_CNT_UP 0x000001ff
+#define __DI_SW_GEN1(pol_gen_en, auto_reload, clr_sel, down, pol_trig_sel, pol_clr_sel, up) \
+ (((pol_gen_en) << 29) | ((auto_reload) << 28) | \
+ ((clr_sel) << 25) | \
+ ((down) << 16) | ((pol_trig_sel) << 12) | \
+ ((pol_clr_sel) << 9) | (up))
+#define IPU_DI_SYNC_AS_GEN 0x00000054
+#define DI_SYNC_AS_GEN_SYNC_START_EN 0x10000000
+#define DI_SYNC_AS_GEN_VSYNC_SEL 0x0000e000
+#define DI_SYNC_AS_GEN_VSYNC_SEL_SHIFT 13
+#define DI_SYNC_AS_GEN_SYNC_STAR 0x00000fff
+#define IPU_DI_DW_GEN(n) (0x00000058 + (n) * 4)
+#define DI_DW_GEN_ACCESS_SIZE_SHIFT 24
+#define DI_DW_GEN_COMPONNENT_SIZE_SHIFT 16
+#define DI_DW_GEN_PIN_SHIFT(n) (((n) - 11) * 2)
+#define DI_DW_GEN_PIN(n) __BITS(DI_DW_GEN_PIN_SHIFT(n) + 1, \
+ DI_DW_GEN_PIN_SHIFT(n))
+#define IPU_DI_DW_SET(n, m) (0x00000088 + (n) * 4 + (m) * 0x30)
+#define DI_DW_SET_DOWN_SHIFT 16
+#define DI_DW_SET_UP_SHIFT 0
+#define IPU_DI_STP_REP(n) (0x00000148 + ((n - 1) / 2) * 4)
+#define DI_STP_REP_SHIFT(n) (((n - 1) % 2) * 16)
+#define DI_STP_REP_MASK(n) (0x00000fff << DI_STP_REP_SHIFT((n)))
+#define IPU_DI_SER_CONF 0x0000015c
+#define IPU_DI_SSC 0x00000160
+#define IPU_DI_POL 0x00000164
+#define DI_POL_DRDY_POLARITY_17 0x00000040
+#define DI_POL_DRDY_POLARITY_16 0x00000020
+#define DI_POL_DRDY_POLARITY_15 0x00000010
+#define DI_POL_DRDY_POLARITY_14 0x00000008
+#define DI_POL_DRDY_POLARITY_13 0x00000004
+#define DI_POL_DRDY_POLARITY_12 0x00000002
+#define DI_POL_DRDY_POLARITY_11 0x00000001
+#define IPU_DI_AW0 0x00000168
+#define IPU_DI_AW1 0x0000016c
+#define IPU_DI_SCR_CONF 0x00000170
+#define IPU_DI_STAT 0x00000174
+
+/*
+ * SMFC
+ * Sensor Multi FIFO Controller
+ */
+#define IPU_SMFC_MAP 0x00000000
+#define IPU_SMFC_WMC 0x00000004
+#define IPU_SMFC_BS 0x00000008
+
+/*
+ * DC
+ * Display Controller
+ */
+#define IPU_DC_READ_CH_CONF 0x00000000
+#define IPU_DC_READ_CH_ADDR 0x00000004
+
+#define IPU_DC_RL0_CH_0 0x00000008
+#define IPU_DC_RL1_CH_0 0x0000000c
+#define IPU_DC_RL2_CH_0 0x00000010
+#define IPU_DC_RL3_CH_0 0x00000014
+#define IPU_DC_RL4_CH_0 0x00000018
+#define IPU_DC_WR_CH_CONF_1 0x0000001c
+#define IPU_DC_WR_CH_ADDR_1 0x00000020
+#define IPU_DC_RL0_CH_1 0x00000024
+#define IPU_DC_RL1_CH_1 0x00000028
+#define IPU_DC_RL2_CH_1 0x0000002c
+#define IPU_DC_RL3_CH_1 0x00000030
+#define IPU_DC_RL4_CH_1 0x00000034
+#define IPU_DC_WR_CH_CONF_2 0x00000038
+#define IPU_DC_WR_CH_ADDR_2 0x0000003c
+#define IPU_DC_RL0_CH_2 0x00000040
+#define IPU_DC_RL1_CH_2 0x00000044
+#define IPU_DC_RL2_CH_2 0x00000048
+#define IPU_DC_RL3_CH_2 0x0000004c
+#define IPU_DC_RL4_CH_2 0x00000050
+#define IPU_DC_CMD_CH_CONF_3 0x00000054
+#define IPU_DC_CMD_CH_CONF_4 0x00000058
+#define IPU_DC_WR_CH_CONF_5 0x0000005c
+#define IPU_DC_WR_CH_ADDR_5 0x00000060
+#define IPU_DC_RL0_CH_5 0x00000064
+#define IPU_DC_RL1_CH_5 0x00000068
+#define IPU_DC_RL2_CH_5 0x0000006c
+#define IPU_DC_RL3_CH_5 0x00000070
+#define IPU_DC_RL4_CH_5 0x00000074
+#define IPU_DC_WR_CH_CONF_6 0x00000078
+#define IPU_DC_WR_CH_ADDR_6 0x0000007c
+#define IPU_DC_RL0_CH_6 0x00000080
+#define IPU_DC_RL1_CH_6 0x00000084
+#define IPU_DC_RL2_CH_6 0x00000088
+#define IPU_DC_RL3_CH_6 0x0000008c
+#define IPU_DC_RL4_CH_6 0x00000090
+#define IPU_DC_WR_CH_CONF1_8 0x00000094
+#define IPU_DC_WR_CH_CONF2_8 0x00000098
+#define IPU_DC_RL1_CH_8 0x0000009c
+#define IPU_DC_RL2_CH_8 0x000000a0
+#define IPU_DC_RL3_CH_8 0x000000a4
+#define IPU_DC_RL4_CH_8 0x000000a8
+#define IPU_DC_RL5_CH_8 0x000000ac
+#define IPU_DC_RL6_CH_8 0x000000b0
+#define IPU_DC_WR_CH_CONF1_9 0x000000b4
+#define IPU_DC_WR_CH_CONF2_9 0x000000b8
+#define IPU_DC_RL1_CH_9 0x000000bc
+#define IPU_DC_RL2_CH_9 0x000000c0
+#define IPU_DC_RL3_CH_9 0x000000c4
+#define IPU_DC_RL4_CH_9 0x000000c8
+#define IPU_DC_RL5_CH_9 0x000000cc
+#define IPU_DC_RL6_CH_9 0x000000d0
+
+#define IPU_DC_RL(chan_base, evt) ((chan_base) + (evt / 2) *0x4)
+#define DC_RL_CH_0 IPU_DC_RL0_CH_0
+#define DC_RL_CH_1 IPU_DC_RL0_CH_1
+#define DC_RL_CH_2 IPU_DC_RL0_CH_2
+#define DC_RL_CH_5 IPU_DC_RL0_CH_5
+#define DC_RL_CH_6 IPU_DC_RL0_CH_6
+#define DC_RL_CH_8 IPU_DC_RL0_CH_8
+
+#define DC_RL_EVT_NF 0
+#define DC_RL_EVT_NL 1
+#define DC_RL_EVT_EOF 2
+#define DC_RL_EVT_NFIELD 3
+#define DC_RL_EVT_EOL 4
+#define DC_RL_EVT_EOFIELD 5
+#define DC_RL_EVT_NEW_ADDR 6
+#define DC_RL_EVT_NEW_CHAN 7
+#define DC_RL_EVT_NEW_DATA 8
+
+#define IPU_DC_GEN 0x000000d4
+#define IPU_DC_DISP_CONF1_0 0x000000d8
+#define IPU_DC_DISP_CONF1_1 0x000000dc
+#define IPU_DC_DISP_CONF1_2 0x000000e0
+#define IPU_DC_DISP_CONF1_3 0x000000e4
+#define IPU_DC_DISP_CONF2_0 0x000000e8
+#define IPU_DC_DISP_CONF2_1 0x000000ec
+#define IPU_DC_DISP_CONF2_2 0x000000f0
+#define IPU_DC_DISP_CONF2_3 0x000000f4
+#define IPU_DC_DI0_CONF_1 0x000000f8
+#define IPU_DC_DI0_CONF_2 0x000000fc
+#define IPU_DC_DI1_CONF_1 0x00000100
+#define IPU_DC_DI1_CONF_2 0x00000104
+
+#define IPU_DC_MAP_CONF_PNTR(n) (0x00000108 + (n) * 4)
+#define IPU_DC_MAP_CONF_0 0x00000108
+#define IPU_DC_MAP_CONF_1 0x0000010c
+#define IPU_DC_MAP_CONF_2 0x00000110
+#define IPU_DC_MAP_CONF_3 0x00000114
+#define IPU_DC_MAP_CONF_4 0x00000118
+#define IPU_DC_MAP_CONF_5 0x0000011c
+#define IPU_DC_MAP_CONF_6 0x00000120
+#define IPU_DC_MAP_CONF_7 0x00000124
+#define IPU_DC_MAP_CONF_8 0x00000128
+#define IPU_DC_MAP_CONF_9 0x0000012c
+#define IPU_DC_MAP_CONF_10 0x00000130
+#define IPU_DC_MAP_CONF_11 0x00000134
+#define IPU_DC_MAP_CONF_12 0x00000138
+#define IPU_DC_MAP_CONF_13 0x0000013c
+#define IPU_DC_MAP_CONF_14 0x00000140
+
+#define IPU_DC_MAP_CONF_MASK(n) (0x00000144 + (n) * 4)
+#define IPU_DC_MAP_CONF_15 0x00000144
+#define IPU_DC_MAP_CONF_16 0x00000148
+#define IPU_DC_MAP_CONF_17 0x0000014c
+#define IPU_DC_MAP_CONF_18 0x00000150
+#define IPU_DC_MAP_CONF_19 0x00000154
+#define IPU_DC_MAP_CONF_20 0x00000158
+#define IPU_DC_MAP_CONF_21 0x0000015c
+#define IPU_DC_MAP_CONF_22 0x00000160
+#define IPU_DC_MAP_CONF_23 0x00000164
+#define IPU_DC_MAP_CONF_24 0x00000168
+#define IPU_DC_MAP_CONF_25 0x0000016c
+#define IPU_DC_MAP_CONF_26 0x00000170
+
+#define IPU_DC_UGDE(m, n) (0x00000174 + (m) * 0x10 + (n) +4)
+#define IPU_DC_UGDE0_0 0x00000174
+#define IPU_DC_UGDE0_1 0x00000178
+#define IPU_DC_UGDE0_2 0x0000017c
+#define IPU_DC_UGDE0_3 0x00000180
+#define IPU_DC_UGDE1_0 0x00000184
+#define IPU_DC_UGDE1_1 0x00000188
+#define IPU_DC_UGDE1_2 0x0000018c
+#define IPU_DC_UGDE1_3 0x00000190
+#define IPU_DC_UGDE2_0 0x00000194
+#define IPU_DC_UGDE2_1 0x00000198
+#define IPU_DC_UGDE2_2 0x0000019c
+#define IPU_DC_UGDE2_3 0x000001a0
+#define IPU_DC_UGDE3_0 0x000001a4
+#define IPU_DC_UGDE3_1 0x000001a8
+#define IPU_DC_UGDE3_2 0x000001ac
+#define IPU_DC_UGDE3_3 0x000001b0
+#define IPU_DC_LLA0 0x000001b4
+#define IPU_DC_LLA1 0x000001b8
+#define IPU_DC_R_LLA0 0x000001bc
+#define IPU_DC_R_LLA1 0x000001c0
+#define IPU_DC_WR_CH_ADDR_5_ALT 0x000001c4
+#define IPU_DC_STAT 0x000001c8
+
+/*
+ * DMFC
+ * Display Multi FIFO Controller
+ */
+#define IPU_DMFC_RD_CHAN 0x00000000
+#define DMFC_RD_CHAN_PPW_C 0x03000000
+#define DMFC_RD_CHAN_WM_DR_0 0x00e00000
+#define DMFC_RD_CHAN_WM_SET_0 0x001c0000
+#define DMFC_RD_CHAN_WM_EN_0 0x00020000
+#define DMFC_RD_CHAN_BURST_SIZE_0 0x000000c0
+#define IPU_DMFC_WR_CHAN 0x00000004
+#define DMFC_WR_CHAN_BUSRT_SIZE_2C 0xc0000000
+#define DMFC_WR_CHAN_FIFO_SIZE_2C 0x38000000
+#define DMFC_WR_CHAN_ST_ADDR_2C 0x07000000
+#define DMFC_WR_CHAN_BURST_SIZE_1C 0x00c00000
+#define DMFC_WR_CHAN_FIFO_SIZE_1C 0x00380000
+#define DMFC_WR_CHAN_ST_ADDR_1C 0x00070000
+#define DMFC_WR_CHAN_BURST_SIZE_2 0x0000c000
+#define DMFC_WR_CHAN_FIFO_SIZE_2 0x00003800
+#define DMFC_WR_CHAN_ST_ADDR_2 0x00000700
+#define DMFC_WR_CHAN_BURST_SIZE_1 0x000000c0
+#define DMFC_WR_CHAN_FIFO_SIZE_1 0x00000038
+#define DMFC_WR_CHAN_ST_ADDR_1 0x00000007
+#define IPU_DMFC_WR_CHAN_DEF 0x00000008
+#define DMFC_WR_CHAN_DEF_WM_CLR_2C 0xe0000000
+#define DMFC_WR_CHAN_DEF_WM_SET_2C 0x1c000000
+#define DMFC_WR_CHAN_DEF_WM_EN_2C 0x02000000
+#define DMFC_WR_CHAN_DEF_WM_CLR_1C 0x00e00000
+#define DMFC_WR_CHAN_DEF_WM_SET_1C 0x001c0000
+#define DMFC_WR_CHAN_DEF_WM_EN_1C 0x00020000
+#define DMFC_WR_CHAN_DEF_WM_CLR_2 0x0000e000
+#define DMFC_WR_CHAN_DEF_WM_SET_2 0x00001c00
+#define DMFC_WR_CHAN_DEF_WM_EN_2 0x00000200
+#define DMFC_WR_CHAN_DEF_WM_CLR_1 0x000000e0
+#define DMFC_WR_CHAN_DEF_WM_SET_1 0x0000000c
+#define DMFC_WR_CHAN_DEF_WM_EN_1 0x00000002
+#define IPU_DMFC_DP_CHAN 0x0000000c
+#define DMFC_DP_CHAN_BUSRT_SIZE_6F 0xc0000000
+#define DMFC_DP_CHAN_FIFO_SIZE_6F 0x38000000
+#define DMFC_DP_CHAN_ST_ADDR_6F 0x07000000
+#define DMFC_DP_CHAN_BURST_SIZE_6B 0x00c00000
+#define DMFC_DP_CHAN_FIFO_SIZE_6B 0x00380000
+#define DMFC_DP_CHAN_ST_ADDR_6B 0x00070000
+#define DMFC_DP_CHAN_BURST_SIZE_5F 0x0000c000
+#define DMFC_DP_CHAN_FIFO_SIZE_5F 0x00003800
+#define DMFC_DP_CHAN_ST_ADDR_5F 0x00000700
+#define DMFC_DP_CHAN_BURST_SIZE_5B 0x000000c0
+#define DMFC_DP_CHAN_FIFO_SIZE_5B 0x00000038
+#define DMFC_DP_CHAN_ST_ADDR_5B 0x00000007
+#define IPU_DMFC_DP_CHAN_DEF 0x00000010
+#define DMFC_DP_CHAN_DEF_WM_CLR_6F 0xe0000000
+#define DMFC_DP_CHAN_DEF_WM_SET_6F 0x1c000000
+#define DMFC_DP_CHAN_DEF_WM_EN_6F 0x02000000
+#define DMFC_DP_CHAN_DEF_WM_CLR_6B 0x00e00000
+#define DMFC_DP_CHAN_DEF_WM_SET_6B 0x001c0000
+#define DMFC_DP_CHAN_DEF_WM_EN_6B 0x00020000
+#define DMFC_DP_CHAN_DEF_WM_CLR_5F 0x0000e000
+#define DMFC_DP_CHAN_DEF_WM_SET_5F 0x00001c00
+#define DMFC_DP_CHAN_DEF_WM_EN_5F 0x00000200
+#define DMFC_DP_CHAN_DEF_WM_CLR_5B 0x000000e0
+#define DMFC_DP_CHAN_DEF_WM_SET_5B 0x0000001c
+#define DMFC_DP_CHAN_DEF_WM_EN_5B 0x00000002
+#define IPU_DMFC_GENERAL1 0x00000014
+#define DMFC_GENERAL1_WAIT4EOT_9 0x01000000
+#define DMFC_GENERAL1_WAIT4EOT_6F 0x00800000
+#define DMFC_GENERAL1_WAIT4EOT_6B 0x00400000
+#define DMFC_GENERAL1_WAIT4EOT_5F 0x00200000
+#define DMFC_GENERAL1_WAIT4EOT_5B 0x00100000
+#define DMFC_GENERAL1_WAIT4EOT_4 0x00080000
+#define DMFC_GENERAL1_WAIT4EOT_3 0x00040000
+#define DMFC_GENERAL1_WAIT4EOT_2 0x00020000
+#define DMFC_GENERAL1_WAIT4EOT_1 0x00010000
+#define DMFC_GENERAL1_WM_CLR_9 0x0000e000
+#define DMFC_GENERAL1_WM_SET_9 0x00001c00
+#define DMFC_GENERAL1_BURST_SIZE_9 0x00000060
+#define DMFC_GENERAL1_DCDP_SYNC_PR 0x00000003
+#define DCDP_SYNC_PR_FORBIDDEN 0
+#define DCDP_SYNC_PR_DC_DP 1
+#define DCDP_SYNC_PR_DP_DC 2
+#define DCDP_SYNC_PR_ROUNDROBIN 3
+#define IPU_DMFC_GENERAL2 0x00000018
+#define DMFC_GENERAL2_FRAME_HEIGHT_RD 0x1fff0000
+#define DMFC_GENERAL2_FRAME_WIDTH_RD 0x00001fff
+#define IPU_DMFC_IC_CTRL 0x0000001c
+#define DMFC_IC_CTRL_IC_FRAME_HEIGHT_RD 0xfff80000
+#define DMFC_IC_CTRL_IC_FRAME_WIDTH_RD 0x0007ffc0
+#define DMFC_IC_CTRL_IC_PPW_C 0x00000030
+#define DMFC_IC_CTRL_IC_IN_PORT 0x00000007
+#define IC_IN_PORT_CH28 0
+#define IC_IN_PORT_CH41 1
+#define IC_IN_PORT_DISABLE 2
+#define IC_IN_PORT_CH23 4
+#define IC_IN_PORT_CH27 5
+#define IC_IN_PORT_CH24 6
+#define IC_IN_PORT_CH29 7
+#define IPU_DMFC_WR_CHAN_ALT 0x00000020
+#define IPU_DMFC_WR_CHAN_DEF_ALT 0x00000024
+#define IPU_DMFC_DP_CHAN_ALT 0x00000028
+#define IPU_DMFC_DP_CHAN_DEF_ALT 0x0000002c
+#define DMFC_DP_CHAN_DEF_ALT_WM_CLR_6F_ALT 0xe0000000
+#define DMFC_DP_CHAN_DEF_ALT_WM_SET_6F_ALT 0x1c000000
+#define DMFC_DP_CHAN_DEF_ALT_WM_EN_6F_ALT 0x02000000
+#define DMFC_DP_CHAN_DEF_ALT_WM_CLR_6B_ALT 0x00e00000
+#define DMFC_DP_CHAN_DEF_ALT_WM_SET_6B_ALT 0x001c0000
+#define DMFC_DP_CHAN_DEF_ALT_WM_EN_6B_ALT 0x00020000
+#define DMFC_DP_CHAN_DEF_ALT_WM_CLR_5B_ALT 0x000000e0
+#define DMFC_DP_CHAN_DEF_ALT_WM_SET_5B_ALT 0x0000001c
+#define DMFC_DP_CHAN_DEF_ALT_WM_EN_5B_ALT 0x00000002
+#define IPU_DMFC_GENERAL1_ALT 0x00000030
+#define DMFC_GENERAL1_ALT_WAIT4EOT_6F_ALT 0x00800000
+#define DMFC_GENERAL1_ALT_WAIT4EOT_6B_ALT 0x00400000
+#define DMFC_GENERAL1_ALT_WAIT4EOT_5B_ALT 0x00100000
+#define DMFC_GENERAL1_ALT_WAIT4EOT_2_ALT 0x00020000
+#define IPU_DMFC_STAT 0x00000034
+#define DMFC_STAT_IC_BUFFER_EMPTY 0x02000000
+#define DMFC_STAT_IC_BUFFER_FULL 0x01000000
+#define DMFC_STAT_FIFO_EMPTY(n) __BIT(12 + (n))
+#define DMFC_STAT_FIFO_FULL(n) __BIT((n))
+
+/*
+ * VCI
+ * Video De Interkacing Module
+ */
+#define IPU_VDI_FSIZE 0x00000000
+#define IPU_VDI_C 0x00000004
+
+/*
+ * DP
+ * Display Processor
+ */
+#define IPU_DP_COM_CONF_SYNC 0x00000000
+#define DP_FG_EN_SYNC 0x00000001
+#define DP_DP_GWAM_SYNC 0x00000004
+#define IPU_DP_GRAPH_WIND_CTRL_SYNC 0x00000004
+#define IPU_DP_FG_POS_SYNC 0x00000008
+#define IPU_DP_CUR_POS_SYNC 0x0000000c
+#define IPU_DP_CUR_MAP_SYNC 0x00000010
+#define IPU_DP_CSC_SYNC_0 0x00000054
+#define IPU_DP_CSC_SYNC_1 0x00000058
+#define IPU_DP_CUR_POS_ALT 0x0000005c
+#define IPU_DP_COM_CONF_ASYNC0 0x00000060
+#define IPU_DP_GRAPH_WIND_CTRL_ASYNC0 0x00000064
+#define IPU_DP_FG_POS_ASYNC0 0x00000068
+#define IPU_DP_CUR_POS_ASYNC0 0x0000006c
+#define IPU_DP_CUR_MAP_ASYNC0 0x00000070
+#define IPU_DP_CSC_ASYNC0_0 0x000000b4
+#define IPU_DP_CSC_ASYNC0_1 0x000000b8
+#define IPU_DP_COM_CONF_ASYNC1 0x000000bc
+#define IPU_DP_GRAPH_WIND_CTRL_ASYNC1 0x000000c0
+#define IPU_DP_FG_POS_ASYNC1 0x000000c4
+#define IPU_DP_CUR_POS_ASYNC1 0x000000c8
+#define IPU_DP_CUR_MAP_ASYNC1 0x000000cc
+#define IPU_DP_CSC_ASYNC1_0 0x00000110
+#define IPU_DP_CSC_ASYNC1_1 0x00000114
+
+/* IDMA parameter */
+ /*
+ * non-Interleaved parameter
+ *
+ * param 0: XV W0[ 9: 0]
+ * YV W0[18:10]
+ * XB W0[31:19]
+ * param 1: YB W0[43:32]
+ * NSB W0[44]
+ * CF W0[45]
+ * UBO W0[61:46]
+ * param 2: UBO W0[67:62]
+ * VBO W0[89:68]
+ * IOX W0[93:90]
+ * RDRW W0[94]
+ * Reserved W0[95]
+ * param 3: Reserved W0[112:96]
+ * S0 W0[113]
+ * BNDM W0[116:114]
+ * BM W0[118:117]
+ * ROT W0[119]
+ * HF W0[120]
+ * VF W0[121]
+ * THF W0[122]
+ * CAP W0[123]
+ * CAE W0[124]
+ * FW W0[127:125]
+ * param 4: FW W0[137:128]
+ * FH W0[149:138]
+ * param 5: EBA0 W1[28:0]
+ * EBA1 W1[31:29]
+ * param 6: EBA1 W1[57:32]
+ * ILO W1[63:58]
+ * param 7: ILO W1[77:64]
+ * NPB W1[84:78]
+ * PFS W1[88:85]
+ * ALU W1[89]
+ * ALBM W1[92:90]
+ * ID W1[94:93]
+ * TH W1[95]
+ * param 8: TH W1[101:96]
+ * SLY W1[115:102]
+ * WID3 W1[127:125]
+ * param 9: SLUV W1[141:128]
+ * CRE W1[149]
+ *
+ * Interleaved parameter
+ *
+ * param 0: XV W0[ 9: 0]
+ * YV W0[18:10]
+ * XB W0[31:19]
+ * param 1: YB W0[43:32]
+ * NSB W0[44]
+ * CF W0[45]
+ * SX W0[57:46]
+ * SY W0[61:58]
+ * param 2: SY W0[68:62]
+ * NS W0[78:69]
+ * SDX W0[85:79]
+ * SM W0[95:86]
+ * param 3: SCC W0[96]
+ * SCE W0[97]
+ * SDY W0[104:98]
+ * SDRX W0[105]
+ * SDRY W0[106]
+ * BPP W0[109:107]
+ * DEC_SEL W0[111:110]
+ * DIM W0[112]
+ * SO W0[113]
+ * BNDM W0[116:114]
+ * BM W0[118:117]
+ * ROT W0[119]
+ * HF W0[120]
+ * VF W0[121]
+ * THF W0[122]
+ * CAP W0[123]
+ * CAE W0[124]
+ * FW W0[127:125]
+ * param 4: FW W0[137:128]
+ * FH W0[149:138]
+ * param 5: EBA0 W1[28:0]
+ * EBA1 W1[31:29]
+ * param 6: EBA1 W1[57:32]
+ * ILO W1[63:58]
+ * param 7: ILO W1[77:64]
+ * NPB W1[84:78]
+ * PFS W1[88:85]
+ * ALU W1[89]
+ * ALBM W1[92:90]
+ * ID W1[94:93]
+ * TH W1[95]
+ * param 8: TH W1[101:96]
+ * SL W1[115:102]
+ * WID0 W1[118:116]
+ * WID1 W1[121:119]
+ * WID2 W1[124:122]
+ * WID3 W1[127:125]
+ * param 9: OFS0 W1[132:128]
+ * OFS1 W1[137:133]
+ * OFS2 W1[142:138]
+ * OFS3 W1[147:143]
+ * SXYS W1[148]
+ * CRE W1[149]
+ * DEC_SEL2 W1[150]
+ */
+
+#define __IDMA_PARAM(word, shift, size) \
+ ((((word) & 0xff) << 16) | (((shift) & 0xff) << 8) | ((size) & 0xff))
+
+/* non-Interleaved parameter */
+/* W0 */
+#define IDMAC_Ch_PARAM_XV __IDMA_PARAM(0, 0, 10)
+#define IDMAC_Ch_PARAM_YV __IDMA_PARAM(0, 10, 9)
+#define IDMAC_Ch_PARAM_XB __IDMA_PARAM(0, 19, 13)
+#define IDMAC_Ch_PARAM_YB __IDMA_PARAM(0, 32, 12)
+#define IDMAC_Ch_PARAM_NSB __IDMA_PARAM(0, 44, 1)
+#define IDMAC_Ch_PARAM_CF __IDMA_PARAM(0, 45, 1)
+#define IDMAC_Ch_PARAM_UBO __IDMA_PARAM(0, 46, 22)
+#define IDMAC_Ch_PARAM_VBO __IDMA_PARAM(0, 68, 22)
+#define IDMAC_Ch_PARAM_IOX __IDMA_PARAM(0, 90, 4)
+#define IDMAC_Ch_PARAM_RDRW __IDMA_PARAM(0, 94, 1)
+#define IDMAC_Ch_PARAM_S0 __IDMA_PARAM(0,113, 1)
+#define IDMAC_Ch_PARAM_BNDM __IDMA_PARAM(0,114, 3)
+#define IDMAC_Ch_PARAM_BM __IDMA_PARAM(0,117, 2)
+#define IDMAC_Ch_PARAM_ROT __IDMA_PARAM(0,119, 1)
+#define IDMAC_Ch_PARAM_HF __IDMA_PARAM(0,120, 1)
+#define IDMAC_Ch_PARAM_VF __IDMA_PARAM(0,121, 1)
+#define IDMAC_Ch_PARAM_THF __IDMA_PARAM(0,122, 1)
+#define IDMAC_Ch_PARAM_CAP __IDMA_PARAM(0,123, 1)
+#define IDMAC_Ch_PARAM_CAE __IDMA_PARAM(0,124, 1)
+#define IDMAC_Ch_PARAM_FW __IDMA_PARAM(0,125, 13)
+#define IDMAC_Ch_PARAM_FH __IDMA_PARAM(0,138, 12)
+/* W1 */
+#define IDMAC_Ch_PARAM_EBA0 __IDMA_PARAM(1, 0, 29)
+#define IDMAC_Ch_PARAM_EBA1 __IDMA_PARAM(1, 29, 29)
+#define IDMAC_Ch_PARAM_ILO __IDMA_PARAM(1, 58, 20)
+#define IDMAC_Ch_PARAM_NPB __IDMA_PARAM(1, 78, 7)
+#define IDMAC_Ch_PARAM_PFS __IDMA_PARAM(1, 85, 4)
+#define IDMAC_Ch_PARAM_ALU __IDMA_PARAM(1, 89, 1)
+#define IDMAC_Ch_PARAM_ALBM __IDMA_PARAM(1, 90, 3)
+#define IDMAC_Ch_PARAM_ID __IDMA_PARAM(1, 93, 2)
+#define IDMAC_Ch_PARAM_TH __IDMA_PARAM(1, 95, 7)
+#define IDMAC_Ch_PARAM_SL __IDMA_PARAM(1,102, 14)
+#define IDMAC_Ch_PARAM_WID3 __IDMA_PARAM(1,125, 3)
+#define IDMAC_Ch_PARAM_SLUV __IDMA_PARAM(1,128, 14)
+#define IDMAC_Ch_PARAM_CRE __IDMA_PARAM(1,149, 1)
+
+/* Interleaved parameter */
+/* W0 */
+#define IDMAC_Ch_PARAM_XV __IDMA_PARAM(0, 0, 10)
+#define IDMAC_Ch_PARAM_YV __IDMA_PARAM(0, 10, 9)
+#define IDMAC_Ch_PARAM_XB __IDMA_PARAM(0, 19, 13)
+#define IDMAC_Ch_PARAM_YB __IDMA_PARAM(0, 32, 12)
+#define IDMAC_Ch_PARAM_NSB __IDMA_PARAM(0, 44, 1)
+#define IDMAC_Ch_PARAM_CF __IDMA_PARAM(0, 45, 1)
+#define IDMAC_Ch_PARAM_SX __IDMA_PARAM(0, 46, 12)
+#define IDMAC_Ch_PARAM_SY __IDMA_PARAM(0, 58, 11)
+#define IDMAC_Ch_PARAM_NS __IDMA_PARAM(0, 69, 10)
+#define IDMAC_Ch_PARAM_SDX __IDMA_PARAM(0, 79, 7)
+#define IDMAC_Ch_PARAM_SM __IDMA_PARAM(0, 86, 10)
+#define IDMAC_Ch_PARAM_SCC __IDMA_PARAM(0, 96, 1)
+#define IDMAC_Ch_PARAM_SCE __IDMA_PARAM(0, 97, 1)
+#define IDMAC_Ch_PARAM_SDY __IDMA_PARAM(0, 98, 7)
+#define IDMAC_Ch_PARAM_SDRX __IDMA_PARAM(0,105, 1)
+#define IDMAC_Ch_PARAM_SDRY __IDMA_PARAM(0,106, 1)
+#define IDMAC_Ch_PARAM_BPP __IDMA_PARAM(0,107, 3)
+#define IDMAC_Ch_PARAM_DEC_SEL __IDMA_PARAM(0,110, 2)
+#define IDMAC_Ch_PARAM_DIM __IDMA_PARAM(0,112, 1)
+#define IDMAC_Ch_PARAM_SO __IDMA_PARAM(0,113, 1)
+#define IDMAC_Ch_PARAM_BNDM __IDMA_PARAM(0,114, 3)
+#define IDMAC_Ch_PARAM_BM __IDMA_PARAM(0,117, 2)
+#define IDMAC_Ch_PARAM_ROT __IDMA_PARAM(0,119, 1)
+#define IDMAC_Ch_PARAM_HF __IDMA_PARAM(0,120, 1)
+#define IDMAC_Ch_PARAM_VF __IDMA_PARAM(0,121, 1)
+#define IDMAC_Ch_PARAM_THF __IDMA_PARAM(0,122, 1)
+#define IDMAC_Ch_PARAM_CAP __IDMA_PARAM(0,123, 1)
+#define IDMAC_Ch_PARAM_CAE __IDMA_PARAM(0,124, 1)
+#define IDMAC_Ch_PARAM_FW __IDMA_PARAM(0,125, 13)
+#define IDMAC_Ch_PARAM_FH __IDMA_PARAM(0,138, 12)
+/* W1 */
+#define IDMAC_Ch_PARAM_EBA0 __IDMA_PARAM(1, 0, 29)
+#define IDMAC_Ch_PARAM_EBA1 __IDMA_PARAM(1, 29, 29)
+#define IDMAC_Ch_PARAM_ILO __IDMA_PARAM(1, 58, 20)
+#define IDMAC_Ch_PARAM_NPB __IDMA_PARAM(1, 78, 7)
+#define IDMAC_Ch_PARAM_PFS __IDMA_PARAM(1, 85, 4)
+#define IDMAC_Ch_PARAM_ALU __IDMA_PARAM(1, 89, 1)
+#define IDMAC_Ch_PARAM_ALBM __IDMA_PARAM(1, 90, 3)
+#define IDMAC_Ch_PARAM_ID __IDMA_PARAM(1, 93, 2)
+#define IDMAC_Ch_PARAM_TH __IDMA_PARAM(1, 95, 7)
+#define IDMAC_Ch_PARAM_SL __IDMA_PARAM(1,102, 14)
+#define IDMAC_Ch_PARAM_WID0 __IDMA_PARAM(1,116, 3)
+#define IDMAC_Ch_PARAM_WID1 __IDMA_PARAM(1,119, 3)
+#define IDMAC_Ch_PARAM_WID2 __IDMA_PARAM(1,122, 3)
+#define IDMAC_Ch_PARAM_WID3 __IDMA_PARAM(1,125, 3)
+#define IDMAC_Ch_PARAM_OFS0 __IDMA_PARAM(1,128, 5)
+#define IDMAC_Ch_PARAM_OFS1 __IDMA_PARAM(1,133, 5)
+#define IDMAC_Ch_PARAM_OFS2 __IDMA_PARAM(1,138, 5)
+#define IDMAC_Ch_PARAM_OFS3 __IDMA_PARAM(1,143, 5)
+#define IDMAC_Ch_PARAM_SXYS __IDMA_PARAM(1,148, 1)
+#define IDMAC_Ch_PARAM_CRE __IDMA_PARAM(1,149, 1)
+#define IDMAC_Ch_PARAM_DEC_SEL2 __IDMA_PARAM(1,150, 1)
+
+/* XXX Temp */
+#define GPUMEM_BASE 0x20000000
+#define GPUMEM_SIZE 0x20000
+
+#define GPU_BASE 0x30000000
+#define GPU_SIZE 0x10000000
+
+/* Image Prossasing Unit */
+#define IPU_BASE 0x40000000
+#define IPU_CM_BASE (IPU_BASE + 0x1e000000)
+#define IPU_CM_SIZE 0x8000
+#define IPU_IDMAC_BASE (IPU_BASE + 0x1e008000)
+#define IPU_IDMAC_SIZE 0x8000
+#define IPU_DP_BASE (IPU_BASE + 0x1e018000)
+#define IPU_DP_SIZE 0x8000
+#define IPU_IC_BASE (IPU_BASE + 0x1e020000)
+#define IPU_IC_SIZE 0x8000
+#define IPU_IRT_BASE (IPU_BASE + 0x1e028000)
+#define IPU_IRT_SIZE 0x8000
+#define IPU_CSI0_BASE (IPU_BASE + 0x1e030000)
+#define IPU_CSI0_SIZE 0x8000
+#define IPU_CSI1_BASE (IPU_BASE + 0x1e038000)
+#define IPU_CSI1_SIZE 0x8000
+#define IPU_DI0_BASE (IPU_BASE + 0x1e040000)
+#define IPU_DI0_SIZE 0x8000
+#define IPU_DI1_BASE (IPU_BASE + 0x1e048000)
+#define IPU_DI1_SIZE 0x8000
+#define IPU_SMFC_BASE (IPU_BASE + 0x1e050000)
+#define IPU_SMFC_SIZE 0x8000
+#define IPU_DC_BASE (IPU_BASE + 0x1e058000)
+#define IPU_DC_SIZE 0x8000
+#define IPU_DMFC_BASE (IPU_BASE + 0x1e060000)
+#define IPU_DMFC_SIZE 0x8000
+#define IPU_VDI_BASE (IPU_BASE + 0x1e068000)
+#define IPU_VDI_SIZE 0x8000
+#define IPU_CPMEM_BASE (IPU_BASE + 0x1f000000)
+#define IPU_CPMEM_SIZE 0x20000
+#define IPU_LUT_BASE (IPU_BASE + 0x1f020000)
+#define IPU_LUT_SIZE 0x20000
+#define IPU_SRM_BASE (IPU_BASE + 0x1f040000)
+#define IPU_SRM_SIZE 0x20000
+#define IPU_TPM_BASE (IPU_BASE + 0x1f060000)
+#define IPU_TPM_SIZE 0x20000
+#define IPU_DCTMPL_BASE (IPU_BASE + 0x1f080000)
+#define IPU_DCTMPL_SIZE 0x20000
+
+#endif /* _ARM_IMX_IMX51_IPUV3REG_H */
diff --git a/sys/arm/freescale/imx/imx51_sdmareg.h b/sys/arm/freescale/imx/imx51_sdmareg.h
new file mode 100644
index 0000000..cc9cacb
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_sdmareg.h
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+/* Internal Registers definition for Freescale i.MX515 SDMA Core */
+
+/* SDMA Core Instruction Memory Space */
+#define SDMA_IBUS_ROM_ADDR_BASE 0x0000
+#define SDMA_IBUS_ROM_ADDR_SIZE 0x07ff
+#define SDMA_IBUS_RAM_ADDR_BASE 0x1000
+#define SDMA_IBUS_RAM_ADDR_SIZE 0x1fff
+
+/* SDMA Core Internal Registers */
+#define SDMA_MC0PTR 0x7000 /* AP (MCU) Channel 0 Pointer R */
+
+#define SDMA_CCPTR 0x7002 /* Current Channel Pointer R */
+#define SDMA_ECTL_CCPTR_MASK 0x0000ffff
+#define SDMA_ECTL_CCPTR_SHIFT 0
+
+#define SDMA_CCR 0x7003 /* Current Channel Register R */
+#define SDMA_ECTL_CCR_MASK 0x0000001f
+#define SDMA_ECTL_CCR_SHIFT 0
+
+#define SDMA_NCR 0x7004 /* Highest Pending Channel Register R */
+#define SDMA_ECTL_NCR_MASK 0x0000001f
+#define SDMA_ECTL_NCR_SHIFT 0
+
+#define SDMA_EVENTS 0x7005 /* External DMA Requests Mirror R */
+
+#define SDMA_CCPRI 0x7006 /* Current Channel Priority R */
+#define SDMA_ECTL_CCPRI_MASK 0x00000007
+#define SDMA_ECTL_CCPRI_SHIFT 0
+
+#define SDMA_NCPRI 0x7007 /* Next Channel Priority R */
+#define SDMA_ECTL_NCPRI_MASK 0x00000007
+#define SDMA_ECTL_NCPRI_SHIFT 0
+
+#define SDMA_ECOUNT 0x7009 /* OnCE Event Cell Counter R/W */
+#define SDMA_ECTL_ECOUNT_MASK 0x0000ffff
+#define SDMA_ECTL_ECOUNT_SHIFT 0
+
+#define SDMA_ECTL 0x700A /* OnCE Event Cell Control Register R/W */
+#define SDMA_ECTL_EN (1 << 13)
+#define SDMA_ECTL_CNT (1 << 12)
+#define SDMA_ECTL_ECTC_MASK 0x00000c00
+#define SDMA_ECTL_ECTC_SHIFT 10
+#define SDMA_ECTL_DTC_MASK 0x00000300
+#define SDMA_ECTL_DTC_SHIFT 8
+#define SDMA_ECTL_ATC_MASK 0x000000c0
+#define SDMA_ECTL_ATC_SHIFT 6
+#define SDMA_ECTL_ABTC_MASK 0x00000030
+#define SDMA_ECTL_ABTC_SHIFT 4
+#define SDMA_ECTL_AATC_MASK 0x0000000c
+#define SDMA_ECTL_AATC_SHIFT 2
+#define SDMA_ECTL_ATS_MASK 0x00000003
+#define SDMA_ECTL_ATS_SHIFT 0
+
+#define SDMA_EAA 0x700B /* OnCE Event Address Register A R/W */
+#define SDMA_ECTL_EAA_MASK 0x0000ffff
+#define SDMA_ECTL_EAA_SHIFT 0
+
+#define SDMA_EAB 0x700C /* OnCE Event Cell Address Register B R/W */
+#define SDMA_ECTL_EAB_MASK 0x0000ffff
+#define SDMA_ECTL_EAB_SHIFT 0
+
+#define SDMA_EAM 0x700D /* OnCE Event Cell Address Mask R/W */
+#define SDMA_ECTL_EAM_MASK 0x0000ffff
+#define SDMA_ECTL_EAM_SHIFT 0
+
+#define SDMA_ED 0x700E /* OnCE Event Cell Data Register R/W */
+#define SDMA_EDM 0x700F /* OnCE Event Cell Data Mask R/W */
+#define SDMA_RTB 0x7018 /* OnCE Real-Time Buffer R/W */
+
+#define SDMA_TB 0x7019 /* OnCE Trace Buffer R */
+#define SDMA_TB_TBF (1 << 28)
+#define SDMA_TB_TADDR_MASK 0x0fffc000
+#define SDMA_TB_TADDR_SHIFT 14
+#define SDMA_TB_CHFADDR_MASK 0x00003fff
+#define SDMA_TB_CHFADDR_SHIFT 0
+
+#define SDMA_OSTAT 0x701A /* OnCE Status R */
+#define SDMA_OSTAT_PST_MASK 0x0000f000
+#define SDMA_OSTAT_PST_SHIFT 12
+#define SDMA_OSTAT_RCV (1 << 11)
+#define SDMA_OSTAT_EDR (1 << 10)
+#define SDMA_OSTAT_ODR (1 << 9)
+#define SDMA_OSTAT_SWB (1 << 8)
+#define SDMA_OSTAT_MST (1 << 7)
+#define SDMA_OSTAT_ECDR_MASK 0x00000007
+#define SDMA_OSTAT_ECDR_SHIFT 0
+
+#define SDMA_MCHN0ADDR 0x701C /* Channel 0 Boot Address R */
+#define SDMA_MCHN0ADDR_SMS_Z (1 << 14)
+#define SDMA_MCHN0ADDR_CHN0ADDR_MASK 0x00003fff
+#define SDMA_MCHN0ADDR_CHN0ADDR_SHIFT 0
+
+#define SDMA_MODE 0x701D /* Mode Status Register R */
+#define SDMA_MODE_DSPCtrl (1 << 3)
+#define SDMA_MODE_AP_END (1 << 0)
+
+#define SDMA_LOCK 0x701E /* Lock Status Register R */
+#define SDMA_LOCK_LOCK (1 << 0)
+
+#define SDMA_EVENTS2 0x701F /* External DMA Requests Mirror #2 R */
+
+#define SDMA_HE 0x7020 /* AP Enable Register R */
+#define SDMA_PRIV 0x7022 /* Current Channel BP Privilege Register R */
+#define SDMA_PRIV_BPPRIV (1 << 0)
+#define SDMA_PRF_CNT 0x7023 /* Profile Free Running Register R/W */
+#define SDMA_PRF_CNT_SEL_MASK 0xc0000000
+#define SDMA_PRF_CNT_SEL_SHIFT 30
+#define SDMA_PRF_CNT_EN (1 << 29)
+#define SDMA_PRF_CNT_OFL (1 << 22)
+#define SDMA_PRF_CNT_COUNTER_MASK 0x003fffff
+#define SDMA_PRF_CNT_COUNTER_SHIFT 0
diff --git a/sys/arm/freescale/imx/imx51_ssireg.h b/sys/arm/freescale/imx/imx51_ssireg.h
new file mode 100644
index 0000000..1a5b5b3
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_ssireg.h
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+/* Registers definition for Freescale i.MX515 Synchronous Serial Interface */
+
+#define IMX51_SSI_STX0_REG 0x0000 /* SSI TX Data Register 0 */
+#define IMX51_SSI_STX1_REG 0x0004 /* SSI TX Data Register 1 */
+#define IMX51_SSI_SRX0_REG 0x0008 /* SSI RX Data Register 0 */
+#define IMX51_SSI_SRX1_REG 0x000C /* SSI RX Data Register 1 */
+#define IMX51_SSI_SCR_REG 0x0010 /* SSI Control Register */
+#define SSI_SCR_RFR_CLK_DIS (1 << 11) /* RX FC Disable */
+#define SSI_SCR_TFR_CLK_DIS (1 << 10) /* TX FC Disable */
+#define SSI_SCR_CLK_IST (1 << 9) /* Clock Idle */
+#define SSI_SCR_TCH_EN (1 << 8) /* 2Chan Enable */
+#define SSI_SCR_SYS_CLK_EN (1 << 7) /* System Clock En */
+#define SSI_SCR_MODE_NORMAL (0 << 5)
+#define SSI_SCR_MODE_I2S_MASTER (1 << 5)
+#define SSI_SCR_MODE_I2S_SLAVE (2 << 5)
+#define SSI_SCR_MODE_MASK (3 << 5)
+#define SSI_SCR_SYN (1 << 4) /* Sync Mode */
+#define SSI_SCR_NET (1 << 3) /* Network Mode */
+#define SSI_SCR_RE (1 << 2) /* RX Enable */
+#define SSI_SCR_TE (1 << 1) /* TX Enable */
+#define SSI_SCR_SSIEN (1 << 0) /* SSI Enable */
+
+#define IMX51_SSI_SISR_REG 0x0014 /* SSI Interrupt Status Register */
+#define SSI_SISR_RFRC (1 << 24) /* RX Frame Complete */
+#define SSI_SIR_TFRC (1 << 23) /* TX Frame Complete */
+#define SSI_SIR_CMDAU (1 << 18) /* Command Address Updated */
+#define SSI_SIR_CMDDU (1 << 17) /* Command Data Updated */
+#define SSI_SIR_RXT (1 << 16) /* RX Tag Updated */
+#define SSI_SIR_RDR1 (1 << 15) /* RX Data Ready 1 */
+#define SSI_SIR_RDR0 (1 << 14) /* RX Data Ready 0 */
+#define SSI_SIR_TDE1 (1 << 13) /* TX Data Reg Empty 1 */
+#define SSI_SIR_TDE0 (1 << 12) /* TX Data Reg Empty 0 */
+#define SSI_SIR_ROE1 (1 << 11) /* RXer Overrun Error 1 */
+#define SSI_SIR_ROE0 (1 << 10) /* RXer Overrun Error 0 */
+#define SSI_SIR_TUE1 (1 << 9) /* TXer Underrun Error 1 */
+#define SSI_SIR_TUE0 (1 << 8) /* TXer Underrun Error 0 */
+#define SSI_SIR_TFS (1 << 7) /* TX Frame Sync */
+#define SSI_SIR_RFS (1 << 6) /* RX Frame Sync */
+#define SSI_SIR_TLS (1 << 5) /* TX Last Time Slot */
+#define SSI_SIR_RLS (1 << 4) /* RX Last Time Slot */
+#define SSI_SIR_RFF1 (1 << 3) /* RX FIFO Full 1 */
+#define SSI_SIR_RFF0 (1 << 2) /* RX FIFO Full 0 */
+#define SSI_SIR_TFE1 (1 << 1) /* TX FIFO Empty 1 */
+#define SSI_SIR_TFE0 (1 << 0) /* TX FIFO Empty 0 */
+
+#define IMX51_SSI_SIER_REG 0x0018 /* SSI Interrupt Enable Register */
+/* 24-23 Enable Bit (See SISR) */
+#define SSI_SIER_RDMAE (1 << 22) /* RX DMA Enable */
+#define SSI_SIER_RIE (1 << 21) /* RX Interrupt Enable */
+#define SSI_SIER_TDMAE (1 << 20) /* TX DMA Enable */
+#define SSI_SIER_TIE (1 << 19) /* TX Interrupt Enable */
+/* 18-0 Enable Bits (See SISR) */
+
+#define IMX51_SSI_STCR_REG 0x001C /* SSI TX Configuration Register */
+#define SSI_STCR_TXBIT0 (1 << 9) /* TX Bit 0 */
+#define SSI_STCR_TFEN1 (1 << 8) /* TX FIFO Enable 1 */
+#define SSI_STCR_TFEN0 (1 << 7) /* TX FIFO Enable 0 */
+#define SSI_STCR_TFDIR (1 << 6) /* TX Frame Direction */
+#define SSI_STCR_TXDIR (1 << 5) /* TX Clock Direction */
+#define SSI_STCR_TSHFD (1 << 4) /* TX Shift Direction */
+#define SSI_STCR_TSCKP (1 << 3) /* TX Clock Polarity */
+#define SSI_STCR_TFSI (1 << 2) /* TX Frame Sync Invert */
+#define SSI_STCR_TFSL (1 << 1) /* TX Frame Sync Length */
+#define SSI_STCR_TEFS (1 << 0) /* TX Early Frame Sync */
+
+#define IMX51_SSI_SRCR_REG 0x0020 /* SSI RX Configuration Register */
+#define SSI_SRCR_RXEXT (1 << 10) /* RX Data Extension */
+#define SSI_SRCR_RXBIT0 (1 << 9) /* RX Bit 0 */
+#define SSI_SRCR_RFEN1 (1 << 8) /* RX FIFO Enable 1 */
+#define SSI_SRCR_RFEN0 (1 << 7) /* RX FIFO Enable 0 */
+#define SSI_SRCR_RFDIR (1 << 6) /* RX Frame Direction */
+#define SSI_SRCR_RXDIR (1 << 5) /* RX Clock Direction */
+#define SSI_SRCR_RSHFD (1 << 4) /* RX Shift Direction */
+#define SSI_SRCR_RSCKP (1 << 3) /* RX Clock Polarity */
+#define SSI_SRCR_RFSI (1 << 2) /* RX Frame Sync Invert */
+#define SSI_SRCR_RFSL (1 << 1) /* RX Frame Sync Length */
+#define SSI_SRCR_REFS (1 << 0) /* RX Early Frame Sync */
+
+#define IMX51_SSI_STCCR_REG 0x0024 /* TX Clock Control */
+#define IMX51_SSI_SRCCR_REG 0x0028 /* RX Clock Control */
+#define SSI_SXCCR_DIV2 (1 << 18) /* Divide By 2 */
+#define SSI_SXCCR_PSR (1 << 17) /* Prescaler Range */
+#define SSI_SXCCR_WL_MASK 0x0001e000
+#define SSI_SXCCR_WL_SHIFT 13 /* Word Length Control */
+#define SSI_SXCCR_DC_MASK 0x00001f00
+#define SSI_SXCCR_DC_SHIFT 8 /* Frame Rate Divider */
+#define SSI_SXCCR_PM_MASK 0x000000ff
+#define SSI_SXCCR_PM_SHIFT 0 /* Prescaler Modulus */
+
+#define IMX51_SSI_SFCSR_REG 0x002C /* SSI FIFO Control/Status Register */
+#define SSI_SFCSR_RFCNT1_MASK 0xf0000000
+#define SSI_SFCSR_RFCNT1_SHIFT 28 /* RX FIFO Counter 1 */
+#define SSI_SFCSR_TFCNT1_MASK 0x0f000000
+#define SSI_SFCSR_TFCNT1_SHIFT 24 /* TX FIFO Counter 1 */
+#define SSI_SFCSR_RFWM1_MASK 0x00f00000
+#define SSI_SFCSR_RFWM1_SHIFT 20 /* RX FIFO Full WaterMark 1 */
+#define SSI_SFCSR_TFWM1_MASK 0x000f0000
+#define SSI_SFCSR_TFWM1_SHIFT 16 /* TX FIFO Empty WaterMark 1 */
+#define SSI_SFCSR_RFCNT0_MASK 0x0000f000
+#define SSI_SFCSR_RFCNT0_SHIFT 12 /* RX FIFO Counter 0 */
+#define SSI_SFCSR_TFCNT0_MASK 0x00000f00
+#define SSI_SFCSR_TFCNT0_SHIFT 8 /* TX FIFO Counter 0 */
+#define SSI_SFCSR_RFWM0_MASK 0x000000f0
+#define SSI_SFCSR_RFWM0_SHIFT 4 /* RX FIFO Full WaterMark 0 */
+#define SSI_SFCSR_TFWM0_MASK 0x0000000f
+#define SSI_SFCSR_TFWM0_SHIFT 0 /* TX FIFO Empty WaterMark 0 */
+
+#define IMX51_SSI_STR_REG 0x0030 /* SSI Test Register1 */
+#define SSI_STR_TEST (1 << 15) /* Test Mode */
+#define SSI_STR_RCK2TCK (1 << 14) /* RX<->TX Clock Loop Back */
+#define SSI_STR_RFS2TFS (1 << 13) /* RX<->TX Frame Loop Back */
+#define SSI_STR_RXSTATE_MASK 0x00001f00
+#define SSI_STR_RXSTATE_SHIFT 8 /* RXer State Machine Status */
+#define SSI_STR_TXD2RXD (1 << 7) /* TX<->RX Data Loop Back */
+#define SSI_STR_TCK2RCK (1 << 6) /* TX<->RX Clock Loop Back */
+#define SSI_STR_TFS2RFS (1 << 5) /* TX<->RX Frame Loop Back */
+#define SSI_STR_TXSTATE_MASK 0x0000001f
+#define SSI_STR_TXSTATE_SHIFT 0 /* TXer State Machine Status */
+
+#define IMX51_SSI_SOR_REG 0x0034 /* SSI Option Register2 */
+#define SSI_SOR_CLKOFF (1 << 6) /* Clock Off */
+#define SSI_SOR_RX_CLR (1 << 5) /* RXer Clear */
+#define SSI_SOR_TX_CLR (1 << 4) /* TXer Clear */
+#define SSI_SOR_INIT (1 << 3) /* Initialize */
+#define SSI_SOR_WAIT_MASK 0x00000006
+#define SSI_SOR_INIT_SHIFT 1 /* Wait */
+#define SSI_SOR_SYNRST (1 << 0) /* Frame Sync Reset */
+
+#define IMX51_SSI_SACNT_REG 0x0038 /* SSI AC97 Control Register */
+#define SSI_SACNT_FRDIV_MASK 0x000007e0
+#define SSI_SACNT_FRDIV_SHIFT 5 /* Frame Rate Divider */
+#define SSI_SACNT_WR (1 << 4) /* Write Command */
+#define SSI_SACNT_RD (1 << 3) /* Read Command */
+#define SSI_SACNT_TIF (1 << 2) /* Tag in FIFO */
+#define SSI_SACNT_FV (1 << 1) /* Fixed/Variable Operation */
+#define SSI_SACNT_AC97EN (1 << 0) /* AC97 Mode Enable */
+
+#define IMX51_SSI_SACADD_REG 0x003C /* SSI AC97 Command Address Register */
+#define SSI_SACADD_MASK 0x0007ffff
+#define IMX51_SSI_SACDAT_REG 0x0040 /* SSI AC97 Command Data Register */
+#define SSI_SACDAT_MASK 0x000fffff
+#define IMX51_SSI_SATAG_REG 0x0044 /* SSI AC97 Tag Register */
+#define SSI_SATAG_MASK 0x0000ffff
+#define IMX51_SSI_STMSK_REG 0x0048 /* SSI TX Time Slot Mask Register */
+#define IMX51_SSI_SRMSK_REG 0x004C /* SSI RX Time Slot Mask Register */
+#define IMX51_SSI_SACCST_REG 0x0050 /* SSI AC97 Channel Status Register */
+#define IMX51_SSI_SACCEN_REG 0x0054 /* SSI AC97 Channel Enable Register */
+#define IMX51_SSI_SACCDIS_REG 0x0058 /* SSI AC97 Channel Disable Register */
+#define SSI_SAC_MASK 0x000003ff /* SACCST,SACCEN,SACCDIS */
diff --git a/sys/arm/freescale/imx/imx51_tzicreg.h b/sys/arm/freescale/imx/imx51_tzicreg.h
new file mode 100644
index 0000000..d8eed64
--- /dev/null
+++ b/sys/arm/freescale/imx/imx51_tzicreg.h
@@ -0,0 +1,85 @@
+/* $NetBSD: imx51_tzicreg.h,v 1.1 2010/11/13 07:11:03 bsh Exp $ */
+/*
+ * Copyright (c) 2010 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _IMX51_TZICREG_H_
+#define _IMX51_TZICRREG_H_
+
+#include <sys/cdefs.h>
+
+#define TZIC_SIZE 0x4000
+#define TZIC_INTCNTL 0x0000
+#define INTCNTL_NSEN_MASK 0x80000000
+#define INTCNTL_NSEN 0x00010000
+#define INTCNTL_EN 0x00000001
+#define TZIC_INTTYPE 0x0004
+#define TZIC_PRIOMASK 0x000c
+#define TZIC_SYNCCTRL 0x0010
+#define TZIC_DSMINT 0x0014
+#define TZIC_INTSEC(n) (0x0080 + 0x04 * (n))
+#define TZIC_ENSET(n) (0x0100 + 0x04 * (n))
+#define TZIC_ENCLEAR(n) (0x0180 + 0x04 * (n))
+#define TZIC_SRCSET(n) (0x0200 + 0x04 * (n))
+#define TZIC_SRCCLAR(n) (0x0280 + 0x04 * (n))
+#define TZIC_PRIORITY(n) (0x0400 + 0x04 * (n))
+#define TZIC_PND(n) (0x0d00 + 0x04 * (n))
+#define TZIC_HIPND(n) (0x0d80 + 0x04 * (n))
+#define TZIC_WAKEUP(n) (0x0e00 + 0x04 * (n))
+#define TZIC_SWINT 0x0f00
+
+#define TZIC_INTNUM 128
+#endif /* _IMX51_TZICRREG_H_ */
diff --git a/sys/arm/freescale/imx/imx_gpt.c b/sys/arm/freescale/imx/imx_gpt.c
new file mode 100644
index 0000000..6e12d00
--- /dev/null
+++ b/sys/arm/freescale/imx/imx_gpt.c
@@ -0,0 +1,370 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+
+#include <machine/fdt.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 <arm/freescale/imx/imx_gptvar.h>
+#include <arm/freescale/imx/imx_gptreg.h>
+
+#include <sys/kdb.h>
+#include <arm/freescale/imx/imx51_ccmvar.h>
+
+#define MIN_PERIOD 100LLU
+
+#define WRITE4(_sc, _r, _v) \
+ bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r), (_v))
+#define READ4(_sc, _r) \
+ bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r))
+#define SET4(_sc, _r, _m) \
+ WRITE4((_sc), (_r), READ4((_sc), (_r)) | (_m))
+#define CLEAR4(_sc, _r, _m) \
+ WRITE4((_sc), (_r), READ4((_sc), (_r)) & ~(_m))
+
+static u_int imx_gpt_get_timecount(struct timecounter *);
+static int imx_gpt_timer_start(struct eventtimer *, sbintime_t,
+ sbintime_t);
+static int imx_gpt_timer_stop(struct eventtimer *);
+
+static int imx_gpt_intr(void *);
+static int imx_gpt_probe(device_t);
+static int imx_gpt_attach(device_t);
+
+static struct timecounter imx_gpt_timecounter = {
+ .tc_name = "i.MX GPT Timecounter",
+ .tc_get_timecount = imx_gpt_get_timecount,
+ .tc_counter_mask = ~0u,
+ .tc_frequency = 0,
+ .tc_quality = 500,
+};
+
+struct imx_gpt_softc *imx_gpt_sc = NULL;
+static volatile int imx_gpt_delay_count = 300;
+
+static struct resource_spec imx_gpt_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+imx_gpt_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,imx51-gpt"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale i.MXxxx GPT timer");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+imx_gpt_attach(device_t dev)
+{
+ struct imx_gpt_softc *sc;
+ int err;
+
+ sc = device_get_softc(dev);
+
+ if (bus_alloc_resources(dev, imx_gpt_spec, sc->res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ sc->sc_dev = dev;
+ sc->sc_clksrc = GPT_CR_CLKSRC_IPG;
+ sc->sc_iot = rman_get_bustag(sc->res[0]);
+ sc->sc_ioh = rman_get_bushandle(sc->res[0]);
+
+ switch (sc->sc_clksrc) {
+ case GPT_CR_CLKSRC_NONE:
+ device_printf(dev, "can't run timer without clock source\n");
+ return (EINVAL);
+ case GPT_CR_CLKSRC_EXT:
+ device_printf(dev, "Not implemented. Geve me the way to get "
+ "external clock source frequency\n");
+ return (EINVAL);
+ case GPT_CR_CLKSRC_32K:
+ sc->clkfreq = 32768;
+ break;
+ case GPT_CR_CLKSRC_IPG_HIGH:
+ sc->clkfreq = imx51_get_clock(IMX51CLK_IPG_CLK_ROOT) * 2;
+ break;
+ default:
+ sc->clkfreq = imx51_get_clock(IMX51CLK_IPG_CLK_ROOT);
+ }
+ device_printf(dev, "Run on %dKHz clock.\n", sc->clkfreq / 1000);
+
+ /* Reset */
+ WRITE4(sc, IMX_GPT_CR, GPT_CR_SWR);
+ /* Enable and setup counters */
+ WRITE4(sc, IMX_GPT_CR,
+ GPT_CR_CLKSRC_IPG | /* Use IPG clock */
+ GPT_CR_FRR | /* Just count (FreeRunner mode) */
+ GPT_CR_STOPEN | /* Run in STOP mode */
+ GPT_CR_WAITEN | /* Run in WAIT mode */
+ GPT_CR_DBGEN); /* Run in DEBUG mode */
+
+ /* Disable interrupts */
+ WRITE4(sc, IMX_GPT_IR, 0);
+
+ /* Tick every 10us */
+ /* XXX: must be calculated from clock source frequency */
+ WRITE4(sc, IMX_GPT_PR, 665);
+ /* Use 100 KHz */
+ sc->clkfreq = 100000;
+
+ /* Setup and enable the timer interrupt */
+ err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_CLK, imx_gpt_intr,
+ NULL, sc, &sc->sc_ih);
+ if (err != 0) {
+ bus_release_resources(dev, imx_gpt_spec, sc->res);
+ device_printf(dev, "Unable to setup the clock irq handler, "
+ "err = %d\n", err);
+ return (ENXIO);
+ }
+
+ sc->et.et_name = "i.MXxxx GPT Eventtimer";
+ sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
+ sc->et.et_quality = 1000;
+ sc->et.et_frequency = sc->clkfreq;
+ sc->et.et_min_period = (MIN_PERIOD << 32) / sc->et.et_frequency;
+ sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
+ sc->et.et_start = imx_gpt_timer_start;
+ sc->et.et_stop = imx_gpt_timer_stop;
+ sc->et.et_priv = sc;
+ et_register(&sc->et);
+
+ /* Disable interrupts */
+ WRITE4(sc, IMX_GPT_IR, 0);
+ /* ACK any panding interrupts */
+ WRITE4(sc, IMX_GPT_SR, (GPT_IR_ROV << 1) - 1);
+
+ if (device_get_unit(dev) == 0)
+ imx_gpt_sc = sc;
+
+ imx_gpt_timecounter.tc_frequency = sc->clkfreq;
+ tc_init(&imx_gpt_timecounter);
+
+ printf("clock: hz=%d stathz = %d\n", hz, stathz);
+
+ device_printf(sc->sc_dev, "timer clock frequency %d\n", sc->clkfreq);
+
+ imx_gpt_delay_count = imx51_get_clock(IMX51CLK_ARM_ROOT) / 4000000;
+
+ SET4(sc, IMX_GPT_CR, GPT_CR_EN);
+
+ return (0);
+}
+
+static int
+imx_gpt_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+ struct imx_gpt_softc *sc;
+ uint32_t ticks;
+
+ sc = (struct imx_gpt_softc *)et->et_priv;
+
+ if (period != 0) {
+ sc->sc_period = ((uint32_t)et->et_frequency * period) >> 32;
+ /* Set expected value */
+ WRITE4(sc, IMX_GPT_OCR2, READ4(sc, IMX_GPT_CNT) + sc->sc_period);
+ /* Enable compare register 2 Interrupt */
+ SET4(sc, IMX_GPT_IR, GPT_IR_OF2);
+ } else if (first != 0) {
+ ticks = ((uint32_t)et->et_frequency * first) >> 32;
+
+ /*
+ * TODO: setupt second compare reg with time which will save
+ * us in case correct one lost, f.e. if period to short and
+ * setup done later than counter reach target value.
+ */
+ /* Do not disturb, otherwise event will be lost */
+ spinlock_enter();
+ /* Set expected value */
+ WRITE4(sc, IMX_GPT_OCR1, READ4(sc, IMX_GPT_CNT) + ticks);
+ /* Enable compare register 1 Interrupt */
+ SET4(sc, IMX_GPT_IR, GPT_IR_OF1);
+ /* Now everybody can relax */
+ spinlock_exit();
+
+ return (0);
+ }
+
+ return (EINVAL);
+}
+
+static int
+imx_gpt_timer_stop(struct eventtimer *et)
+{
+ struct imx_gpt_softc *sc;
+
+ sc = (struct imx_gpt_softc *)et->et_priv;
+
+ /* Disable OF2 Interrupt */
+ CLEAR4(sc, IMX_GPT_IR, GPT_IR_OF2);
+ WRITE4(sc, IMX_GPT_SR, GPT_IR_OF2);
+ sc->sc_period = 0;
+
+ return (0);
+}
+
+int
+imx_gpt_get_timerfreq(struct imx_gpt_softc *sc)
+{
+
+ return (sc->clkfreq);
+}
+
+void
+cpu_initclocks(void)
+{
+
+ if (!imx_gpt_sc) {
+ panic("%s: driver has not been initialized!", __func__);
+ }
+
+ cpu_initclocks_bsp();
+
+ /* Switch to DELAY using counter */
+ imx_gpt_delay_count = 0;
+ device_printf(imx_gpt_sc->sc_dev,
+ "switch DELAY to use H/W counter\n");
+}
+
+static int
+imx_gpt_intr(void *arg)
+{
+ struct imx_gpt_softc *sc;
+ uint32_t status;
+
+ sc = (struct imx_gpt_softc *)arg;
+
+ /* Sometime we not get staus bit when interrupt arrive. Cache? */
+ while (!(status = READ4(sc, IMX_GPT_SR)))
+ ;
+
+ if (status & GPT_IR_OF1) {
+ if (sc->et.et_active) {
+ sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+ }
+ }
+ if (status & GPT_IR_OF2) {
+ if (sc->et.et_active) {
+ sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+ /* Set expected value */
+ WRITE4(sc, IMX_GPT_OCR2, READ4(sc, IMX_GPT_CNT) +
+ sc->sc_period);
+ }
+ }
+
+ /* ACK */
+ WRITE4(sc, IMX_GPT_SR, status);
+
+ return (FILTER_HANDLED);
+}
+
+u_int
+imx_gpt_get_timecount(struct timecounter *tc)
+{
+
+ if (imx_gpt_sc == NULL)
+ return (0);
+
+ return (READ4(imx_gpt_sc, IMX_GPT_CNT));
+}
+
+static device_method_t imx_gpt_methods[] = {
+ DEVMETHOD(device_probe, imx_gpt_probe),
+ DEVMETHOD(device_attach, imx_gpt_attach),
+
+ DEVMETHOD_END
+};
+
+static driver_t imx_gpt_driver = {
+ "imx_gpt",
+ imx_gpt_methods,
+ sizeof(struct imx_gpt_softc),
+};
+
+static devclass_t imx_gpt_devclass;
+
+EARLY_DRIVER_MODULE(imx_gpt, simplebus, imx_gpt_driver, imx_gpt_devclass, 0,
+ 0, BUS_PASS_TIMER);
+
+void
+DELAY(int usec)
+{
+ int32_t counts;
+ uint32_t last;
+
+ /*
+ * Check the timers are setup, if not just use a for loop for the
+ * meantime.
+ */
+ if (imx_gpt_delay_count) {
+ for (; usec > 0; usec--)
+ for (counts = imx_gpt_delay_count; counts > 0;
+ counts--)
+ /* Prevent optimizing out the loop */
+ cpufunc_nullop();
+ return;
+ }
+
+ /* At least 1 count */
+ usec = MAX(1, usec / 100);
+
+ last = READ4(imx_gpt_sc, IMX_GPT_CNT) + usec;
+ while (READ4(imx_gpt_sc, IMX_GPT_CNT) < last) {
+ /* Prevent optimizing out the loop */
+ cpufunc_nullop();
+ }
+ /* TODO: use interrupt on OCR2 */
+}
diff --git a/sys/arm/freescale/imx/imx_gptreg.h b/sys/arm/freescale/imx/imx_gptreg.h
new file mode 100644
index 0000000..cdee630
--- /dev/null
+++ b/sys/arm/freescale/imx/imx_gptreg.h
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+/* Registers definition for Freescale i.MX515 Generic Periodic Timer */
+
+#define IMX_GPT_CR 0x0000 /* Control Register R/W */
+#define GPT_CR_FO3 (1 << 31)
+#define GPT_CR_FO2 (1 << 30)
+#define GPT_CR_FO1 (1 << 29)
+#define GPT_CR_OM3_SHIFT 26
+#define GPT_CR_OM3_MASK 0x1c000000
+#define GPT_CR_OM2_SHIFT 23
+#define GPT_CR_OM2_MASK 0x03800000
+#define GPT_CR_OM1_SHIFT 20
+#define GPT_CR_OM1_MASK 0x00700000
+#define GPT_CR_OMX_NONE 0
+#define GPT_CR_OMX_TOGGLE 1
+#define GPT_CR_OMX_CLEAR 2
+#define GPT_CR_OMX_SET 3
+#define GPT_CR_OMX_PULSE 4 /* Run CLKSRC on output pin */
+#define GPT_CR_IM2_SHIFT 18
+#define GPT_CR_IM2_MASK 0x000c0000
+#define GPT_CR_IM1_SHIFT 16
+#define GPT_CR_IM1_MASK 0x00030000
+#define GPT_CR_IMX_NONE 0
+#define GPT_CR_IMX_REDGE 1
+#define GPT_CR_IMX_FEDGE 2
+#define GPT_CR_IMX_BOTH 3
+#define GPT_CR_SWR (1 << 15)
+#define GPT_CR_FRR (1 << 9)
+#define GPT_CR_CLKSRC_NONE 0x00000000
+#define GPT_CR_CLKSRC_IPG 0x00000040
+#define GPT_CR_CLKSRC_IPG_HIGH 0x00000080
+#define GPT_CR_CLKSRC_EXT 0x000000c0
+#define GPT_CR_CLKSRC_32K 0x00000100
+#define GPT_CR_STOPEN (1 << 5)
+#define GPT_CR_WAITEN (1 << 3)
+#define GPT_CR_DBGEN (1 << 2)
+#define GPT_CR_ENMOD (1 << 1)
+#define GPT_CR_EN (1 << 0)
+
+#define IMX_GPT_PR 0x0004 /* Prescaler Register R/W */
+#define GPT_PR_VALUE_SHIFT 0
+#define GPT_PR_VALUE_MASK 0x00000fff
+
+/* Same map for SR and IR */
+#define IMX_GPT_SR 0x0008 /* Status Register R/W */
+#define IMX_GPT_IR 0x000c /* Interrupt Register R/W */
+#define GPT_IR_ROV (1 << 5)
+#define GPT_IR_IF2 (1 << 4)
+#define GPT_IR_IF1 (1 << 3)
+#define GPT_IR_OF3 (1 << 2)
+#define GPT_IR_OF2 (1 << 1)
+#define GPT_IR_OF1 (1 << 0)
+#define GPT_IR_ALL \
+ (GPT_IR_ROV | \
+ GPT_IR_IF2 | \
+ GPT_IR_IF1 | \
+ GPT_IR_OF3 | \
+ GPT_IR_OF2 | \
+ GPT_IR_OF1)
+
+#define IMX_GPT_OCR1 0x0010 /* Output Compare Register 1 R/W */
+#define IMX_GPT_OCR2 0x0014 /* Output Compare Register 2 R/W */
+#define IMX_GPT_OCR3 0x0018 /* Output Compare Register 3 R/W */
+#define IMX_GPT_ICR1 0x001c /* Input capture Register 1 RO */
+#define IMX_GPT_ICR2 0x0020 /* Input capture Register 2 RO */
+#define IMX_GPT_CNT 0x0024 /* Counter Register RO */
diff --git a/sys/arm/freescale/imx/imx_gptvar.h b/sys/arm/freescale/imx/imx_gptvar.h
new file mode 100644
index 0000000..7004e05
--- /dev/null
+++ b/sys/arm/freescale/imx/imx_gptvar.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _IMXGPTVAR_H
+#define _IMXGPTVAR_H
+
+struct imx_gpt_softc {
+ device_t sc_dev;
+ struct resource *res[2];
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ void *sc_ih; /* interrupt handler */
+ uint32_t sc_period;
+ uint32_t sc_clksrc;
+ uint32_t clkfreq;
+ struct eventtimer et;
+};
+
+extern struct imx_gpt_softc *imx_gpt_sc;
+
+int imx_gpt_get_timerfreq(struct imx_gpt_softc *);
+#endif /* _IMXGPTVAR_H */
diff --git a/sys/arm/freescale/imx/imx_machdep.c b/sys/arm/freescale/imx/imx_machdep.c
new file mode 100644
index 0000000..03d0383
--- /dev/null
+++ b/sys/arm/freescale/imx/imx_machdep.c
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c, rev 45
+ */
+
+#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 <sys/reboot.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/frame.h> /* For trapframe_t, used in <machine/machdep.h> */
+#include <machine/machdep.h>
+#include <machine/pmap.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#define IMX51_DEV_VIRT_BASE 0xe0000000
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+ boothowto |= RB_VERBOSE|RB_MULTIPLE;
+ bootverbose = 1;
+
+ if (fdt_immr_addr(IMX51_DEV_VIRT_BASE) != 0)
+ while (1);
+
+ /* Platform-specific initialisation */
+ return (fdt_immr_va - ARM_NOCACHE_KVA_SIZE);
+}
+
+/*
+ * Set initial values of GPIO output ports
+ */
+void
+initarm_gpio_init(void)
+{
+
+}
+
+void
+initarm_late_init(void)
+{
+
+}
+
+#define FDT_DEVMAP_MAX 2
+static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = {
+ { 0, 0, 0, 0, 0, },
+ { 0, 0, 0, 0, 0, }
+};
+
+/*
+ * Construct pmap_devmap[] with DT-derived config data.
+ */
+int
+platform_devmap_init(void)
+{
+
+ /*
+ * Map segment where UART1 and UART2 located.
+ */
+ fdt_devmap[0].pd_va = IMX51_DEV_VIRT_BASE + 0x03f00000;
+ fdt_devmap[0].pd_pa = 0x73f00000;
+ fdt_devmap[0].pd_size = 0x00100000;
+ fdt_devmap[0].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+ fdt_devmap[0].pd_cache = PTE_NOCACHE;
+
+ pmap_devmap_bootstrap_table = &fdt_devmap[0];
+ return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+ return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+ return (0);
+}
+
+void
+cpu_reset(void)
+{
+
+ printf("Reset ...\n");
+ /* Clear n_reset flag */
+ *((volatile u_int16_t *)(IMX51_DEV_VIRT_BASE + 0x03f98000)) =
+ (u_int16_t)0;
+ while (1);
+}
diff --git a/sys/arm/freescale/imx/imx_wdog.c b/sys/arm/freescale/imx/imx_wdog.c
new file mode 100644
index 0000000..c8c9fda
--- /dev/null
+++ b/sys/arm/freescale/imx/imx_wdog.c
@@ -0,0 +1,163 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/watchdog.h>
+
+#include <machine/bus.h>
+#include <machine/intr.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/fdt.h>
+
+#include <arm/freescale/imx/imx_wdogreg.h>
+
+struct imx_wdog_softc {
+ struct mtx sc_mtx;
+ device_t sc_dev;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh;
+ struct resource *sc_res[2];
+ uint32_t sc_timeout;
+};
+
+static struct resource_spec imx_wdog_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static void imx_watchdog(void *, u_int, int *);
+static int imx_wdog_probe(device_t);
+static int imx_wdog_attach(device_t);
+
+static device_method_t imx_wdog_methods[] = {
+ DEVMETHOD(device_probe, imx_wdog_probe),
+ DEVMETHOD(device_attach, imx_wdog_attach),
+ DEVMETHOD_END
+};
+
+static driver_t imx_wdog_driver = {
+ "imx_wdog",
+ imx_wdog_methods,
+ sizeof(struct imx_wdog_softc),
+};
+static devclass_t imx_wdog_devclass;
+DRIVER_MODULE(imx_wdog, simplebus, imx_wdog_driver, imx_wdog_devclass, 0, 0);
+
+
+static void
+imx_watchdog(void *arg, u_int cmd, int *error)
+{
+ struct imx_wdog_softc *sc;
+ uint16_t reg;
+ int timeout;
+
+ sc = arg;
+ mtx_lock(&sc->sc_mtx);
+
+ /* Refresh counter, since we feels good */
+ WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP1);
+ WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP2);
+
+ /* We don't require precession, so "-10" (/1024) is ok */
+ timeout = (1 << ((cmd & WD_INTERVAL) - 10)) / 1000000;
+ if (timeout > 1 && timeout < 128) {
+ if (timeout != sc->sc_timeout) {
+ device_printf(sc->sc_dev,
+ "WARNING: watchdog can't be disabled!!!");
+ sc->sc_timeout = timeout;
+ reg = READ(sc, WDOG_CR_REG);
+ reg &= ~WDOG_CR_WT_MASK;
+ reg |= (timeout << (WDOG_CR_WT_SHIFT + 1)) &
+ WDOG_CR_WT_MASK;
+ WRITE(sc, WDOG_CR_REG, reg);
+ /* Refresh counter */
+ WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP1);
+ WRITE(sc, WDOG_SR_REG, WDOG_SR_STEP2);
+ *error = 0;
+ } else {
+ *error = EOPNOTSUPP;
+ }
+ } else {
+ device_printf(sc->sc_dev, "Can not be disabled.\n");
+ *error = EOPNOTSUPP;
+ }
+ mtx_unlock(&sc->sc_mtx);
+
+}
+
+static int
+imx_wdog_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,imx51-wdt"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale i.MX5xx Watchdog Timer");
+ return (0);
+}
+
+static int
+imx_wdog_attach(device_t dev)
+{
+ struct imx_wdog_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+
+ if (bus_alloc_resources(dev, imx_wdog_spec, sc->sc_res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "imx_wdt", MTX_DEF);
+
+ sc->sc_dev = dev;
+ sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
+ sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
+
+ /* TODO: handle interrupt */
+
+ EVENTHANDLER_REGISTER(watchdog_list, imx_watchdog, sc, 0);
+ return (0);
+}
diff --git a/sys/arm/freescale/imx/imx_wdogreg.h b/sys/arm/freescale/imx/imx_wdogreg.h
new file mode 100644
index 0000000..0decd69
--- /dev/null
+++ b/sys/arm/freescale/imx/imx_wdogreg.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 WDOG_CLK_FREQ 32768
+
+#define WDOG_CR_REG 0x00 /* Control Register */
+#define WDOG_CR_WT_MASK 0xff00 /* Count of 0.5 sec */
+#define WDOG_CR_WT_SHIFT 8
+#define WDOG_CR_WDW (1 << 7) /* Suspend WDog */
+#define WDOG_CR_WDA (1 << 5) /* Don't touch ipp_wdog */
+#define WDOG_CR_SRS (1 << 4) /* Don't touch sys_reset */
+#define WDOG_CR_WDT (1 << 3) /* Assert ipp_wdog on tout */
+#define WDOG_CR_WDE (1 << 2) /* WDog Enable */
+#define WDOG_CR_WDBG (1 << 1) /* Suspend when DBG mode */
+#define WDOG_CR_WDZST (1 << 0) /* Suspend when LP mode */
+
+#define WDOG_SR_REG 0x02 /* Service Register */
+#define WDOG_SR_STEP1 0x5555
+#define WDOG_SR_STEP2 0xaaaa
+
+#define WDOG_RSR_REG 0x04 /* Reset Status Register */
+#define WDOG_RSR_TOUT (1 << 1) /* Due WDog timeout reset */
+#define WDOG_RSR_SFTW (1 << 0) /* Due Soft reset */
+
+#define WDOG_ICR_REG 0x06 /* Interrupt Control Register */
+#define WDOG_ICR_WIE (1 << 15) /* Enable Interrupt */
+#define WDOG_ICR_WTIS (1 << 14) /* Interrupt has occurred */
+#define WDOG_ICR_WTCT_MASK 0x00ff
+#define WDOG_ICR_WTCT_SHIFT 0 /* Interrupt hold time */
+
+#define WDOG_MCR_REG 0x08 /* Miscellaneous Control Register */
+#define WDOG_MCR_PDE (1 << 0)
+
+#define READ(_sc, _r) \
+ bus_space_read_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r))
+#define WRITE(_sc, _r, _v) \
+ bus_space_write_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r), (_v))
diff --git a/sys/arm/freescale/imx/std.imx b/sys/arm/freescale/imx/std.imx
new file mode 100644
index 0000000..60903f6
--- /dev/null
+++ b/sys/arm/freescale/imx/std.imx
@@ -0,0 +1,15 @@
+# $FreeBSD$
+machine arm armv6
+cpu CPU_CORTEXA
+makeoptions ARM_LITTLE_ENDIAN
+options ARM_L2_PIPT
+
+options KERNVIRTADDR=0xc0100000
+makeoptions KERNVIRTADDR=0xc0100000
+options KERNPHYSADDR=0x90100000
+makeoptions KERNPHYSADDR=0x90100000
+options PHYSADDR=0x90000000
+options STARTUP_PAGETABLE_ADDR=0x91000000
+
+files "../freescale/imx/imx.files"
+
diff --git a/sys/arm/freescale/imx/tzic.c b/sys/arm/freescale/imx/tzic.c
new file mode 100644
index 0000000..9b7ecec
--- /dev/null
+++ b/sys/arm/freescale/imx/tzic.c
@@ -0,0 +1,187 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/cpuset.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/bus.h>
+#include <machine/intr.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 <arm/freescale/imx/imx51_tzicreg.h>
+
+struct tzic_softc {
+ struct resource * tzic_res[3];
+ bus_space_tag_t tzic_bst;
+ bus_space_handle_t tzic_bsh;
+ uint8_t ver;
+};
+
+static struct resource_spec tzic_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static struct tzic_softc *tzic_sc = NULL;
+
+#define tzic_read_4(reg) \
+ bus_space_read_4(tzic_sc->tzic_bst, tzic_sc->tzic_bsh, reg)
+#define tzic_write_4(reg, val) \
+ bus_space_write_4(tzic_sc->tzic_bst, tzic_sc->tzic_bsh, reg, val)
+
+static void tzic_post_filter(void *);
+
+static int
+tzic_probe(device_t dev)
+{
+ if (ofw_bus_is_compatible(dev, "fsl,tzic")) {
+ device_set_desc(dev, "TrustZone Interrupt Controller");
+ return (BUS_PROBE_DEFAULT);
+ }
+ return (ENXIO);
+}
+
+static int
+tzic_attach(device_t dev)
+{
+ struct tzic_softc *sc = device_get_softc(dev);
+ int i;
+ uint32_t reg;
+
+ if (tzic_sc)
+ return (ENXIO);
+
+ if (bus_alloc_resources(dev, tzic_spec, sc->tzic_res)) {
+ device_printf(dev, "could not allocate resources\n");
+ return (ENXIO);
+ }
+
+ arm_post_filter = tzic_post_filter;
+
+ /* Distributor Interface */
+ sc->tzic_bst = rman_get_bustag(sc->tzic_res[0]);
+ sc->tzic_bsh = rman_get_bushandle(sc->tzic_res[0]);
+
+ tzic_sc = sc;
+
+ reg = tzic_read_4(TZIC_INTCNTL);
+ tzic_write_4(TZIC_INTCNTL, INTCNTL_NSEN_MASK|INTCNTL_NSEN|INTCNTL_EN);
+ reg = tzic_read_4(TZIC_INTCNTL);
+ tzic_write_4(TZIC_PRIOMASK, 0x1f);
+ reg = tzic_read_4(TZIC_PRIOMASK);
+
+ tzic_write_4(TZIC_SYNCCTRL, 0x02);
+ reg = tzic_read_4(TZIC_SYNCCTRL);
+
+ /* route all interrupts to IRQ. secure interrupts are for FIQ */
+ for (i = 0; i < 4; i++)
+ tzic_write_4(TZIC_INTSEC(i), 0xffffffff);
+
+ /* disable all interrupts */
+ for (i = 0; i < 4; i++)
+ tzic_write_4(TZIC_ENCLEAR(i), 0xffffffff);
+
+ return (0);
+}
+
+static device_method_t tzic_methods[] = {
+ DEVMETHOD(device_probe, tzic_probe),
+ DEVMETHOD(device_attach, tzic_attach),
+ { 0, 0 }
+};
+
+static driver_t tzic_driver = {
+ "tzic",
+ tzic_methods,
+ sizeof(struct tzic_softc),
+};
+
+static devclass_t tzic_devclass;
+
+/*
+ * Memory space of controller located outside of device range, so let him to
+ * attach not only to simplebus, but fdtbus also.
+ */
+EARLY_DRIVER_MODULE(tzic, fdtbus, tzic_driver, tzic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
+EARLY_DRIVER_MODULE(tzic, simplebus, tzic_driver, tzic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT);
+
+static void
+tzic_post_filter(void *arg)
+{
+
+}
+
+int
+arm_get_next_irq(int last_irq)
+{
+ uint32_t pending;
+ int i, b;
+
+ for (i = 0; i < 4; i++) {
+ pending = tzic_read_4(TZIC_PND(i));
+ for (b = 0; b < 32; b++)
+ if (pending & (1 << b)) {
+ return (i * 32 + b);
+ }
+ }
+
+ return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+
+ tzic_write_4(TZIC_ENCLEAR(nb / 32), (1UL <<(nb % 32)));
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+
+ tzic_write_4(TZIC_ENSET(nb / 32), (1UL <<(nb % 32)));
+}
diff --git a/sys/boot/fdt/dts/efikamx.dts b/sys/boot/fdt/dts/efikamx.dts
new file mode 100644
index 0000000..120d1f4
--- /dev/null
+++ b/sys/boot/fdt/dts/efikamx.dts
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ *
+ * Freescale i.MX515 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/dts-v1/;
+/include/ "imx51x.dtsi"
+
+/ {
+ model = "Genesi Efika MX";
+ compatible = "genesi,imx51-efikamx";
+
+ memory {
+ /* RAM 512M */
+ reg = <0x90000000 0x20000000>;
+ };
+
+ localbus@5e000000 {
+ ipu3@5e000000 {
+ status = "okay";
+ };
+ };
+
+ soc@70000000 {
+ aips@70000000 {
+ spba@70000000 {
+ esdhc@70004000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ esdhc@70008000 {
+ clock-frequency = <216000000>;
+ status = "okay";
+ };
+ SSI2: ssi@70014000 {
+ status = "okay";
+ };
+ };
+ timer@73fa0000 {
+ status = "okay";
+ };
+
+ /* UART1, console */
+ UART1: serial@73fbc000 {
+ status = "okay";
+ clock-frequency = <3000000>; /* XXX */
+ };
+
+ clock@73fd4000 {
+ status = "okay";
+ };
+ gpio@73f84000 {
+ status = "okay";
+ };
+ gpio@73f88000 {
+ status = "okay";
+ };
+ gpio@73f8c000 {
+ status = "okay";
+ };
+ gpio@73f90000 {
+ status = "okay";
+ };
+ wdog@73f98000 {
+ status = "okay";
+ };
+ };
+ aips@80000000 {
+ i2c@83fc4000 {
+ status = "okay";
+ };
+ i2c@83fc8000 {
+ status = "okay";
+ };
+ audmux@83fd4000 {
+ status = "okay";
+ };
+ ide@83fe0000 {
+ status = "okay";
+ };
+ };
+ };
+
+ aliases {
+ UART1 = &UART1;
+ SSI2 = &SSI2;
+ };
+
+ chosen {
+ bootargs = "-v";
+ stdin = "UART1";
+ stdout = "UART1";
+ };
+};
diff --git a/sys/boot/fdt/dts/imx51x.dtsi b/sys/boot/fdt/dts/imx51x.dtsi
new file mode 100644
index 0000000..19f281e
--- /dev/null
+++ b/sys/boot/fdt/dts/imx51x.dtsi
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ *
+ * Freescale i.MX515 Device Tree Source.
+ *
+ * $FreeBSD$
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &SOC;
+ };
+
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "ARM,MCIMX515";
+ reg = <0x0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x8000>;
+ i-cache-size = <0x8000>;
+ /* TODO: describe L2 cache also */
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ localbus@e0000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* This reflects CPU decode windows setup. */
+ ranges;
+
+ tzic: tz-interrupt-controller@e0000000 {
+ compatible = "fsl,imx51-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xe0000000 0x00004000>;
+ };
+ /*
+ * 60000000 60000FFF 4K Debug ROM
+ * 60001000 60001FFF 4K ETB
+ * 60002000 60002FFF 4K ETM
+ * 60003000 60003FFF 4K TPIU
+ * 60004000 60004FFF 4K CTI0
+ * 60005000 60005FFF 4K CTI1
+ * 60006000 60006FFF 4K CTI2
+ * 60007000 60007FFF 4K CTI3
+ * 60008000 60008FFF 4K Cortex Debug Unit
+ *
+ * E0000000 E0003FFF 0x4000 TZIC
+ */
+ };
+
+ SOC: soc@70000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges = <0x70000000 0x70000000 0x14000000>;
+
+ aips@70000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* Required by many devices, so better to stay first */
+ /* 73FD4000 0x4000 CCM */
+ clock@73fd4000 {
+ compatible = "fsl,imx51-ccm";
+ /* 83F80000 0x4000 DPLLIP1 */
+ /* 83F84000 0x4000 DPLLIP2 */
+ /* 83F88000 0x4000 DPLLIP3 */
+ reg = <0x73fd4000 0x4000
+ 0x83F80000 0x4000
+ 0x83F84000 0x4000
+ 0x83F88000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <71 72>;
+ status = "disabled";
+ };
+
+ /*
+ * GPIO modules moved up - to have it attached for
+ * drivers which rely on GPIO
+ */
+ /* 73F84000 0x4000 GPIO1 */
+ gpio1: gpio@73f84000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f84000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <50 51 42 43 44 45 46 47 48 49>;
+ /* TODO: use <> also */
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 73F88000 0x4000 GPIO2 */
+ gpio2: gpio@73f88000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f88000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 73F8C000 0x4000 GPIO3 */
+ gpio3: gpio@73f8c000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f8c000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ /* 73F90000 0x4000 GPIO4 */
+ gpio4: gpio@73f90000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f90000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ spba@70000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* 70004000 0x4000 ESDHC 1 */
+ esdhc@70004000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70004000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <1>;
+ status = "disabled";
+ };
+
+ /* 70008000 0x4000 ESDHC 2 */
+ esdhc@70008000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70008000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <2>;
+ status = "disabled";
+ };
+
+ /* 7000C000 0x4000 UART 3 */
+ uart3: serial@7000c000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x7000c000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <33>;
+ status = "disabled";
+ };
+
+ /* 70010000 0x4000 eCSPI1 */
+ ecspi@70010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x70010000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <36>;
+ status = "disabled";
+ };
+
+ /* 70014000 0x4000 SSI2 irq30 */
+ SSI2: ssi@70014000 {
+ compatible = "fsl,imx51-ssi";
+ reg = <0x70014000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <30>;
+ status = "disabled";
+ };
+
+ /* 70020000 0x4000 ESDHC 3 */
+ esdhc@70020000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70020000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <3>;
+ status = "disabled";
+ };
+
+ /* 70024000 0x4000 ESDHC 4 */
+ esdhc@70024000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70024000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <4>;
+ status = "disabled";
+ };
+
+ /* 70028000 0x4000 SPDIF */
+ /* 91 SPDIF */
+
+ /* 70030000 0x4000 PATA (PORT UDMA) irq70 */
+
+ /* 70034000 0x4000 SLM */
+ /* 70038000 0x4000 HSI2C */ /* 64 HS-I2C */
+ /* 7003C000 0x4000 SPBA */
+ };
+
+ /* 73F80000 0x4000 USBOH3 */
+ /* irq14 USBOH3 USB Host 1 */
+ /* irq16 USBOH3 USB Host 2 */
+ /* irq17 USBOH3 USB Host 3 */
+ /* irq18 USBOH3 USB OTG */
+ usb1: usb@73F80000 {
+ compatible = "fsl,usb-4core";
+ reg = <0x73f80000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <18 14 16 17>;
+ };
+
+ /* 73F98000 0x4000 WDOG1 */
+ wdog@73f98000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f98000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <58>;
+ status = "disabled";
+ };
+
+ /* 73F9C000 0x4000 WDOG2 (TZ) */
+ wdog@73f9c000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f9c000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <59>;
+ status = "disabled";
+ };
+
+ /* 73F94000 0x4000 KPP */
+ keyboard@73f94000 {
+ compatible = "fsl,imx51-kpp";
+ reg = <0x73f94000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <60>;
+ status = "disabled";
+ };
+
+ /* 73FA0000 0x4000 GPT */
+ timer@73fa0000 {
+ compatible = "fsl,imx51-gpt";
+ reg = <0x73fa0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <39>;
+ status = "disabled";
+ };
+
+ /* 73FA4000 0x4000 SRTC */
+
+ rtc@73fa4000 {
+ compatible = "fsl,imx51-srtc";
+ reg = <0x73fa4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <24 25>;
+ status = "disabled";
+ };
+
+ /* 73FA8000 0x4000 IOMUXC */
+ iomux@73fa8000 {
+ compatible = "fsl,imx51-iomux";
+ reg = <0x73fa8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <7>;
+ };
+
+ /* 73FAC000 0x4000 EPIT1 */
+ epit1: timer@73fac000 {
+ compatible = "fsl,imx51-epit";
+ reg = <0x73fac000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <40>;
+ status = "disabled";
+ };
+
+ /* 73FB0000 0x4000 EPIT2 */
+ epit2: timer@73fb0000 {
+ compatible = "fsl,imx51-epit";
+ reg = <0x73fb0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <41>;
+ status = "disabled";
+ };
+
+ /* 73FB4000 0x4000 PWM1 */
+ pwm@73fb4000 {
+ compatible = "fsl,imx51-pwm";
+ reg = <0x73fb4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <61>;
+ status = "disabled";
+ };
+
+ /* 73FB8000 0x4000 PWM2 */
+ pwm@73fb8000 {
+ compatible = "fsl,imx51-pwm";
+ reg = <0x73fb8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <94>;
+ status = "disabled";
+ };
+
+ /* 73FBC000 0x4000 UART 1 */
+ uart1: serial@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <31>;
+ status = "disabled";
+ };
+
+ /* 73FC0000 0x4000 UART 2 */
+ uart2: serial@73fc0000 {
+ compatible = "fsl,imx51-uart", "fsl,imx-uart";
+ reg = <0x73fc0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <32>;
+ status = "disabled";
+ };
+
+ /* 73FC4000 0x4000 USBOH3 */
+ /* NOTYET
+ usb@73fc4000 {
+ compatible = "fsl,imx51-otg";
+ reg = <0x73fc4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <>;
+ status = "disabled";
+ };
+ */
+ /* 73FD0000 0x4000 SRC */
+ reset@73fd0000 {
+ compatible = "fsl,imx51-src";
+ reg = <0x73fd0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <75>;
+ status = "disabled";
+ };
+ /* 73FD8000 0x4000 GPC */
+ power@73fd8000 {
+ compatible = "fsl,imx51-gpc";
+ reg = <0x73fd8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <73 74>;
+ status = "disabled";
+ };
+
+ };
+
+ aips@80000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ /* 83F94000 0x4000 AHBMAX */
+ /* 83F98000 0x4000 IIM */
+ /*
+ * 69 IIM Interrupt request to the processor.
+ * Indicates to the processor that program or
+ * explicit.
+ */
+ /* 83F9C000 0x4000 CSU */
+ /*
+ * 27 CSU Interrupt Request 1. Indicates to the
+ * processor that one or more alarm inputs were.
+ */
+
+ /* 83FA0000 0x4000 TIGERP_PLATFORM_NE_32K_256K */
+ /* irq76 Neon Monitor Interrupt */
+ /* irq77 Performance Unit Interrupt */
+ /* irq78 CTI IRQ */
+ /* irq79 Debug Interrupt, Cross-Trigger Interface 1 */
+ /* irq80 Debug Interrupt, Cross-Trigger Interface 1 */
+ /* irq89 Debug Interrupt, Cross-Trigger Interface 2 */
+ /* irq98 Debug Interrupt, Cross-Trigger Interface 3 */
+
+ /* 83FA4000 0x4000 OWIRE irq88 */
+ /* 83FA8000 0x4000 FIRI irq93 */
+ /* 83FAC000 0x4000 eCSPI2 */
+ ecspi@83fac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x83fac000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <37>;
+ status = "disabled";
+ };
+
+ /* 83FB0000 0x4000 SDMA */
+ sdma@83fb0000 {
+ compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
+ reg = <0x83fb0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <6>;
+ };
+
+ /* 83FB4000 0x4000 SCC */
+ /* 21 SCC Security Monitor High Priority Interrupt. */
+ /* 22 SCC Secure (TrustZone) Interrupt. */
+ /* 23 SCC Regular (Non-Secure) Interrupt. */
+
+ /* 83FB8000 0x4000 ROMCP */
+ /* 83FBC000 0x4000 RTIC */
+ /*
+ * 26 RTIC RTIC (Trust Zone) Interrupt Request.
+ * Indicates that the RTIC has completed hashing the
+ */
+
+ /* 83FC0000 0x4000 CSPI */
+ cspi@83fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
+ reg = <0x83fc0000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <38>;
+ status = "disabled";
+ };
+
+ /* 83FC4000 0x4000 I2C2 */
+ i2c@83fc4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx1-i2c", "fsl,imx-i2c";
+ reg = <0x83fc4000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <63>;
+ status = "disabled";
+ };
+
+ /* 83FC8000 0x4000 I2C1 */
+ i2c@83fc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx1-i2c", "fsl,imx-i2c";
+ reg = <0x83fc8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <62>;
+ status = "disabled";
+ };
+
+ /* 83FCC000 0x4000 SSI1 */
+ /* 29 SSI1 SSI-1 Interrupt Request */
+ SSI1: ssi@83fcc000 {
+ compatible = "fsl,imx51-ssi";
+ reg = <0x83fcc000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <29>;
+ status = "disabled";
+ };
+
+ /* 83FD0000 0x4000 AUDMUX */
+ audmux@83fd4000 {
+ compatible = "fsl,imx51-audmux";
+ reg = <0x83fd4000 0x4000>;
+ status = "disabled";
+ };
+
+ /* 83FD8000 0x4000 EMI1 */
+ /* 8 EMI (NFC) */
+ /* 15 EMI */
+ /* 97 EMI Boot sequence completed interrupt */
+ /*
+ * 101 EMI Indicates all pages have been transferred
+ * to NFC during an auto program operation.
+ */
+
+ /* 83FE0000 0x4000 PATA (PORT PIO) */
+ /* 70 PATA Parallel ATA host controller interrupt */
+ ide@83fe0000 {
+ compatible = "fsl,imx51-ata";
+ reg = <0x83fe0000 0x4000>;
+ interrupt-parent = <&tzic>;
+ interrupts = <70>;
+ status = "disabled";
+ };
+
+ /* 83FE4000 0x4000 SIM */
+ /* 67 SIM intr composed of oef, xte, sdi1, and sdi0 */
+ /* 68 SIM intr composed of tc, etc, tfe, and rdrf */
+
+ /* 83FE8000 0x4000 SSI3 */
+ /* 96 SSI3 SSI-3 Interrupt Request */
+ SSI3: ssi@83fe8000 {
+ compatible = "fsl,imx51-ssi";
+ reg = <0x83fe8000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <96>;
+ status = "disabled";
+ };
+
+ /* 83FEC000 0x4000 FEC */
+ ethernet@83fec000 {
+ compatible = "fsl,imx51-fec";
+ reg = <0x83fec000 0x4000>;
+ interrupt-parent = <&tzic>; interrupts = <87>;
+ status = "disabled";
+ };
+
+ /* 83FF0000 0x4000 TVE */
+ /* 92 TVE */
+ /* 83FF4000 0x4000 VPU */
+ /* 9 VPU */
+ /* 100 VPU Idle interrupt from VPU */
+
+ /* 83FF8000 0x4000 SAHARA Lite */
+ /* 19 SAHARA SAHARA host 0 (TrustZone) Intr Lite */
+ /* 20 SAHARA SAHARA host 1 (non-TrustZone) Intr Lite */
+ };
+ };
+
+ localbus@5e000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges;
+
+ vga: ipu3@5e000000 {
+ compatible = "fsl,ipu3";
+ reg = <
+ 0x5e000000 0x08000 /* CM */
+ 0x5e008000 0x08000 /* IDMAC */
+ 0x5e018000 0x08000 /* DP */
+ 0x5e020000 0x08000 /* IC */
+ 0x5e028000 0x08000 /* IRT */
+ 0x5e030000 0x08000 /* CSI0 */
+ 0x5e038000 0x08000 /* CSI1 */
+ 0x5e040000 0x08000 /* DI0 */
+ 0x5e048000 0x08000 /* DI1 */
+ 0x5e050000 0x08000 /* SMFC */
+ 0x5e058000 0x08000 /* DC */
+ 0x5e060000 0x08000 /* DMFC */
+ 0x5e068000 0x08000 /* VDI */
+ 0x5f000000 0x20000 /* CPMEM */
+ 0x5f020000 0x20000 /* LUT */
+ 0x5f040000 0x20000 /* SRM */
+ 0x5f060000 0x20000 /* TPM */
+ 0x5f080000 0x20000 /* DCTMPL */
+ >;
+ interrupt-parent = <&tzic>;
+ interrupts = <
+ 10 /* IPUEX Error */
+ 11 /* IPUEX Sync */
+ >;
+ status = "disabled";
+ };
+ };
+};
+
+/*
+
+TODO: Not mapped interrupts
+
+5 DAP
+84 GPU2D (OpenVG) general interrupt
+85 GPU2D (OpenVG) busy signal (for S/W power gating feasibility)
+12 GPU3D
+102 GPU3D Idle interrupt from GPU3D (for S/W power gating)
+90 SJC
+*/
diff --git a/sys/dev/ata/chipsets/ata-fsl.c b/sys/dev/ata/chipsets/ata-fsl.c
new file mode 100644
index 0000000..5e5a686
--- /dev/null
+++ b/sys/dev/ata/chipsets/ata-fsl.c
@@ -0,0 +1,238 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 "opt_ata.h"
+#include <sys/param.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/ata.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sema.h>
+#include <sys/taskqueue.h>
+#include <vm/uma.h>
+#include <machine/stdarg.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/ata/ata-all.h>
+#include <dev/ata/ata-pci.h>
+#include <ata_if.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/fdt.h>
+
+/* local prototypes */
+static int imx_ata_ch_attach(device_t dev);
+static int imx_ata_setmode(device_t dev, int target, int mode);
+
+static int
+imx_ata_probe(device_t dev)
+{
+ struct ata_pci_controller *ctrl;
+
+ if (!ofw_bus_is_compatible(dev, "fsl,imx51-ata"))
+ return (ENXIO);
+
+ ctrl = device_get_softc(dev);
+
+ device_set_desc(dev, "Freescale Integrated PATA Controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static void
+imx_ata_intr(void *data)
+{
+ struct ata_pci_controller *ctrl = data;
+
+ bus_write_2(ctrl->r_res1, 0x28, bus_read_2(ctrl->r_res1, 0x28));
+ ctrl->interrupt[0].function(ctrl->interrupt[0].argument);
+}
+
+static int
+imx_ata_attach(device_t dev)
+{
+ struct ata_pci_controller *ctrl;
+ device_t child;
+ int unit;
+
+ ctrl = device_get_softc(dev);
+ /* do chipset specific setups only needed once */
+ ctrl->legacy = ata_legacy(dev);
+ ctrl->channels = 1;
+ ctrl->ichannels = -1;
+ ctrl->ch_attach = ata_pci_ch_attach;
+ ctrl->ch_detach = ata_pci_ch_detach;
+ ctrl->dev = dev;
+
+ ctrl->r_type1 = SYS_RES_MEMORY;
+ ctrl->r_rid1 = 0;
+ ctrl->r_res1 = bus_alloc_resource_any(dev, ctrl->r_type1,
+ &ctrl->r_rid1, RF_ACTIVE);
+
+ if (ata_setup_interrupt(dev, imx_ata_intr)) {
+ device_printf(dev, "failed to setup interrupt\n");
+ return ENXIO;
+ }
+
+ ctrl->channels = 1;
+
+ ctrl->ch_attach = imx_ata_ch_attach;
+ ctrl->setmode = imx_ata_setmode;
+
+ /* attach all channels on this controller */
+ unit = 0;
+ child = device_add_child(dev, "ata", ((unit == 0) && ctrl->legacy) ?
+ unit : devclass_find_free_unit(ata_devclass, 2));
+ if (child == NULL)
+ device_printf(dev, "failed to add ata child device\n");
+ else
+ device_set_ivars(child, (void *)(intptr_t)unit);
+
+ bus_generic_attach(dev);
+ return 0;
+}
+
+static int
+imx_ata_ch_attach(device_t dev)
+{
+ struct ata_pci_controller *ctrl;
+ struct ata_channel *ch;
+ int i;
+
+ ctrl = device_get_softc(device_get_parent(dev));
+ ch = device_get_softc(dev);
+ for (i = ATA_DATA; i < ATA_MAX_RES; i++)
+ ch->r_io[i].res = ctrl->r_res1;
+
+ bus_write_2(ctrl->r_res1, 0x24, 0x80);
+ DELAY(100);
+ bus_write_2(ctrl->r_res1, 0x24, 0xc0);
+ DELAY(100);
+
+
+ /* Write TIME_OFF/ON/1/2W */
+ bus_write_1(ctrl->r_res1, 0x00, 3);
+ bus_write_1(ctrl->r_res1, 0x01, 3);
+ bus_write_1(ctrl->r_res1, 0x02, (25 + 15) / 15);
+ bus_write_1(ctrl->r_res1, 0x03, (70 + 15) / 15);
+
+ /* Write TIME_2R/AX/RDX/4 */
+ bus_write_1(ctrl->r_res1, 0x04, (70 + 15) / 15);
+ bus_write_1(ctrl->r_res1, 0x05, (50 + 15) / 15 + 2);
+ bus_write_1(ctrl->r_res1, 0x06, 1);
+ bus_write_1(ctrl->r_res1, 0x07, (10 + 15) / 15);
+
+ /* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */
+ bus_write_1(ctrl->r_res1, 0x08, (10 + 15) / 15);
+
+ bus_write_2(ctrl->r_res1, 0x24, 0xc1);
+ DELAY(30000);
+
+ /* setup ATA registers */
+ ch->r_io[ATA_DATA ].offset = 0xa0;
+ ch->r_io[ATA_FEATURE].offset = 0xa4;
+ ch->r_io[ATA_ERROR ].offset = 0xa4;
+ ch->r_io[ATA_COUNT ].offset = 0xa8;
+ ch->r_io[ATA_SECTOR ].offset = 0xac;
+ ch->r_io[ATA_CYL_LSB].offset = 0xb0;
+ ch->r_io[ATA_CYL_MSB].offset = 0xb4;
+ ch->r_io[ATA_DRIVE ].offset = 0xb8;
+ ch->r_io[ATA_COMMAND].offset = 0xbc;
+
+ ch->r_io[ATA_STATUS ].offset = 0xbc;
+ ch->r_io[ATA_ALTSTAT].offset = 0xd8;
+ ch->r_io[ATA_CONTROL].offset = 0xd8;
+
+ ata_pci_hw(dev);
+
+ ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_USE_16BIT;
+ ch->flags |= ATA_CHECKS_CABLE;
+ ch->flags |= ATA_KNOWN_PRESENCE;
+
+ /* Clear pending interrupts. */
+ bus_write_2(ctrl->r_res1, 0x28, 0xf8);
+ /* Enable all, but Idle interrupts. */
+ bus_write_2(ctrl->r_res1, 0x2c, 0x88);
+
+ return 0;
+}
+
+static int
+imx_ata_setmode(device_t dev, int target, int mode)
+{
+
+ return (min(mode, ATA_PIO4));
+}
+
+static device_method_t imx_ata_methods[] = {
+ DEVMETHOD(device_probe, imx_ata_probe),
+ DEVMETHOD(device_attach, imx_ata_attach),
+ DEVMETHOD(device_detach, ata_pci_detach),
+ DEVMETHOD(device_suspend, ata_pci_suspend),
+ DEVMETHOD(device_resume, ata_pci_resume),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(bus_read_ivar, ata_pci_read_ivar),
+ DEVMETHOD(bus_write_ivar, ata_pci_write_ivar),
+ DEVMETHOD(bus_alloc_resource, ata_pci_alloc_resource),
+ DEVMETHOD(bus_release_resource, ata_pci_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, ata_pci_setup_intr),
+ DEVMETHOD(bus_teardown_intr, ata_pci_teardown_intr),
+ DEVMETHOD(pci_read_config, ata_pci_read_config),
+ DEVMETHOD(pci_write_config, ata_pci_write_config),
+ DEVMETHOD(bus_print_child, ata_pci_print_child),
+ DEVMETHOD(bus_child_location_str, ata_pci_child_location_str),
+ DEVMETHOD_END
+};
+static driver_t imx_ata_driver = {
+ "atapci",
+ imx_ata_methods,
+ sizeof(struct ata_pci_controller)
+};
+DRIVER_MODULE(imx_ata, simplebus, imx_ata_driver, ata_pci_devclass, NULL,
+ NULL);
+MODULE_VERSION(imx_ata, 1);
+MODULE_DEPEND(imx_ata, ata, 1, 1, 1);
+MODULE_DEPEND(imx_ata, atapci, 1, 1, 1);
diff --git a/sys/dev/uart/uart.h b/sys/dev/uart/uart.h
index 7647188..5229747 100644
--- a/sys/dev/uart/uart.h
+++ b/sys/dev/uart/uart.h
@@ -64,6 +64,7 @@ struct uart_bas {
*/
struct uart_class;
+extern struct uart_class uart_imx_class __attribute__((weak));
extern struct uart_class uart_ns8250_class __attribute__((weak));
extern struct uart_class uart_quicc_class __attribute__((weak));
extern struct uart_class uart_sab82532_class __attribute__((weak));
diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c
index b55329e..cd4f71c 100644
--- a/sys/dev/uart/uart_bus_fdt.c
+++ b/sys/dev/uart/uart_bus_fdt.c
@@ -105,6 +105,8 @@ uart_fdt_probe(device_t dev)
sc->sc_class = &uart_ns8250_class;
else if (ofw_bus_is_compatible(dev, "lpc,uart"))
sc->sc_class = &uart_lpc_class;
+ else if (ofw_bus_is_compatible(dev, "fsl,imx-uart"))
+ sc->sc_class = &uart_imx_class;
else if (ofw_bus_is_compatible(dev, "arm,pl011"))
sc->sc_class = &uart_pl011_class;
else
@@ -184,6 +186,8 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
/*
* Finalize configuration.
*/
+ if (fdt_is_compatible(node, "fsl,imx-uart"))
+ class = &uart_imx_class;
if (fdt_is_compatible(node, "quicc"))
class = &uart_quicc_class;
if (fdt_is_compatible(node, "lpc"))
diff --git a/sys/dev/uart/uart_dev_imx.c b/sys/dev/uart/uart_dev_imx.c
new file mode 100644
index 0000000..81fe163
--- /dev/null
+++ b/sys/dev/uart/uart_dev_imx.c
@@ -0,0 +1,436 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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 "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 <dev/uart/uart_dev_imx5xx.h>
+
+#include "uart_if.h"
+/*
+ * Low-level UART interface.
+ */
+static int imx_uart_probe(struct uart_bas *bas);
+static void imx_uart_init(struct uart_bas *bas, int, int, int, int);
+static void imx_uart_term(struct uart_bas *bas);
+static void imx_uart_putc(struct uart_bas *bas, int);
+static int imx_uart_rxready(struct uart_bas *bas);
+static int imx_uart_getc(struct uart_bas *bas, struct mtx *);
+
+static struct uart_ops uart_imx_uart_ops = {
+ .probe = imx_uart_probe,
+ .init = imx_uart_init,
+ .term = imx_uart_term,
+ .putc = imx_uart_putc,
+ .rxready = imx_uart_rxready,
+ .getc = imx_uart_getc,
+};
+
+static int
+imx_uart_probe(struct uart_bas *bas)
+{
+
+ return (0);
+}
+
+static void
+imx_uart_init(struct uart_bas *bas, int baudrate, int databits,
+ int stopbits, int parity)
+{
+
+}
+
+static void
+imx_uart_term(struct uart_bas *bas)
+{
+
+}
+
+static void
+imx_uart_putc(struct uart_bas *bas, int c)
+{
+
+ while (!(IS(bas, USR2, TXFE)))
+ ;
+ SETREG(bas, REG(UTXD), c);
+}
+
+static int
+imx_uart_rxready(struct uart_bas *bas)
+{
+
+ return ((IS(bas, USR2, RDR)) ? 1 : 0);
+}
+
+static int
+imx_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+ int c;
+
+ uart_lock(hwmtx);
+ while (!(IS(bas, USR2, RDR)))
+ ;
+
+ c = GETREG(bas, REG(URXD));
+ uart_unlock(hwmtx);
+#if defined(KDB)
+ if (c & FLD(URXD, BRK)) {
+ if (kdb_break())
+ return (0);
+ }
+#endif
+ return (c & 0xff);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct imx_uart_softc {
+ struct uart_softc base;
+};
+
+static int imx_uart_bus_attach(struct uart_softc *);
+static int imx_uart_bus_detach(struct uart_softc *);
+static int imx_uart_bus_flush(struct uart_softc *, int);
+static int imx_uart_bus_getsig(struct uart_softc *);
+static int imx_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int imx_uart_bus_ipend(struct uart_softc *);
+static int imx_uart_bus_param(struct uart_softc *, int, int, int, int);
+static int imx_uart_bus_probe(struct uart_softc *);
+static int imx_uart_bus_receive(struct uart_softc *);
+static int imx_uart_bus_setsig(struct uart_softc *, int);
+static int imx_uart_bus_transmit(struct uart_softc *);
+
+static kobj_method_t imx_uart_methods[] = {
+ KOBJMETHOD(uart_attach, imx_uart_bus_attach),
+ KOBJMETHOD(uart_detach, imx_uart_bus_detach),
+ KOBJMETHOD(uart_flush, imx_uart_bus_flush),
+ KOBJMETHOD(uart_getsig, imx_uart_bus_getsig),
+ KOBJMETHOD(uart_ioctl, imx_uart_bus_ioctl),
+ KOBJMETHOD(uart_ipend, imx_uart_bus_ipend),
+ KOBJMETHOD(uart_param, imx_uart_bus_param),
+ KOBJMETHOD(uart_probe, imx_uart_bus_probe),
+ KOBJMETHOD(uart_receive, imx_uart_bus_receive),
+ KOBJMETHOD(uart_setsig, imx_uart_bus_setsig),
+ KOBJMETHOD(uart_transmit, imx_uart_bus_transmit),
+ { 0, 0 }
+};
+
+struct uart_class uart_imx_class = {
+ "imx",
+ imx_uart_methods,
+ sizeof(struct imx_uart_softc),
+ .uc_ops = &uart_imx_uart_ops,
+ .uc_range = 0x100,
+ .uc_rclk = 24000000 /* TODO: get value from CCM */
+};
+
+#define SIGCHG(c, i, s, d) \
+ if (c) { \
+ i |= (i & s) ? s : s | d; \
+ } else { \
+ i = (i & s) ? (i & ~s) | d : i; \
+ }
+
+static int
+imx_uart_bus_attach(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ struct uart_devinfo *di;
+
+ bas = &sc->sc_bas;
+ if (sc->sc_sysdev != NULL) {
+ di = sc->sc_sysdev;
+ imx_uart_init(bas, di->baudrate, di->databits, di->stopbits,
+ di->parity);
+ } else {
+ imx_uart_init(bas, 115200, 8, 1, 0);
+ }
+
+ sc->sc_rxfifosz = 1;
+ sc->sc_txfifosz = 1;
+
+ (void)imx_uart_bus_getsig(sc);
+
+ /* XXX workaround to have working console on manut prompt */
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE){
+ DIS(bas, UCR4, DREN);
+ } else {
+ ENA(bas, UCR4, DREN);
+ }
+ DIS(bas, UCR1, RRDYEN);
+ DIS(bas, UCR1, IDEN);
+ DIS(bas, UCR3, RXDSEN);
+ DIS(bas, UCR2, ATEN);
+ DIS(bas, UCR1, TXMPTYEN);
+ DIS(bas, UCR1, TRDYEN);
+ DIS(bas, UCR4, TCEN);
+ DIS(bas, UCR4, OREN);
+ ENA(bas, UCR4, BKEN);
+ DIS(bas, UCR4, WKEN);
+ DIS(bas, UCR1, ADEN);
+ DIS(bas, UCR3, ACIEN);
+ DIS(bas, UCR2, ESCI);
+ DIS(bas, UCR4, ENIRI);
+ DIS(bas, UCR3, AIRINTEN);
+ DIS(bas, UCR3, AWAKEN);
+ DIS(bas, UCR3, FRAERREN);
+ DIS(bas, UCR3, PARERREN);
+ DIS(bas, UCR1, RTSDEN);
+ DIS(bas, UCR2, RTSEN);
+ DIS(bas, UCR3, DTREN);
+ DIS(bas, UCR3, RI);
+ DIS(bas, UCR3, DCD);
+ DIS(bas, UCR3, DTRDEN);
+
+ /* ACK all interrupts */
+ SETREG(bas, REG(USR1), 0xffff);
+ SETREG(bas, REG(USR2), 0xffff);
+ return (0);
+}
+
+static int
+imx_uart_bus_detach(struct uart_softc *sc)
+{
+
+ SETREG(&sc->sc_bas, REG(UCR4), 0);
+
+ return (0);
+}
+
+static int
+imx_uart_bus_flush(struct uart_softc *sc, int what)
+{
+
+ /* TODO */
+ return (0);
+}
+
+static int
+imx_uart_bus_getsig(struct uart_softc *sc)
+{
+ uint32_t new, old, sig;
+ uint8_t bes;
+
+ do {
+ old = sc->sc_hwsig;
+ sig = old;
+ uart_lock(sc->sc_hwmtx);
+ bes = GETREG(&sc->sc_bas, REG(USR2));
+ uart_unlock(sc->sc_hwmtx);
+ /* XXX: chip can show delta */
+ SIGCHG(bes & FLD(USR2, DCDIN), sig, SER_DCD, SER_DDCD);
+ new = sig & ~SER_MASK_DELTA;
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+
+ return (sig);
+}
+
+static int
+imx_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
+imx_uart_bus_ipend(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ int ipend;
+ uint32_t usr1, usr2;
+ uint32_t ucr1, ucr4;
+
+ bas = &sc->sc_bas;
+ ipend = 0;
+
+ uart_lock(sc->sc_hwmtx);
+
+ /* Read pending interrupts */
+ usr1 = GETREG(bas, REG(USR1));
+ usr2 = GETREG(bas, REG(USR2));
+ /* ACK interrupts */
+ SETREG(bas, REG(USR1), usr1);
+ SETREG(bas, REG(USR2), usr2);
+
+ ucr1 = GETREG(bas, REG(UCR1));
+ ucr4 = GETREG(bas, REG(UCR4));
+
+ if ((usr2 & FLD(USR2, TXFE)) && (ucr1 & FLD(UCR1, TXMPTYEN))) {
+ DIS(bas, UCR1, TXMPTYEN);
+ /* Continue TXing */
+ ipend |= SER_INT_TXIDLE;
+ }
+ if ((usr2 & FLD(USR2, RDR)) && (ucr4 & FLD(UCR4, DREN))) {
+ DIS(bas, UCR4, DREN);
+ /* Wow, new char on input */
+ ipend |= SER_INT_RXREADY;
+ }
+ if ((usr2 & FLD(USR2, BRCD)) && (ucr4 & FLD(UCR4, BKEN)))
+ ipend |= SER_INT_BREAK;
+
+ uart_unlock(sc->sc_hwmtx);
+
+ return (ipend);
+}
+
+static int
+imx_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
+ int stopbits, int parity)
+{
+
+ uart_lock(sc->sc_hwmtx);
+ imx_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity);
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+}
+
+static int
+imx_uart_bus_probe(struct uart_softc *sc)
+{
+ int error;
+
+ error = imx_uart_probe(&sc->sc_bas);
+ if (error)
+ return (error);
+
+ device_set_desc(sc->sc_dev, "imx_uart");
+ return (0);
+}
+
+static int
+imx_uart_bus_receive(struct uart_softc *sc)
+{
+ struct uart_bas *bas;
+ int xc, out;
+
+ bas = &sc->sc_bas;
+ uart_lock(sc->sc_hwmtx);
+
+ /* Read while we have anything in FIFO */
+ while (IS(bas, USR2, RDR)) {
+ if (uart_rx_full(sc)) {
+ /* No space left in input buffer */
+ sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+ break;
+ }
+ out = 0;
+ xc = GETREG(bas, REG(URXD));
+
+ /* We have valid char */
+ if (xc & FLD(URXD, CHARRDY))
+ out = xc & 0x000000ff;
+
+ if (xc & FLD(URXD, FRMERR))
+ out |= UART_STAT_FRAMERR;
+ if (xc & FLD(URXD, PRERR))
+ out |= UART_STAT_PARERR;
+ if (xc & FLD(URXD, OVRRUN))
+ out |= UART_STAT_OVERRUN;
+ if (xc & FLD(URXD, BRK))
+ out |= UART_STAT_BREAK;
+
+ uart_rx_put(sc, out);
+ }
+ /* Reenable Data Ready interrupt */
+ ENA(bas, UCR4, DREN);
+
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+}
+
+static int
+imx_uart_bus_setsig(struct uart_softc *sc, int sig)
+{
+
+ /* TODO: implement (?) */
+
+ /* XXX workaround to have working console on mount prompt */
+ /* Enable RX interrupt */
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE)
+ if (!IS(&sc->sc_bas, UCR4, DREN))
+ ENA(&sc->sc_bas, UCR4, DREN);
+ return (0);
+}
+
+static int
+imx_uart_bus_transmit(struct uart_softc *sc)
+{
+ struct uart_bas *bas = &sc->sc_bas;
+ int i;
+
+ bas = &sc->sc_bas;
+ uart_lock(sc->sc_hwmtx);
+
+ /* Fill TX FIFO */
+ for (i = 0; i < sc->sc_txdatasz; i++) {
+ SETREG(bas, REG(UTXD), sc->sc_txbuf[i] & 0xff);
+ }
+
+ sc->sc_txbusy = 1;
+ /* Call me when ready */
+ ENA(bas, UCR1, TXMPTYEN);
+
+ uart_unlock(sc->sc_hwmtx);
+
+ return (0);
+}
diff --git a/sys/dev/uart/uart_dev_imx5xx.h b/sys/dev/uart/uart_dev_imx5xx.h
new file mode 100644
index 0000000..ac24a3f
--- /dev/null
+++ b/sys/dev/uart/uart_dev_imx5xx.h
@@ -0,0 +1,222 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _UART_DEV_IMX5XX_H
+#define _UART_DEV_IMX5XX_H
+
+#define IMXUART_URXD_REG 0x0000 /* UART Receiver Register */
+#define IMXUART_URXD_CHARRDY (1 << 15)
+#define IMXUART_URXD_ERR (1 << 14)
+#define IMXUART_URXD_OVRRUN (1 << 13)
+#define IMXUART_URXD_FRMERR (1 << 12)
+#define IMXUART_URXD_BRK (1 << 11)
+#define IMXUART_URXD_PRERR (1 << 10)
+#define IMXUART_URXD_RX_DATA_MASK 0xff
+
+#define IMXUART_UTXD_REG 0x0040 /* UART Transmitter Register */
+#define IMXUART_UTXD_TX_DATA_MASK 0xff
+
+#define IMXUART_UCR1_REG 0x0080 /* UART Control Register 1 */
+#define IMXUART_UCR1_ADEN (1 << 15)
+#define IMXUART_UCR1_ADBR (1 << 14)
+#define IMXUART_UCR1_TRDYEN (1 << 13)
+#define IMXUART_UCR1_IDEN (1 << 12)
+#define IMXUART_UCR1_ICD_MASK (3 << 10)
+#define IMXUART_UCR1_ICD_IDLE4 (0 << 10)
+#define IMXUART_UCR1_ICD_IDLE8 (1 << 10)
+#define IMXUART_UCR1_ICD_IDLE16 (2 << 10)
+#define IMXUART_UCR1_ICD_IDLE32 (3 << 10)
+#define IMXUART_UCR1_RRDYEN (1 << 9)
+#define IMXUART_UCR1_RXDMAEN (1 << 8)
+#define IMXUART_UCR1_IREN (1 << 7)
+#define IMXUART_UCR1_TXMPTYEN (1 << 6)
+#define IMXUART_UCR1_RTSDEN (1 << 5)
+#define IMXUART_UCR1_SNDBRK (1 << 4)
+#define IMXUART_UCR1_TXDMAEN (1 << 3)
+#define IMXUART_UCR1_ATDMAEN (1 << 2)
+#define IMXUART_UCR1_DOZE (1 << 1)
+#define IMXUART_UCR1_UARTEN (1 << 0)
+
+#define IMXUART_UCR2_REG 0x0084 /* UART Control Register 2 */
+#define IMXUART_UCR2_ESCI (1 << 15)
+#define IMXUART_UCR2_IRTS (1 << 14)
+#define IMXUART_UCR2_CTSC (1 << 13)
+#define IMXUART_UCR2_CTS (1 << 12)
+#define IMXUART_UCR2_ESCEN (1 << 11)
+#define IMXUART_UCR2_RTEC_MASK (3 << 9)
+#define IMXUART_UCR2_RTEC_REDGE (0 << 9)
+#define IMXUART_UCR2_RTEC_FEDGE (1 << 9)
+#define IMXUART_UCR2_RTEC_EDGE (2 << 9)
+#define IMXUART_UCR2_PREN (1 << 8)
+#define IMXUART_UCR2_PROE (1 << 7)
+#define IMXUART_UCR2_STPB (1 << 6)
+#define IMXUART_UCR2_WS (1 << 5)
+#define IMXUART_UCR2_RTSEN (1 << 4)
+#define IMXUART_UCR2_ATEN (1 << 3)
+#define IMXUART_UCR2_TXEN (1 << 2)
+#define IMXUART_UCR2_RXEN (1 << 1)
+#define IMXUART_UCR2_N_SRST (1 << 0)
+
+#define IMXUART_UCR3_REG 0x0088 /* UART Control Register 3 */
+#define IMXUART_UCR3_DPEC_MASK (3 << 14)
+#define IMXUART_UCR3_DPEC_REDGE (0 << 14)
+#define IMXUART_UCR3_DPEC_FEDGE (1 << 14)
+#define IMXUART_UCR3_DPEC_EDGE (2 << 14)
+#define IMXUART_UCR3_DTREN (1 << 13)
+#define IMXUART_UCR3_PARERREN (1 << 12)
+#define IMXUART_UCR3_FRAERREN (1 << 11)
+#define IMXUART_UCR3_DSR (1 << 10)
+#define IMXUART_UCR3_DCD (1 << 9)
+#define IMXUART_UCR3_RI (1 << 8)
+#define IMXUART_UCR3_ADNIMP (1 << 7)
+#define IMXUART_UCR3_RXDSEN (1 << 6)
+#define IMXUART_UCR3_AIRINTEN (1 << 5)
+#define IMXUART_UCR3_AWAKEN (1 << 4)
+#define IMXUART_UCR3_DTRDEN (1 << 3)
+#define IMXUART_UCR3_RXDMUXSEL (1 << 2)
+#define IMXUART_UCR3_INVT (1 << 1)
+#define IMXUART_UCR3_ACIEN (1 << 0)
+
+#define IMXUART_UCR4_REG 0x008c /* UART Control Register 4 */
+#define IMXUART_UCR4_CTSTL_MASK (0x3f << 10)
+#define IMXUART_UCR4_CTSTL_SHIFT 10
+#define IMXUART_UCR4_INVR (1 << 9)
+#define IMXUART_UCR4_ENIRI (1 << 8)
+#define IMXUART_UCR4_WKEN (1 << 7)
+#define IMXUART_UCR4_IDDMAEN (1 << 6)
+#define IMXUART_UCR4_IRSC (1 << 5)
+#define IMXUART_UCR4_LPBYP (1 << 4)
+#define IMXUART_UCR4_TCEN (1 << 3)
+#define IMXUART_UCR4_BKEN (1 << 2)
+#define IMXUART_UCR4_OREN (1 << 1)
+#define IMXUART_UCR4_DREN (1 << 0)
+
+#define IMXUART_UFCR_REG 0x0090 /* UART FIFO Control Register */
+#define IMXUART_UFCR_TXTL_MASK (0x3f << 10)
+#define IMXUART_UFCR_TXTL_SHIFT 10
+#define IMXUART_UFCR_RFDIV_MASK (0x07 << 7)
+#define IMXUART_UFCR_RFDIV_SHIFT 7
+#define IMXUART_UFCR_RFDIV_SHIFT 7
+#define IMXUART_UFCR_RFDIV_DIV6 (0 << 7)
+#define IMXUART_UFCR_RFDIV_DIV5 (1 << 7)
+#define IMXUART_UFCR_RFDIV_DIV4 (2 << 7)
+#define IMXUART_UFCR_RFDIV_DIV3 (3 << 7)
+#define IMXUART_UFCR_RFDIV_DIV2 (4 << 7)
+#define IMXUART_UFCR_RFDIV_DIV1 (5 << 7)
+#define IMXUART_UFCR_RFDIV_DIV7 (6 << 7)
+#define IMXUART_UFCR_DCEDTE (1 << 6)
+#define IMXUART_UFCR_RXTL_MASK 0x0000003f
+#define IMXUART_UFCR_RXTL_SHIFT 0
+
+#define IMXUART_USR1_REG 0x0094 /* UART Status Register 1 */
+#define IMXUART_USR1_PARITYERR (1 << 15)
+#define IMXUART_USR1_RTSS (1 << 14)
+#define IMXUART_USR1_TRDY (1 << 13)
+#define IMXUART_USR1_RTSD (1 << 12)
+#define IMXUART_USR1_ESCF (1 << 11)
+#define IMXUART_USR1_FRAMERR (1 << 10)
+#define IMXUART_USR1_RRDY (1 << 9)
+#define IMXUART_USR1_AGTIM (1 << 8)
+#define IMXUART_USR1_DTRD (1 << 7)
+#define IMXUART_USR1_RXDS (1 << 6)
+#define IMXUART_USR1_AIRINT (1 << 5)
+#define IMXUART_USR1_AWAKE (1 << 4)
+/* 6040 5008 XXX */
+
+#define IMXUART_USR2_REG 0x0098 /* UART Status Register 2 */
+#define IMXUART_USR2_ADET (1 << 15)
+#define IMXUART_USR2_TXFE (1 << 14)
+#define IMXUART_USR2_DTRF (1 << 13)
+#define IMXUART_USR2_IDLE (1 << 12)
+#define IMXUART_USR2_ACST (1 << 11)
+#define IMXUART_USR2_RIDELT (1 << 10)
+#define IMXUART_USR2_RIIN (1 << 9)
+#define IMXUART_USR2_IRINT (1 << 8)
+#define IMXUART_USR2_WAKE (1 << 7)
+#define IMXUART_USR2_DCDDELT (1 << 6)
+#define IMXUART_USR2_DCDIN (1 << 5)
+#define IMXUART_USR2_RTSF (1 << 4)
+#define IMXUART_USR2_TXDC (1 << 3)
+#define IMXUART_USR2_BRCD (1 << 2)
+#define IMXUART_USR2_ORE (1 << 1)
+#define IMXUART_USR2_RDR (1 << 0)
+
+#define IMXUART_UESC_REG 0x009c /* UART Escape Character Register */
+#define IMXUART_UESC_ESC_CHAR_MASK 0x000000ff
+
+#define IMXUART_UTIM_REG 0x00a0 /* UART Escape Timer Register */
+#define IMXUART_UTIM_TIM_MASK 0x00000fff
+
+#define IMXUART_UBIR_REG 0x00a4 /* UART BRM Incremental Register */
+#define IMXUART_UBIR_INC_MASK 0x0000ffff
+
+#define IMXUART_UBMR_REG 0x00a8 /* UART BRM Modulator Register */
+#define IMXUART_UBMR_MOD_MASK 0x0000ffff
+
+#define IMXUART_UBRC_REG 0x00ac /* UART Baud Rate Count Register */
+#define IMXUART_UBRC_BCNT_MASK 0x0000ffff
+
+#define IMXUART_ONEMS_REG 0x00b0 /* UART One Millisecond Register */
+#define IMXUART_ONEMS_ONEMS_MASK 0x00ffffff
+
+#define IMXUART_UTS_REG 0x00b4 /* UART Test Register */
+#define IMXUART_UTS_FRCPERR (1 << 13)
+#define IMXUART_UTS_LOOP (1 << 12)
+#define IMXUART_UTS_DBGEN (1 << 11)
+#define IMXUART_UTS_LOOPIR (1 << 10)
+#define IMXUART_UTS_RXDBG (1 << 9)
+#define IMXUART_UTS_TXEMPTY (1 << 6)
+#define IMXUART_UTS_RXEMPTY (1 << 5)
+#define IMXUART_UTS_TXFULL (1 << 4)
+#define IMXUART_UTS_RXFULL (1 << 3)
+#define IMXUART_UTS_SOFTRST (1 << 0)
+
+#define REG(_r) IMXUART_ ## _r ## _REG
+#define FLD(_r, _v) IMXUART_ ## _r ## _ ## _v
+
+#define GETREG(bas, reg) \
+ bus_space_read_4((bas)->bst, (bas)->bsh, (reg))
+#define SETREG(bas, reg, value) \
+ bus_space_write_4((bas)->bst, (bas)->bsh, (reg), (value))
+
+#define CLR(_bas, _r, _b) \
+ SETREG((_bas), (_r), GETREG((_bas), (_r)) & ~(_b))
+#define SET(_bas, _r, _b) \
+ SETREG((_bas), (_r), GETREG((_bas), (_r)) | (_b))
+#define IS_SET(_bas, _r, _b) \
+ ((GETREG((_bas), (_r)) & (_b)) ? 1 : 0)
+
+#define ENA(_bas, _r, _b) SET((_bas), REG(_r), FLD(_r, _b))
+#define DIS(_bas, _r, _b) CLR((_bas), REG(_r), FLD(_r, _b))
+#define IS(_bas, _r, _b) IS_SET((_bas), REG(_r), FLD(_r, _b))
+
+
+#endif /* _UART_DEV_IMX5XX_H */
diff --git a/sys/dev/usb/controller/ehci_imx.c b/sys/dev/usb/controller/ehci_imx.c
new file mode 100644
index 0000000..e9f148c
--- /dev/null
+++ b/sys/dev/usb/controller/ehci_imx.c
@@ -0,0 +1,282 @@
+/*-
+ * Copyright (c) 2010-2012 Semihalf
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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 "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 <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 <machine/bus.h>
+#include <machine/resource.h>
+
+#include "opt_platform.h"
+
+#define FSL_EHCI_COUNT 4
+#define FSL_EHCI_REG_OFF 0x100
+#define FSL_EHCI_REG_SIZE 0x100
+#define FSL_EHCI_REG_STEP 0x200
+
+struct imx_ehci_softc {
+ ehci_softc_t ehci[FSL_EHCI_COUNT];
+ /* MEM + 4 interrupts */
+ struct resource *sc_res[1 + FSL_EHCI_COUNT];
+};
+
+/* i.MX515 have 4 EHCI inside USB core */
+/* TODO: we can get number of EHCIs by IRQ allocation */
+static struct resource_spec imx_ehci_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 },
+ /* RF_OPTIONAL will allow to use driver for systems with 3 EHCIs */
+ { SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL },
+ { -1, 0 }
+};
+
+/* Forward declarations */
+static int fsl_ehci_attach(device_t self);
+static int fsl_ehci_detach(device_t self);
+static int fsl_ehci_probe(device_t self);
+
+static device_method_t ehci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fsl_ehci_probe),
+ DEVMETHOD(device_attach, fsl_ehci_attach),
+ DEVMETHOD(device_detach, fsl_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(struct imx_ehci_softc)
+};
+
+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
+fsl_ehci_probe(device_t dev)
+{
+
+ if (ofw_bus_is_compatible(dev, "fsl,usb-4core") == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale integrated USB controller");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+fsl_ehci_attach(device_t self)
+{
+ struct imx_ehci_softc *sc;
+ bus_space_tag_t iot;
+ ehci_softc_t *esc;
+ int err, i, rid;
+
+ sc = device_get_softc(self);
+ rid = 0;
+
+ /* Allocate io resource for EHCI */
+ if (bus_alloc_resources(self, imx_ehci_spec, sc->sc_res)) {
+ device_printf(self, "could not allocate resources\n");
+ return (ENXIO);
+ }
+ iot = rman_get_bustag(sc->sc_res[0]);
+
+ /* TODO: Power/clock enable */
+ /* TODO: basic init */
+
+ for (i = 0; i < FSL_EHCI_COUNT; i ++) {
+ /* No interrupt - no driver */
+ if (sc->sc_res[1 + i] == NULL)
+ continue;
+
+ esc = &sc->ehci[i];
+ esc->sc_io_tag = iot;
+ esc->sc_bus.parent = self;
+ esc->sc_bus.devices = esc->sc_devices;
+ esc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+
+ if (usb_bus_mem_alloc_all(&esc->sc_bus, USB_GET_DMA_TAG(self),
+ &ehci_iterate_hw_softc))
+ continue;
+
+ /*
+ * Set handle to USB related registers subregion used by
+ * generic EHCI driver.
+ */
+ err = bus_space_subregion(iot,
+ rman_get_bushandle(sc->sc_res[0]),
+ FSL_EHCI_REG_OFF + (i * FSL_EHCI_REG_STEP),
+ FSL_EHCI_REG_SIZE, &esc->sc_io_hdl);
+ if (err != 0)
+ continue;
+
+ /* Setup interrupt handler */
+ err = bus_setup_intr(self, sc->sc_res[1 + i], INTR_TYPE_BIO,
+ NULL, (driver_intr_t *)ehci_interrupt, esc,
+ &esc->sc_intr_hdl);
+ if (err) {
+ device_printf(self, "Could not setup irq, "
+ "for EHCI%d %d\n", i, err);
+ continue;
+ }
+
+ /* Add USB device */
+ esc->sc_bus.bdev = device_add_child(self, "usbus", -1);
+ if (!esc->sc_bus.bdev) {
+ device_printf(self, "Could not add USB device\n");
+ err = bus_teardown_intr(self, esc->sc_irq_res,
+ esc->sc_intr_hdl);
+ if (err)
+ device_printf(self, "Could not tear down irq,"
+ " %d\n", err);
+ continue;
+ }
+ device_set_ivars(esc->sc_bus.bdev, &esc->sc_bus);
+
+ esc->sc_id_vendor = 0x1234;
+ strlcpy(esc->sc_vendor, "Freescale", sizeof(esc->sc_vendor));
+
+ /* Set flags */
+ esc->sc_flags |= EHCI_SCFLG_DONTRESET | EHCI_SCFLG_NORESTERM;
+
+ err = ehci_init(esc);
+ if (!err) {
+ esc->sc_flags |= EHCI_SCFLG_DONEINIT;
+ err = device_probe_and_attach(esc->sc_bus.bdev);
+ } else {
+ device_printf(self, "USB init failed err=%d\n", err);
+
+ device_delete_child(self, esc->sc_bus.bdev);
+ esc->sc_bus.bdev = NULL;
+
+ err = bus_teardown_intr(self, esc->sc_irq_res,
+ esc->sc_intr_hdl);
+ if (err)
+ device_printf(self, "Could not tear down irq,"
+ " %d\n", err);
+
+ continue;
+ }
+ }
+ return (0);
+}
+
+static int
+fsl_ehci_detach(device_t self)
+{
+ struct imx_ehci_softc *sc;
+ ehci_softc_t *esc;
+ int err, i;
+
+ sc = device_get_softc(self);
+
+ for (i = 0; i < FSL_EHCI_COUNT; i ++) {
+ esc = &sc->ehci[i];
+ if (esc->sc_flags & EHCI_SCFLG_DONEINIT)
+ continue;
+ /*
+ * only call ehci_detach() after ehci_init()
+ */
+ if (esc->sc_flags & EHCI_SCFLG_DONEINIT) {
+ ehci_detach(esc);
+ esc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+ }
+
+ /*
+ * Disable interrupts that might have been switched on in
+ * ehci_init.
+ */
+ if (esc->sc_io_tag && esc->sc_io_hdl)
+ bus_space_write_4(esc->sc_io_tag, esc->sc_io_hdl,
+ EHCI_USBINTR, 0);
+
+ if (esc->sc_irq_res && esc->sc_intr_hdl) {
+ err = bus_teardown_intr(self, esc->sc_irq_res,
+ esc->sc_intr_hdl);
+ if (err) {
+ device_printf(self, "Could not tear down irq,"
+ " %d\n", err);
+ return (err);
+ }
+ esc->sc_intr_hdl = NULL;
+ }
+
+ if (esc->sc_bus.bdev) {
+ device_delete_child(self, esc->sc_bus.bdev);
+ esc->sc_bus.bdev = NULL;
+ }
+ }
+
+ /* During module unload there are lots of children leftover */
+ device_delete_children(self);
+
+ if (sc->sc_res[0])
+ bus_release_resources(self, imx_ehci_spec, sc->sc_res);
+
+ return (0);
+}
OpenPOWER on IntegriCloud